Znajdź plik (poprzez rekurencyjne przeszukiwanie katalogu) w Vimie

84

Czy jest jakiś sposób na rekurencyjne przeszukiwanie katalogu w poszukiwaniu pliku (używając symboli wieloznacznych, gdy jest to potrzebne) w Vimie? Jeśli nie natywnie, czy istnieje wtyczka, która może to obsłużyć?

mat-mcloughlin
źródło
1
powiązany stackoverflow.com/questions/1457540/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
@E_Jovi co znaczy 吊?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
@CiroSantilli 巴拿馬 文件 六四 事件 法轮功 Mam na myśli twoje imię ... które wyraża coś zakazanego w Chinach.
E_Jovi,
1
@E_Jovi, ale co oznacza 吊? Tylko po to, aby poprawić mój chiński :-)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
2
@CiroSantilli 巴拿馬 文件 六四 事件 法轮功 Jako termin pochwały oznacza to, że robisz coś, podczas gdy większość innych ludzi nie może, w tym przypadku myślę, że twoje imię mówi prawdę o historii, ale większość Chińczyków nie może tego zrobić z powodu zachowania rządu jako obraźliwe określenie wyraża, że ​​osoba mówi lub zachowuje się w sposób, który pokazuje brak szacunku dla osoby.
E_Jovi,

Odpowiedzi:

108

W poleceniu można używać symboli wieloznacznych :edit. Więc,

:e **/test/Suite.java

otworzy test / Suite.java bez względu na to, gdzie się on znajduje w bieżącej hierarchii katalogów. Działa to z uzupełnianiem tabulatorami, więc możesz użyć [tab], aby rozwinąć symbole wieloznaczne przed otwarciem pliku. Zobacz także opcję trybu dzikiego, aby dowiedzieć się, jak przeglądać wszystkie możliwe rozszerzenia.

Inną sztuczką jest użycie

:r! find . -type f

aby załadować listę wszystkich plików z bieżącego katalogu do bufora. Następnie możesz użyć wszystkich zwykłych narzędzi do manipulacji tekstem vim, aby nawigować / sortować / przycinać listę i CTRL+W gfotwierać plik pod kursorem w nowym panelu.

