Created
July 28, 2011 15:31
-
-
Save anyakichi/1111755 to your computer and use it in GitHub Desktop.
history search plugin for vim
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" 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