Suchen Sie eine Datei (über die rekursive Verzeichnissuche) in Vim

83

Gibt es eine Möglichkeit, ein Verzeichnis in Vim rekursiv nach einer Datei zu durchsuchen (bei Bedarf mit Platzhaltern)? Wenn nicht nativ, gibt es ein Plugin, das damit umgehen kann?

mat-mcloughlin
quelle
1
verwandte stackoverflow.com/questions/1457540/…
Ciro Santilli 法轮功 冠状 病 病 事件 法轮功
@E_Jovi was bedeutet 吊?
Ciro Santilli 法轮功 冠状 病. 事件 法轮功
@CiroSantilli mean 文件 六四 事件 法轮功 Ich meine deinen Namen .. die etwas ausdrücken, was in China verboten ist.
E_Jovi
1
@E_Jovi aber was bedeutet 吊? Nur um meine Chinesen zu verbessern :-)
Ciro Santilli 郝海东 冠状 病 六四 六四 事件 13.
2
@CiroSantilli comm 文件 六四 事件 法轮功 Als lobenswerter Begriff bedeutet dies, dass Sie etwas tun, während die meisten anderen Menschen dies nicht können. In diesem Fall denke ich, dass Ihr Name die Wahrheit über die Geschichte sagt, aber die meisten Chinesen können es aufgrund des Verhaltens der Regierung nicht tun als abfälliger Begriff drückt es aus, dass eine Person auf eine Weise spricht oder sich so verhält, die einen Mangel an Respekt für eine Person zeigt.
E_Jovi

Antworten:

106

Mit dem :editBefehl können Sie Platzhalter verwenden . So,

:e **/test/Suite.java

öffnet test / Suite.java unabhängig davon, wo es sich in der aktuellen Verzeichnishierarchie befindet. Dies funktioniert mit Tab-Vervollständigung, sodass Sie mit [Tab] die Platzhalter erweitern können, bevor Sie die Datei öffnen. Siehe auch die Wildmode- Option, um stattdessen alle möglichen Erweiterungen zu durchsuchen.

Ein weiterer Trick ist zu verwenden

:r! find . -type f

um eine Liste aller Dateien im aktuellen Verzeichnis in einen Puffer zu laden. Anschließend können Sie mit allen üblichen Vim-Textbearbeitungswerkzeugen in der Liste navigieren / sortieren / zuschneiden und CTRL+W gfdie Datei unter dem Cursor in einem neuen Bereich öffnen.

David Winslow
quelle
1
+1 Ich habe den Platzhalter im Bearbeitungsbefehl nie ausprobiert. Das funktioniert auch im Wildmode sehr gut. Sie können also
Folgendes eingeben
Ich wiederum hatte Wildmode mit Wildcard-Erweiterung nicht ausprobiert. Ich habe meine Antwort mit einer Erwähnung aktualisiert.
David Winslow
5
Seien Sie sehr vorsichtig bei großen Dateisammlungen mit komplexer Verzeichnisstruktur. Dieser Befehl kann Ihr vim sehr lange hängen lassen. Mit meiner Codebasis wurde bereits 20 Minuten lang gesucht. Was die Sache kompliziert, ist, dass es keine Möglichkeit gibt, sie zu stoppen. Ich habe die üblichen Strg + C und Strg + Pause ausprobiert. Procmon zeigt, dass vim immer noch nach meiner Datei sucht. Die Lösung ist also nicht jedermanns
Sache
1
@evpo Ich hatte das gleiche Problem. Ich habe es gelöst, indem ich den ersten Teil des Pfads in der Suche angegeben habe, um die Anzahl der Ordner zu verringern: e dir / ** / File.java. Dann dauerte es weniger als eine Sekunde.
user79878
Woher wusste ich das nicht? Ich benutze vim seit mehr als 20 Jahren. Einfach unglaublich Bradley
Bradley
50

Es gibt einen Suchbefehl. Wenn Sie **Ihrem Pfad hinzufügen , können Sie rekursiv suchen.

:set path

zeigt Ihnen Ihren aktuellen Pfad, fügen Sie ** hinzu, indem Sie so etwas tun

:set path=.,/usr/include,,**

das bit vor dem habe **ich von der initial kopiert:set path

dann können Sie einfach tippen

:find myfile.txt

und es öffnet sich magisch!

Wenn Sie den Befehl set zu Ihrer .vimrc hinzufügen, wird sichergestellt, dass Sie in Zukunft eine rekursive Suche durchführen können. Es scheint keine Punktverzeichnisse zu durchsuchen (z. B. .ssh)

