python support improved

This commit is contained in:
Thies Lennart Alff 2022-04-29 11:57:03 +02:00
parent 7ea4796fdd
commit 7b2475271f
3 changed files with 37 additions and 210 deletions

View file

@ -28,9 +28,11 @@ RUN apt-get update \
byobu \ byobu \
xmlstarlet \ xmlstarlet \
clang-format \ clang-format \
&& pip3 install yapf \ && python3 -m pip install yapf \
rope \ rope \
flake8 \ flake8 \
pylint \
jedi \
&& groupadd --gid $USER_GID $USERNAME \ && groupadd --gid $USER_GID $USERNAME \
&& useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME \ && useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME \
&& echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME\ && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME\
@ -47,20 +49,22 @@ RUN sh -c "$(wget -O- https://github.com/deluan/zsh-in-docker/releases/download/
-a 'fpath+=$HOME/.zsh/pure' \ -a 'fpath+=$HOME/.zsh/pure' \
-a 'autoload -U promptinit; promptinit' \ -a 'autoload -U promptinit; promptinit' \
-a 'prompt pure' \ -a 'prompt pure' \
-a 'PATH=$PATH:$HOME/.local/bin' \
&& mkdir -p "$HOME/.zsh" \ && mkdir -p "$HOME/.zsh" \
&& git clone https://github.com/sindresorhus/pure.git "$HOME/.zsh/pure" \ && git clone https://github.com/sindresorhus/pure.git "$HOME/.zsh/pure" \
&& echo "source /opt/ros/$ROS_DISTR/setup.zsh" >> /home/$USERNAME/.zshrc && echo "source /opt/ros/$ROS_DISTR/setup.zsh" >> /home/$USERNAME/.zshrc
ADD vimrc /home/$USERNAME/.vimrc ADD vimrc /home/$USERNAME/.vimrc
ADD ycm_extra_conf.py /home/$USERNAME/.ycm_extra_conf.py
RUN git clone https://github.com/VundleVim/Vundle.vim.git /home/$USERNAME/.vim/bundle/Vundle.vim RUN git clone https://github.com/VundleVim/Vundle.vim.git /home/$USERNAME/.vim/bundle/Vundle.vim
RUN vim +PluginInstall +qall RUN vim +PluginInstall +qall
RUN cd /home/$USERNAME/.vim/bundle/YouCompleteMe \ RUN cd /home/$USERNAME/.vim/bundle/YouCompleteMe \
&& python3 install.py --clang-completer && python3 install.py --clangd-completer
USER root USER root
RUN chown -R $USERNAME /home/$USERNAME/ RUN chown -R $USERNAME /home/$USERNAME/
USER ${USERNAME} USER ${USERNAME}
WORKDIR /home/$USERNAME WORKDIR /home/$USERNAME
RUN wget https://raw.githubusercontent.com/llvm-mirror/clang/master/tools/clang-format/clang-format.py RUN wget https://raw.githubusercontent.com/llvm/llvm-project/main/clang/tools/clang-format/clang-format.py
# Switch back to dialog for any ad-hoc use of apt-get # Switch back to dialog for any ad-hoc use of apt-get
ENV DEBIAN_FRONTEND=dialog ENV DEBIAN_FRONTEND=dialog
CMD [ "/usr/bin/zsh"] CMD [ "/usr/bin/zsh"]

20
vimrc
View file

@ -37,7 +37,23 @@ inoremap jj <ESC>
set t_Co=256 set t_Co=256
set background=dark set background=dark
silent! colorscheme PaperColor silent! colorscheme PaperColor
:set colorcolumn=81,121
let g:clang_format_fallback_style="Google" let g:clang_format_fallback_style="Google"
map <C-I> :py3f $HOME/clang-format.py<CR> let g:ycm_autoclose_preview_window_after_completion=1
imap <C-I> :py3f $HOME/clang-format.py<CR> let g:ycm_confirm_extra_conf=0
let mapleader=","
autocmd FileType c,cpp nnoremap <leader><F> :py3f $HOME/clang-format.py<CR>
autocmd FileType c,cpp vnoremap <leader><F> :py3f $HOME/clang-format.py<CR>
" autocmd FileType python nnoremap <leader><F> :0,$!yapf<CR><C-o>
let g:ale_linters={"python": ["pylint"]}
let g:ale_fixers = ["yapf"]
let g:ale_open_list=1
let g:ale_set_quickfix=1
let g:ale_set_loclist=0
" does not seem to work due to os.fspath called by config_initialization of
" pylint?
" let g:ale_python_pylint_options='--rcfile $HOME/uuv/ros2/.pylintrc'
silent! autocmd FileType python nnoremap <leader>f <Plug>(ale_fix)

View file

