Знайдіть файл (за допомогою рекурсивного пошуку в каталозі) у Vim


84

Чи є спосіб рекурсивного пошуку файлу у каталозі (використовуючи підстановні символи, коли це потрібно) у Vim? Якщо не спочатку, чи існує плагін, який може це впоратись?




@CiroSantilli 巴拿馬 文件 六四 事件 法轮功 Я маю на увазі ваше ім’я .., що виражає щось заборонене в Китаї.
E_Jovi

1
@E_Jovi, але що означає 吊? Просто, щоб покращити свій чинсес :-)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

2
@CiroSantilli 巴拿馬 文件 六四 事件 法轮功 Як похвальний термін, це означає, що ви робите щось, тоді як більшість інших людей не можуть, у цьому випадку я думаю, що ваше ім’я говорить правду історії, але більшість китайців не можуть це зробити через поведінку уряду , як зневажливий термін, він виражає, що людина говорить або поводиться таким чином, що демонструє відсутність поваги до людини.
E_Jovi

Відповіді:


108

Ви можете використовувати символи підстановки за допомогою :editкоманди. Тому,

:e **/test/Suite.java

відкриє test / Suite.java незалежно від того, де він знаходиться в поточній ієрархії каталогів. Це працює із заповненням вкладки, тому ви можете використовувати [tab] для розширення символів підстановки перед відкриттям файлу. Дивіться також параметр wildmode щодо способу перегляду всіх можливих розширень.

Ще одна хитрість - використовувати

:r! find . -type f

щоб завантажити в буфер список усіх файлів у поточному каталозі. Тоді ви можете використовувати всі звичайні засоби обробки тексту vim для навігації / сортування / обрізки списку та CTRL+W gfвідкриття файлу під курсором на новій панелі.


1
+1 Я ніколи не пробував підстановочний знак у команді редагування. Це дуже добре працює і з диким режимом. Отже, ви можете ввести: e ** / Suite <tab>, і всі мають список можливих файлів
mb14

