As I suspected, this is possible. We use `complete_info()` to find the existing matches, ask the user to type his desired filter using `getchar()`, and replace the completions with `complete()`. One more subtlety is that we need to get the "startcol", that is, the start of the text being replaced, so that selecting the completions replaces that text, rather than appending to the end. We find this by `<C-n>` (to ensure some completion is selected), get the cursor position after the selection and finding the length of the selected completion by `complete_info()`, and compensating the `<C-n>` with a `<C-p>`. The "startcol" is the cursor position after selection minus the length of the selected completion. I mapped this to `<C-/>`/`<C-_>`. To use this, after getting a lot of completions (e.g. from `<C-n>` or `<C-x><C-i>`), invoke `<C-/>` and start typing to search for the completion you need. You will see your search at the bottom of the screen (like the usual search prompt). You can see the completions being filtered as you type. You can use all normal vim regex patterns here (like the `magic` mode). Press backspace to delete the last character or `<C-u>` to delete your whole search. Press `<C-/>` to accept this filter and begin another search. Press Enter to leave the search and go back to the completion. The usual completion bindings `<C-e>`, `<C-y>`, `<C-n>`, `<C-p>`, `<C-h>`, `<C-l>`, `<Up>`, `<Down>`, `<Esc>` also work, and automatically leave the completion search. function! Prepareearchpum () let g:compstartcol = col('.') let g:compinf = complete_info() if len(g:compinf.items) && (g:compinf.selected == -1) return "\<C-n>\<C-r>=Prepareearchpum()\<CR>\<C-p>" else return "" endif endfunction function! Searchpum () let words = [] for item in g:compinf.items call add(words, item.word) endfor let filter = "" if len(words) let startcol = g:compstartcol - len(g:compinf.items[g:compinf.selected].word) while 1 let matchwords = [] for word in words if word =~ filter call add (matchwords, word) endif endfor call complete(startcol, matchwords) echomsg filter try let char = getchar() catch /^Vim:Interrupt$/ return "\<C-c>" endtry if type(char) == 0 let char = nr2char(char) endif if char == "\<C-e>" return "\<C-e>" elseif char == "\<C-y>" return "\<C-y>" elseif char == "\<C-n>" return "\<C-n>" elseif char == "\<C-p>" return "\<C-p>" elseif char == "\<C-l>" return "\<C-l>" elseif char == "\<C-h>" return "\<C-h>" elseif char == "\<Up>" return "\<Up>" elseif char == "\<Down>" return "\<Down>" elseif char == "\<Esc>" return "\<Esc>" elseif char == "\<C-_>" call feedkeys ("\<C-_>") return "" elseif char == "\<CR>" return "" elseif char == "\<BS>" if len(filter) == 1 let filter = "" else let filter = filter[:len(filter) - 2] endif elseif char == "\<C-u>" let filter = "" else let filter = filter .. char endif endwhile endif endfunction inoremap <expr> <C-_> Prepareearchpum () . '<C-r>=Searchpum()<CR>'