PlatformIO with Neovim
Recently I got interested in EPS32 and ESP8266 programming and I found PlatformIO provides a framework to work with a wide range of devices using simpler code like in Arduino.
I started with VSCode as IDE but soon felt I want to move back to my original editor which is Neovim. I have everything set up according to my need and wanted to see whether PlatformIO can work with Neovim. To start of with I installed there cli tool which can be found here: https://docs.platformio.org/en/stable/core/index.html. After installing pio
cli I created new ESP32 project using following command:
pio project init --board esp32dev --ide vim
which scaffolded basic project with following platform.ini
file
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
and after that created a new file in src
directory named main.cpp
but Neovim started showing multiple errors that it is not able to find Arduino.h
. LSP I am using is Clangd and solving this was the easiest part of the whole journey. I need to run this command to generate compile_commands.json
file that Clangd will look at find all necessary libraries.
pio run -t compiledb
After I restarted my LSP i got few new errors about machine/endian.h
not found and few unknown compiler flags but if I run pio run
it successfully builds so its issue with LSP only. After scavenging internet for few hours I got a solution that works for me and here it is:
# platform.ini
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
build_flags = -Ilib -Isrc # add this line
I also needed a bash script that generates and fixes flags in compile_commands.h
#!/bin/bash
# Compile the project
pio run -t compiledb
# Clean up existing define files
rm -f _compiler_defines.h compiler_defines.h clang_defines.h
# Generate defines for clang
clang -dM -xc++ /dev/null -c -v -E 2>/dev/null | sed "s/\([^[:space:]]\+[[:space:]]\+[^[:space:]]\+\)\(.*\)/\1/;s/#define/#undef/" >clang_defines.h
# Iterate through compile_commands.json and extract compiler defines
for comp in $(cat compile_commands.json | grep -E "\"command\": \"[^[:space:]]* -o" | sed 's:"command"\: "::g; s:-o.*::g' | sort | uniq); do
set -x
$comp -dM -E -xc++ /dev/null >>_compiler_defines.h
set +x
done
# Combine defines from clang and extracted defines
cat clang_defines.h >compiler_defines.h
cat _compiler_defines.h | sort | uniq >>compiler_defines.h
# Clean up temporary define files
rm -f _compiler_defines.h clang_defines.h
# Update compile_commands.json with additional include flags
sed -i "s:.cpp\",:.cpp -include $${PWD}/compiler_defines.h\",:" compile_commands.json
sed -i "s:.c\",:.c -include $${PWD}/compiler_defines.h\",:" compile_commands.json
After running this when I restarted my LSP everything works except few things like Serail.println
still throws an error. Except that last thing everything looks good. I will continue learning ESP32 programming in Neovim and if I find something to update I will add a new article as part 2 of this. Hope this article helps you.
Happy Coding
Subscribe to my newsletter
Read articles from Ratnadeep Bhattacharyya directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Ratnadeep Bhattacharyya
Ratnadeep Bhattacharyya
I am developer from India, currently working remote as Software Engineer in Nagarro. Love to work on new technologies and experiment with bleeding edge one.