1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-02-15 23:39:27 +08:00
SpaceVim/bundle/incsearch.vim/autoload/incsearch/over/modules/incsearch.vim
Wang Shidong cd6ea298f2
fix java neoformat config
* Add incsearch.vim into bundle dir

* Fix java neoformat config

close #3573

* Use echom instead in pull.vim
2020-06-13 21:58:05 +08:00

296 lines
10 KiB
VimL

"=============================================================================
" FILE: autoload/incsearch/over/modules/incsearch.vim
" AUTHOR: haya14busa
" License: MIT license
"=============================================================================
scriptencoding utf-8
let s:save_cpo = &cpo
set cpo&vim
let s:TRUE = !0
let s:FALSE = 0
let s:DIRECTION = { 'forward': 1, 'backward': 0 } " see :h v:searchforward
let s:hi = g:incsearch#highlight#_hi
let s:U = incsearch#util#import()
let s:inc = {
\ 'name' : 'incsearch',
\}
" NOTE: for InsertRegister handling
function! s:inc.priority(event) abort
return a:event is# 'on_char' ? 10 : 0
endfunction
function! s:inc.on_enter(cmdline) abort
nohlsearch " disable previous highlight
let a:cmdline._w = winsaveview()
let hgm = incsearch#highlight#hgm()
let c = hgm.cursor
call s:hi.add(c.group, c.group, '\%#', c.priority)
call incsearch#highlight#update()
" XXX: Manipulate search history for magic option
" In the first place, I want to omit magic flag when histadd(), but
" when returning cmd as expr mapping and feedkeys() cannot handle it, so
" remove no user intended magic flag at on_enter.
" Maybe I can also handle it with autocmd, should I use autocmd instead?
let hist = histget('/', -1)
if len(hist) > 2 && hist[:1] ==# incsearch#magic()
call histdel('/', -1)
call histadd('/', hist[2:])
endif
endfunction
function! s:inc.on_leave(cmdline) abort
call s:hi.disable_all()
call s:hi.delete_all()
" redraw: hide pseud-cursor
redraw " need to redraw for handling non-<expr> mappings
if a:cmdline.getline() ==# ''
echo ''
else
echo a:cmdline.get_prompt() . a:cmdline.getline()
endif
" NOTE:
" push rest of keymappings with feedkeys()
" FIXME: assume 'noremap' but it should take care wheter or not the
" mappings should be remapped or not
if a:cmdline.input_key_stack_string() !=# ''
call feedkeys(a:cmdline.input_key_stack_string(), 'n')
endif
endfunction
" Avoid search-related error while incremental searching
function! s:on_searching(func, ...) abort
try
return call(a:func, a:000)
catch /E16:/ " E16: Invalid range (with /\_[a- )
catch /E33:/ " E33: No previous substitute regular expression
catch /E53:/ " E53: Unmatched %(
catch /E54:/
catch /E55:/
catch /E62:/ " E62: Nested \= (with /a\=\=)
catch /E63:/ " E63: invalid use of \_
catch /E64:/ " E64: \@ follows nothing
catch /E65:/ " E65: Illegal back reference
catch /E66:/ " E66: \z( not allowed here
catch /E67:/ " E67: \z1 et al. not allowed here
catch /E68:/ " E68: Invalid character after \z (with /\za & re=1)
catch /E69:/ " E69: Missing ] after \%[
catch /E70:/ " E70: Empty \%[]
catch /E71:/ " E71: Invalid character after \%
catch /E554:/
catch /E678:/ " E678: Invalid character after \%[dxouU]
catch /E864:/ " E864: \%#= can only be followed by 0, 1, or 2. The
" automatic engine will be used
catch /E865:/ " E865: (NFA) Regexp end encountered prematurely
catch /E866:/ " E866: (NFA regexp) Misplaced @
catch /E867:/ " E867: (NFA) Unknown operator
catch /E869:/ " E869: (NFA) Unknown operator '\@m
catch /E870:/ " E870: (NFA regexp) Error reading repetition limits
catch /E871:/ " E871: (NFA regexp) Can't have a multi follow a multi !
catch /E874:/ " E874: (NFA) Could not pop the stack ! (with \&)
catch /E877:/ " E877: (NFA regexp) Invalid character class: 109
catch /E888:/ " E888: (NFA regexp) cannot repeat (with /\ze*)
call s:hi.disable_all()
catch
echohl ErrorMsg | echom v:throwpoint . ' ' . v:exception | echohl None
endtry
endfunction
function! s:on_char_pre(cmdline) abort
" NOTE:
" `:call a:cmdline.setchar('')` as soon as possible!
let [raw_pattern, offset] = a:cmdline._parse_pattern()
let pattern = a:cmdline._convert(raw_pattern)
" Interactive :h last-pattern if pattern is empty
if ( a:cmdline.is_input('<Over>(incsearch-next)')
\ || a:cmdline.is_input('<Over>(incsearch-prev)')
\ ) && empty(pattern)
call a:cmdline.setchar('')
" Use history instead of @/ to work with magic option and converter
call a:cmdline.setline(histget('/', -1) . (empty(offset) ? '' : a:cmdline._base_key) . offset)
" Just insert last-pattern and do not count up, but the incsearch-prev
" should move the cursor to reversed directly, so do not return if the
" command is prev
if a:cmdline.is_input('<Over>(incsearch-next)') | return | endif
endif
if a:cmdline.is_input('<Over>(incsearch-next)')
call a:cmdline.setchar('')
if a:cmdline._flag ==# 'n' " exit stay mode
let a:cmdline._flag = ''
else
let a:cmdline._vcount1 += 1
endif
elseif a:cmdline.is_input('<Over>(incsearch-prev)')
call a:cmdline.setchar('')
if a:cmdline._flag ==# 'n' " exit stay mode
let a:cmdline._flag = ''
endif
let a:cmdline._vcount1 -= 1
elseif (a:cmdline.is_input('<Over>(incsearch-scroll-f)')
\ && (a:cmdline._flag ==# '' || a:cmdline._flag ==# 'n'))
\ || (a:cmdline.is_input('<Over>(incsearch-scroll-b)') && a:cmdline._flag ==# 'b')
call a:cmdline.setchar('')
if a:cmdline._flag ==# 'n' | let a:cmdline._flag = '' | endif
let pos_expr = a:cmdline.is_input('<Over>(incsearch-scroll-f)') ? 'w$' : 'w0'
let to_col = a:cmdline.is_input('<Over>(incsearch-scroll-f)')
\ ? s:U.get_max_col(pos_expr) : 1
let [from, to] = [getpos('.')[1:2], [line(pos_expr), to_col]]
let cnt = s:U.count_pattern(pattern, from, to)
let a:cmdline._vcount1 += cnt
elseif (a:cmdline.is_input('<Over>(incsearch-scroll-b)')
\ && (a:cmdline._flag ==# '' || a:cmdline._flag ==# 'n'))
\ || (a:cmdline.is_input('<Over>(incsearch-scroll-f)') && a:cmdline._flag ==# 'b')
call a:cmdline.setchar('')
if a:cmdline._flag ==# 'n'
let a:cmdline._flag = ''
let a:cmdline._vcount1 -= 1
endif
let pos_expr = a:cmdline.is_input('<Over>(incsearch-scroll-f)') ? 'w$' : 'w0'
let to_col = a:cmdline.is_input('<Over>(incsearch-scroll-f)')
\ ? s:U.get_max_col(pos_expr) : 1
let [from, to] = [getpos('.')[1:2], [line(pos_expr), to_col]]
let cnt = s:U.count_pattern(pattern, from, to)
let a:cmdline._vcount1 -= cnt
endif
" Handle nowrapscan:
" if you `:set nowrapscan`, you can't move to the reversed direction
if !&wrapscan && (
\ a:cmdline.is_input('<Over>(incsearch-next)')
\ || a:cmdline.is_input('<Over>(incsearch-prev)')
\ || a:cmdline.is_input('<Over>(incsearch-scroll-f)')
\ || a:cmdline.is_input('<Over>(incsearch-scroll-b)')
\ )
if a:cmdline._vcount1 < 1
let a:cmdline._vcount1 = 1
else
call a:cmdline.setchar('')
let [from, to] = [[a:cmdline._w.lnum, a:cmdline._w.col + 1],
\ a:cmdline._flag !=# 'b'
\ ? [line('$'), s:U.get_max_col('$')]
\ : [1, 1]
\ ]
let max_cnt = s:U.count_pattern(pattern, from, to, s:TRUE)
let a:cmdline._vcount1 = min([max_cnt, a:cmdline._vcount1])
endif
endif
if &wrapscan && a:cmdline._vcount1 < 1
let a:cmdline._vcount1 += s:U.count_pattern(pattern)
endif
endfunction
function! s:on_char(cmdline) abort
if a:cmdline._does_exit_from_incsearch
return
endif
let [raw_pattern, offset] = a:cmdline._parse_pattern()
if raw_pattern ==# ''
call s:hi.disable_all()
nohlsearch
return
endif
" For InsertRegister
if a:cmdline.get_tap_key() ==# "\<C-r>"
let p = a:cmdline.getpos()
" Remove `"`
let raw_pattern = raw_pattern[:p-1] . raw_pattern[p+1:]
let w = winsaveview()
call cursor(line('.'), col('.') + len(a:cmdline.backward_word()))
call a:cmdline.get_module('InsertRegister').reset()
call winrestview(w)
endif
let pattern = a:cmdline._convert(raw_pattern)
" Improved Incremental cursor move!
call s:move_cursor(a:cmdline, pattern, offset)
" Improved Incremental highlighing!
" case: because matchadd() doesn't handle 'ignorecase' nor 'smartcase'
let case = incsearch#detect_case(raw_pattern)
let should_separate = g:incsearch#separate_highlight && a:cmdline._flag !=# 'n'
let pattern_for_hi =
\ (a:cmdline._flag is# 'b' ? s:unescape_question_for_backward(pattern) : pattern)
\ . case
call incsearch#highlight#incremental_highlight(
\ pattern_for_hi,
\ should_separate,
\ a:cmdline._direction,
\ [a:cmdline._w.lnum, a:cmdline._w.col])
" functional `normal! zz` after scroll for <expr> mappings
if ( a:cmdline.is_input('<Over>(incsearch-scroll-f)')
\ || a:cmdline.is_input('<Over>(incsearch-scroll-b)'))
call winrestview({'topline': max([1, line('.') - winheight(0) / 2])})
endif
endfunction
" Caveat: It handle :h last-pattern, so be careful if you want to pass empty
" string as a pattern
function! s:move_cursor(cli, pattern, ...) abort
let offset = get(a:, 1, '')
if a:cli._flag ==# 'n' " skip if stay mode
return
endif
call winrestview(a:cli._w)
" pseud-move cursor position: this is restored afterward if called by
" <expr> mappings
if a:cli._is_expr
for _ in range(a:cli._vcount1)
" NOTE: This cannot handle {offset} for cursor position
call search(a:pattern, a:cli._flag)
endfor
else
" More precise cursor position while searching
" Caveat:
" This block contains `normal`, please make sure <expr> mappings
" doesn't reach this block
let is_visual_mode = s:U.is_visual(mode(1))
let cmd = incsearch#with_ignore_foldopen(
\ s:U.dictfunction(a:cli._build_search_cmd, a:cli),
\ a:cli._combine_pattern(a:pattern, offset), 'n')
" NOTE:
" :silent!
" Shut up errors! because this is just for the cursor emulation
" while searching
silent! call incsearch#execute_search(cmd)
if is_visual_mode
let w = winsaveview()
normal! gv
call winrestview(w)
call incsearch#highlight#emulate_visual_highlight()
endif
endif
endfunction
function! s:inc.on_char_pre(cmdline) abort
call s:on_searching(function('s:on_char_pre'), a:cmdline)
endfunction
function! s:inc.on_char(cmdline) abort
call s:on_searching(function('s:on_char'), a:cmdline)
endfunction
function! s:unescape_question_for_backward(pattern) abort
return substitute(a:pattern, '\\?', '?', 'g')
endfunction
function! incsearch#over#modules#incsearch#make() abort
return deepcopy(s:inc)
endfunction
let &cpo = s:save_cpo
unlet s:save_cpo
" __END__
" vim: expandtab softtabstop=2 shiftwidth=2 foldmethod=marker