2011-09-13 3 views
8

Supponiamo che ho un documento come questo, e voglio cercare tutte le occorrenze di URL:Creare una mappatura per riga di comando di Vim che sfugge il contenuto di un registro prima di inserirlo

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

I non voglio scriverlo per intero, quindi metto il cursore sul primo URL ed eseguo "uyi[ per strattonarlo nel registro 'u'. Ora per cercarlo, mi piacerebbe per incollare solo il contenuto di tale registro nel campo di ricerca eseguendo:

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

Ciò si traduce in Vim ricerca della stringa 'http:' - perché il '/' carattere termina il campo di ricerca.

posso aggirare il problema eseguendo questo, invece:

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

Ma è un sacco di battitura!

Come è possibile creare una mappatura per la riga di comando di Vim che semplifica questo flusso di lavoro?

mio flusso di lavoro ideale sarebbe andato qualcosa come questo:

  • stampa /\V per aprire il prompt di ricerca, e utilizzare la modalità molto nomagic
  • premere Ctrl-x per attivare la mappatura personalizzata (ctrl-x è disponibili)
  • Vim ascolta per la prossima pressione di un tasto ... (premendo <Esc> cancellerebbe)
  • premendo 'u' sfuggirebbe il contenuto della 'u' registrare il, e inserire nella riga di comando
+0

Attualmente utilizzo '*' in modalità visuale. Ho alcuni plugin fatti in casa al largo di questo script: http://amix.dk/blog/post/19334 –

+0

@PeterRincker - sì, io uso [qualcosa del genere] (https://github.com/bronson/vim- visual-star-search) anche! La documentazione di Vim suggerisce una [mappatura simile] (http://vimdoc.sourceforge.net/htmldoc/visual.html#visual-search), anche se è un po 'cotta. – nelstrom

risposta

7

Prova questa:

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 

Tra l'altro, qualcosa che potrebbe essere utile sapere (se non già) è che è possibile utilizzare ? come delimitatore per :s. Il che significa che si potrebbe scrivere una ricerca e sostituzione per un URL in questo modo:

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

Questa è un'ottima soluzione, grazie! – nelstrom

+2

Non ho attirato l'attenzione nella mia domanda iniziale, ma ho usato deliberatamente un URL che includeva sia "/" che "?" personaggi. Se il target di ricerca includeva solo uno di questi due, è possibile comporre il prompt di ricerca utilizzando l'altro, evitando di dover evadere. – nelstrom

+0

Hai ragione, non ho notato i punti interrogativi abbastanza presto. –

7

ho accettato Andrew Radev's solution, che ha risolto le parti dure. Ma ecco la versione che ho aggiunto al mio file vimrc, che aggiunge un paio di miglioramenti:

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 

Questo dovrebbe funzionare:

  • se si utilizza / o ? (per la ricerca in avanti, o all'indietro)
  • e quando il registro incollato comprende più linee

Inoltre, ho cambiato la richiesta. In attesa di un registro, il prompt passa a \ - che sembra un suggerimento adatto per "PasteEscaped". Inoltre, ho aggiunto uno ", che imita il comportamento di Vim dopo aver premuto <c-r> nella riga di comando.

Se avete ulteriori suggerimenti per miglioramenti, si prega di lasciare un commento.

2

E un flusso di lavoro diverso? Ad esempio, creare il proprio operatore per la ricerca di testo di destinazione come è:

" 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

mi piace @ soluzione nelstrom e ha fatto un piccolo cambiamento per sostenere la fuga [e].

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 
Problemi correlati