Skip to content

Commit e988b9e

Browse files
committed
Display full board and programmer names in the chooser UI
1 parent cefbe60 commit e988b9e

File tree

1 file changed

+93
-31
lines changed

1 file changed

+93
-31
lines changed

autoload/arduino.vim

Lines changed: 93 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -232,10 +232,13 @@ function! arduino#GetBoards() abort
232232
if g:arduino_use_cli
233233
let boards_data = s:get_json_output('arduino-cli board listall --format json')
234234
for board in boards_data['boards']
235-
let boardname = board['fqbn']
236-
call add(boards, boardname)
235+
call add(boards, {
236+
\ 'label': board['name'],
237+
\ 'value': board['fqbn']
238+
\ })
237239
endfor
238240
else
241+
let seen = {}
239242
for [dir,meta] in items(s:hardware_dirs)
240243
if !isdirectory(dir)
241244
continue
@@ -252,15 +255,19 @@ function! arduino#GetBoards() abort
252255
let linesplit = split(line, '=')
253256
let name = linesplit[1]
254257
let board = meta.package . ':' . meta.arch . ':' . board
255-
if index(boards, board) == -1
256-
call add(boards, board)
258+
if index(boards, board) == -1 && !has_key(seen, board)
259+
let seen[board] = 1
260+
call add(boards, {
261+
\ 'label': name,
262+
\ 'value': board
263+
\ })
257264
endif
258265
endif
259266
endfor
260267
unlet dir meta
261268
endfor
262269
endif
263-
call sort(boards, 's:BoardOrder')
270+
call sort(boards, 's:ChooserItemOrder')
264271
return boards
265272
endfunction
266273

@@ -275,7 +282,10 @@ function! arduino#GetBoardOptions(board) abort
275282
for opt in opts
276283
let values = []
277284
for entry in opt['values']
278-
call add(values, entry['value'])
285+
call add(values, {
286+
\ 'label': entry['value_label'],
287+
\ 'value': entry['value']
288+
\ })
279289
endfor
280290
let ret[opt['option']] = values
281291
endfor
@@ -328,11 +338,14 @@ function! arduino#GetProgrammers() abort
328338
if g:arduino_use_cli
329339
let data = s:get_json_output('arduino-cli board details ' . g:arduino_board . ' --list-programmers --format json')
330340
for entry in data['programmers']
331-
call add(programmers, entry['id'])
341+
call add(programmers, {
342+
\ 'label': entry['name'],
343+
\ 'value': entry['id'],
344+
\ })
332345
endfor
333346
" I'm running into some issues with 3rd party boards (e.g. adafruit:avr:gemma) where the programmer list is empty. If so, fall back to the hardware directory method
334347
if !empty(programmers)
335-
return sort(programmers)
348+
return sort(programmers, 's:ChooserItemOrder')
336349
endif
337350
endif
338351
for [dir,meta] in items(s:hardware_dirs)
@@ -366,10 +379,10 @@ function! arduino#RebuildMakePrg() abort
366379
endif
367380
endfunction
368381

369-
function! s:BoardOrder(b1, b2) abort
370-
let c1 = split(a:b1, ':')[2]
371-
let c2 = split(a:b2, ':')[2]
372-
return c1 == c2 ? 0 : c1 > c2 ? 1 : -1
382+
function! s:ChooserItemOrder(i1, i2) abort
383+
let l1 = has_key(a:i1, 'label') ? a:i1['label'] : a:i1['value']
384+
let l2 = has_key(a:i2, 'label') ? a:i2['label'] : a:i2['value']
385+
return l1 == l2 ? 0 : l1 > l2 ? 1 : -1
373386
endfunction
374387

375388
" Port selection {{{2
@@ -597,39 +610,85 @@ function! s:fzf_leave(callback, item)
597610
let s:fzf_counter -= 1
598611
endfunction
599612
function! s:mk_fzf_callback(callback)
600-
return { item -> s:fzf_leave(a:callback, item) }
613+
return { item -> s:fzf_leave(a:callback, s:ChooserValueFromLabel(item)) }
601614
endfunction
602615

