12

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.

4

4 回答 4

10

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
于 2013-04-10T06:40:29.943 回答
1

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.

于 2018-11-08T13:22:21.777 回答
0

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.

于 2019-12-26T00:59:08.383 回答
-2

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.

于 2013-04-10T01:42:30.007 回答