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>'