Tìm tệp (thông qua tìm kiếm thư mục đệ quy) trong Vim


84

Có cách nào để tìm kiếm tệp tin trong thư mục một cách đệ quy (sử dụng ký tự đại diện khi cần thiết) trong Vim không? Nếu không phải là nguyên bản, có plugin nào có thể xử lý điều này không?




@CiroSantilli 巴拿馬 文件 六四 事件 法轮功 Ý tôi là tên của bạn .. thể hiện điều gì đó bị cấm ở Trung Quốc.
E_Jovi

1
@E_Jovi nhưng 吊 có nghĩa là gì? Chỉ để cải thiện tiếng Chinsese của tôi :-)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

2
@CiroSantilli 巴拿馬 文件 六四 事件 法轮功 Như một thuật ngữ đáng khen ngợi, nó có nghĩa là bạn làm điều gì đó trong khi hầu hết những người khác không thể, trong trường hợp này, tôi nghĩ rằng tên của bạn nói lên sự thật lịch sử nhưng hầu hết người Trung Quốc không thể làm điều đó vì hành vi của chính phủ , là thuật ngữ xúc phạm, nó thể hiện người đó nói hoặc cư xử theo cách thể hiện sự thiếu tôn trọng đối với một người.
E_Jovi

Câu trả lời:


108

Bạn có thể sử dụng các ký tự đại diện với :editlệnh. Vì thế,

:e **/test/Suite.java

sẽ mở test / Suite.java cho dù nó ở đâu trong hệ thống phân cấp thư mục hiện tại. Điều này hoạt động với tính năng hoàn thành bằng tab nên bạn có thể sử dụng [tab] để mở rộng các ký tự đại diện trước khi mở tệp. Xem thêm wildmode lựa chọn cho một cách để duyệt qua tất cả các phần mở rộng có thể thay thế.

Một thủ thuật khác là sử dụng

:r! find . -type f

để tải danh sách tất cả các tệp trong thư mục hiện tại vào bộ đệm. Sau đó, bạn có thể sử dụng tất cả các công cụ thao tác văn bản vim thông thường để điều hướng / sắp xếp / cắt danh sách và CTRL+W gfđể mở tệp dưới con trỏ trong ngăn mới.


1
+1 Tôi chưa bao giờ thử ký tự đại diện trong lệnh chỉnh sửa. Điều đó cũng hoạt động thực sự tốt với mã đại diện. Vì vậy, bạn có thể nhập: e ** / Suite <tab> và tất cả đều có danh sách các tệp có thể có
mb14

