Trova un file (tramite la ricerca di directory ricorsiva) in Vim


84

C'è un modo per cercare un file in una directory ricorsivamente (usando i caratteri jolly quando necessario) in Vim? Se non in modo nativo, esiste un plugin in grado di gestirlo?




@CiroSantilli 巴拿馬 文件 六四 事件 法轮功 Intendo il tuo nome .. che esprime qualcosa di proibito in Cina.
E_Jovi

1
@E_Jovi ma cosa significa 吊? Solo per migliorare il mio cinese :-)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

2
@CiroSantilli 巴拿馬 文件 六四 事件 法轮功 Come termine encomiabile, significa che fai qualcosa mentre la maggior parte delle altre persone non può, in questo caso, penso che il tuo nome racconti la verità sulla storia ma la maggior parte dei cinesi non può farlo a causa del comportamento del governo , come termine dispregiativo, esprime che la persona parla o si comporta in un modo che mostra mancanza di rispetto per una persona.
E_Jovi

Risposte:


110

È possibile utilizzare caratteri jolly con il :editcomando. Così,

:e **/test/Suite.java

aprirà test / Suite.java indipendentemente da dove si trovi nella gerarchia di directory corrente. Funziona con il completamento con tabulazione, quindi puoi usare [tab] per espandere i caratteri jolly prima di aprire il file. Vedi anche l' opzione wildmode per un modo per sfogliare tutte le estensioni possibili.

Un altro trucco è usare

:r! find . -type f

per caricare un elenco di tutti i file nella directory corrente in un buffer. Quindi puoi usare tutti i soliti strumenti di manipolazione del testo di vim per navigare / ordinare / tagliare l'elenco e CTRL+W gfper aprire il file sotto il cursore in un nuovo pannello.


1
+1 Non ho mai provato il carattere jolly nel comando di modifica. Funziona molto bene anche con la modalità selvaggia. Quindi puoi digitare: e ** / Suite <tab> e tutti hanno l'elenco dei file possibili
mb14

7
Fai molta attenzione con raccolte di file di grandi dimensioni con una struttura di directory complessa. Questo comando può bloccare il tuo vim per molto tempo. Con la mia base di codice è già da 20 minuti che cerca. Ciò che complica le cose è che non c'è modo di fermarlo. Ho provato i soliti Ctrl + C e Ctrl + Break. Procmon mostra che vim sta ancora cercando il mio file. Quindi la soluzione non è per tutti :(
evpo

1
@evpo ho avuto lo stesso problema. L'ho risolto dando la prima parte del percorso nella ricerca per ridurre il numero di cartelle: e dir / ** / File.java. Poi ci è voluto meno di un secondo.
user79878

1
come cazzo non lo sapevo? Uso vim da più di 20 anni. Semplicemente fantastico 👏🏼👏🏼👏🏼
Bradley

1
OMG QUESTO È FANTASTICO!
Funkodebat

51

C'è un comando di ricerca. Se aggiungi **(vedi :help starstar) al tuo 'path', puoi cercare in modo ricorsivo:

:set path

ti mostrerà il tuo percorso attuale, aggiungi **facendo qualcosa come

:set path+=**

quindi puoi semplicemente digitare

:find myfile.txt

e si apre magicamente!

Se aggiungi il comando set al tuo .vimrc, in futuro potrai eseguire ricerche ricorsive. Non sembra cercare nelle directory dei punti (ad esempio .ssh)


1
Se il nome del file è molto lungo, questo metodo non è molto comodo o lo fa my*.txtanche?
Shrikant Sharat

1
Sì, puoi utilizzare il carattere jolly *. vedere :h find.
Tae

12
Puoi anche aggiungere al tuo percorso facendo:set path+=**
alanboy

c'è qualche pericolo nell'aggiungere una logica simile al vimrc? cc @alanboy
iamnotsam

21

Consiglierei ctrlp.vim . È un ottimo plugin, ideale per lavorare all'interno di grandi progetti. Ha la ricerca per nome file o percorso completo, ricerca regexp, rilevamento automatico della radice del progetto (quella con la cartella .git | hg | svn | bzr | _darcs), esclusioni di nomi di file personalizzati e molto altro.

Basta premere <c-p>e si aprirà un pannello molto intuitivo dove puoi cercare quello che vuoi:

inserisci qui la descrizione dell'immagine

È possibile selezionare e aprire più file contemporaneamente. Accetta anche comandi arbitrari aggiuntivi, come il salto a una certa riga, l'occorrenza di una stringa o qualsiasi altro comando Vim.

Repo: https://github.com/kien/ctrlp.vim


5
kien / ctrlp.vim sembra non essere mantenuto. Sembra esserci consenso sull'uso del fork ctrlpvim / ctrlp.vim, che sembra essere mantenuto attivamente: github.com/ctrlpvim/ctrlp.vim
Damien Bezborodow

4
fzf è molto simile a ctrlp. È più veloce e classifica meglio i risultati. Funziona anche al di fuori di Vim, ma ha un ottimo supporto integrato per Vim: github.com/junegunn/fzf
still_dreaming_1

6

