Сделать {и} игнорировать строки, содержащие только пробелы
Когда вы перемещаетесь по абзацу в vim с помощью {и}, он пропускает строки, которые не содержат ничего, кроме пробелов, хотя в противном случае они являются "пустыми".
Как я могу убедить vim обрабатывать строки "только пробелы", поскольку абзацы разбиваются, поэтому {и} будет прыгать на них?
Ответы
Ответ 1
Здесь измененная версия, которая обрабатывает правильные значения:
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>
Ответ 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}' и т.д., Похоже, работают нормально. Если у кого-то есть идеи для того, чтобы подсчеты работали или фиксировали визуальный режим, пожалуйста, дайте мне знать.
Ответ 3
Как уже говорилось, если вы запустите :help paragraph
, вы увидите, что строки с пробелом не рассматриваются как граница.
В то же время есть два проекта плагина, которые могут помочь:
Если вы используете Pathogen, просто загрузите с одного из сайтов, упомянутых выше.
Если вы используете Vundle, поместите одно из следующих значений в .vimrc
:
-
Улучшено движение абзаца:
Bundle 'vim-scripts/Improved-paragraph-motion'
-
Vim Paragraph Motion:
Bundle 'dbakker/vim-paragraph-motion'
Запустите :BundleInstall
после перезагрузки и движения {
}
должны остановиться на строках, содержащих пробельные символы.
Ответ 4
Команды {и} перемещаются по "абзацу", а документация vim (см. :help paragraph
) говорит:
Обратите внимание, что пустая строка (только содержащее пустое пространство) НЕ границы абзаца.
Таким образом, единственный способ сделать это - переназначить {и}.
Что-то вроде:
nmap { ?^\\s*$<CR>
nmap } /^\\s*$<CR>
может работать, но вы можете настроить его таким образом, чтобы он не изменял вашу историю поиска.
Ответ 5
У меня никогда не было законной необходимости в простых пробелах, поэтому я решил эту "проблему", добавив следующее к моему .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
Итак, если { и } пропускают только пробельные строки, я использую свое сопоставление, чтобы удалить его и повторить попытку.