LanguageClient-neovim(cquery)で補完を有効にするため,colcon(ROS2)のワークスペースにcompile_commands.jsonを配置する

中小規模のpackageではvimで手軽に書きたい!!

(neo)vimC++を書く時,ROS2のような外部ライブラリはパスを設定しておかないと補完が効きません. neovim + LanguageClient-neovim (cquery) 環境では,cmake (or colcon build )の引数で CMAKE_EXPORT_COMPILE_COMMANDS をつけた際に生成されるcompile_commands.jsonプロジェクト下にあるといい感じに補完してくれます.

colcon build --cmake-args -DCMAKE_EXPORT_COMPILE_COMMANDS=1

生成されるcompile_commands.jsonの例

[
{
  "directory": "/path_to_colcon_ws/ros2_ws/build/examples_rclcpp_minimal_publisher",
  "command": "/usr/bin/clang++   -I/opt/ros/dashing/include    -Wall -Wextra -Wpedantic -std=gnu++14 -o CMakeFiles/publisher_lambda.dir/lambda.cpp.o -c /path_to_colcon_ws/ros2_ws/src/examples/rclcpp/minimal_publisher/lambda.cpp",
  "file": "/path_to_colcon_ws/ros2_ws/src/examples/rclcpp/minimal_publisher/lambda.cpp"
},
{
  "directory": "/path_to_colcon_ws/ros2_ws/build/examples_rclcpp_minimal_publisher",
  "command": "/usr/bin/clang++   -I/opt/ros/dashing/include    -Wall -Wextra -Wpedantic -std=gnu++14 -o CMakeFiles/publisher_member_function.dir/member_function.cpp.o -c /path_to_colcon_ws/ros2_ws/src/examples/rclcpp/minimal_publisher/member_function.cpp",
  "file": "/path_to_colcon_ws/ros2_ws/src/examples/rclcpp/minimal_publisher/member_function.cpp"
},
{
  "directory": "/path_to_colcon_ws/ros2_ws/build/examples_rclcpp_minimal_publisher",
  "command": "/usr/bin/clang++   -I/opt/ros/dashing/include    -Wall -Wextra -Wpedantic -std=gnu++14 -o CMakeFiles/publisher_not_composable.dir/not_composable.cpp.o -c /path_to_colcon_ws/ros2_ws/src/examples/rclcpp/minimal_publisher/not_composable.cpp",
  "file": "/path_to_colcon_ws/ros2_ws/src/examples/rclcpp/minimal_publisher/not_composable.cpp"
}
]

f:id:DeanKH:20191015225057p:plain
vim上での補完例

ですが,各パッケージのcompile_commands.jsonは,colcon build した場所に生成されるbuild/{project name}/の下に生成されます.そのため,補完を有効にするためにはsrc/{package name}/の下に持ってくる必要があります1.この場合はシンボリックリンクでOK. 以下に置いたのは,そのためのスクリプトです.

コード

gist.github.com

スクリプトについて

気が向いたらします.

課題

おわりに

他に何かいい方法はあるのだろうか...


  1. vim-lspかcqueryでパスを指定すれば直下にいなくても大丈夫なようですが,各プロジェクトのcompile_commands.jsonのパスを指定するのはメンドイ

;(function(document){ var pres = document.getElementsByTagName("pre") for(var i=pres.length; i--; ){  var el = makeOl(pres[i]) pres[i].appendChild(el) } function makeOl(pre){ if (pre.className.indexOf("gist") !== -1) { return } var ol = document.createElement("ol") , li = document.createElement("li") , df = document.createDocumentFragment() , br = pre.innerHTML.match(/\n/g) || 0 ol.className = "preLine" ol.setAttribute("role", "presentation") // no lang, no line-number if( pre.className && ! /lang-./.test(pre.className) ){ br.length += 1 } for(var i=br.length; i--; ){ var li2 = li.cloneNode(true) df.appendChild(li2) } ol.appendChild(df) return ol } })(document)