@@ -2,6 +2,7 @@ if (exists('g:loaded_arduino_autoload') && g:loaded_arduino_autoload)
2
2
finish
3
3
endif
4
4
let g: loaded_arduino_autoload = 1
5
+ let s: has_cli = executable (' arduino-cli' ) == 1
5
6
if has (' win64' ) || has (' win32' ) || has (' win16' )
6
7
echoerr " vim-arduino does not support windows :("
7
8
finish
19
20
let s: TERM = ' !'
20
21
endif
21
22
let s: hardware_dirs = {}
23
+ python3 import json
22
24
23
25
" Initialization {{{1
24
26
" Set up all user configuration variables
@@ -40,6 +42,9 @@ function! arduino#InitializeConfig() abort
40
42
if ! exists (' g:arduino_args' )
41
43
let g: arduino_args = ' --verbose-upload'
42
44
endif
45
+ if ! exists (' g:arduino_cli_args' )
46
+ let g: arduino_cli_args = ' -v'
47
+ endif
43
48
if ! exists (' g:arduino_serial_cmd' )
44
49
let g: arduino_serial_cmd = ' screen {port} {baud}'
45
50
endif
@@ -61,7 +66,7 @@ function! arduino#InitializeConfig() abort
61
66
endif
62
67
63
68
if ! exists (' g:arduino_run_headless' )
64
- let g: arduino_run_headless = executable (' Xvfb' ) ? 1 : 0
69
+ let g: arduino_run_headless = executable (' Xvfb' ) == 1
65
70
endif
66
71
67
72
if ! exists (' g:arduino_serial_port_globs' )
@@ -71,11 +76,20 @@ function! arduino#InitializeConfig() abort
71
76
\' /dev/ tty .usbserial* ',
72
77
\' /dev/ tty .wchusbserial* ']
73
78
endif
79
+ if ! exists (' g:arduino_use_cli' )
80
+ let g: arduino_use_cli = s: has_cli
81
+ elseif g: arduino_use_cli && ! s: has_cli
82
+ echoerr ' arduino-cli: command not found'
83
+ endif
74
84
call arduino#ReloadBoards ()
75
85
endfunction
76
86
77
87
" Boards and programmer definitions {{{1
78
88
function ! arduino#ReloadBoards () abort
89
+ " TODO in the future if we're using arduino-cli we shouldn't have to do this,
90
+ " but at the moment I'm having issues where `arduino-cli board details
91
+ " adafruit:avr:gemma --list-programmers` is empty
92
+
79
93
" First let's search the arduino system install for boards
80
94
" The path looks like /hardware/<package>/<arch>/boards.txt
81
95
let arduino_dir = arduino#GetArduinoDir ()
@@ -171,6 +185,24 @@ function! arduino#GetBuildPath() abort
171
185
return l: path
172
186
endfunction
173
187
188
+ function ! arduino#GetCLICompileCommand (... ) abort
189
+ let cmd = ' arduino-cli compile -b ' . g: arduino_board
190
+ let port = arduino#GetPort ()
191
+ if ! empty (port)
192
+ let cmd = cmd . ' -p ' . port
193
+ endif
194
+ if ! empty (g: arduino_programmer )
195
+ let cmd = cmd . ' -P ' . g: arduino_programmer
196
+ endif
197
+ let l: build_path = arduino#GetBuildPath ()
198
+ if ! empty (l: build_path )
199
+ let cmd = cmd . ' --build-path "' . l: build_path . ' "'
200
+ endif
201
+ if a: 0
202
+ let cmd = cmd . " " . a: 1
203
+ endif
204
+ return cmd . " " . g: arduino_cli_args . ' "' . expand (' %:p' ) . ' "'
205
+ endfunction
174
206
175
207
function ! arduino#GetArduinoCommand (cmd) abort
176
208
let arduino = arduino#GetArduinoExecutable ()
@@ -197,33 +229,59 @@ endfunction
197
229
198
230
function ! arduino#GetBoards () abort
199
231
let boards = []
200
- for [dir ,meta] in items (s: hardware_dirs )
201
- if ! isdirectory (dir )
202
- continue
203
- endif
204
- let filename = dir . ' /boards.txt'
205
- if ! filereadable (filename)
206
- continue
207
- endif
208
- let lines = readfile (filename)
209
- for line in lines
210
- if line = ~? ' ^[^.]*\.name=.*$'
211
- let linesplit = split (line , ' \.' )
212
- let board = linesplit[0 ]
213
- let linesplit = split (line , ' =' )
214
- let name = linesplit[1 ]
215
- let board = meta.package . ' :' . meta.arch . ' :' . board
216
- if index (boards, board) == -1
217
- call add (boards, board)
218
- endif
232
+ if g: arduino_use_cli
233
+ let boards_data = s: get_json_output (' arduino-cli board listall --format json' )
234
+ for board in boards_data[' boards' ]
235
+ let boardname = board[' fqbn' ]
236
+ call add (boards, boardname)
237
+ endfor
238
+ else
239
+ for [dir ,meta] in items (s: hardware_dirs )
240
+ if ! isdirectory (dir )
241
+ continue
242
+ endif
243
+ let filename = dir . ' /boards.txt'
244
+ if ! filereadable (filename)
245
+ continue
219
246
endif
247
+ let lines = readfile (filename)
248
+ for line in lines
249
+ if line = ~? ' ^[^.]*\.name=.*$'
250
+ let linesplit = split (line , ' \.' )
251
+ let board = linesplit[0 ]
252
+ let linesplit = split (line , ' =' )
253
+ let name = linesplit[1 ]
254
+ let board = meta.package . ' :' . meta.arch . ' :' . board
255
+ if index (boards, board) == -1
256
+ call add (boards, board)
257
+ endif
258
+ endif
259
+ endfor
260
+ unlet dir meta
220
261
endfor
221
- unlet dir meta
222
- endfor
262
+ endif
263
+ call sort (boards, ' s:BoardOrder ' )
223
264
return boards
224
265
endfunction
225
266
226
267
function ! arduino#GetBoardOptions (board) abort
268
+ if g: arduino_use_cli
269
+ let ret = {}
270
+ let data = s: get_json_output (' arduino-cli board details ' . a: board . ' --format json' )
271
+ if ! has_key (data, ' config_options' )
272
+ return ret
273
+ endif
274
+ let opts = data[' config_options' ]
275
+ for opt in opts
276
+ let values = []
277
+ for entry in opt [' values' ]
278
+ call add (values , entry[' value' ])
279
+ endfor
280
+ let ret [opt [' option' ]] = values
281
+ endfor
282
+ return ret
283
+ endif
284
+
227
285
" Board will be in the format package:arch:board
228
286
let [package, arch, boardname] = split (a: board , ' :' )
229
287
@@ -267,6 +325,16 @@ endfunction
267
325
268
326
function ! arduino#GetProgrammers () abort
269
327
let programmers = []
328
+ if g: arduino_use_cli
329
+ let data = s: get_json_output (' arduino-cli board details ' . g: arduino_board . ' --list-programmers --format json' )
330
+ for entry in data[' programmers' ]
331
+ call add (programmers, entry[' id' ])
332
+ endfor
333
+ " 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
334
+ if ! empty (programmers)
335
+ return sort (programmers)
336
+ endif
337
+ endif
270
338
for [dir ,meta] in items (s: hardware_dirs )
271
339
if ! isdirectory (dir )
272
340
continue
@@ -291,7 +359,11 @@ function! arduino#GetProgrammers() abort
291
359
endfunction
292
360
293
361
function ! arduino#RebuildMakePrg () abort
294
- let &l: makeprg = arduino#GetArduinoCommand (" --verify" )
362
+ if g: arduino_use_cli
363
+ let &l: makeprg = arduino#GetCLICompileCommand ()
364
+ else
365
+ let &l: makeprg = arduino#GetArduinoCommand (" --verify" )
366
+ endif
295
367
endfunction
296
368
297
369
function ! s: BoardOrder (b1, b2) abort
@@ -330,7 +402,6 @@ function! arduino#ChooseBoard(...) abort
330
402
return
331
403
endif
332
404
let boards = arduino#GetBoards ()
333
- call sort (boards, ' s:BoardOrder' )
334
405
call arduino#Choose (' Arduino Board' , boards, ' arduino#SelectBoard' )
335
406
endfunction
336
407
@@ -405,7 +476,11 @@ function! arduino#SetBoard(board, ...) abort
405
476
endfunction
406
477
407
478
function ! arduino#Verify () abort
408
- let cmd = arduino#GetArduinoCommand (" --verify" )
479
+ if g: arduino_use_cli
480
+ let cmd = arduino#GetCLICompileCommand ()
481
+ else
482
+ let cmd = arduino#GetArduinoCommand (" --verify" )
483
+ endif
409
484
if g: arduino_use_slime
410
485
call slime#send (cmd." \r " )
411
486
else
@@ -415,12 +490,16 @@ function! arduino#Verify() abort
415
490
endfunction
416
491
417
492
function ! arduino#Upload () abort
418
- if g: arduino_upload_using_programmer
419
- let cmd_options = " --upload --useprogrammer "
493
+ if g: arduino_use_cli
494
+ let cmd = arduino#GetCLICompileCommand ( ' -u ' )
420
495
else
421
- let cmd_options = " --upload"
496
+ if g: arduino_upload_using_programmer
497
+ let cmd_options = " --upload --useprogrammer"
498
+ else
499
+ let cmd_options = " --upload"
500
+ endif
501
+ let cmd = arduino#GetArduinoCommand (cmd_options)
422
502
endif
423
- let cmd = arduino#GetArduinoCommand (cmd_options)
424
503
if g: arduino_use_slime
425
504
call slime#send (cmd." \r " )
426
505
else
@@ -506,7 +585,12 @@ endfunction
506
585
" }}}2
507
586
508
587
" Utility functions {{{1
509
- "
588
+
589
+ function ! s: get_json_output (cmd) abort
590
+ let output_str = system (a: cmd )
591
+ return py3eval (' json.loads(vim.eval("output_str"))' )
592
+ endfunction
593
+
510
594
let s: fzf_counter = 0
511
595
function ! s: fzf_leave (callback, item)
512
596
call function (a: callback )(a: item )
@@ -604,6 +688,7 @@ function! arduino#GetInfo() abort
604
688
echo " Baud rate : " . g: arduino_serial_baud
605
689
echo " Hardware dirs : " . dirs
606
690
echo " Verify command: " . arduino#GetArduinoCommand (" --verify" )
691
+ echo " CLI command : " . arduino#GetCLICompileCommand ()
607
692
endfunction
608
693
609
694
" Ctrlp extension {{{1
0 commit comments