Skip to content

Instantly share code, notes, and snippets.

@anyakichi
Created July 28, 2011 15:31
Show Gist options
  • Save anyakichi/1111755 to your computer and use it in GitHub Desktop.
Save anyakichi/1111755 to your computer and use it in GitHub Desktop.
history search plugin for vim
" History search plugin
if exists("g:loaded_histsearch")
finish
endif
let g:loaded_histsearch = 1
let s:cpo_save = &cpo
set cpo&vim
augroup HistSearch
autocmd CmdWinEnter [:/\?] call s:histsearch_setup(expand('<afile>'))
augroup END
nnoremap <expr> q; 'q:i' . <SID>histsearch_start()
nnoremap <expr> q' 'q/i' . <SID>histsearch_start()
nnoremap <expr> q" 'q?i' . <SID>histsearch_start()
let s:histsearch_prefix = "(*history-search*)"
function! HistSearch(findstart, base)
if a:findstart
let b:histsearch_end = col('.')
return 0
else
if !exists('b:histsearch_history')
call histdel(b:histsearch_mode, '^\V' . s:histsearch_prefix)
let b:histsearch_history = s:histsearch_history(b:histsearch_mode)
endif
let res = copy(b:histsearch_history)
let base = a:base
let base = substitute(base, '^\V' . s:histsearch_prefix , '', '')
let base = substitute(base, '*', '.*', 'g')
let base = substitute(base, '?', '.', 'g')
let base = escape(base, '"')
call filter(res, 'v:val =~? "' . base . '"')
let b:histsearch_empty = empty(res)
return res
endif
endfun
function! s:histsearch_setup(mode)
setlocal completefunc=HistSearch
let b:histsearch_mode = a:mode == '?' ? '/' : a:mode
nnoremap <silent> <buffer> <Esc><Esc> :<C-u>quit<CR>
inoremap <buffer> <expr> <CR> <SID>histsearch_enter("\<CR>")
inoremap <buffer> <expr> <C-j> pumvisible() ? "\<Down>" : "\<C-j>"
inoremap <buffer> <expr> <C-k> pumvisible() ? "\<Up>" :
\ <SID>histsearch_start()
inoremap <buffer> <expr> <C-e> <SID>histsearch_end("\<C-e>")
autocmd! * <buffer>
autocmd CursorMovedI <buffer> call s:histsearch_feedkeys()
endfunction
function! s:histsearch_start0()
let up = "\<C-r>=pumvisible() ? \"\\<Up>\" : ''\<CR>"
return "\<C-x>\<C-u>\<C-p>\<C-p>\<C-n>" . up
endfunction
function! s:histsearch_start()
let prefix = "\<Home>" . s:histsearch_prefix . "\<End>"
return prefix . s:histsearch_start0()
endfunction
function! s:histsearch_end0()
let n = strlen(s:histsearch_prefix)
return "\<Home>" . repeat("\<Del>", n) . "\<End>"
endfunction
function! s:histsearch_end(fallback)
let curline = getline('.')
if curline =~# '^\V' . s:histsearch_prefix
let end = pumvisible() ? "\<C-e>" : ""
return end . s:histsearch_end0()
endif
return a:fallback
endfunction
function! s:histsearch_enter(fallback)
let curline = getline('.')
if curline =~# '^\V' . s:histsearch_prefix
if pumvisible()
return "\<C-y>\<CR>"
endif
return s:histsearch_end0() . "\<CR>"
endif
return a:fallback
endfunction
function! s:histsearch_feedkeys()
let curline = getline('.')
if curline =~# '^\V' . s:histsearch_prefix &&
\ (!b:histsearch_empty || b:histsearch_end != col('.'))
call feedkeys(s:histsearch_start0(), "n")
elseif curline ==# s:histsearch_prefix[:-2]
call feedkeys("\<End>\<C-u>")
endif
endfunction
function! s:histsearch_history(type)
let histlist = []
let histdic = {}
for i in range(histnr(a:type), 1, -1)
let item = histget(a:type, i)
if item != "" && !has_key(histdic, item)
let histdic[item] = 1
call insert(histlist, item)
endif
endfor
return histlist
endfunction
let &cpo = s:cpo_save
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment