Posso usare "gf" (o simile) per aprire un file e passare a un termine di ricerca?


9

C'è un modo per ottenere il gfcomando di vim (o qualcosa di simile) per riconoscere un +{cmd}argomento per i percorsi dei file?

Si può avviare vim e andare direttamente a un termine di ricerca facendo:

$ vim +/coding_effort ~/project/file

Allo stesso modo, in modalità comando puoi fare:

:e +/coding_effort ~/project/file

Prendo spesso appunti e mi riferisco ad altri file come questo:

For more info see +/coding_effort ~/project/file where there's a detailed discussion.

Mi piacerebbe poter selezionare +/coding_effort ~/project/file, digitare qualcosa di simile gfe fare in modo che Vim faccia la cosa giusta.


Non penso che ci sia alcun modo di farlo per impostazione predefinita, ma probabilmente potresti creare un plugin che lo fa.
EvergreenTree

Risposte:


6

No, il primo problema è che lo spazio necessario tra comando e nomefile non fa parte isfname'dell'opzione ' e aggiungerlo significherebbe non riconoscere affatto i bordi dei file. Dovresti o usare sempre una selezione visiva (sia di comando che di nome file), oppure implementare l'analisi personalizzata in un gfsovraccarico di comando.

In secondo luogo, il built-in gfnon riconosce la +{cmd}sintassi, quindi non c'è davvero modo di implementare la propria mappatura personalizzata. Ciò è certamente possibile (utilizzando funzioni come expand('<cfile>'), getline()ecc.), Ma probabilmente richiede alcune righe della funzione Vimscript.

Se si sceglie una sintassi diversa ( filename:+command), è possibile mantenere i gfcomandi originali e implementare la suddivisione in un :autocmd, simile a quello che fa il file molto correlato : line plugin filespec:linenumber).


2

Ecco una funzione che dovrebbe replicare il built-in gfcomportamento, e anche le scansioni per lavori a cominciare +che viene quindi passato al:edit

fun! GotoWithCommand()
        let l:file = expand('<cfile>')

        " Replace ~ with the home directory
        let l:file = substitute(l:file, '^\~', $HOME, '')

        " File doesn't exist; return
        if !filereadable(l:file)
                echohl ErrorMsg
                echomsg "E447: Can't find file \"" . l:file . '" in path'
                echohl None
                return 0
        endif

        " Save cursor postion
        let l:save_cursor = getpos(".")

        " Make sure we go to the previous word (B on the first character of the
        " filename goes to the previous word, B anywhere else goes to the start of
        " the filename)
        call search('\(\s\|^\)', 'b')

        " Try to find argument to be executed; these start with a `+'
        let l:commands = ''
        while 1
                " Go one WORD backwards
                normal! B

                " Not a +; stop the loop
                if getline('.')[col('.') - 1] != '+'
                        break
                endif

                let l:commands .= ' ' . expand('<cWORD>')
        endwhile

        " Restore cursor postion
        call setpos('.', l:save_cursor)

        " Now, open the new file...
        execute ':edit ' . l:commands . ' ' . l:file
endfun

nnoremap <Leader>gf :call GotoWithCommand()<CR>

I commenti dovrebbero spiegare cosa fa la funzione in modo più dettagliato ... L'ho scritto sul treno la mattina e (ovviamente) non l'ho provato ampiamente ;-)


1

Un'opzione sarebbe (supponendo che +cmd file/pathsia selezionato) per spostare la selezione in un registro, quindi inserire quel registro nel prompt dei comandi. L'ho fatto con la seguente mappatura:

vnoremap gsf "0y:e <c-r>0<cr>


1

Questa notazione funziona ( file name+ trailing :+ / pat /)

/usr/include/stdio.h:/int printf/  -- `file name` + `:` + `/ pat /`
/usr/include/stdio.h:+/int printf/
/usr/include/stdio.h: /int printf/
/usr/include/stdio.h: /#define\s/
/usr/include/stdio.h: /^#define\sSEEK/

con funzione e mappatura di seguito.

nn gf :<C-u>call Gf_search()<CR>

func! Gf_search() abort
    let word = expand('<cWORD>')
    let idx = stridx(word, ':')
    if idx != -1
        let remline = strpart(getline('.'),col('.'))
        let pat = substitute(remline, '.*[:+ ]/\([^/]*\)/.*', '\1', "")
        if pat != remline
            let pat = substitute(pat, '\\', '\\\\', 'g')
            let pat = substitute(pat, ' ', '\\ ', 'g')
            let filename = expand('<cfile>')
            exec 'e +/'.pat filename
            return
        endif
    endif
    " fallback to builtin gF
    norm! gF
endfunc
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.