6
Hãy hết sức cẩn thận với các bộ sưu tập tệp lớn có cấu trúc thư mục phức tạp. Lệnh này có thể treo vim của bạn rất lâu. Với codebase của tôi, nó đã tìm kiếm được 20 phút rồi. Điều làm phức tạp vấn đề là không có cách nào để ngăn chặn nó. Tôi đã thử Ctrl + C và Ctrl + Break thông thường. Procmon cho thấy vim vẫn đang tìm kiếm tệp của tôi. Vì vậy, giải pháp không phải là cho mọi người :(
evpo

1
@evpo Tôi đã gặp vấn đề tương tự. Tôi đã giải quyết nó bằng cách cho phần đầu tiên của đường dẫn trong tìm kiếm để giảm số lượng thư mục: e dir / ** / File.java. Sau đó, nó mất chưa đầy một giây.
user79878

1
Làm thế nào tào lao mà tôi không biết về điều này? Tôi đã sử dụng vim trong hơn 20 năm. Thật tuyệt vời 👏🏼👏🏼👏🏼
Bradley

1
OMG ĐÂY LÀ TUYỆT VỜI!
Funkodebat

50

Có một lệnh tìm. Nếu bạn thêm **(xem :help starstar) vào 'path'thì bạn có thể tìm kiếm đệ quy:

:set path

sẽ cho bạn thấy con đường hiện tại của bạn, hãy thêm **bằng cách làm điều gì đó như

:set path+=**

sau đó bạn có thể chỉ cần gõ

:find myfile.txt

và nó mở ra một cách kỳ diệu!

Nếu bạn thêm lệnh set vào .vimrc của mình, nó sẽ đảm bảo rằng bạn có thể thực hiện tìm kiếm đệ quy trong tương lai. Nó dường như không tìm kiếm các thư mục dấu chấm (.ssh chẳng hạn)


1
Nếu tên tệp rất dài, thì phương pháp này không thoải mái lắm, hoặc nó my*.txtcũng làm được?
Shrikant Sharat

1
Có, bạn có thể sử dụng ký tự đại diện *. xem :h find.
Tae

12
Bạn cũng có thể thêm vào đường dẫn của bạn bằng cách thực hiện:set path+=**
alanboy

có nguy hiểm nào trong việc thêm một logic tương tự vào vimrc không? cc @alanboy
iamnotsam

21

Tôi muốn giới thiệu ctrlp.vim . Đây là một plugin rất tốt, lý tưởng để làm việc trong các dự án lớn. Nó có tính năng tìm kiếm theo tên tệp hoặc đường dẫn đầy đủ, tìm kiếm regexp, tự động phát hiện gốc của dự án (tệp có thư mục .git | hg | svn | bzr | _darcs), loại trừ tên tệp được cá nhân hóa và nhiều hơn nữa.

Chỉ cần nhấn <c-p>và nó sẽ mở ra một ngăn rất trực quan, nơi bạn có thể tìm kiếm những gì bạn muốn:

nhập mô tả hình ảnh ở đây

Có thể chọn và mở nhiều tệp cùng một lúc. Nó cũng chấp nhận các lệnh tùy ý bổ sung, như nhảy đến một dòng nhất định, sự xuất hiện chuỗi hoặc bất kỳ lệnh Vim nào khác.

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


5
kien / ctrlp.vim dường như không có nguyên nhân. Dường như có sự đồng thuận để sử dụng ctrlpvim / ctrlp.vim fork, có vẻ như đang được duy trì tích cực: github.com/ctrlpvim/ctrlp.vim
Damien Ó Ceallaigh 22/09/15

4
fzf rất giống với ctrlp. Nó nhanh hơn và sắp xếp kết quả tốt hơn. Nó cũng hoạt động bên ngoài Vim, nhưng được tích hợp sẵn trong hỗ trợ Vim: github.com/junegunn/fzf
still_dreaming_1

6

vim dưới dạng lệnh tìm nội trang (: help find) nhưng chỉ mở tệp đầu tiên được tìm thấy. Tuy nhiên, bạn có thể sử dụng plugin tuyệt vời này: FuzzyFinder thực hiện mọi thứ bạn muốn và thậm chí hơn thế nữa



3

Command-T cho phép bạn tìm tệp rất nhanh chỉ bằng cách nhập một số chữ cái. Bạn cũng có thể mở tệp trong tab mới, nhưng nó cần vim được biên dịch với sự hỗ trợ của ruby.


Và ctrlp.vim nữa.
Chris


2

Command-t trong một trong những plugin vim yêu thích của tôi, đó là plugin dựa trên ruby ​​ở trên tích hợp với FZF.

Bằng cách sử dụng Comamnd-T và FZF, bạn có thể thực hiện tìm kiếm với cơ chế "mờ" cực kỳ nhanh chóng cho:

  • Mở tệp và bộ đệm
  • Chuyển đến thẻ và trợ giúp
  • Các lệnh đang chạy hoặc các tìm kiếm và lệnh trước đó
  • với một số lần nhấn phím tối thiểu.

Bạn có thể thấy

nhập mô tả hình ảnh ở đây

Tôi luôn tìm kiếm trong lịch sử lệnh bằng cách mở một thiết bị đầu cuối mới và nhấn:

CTRL+R

Ngoài việc tìm kiếm trong tất cả các thư mục một cách đệ quy bằng cách viết vào bất kỳ tab đầu cuối nào:

fzf

Ngoài ra, bạn có thể viết bên trong vim

:CommandT 

Thực sự mạnh mẽ và nhanh chóng.


Bạn thậm chí không cần lệnh t, chỉ FZF cộng với liên quan Vim Plugin github.com/junegunn/fzf.vim
icc97

1
Cảm ơn vì đã đưa ra điều này. Tôi cài đặt nó với vundle nhưng không bao giờ biết rằng nó ở đó. Từ từ nhưng chắc chắn, tôi đang rời khỏi VS Code :). Trở thành Anh hùng CLI thật tuyệt vời!
Benyamin Limanto

1

vim có bild trong các lệnh có tên grep, lgrep, vimgrep hoặc lvimgrep có thể thực hiện việc này

