Подтвердить что ты не робот

ViM: поиск и выделение, но не прыгать

Кнопка super star (*) в ViM будет искать слово под курсором и перейти к следующему совпадению. Пользователь может перейти к следующим совпадениям с помощью клавиши n. Если hlsearch включен, он также выделит совпадения.

Я хочу иметь возможность нажимать * и получать выделенные совпадения и иметь возможность перемещаться по совпадениям с помощью клавиши n. Тем не менее, я не хочу, чтобы ViM перешел к следующему совпадению при нажатии *, он должен оставаться на текущем слове. Есть ли способ сделать это?

4b9b3361

Ответ 1

Я бы отобразил:

nnoremap * *``

Работает точно так, как вы хотите, за исключением того, что добавляет прыжок в списке прыжков. Чтобы это не нужно:

nnoremap * :keepjumps normal *``<cr>

Ответ 2

Лучшее решение:

  • не добавляйте переход к списку переходов
  • поведение звездочки не изменяется

Итак, попробуйте плагин: http://www.vim.org/scripts/script.php?script_id=4335

Гораздо лучше, чем:

" a jump adds to the jump list
nnoremap * *``
" I got a dead loop on macvim
nnoremap * :keepjumps normal *``<cr>
" the behavior is changed
nnoremap <silent> <Leader>* :let @/='\<<C-R>=expand("<cword>")<CR>\>'<CR>:set hls<CR>

Ответ 3

У меня есть следующее в моем .vimrc, которое, я думаю, работает лучше, чем другие альтернативы:

" Put word under cursor into search register and highlight
nnoremap <silent> <Leader>* :let @/='\<<C-R>=expand("<cword>")<CR>\>'<CR>:set hls<CR>
vnoremap <silent> <Leader>* :<C-U>
  \let old_reg=getreg('"')<Bar>let old_regtype=getregtype('"')<CR>
  \gvy:let @/=substitute(
  \escape(@", '/\.*$^~['), '\_s\+', '\\_s\\+', 'g')<CR>
  \gV:call setreg('"', old_reg, old_regtype)<CR>:set hls<CR>

Ответ 4

Если вы хотите сохранить текущее представление и добавить поиск в историю, попробуйте это [не очень эффективное] решение:

noremap * msHmt`s*`tzt`s

Используются метки s (save) и t (вверху).

Ответ 5

Мне пришло в голову простое решение: поместите map * *# в .vimrc файл (он будет мигать, хотя).

Ответ 6

Я еще не видел этого:

nmap <silent> * "syiw<Esc>: let @/ = @s<CR>

Он очень короткий и не включает прыжки вокруг, что может привести к миганию.

Объяснение: скопируйте слово под курсором в регистр s, а затем установите регистр поиска (/) в содержимое регистра s. Регистр поиска не может быть записан напрямую, поэтому необходимо использовать let и, следовательно, silent сохранить чистую командную строку vim.

Ответ 7

Я обнаружил, что это работает довольно хорошо, нет мерцания и не требуется промежуточный регистр.

nnoremap <silent> * :let @/= '\<' . expand('<cword>') . '\>' <bar> set hls <cr>

Или, если вы хотите поведение g*:

nnoremap <silent> g* :let @/=expand('<cword>') <bar> set hls <cr>

Ответ 8

Многие ответы здесь описывают довольно простые сопоставления, которые хорошо работают в обычных случаях, но могут иметь побочные эффекты (например, мерцание при переходе назад и вперед) или не иметь устойчивости (могут сломаться, если некоторые символы регулярного выражения определены как символы ключевых слов).

Если вы ищете надежную реализацию и не возражаете против установки плагина, вы можете выбрать из множества альтернатив, многие из которых также предлагают дополнительные улучшения, связанные с поиском:

  • Мой плагин SearchHighlighting изменяет команду *, расширяет ее до визуальных выделений и предлагает опциональный автоматический поиск слова под курсором.
  • поиск по звездам изменяет поведение * чтобы не переходить к следующему совпадению, и включает визуальный поиск из следующего плагина
  • vim-visual-star-search обеспечивает поиск визуального выбора
  • visualstar.vim обеспечивает поиск визуального выбора
  • select & search может использовать n/N или * в визуальном выборе и может избежать прыжков.
  • vim-asterisk предоставляет отображение z* которое также не прыгает, визуальное *, более интуитивно понятное управление смарт-регистром и может сохранять позицию курсора при прыжке (например ,*)
  • searchant.vim подключается к встроенным командам поиска и предоставляет отдельную подсветку для последнего найденного совпадения.

Ответ 9

Другие ответы здесь хороши, особенно @rodrigo, но я хотел написать решение, которое сохраняет положение прокрутки и делает это, не затрагивая ни одну из меток.

Это работает для меня:

function! StarPositionSave()
  let g:star_position_cursor = getpos('.')
  normal! H
  let g:star_position_top = getpos('.')
  call setpos('.', g:star_position_cursor)
endfunction
function! StarPositionRestore()
  call setpos('.', g:star_position_top)
  normal! zt
  call setpos('.', g:star_position_cursor)
endfunction
nnoremap <silent> * :call StarPositionSave()<CR>*:call StarPositionRestore()<CR>

Выкладываю normal! * normal! * в функции напрямую не работает, так как (по крайней мере, в neovim) она подавляет подсветку поиска от срабатывания (как будто :nohlsearch был запущен).

Ответ 10

Мое решение:

nnoremap <silent><expr> * v:count ? '*'
      \ : ':execute "keepjumps normal! *" <Bar> call winrestview(' . string(winsaveview()) . ')<CR>'
nnoremap <silent><expr> g* v:count ? 'g*'
      \ : ':execute "keepjumps normal! g*" <Bar> call winrestview(' . string(winsaveview()) . ')<CR>'

Плюсы:

  • Нет мерцания.
  • Список переходов остается без изменений.
  • Если указано количество, оно действует как оригинал *.
  • Он не использует отметки или регистры.
  • При использовании фактического * его поведение практически идентично * (за исключением прыжков).
  • Не требует установки плагинов.

Ответ 11

Аналогично * у нас есть

[I ..................... it shows where the word under the cursor appears

У меня также есть несколько полезных строк на моем vimrc, которые могут, возможно, помочь вам

" When double click a word vim will hightlight all other ocurences
" see CountWordFunction()
" [I shows lines with word under the cursor
nnoremap <silent> <2-LeftMouse> :let @/='\V\<'.escape(expand('<cword>'), '\').'\>'<cr>:set hls<cr>:CountWord<cr>
nnoremap <Leader>* :let @/='\V\<'.escape(expand('<cword>'), '\').'\>'<cr>:set hls<cr>:CountWord<cr>

if !exists('*CountWordFunction')
    fun! CountWordFunction()
        try
            let l:win_view = winsaveview()
            exec "%s/" . expand("<cword>") . "//gn"
        finally
            call winrestview(l:win_view)
        endtry
    endfun
endif

command! -nargs=0 CountWord :call CountWordFunction()
cnoreabbrev cw CountWord
nnoremap <F3> :CountWord<CR>