Як шукати поточне слово на всіх відкритих вкладках у Vim?


16

Я почав вивчати пошук слова Vim за допомогою *та, #поки курсор перебуває над поточним словом. Але цей пошук обмежений поточним буфером файлів.

Чи є команда чи ярлик для розширення цього пошуку на:

  1. усі відкриті вкладки?
  2. всі відкриті буфери?


Відповіді:


4

Я не маю точного рішення для вашої проблеми, сподіваюся, кращої відповіді, ніж моя, прийде. Але саме так я вирішив проблему пошуку слова у всіх буферах.

" 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

Перший рядок створює команду Searchіз шаблоном пошуку як аргументом, який записує результати у список швидких виправлень. Два інші рядки відображають (принаймні для мене) марні стрілки на щось корисне; вони відображаються для переходу до наступного / попереднього пошуку або до наступної / попередньої помилки компіляції тощо. Вони просто переходять через список швидких виправлень. Ви можете використовувати це наступним чином:

:Search foobar
<right>
<right>
…

Я люблю цю команду, але додав декілька речей, щоб вона краще уникала пошукових термінів і примушувала перемальовувати. (використання мовчання з розщепленнями може спричинити помилку vim ui). командувати! -nargs = 1 Пошук викликів setqflist ([]) | тихо виконайте "bufdo grepadd! '<args>'%" | перемалювати!
Ігоріо

ви також можете просто ввести :cnабо :cpперейти до наступного документа.
фіат

7

Це насправді поведінка за замовчуванням, хоча це може бути важко помітити: спробуйте *перейти на іншу вкладку і скористайтеся nans Nв командному режимі, щоб перейти вперед і назад між пошуковими хітами.

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

:set hlsearch

1
+1 лише через hlsearchте, що я не знав, і який би я шукав у той чи інший день :-). Однак за замовчуванням я спробував * #, n і N, і він не переходить на інші файлові буфери ...
Stephane Rolland

Ні, nі Nне стрибайте буфери (вони обертаються), але термін, на який вони націлені, шукається на всіх вкладках; натисніть *на підсвічування, а потім перейдіть по вкладках - всі вони будуть виділятися одним і тим же терміном, тому ви можете користуватися nі Nлокально там без нового пошуку.
золотинки

2
Вся справа в тому, що НЕ доведеться перебирати свої вкладки, щоб знайти всі збіги.
Магнус

1
@Magnus Хоча це може бути кращим, насправді це прямо не вказано у запитанні, яке запитує, як "розширити цей пошук на ... всі буфери" -> він розширюється на всі буфери. Суть моєї відповіді полягала в тому, щоб зробити це зрозумілим, оскільки це може бути не особливо, особливо якщо ви цього не hlsearchвстановили.
goldilocks


1

Оскільки я часто робив це, я розім'яв (неймовірно) сценарій.

Ви чи хтось інший може вважати це корисним


Коротке пояснення:

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

Додано дві основні команди.

  1. Search <pattern> : Пошук у всіх буферах <pattern> .
  2. Search1 <pattern>: Пошук у всіх буферах <pattern>, але показуйте лише перший результат для кожного буфера. Зазвичай корисно для перерахування всіх буферів, де функціонує, зміннаfoo (або що раніше).

Використовуйте чубок (:Search! foo ), щоб додати результати.

Крім того , GSearchі GSearch1додається , де різниця в тому , що з Searchв скрипт додавання регулярних виразів роздільників, наприклад:

foo -> /foo/

Де як GSearch очікують, вона буде закрита.

The jПрапор завжди додається , щоб запобігти стрибок.


Код:

Існує декілька хак, які запобігають переліку помилок, одночасно утримуючи короткий код. try / catchбув трохи громіздкий на 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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.