Last active
April 12, 2021 11:55
-
-
Save ajford/f551b2b6fd4d6b6e1ef2 to your computer and use it in GitHub Desktop.
PlatformIO/YouCompleteMe Integration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
YouCompleteMe extra configuration for Platformio based | |
projects. | |
Based on the `.ycm_extra_conf.py` by @ladislas in his Bare-Arduino-Project. | |
Anthony Ford <github.com/ajford> | |
""" | |
import os | |
import ycm_core | |
import logging | |
# Logger for additional logging. | |
# To enable debug logging, add `let g:ycm_server_log_level = 'debug'` to | |
# your .vimrc file. | |
logger = logging.getLogger('ycm-extra-conf') | |
# Platformio Autogen libs. | |
## Platformio automatically copies over the libs you use after your first run. | |
## Be warned that you will not receive autocompletion on libraries until after | |
## your first `platformio run`. | |
PlatformioAutogen = ".pioenvs/" | |
# All Platformio Arduin Libs | |
## This will link directly to the Platformio Libs for Arduino. | |
## Be warned that this can polute your namespace (in #include) | |
## and slightly increase startup time (while crawling the lib | |
## dir for header files). This will however allow you to | |
## complete for header files you haven't included yet. | |
PlatformioArduinoLibs = "~/.platformio/packages/framework-arduinoavr/libraries/" | |
# Platformio Arduino Core | |
## This links to the Platformio Arduino Cores. This provides | |
## the core libs, such as Arduino.h and HardwareSerial.h | |
PlatformioArduinoCore = "~/.platformio/packages/framework-arduinoavr/cores/arduino/" | |
# Platformio Arduino Std Libs | |
## Arduino Std libs from .platformio packages. Provides stdlib.h and such. | |
PlatformioArduinoSTD = '~/.platformio/packages/toolchain-atmelavr/avr/include' | |
# This is the list of all directories to search for header files. | |
# Dirs in this list can be paths relative to this file, absolute | |
# paths, or paths relative to the user (using ~/path/to/file). | |
libDirs = [ | |
"lib" | |
,PlatformioAutogen | |
,PlatformioArduinoCore | |
,PlatformioArduinoLibs | |
,PlatformioArduinoSTD | |
] | |
flags = [ | |
# General flags | |
'-Wall' | |
,'-x' | |
,'c++' | |
,'-ansi' | |
# Customize microcontroler and Arduino version | |
,'-mmcu=atmega328p' | |
,'-DF_CPU=16000000L' | |
,'-DARDUINO_ARCH_AVR' | |
,'-DARDUINO_AVR_DUEMILANOVE' | |
,'-DARDUINO=106000' | |
# ,'-MMD -DUSB_VID=null' | |
# ,'-DUSB_PID=null' | |
] | |
compilation_database_folder = '' | |
if os.path.exists( compilation_database_folder ): | |
database = ycm_core.CompilationDatabase( compilation_database_folder ) | |
else: | |
database = None | |
SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.ino', '.m', '.mm' ] | |
def DirectoryOfThisScript(): | |
return os.path.dirname( os.path.abspath( __file__ ) ) | |
def MakeRelativePathsInFlagsAbsolute( flags, working_directory ): | |
if not working_directory: | |
return list( flags ) | |
new_flags = [] | |
make_next_absolute = False | |
path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ] | |
for libDir in libDirs: | |
# dir is relative to $HOME | |
if libDir.startswith('~'): | |
libDir = os.path.expanduser(libDir) | |
# dir is relative to `working_directory` | |
if not libDir.startswith('/'): | |
libDir = os.path.join(working_directory,libDir) | |
# Else, assume dir is absolute | |
for path, dirs, files in os.walk(libDir): | |
# Add to flags if dir contains a header file and is not | |
# one of the metadata dirs (examples and extras). | |
if any(IsHeaderFile(x) for x in files) and\ | |
path.find("examples") is -1 and path.find("extras") is -1: | |
logger.debug("Directory contains header files - %s"%path) | |
flags.append('-I'+path) | |
for flag in flags: | |
new_flag = flag | |
if make_next_absolute: | |
make_next_absolute = False | |
if not flag.startswith( '/' ): | |
new_flag = os.path.join( working_directory, flag ) | |
for path_flag in path_flags: | |
if flag == path_flag: | |
make_next_absolute = True | |
break | |
if flag.startswith( path_flag ): | |
path = flag[ len( path_flag ): ] | |
new_flag = path_flag + os.path.join( working_directory, path ) | |
break | |
if new_flag: | |
new_flags.append( new_flag ) | |
return new_flags | |
def IsHeaderFile( filename ): | |
extension = os.path.splitext( filename )[ 1 ] | |
return extension in [ '.h', '.hxx', '.hpp', '.hh' ] | |
def GetCompilationInfoForFile( filename ): | |
# The compilation_commands.json file generated by CMake does not have entries | |
# for header files. So we do our best by asking the db for flags for a | |
# corresponding source file, if any. If one exists, the flags for that file | |
# should be good enough. | |
if IsHeaderFile( filename ): | |
basename = os.path.splitext( filename )[ 0 ] | |
for extension in SOURCE_EXTENSIONS: | |
replacement_file = basename + extension | |
if os.path.exists( replacement_file ): | |
compilation_info = database.GetCompilationInfoForFile( | |
replacement_file ) | |
if compilation_info.compiler_flags_: | |
return compilation_info | |
return None | |
return database.GetCompilationInfoForFile( filename ) | |
def FlagsForFile( filename, **kwargs ): | |
if database: | |
# Bear in mind that compilation_info.compiler_flags_ does NOT return a | |
# python list, but a "list-like" StringVec object | |
compilation_info = GetCompilationInfoForFile( filename ) | |
if not compilation_info: | |
return None | |
final_flags = MakeRelativePathsInFlagsAbsolute( | |
compilation_info.compiler_flags_, | |
compilation_info.compiler_working_dir_ ) | |
# NOTE: This is just for YouCompleteMe. it's highly likely that your project | |
# does NOT need to remove the stdlib flag. DO NOT USE THIS IN YOUR | |
# ycm_extra_conf IF YOU'RE NOT 100% SURE YOU NEED IT. | |
#try: | |
# final_flags.remove( '-stdlib=libc++' ) | |
#except ValueError: | |
# pass | |
else: | |
relative_to = DirectoryOfThisScript() | |
final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to ) | |
return { | |
'flags': final_flags, | |
'do_cache': True | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Have tried to use YouCompleteMe with platformio and vim many times but I always fail.
This time YouCompleteMe does not recognise Serial altought I have included Arduino.h
Also YcmDiags give me this errors:
/home/neophytos/.platformio/packages/toolchain-atmelavr/avr/include/avr/io.h|625 col 6 warning| "device type not defined" /home/neophytos/.platformio/packages/framework-arduinoavr/cores/arduino/Arduino.h|163 col 23 warning| unknown attribute '__progmem__' ignored /home/neophytos/.platformio/packages/framework-arduinoavr/cores/arduino/Arduino.h|164 col 23 warning| unknown attribute '__progmem__' ignored /home/neophytos/.platformio/packages/framework-arduinoavr/cores/arduino/Arduino.h|165 col 23 warning| unknown attribute '__progmem__' ignored /home/neophytos/.platformio/packages/framework-arduinoavr/cores/arduino/Arduino.h|167 col 22 warning| unknown attribute '__progmem__' ignored /home/neophytos/.platformio/packages/framework-arduinoavr/cores/arduino/Arduino.h|169 col 22 warning| unknown attribute '__progmem__' ignored /home/neophytos/.platformio/packages/framework-arduinoavr/cores/arduino/Arduino.h|170 col 22 warning| unknown attribute '__progmem__' ignored /home/neophytos/.platformio/packages/toolchain-atmelavr/avr/include/avr/eeprom.h|41 col 3 warning| "Device does not have EEPROM available." /home/neophytos/.platformio/packages/toolchain-atmelavr/avr/include/util/delay_basic.h|108 col 5 error| invalid output constraint '=w' in asm /home/neophytos/.platformio/packages/toolchain-atmelavr/avr/include/util/delay.h|112 col 3 warning| "Compiler optimizations disabled; functions from <util /delay.h> won't work as designed" /home/neophytos/.platformio/packages/framework-arduinoavr/cores/arduino/Arduino.h|257 col 10 error| 'pins_arduino.h' file not found src/main.cpp|6 col 5 error| use of undeclared identifier 'Serial'
Any help will be highly appreciated