2009-12-05 3 views
16

Когда вы перемещаетесь по абзацу в vim, используя {и}, он пропускает строки, которые содержат только пробелы, хотя в противном случае они являются «пустыми».Сделать строки {и} игнорировать строки, содержащие только пробелы

Как я могу убедить vim обрабатывать строки «только пробелы», поскольку абзацы разбиваются, поэтому {и} будет прыгать на них?

ответ

1

{и} команд перемещения по «пункта», а также документации VIM (см :help paragraph) говорит:

Обратите внимание, что пустая строка (только , содержащий пустое пространство) НЕ граница абзаца .

Таким образом, единственный способ сделать это - переназначить {и}. Что-то вроде:

nmap { ?^\\s*$<CR> 
nmap } /^\\s*$<CR> 

может работать, но вы можете настроить это так, не изменяет свою историю поиска.

+0

Это достойный старт, но есть несколько проблем ... те, которые сразу приходят на ум: визуальный режим, сбивающий историю поиска, правильное отключение/сброс 'hlsearch', небольшое мигание курсора, когда он щелкает панель управления (незначительная, да, но все еще раздражающая). –

+0

В любом случае, я думаю, что это хорошее решение ... И если ничего не получится, это может быть единственное решение (в этом случае немного скриптов Vim может сделать проблемы менее болезненными). –

0

Я никогда не имеют законные потребности в пробельном только строки, так что я решить эту «проблему», добавив следующее моих .vimrc:

" Highlight spaces at the end of lines. 
highlight link localWhitespaceError Error 
au Syntax * syn match localWhitespaceError /\(\zs\%#\|\s\)\+$/ display 

" Remove end of line white space. 
noremap <Leader>r ma:%s/\s\+$//e<CR>`a 

Так тогда, если { и } пропускается команда пробельного только линии Я использую свое сопоставление, чтобы удалить его и повторить попытку.

2

Это то, что беспокоило меня в течение длительного времени. Вероятно, «правильным» решением было бы отправить патч самому vim, который позволит вам настраивать границы абзаца с помощью регулярного выражения (например: установить абзацы, но на самом деле полезно).

В то же время, я сделал функцию и несколько отображений, что почти сделать правильную вещь:

function! ParagraphMove(delta, visual) 
    normal m' 
    normal | 
    if a:visual 
     normal gv 
    endif 

    if a:delta > 0 
     " first whitespace-only line following a non-whitespace character 
     let pos1 = search("\\S", "W") 
     let pos2 = search("^\\s*$", "W") 
     if pos1 == 0 || pos2 == 0 
      let pos = search("\\%$", "W") 
     endif 
    elseif a:delta < 0 
     " first whitespace-only line preceding a non-whitespace character 
     let pos1 = search("\\S", "bW") 
     let pos2 = search("^\\s*$", "bW") 
     if pos1 == 0 || pos2 == 0 
      let pos = search("\\%^", "bW") 
     endif 
    endif 
    normal | 
endfunction 

nnoremap <silent> } :call ParagraphMove(1, 0)<CR> 
onoremap <silent> } :call ParagraphMove(1, 0)<CR> 
" vnoremap <silent> } :call ParagraphMove(1, 1)<CR> 
nnoremap <silent> { :call ParagraphMove(-1, 0)<CR> 
onoremap <silent> { :call ParagraphMove(-1, 0)<CR> 
" vnoremap <silent> { :call ParagraphMove(-1, 1)<CR> 

Это не правильно обрабатывать отсчеты, как «4}» или визуальном режиме (правильно раскомментируйте строки vnoremap на свой страх и риск), но, похоже, подходит для таких вещей, как не сбивание текущего шаблона поиска, а не мерцание. Кроме того, 'd}', 'y}' и т. Д., Похоже, работают нормально. Если у кого-то есть идеи для того, чтобы сделать подсчет работы или фиксировать визуальный режим, пожалуйста, дайте мне знать.

+0

Идея патча - лучшее решение, которое я слышал/читал. – rossipedia

6

Вот модифицированная версия, которая обрабатывает отсчеты правильно:

function! ParagraphMove(delta, visual, count) 
    normal m' 
    normal | 
    if a:visual 
     normal gv 
    endif 

    if a:count == 0 
     let limit = 1 
    else 
     let limit = a:count 
    endif 

    let i = 0 
    while i < limit 
     if a:delta > 0 
      " first whitespace-only line following a non-whitespace character   
      let pos1 = search("\\S", "W") 
      let pos2 = search("^\\s*$", "W") 
      if pos1 == 0 || pos2 == 0 
       let pos = search("\\%$", "W") 
      endif 
     elseif a:delta < 0 
      " first whitespace-only line preceding a non-whitespace character   
      let pos1 = search("\\S", "bW") 
      let pos2 = search("^\\s*$", "bW") 
      if pos1 == 0 || pos2 == 0 
       let pos = search("\\%^", "bW") 
      endif 
     endif 
     let i += 1 
    endwhile 
    normal | 
endfunction 

nnoremap <silent> } :<C-U>call ParagraphMove(1, 0, v:count)<CR> 
onoremap <silent> } :<C-U>call ParagraphMove(1, 0, v:count)<CR> 
" vnoremap <silent> } :<C-U>call ParagraphMove(1, 1)<CR> 
nnoremap <silent> { :<C-U>call ParagraphMove(-1, 0, v:count)<CR> 
onoremap <silent> { :<C-U>call ParagraphMove(-1, 0, v:count)<CR> 
" vnoremap <silent> { :<C-U>call ParagraphMove(-1, 1)<CR> 
+0

не работает в визуальном режиме с этими линиями без ранений :( –

2

Как было сказано ранее, если вы запустите :help paragraph вы увидите, что строки с пробелами, не рассматриваются в качестве границы.

В то же время существуют два плагина проекты, которые могли бы помочь:


Если вы используете патоген, просто скачать с одного из сайтов, указанных выше.

Если вы используете Vundle, поместите одно из следующих действий в вашем .vimrc:

  • Улучшение движения пункт:

    Bundle 'vim-scripts/Improved-paragraph-motion' 
    
  • Vim Пункт Motion:

    Bundle 'dbakker/vim-paragraph-motion' 
    

Запустите :BundleInstall после перезагрузки и {} движения должны останавливаться на строках, содержащих пробельные символы.

Смежные вопросы