Skip to content

Commit cefbe60

Browse files
committed
For #37: Use the new arduino-cli when available
1 parent aef4ab5 commit cefbe60

File tree

4 files changed

+152
-43
lines changed

4 files changed

+152
-43
lines changed

README.md

+8-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# vim-arduino
2-
Vim plugin for compiling, uploading, and debugging arduino sketches. It makes
3-
use of the Arduino IDE's [commandline
2+
Vim plugin for compiling, uploading, and debugging arduino sketches. It uses
3+
[arduino-cli](https://arduino.github.io/arduino-cli/latest/) when available, and
4+
falls back to using the Arduino IDE's [commandline
45
interface](https://github.com/arduino/Arduino/blob/master/build/shared/manpage.adoc)
56
(new in 1.5.x).
67

@@ -19,9 +20,11 @@ and [vim-plug](https://github.com/junegunn/vim-plug)
1920
Plug 'stevearc/vim-arduino'
2021
```
2122

22-
You also need to download the [Arduino
23-
IDE](https://www.arduino.cc/en/Main/Software) (version 1.5 or newer) and make
24-
sure the `arduino` command is in your PATH.
23+
Installation instructions for `arduino-cli` are here: https://arduino.github.io/arduino-cli/latest/installation/
24+
25+
Otherwise (or in addition to), download [Arduino
26+
IDE](https://www.arduino.cc/en/Main/Software) (version 1.5 or newer). Linux
27+
users make sure the `arduino` command is in your PATH.
2528

2629
## Platforms
2730

autoload/arduino.vim

+115-30
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ if (exists('g:loaded_arduino_autoload') && g:loaded_arduino_autoload)
22
finish
33
endif
44
let g:loaded_arduino_autoload = 1
5+
let s:has_cli = executable('arduino-cli') == 1
56
if has('win64') || has('win32') || has('win16')
67
echoerr "vim-arduino does not support windows :("
78
finish
@@ -19,6 +20,7 @@ else
1920
let s:TERM = '!'
2021
endif
2122
let s:hardware_dirs = {}
23+
python3 import json
2224

2325
" Initialization {{{1
2426
" Set up all user configuration variables
@@ -40,6 +42,9 @@ function! arduino#InitializeConfig() abort
4042
if !exists('g:arduino_args')
4143
let g:arduino_args = '--verbose-upload'
4244
endif
45+
if !exists('g:arduino_cli_args')
46+
let g:arduino_cli_args = '-v'
47+
endif
4348
if !exists('g:arduino_serial_cmd')
4449
let g:arduino_serial_cmd = 'screen {port} {baud}'
4550
endif
@@ -61,7 +66,7 @@ function! arduino#InitializeConfig() abort
6166
endif
6267

6368
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
6570
endif
6671

6772
if !exists('g:arduino_serial_port_globs')
@@ -71,11 +76,20 @@ function! arduino#InitializeConfig() abort
7176
\'/dev/tty.usbserial*',
7277
\'/dev/tty.wchusbserial*']
7378
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
7484
call arduino#ReloadBoards()
7585
endfunction
7686

7787
" Boards and programmer definitions {{{1
7888
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+
7993
" First let's search the arduino system install for boards
8094
" The path looks like /hardware/<package>/<arch>/boards.txt
8195
let arduino_dir = arduino#GetArduinoDir()
@@ -171,6 +185,24 @@ function! arduino#GetBuildPath() abort
171185
return l:path
172186
endfunction
173187

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
174206

175207
function! arduino#GetArduinoCommand(cmd) abort
176208
let arduino = arduino#GetArduinoExecutable()
@@ -197,33 +229,59 @@ endfunction
197229

198230
function! arduino#GetBoards() abort
199231
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
219246
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
220261
endfor
221-
unlet dir meta
222-
endfor
262+
endif
263+
call sort(boards, 's:BoardOrder')
223264
return boards
224265
endfunction
225266

226267
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+
227285
" Board will be in the format package:arch:board
228286
let [package, arch, boardname] = split(a:board, ':')
229287

@@ -267,6 +325,16 @@ endfunction
267325

268326
function! arduino#GetProgrammers() abort
269327
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
270338
for [dir,meta] in items(s:hardware_dirs)
271339
if !isdirectory(dir)
272340
continue
@@ -291,7 +359,11 @@ function! arduino#GetProgrammers() abort
291359
endfunction
292360

293361
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
295367
endfunction
296368

297369
function! s:BoardOrder(b1, b2) abort
@@ -330,7 +402,6 @@ function! arduino#ChooseBoard(...) abort
330402
return
331403
endif
332404
let boards = arduino#GetBoards()
333-
call sort(boards, 's:BoardOrder')
334405
call arduino#Choose('Arduino Board', boards, 'arduino#SelectBoard')
335406
endfunction
336407

@@ -405,7 +476,11 @@ function! arduino#SetBoard(board, ...) abort
405476
endfunction
406477

407478
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
409484
if g:arduino_use_slime
410485
call slime#send(cmd."\r")
411486
else
@@ -415,12 +490,16 @@ function! arduino#Verify() abort
415490
endfunction
416491

417492
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')
420495
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)
422502
endif
423-
let cmd = arduino#GetArduinoCommand(cmd_options)
424503
if g:arduino_use_slime
425504
call slime#send(cmd."\r")
426505
else
@@ -506,7 +585,12 @@ endfunction
506585
"}}}2
507586

508587
" 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+
510594
let s:fzf_counter = 0
511595
function! s:fzf_leave(callback, item)
512596
call function(a:callback)(a:item)
@@ -604,6 +688,7 @@ function! arduino#GetInfo() abort
604688
echo "Baud rate : " . g:arduino_serial_baud
605689
echo "Hardware dirs : " . dirs
606690
echo "Verify command: " . arduino#GetArduinoCommand("--verify")
691+
echo "CLI command : " . arduino#GetCLICompileCommand()
607692
endfunction
608693

609694
" Ctrlp extension {{{1

doc/arduino.txt

+27-8
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,21 @@ OPTIONS *arduino-options*
2424
Overview:~
2525

2626
|arduino_cmd|..................Path to the arduino executable
27+
|arduino_use_cli|..............Selects usage of newer arduino-cli tool
2728
|arduino_dir|..................Path to the arduino install directory
2829
|arduino_home_dir|.............Path to the arduino user install directory
2930
|arduino_build_path|...........Path to use for building the sketch
3031
|arduino_run_headless|.........Try to run inside Xvfb
31-
|arduino_args|.................Additional args to pass to 'arduino' command.
32-
|arduino_board|................The fully-qualified name of the board.
33-
|arduino_programmer|...........The programmer type.
34-
|arduino_serial_cmd|...........Command to run to attach to serial port.
35-
|arduino_serial_baud|..........The baud rate for the serial connection.
36-
|arduino_auto_baud|............Auto-detect the baud rate.
32+
|arduino_args|.................Additional args to pass to 'arduino' command
33+
|arduino_cli_args|.............Additional args to pass to 'arduino-cli' command
34+
|arduino_board|................The fully-qualified name of the board
35+
|arduino_programmer|...........The programmer type
36+
|arduino_serial_cmd|...........Command to run to attach to serial port
37+
|arduino_serial_baud|..........The baud rate for the serial connection
38+
|arduino_auto_baud|............Auto-detect the baud rate
3739
|arduino_use_slime|............Use vim-slime to run commands in tmux/screen/etc
38-
|arduino_serial_port|..........Location of the serial port.
39-
|arduino_serial_port_globs|....Globs to auto-search for serial port.
40+
|arduino_serial_port|..........Location of the serial port
41+
|arduino_serial_port_globs|....Globs to auto-search for serial port
4042

4143
-------------------------------------------------------------------------------
4244
Detailed descriptions and default values:~
@@ -45,6 +47,16 @@ Detailed descriptions and default values:~
4547
The path to the 'arduino' command. By default it will look in your PATH, or in
4648
Applications on Mac. >
4749
let g:arduino_cmd = '/usr/share/local/arduino/arduino'
50+
<
51+
*'g:arduino_use_cli'*
52+
The newest and least janky way to interact with arduino on the command line is
53+
using arduino-cli (see https://arduino.github.io/arduino-cli/latest/). If we
54+
detect 'arduino-cli' in your PATH, we will use it. If it is not found, we fall
55+
back to using the Arduino IDE commandline args (see
56+
https://github.com/arduino/Arduino/blob/master/build/shared/manpage.adoc). You
57+
may set this value explicitly to force using one tool or the other. >
58+
let g:arduino_use_cli = 0 " this will always use the Arduino IDE
59+
let g:arduino_use_cli = 1 " this will always use arduino-cli
4860
<
4961
*'g:arduino_dir'*
5062
The path to your 'arduino' directory. Usually vim-arduino will be able to
@@ -83,6 +95,13 @@ and upload. See
8395
https://github.com/arduino/Arduino/blob/master/build/shared/manpage.adoc for
8496
more detail. >
8597
let g:arduino_args = '--verbose-upload'
98+
<
99+
*'g:arduino_cli_args'*
100+
Additional arguments that will be passed to the 'arduino-cli' command during
101+
build and upload. See
102+
https://arduino.github.io/arduino-cli/latest/commands/arduino-cli_compile/ for
103+
more detail. >
104+
let g:arduino_args = '-v'
86105
<
87106
*'g:arduino_board'*
88107
The board type to use when compiling and uploading. See also

doc/tags

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
'g:arduino_auto_baud' arduino.txt /*'g:arduino_auto_baud'*
33
'g:arduino_board' arduino.txt /*'g:arduino_board'*
44
'g:arduino_build_path' arduino.txt /*'g:arduino_build_path'*
5+
'g:arduino_cli_args' arduino.txt /*'g:arduino_cli_args'*
56
'g:arduino_cmd' arduino.txt /*'g:arduino_cmd'*
67
'g:arduino_dir' arduino.txt /*'g:arduino_dir'*
78
'g:arduino_home_dir' arduino.txt /*'g:arduino_home_dir'*
@@ -11,6 +12,7 @@
1112
'g:arduino_serial_cmd' arduino.txt /*'g:arduino_serial_cmd'*
1213
'g:arduino_serial_port' arduino.txt /*'g:arduino_serial_port'*
1314
'g:arduino_serial_port_globs' arduino.txt /*'g:arduino_serial_port_globs'*
15+
'g:arduino_use_cli' arduino.txt /*'g:arduino_use_cli'*
1416
'g:arduino_use_slime' arduino.txt /*'g:arduino_use_slime'*
1517
'vim-arduino' arduino.txt /*'vim-arduino'*
1618
:ArduinoChooseBoard arduino.txt /*:ArduinoChooseBoard*

0 commit comments

Comments
 (0)