我编写了一个函数,给定一个目录和标题,显示一个弹出窗口,其中包含该文件夹中包含的所有文件:
function! ListFiles(dir, title)
let l:dir = a:dir
let l:title = a:title
let l:files = glob(l:dir . '/*', 0, 1)
let l:file_list = []
for l:file in l:files
call add(l:file_list, fnamemodify(l:file, ':t'))
endfor
" Define custom highlight groups
highlight PopupMenu guifg=#ffffff guibg=#333333 ctermfg=white ctermbg=darkred
highlight PopupMenuSelected guifg=#000000 guibg=#ffff00 ctermfg=black ctermbg=yellow
" Create a popup menu with the file list
let l:selected_file = popup_menu(l:file_list, {
\ 'title': ' ' . l:title . ' ',
\ 'callback': 's:HandleFileSelection',
\ 'line': &lines / 2,
\ 'col': &columns / 2,
\ 'highlight': 'PopupMenu',
\ 'border': [],
\ 'close': 'click',
\ 'padding': [1, 2, 1, 2],
\ 'mapping': 0,
\ 'filter': 'popup_filter_menu',
\ 'wrap': 0
\ })
" Define a function to handle the selection
function! s:HandleFileSelection(id, result)
let l:file_name = ""
if a:result != -1
let l:file_name = getbufline(winbufnr(a:id), a:result)[0]
endif
echom "FOO.".l:selected_file
return l:file_name
endfunction
" Return file
echom "BAR.".l:selected_file
return l:selected_file
endfunction
但是,当我运行它时,我可以看到,一旦您在某个项目上按下回车键,在出现消息(带有选定的文件)BAR...
之前会显示该消息(带有数字) 。FOO...
因此看起来代码首先执行ListFiles
函数的返回,然后执行处理程序的返回。
为什么会发生这种情况?哪种方法可以仅获得所选项目的单个返回值?
嗯,这就是它的工作原理。无论调用
popup_menu
还是popup_dialog
,唯一的区别是由于filter
函数可以在popup_menu
仍处于活动状态时使用所有用户输入。但是,那里没有模态循环。该怎么办?立即返回并在回调函数内部继续执行。