@ -1,210 +1,17 @@
# Copyright 2021 Chen Bainian
# Copyright 2015 Gaël Ecorchard
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Reference:
# Gist link: https://gist.github.com/galou/92a2d05dd772778f86f2
# Author: Gaël Ecorchard (2015)
# License: CC0
import os import os
import ycm_core import shlex
import subprocess
# These are the compilation flags that will be used in case there's no
# compilation database set (by default, one is not set).
# CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR.
# You can get CMake to generate the compilation_commands.json file for you by
# adding:
# set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
# to your CMakeLists.txt file or by once entering
# catkin config --cmake-args -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
# or
# colcon build --cmake-args -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
# in your shell.
DEFAULT_FLAGS = [
'-Wall',
'-Wextra',
'-Werror',
# '-Wc++98-compat',
'-Wno-long-long',
'-Wno-variadic-macros',
'-fexceptions',
'-DNDEBUG',
# THIS IS IMPORTANT! Without a "-std=<something>" flag, clang won't know
# which language to use when compiling headers. So it will guess. Badly. So
# C++ headers will be compiled as C headers. You don't want that so ALWAYS
# specify a "-std=<something>".
# For a C project, you would set this to something like 'c99' instead of
# 'c++11'.
'-std=c++14',
# ...and the same thing goes for the magic -x option which specifies the
# language that the files to be compiled are written in. This is mostly
# relevant for c++ headers.
# For a C project, you would set this to 'c' instead of 'c++'.
'-x',
'c++',
'-I',
'.',
# include third party libraries
# '-isystem',
# '/some/path/include',
]
def GetWorkspaceDir(): def find_ros_python_packages():
""" ros_ws = os.environ['ROS_WORKSPACE']
Get the ROS workspace directory path. cmd = shlex.split(
Return this script directory is ROS_WORKSPACE is not set. f'bash -c "source {ros_ws}/install/setup.bash && echo $PYTHONPATH"')
""" p = subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True)
ws_dir = os.environ.get('ROS_WORKSPACE') for line in p.stdout:
return os.path.dirname(os.path.abspath(__file__)) if ws_dir is None else ws_dir paths = line.rstrip().split(':')
p.communicate()
return paths
def GetDefaultRosIncludePaths():
"""
Return a list of potential include directories.
The directories are looked for in ros workspace.
This doesn't work well with the ROS 1 build configured with install.
"""
ros_ver = os.environ.get('ROS_VERSION')
includes = []
# ROS 1
if ros_ver == '1':
try:
from rospkg import RosPack
except ImportError:
return []
rospack = RosPack()
devel_includes_path = os.path.join(GetWorkspaceDir(),
'devel', 'include')
if os.path.exists(devel_includes_path):
includes.append(devel_includes_path)
for p in rospack.list():
if os.path.exists(rospack.get_path(p) + '/include'):
includes.append(rospack.get_path(p) + '/include')
includes.append('/opt/ros/' + os.environ.get('ROS_DISTRO') + '/include')
# ROS 2
elif ros_ver == '2':
try:
from ros2pkg.api import get_package_names
from ament_index_python import get_package_prefix
except ImportError:
return []
for package_name in get_package_names():
include_path = os.path.join(get_package_prefix(package_name), 'include')
if os.path.exists(include_path) and include_path not in includes:
includes.append(include_path)
return includes
def GetDefaultFlags():
includes = GetDefaultRosIncludePaths()
flags = DEFAULT_FLAGS
for include in includes:
flags.append('-isystem')
flags.append(include)
return flags
def GetCompileCommandsPath(filename):
"""
Return the directory potentially containing `compilation_commands.json`.
Return the absolute path to the folder (NOT the file!) containing the
compile_commands.json file to use that instead of 'flags'. See here for
more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html.
The compilation_commands.json for the given file is returned by getting
the package the file belongs to.
"""
# Find the corresponding ROS package name for the file.
# This function works in both ROS1 and ROS2
try:
from rospkg import get_package_name
except ImportError:
return ''
pkg_name = get_package_name(filename)
if not pkg_name:
return ''
return os.path.join(GetWorkspaceDir(), 'build', pkg_name)
def GetDatabase(compilation_database_folder):
if os.path.exists(compilation_database_folder):
return ycm_core.CompilationDatabase(compilation_database_folder)
return None
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 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 Settings(**kwargs): def Settings(**kwargs):
if kwargs['language'] != 'cfamily': return {'sys_path': find_ros_python_packages()}
return {}
filename = kwargs['filename']
flags = []
database_dir = GetCompileCommandsPath(filename)
if os.path.exists(database_dir):
# Load the compile_commands.json file
database = ycm_core.CompilationDatabase(database_dir)
if database:
# Bear in mind that compilation_info.compiler_flags_ does NOT return a
# python list, but a "list-like" StringVec object
compilation_info = database.GetCompilationInfoForFile(filename)
if not compilation_info:
flags = GetDefaultFlags() # Use default flags if there are any loading error.
else:
flags = MakeRelativePathsInFlagsAbsolute(
compilation_info.compiler_flags_,
compilation_info.compiler_working_dir_)
if not flags:
flags = GetDefaultFlags() # Use default flags if there is no flags defined.
return {
'flags': flags,
'do_cache': True
}