603-
function! arduino#Choose(title, items, callback) abort
616+
function! s:ConvertItemsToLabels(items) abort
617+
let longest = 1
618+
for item in a:items
619+
if has_key(item, 'label')
620+
let longest = max([longest, strchars(item['label'])])
621+
endif
622+
endfor
623+
return map(copy(a:items), 's:ChooserItemLabel(v:val, ' . longest . ')')
624+
endfunction
625+
626+
function! s:ChooserItemLabel(item, ...) abort
627+
let pad_amount = a:0 ? a:1 : 0
628+
if has_key(a:item, 'label')
629+
let label = a:item['label']
630+
let spacing = 1 + max([pad_amount - strchars(label), 0])
631+
return label . repeat(' ', spacing) . '[' . a:item['value'] . ']'
632+
endif
633+
return a:item['value']
634+
endfunction
635+
636+
function! s:ChooserValueFromLabel(label) abort
637+
" The label may be in the format 'label [value]'.
638+
" If so, we need to parse out the value
639+
let groups = matchlist(a:label, '\[\(.*\)\]$')
640+
if empty(groups)
641+
return a:label
642+
else
643+
return groups[1]
644+
endif
645+
endfunction
646+
647+
" items should be a list of dictionary items with the following keys:
648+
" label (optional) The string to display
649+
" value The corresponding value passed to the callback
650+
" items may also be a raw list of strings. They will be treated as values
651+
function! arduino#Choose(title, raw_items, callback) abort
652+
let items = []
653+
let dict_type = type({})
654+
for item in a:raw_items
655+
if type(item) == dict_type
656+
call add(items, item)
657+
else
658+
call add(items, {'value': item})
659+
endif
660+
endfor
661+
604662
if g:arduino_ctrlp_enabled
605663
let ext_data = get(g:ctrlp_ext_vars, s:ctrlp_idx)
606664
let ext_data.lname = a:title
607-
let s:ctrlp_list = a:items
665+
let s:ctrlp_list = items
608666
let s:ctrlp_callback = a:callback
609667
call ctrlp#init(s:ctrlp_id)
610668
elseif g:arduino_fzf_enabled
611669
let s:fzf_counter += 1
612-
call fzf#run({'source':a:items, 'sink':s:mk_fzf_callback(a:callback), 'options':'--prompt="'.a:title.': "'})
670+
call fzf#run({
671+
\ 'source': s:ConvertItemsToLabels(items),
672+
\ 'sink': s:mk_fzf_callback(a:callback),
673+
\ 'options': '--prompt="'.a:title.': "'
674+
\ })
613675
" neovim got a problem with startinsert for the second fzf call, therefore feedkeys("i")
614676
" see https://github.com/junegunn/fzf/issues/426
615677
" see https://github.com/junegunn/fzf.vim/issues/21
616678
if has("nvim") && mode() != "i" && s:fzf_counter > 1
617679
call feedkeys('i')
618680
endif
619681
else
620-
let labels = [" " . a:title]
621-
let idx = 1
622-
for item in a:items
623-
if idx<10
624-
call add(labels, " " . idx . ") " . item)
625-
else
626-
call add(labels, idx . ") " . item)
627-
endif
628-
let idx += 1
629-
endfor
682+
let labels = s:ConvertItemsToLabels(items)
683+
call map(labels, {i, l ->
684+
\ i < 9
685+
\ ? ' '.(i+1).') '.l
686+
\ : (i+1).') '.l
687+
\ })
688+
let labels = [" " . a:title] + labels
630689
let choice = inputlist(labels)
631690
if choice > 0
632-
call call(a:callback, [a:items[choice-1]])
691+
call call(a:callback, [items[choice-1]['value']])
633692
endif
634693
endif
635694
endfunction
@@ -693,7 +752,9 @@ endfunction
693752

694753
" Ctrlp extension {{{1
695754
if exists('g:ctrlp_ext_vars')
696-
let g:arduino_ctrlp_enabled = 1
755+
if !exists('g:arduino_ctrlp_enabled')
756+
let g:arduino_ctrlp_enabled = 1
757+
endif
697758
let s:ctrlp_idx = len(g:ctrlp_ext_vars)
698759
call add(g:ctrlp_ext_vars, {
699760
\ 'init': 'arduino#ctrlp_GetData()',
@@ -709,16 +770,17 @@ else
709770
endif
710771

711772
function! arduino#ctrlp_GetData() abort
712-
return s:ctrlp_list
773+
return s:ConvertItemsToLabels(s:ctrlp_list)
713774
endfunction
714775

715776
function! arduino#ctrlp_Callback(mode, str) abort
716777
call ctrlp#exit()
717-
call call(s:ctrlp_callback, [a:str])
778+
let value = s:ChooserValueFromLabel(a:str)
779+
call call(s:ctrlp_callback, [value])
718780
endfunction
719781

720782
" fzf extension {{{1
721-
if exists("*fzf#run")
783+
if exists("*fzf#run") && !exists('g:arduino_fzf_enabled')
722784
let g:arduino_fzf_enabled = 1
723785
else
724786
let g:arduino_fzf_enabled = 0

0 commit comments

Comments
 (0)