Stephen Paulger
quelle
1
Wenn der Dateiname sehr lang ist, ist diese Methode nicht sehr komfortabel oder my*.txtauch?
Shrikant Sharat
1
Ja, Sie können einen Platzhalter * verwenden. siehe :h find.
Tae
11
Sie können auch an Ihren Weg anhängen, indem Sie:set path+=**
Alanboy
Besteht die Gefahr, dem vimrc eine ähnliche Logik hinzuzufügen? cc @alanboy
iamnotsam
21

Ich würde ctrlp.vim empfehlen . Es ist ein sehr gutes Plugin, ideal für große Projekte. Es verfügt über eine Suche nach Dateinamen oder vollständigem Pfad, eine Regexp-Suche, eine automatische Erkennung des Projektstamms (der mit dem Ordner .git | hg | svn | bzr | _darcs), Ausschlüsse für personalisierte Dateinamen und vieles mehr.

Drücken <c-p>Sie einfach und es öffnet sich ein sehr intuitiver Bereich, in dem Sie suchen können, was Sie wollen:

Geben Sie hier die Bildbeschreibung ein

Es ist möglich, mehrere Dateien gleichzeitig auszuwählen und zu öffnen. Es werden auch zusätzliche beliebige Befehle akzeptiert, z. B. das Springen zu einer bestimmten Zeile, das Auftreten von Zeichenfolgen oder ein anderer Vim-Befehl.

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

Victor Schröder
quelle
5
kien / ctrlp.vim scheint nicht gewartet zu werden. Es scheint Konsens darüber zu bestehen, die Gabel ctrlpvim / ctrlp.vim zu verwenden, die offenbar aktiv gewartet wird: github.com/ctrlpvim/ctrlp.vim
Damien Ó Ceallaigh
4
fzf ist ctrlp sehr ähnlich. Es ist schneller und sortiert die Ergebnisse besser. Es funktioniert auch außerhalb von Vim, hat aber eine großartige eingebaute Vim-Unterstützung: github.com/junegunn/fzf
still_dreaming_1
6

vim als eingebauter Suchbefehl (: help find), aber nur die zuerst gefundene Datei öffnen. Sie können jedoch dieses erstaunliche Plugin verwenden: FuzzyFinder, das alles tut, was Sie wollen und noch mehr

mb14
quelle
3

Mit Command-T können Sie eine Datei sehr schnell finden, indem Sie einige Buchstaben eingeben. Sie können die Datei auch in einem neuen Tab öffnen, es muss jedoch vim mit Ruby-Unterstützung kompiliert werden.

Martin Baum
quelle
Und ctrlp.vim auch.
Chris
2

Sie können verwenden! So führen Sie Shell-Befehle aus:

:! find . -name *.xml
Peter Tillemans
quelle
2

Command-t in einem meiner Lieblings-Vim-Plugins, es ist ein Ruby-basiertes Plugin über der Integration mit FZF.

Mit Comamnd-T und FZF können Sie die Suche mit einem extrem schnellen "Fuzzy" -Mechanismus durchführen für:

  • Dateien und Puffer öffnen
  • Zu Tags springen und helfen
  • Ausführen von Befehlen oder vorherigen Suchen und Befehlen
  • mit einer minimalen Anzahl von Tastenanschlägen.

Wie du siehst

Geben Sie hier die Bildbeschreibung ein

Ich suche immer im Befehlsverlauf, indem ich ein neues Terminal öffne und drücke:

CTRL+R

Zusätzlich zur rekursiven Suche in allen Ordnern durch Schreiben in eine beliebige Terminalregisterkarte:

fzf

Sie können auch hinein schreiben vim

:CommandT 

Wirklich kraftvoll und schnell.

HMagdy
quelle
Sie brauchen nicht einmal Befehl-t, nur FZF und das zugehörige Vim-Plugin github.com/junegunn/fzf.vim
icc97
1
Danke, dass du das angesprochen hast. Ich installiere es mit dem Vundle, weiß aber nie, dass es da ist. Langsam aber stetig verlasse ich VS Code :). CLI Heroes zu sein ist großartig!
Benyamin Limanto
1

vim hat bild in Befehlen mit den Namen grep, lgrep, vimgrep oder lvimgrep, die dies können

Hier ist ein Tutorial zu deren Verwendung http://vim.wikia.com/wiki/Find_in_files_within_Vim#Recursive_Search

