🥽
Vim scriptでNeovimのvim.ui.selectっぽいセレクトを作る
Neovimの標準のvim.ui.select()
っぽいセレクトメニューを出力するVim scriptをかきました。
utils.vim
function! utils#select(items, opts, on_choice) abort
let prompt = get(a:opts, 'prompt', 'Select one of:')
let s:format_item = get(a:opts, 'format_item', {item->item})
let items = map(a:items[:], {idx,item-> (idx + 1) .. ': ' .. s:format_item(item)})
let choice = inputlist(insert(items, prompt))
if choice > 0 && choice <= len(a:items)
call a:on_choice(a:items[choice-1], choice)
else
call a:on_choice(v:null, v:null)
endif
endfunction
function! utils#handler(item, idx) abort
# process item and idx
echo a:item a:idx
endfunction
以下の2つが同じような結果になります。
lua vim.ui.select({'Fire', 'Air', 'Water', 'Earth'}, {}, vim.fn['utils#handler'])
call utils#select(['Fire', 'Air', 'Water', 'Earth'], {}, function('utils#handler'))
即時関数を使うならこんな感じ。
lua vim.ui.select({'Fire', 'Air', 'Water', 'Earth'}, {}, function(item,idx) if idx then vim.api.nvim_echo({{item}}, nil, {}) end end)
call utils#select(['Fire', 'Air', 'Water', 'Earth'], {}, {item,idx->idx != v:null ? execute('echo "' .. item .. '"', '') : ''})
オプションを使うならこんな感じです。
lua vim.ui.select({'Fire', 'Air', 'Water', 'Earth'}, { prompt = 'Select Element:', format_item = function(item) return 'The ' .. item end }, vim.fn['utils#handler'])
call utils#select(['Fire', 'Air', 'Water', 'Earth'], { 'prompt': 'Select Element:', 'format_item': {item->'The ' .. item} }, function('utils#handler'))
vim.ui.select
はdressing.nvimなど外部プラグインで拡張できるのが強みなので、Vim scriptで模倣しても同じものができるわけではないのですが、何かの参考になれば。
Discussion