augroup vimrc-selector autocmd! autocmd User SelectorChanged : augroup END function! s:cursor_changed() abort let old = get(s:, 'current', 'xyzzy') let new = getline('.') .. getcmdline() if old !=# new let s:current = new doautocmd User SelectorChanged endif endfunction function! selector#changed() abort if expand('') !=# '@' return endif let oldline = get(b:, 'oldline', "\") let newline = getcmdline() if oldline ==# newline return endif let b:oldline = newline let filtered = b:filter(getcmdline()) call deletebufline('%', 1, '$') call setbufline('%', 1, filtered) call cursor(1, 1) call s:cursor_changed() redraw endfunction function! s:down() abort let current = line('.') if current == line('$') let next = 1 else let next = current + 1 endif call cursor(next, 1) redraw call s:cursor_changed() return '' endfunction function! s:up() abort let current = line('.') if current == 1 let next = line('$') else let next = current - 1 endif call cursor(next, 1) redraw call s:cursor_changed() return '' endfunction function! selector#run(source, ...) abort let winid = win_getid() let rest = winrestcmd() botright 1new let filter_name = get(a:000, 0, 'exact') call selector#filter#{filter_name}#gather(a:source) let b:filter = function(printf('selector#filter#%s#filter', get(a:000, 0, 'exact'))) execute 'resize' &cmdwinheight setlocal buftype=nofile bufhidden=hide noswapfile cursorline autocmd CmdlineEnter,CmdlineChanged call selector#changed() cnoremap " vim cnoremap =down() cnoremap =up() " emacs cnoremap =down() cnoremap =up() " cursor cnoremap =down() cnoremap =up() try let result = input('> ') return getline('.') catch finally close call win_gotoid(winid) execute rest endtry endfunction