C/C++ Source Code Completion With YouCompleteMe and Vim for Android and the Linux Kernel

YouCompleteMe is currently the best clang based completion engine for vim/neovim and there is also an emacs version.

A gif is worth a thousand words -

images

I’ve been using YCM for a while for C/C++ code completion in the Android source tree as well as the Linux kernel and it just works without any need to generate tags. It also does syntax error checking on the fly with syntastic, which is an added bonus. The basic idea is to rely on .repo as a marker to set up the necessary header paths in ycm_extra_conf.py for userspace and Kbuild as a marker for the kernel Here is my configuration for vim. The python part of the configuration below also works with emacs.

  • Install vim > version 7.04 or the latest alpha version of neovim. This can be easily done with brew on OSX or linuxbrew on Linux.
  • Install YCM for your OS with the clang completer. I’ve only tested Linux and OSX
  • Configure YCM with the following options in your ~/.vimrc
1
2
3
4
5
6
7
8
9
10
11
let g:ycm_complete_in_comments_and_strings=1
let g:ycm_key_list_select_completion=['<C-n>', '<Down>']
let g:ycm_key_list_previous_completion=['<C-p>', '<Up>']
let g:ycm_autoclose_preview_window_after_completion = 1

"This assumes your kernel directory has the word 'kernel'
if getcwd() =~ "kernel"
    let g:ycm_global_ycm_extra_conf='~/ycm_extra_conf_kernel.py'
else
    let g:ycm_global_ycm_extra_conf='~/ycm_extra_conf.py'
endif
  • Copy the contents of this gist into ~/ycm_extra_conf.py and that should be it for userspace code!

  • To configure the kernel for code completion, copy the contents of this gist into ~/ycm_extra_conf_kernel.py. This may or may not work on all kernels, I’ve had varying levels of success depending on the level of clang support in that kernel version, It does seem to work fine with kernel 3.10.

UPDATE - Aug 25, 2015: Updated this post with links to the full config files and edited the ycm configs to avoid the need for sourcing the build environment.

Mermaid: Javascript Based Sequence Diagrams and Graphs

Mermaid is a nice javascript library to generate sequence diagrams, flowcharts and graphs from markdown-like-syntax. It is based on d3.js.

It also has a command line tool, but there is currently no option to style the output with that tool.

I wanted to use it internally for personal projects along with some CSS styling so I threw together a small webpage using angular that generates mermaid diagrams from it’s syntax. The webapp is located here (source)

Right now, I typically type out the syntax and just take a screenshot with ⌘+Shift+4 to embed it in my documents - though I hope this can be improved with proper sharing features in the future.

UPDATE: The webapp has been merged into the official mermaid repository and is located here

Of Docking Stations and 4k Monitors

Macbook Pros are powerful developer machines that you can hook up monitors and keyboards to to convert into nice workstations. Yet, Apple doesn’t provide any standard dock for them. Enter, the Caldigit Thunderbolt Station, which is a great little docking station for expanding peripherals for devices that support Thunderbolt.

I have a keyboard, mouse, headphones and an Android device for debugging connected to this docking station. Originally, I also had one 4k monitor hooked up as well with DisplayPort 1.1. However, DisplayPort 1.1 is only capable of 4k@30fps. For regular use, 30 fps is too janky for my eyes, so I had to go back to 60 fps. Option one was to go back to a lower resolution - but that’s not progress!

So I chose Option two - which was to switch the display to DisplayPort 1.2, support for which came in a point update to Mavericks.

Unfortunately, the bandwidth on the first version of thunderbolt is still not sufficient to drive the 4k monitor@60 Hz. This meant that I in the end still have to connect two thunderbolt cables to my MBP, one for my peripherals (keyboard, mouse, debug USB cable, ethernet) and the other for the 4k monitor.

I’m happy with this solution though, since I still do not have to plug in all of the other peripherals each morning as I get in to work.

Use Cscope to Browse the Android Source Code

Cscope can be a great tool to browse the Android source code. Here is what I did to get it working with vim

  • Get cscope_maps.vim from here and place it into your ~.vim/plugin directory. (create this dir if it does not exist)
  • Add the following lines to your .vimrc
1
2
3
4
5
6
7
8
9
10
11
set nocsverb
if filereadable("cscope.out")
else
    if $ANDROID_BUILD_TOP !=""
        "This assumes you have sourced the Android build environment
        cscope add $ANDROID_BUILD_TOP/cscope.out
 else
        "Or, you can point to your android source directory in $ANDROID_DIR
        cscope add $ANDROID_DIR/cscope.out
    endif
endif

Use the following shell script to create the Android cscope database. You can add/remove search paths based on relevance to you.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

#!/bin/bash

echo "Listing Android files ..."

find "$PWD/bionic"
"$PWD/bootable"
"$PWD/build"
"$PWD/dalvik"
"$PWD/development"
"$PWD/device"
"$PWD/external"
"$PWD/frameworks"
"$PWD/hardware"
"$PWD/packages"
"$PWD/system"
"$PWD/vendor"
-name '*.java' -print -o
-name '*.aidl' -print -o
-name '*.hpp' -print -o
-name '*.cpp'  -print -o
-name '*.xml'  -print -o
-name '*.mk'  -print -o
-name '*.[chxsS]' -print > cscope.files

echo "Listing Kernel files ..."
find  kernel
-path "kernel/arch/*" -prune -o
-path "kernel/tmp*" -prune -o
-path "kernel/Documentation*" -prune -o
-path "kernel/scripts*" -prune -o
-name "*.[chxsS]" -print >> cscope.files

find "$PWD/kernel/arch/arm/include/"
"$PWD/kernel/arch/arm/kernel/"
"$PWD/kernel/arch/arm/common/"
"$PWD/kernel/arch/arm/boot/"
"$PWD/kernel/arch/arm/lib/"
"$PWD/kernel/arch/arm/mm/"
"$PWD/kernel/arch/arm/mach-msm/" -name "*.[chxsS]" -print >> cscope.files

echo "Creating cscope DB ..."
/usr/bin/cscope -b -q -k
echo "Done"
  • Go to your Android source code directory and run the above script
  • source build/envsetup.sh and lunch/choosecombo as usual
  • open vim - your cscope DB should be sourced into this vim instance
  • Run :cs find f filename to go to a file
  • If you want to go to the definition of a symbol, press Ctrl+]
  • If you want to find all references to the token under the cursor, press Ctrl +\ then s
  • If you want to go to the filename under the cursor, press Ctrl +\ then f
  • The other shortcuts are in the cscope_maps.vim that you downloaded above
  • You can also run :cscope help for more help on cscope in vim