David Winslow
źródło
1
+1 Nigdy nie próbowałem używać symbolu wieloznacznego w poleceniu edycji. Działa to również bardzo dobrze w trybie dzikim. Możesz więc wpisać: e ** / Suite <tab> i wszystkie mają listę możliwych plików
mb14
7
Zachowaj ostrożność w przypadku dużych kolekcji plików o złożonej strukturze katalogów. To polecenie może zawiesić twój vim na bardzo długi czas. Z moją bazą kodów szukał już od 20 minut. Sprawę komplikuje fakt, że nie da się tego zatrzymać. Wypróbowałem zwykłe Ctrl + C i Ctrl + Break. Procmon pokazuje, że vim wciąż szuka mojego pliku. Więc rozwiązanie nie jest dla wszystkich :(
evpo
1
@evpo miałem ten sam problem. Rozwiązałem to, podając pierwszą część ścieżki w wyszukiwaniu, aby zmniejszyć liczbę folderów: e dir / ** / File.java. Potem zajęło to mniej niż sekundę.
user79878
1
jak do cholery nie wiedziałem o tym? Używam Vima od ponad 20 lat. Po prostu niesamowite 👏🏼👏🏼👏🏼
Bradley,
1
OMG TO JEST NIESAMOWITE!
Funkodebat
50

Istnieje polecenie wyszukiwania. Jeśli dodasz **(zobacz :help starstar) do swojego 'path', możesz wyszukiwać rekurencyjnie:

:set path

pokaże ci twoją aktualną ścieżkę, dodaj **robiąc coś takiego

:set path+=**

możesz po prostu wpisać

:find myfile.txt

i otwiera się magicznie!

Jeśli dodasz polecenie set do swojego .vimrc, upewni się, że możesz w przyszłości wyszukiwać rekursywnie. Wygląda na to, że nie przeszukuje katalogów z kropkami (na przykład .ssh)

Stephen Paulger
źródło
1
Jeśli nazwa pliku jest bardzo długa, ta metoda nie jest zbyt wygodna, czy też działa my*.txt?
Shrikant Sharat,
1
Tak, możesz użyć * symbolu wieloznacznego. zobacz :h find.
Tae
12
Możesz również dołączyć do swojej ścieżki, wykonując:set path+=**
alanboy,
czy jest jakieś niebezpieczeństwo w dodaniu podobnej logiki do vimrc? cc @alanboy
iamnotsam
21

Polecam ctrlp.vim . To bardzo dobra wtyczka, idealna do pracy w dużych projektach. Ma wyszukiwanie według nazwy pliku lub pełnej ścieżki, wyszukiwanie wyrażeń regularnych, automatyczne wykrywanie katalogu głównego projektu (tego z folderem .git | hg | svn | bzr | _darcs), spersonalizowane wykluczenia nazw plików i wiele innych.

Po prostu naciśnij, <c-p>a otworzy się bardzo intuicyjny panel, w którym możesz wyszukać to, co chcesz:

wprowadź opis obrazu tutaj

Możliwe jest jednoczesne wybranie i otwarcie kilku plików. Przyjmuje również dodatkowe dowolne polecenia, takie jak skok do określonej linii, wystąpienie łańcucha lub dowolne inne polecenie Vima.

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

Victor Schröder
źródło
5
kien / ctrlp.vim wygląda na nieobsługiwany. Wydaje się, że istnieje zgoda co do użycia widelca ctrlpvim / ctrlp.vim, który wydaje się być aktywnie utrzymywany: github.com/ctrlpvim/ctrlp.vim
Damien Ó Ceallaigh
4
fzf jest bardzo podobny do ctrlp. Jest szybszy i lepiej sortuje wyniki. Działa również poza Vimem, ale ma świetnie wbudowaną obsługę Vima: github.com/junegunn/fzf
still_dreaming_1
6

vim jako wbudowane polecenie znajdowania (: help find), ale otwiera tylko pierwszy znaleziony plik. Możesz jednak użyć tej niesamowitej wtyczki: FuzzyFinder, która robi wszystko, co chcesz, a nawet więcej

mb14
źródło
3

Command-T pozwala bardzo szybko znaleźć plik, po prostu wpisując kilka liter. Możesz także otworzyć plik w nowej karcie, ale wymaga on skompilowania vima z obsługą ruby.

Martin Baum
źródło
A także ctrlp.vim.
Chris
2

Możesz użyć ! aby uruchomić polecenia powłoki:

:! find . -name *.xml
Peter Tillemans
źródło
1

vim ma bild w poleceniach o nazwach grep, lgrep, vimgrep lub lvimgrep, które mogą to zrobić

tutaj jest poradnik, jak z nich korzystać http://vim.wikia.com/wiki/Find_in_files_within_Vim#Recursive_Search

możesz także użyć zewnętrznego polecenia, takiego jak find lub grep z vima, wykonując je w ten sposób

:!find ...
Nikolaus Gradwohl
źródło
W jaki sposób grep, lgrep, vimgrep lub lvimgrep mogą to zrobić? Szukają w pliku, a nie pliku.
kroiz
na przykład używając: grep test * / .java
Nikolaus Gradwohl
czy to nie będzie szukać słowa test w nazwach plików .java? Czy mógłbyś wyjaśnić? Nie mogłem zmusić go do pracy.
kroiz
@kroiz, tak :grep test */.java, wyszuka słowo testwe wszystkich .javaplikach. :!findużyje findpolecenia powłoki, aby znaleźć pliki. Polecenie findpowłoki jest dość potężne, jeśli połączysz je z pcre lub rozszerzonym wyrażeniem regularnym
alpha_989
1

Dziwię się, że nikt jeszcze nie wspomniał o Unite.vim .

Znajdowanie plików (niejasno lub w inny sposób) to tylko wierzchołek góry lodowej tego, co może zrobić dla programisty. Posiada wbudowaną obsługę ag, gitoraz mnóstwo innych programów / Narzędzia / vim wtyczek. Krzywa uczenia się może być nieco stroma, ale nie wyobrażam sobie życia bez niej. Baza użytkowników jest duża, a błędy są naprawiane natychmiast.

minusf
źródło
1

Przeglądanie wyników w stylu Quickfix

Stosowanie:

Find my.regex

Wynik:

  • otwiera się nowa karta
  • każda linia zawiera ścieżkę względną, która pasuje do grep -Ewyrażenia regularnego
  • trafienie:
    • <enter>lub <C-w>gfotworzyć plik w bieżącym wierszu w nowej karcie
    • gf aby otworzyć plik na bieżącej karcie i stracić listę plików

Zamiast tego znajdź wszystkie pliki:

Find

Alternatywne metody:

Kod:

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 郝海东 冠状 病 六四 事件 法轮功
źródło
1

W zależności od sytuacji (to znaczy zakładając, że poniższe polecenie znajdzie tylko jeden plik), być może użyj polecenia takiego jak:

:e `locate SomeUniqueFileName.java`

Spowoduje to, że Vim otworzy w bieżącej zakładce (polecenie e) plik będący wynikiem uruchomienia (w tym przykładzie),

locate SomeUniqueFileName.java

Zauważ, że magia tutaj polega na odwrotnych znakach wokół polecenia, które konwertują dane wyjściowe polecenia powłoki na tekst używany w poleceniu Vim.

Byron Katz
źródło
1

Nie potrzebujesz wtyczki tylko do tej funkcji, wystarczy poniższy fragment kodu.

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>
brook hong
źródło
Dodaj przykład, jak go używać.
Witalij Zdanevich
0

Możesz znaleźć pliki rekurencyjnie w swojej „ścieżce” za pomocą tej wtyczki . Obsługuje również uzupełnianie tabulatorami dla nazwy pliku.

lomilomi26
źródło
0

Narzędzie ag i odpowiadająca mu wtyczka Ag vim doskonale rozwiązują ten problem:

Aby znaleźć plik za pomocą jakiegoś wzorca, użyj:

AgFile! pattern

Otworzy się okno quickfix z wynikami, które możesz wybrać.

Możesz dodać przypisanie klawiszy vim, aby wywołać to polecenie używając wybranego słowa jako wzorca.

nnoremap <silent> <C-h> :AgFile! '<C-R><C-W>'<CR>
vnoremap <silent> <C-h> y :AgFile! '<C-R>"'<CR>
aGlacier
źródło