Encuentre un archivo (a través de la búsqueda de directorio recursiva) en Vim

84

¿Hay alguna forma de buscar un archivo de forma recursiva en un directorio (utilizando comodines cuando sea necesario) en Vim? Si no es de forma nativa, ¿hay algún complemento que pueda manejar esto?

mat-mcloughlin
fuente
1
relacionado stackoverflow.com/questions/1457540/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
@E_Jovi ¿qué significa 吊?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
@CiroSantilli 巴拿馬 文件 六四 事件 法轮功 Me refiero a tu nombre ... que expresa algo prohibido en China.
E_Jovi
1
@E_Jovi pero ¿qué significa 吊? Solo para mejorar mi Chinsese :-)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
2
@CiroSantilli 巴拿馬 文件 六四 事件 法轮功 Como término elogioso, significa que haces algo mientras que la mayoría de las personas no pueden, en este caso, creo que tu nombre dice la verdad de la historia, pero la mayoría de los chinos no pueden hacerlo debido al comportamiento del gobierno. , como término despectivo, expresa que la persona habla o se comporta de una manera que muestra falta de respeto por una persona.
E_Jovi

Respuestas:

108

Puede utilizar comodines con el :editcomando. Entonces,

:e **/test/Suite.java

abrirá test / Suite.java sin importar dónde se encuentre en la jerarquía de directorios actual. Esto funciona con la finalización de tabulación para que pueda usar [tab] para expandir los comodines antes de abrir el archivo. Consulte también la opción wildmode para conocer una forma de examinar todas las extensiones posibles.

Otro truco es usar

:r! find . -type f

para cargar una lista de todos los archivos del directorio actual en un búfer. Luego, puede usar todas las herramientas habituales de manipulación de texto de vim para navegar / ordenar / recortar la lista y CTRL+W gfabrir el archivo debajo del cursor en un nuevo panel.

David Winslow
fuente
1
+1 Nunca probé el comodín en el comando de edición. Eso también funciona muy bien con el modo salvaje. Entonces puede escribir: e ** / Suite <tab> y todos tienen la lista de archivos posibles
mb14
6
Tenga mucho cuidado con las colecciones de archivos grandes con una estructura de directorios compleja. Este comando puede colgar su vim durante mucho tiempo. Con mi código base ya ha estado buscando 20 minutos. Lo que complica las cosas es que no hay forma de detenerlo. Probé las habituales Ctrl + C y Ctrl + Break. Procmon muestra que vim todavía está buscando mi archivo. Entonces, la solución no es para todos :(
evpo
1
@evpo Tuve el mismo problema. Lo resolví dando la primera parte de la ruta en la búsqueda para reducir el número de carpetas: e dir / ** / File.java. Luego tardó menos de un segundo.
user79878
1
¿Cómo diablos no sabía sobre esto? He estado usando vim durante más de 20 años. Simplemente increíble 👏🏼👏🏼👏🏼
Bradley
1
¡Dios mío, esto es increíble!
Funkodebat
50

Hay un comando de búsqueda. Si agrega **(ver :help starstar) a su 'path', puede buscar de forma recursiva:

:set path

le mostrará su ruta actual, agregue **haciendo algo como

:set path+=**

entonces puedes escribir

:find myfile.txt

¡y se abre mágicamente!

Si agrega el comando set a su .vimrc, se asegurará de que pueda realizar búsquedas recursivas en el futuro. No parece buscar directorios de puntos (.ssh por ejemplo)

Stephen Paulger
fuente
1
Si el nombre del archivo es muy largo, este método no es muy cómodo, ¿o my*.txttambién lo es?
Shrikant Sharat
1
Sí, puede utilizar * comodín. ver :h find.
Tae
12
También puede agregar a su ruta haciendo:set path+=**
alanboy
¿Existe algún peligro en agregar una lógica similar al vimrc? cc @alanboy
iamnotsam
21

Recomendaría ctrlp.vim . Es un complemento muy bueno, ideal para trabajar dentro de grandes proyectos. Tiene búsqueda por nombre de archivo o ruta completa, búsqueda de expresiones regulares, detección automática de la raíz del proyecto (la que tiene la carpeta .git | hg | svn | bzr | _darcs), exclusiones personalizadas de nombres de archivos y muchas más.

Simplemente presione <c-p>y se abrirá un panel muy intuitivo donde puede buscar lo que desee:

ingrese la descripción de la imagen aquí

Es posible seleccionar y abrir varios archivos a la vez. También acepta comandos arbitrarios adicionales, como saltar a una determinada línea, ocurrencia de cadena o cualquier otro comando de Vim.

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

Victor Schröder
fuente
5
kien / ctrlp.vim parece estar sin mantenimiento. Parece haber consenso para usar la bifurcación ctrlpvim / ctrlp.vim, que parece mantenerse activamente: github.com/ctrlpvim/ctrlp.vim
Damien Ó Ceallaigh
4
fzf es muy similar a ctrlp. Es más rápido y clasifica mejor los resultados. También funciona fuera de Vim, pero tiene una excelente compatibilidad con Vim incorporada: github.com/junegunn/fzf
still_dreaming_1
6

vim como un comando de búsqueda incorporado (: ayuda a buscar) pero solo abre el primer archivo encontrado. Sin embargo, puede usar este increíble complemento: FuzzyFinder que hace todo lo que desea y aún más

mb14
fuente
3

Command-T te permite encontrar un archivo muy rápido con solo escribir algunas letras. También puede abrir el archivo en una nueva pestaña, pero necesita vim compilado con soporte ruby.

Martin Baum
fuente
Y ctrlp.vim también.
Chris
2

Puedes usar ! para ejecutar comandos de shell:

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

Command-t en uno de mis complementos vim favoritos, es un complemento basado en ruby ​​por encima de la integración con FZF.

Al usar Comamnd-T y FZF, puede realizar la búsqueda con un mecanismo "difuso" extremadamente rápido para:

  • Abrir archivos y búferes
  • Saltar a etiquetas y ayuda
  • Ejecución de comandos o búsquedas y comandos anteriores
  • con un número mínimo de pulsaciones de teclas.

Como puedes ver

ingrese la descripción de la imagen aquí

Siempre busco en el historial de comandos abriendo una nueva terminal y presiono:

CTRL+R

Además de buscar en todas las carpetas de forma recursiva escribiendo en cualquier pestaña del terminal:

fzf

Además, puedes escribir dentro vim

:CommandT 

Realmente potente y rápido.

HMagdy
fuente
Ni siquiera necesita command-t, solo FZF más el complemento Vim relacionado github.com/junegunn/fzf.vim
icc97
1
Gracias por mencionar esto. Lo instalo con el vundle pero nunca sé que está ahí. Lenta pero firme, me voy de VS Code :). ¡Ser CLI Heroes es increíble!
Benyamin Limanto
1

