Làm cách nào để tìm kiếm từ hiện tại trong tất cả các tab đã mở trong Vim?


16

Tôi đã bắt đầu học tìm kiếm từ Vim bằng cách sử dụng *#trong khi con trỏ ở trên từ hiện tại. Nhưng tìm kiếm này được giới hạn trong bộ đệm tập tin hiện tại.

Có một lệnh hoặc một phím tắt để mở rộng tìm kiếm này tới:

  1. tất cả các tab đã mở?
  2. Tất cả đã mở bộ đệm?

1
Bạn có thể thấy giải thích về các tab so với bộ đệm thú vị và hữu ích.
tự đại diện

Câu trả lời:


4

Tôi không có giải pháp chính xác cho vấn đề của bạn, hy vọng câu trả lời tốt hơn câu hỏi của tôi sẽ được đưa ra. Nhưng đây là cách tôi giải quyết vấn đề tìm từ trong tất cả các bộ đệm.

" enables to search in all open buffers with :Search <pattern>
command! -nargs=1 Search call setqflist([]) | silent bufdo grepadd! <args> %

nnoremap <left>  :cprev<cr>zvzz
nnoremap <right> :cnext<cr>zvzz

Dòng đầu tiên tạo một lệnh Searchvới mẫu tìm kiếm làm đối số, ghi kết quả vào danh sách quickfix. Hai dòng khác ánh xạ các phím mũi tên vô dụng (ít nhất là đối với tôi) thành thứ gì đó hữu ích; chúng được ánh xạ để chuyển sang Tìm kiếm tiếp theo / trước hoặc lỗi biên dịch tiếp theo / trước, v.v., chúng chỉ đơn giản là bước qua danh sách quickfix. Bạn có thể sử dụng như sau:

:Search foobar
<right>
<right>
…

Tôi thích lệnh này, nhưng đã thêm một vài thứ để nó thoát khỏi cụm từ tìm kiếm tốt hơn và buộc vẽ lại. (sử dụng chế độ im lặng với các phần tách có thể khiến vim ui bị lỗi). chỉ huy! -nargs = 1 Tìm kiếm cuộc gọi setqflist ([]) | thực thi im lặng "bufdo grepadd! '<args>'%" | vẽ lại!
Igorio

bạn cũng có thể chỉ cần gõ :cnhoặc :cpđể chuyển sang tài liệu tiếp theo.
phyatt

7

Đây thực sự là hành vi mặc định mặc dù có thể khó nhận thấy: thử *sau đó thay đổi sang một tab khác và sử dụng nans Ntrong chế độ lệnh để nhảy tới và lùi giữa các lần tìm kiếm.

Điều này có thể có ý nghĩa hơn nếu lần đầu tiên bạn bật đánh dấu cho tất cả các lần truy cập:

:set hlsearch

1
+1 chỉ vì hlsearchđiều đó tôi không biết, và tôi sẽ tìm kiếm ngày này hay ngày khác :-). Tuy nhiên, theo mặc định, tôi đã thử * #, n và N và nó không chuyển sang bộ đệm tệp khác ...
Stephane Rolland

Không, nNkhông nhảy bộ đệm (chúng quấn quanh), nhưng thuật ngữ chúng nhắm mục tiêu được tìm kiếm trong tất cả các tab; nhấn vào *phần tô sáng sau đó chuyển qua các tab của bạn - tất cả chúng sẽ được tô sáng với cùng một thuật ngữ, vì vậy bạn có thể sử dụng nNcục bộ ở đó mà không cần tìm kiếm mới.
goldilocks

2
Toàn bộ vấn đề là KHÔNG phải quay vòng qua các tab của bạn để tìm tất cả các trận đấu.
Magnus

