Как запросить у пользователя несколько записей в списке?
Я работаю над плагином vim. Существует множество допустимых опций для параметра конфигурации. Я бы хотел, чтобы пользователь мог выбирать нужные параметры из списка.
Это похоже на inputlist
, но inputlist
возвращает только индекс одного выбранного элемента. Я бы предпочел, чтобы он возвращал индексы всех выбранных элементов.
Как бы я создал мутлиселект в vim?
2 ответа
Я не знаю точно, какой интерфейс вы имеете в виду, но так как вы упомянули inputlist()
Я думал, что вы могли бы просто написать цикл, тело которого будет вызывать его.
Может быть, что-то вроде этого:
let options_chosen = []
let options_valid = [
\ 'foo',
\ 'bar',
\ 'baz',
\ 'qux',
\ 'norf'
\ ]
for i in range(1,len(options_valid))
let choice = inputlist([ 'Select your options:' ]
\ + map(copy(options_valid), '(v:key+1).". ".v:val'))
if choice >= 1 && choice <= len(copy(options_valid))
let options_chosen += [copy(options_valid)[choice - 1]]
let options_valid = filter(options_valid, 'v:val !=# options_chosen[-1]')
else
break
endif
redraw
endfor
Если вы выполните этот код, он должен позволить вам выбрать вариант из списка options_valid
, После каждой итерации следует добавить выбранный элемент в список options_chosen
и удалите его из списка options_valid
, Цикл повторяется столько раз, сколько элементов в options_valid
первоначально. Когда вы закончите, вы можете остановить цикл, нажав Escape
,
Это может быть не то, что вы хотите, потому что я не знаю, какой интерфейс вы хотите представить пользователю: команду, отображение, интерактивный буфер... Но это может быть началом, на котором вы могли бы построить что-то еще,
С интерактивным буфером в качестве интерфейса я придумал это:
let s:options_valid = ['foo', 'bar', 'baz', 'qux', 'norf']
com! MultipleOptions call s:multiple_options()
fu! s:multiple_options() abort
vnew | exe 'vert resize '.(&columns/3)
setl bh=wipe bt=nofile nobl noswf nowrap
if !bufexists('Multiple Options') | sil file Multiple\ Options | endif
sil! 0put =s:options_valid
sil! $d_
setl noma ro
nno <silent> <buffer> <nowait> q :<c-u>close<cr>
nno <silent> <buffer> <nowait> <cr> :<c-u>call <sid>toggle_option()<cr>
augroup multi_op_close
au!
au WinLeave <buffer> call s:close()
augroup END
endfu
fu! s:close() abort
let g:selected_options = exists('w:options_chosen')
\ ? map(w:options_chosen.lines, 's:options_valid[v:val-1]')
\ : []
au! multi_op_close | aug! multi_op_close
close
endfu
fu! s:toggle_option() abort
if !exists('w:options_chosen')
let w:options_chosen = { 'lines' : [], 'pattern' : '', 'id' : 0 }
else
if w:options_chosen.id
call matchdelete(w:options_chosen.id)
let w:options_chosen.pattern .= '|'
endif
endif
if !empty(w:options_chosen.lines) && count(w:options_chosen.lines, line('.'))
call filter(w:options_chosen.lines, "v:val != line('.')")
else
let w:options_chosen.lines += [ line('.') ]
endif
let w:options_chosen.pattern = '\v'.join(map(
\ copy(w:options_chosen.lines),
\ "'%'.v:val.'l'"
\ ), '|')
let w:options_chosen.id = !empty(w:options_chosen.lines)
\ ? matchadd('IncSearch', w:options_chosen.pattern)
\ : 0
endfu
Если вы выполните команду :MultipleOptions
, он должен открыть временный вертикальный видовой экран, в котором параметры хранятся внутри списка s:options_valid
должен отображаться.
Оттуда вы можете нажать Enter
выбрать или отменить выбор текущей строки. Когда опция выбрана, ее линия окрашивается группой выделения IncSearch
,
Когда вы закончите, вы можете закрыть окно, нажав q
и все выбранные вами варианты должны быть внутри g:selected_options
,
В lh-vim-lib я предоставляю lh#ui#check()
функция, которая делает именно это. Его поведение похоже на confirm()
в текстовом режиме. т.е. я полагаюсь на старый трюк, который взламывает статусную строку. (Это нужно играть с "\r"
, :redraw
и так далее)
Вы можете увидеть это в прямом эфире на экране, который я сделал для lh-тегов. Ждите "Какие виды вы хотите отобразить?" вопрос. (В скриншоте вы должны увидеть старый код с CHECK
, CONFIRM
а также CHOOSE
)
Кстати, диалог, используемый в lh-тэгах для выбора одной записи, также может быть использован (с tagged
параметр установлен на один), чтобы выбрать несколько записей одновременно.