Создайте отображение для командной строки Vim, которое экранирует содержимое регистра перед его вставкой - PullRequest
8 голосов
/ 13 сентября 2011

Предположим, у меня есть такой документ, и я хочу найти все вхождения URL:

Vim resources: [http://example.com/search?q=vim][q]
...
[q]: http://example.com/search?q=vim

Я не хочу печатать его полностью, поэтому я помещунаведите курсор на первый URL и запустите "uyi[, чтобы вставить его в регистр 'u'.Теперь, чтобы найти его, я бы просто вставил содержимое этого регистра в поле поиска, выполнив:

/\V<c-r>u<CR> 

В результате Vim ищет строку 'http:' - потому что '/ 'символ заканчивает поле поиска.

Я могу обойти проблему, выполнив это вместо:

/\V<c-r>=escape(@u, '\/')<CR><CR>

Но это много печатать!

Как я могусоздать сопоставление для командной строки Vim, которое упрощает этот рабочий процесс?

Мой идеальный рабочий процесс будет выглядеть примерно так:

  • нажмите /\V, чтобы вызвать запрос поиска, и используйте очень неловкоmode
  • нажмите ctrl-x, чтобы активировать пользовательское отображение (ctrl-x доступен)
  • Vim прослушивает следующее нажатие клавиши ... (нажатие <Esc> отменит)
  • нажатие на 'u' приведет к удалению содержимого регистра 'u' и вставке в командную строку

Ответы [ 4 ]

7 голосов
/ 13 сентября 2011

Я принял решение Эндрю Радева , которое решило сложные части. Но вот версия, которую я добавил в свой файл vimrc, который добавляет пару улучшений:

cnoremap <c-x> <c-r>=<SID>PasteEscaped()<cr>
function! s:PasteEscaped()
  echo "\\".getcmdline()."\""
  let char = getchar()
  if char == "\<esc>"
    return ''
  else
    let register_content = getreg(nr2char(char))
    let escaped_register = escape(register_content, '\'.getcmdtype())
    return substitute(escaped_register, '\n', '\\n', 'g')
  endif
endfunction

Это должно работать:

  • используете ли вы / или ? (для поиска вперед или назад)
  • и когда вставленный регистр содержит несколько строк

Также я изменил подсказку. В ожидании регистрации приглашение переключается на \ - что похоже на подходящую подсказку для PasteEscaped. Кроме того, я добавил ", который имитирует поведение Vim после нажатия <c-r> в командной строке.

Если у вас есть предложения по улучшению, оставьте комментарий.

7 голосов
/ 13 сентября 2011

Попробуйте:

cnoremap <c-x> <c-r>=<SID>PasteEscaped()<cr>
function! s:PasteEscaped()
  " show some kind of feedback
  echo ":".getcmdline()."..."

  " get a character from the user
  let char = getchar()

  if char == "\<esc>"
    return ''
  else
    let register_content = getreg(nr2char(char))
    return escape(register_content, '\/')
  endif
endfunction

Кстати, кое-что, что может быть полезно знать (если вы этого еще не сделали), это то, что вы можете использовать ? в качестве разделителя для :s.Это означает, что вы могли бы написать поиск и замену для URL, например, так:

:s?http://foo.com?http://bar.com?g
2 голосов
/ 13 сентября 2011

Как насчет другого рабочего процесса? Например, создание собственного оператора для поиска целевого текста как:

" https://gist.github.com/1213642
" Requiement: https://github.com/kana/vim-operator-user
map YourFavoriteKeySequence  <Plug>(operator-search-target-text)
call operator#user#define('search-target-text', 'OperatorSerachTargetText')
function! OperatorSerachTargetText(motion_wise)
  execute 'normal!' '`['.operator#user#visual_command_from_wise_name(a:motion_wise).'`]"xy'
  let @/ = '\V' . escape(substitute(@x, '[\r\n]$', '', ''), '\')
  normal! n
endfunction
1 голос
/ 13 ноября 2012

Мне нравится решение @ nelstrom, и я внес небольшое изменение для поддержки экранирования [and].

 cnoremap <c-x> <c-r>=<SID>PasteEscaped()<cr>
 function! s:PasteEscaped()
   echo "\\".getcmdline()."\""
   let char = getchar()
   if char == "\<esc>"
     return ''
   else
     let register_content = getreg(nr2char(char))
     let escaped_register = escape(register_content, '\'.getcmdtype())
     let escaped_register2 = substitute(escaped_register,'[','\\[','g')
     let escaped_register3 = substitute(escaped_register2,']','\\]','g')
     return substitute(escaped_register3, '\n', '\\n', 'g')
   endif
 endfunction
...