Как искать текущее слово во всех открытых вкладках в Vim?


16

Я начал изучать Vim слово-поиск , используя *и , #когда курсор находится над текущим словом. Но этот поиск ограничен текущим файловым буфером.

Есть ли команда или ярлык для расширения поиска:

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

1
Вы можете найти это объяснение вкладок против буферов интересным и полезным.
Wildcard

Ответы:


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перейти к следующему документу.
phyatt

7

На самом деле это поведение по умолчанию, хотя это может быть трудно заметить: попробуйте *затем перейти на другую вкладку и использовать nans Nв командном режиме для перехода вперед и назад между поисковыми попаданиями.

Это может иметь больше смысла, если сначала включить подсветку для всех попаданий:

:set hlsearch

1
+1 только из-за того, hlsearchчто я не знал, и что мне придется искать в тот или иной день :-). Однако по умолчанию я пробовал * #, n и N, и он не переходит на другие файловые буферы ...
Стефан Роллан

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

2
Весь смысл не в том, чтобы циклически перебирать вкладки, чтобы найти все совпадения.
Магнус

1
@Magnus Хотя это может быть предпочтительнее, на самом деле это явно не указано в вопросе, который спрашивает, как «расширить этот поиск до ... всех буферов» -> он распространяется на все буферы. Суть моего ответа состояла в том, чтобы прояснить это, поскольку это может быть не так, особенно если вы не hlsearchустановили.
Златовласка


1

Поскольку я часто делал это, я использовал (улучшенный) сценарий.

Вы или кто-то еще может найти это полезным.


Краткое объяснение:

По сути, он ищет список буферов и показывает результат в quickfix-окне.

Добавлены две основные команды.

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

Используйте bang ( :Search! foo) для добавления к результатам.

Кроме того , GSearchи GSearch1добавляется , где разница в том , что с Searchв скрипт добавления регулярных выражений разделителей, например:

foo -> /foo/

Где, как и GSearchожидалось, будет вложено.

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.