7
Будьте дуже обережні з великими колекціями файлів зі складною структурою каталогів. Ця команда може повісити ваш vim дуже довго. З моєю кодовою базою він шукає вже 20 хвилин. Справа ускладнює те, що неможливо це зупинити. Я спробував звичайні Ctrl + C і Ctrl + Break. Procmon показує, що vim все ще шукає мій файл. Тож рішення не для всіх :(
evpo

1
@evpo У мене була та ж проблема. Я вирішив це, давши першу частину шляху під час пошуку, щоб зменшити кількість папок: e dir / ** / File.java. Потім це зайняло менше секунди.
user79878

1
як лайно я про це не знав? Я використовую vim більше 20 років. Просто дивовижно 👏🏼👏🏼👏🏼
Бредлі

1
OMG ЦЕ ДИВО!
Funkodebat

50

Існує команда пошуку. Якщо ви додасте **(див. :help starstar) До свого, 'path'то ви зможете шукати рекурсивно:

:set path

покаже вам ваш поточний шлях, додайте **, роблячи щось на зразок

:set path+=**

то ви можете просто ввести

:find myfile.txt

і це чарівно відкривається!

Якщо ви додасте команду set до вашого .vimrc, він переконається, що ви зможете робити рекурсивний пошук у майбутньому. Здається, він не шукає крапкові каталоги (наприклад .ssh)


1
Якщо ім'я файлу дуже довге, цей метод не дуже зручний, або він my*.txtтакож робить?
Шрікант Шарат

1
Так, ви можете використовувати * підстановочний знак. див :h find.
Тей

12
Ви також можете додати свій шлях, роблячи:set path+=**
alanboy

чи є якась небезпека у додаванні подібної логіки до vimrc? cc @alanboy
iamnotsam

21

Я б рекомендував ctrlp.vim . Це дуже хороший плагін, ідеально підходить для роботи у великих проектах. У ньому є пошук за іменем файлу або повним шляхом, пошук за регулярними виразами, автоматичне виявлення кореня проекту (того, що має папку .git | hg | svn | bzr | _darcs), персоналізовані виключення імен файлів та багато іншого.

Просто натисніть, <c-p>і відкриється дуже інтуїтивна панель, де ви можете шукати те, що хочете:

введіть тут опис зображення

Можна вибрати та відкрити кілька файлів одночасно. Він також приймає додаткові довільні команди, такі як перехід до певного рядка, входження рядка або будь-яку іншу команду Vim.

Репо: https://github.com/kien/ctrlp.vim


5
kien / ctrlp.vim, здається, не підтримується. Здається, існує консенсус щодо використання вилки ctrlpvim / ctrlp.vim, яка, як видається, активно підтримується: github.com/ctrlpvim/ctrlp.vim
Damien Ó Ceallaigh

4
fzf дуже схожий на ctrlp. Це швидше і сортує результати краще. Він також працює за межами Vim, але має чудову вбудовану підтримку Vim: github.com/junegunn/fzf
still_dreaming_1

6

vim як вбудована команда пошуку (: help find), але відкриває лише перший знайдений файл. Однак ви можете використовувати цей дивовижний плагін: FuzzyFinder, який робить все, що завгодно, і навіть більше


3

Ви можете переглядати файлову систему за допомогою :ex ., але я не знаю, як здійснювати рекурсивний пошук (я новачок Vim - я користуюся нею лише десять років).

Є кілька популярних плагінів для браузерів файлів:

Дивіться також цю тему про SuperUser .


3

Command-T дозволяє дуже швидко знаходити файл, просто ввівши кілька літер. Ви також можете відкрити файл на новій вкладці, але для цього потрібен vim, скомпільований з підтримкою ruby.


І ctrlp.vim також.
Кріс


1

vim має bild у командах grep, lgrep, vimgrep або lvimgrep, які можуть це зробити

ось підручник з їх використання http://vim.wikia.com/wiki/Find_in_files_within_Vim#Recursive_Search

Ви також можете використовувати зовнішню команду, як find або grep з vim, виконавши її так

:!find ...

Як grep, lgrep, vimgrep або lvimgrep можуть це зробити? Вони шукають у файлі не файл.
kroiz

наприклад, використовуючи: grep test * / .java
Nikolaus Gradwohl

чи не буде це шукати слово test в іменах файлів .java? Не могли б ви пояснити? Я не міг змусити його працювати.
kroiz

@kroiz, так, :grep test */.javaбуде шукати слово testу всіх .javaфайлах. :!findбуде використовувати команду findоболонки для пошуку файлів. Команда findоболонки досить потужна, якщо поєднати її з pcre або розширеним регулярним виразом
alpha_989

1

Я здивований, що Unite.vim ще ніхто не згадував .

Пошук файлів (нечітко чи іншим чином) - це лише сама вершина айсберга того, що він може зробити для розробника. Він має вбудовану підтримку ag, gitі безліч інших програм / утиліт / VIM плагін. Крива навчання може бути трохи крутою, але я не уявляю свого життя без неї. База користувачів велика, і помилки виправляються негайно.


1

Перегляд результатів, схожий на швидкі виправлення

Використання:

Find my.regex

Результат:

  • відкриється нова вкладка
  • кожен рядок містить відносний шлях, який відповідає grep -Eрегулярному виразу
  • хіт:
    • <enter>або <C-w>gfвідкрити файл у поточному рядку в новій вкладці
    • gf щоб відкрити файл на поточній вкладці та втратити список файлів

Знайдіть натомість усі файли:

Find

Альтернативні методи:

  • Gfind my.regex: шукати лише файли, що відстежуються Git ( git ls-files). Запит на втечу: https://github.com/tpope/vim-fugitive/issues/132#issuecomment-200749743
  • Gtfind my.regex: like Gfind, але шукайте з верхнього рівня git замість поточного каталогу
  • Locate somefile: locateверсія

Код:

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

Залежно від вашої ситуації (тобто припускаючи, що наступна команда знайде лише один файл), можливо, використовуйте таку команду, як:

:e `locate SomeUniqueFileName.java`

Це призведе до того, що Vim у поточній вкладці (команда e) відкриє файл, який є результатом запуску (у цьому прикладі),

locate SomeUniqueFileName.java

Зверніть увагу, що магією тут є зворотні позначки навколо команди, яка перетворить вихідні дані команди оболонки у текст, який можна використовувати в команді Vim.


1

Вам не потрібен плагін лише для цієї функції, достатньо фрагмента коду.

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>

Будь ласка, додайте приклад, як ним користуватися.
Віталій Зданевич

1

Виконати:

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

Vim запустить команду оболонки у зворотних позначках, додасть список файлів до списку аргументів і відкриє перший файл. Потім ви можете використовувати :argsдля перегляду списку аргументів (тобто переліку знайдених файлів), а :nтакож :Nдля навігації вперед і назад по файлах в списку аргументів. Див. Https://vimhelp.org/editing.txt.html#%7Barglist%7D та https://vimhelp.org/editing.txt.html#backtick-expansion


0

За допомогою цього плагіна ви можете знаходити файли рекурсивно у своєму "шляху" . Він також підтримує заповнення вкладки для імені файлу.


0

ag і відповідний плагін Ag vim вирішує цю проблему ідеально:

Щоб знайти файл за деяким шаблоном, використовуйте:

AgFile! pattern

Відкриється вікно швидкого виправлення з результатами, де ви можете вибрати.

Ви можете додати прив’язку клавіш vim, щоб викликати цю команду, використовуючи вибране слово як шаблон.

nnoremap <silent> <C-h> :AgFile! '<C-R><C-W>'<CR>
vnoremap <silent> <C-h> y :AgFile! '<C-R>"'<CR>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.