VimScript выполнить поиск больше не работает - PullRequest
1 голос
/ 06 июня 2019

С тех пор я не знаю, но моя функция поиска визуального выбора больше не работает. Я разбил проблему до этого минимального примера.

Предположим, следующий буфер:

word
word
word

Когда я запускаю /word, я нахожу все результаты и могу переключаться между ними.

Когда я запускаю :execute '/word', это работает так же, как и раньше.

Когда я пишу короткую функцию автозагрузки, просто делая то же самое, она не работает так же:

~/.config/nvim/autoload/utils/search.vim:

function! utils#search#visual_selection() abort
    execute '/word'
endfunction

Выполнение :call utils#search#visual_selection() делает курсор на первом результате, но результаты не подсвечиваются. Более того, он использует старый шаблон поиска вместо нового. Поэтому, если я сначала найду что-то несуществующее, например foo, а затем выполню эту функцию, нажав n, появится сообщение об ошибке Pattern not found: foo.

Что изменилось. В чем здесь разница?

1 Ответ

1 голос
/ 18 июля 2019

Это фактически задокументированное поведение Vim и NeoVim.На самом деле это не связано с использованием :execute (вы можете воспроизвести его с прямым использованием /word), но с тем, как поиск (и повтор) работает в функции.

См. :help function-search-undo, в котором говорится:

Последний использованный шаблон поиска и команда повторного выполнения "." не будут изменены функцией.Это также подразумевает, что эффект :nohlsearch отменяется при возврате функции.

Вы можете обойти это, явно установив регистр шаблона поиска , что можно сделать с помощьюa let команда.

function! utils#search#visual_selection()
    let @/ = 'word'
    execute "normal /\<cr>"
endfunction

Вторая команда выполняет простой / из обычного режима, которого достаточно для поиска слова, поскольку она будет искать последний шаблон поиска, который теперь установлен нато, что вы хотели.

После завершения функции шаблон поиска сохранит свое значение, что означает, что подсветка с помощью 'hlsearch' будет работать, и команда n найдет следующее совпадение.


Ограничением из вышеприведенного подхода является то, что вы не можете установить направление поиска для повторов с помощью n.Даже если есть значение v:searchforward, которое можно установить, эта переменная также сбрасывается после функции как часть эффектов :help function-search-undo.Похоже, с этим ничего нельзя поделать ...

Если цель этой функции - использовать ее в сопоставлении клавиш, вы можете рассмотреть совершенно другой подход, используя nnoremap <expr> иесли функция возвращает команду нормального режима поиска в виде строки, то фактический поиск происходит вне функции, и ограничения из function-search-undo не применяются.

Например:

function! utils#search#visual_selection(searchforward)
    let pattern = 'word'
    if a:searchforward
        let dir = '?'
    else
        let dir = '/'
    endif
    return dir.pattern."\<cr>"
endfunction

А затем:

" Mappings for next-word and previous-word
nnoremap <expr> <leader>nw utils#search#visual_selection(1)
nnoremap <expr> <leader>pw utils#search#visual_selection(0)

Это позволяет полностью избежать проблемы с :help function-search-undo, поэтому рассмотрим что-то подобное, если возможно, в вашем случае.

...