vim come comando find integrato (: help find) ma apre solo il primo file trovato. Tuttavia puoi usare questo fantastico plugin: FuzzyFinder che fa tutto quello che vuoi e anche di più



3

Comando-T ti consente di trovare un file molto velocemente semplicemente digitando alcune lettere. Puoi anche aprire il file in una nuova scheda, ma ha bisogno di vim compilato con il supporto per ruby.


E anche ctrlp.vim.
Chris


1

vim ha bild in comandi chiamati grep, lgrep, vimgrep o lvimgrep che possono farlo

ecco un tutorial su come usarli http://vim.wikia.com/wiki/Find_in_files_within_Vim#Recursive_Search

puoi anche usare un comando esterno come find o grep da vim eseguendolo in questo modo

:!find ...

Come possono grep, lgrep, vimgrep o lvimgrep farlo? Cercano in un file, non in un file.
kroiz

ad esempio utilizzando: grep test * / .java
Nikolaus Gradwohl

non cercherà la parola test nei nomi dei file .java? Potresti spiegare per favore? Non sono riuscito a farlo funzionare.
kroiz

@kroiz, yes :grep test */.javacercherà la parola testin tutti i .javafile. :!findutilizzerà il findcomando della shell per trovare i file. Il findcomando shell è piuttosto potente, se lo combini con pcre o regex esteso
alpha_989

1

Sono sorpreso che nessuno abbia ancora menzionato Unite.vim .

Trovare file (in modo confuso o meno) è solo la punta dell'iceberg di ciò che può fare per uno sviluppatore. Ha integrato il supporto per ag, gite una miriade di altri programmi / utilità / plugin vim. La curva di apprendimento può essere un po 'ripida, ma non riesco a immaginare la mia vita senza di essa. La base di utenti è ampia e i bug vengono corretti immediatamente.


1

Ricerca dei risultati simile a Quickfix

Utilizzo:

Find my.regex

Risultato:

  • si apre una nuova scheda
  • ogni riga contiene un percorso relativo che corrisponde a una grep -Eregex
  • colpire:
    • <enter>o <C-w>gfper aprire il file sulla riga corrente in una nuova scheda
    • gf per aprire il file nella scheda corrente e perdere l'elenco dei file

Trova invece tutti i file:

Find

Metodi alternativi:

Codice:

function! Find(cmd)
  let l:files = system(a:cmd)
  if (l:files =~ '^\s*$')
    echomsg 'No matching files.'
    return
  endif
  tabedit
  set filetype=filelist
      set buftype=nofile
  " TODO cannot open two such file lists with this. How to get a nice tab label then?
  " http://superuser.com/questions/715928/vim-change-label-for-specific-tab
  "file [filelist]
  put =l:files
  normal ggdd
  nnoremap <buffer> <Enter> <C-W>gf
  execute 'autocmd BufEnter <buffer> lcd ' . getcwd()
endfunction
command! -nargs=1 Find call Find("find . -iname '*'" . shellescape('<args>') . "'*'")
command! -nargs=1 Gfind call Find('git ls-files | grep -E ' . shellescape('<args>'))
command! -nargs=1 Gtfind call Find('git rev-parse --show-toplevel && git ls-files | grep -E ' . shellescape('<args>'))
command! -nargs=1 Locate call Find('locate ' . shellescape('<args>'))

1

A seconda della tua situazione (cioè, supponendo che il seguente comando trovi solo un singolo file), forse usa un comando come:

:e `locate SomeUniqueFileName.java`

Questo farà sì che Vim apra, nella scheda corrente (il comando e) un file che è il risultato dell'esecuzione (in questo esempio),

locate SomeUniqueFileName.java

Nota che la magia qui è il backtick attorno al comando, che convertirà l'output del comando di shell in testo utilizzabile nel comando Vim.


1

Non è necessario un plug-in solo per questa funzione, è sufficiente lo snippet di codice riportato di seguito.

function! FindFiles()
    call inputsave()
    let l:dir = input("Find file in: ", expand("%:p:h"), "dir")
    call inputrestore()
    if l:dir != ""
        call inputsave()
        let l:file = input("File name: ")
        call inputrestore()
        let l:nf = 'find '.l:dir.' -type f -iname '.l:file.' -exec grep -nH -m 1 ".*" {} \;'
        lexpr system(l:nf)
    endif
endfunction
nnoremap <silent> <leader>fo :call FindFiles()<CR>

Si prega di aggiungere un esempio su come usarlo.
Vitaly Zdanevich


0

Puoi trovare i file ricorsivamente nel tuo "percorso" con questo plugin . Supporta anche il completamento tramite tabulazione per il nome del file.


0

Lo strumento ag e il corrispondente plugin Ag vim risolvono perfettamente questo problema:

Per trovare un file usando un modello usa:

AgFile! pattern

Si aprirà la finestra di correzione rapida con i risultati in cui puoi scegliere.

È possibile aggiungere la combinazione di tasti vim per chiamare questo comando utilizzando la parola selezionata come modello.

nnoremap <silent> <C-h> :AgFile! '<C-R><C-W>'<CR>
vnoremap <silent> <C-h> y :AgFile! '<C-R>"'<CR>
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.