2011-09-13 2 views
8

Supongamos que tengo un documento como este, y quiero buscar todas las apariciones de la URL:Crear una asignación para la línea de comandos de Vim que se escapa el contenido de un registro antes de insertarlo

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

I No quiero escribirlo en su totalidad, así que colocaré mi cursor en la primera URL y ejecutaré "uyi[ para arrastrarlo al registro 'u'. Ahora que buscarlo, me gustaría simplemente pegar el contenido de dicho registro en el campo de búsqueda mediante la ejecución:

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

Esto se traduce en Vim busca de la cadena 'http:' - porque el '/' personaje termina el campo de búsqueda.

puedo evitar el problema mediante la ejecución de este lugar:

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

pero es un montón de escribir!

¿Cómo puedo crear una asignación para la línea de comandos de Vim que simplifique este flujo de trabajo?

Mi flujo de trabajo ideal sería algo parecido a esto:

  • prensa /\V para que aparezca el símbolo de búsqueda, y utilizar el modo muy nomagic
  • pulse Ctrl-x para disparar la asignación personalizada (ctrl-x es disponible)
  • Vim escucha para la siguiente pulsación de tecla ... (presionando <Esc> cancelaría)
  • presionando 'u' escaparía el contenido de la 'U' registro, e insertar en la línea de comandos
+0

Actualmente uso '*' en modo visual. Tengo un plugin casero basado en este script: http://amix.dk/blog/post/19334 –

+0

@PeterRincker - Sí, uso [algo así] (https://github.com/bronson/vim- visual-star-search) también! La propia documentación de Vim sugiere un [mapeo similar] (http://vimdoc.sourceforge.net/htmldoc/visual.html#visual-search), aunque está un poco medio coagulado. – nelstrom

Respuesta

7

Prueba esto:

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 

Por cierto, algo que podría ser útil saber (si no lo hace ya) es que se puede utilizar ? como delimitador de :s. Lo que significa que se podría escribir una búsqueda y reemplazo para una URL de este modo:

:s?http://foo.com?http://bar.com?g 
+0

¡Esa es una gran solución, gracias! – nelstrom

+2

No lo llamé la atención en mi pregunta original, pero deliberadamente utilicé una URL que incluía tanto '/' como '?' caracteres. Si el objetivo de búsqueda solo incluía uno de esos dos, puede marcar el indicador de búsqueda usando el otro, evitando la necesidad de escapar de cualquier cosa. – nelstrom

+0

Tiene razón al respecto, no me di cuenta de los signos de interrogación lo suficientemente temprano. –

7

He aceptado Andrew Radev's solution, que resuelve las partes duras. Pero aquí está la versión que he añadido a mi archivo vimrc, lo que añade un par de mejoras:

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 

Esto debería funcionar:

  • si se utiliza / o ? (para buscar hacia delante o al revés)
  • y cuando el registro pegado incluye múltiples líneas

Además, he cambiado el indicador. Mientras espera un registro, la solicitud cambia a \, lo que parece una señal adecuada para 'PasteEscaped'. Además, he agregado un ", que imita el comportamiento de Vim después de presionar <c-r> en la línea de comandos.

Si tienes más sugerencias para mejoras, por favor deja un comentario.

2

¿Qué tal un flujo de trabajo diferente? Por ejemplo, la creación de su propio operador para buscar texto de destino como es:

" 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

me gusta @ solución de nelstrom e hizo un pequeño cambio para apoyar escapar [y].

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 
Cuestiones relacionadas