Sie können auch einen externen Befehl wie find oder grep von vim verwenden, indem Sie ihn wie folgt ausführen

:!find ...
Nikolaus Gradwohl
quelle
Wie können grep, lgrep, vimgrep oder lvimgrep das? Sie suchen in einer Datei nicht nach einer Datei.
Kroiz
Zum Beispiel mit: grep test * / .java
Nikolaus Gradwohl
sucht das nicht nach dem Wort test in den Dateinamen .java? Könnten Sie bitte erklären? Ich konnte es nicht zum Laufen bringen.
Kroiz
@ Kroiz, ja :grep test */.javawird testin allen .javaDateien nach dem Wort suchen . :!findverwendet den findShell-Befehl, um nach Dateien zu suchen. Der findShell-Befehl ist ziemlich mächtig, wenn Sie ihn mit pcre oder erweitertem
regulären
1

Ich bin überrascht, dass niemand Unite.vim erwähnt hat .

Das Finden von Dateien (unscharf oder auf andere Weise) ist nur die Spitze des Eisbergs dessen, was es für einen Entwickler tun kann. Es hat eingebaute Unterstützung für ag, gitund eine Vielzahl von anderen Programmen / Dienstprogramme / vim Plugins. Die Lernkurve kann etwas steil sein, aber ich kann mir mein Leben ohne sie nicht vorstellen. Die Benutzerbasis ist groß und Fehler werden sofort behoben.

minusf
quelle
1

Quickfix-ähnliches Ergebnis-Browsing

Verwendung:

Find my.regex

Ergebnis:

  • Eine neue Registerkarte wird geöffnet
  • Jede Zeile enthält einen relativen Pfad, der mit a übereinstimmt grep -E regulären Ausdruck entspricht
  • schlagen:
    • <enter>oder <C-w>gfum die Datei in der aktuellen Zeile in einer neuen Registerkarte zu öffnen
    • gf um die Datei auf der aktuellen Registerkarte zu öffnen und die Dateiliste zu verlieren

Finden Sie stattdessen alle Dateien:

Find

Alternative Methoden:

Code:

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>'))
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
quelle
1

Verwenden Sie abhängig von Ihrer Situation (dh wenn der folgende Befehl nur eine einzige Datei findet) möglicherweise einen Befehl wie:

:e `locate SomeUniqueFileName.java`

Dies führt dazu, dass Vim auf der aktuellen Registerkarte (dem Befehl e) eine Datei öffnet, die das Ergebnis der Ausführung ist (in diesem Beispiel).

locate SomeUniqueFileName.java

Beachten Sie, dass die Magie hier die Backticks um den Befehl sind, die die Ausgabe des Shell-Befehls in Text konvertieren, der im Vim-Befehl verwendet werden kann.

Byron Katz
quelle
1

Sie benötigen nicht nur für diese Funktion ein Plugin, das folgende Code-Snippet reicht aus.

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>
Bach Hong
quelle
Bitte fügen Sie ein Beispiel für die Verwendung hinzu.
Vitaly Zdanevich
1

Lauf:

:args `find . -name '*xml'`

Vim führt den Shell-Befehl in Backticks aus, legt die Liste der Dateien in der Arglist ab und öffnet die erste Datei. Dann können Sie mit :argsder arglist anzuzeigen (dh Liste der Dateien gefunden) und :nund nach :Nvorne und bacwards durch die Dateien in arglist navigieren. Siehe https://vimhelp.org/editing.txt.html#%7Barglist%7D und https://vimhelp.org/editing.txt.html#backtick-expansion

Eugene Prikazchikov
quelle
0

Mit diesem Plugin können Sie Dateien rekursiv in Ihrem "Pfad" finden . Es unterstützt auch die Tab-Vervollständigung für den Dateinamen.

lomilomi26
quelle
0

Das ag-Tool und das entsprechende Ag vim-Plugin lösen dieses Problem perfekt:

Um eine Datei mit einem Muster zu finden, verwenden Sie:

AgFile! pattern

Es öffnet sich ein Quickfix-Fenster mit Ergebnissen, in denen Sie auswählen können.

Sie können vim keybinding hinzufügen, um diesen Befehl mit dem ausgewählten Wort als Muster aufzurufen.

nnoremap <silent> <C-h> :AgFile! '<C-R><C-W>'<CR>
vnoremap <silent> <C-h> y :AgFile! '<C-R>"'<CR>
Gletscher
quelle