1
@Magnus Mặc dù điều đó có thể thích hợp hơn nhưng thực tế nó không được nêu rõ ràng trong câu hỏi, nó hỏi làm thế nào để "mở rộng tìm kiếm này đến ... tất cả các bộ đệm" -> nó được mở rộng trên tất cả các bộ đệm. Quan điểm của câu trả lời của tôi là làm rõ điều này, vì nó có thể không, đặc biệt là nếu bạn chưa hlsearchđặt.
goldilocks


1

Vì tôi thấy mình thường xuyên làm điều này nên tôi đã tạo ra một kịch bản (có thể ứng biến).

Bạn hoặc người khác có thể thấy nó hữu ích.


Giải thích ngắn gọn:

Về cơ bản, nó tìm kiếm danh sách bộ đệm và hiển thị kết quả trong cửa sổ quickfix.

Hai lệnh cơ bản được thêm vào.

  1. Search <pattern> : Tìm kiếm tất cả các bộ đệm cho <pattern>.
  2. Search1 <pattern>: Tìm kiếm tất cả các bộ đệm cho <pattern>, nhưng chỉ hiển thị kết quả đầu tiên cho mỗi bộ đệm. Thông thường hữu ích để liệt kê tất cả các bộ đệm trong đó chức năng, biến foođược sử dụng, (hoặc những gì đã từng).

Sử dụng bang ( :Search! foo) để nối vào kết quả.

Ngoài ra GSearchGSearch1được thêm vào khi có sự khác biệt với Searchtập lệnh thêm dấu phân cách regex, ví dụ:

foo -> /foo/

Trường hợp như GSearchmong đợi nó được bao quanh.

Các jlá cờ luôn được bổ sung để ngăn chặn nhảy.


Mã số:

Có một số hack để ngăn chặn danh sách lỗi trong khi đồng thời giữ mã ngắn. try / catchlà một chút rườm rà trên bufdo.

let s:not_idents = split("/!#$%&\"`´¨'¯()*+,-.:;<=>?¿@[\]^{|}µ¶·¸~±×÷®©«»¬­ª°º¹²³¼½¾", '\zs')
" Create a delimited pattern. "
fun! s:Parse_pat(pat)
    for c in s:not_idents
        if stridx(a:pat, c) == -1
            return c . a:pat . c
        endif
    endfor
    echohl Error
    echom "Could not delimit pattern '". a:pat ."'"
    echohl None
    return ''
endfun

fun! s:AllBufSearch(pat, bang, uno, isg)
    if a:isg
        let pat = a:pat
    else
        let pat = s:Parse_pat(a:pat)
    endif
    if pat == ''
        return
    endif
    cclose
    let [_buf, _view] = [bufnr("%"), winsaveview()]
    let _foldenable = &foldenable
    set nofoldenable

    " Copy of current qflist. "
    let qfc = getqflist()
    " Hack to prevent error if no matches. "
    call setqflist([{}])
    silent execute "bufdo vimgrepadd! " . pat . "j %"
    " Restore "
    exec "buffer " . _buf
    let &foldenable = _foldenable
    call winrestview(_view)
    " Fix "
    let qf = getqflist()
    call remove(qf, 0)
    " Only one listing per buffer. "
    if a:uno
        let bn = {}
        let i  = 0
        for m in qf
            if has_key(bn, m["bufnr"])
                call remove(qf, i)
            else
                let bn[m["bufnr"]] = 1
                call remove(qf[i], "valid")
                let i += 1
            endif
        endfor
    endif
    if a:bang == "!"
        let qf = qfc + qf
    endif
    " If any matches, copen. "
    if len(qf)
        call setqflist(qf)
        copen
    endif
endfun

command! -nargs=1 -bang Search   call s:AllBufSearch(<q-args>, "<bang>", 0, 0)
command! -nargs=1 -bang Search1  call s:AllBufSearch(<q-args>, "<bang>", 1, 0)
command! -nargs=1 -bang GSearch  call s:AllBufSearch(<q-args>, "<bang>", 0, 1)
command! -nargs=1 -bang GSearch1 call s:AllBufSearch(<q-args>, "<bang>", 1, 1)
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.