đây là hướng dẫn về cách sử dụng chúng http://vim.wikia.com/wiki/Find_in_files_within_Vim#Recursive_Search

bạn cũng có thể sử dụng một lệnh bên ngoài như find hoặc grep từ vim bằng cách thực thi nó như thế này

:!find ...

Làm thế nào grep, lgrep, vimgrep hoặc lvimgrep có thể làm điều này? Họ tìm kiếm trong một tệp không phải cho một tệp.
kroiz

ví dụ bằng cách sử dụng: kiểm tra grep * / java
Nikolaus Gradwohl

điều này sẽ không tìm kiếm kiểm tra từ trong tên tệp .java? Bạn có thể vui lòng giải thích? Tôi không thể làm cho nó hoạt động.
kroiz

@kroiz, yes :grep test */.javasẽ tìm kiếm từ testtrong tất cả .javacác tệp. :!findsẽ sử dụng findlệnh shell để tìm tệp. Các findlệnh shell là khá mạnh mẽ, nếu bạn kết hợp nó với PCRE hoặc regex mở rộng
alpha_989

1

Tôi ngạc nhiên là chưa có ai đề cập đến Unite.vim .

Tìm kiếm tệp (mờ hoặc khác) chỉ là phần nổi của tảng băng chìm về những gì nó có thể làm cho một nhà phát triển. Nó đã được xây dựng trong hỗ trợ cho ag, gitvà vô số các chương trình / tiện ích / plugins vim khác. Con đường học tập có thể hơi dốc, nhưng tôi không thể tưởng tượng cuộc sống của mình nếu không có nó. Cơ sở người dùng lớn và các lỗi được sửa ngay lập tức.


1

Duyệt kết quả giống như Quickfix

Sử dụng:

Find my.regex

Kết quả:

  • một tab mới mở ra
  • mỗi dòng chứa một đường dẫn tương đối khớp với một grep -Eregex
  • đánh:
    • <enter>hoặc <C-w>gfđể mở tệp trên dòng hiện tại trong tab mới
    • gf để mở tệp trên tab hiện tại và mất danh sách tệp

Tìm tất cả các tệp thay thế:

Find

Các phương thức thay thế:

Mã:

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

Tùy thuộc vào tình huống của bạn (nghĩa là, giả sử lệnh sau sẽ chỉ tìm thấy một tệp duy nhất), có thể sử dụng lệnh như:

:e `locate SomeUniqueFileName.java`

Điều này sẽ làm cho Vim mở, trong tab hiện tại (lệnh e) một tệp là kết quả của việc chạy (trong ví dụ này),

locate SomeUniqueFileName.java

Lưu ý rằng điều kỳ diệu ở đây là các dấu gạch ngược xung quanh lệnh, sẽ chuyển đầu ra từ lệnh shell thành văn bản có thể sử dụng được trong lệnh Vim.


1

Bạn không cần plugin chỉ cho chức năng này, đoạn mã bên dưới là đủ.

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>

Vui lòng thêm ví dụ về cách sử dụng nó.
Vitaly Zdanevich

1

Chạy:

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

Vim sẽ chạy lệnh shell trong backticks, đưa danh sách các tệp vào arglist và mở tệp đầu tiên. Sau đó, bạn có thể sử dụng :argsđể xem các arglist (tức là danh sách các tập tin được tìm thấy) và :n:Nđể di chuyển về phía trước và bacwards thông qua các tập tin trong arglist. Xem https://vimhelp.org/editing.txt.html#%7Barglist%7Dhttps://vimhelp.org/editing.txt.html#backtick-expansion


0

Bạn có thể tìm các tệp một cách đệ quy trong "đường dẫn" của mình bằng plugin này . Nó cũng hỗ trợ hoàn thành tab cho tên tệp.


0

Công cụ ag và plugin Ag vim tương ứng giải quyết vấn đề này một cách hoàn hảo:

Để tìm tệp bằng cách sử dụng một số mẫu:

AgFile! pattern

Nó sẽ mở ra cửa sổ Quickfix với các kết quả mà bạn có thể chọn.

Bạn có thể thêm keybinding vim để gọi lệnh này bằng cách sử dụng từ đã chọn làm mẫu.

nnoremap <silent> <C-h> :AgFile! '<C-R><C-W>'<CR>
vnoremap <silent> <C-h> y :AgFile! '<C-R>"'<CR>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.