vim tiene bild en comandos llamados grep, lgrep, vimgrep o lvimgrep que pueden hacer esto

aquí hay un tutorial sobre cómo usarlos http://vim.wikia.com/wiki/Find_in_files_within_Vim#Recursive_Search

también puede usar un comando externo como find o grep de vim ejecutándolo así

:!find ...
Nikolaus Gradwohl
fuente
¿Cómo pueden grep, lgrep, vimgrep o lvimgrep hacer esto? Buscan en un archivo, no en un archivo.
kroiz
por ejemplo, usando: prueba grep * / .java
Nikolaus Gradwohl
¿No buscará esto la palabra prueba en los nombres de archivos .java? ¿Podría explicar por favor? No pude arreglarlo.
kroiz
@kroiz, sí :grep test */.javabuscará la palabra testen todos los .javaarchivos. :!findusará el findcomando de shell para buscar archivos. El findcomando de shell es bastante poderoso, si lo combina con pcre o
expresiones
1

Me sorprende que nadie haya mencionado Unite.vim todavía.

Encontrar archivos (de forma confusa o no) es solo la punta del iceberg de lo que puede hacer por un desarrollador. Tiene soporte integrado para ag, gity una miríada de otros programas / utilidades / complementos vim. La curva de aprendizaje puede ser un poco empinada, pero no puedo imaginar mi vida sin ella. La base de usuarios es grande y los errores se corrigen de inmediato.

minusf
fuente
1

Navegación de resultados similar a Quickfix

Uso:

Find my.regex

Salir:

  • se abre una nueva pestaña
  • cada línea contiene una ruta relativa que coincide con una grep -Eexpresión regular
  • golpear:
    • <enter>o <C-w>gfpara abrir el archivo en la línea actual en una nueva pestaña
    • gf para abrir el archivo en la pestaña actual y perder la lista de archivos

Encuentra todos los archivos en su lugar:

Find

Metodos alternativos:

Código:

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 郝海东 冠状 病 六四 事件 法轮功
fuente
1

Dependiendo de su situación (es decir, asumiendo que el siguiente comando encontrará solo un archivo), quizás use un comando como:

:e `locate SomeUniqueFileName.java`

Esto hará que Vim abra, en la pestaña actual (el comando e) un archivo que es el resultado de ejecutar (en este ejemplo),

locate SomeUniqueFileName.java

Tenga en cuenta que la magia aquí son las comillas inversas alrededor del comando, que convertirán la salida del comando de shell en texto utilizable en el comando Vim.

Byron Katz
fuente
1

No necesita un complemento solo para esta función, el siguiente fragmento de código es suficiente.

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
fuente
Por favor, agregue un ejemplo de cómo usarlo.
Vitaly Zdanevich
1

Correr:

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

Vim ejecutará el comando de shell con comillas inversas, colocará la lista de archivos en arglist y abrirá el primer archivo. A continuación, se puede utilizar :argspara ver el arglist (es decir, lista de los archivos encontrados) y :ny :Npara desplazarse hacia delante y bacwards a través de los archivos en arglist. Consulte https://vimhelp.org/editing.txt.html#%7Barglist%7D y https://vimhelp.org/editing.txt.html#backtick-expansion

Eugene Prikazchikov
fuente
0

Puede encontrar archivos de forma recursiva en su "ruta" con este complemento . También admite la finalización de pestañas para el nombre de archivo.

lomilomi26
fuente
0

ag tool y el complemento Ag vim correspondiente resuelve este problema a la perfección:

Para encontrar un archivo usando algún patrón, use:

AgFile! pattern

Se abrirá una ventana de corrección rápida con resultados donde puede elegir.

Puede agregar la combinación de teclas vim para llamar a este comando usando la palabra seleccionada como patrón.

nnoremap <silent> <C-h> :AgFile! '<C-R><C-W>'<CR>
vnoremap <silent> <C-h> y :AgFile! '<C-R>"'<CR>
un glaciar
fuente