Reputation: 1144
My vim has path settings as shown below.
path=.,/usr/include,,
I think this is a default setting of 'path' I guess.
Because of this, g f opens c header files under the cursor.
But on C++ file C++ header files are not opened because the C++ header file location is not added to path
variable of vim.
set path+=/usr/include/c++/4.6
I think that this setting on vimrc
would be a solution.
But the problem is the actual directory location for C++ header file would be changed in every different linux distributions and g++ compiler versions.
How can I set path for c++ header files in a portable manner?
let g:gcpp_headers_path = system("g++ --version | grep g++ | awk '{print \"/usr/include/c++/\"$NF}'")
execute 'set path+=' . g:gcpp_headers_path
Now I am using this above: This works with g++ environment. Not tested with other compilers.
Upvotes: 13
Views: 15962
Reputation: 4170
The following Vimscript code, intended for a .vimrc
file, updates path
to include the search paths used by the preprocessor.
if executable('gcc')
let s:expr = 'gcc -Wp,-v -x c++ - -fsyntax-only 2>&1 | grep "^ " | sed "s/^ //"'
let s:lines = systemlist(s:expr)
for s:line in s:lines
execute 'set path+=' . fnameescape(s:line)
endfor
endif
I have similar code in my .vimrc
, but with additional special-case handling.
Upvotes: 0
Reputation: 12950
I recently had the same problem, so here is my solution for documentation purposes:
1) I added the following to my .bashrc
:
# add additional search paths to vim.
VIM_EXTPATHS="$HOME/.vim.extpaths"
if [ ! -e "$VIM_EXTPATHS" ] || [ "/usr/bin/cpp" -nt "$VIM_EXTPATHS" ]; then
echo | cpp -v 2>&1 | \
awk '/^#include </ { state=1 } /End of search list/ { state=0 } /^ / && state { print "set path+=" substr($0, 2) "/**2" }' > $VIM_EXTPATHS
fi
2) I added the following to my .vimrc
:
" add extra paths.
let s:extpaths=expand("$HOME/.vim.extpaths")
if filereadable(s:extpaths)
execute "source ".s:extpaths
endif
On my system, the contents of the .vim.extpaths
file are as follows:
set path+=/usr/lib/gcc/x86_64-linux-gnu/8/include/**2
set path+=/usr/local/include/**2
set path+=/usr/lib/gcc/x86_64-linux-gnu/8/include-fixed/**2
set path+=/usr/include/x86_64-linux-gnu/**2
set path+=/usr/include/**2
The **2
means that ViM will search two directories deep inside these directories. Now gf
will find all the C++ headers I need. If you increase the depth, searches will take a lot more time, so don't set this number too high.
@note: for #include <chrono>
, ViM will go to /usr/include/boost/chrono
, which, funny enough, is a directory. I wonder why go file
will open a directory, maybe this should be reported as a bug. To get to the correct chrono
header you have to type 2gf
.
Upvotes: 2
Reputation: 172608
If there's a limited number of locations, a simple conditional in ~/.vimrc
will do:
if isdirectory('/usr/include/c++/4.6')
set path+=/usr/include/c++/4.6
elseif isdirectory(...
If you have a lot of different systems, and don't want to maintain all variations in a central place, you can move the system-dependent settings to a separate, local-only file, and invoke that from your ~/.vimrc
, like this:
" Source system-specific .vimrc first.
if filereadable(expand('~/local/.vimrc'))
source ~/local/.vimrc
endif
Upvotes: 10
Reputation: 164
There are specific environment variables for the compiler to examine. If you are using gcc/g++ in a linux/Unix environment, then the variables are C_INCLUDE_PATH
and CPLUS_INCLUDE_PATH
. If you are using bash/sh then use export VARIABLE=value
or if you are using csh/tcsh then use setenv VARIABLE value
or if you are using some other shell then you will need to look that up. In these examples VARIABLE
is either C_INCLUDE_PATH
and CPLUS_INCLUDE_PATH
. I hope this helps.
Upvotes: -2