I am linux newbie, but I finally decided to try one, I recently installed openSUSE. On windows 7 I used Visual Studio for c/c++ programming. I tried to find any IDE under linux, tried KDevelop but didn't like it, so i decided to try to setup VIM to be my source code editor.
Firstly I needed to find some auto completion. I read some things about GCCSense and clang_complete but for now installing those things is a bit complicated for me, so I settled for omnicpp and ctags.
I downloaded omnicpp and put those files in ~/.vim folder, I installed ctags. My .vimrc looks like this:
set number
" --- OmniCppComplete ---
" -- required --
set nocp " non vi compatible mode
filetype plugin on " enable plugins
" -- optional --
" auto close options when exiting insert mode
autocmd InsertLeave * if pumvisible() == 0|pclose|endif
set completeopt=menu,menuone
" -- configs --
let OmniCpp_MayCompleteDot = 1 " autocomplete with .
let OmniCpp_MayCompleteArrow = 1 " autocomplete with ->
let OmniCpp_MayCompleteScope = 1 " autocomplete with ::
let OmniCpp_SelectFirstItem = 2 " select first item (but don't insert)
let OmniCpp_NamespaceSearch = 2 " search namespaces in this and included files
let OmniCpp_ShowPrototypeInAbbr = 1 " show function prototype (i.e. parameters) in popup window
" -- ctags --
" map F8 to generate ctags for current folder:
map <F8> :!/usr/bin/ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .<CR>
" add current directory's generated tags file to available tags
set tags=./tags,tags,/home/andrzej/vim/commontags
So to try it I made simple .c file
struct str
{
int aaa;
};
int main()
{
str *wsk;
wsk->aaa=5;
return 0;
}
I press F8 when I am not in input mode, it should generate tag file in place when .c file is located (map :!/usr/bin/ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .) but no such file is generated. What I am doing wrong?
Edit:
Neither vim nor gvim change the current directory for you by default. Therefore, commands will be executed in the current working directory of your environment. In short, if you ran:
cd / && vi ~/prog/c/file.c
you would have the same "problem" with vi that you're having in gvim. That's why I used absolute paths in the binding I showed in my comment. Using autochdir is a reasonable solution, if that's the behavior you're expecting.
Original:
The problem seems to be the + characters. I'd suggest placing your ctags arguments into ~/.ctags:
$ echo -e "--c++-kinds=+p\n--fields=+iaS\n--extras=+q" > ~/.ctags
$ cat ~/.ctags
--c++-kinds=+p
--fields=+iaS
--extra=+q
Then change your mapping to:
map <F8> :!/usr/bin/ctags -R<CR>
Otherwise, you can escape the '+' characters:
map <F8> :!/usr/bin/ctags -R --c\+\+-kinds=\+p --fields=\+iaS --extra=\+q .<CR>
Omni:
Anyone seen or referenced this?
https://llvm.org/svn/llvm-project/llvm/trunk/utils/vim/vimrc
Tags:
Shot from the hip (Read: untested and unverified) Try CD'ing to the current dir.
map <F8> :cd %:p:h <Bar> :!/usr/bin/ctags -R --c\+\+-kinds=\+p --fields=\+iaS --extra=\+q .<CR>
Ok, thanks for all your answers, I found where the source of the problem is. When I run VIM from terminal F8 works fine, when I type !pwd it shows the directory where my .c file is (ex. ~/prog/C), but when I use GvIM and I open the same .c file and type !pwd it shows ~/dokumenty, so I think the problem lies somewhere in VIM/GVIM. I wonder why GVIM doesen't recognize the folder, no matter what file I open?
---edit---
I added set autochdir to my .vimrc and now everything works fine, the problem is solved, but I would be grateful if someone could answer me, why everything was working when i run VIM from terminal(even when autochdir was turned off) but it didn't work for GVIM.
Related
I know YoucompleteMe on base of LLVM, but I want to use OmniCppComplete. This works nice, if I use the modified headers for C++. This modified headers are outdated and doesn't contain anything from C++11.
If noticed that I can modifiy my headers myself e.g.:
$ find . -name '*.h' | xargs sed -i 's/__STL_BEGIN_NAMESPACE/namespace std {/'
$ find . -name '*.h' | xargs sed -i 's/__STL_END_NAMESPACE/}/'
Or use this setting:
let OmniCpp_DefaultNamespaces = ["std", "_GLIBCXX_STD"]
Both doesn't work and of course most headers doesn't have and any file extensions. I've already tried to workaround this by using a list of files. How can I create working CTAGS on base of my current GCC (e.g. /usr/include/c++/...)? What is the common way?
Thank you
This is what I got, if I try to complete something from LIBSTD++:
std::fs
Omni completion (^O^N^P) Back at original
Ctrl+x, Ctrl+o
Omni completion (^O^N^P) Pattern not found
Finally I've written despairingly an email to the author of the modified headers for the LIBSTDC++ (GCC). He answered me promptly (thanks!):
Requirements:
Install vim and vim-omnicppcomplete and ctags (dependency of vim-omnicppcomplete).
Solution:
$ cp -R /usr/include/c++/$GCC_VERSION ~/.vim/cpp_src
# it is not necessary to rename headers without an extension
# replace the "namespace std _GLIBCXX_VISIBILITY(default)" with "namespace std"
$ find . -type f | xargs sed -i 's/namespace std _GLIBCXX_VISIBILITY(default)/namespace std/'
$ ctags -f cpp_tags -R --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ -I _GLIBCXX_NOEXCEPT cpp_src
Edit your ~/.vimrc:
" configure tags - add additional tags here or comment out not-used ones
set tags+=~/.vim/cpp_tags
" build tags of your own project with Ctrl-F12
map <C-F12> :!ctags -R --sort=yes --c++-kinds=+p --fields=+iaS --extra=+q -I _GLIBCXX_NOEXCEPT .<CR>
" OmniCppComplete
let OmniCpp_NamespaceSearch = 1
let OmniCpp_GlobalScopeSearch = 1
let OmniCpp_ShowAccess = 1
let OmniCpp_ShowPrototypeInAbbr = 1 " show function parameters
let OmniCpp_MayCompleteDot = 1 " autocomplete after .
let OmniCpp_MayCompleteArrow = 1 " autocomplete after ->
let OmniCpp_MayCompleteScope = 1 " autocomplete after ::
" also necessary for fixing LIBSTDC++ releated stuff
let OmniCpp_DefaultNamespaces = ["std", "_GLIBCXX_STD"]
" automatically open and close the popup menu / preview window
au CursorMovedI,InsertLeave * if pumvisible() == 0|silent! pclose|endif
set completeopt=menuone,menu,longest,preview
Autocompletion for LIBSTDC++ should now work within vim!
Manuall autocomplete with Ctrl+x -> Ctrl+o.
If you still have trouble with autocomplete, you maybe find a solution in the documentation (see FAQ 7).
Bye
After try hard to search how to create c++-specific tags file using ctags, finally I made desirable progress. Need to say, ctags indeed is a little hard to use, powerful though.
First to emphasize, DONOT ignore -I option (see here for more option info) provided by ctags. It's pretty important for you to see more symbols in the tags file. Simply speaking, ctags cannot process some irregular syntactic statements, for example, prefixed or suffixed with C/C++ macros. If many functions are prefixed or suffixed with some kind of macros, ctags may be very likely to drop it. In the end, you cannot see them when coding.
Here's a way I use to find such macros as more as possible from C++ standard header path, /usr/include/c++/4.9.3 for example, and add them to -I option.
find /usr/include/c++/ -type f -exec grep '_GLIBCXX_' {} \; | grep -v -E '^[#if|#end]' | sort -u > glibcxx.log
After the command, you'll find several macros used in C++ 4.9.3 source files, then choose some of them to be ignored by ctags.
My final command to generate c++ tags file is this:
ctags -R --languages=c++ --langmap=c++:+.tcc. --c++-kinds=+p --fields=+iaS --extra=+qf -I "_GLIBCXX_NOEXCEPT _GLIBCXX_USE_NOEXCEPT _GLIBCXX_NOTHROW _GLIBCXX_USE_CONSTEXPR _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _GLIBCXX_END_NAMESPACE_CONTAINER _GLIBCXX_CONSTEXPR _GLIBCXX_NAMESPACE_LDBL _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_END_NAMESPACE_VERSION _GLIBCXX_VISIBILITY+" -f gcc-4.9.3.tags /usr/include/c++/4.9.3/
Caveat
DONOT forget to write . sign following word tcc, it means match those files without explicit extension name such as vector,set
DONOT forget to write + sign following word VISIBILITY, it means match std _GLIBCXX_VISIBILITY(**)
DONOT forget to write + sign followed by .tcc, it means append the denoted extension to current map of the langugae, otherwise replace the map
I actually use OmniCppComplete too, and have been happily using a C++ only tags file (amongst others. I break my tags files up into smaller pieces, like C++, boost, X11, etc.) for quite a while. Here's the solution I use for generating that tags file on Ubuntu 14.04:
ctags -f cpp_tags --c-kinds=cdefgmstuv --c++-kinds=cdefgmstuv --fields=+iaSmKz --extra=+q --langmap=c++:+.tcc. --languages=c,c++ -I "_GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_END_NAMESPACE_VERSION _GLIBCXX_VISIBILITY+" -n $INC_DIR/* /usr/include/$CPP_TARGET/c++/$CPP_VERSION/bits/* /usr/include/$CPP_TARGET/c++/$CPP_VERSION/ext/* $INC_DIR/bits/* $INC_DIR/ext $SYSTEM/* $SYSTEM2/*
Where:
CPP_VERSION=4.8
INC_DIR=/usr/include/c++/$CPP_VERSION
CPP_TARGET=x86_64-linux-gnu
SYSTEM=/usr/lib/gcc/x86_64-linux-gnu/4.8/include
SYSTEM2=/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed
Please note that the real trick to getting most of the tags generated is the -I option! It may need to be tweaked. Of course, the --c-kinds/c++-kinds and fields options can be adjusted as well.
The final piece is adding:
tags+=cpp_tags
to your .vimrc file to allow the tags to be seen.
All of this requires NO MODIFICATIONS to the headers. If you use a different C++ library, chances are you'll need to fiddle with the -I option to get the tags to show up properly (or even at all).
Now that I think about it, I should probably post this information in the Vim Wiki also.
Your second part about let OmniCpp_DefaultNamespaces can stand some improvement. Try let OmniCpp_DefaultNamespaces = ["std", "_GLIBCXX_STD", "_GLIBCXX_STD_A", "_GLIBCXX_STD_C"]. That's what I use and should allow for more items to be found.
Finally, don't forget about using Vim's CTRL-p to complete the std::fs. It's quite powerful... and no tags file required!
Basically what I want is a keyboard shortcut in vim that lets me [compile and] run the currently being edited C, C++ or Python program. In psuedocode:
when a shortcut key is pressed:
if current_extension == 'c' then
shell: gcc this_filename.c -o this_filename_without_extension
if retcode == 0 then shell: ./this_filename_without_extension
else if current_extension == 'cpp' then
shell: g++ this_filename.cpp -o this_filename_without_extension
if retcode == 0 then shell: ./this_filename_without_extension
else if current_extension == 'py' then
shell: python this_filename.py
end if
end key
I realise I might be asking a bit much but would love it if this was possible!
Something like this would work. Just create filetype autocmd that map <F4> or whatever you want to save and compile and run the program. It uses exec to build the string and uses shellescape to escape the file name.
autocmd filetype python nnoremap <F4> :w <bar> exec '!python '.shellescape('%')<CR>
autocmd filetype c nnoremap <F4> :w <bar> exec '!gcc '.shellescape('%').' -o '.shellescape('%:r').' && ./'.shellescape('%:r')<CR>
autocmd filetype cpp nnoremap <F4> :w <bar> exec '!g++ '.shellescape('%').' -o '.shellescape('%:r').' && ./'.shellescape('%:r')<CR>
% is the current buffer filename. %:r is the buffer filename without extension
http://singlecompile.topbug.net seems to do more than what you want. For a simpler solution you could also just add the following to your vimrc
au BufEnter *.cpp set makeprg=g++\ -g\ %\ -o\ %<
au BufEnter *.c set makeprg=gcc\ -g\ %\ -o\ %<
au BufEnter *.py set makeprg=python\ %
au BufEnter *.[rR] set makeprg=Rscript\ %
map <F5> :call CompileGcc()<CR>
func! CompileGcc()
exec "w"
silent make
endfunc
HTH
It's 2018 now, vim 8 has released for 2 years and shipped with all the mean stream Linux distributions and Mac OS X. But a lot of vim tutorials are still teaching people something ten years ago.
You can compile your C++/Java programs in vim as convenience as Sublime Text or NotePad++ with some dedicated plugins for Vim 8 or NeoVim.
For example, the AsyncRun plugin will allow you run shell commands in background and read output from quickfix window in realtime.
See the screen capture.
Just like compiling programs in IDEs, the compilation errors will be matched by errorformat and be highlighted and become selectable. You can navigate errors in the quickfix window or continue editing while compiling.
Quick setup
Copy & paste the lines below to your vimrc:
Plug 'skywind3000/asyncrun.vim'
" open quickfix window automatically when AsyncRun is executed
" set the quickfix window 6 lines height.
let g:asyncrun_open = 6
" ring the bell to notify you job finished
let g:asyncrun_bell = 1
" F10 to toggle quickfix window
nnoremap <F10> :call asyncrun#quickfix_toggle(6)<cr>
When you input “:AsyncRun echo hello ” in the command line:
see the capture here
You will see the realtime command output in the open quickfix window.
Compile and run a single file
Compiling a single file with AsyncRun is much simpler than Sublime Text’s build system. We can setup F9 for this:
noremap <silent> <F9> :AsyncRun gcc -Wall -O2 "$(VIM_FILEPATH)" -o "$(VIM_FILEDIR)/$(VIM_FILENOEXT)" <cr>
The macros in $(..) form will be expanded as the real file name or directory, and then we will have F5 to run the executable:
noremap <silent> <F5> :AsyncRun -raw -cwd=$(VIM_FILEDIR) "$(VIM_FILEDIR)/$(VIM_FILENOEXT)" <cr>
The double quotation mark is used to handle path names containing spaces. The option -cwd=$(VIM_FILEDIR) means running the file in the file's directory. The absolute path name $(VIM_FILEDIR)/$(VIM_FILENOEXT) is used because linux needs a ./ prefix to running executables in current directory, but windows doesn't . Using the absolute path name of the binary file can handle this crossing platform issue.
Another option -raw means the output will not be matched by vim's errorformat, and will be displayed in quickfix as what it is. Now you can compile your file with F9, check the compilation errors in quickfix window and press F5 to run the binary.
Build C/C++ Projects
No matter what build tool you are using, make or cmake, project building means acting to a group of files. It requires locating the project root directory. AsyncRun uses a simple method called root markers to identify the project root. The Project Root is identified as the nearest ancestor directory of the current file which contains one of these directories or files:
let g:asyncrun_rootmarks = ['.svn', '.git', '.root', '_darcs']
If none of the parent directories contains these root markers, the directory of the current file is used as the project root. This enables us to use either <root> or $(VIM_ROOT) to represent the project root. and F7 can be setup to build the current project:
noremap <silent> <F7> :AsyncRun -cwd=<root> make <cr>
What if your current project is not in any git or subversion repository ? How to find out where is my project root ? The solution is very simple, just put an empty .root file in your project root, it will be located easily.
Let’s move on, setup F8 to run the current project:
noremap <silent> <F8> :AsyncRun -cwd=<root> -raw make run <cr>
The project will run in its root directory. Of course, you need define the run rule in your own makefile. then remap F6 to test:
noremap <silent> <F6> :AsyncRun -cwd=<root> -raw make test <cr>
If you are using cmake, F4 can be map to update your Makefile:
nnoremap <silent> <F4> :AsyncRun -cwd=<root> cmake . <cr>
Due to the implementation of c runtime, if the process is running is a non-tty environment, all the data in stdout will be buffered until process exits. So, there must be a fflush(stdout) after your printf statement if you want to see the real-time output. or you can close the stdout buffer at the beginning by
setbuf(stdout, NULL);
At the mean time, if you are writing C++ code, a std::endl can be appended to the end of std::cout. It can force flush the stdout buffer. If you are developing on windows, AsyncRun can open a new cmd window for the child process:
nnoremap <silent> <F5> :AsyncRun -cwd=$(VIM_FILEDIR) -mode=4 "$(VIM_FILEDIR)/$(VIM_FILENOEXT)" <cr>
nnoremap <silent> <F8> :AsyncRun -cwd=<root> -mode=4 make run <cr>
Using the option -mode=4 on windows will open a new prompt window to run the command, just like running command line programs in Visual Studio. Finally, we have these key mappings below:
F4: update Makefile with cmake.
F5: run the single file
F6: run project test
F7: build project
F8: run project
F9: compile the single file
F10: toggle quickfix window
It is more like build system in NotePad++ and GEdit. If you are using cmake heavily, you can write a simple shell script located in ~/.vim/script/build.sh to combine F4 and F7 together: it will update Makefile if CMakeList.txt has been changed, then exectute make.
Advanced usage
You can also define shell scripts in your dotfiles repository and execute the script with F3:
nnoremap <F3> :AsyncRun -cwd=<root> sh /path/to/your/dotfiles/script/build_advanced.sh <cr>
The following shell environment variables are defined by AsyncRun:
$VIM_FILEPATH - File name of current buffer with full path
$VIM_FILENAME - File name of current buffer without path
$VIM_FILEDIR - Full path of current buffer without the file name
$VIM_FILEEXT - File extension of current buffer
$VIM_FILENOEXT - File name of current buffer without path and extension
$VIM_CWD - Current directory
$VIM_RELDIR - File path relativize to current directory
$VIM_RELNAME - File name relativize to current directory
$VIM_ROOT - Project root directory
$VIM_CWORD - Current word under cursor
$VIM_CFILE - Current filename under cursor
$VIM_GUI - Is running under gui ?
$VIM_VERSION - Value of v:version
$VIM_COLUMNS - How many columns in vim's screen
$VIM_LINES - How many lines in vim's screen
$VIM_SVRNAME - Value of v:servername for +clientserver usage
All the above environment variables can be used in your build_advanced.sh. Using the external shell script file can do more complex work then a single command.
Grep symbols
Sometimes, If you don't have a well setup environment in you remote linux box, grep is the most cheap way to search symbol definition and references among sources. Now we will have F2 to search keyword under cursor:
if has('win32') || has('win64')
noremap <F2> :AsyncRun! -cwd=<root> grep -n -s -R <C-R><C-W> --include='*.h' --include='*.c*' '<root>' <cr>
else
noremap <F2> :AsyncRun! -cwd=<root> findstr /n /s /C:"<C-R><C-W>" "\%CD\%\*.h" "\%CD\%\*.c*" <cr>
endif
The above script will run grep or findstr in your project root directory, and find symbols in only .c, .cpp and .h files. Now we move around the cursor and press F2, the symbol references in current project will be displayed in the quickfix window immediately.
This simple keymap is enough for most time. And you can improve this script to support more file types or other grep tools in your vimrc .
That’s the practical way to build/run C/C++ projects in Vim 8 or NeoVim. Just like Sublime Text’s build system and NotePad++’s NppExec.
No more outdated vim tutorials again, try something new.
this is my map it really work you can update it to any language:
" <!----------------------------" gcc compile C files----------------------------------------!>
autocmd filetype c nnoremap <Leader>c :w <CR>:!gcc % -o %:r && ./%:r<CR>
" <!----------------------------" java compile files----------------------------------------!>
autocmd filetype java nnoremap <Leader>c :w <CR>:!javac % :r&& java %:r<CR>
" <!----------------------------" php compile files----------------------------------------!>
autocmd filetype php nnoremap <Leader>c :w <CR>:!clear && php %<CR>
now if you are ine one of those file in vim just do in normal mode:
<leader>c
I know I came here 7 years later. I tried the code of other answers and the result didn't satisfied me, so I tried this:
autocmd filetype cpp nnoremap <F9> :w<bar>term ++shell g++ %:p -o %:p:r && %:p:r<CR>
When F9 is pressed, it (like all the answers above) compiles and executes the current file. The output is displayed in a :terminal section splitted screen.
You can change the g++ command to run another language code.
It is saved in a gist, with another mapping to display the output, also in a splitted section, but in a new file, so you can save the output.
Hopefully it could help someone.
I wanted to find a shortcut too. But I didn't want to use autocmd for some reason. I used bash script. I was already using a bash script to compile and run my C/C++ codes. So, I thought, why don't I use a bash script and use it in fltplugin file for C and C++. I made two separate bash scripts. One for C and one for C++. Here is the script for C (For C++, it is also similar just change the compiler to clang++/g++,
std=c2x to std=c++20 and $filename.c to $filename.cpp),
filename=$1
compiler=clang-10
if [ $2 ]; then
if [ $2 == "-v" ]; then
FLAGS="-g -Wall -Wextra -pedantic -std=c2x"
fi
else
FLAGS="-Wall -Wextra -pedantic -std=c2x"
fi
$compiler $FLAGS $filename.c -o $filename -lm
return_value=$?
if [ $return_value -eq 0]; then
if [ $2 ]; then
if [ $2 == "-v" ]; then
valgrind ./$filename
rm $filename
fi
else
./$filename
echo
echo "[process exited $return_value]"
rm $filename
fi
fi
Saved it as run. I made it executable for all users,
$ chmod 777 run
I moved it to my user bin directory.
$ mv run ~/bin
If you dont have a user bin directory, make on. Go to your home directory, and make a directory named bin.
$ cd ~
$ mkdir bin
Then move the run (or whatever name you gave to your script) file to the bin directory.
$ mv run ~/bin
Let's move on.
Then I made a c.vim file in ~/.vim/after/ftplugin directory. And add two new key remaps to the c.vim file.
nnoremap <F9> :vertical bo term run %:r<CR>
# This will run my code with valgrind
nnoremap <F2> :vertical bo term run %:r -v<CR>
Here are some screen shots,
Clicking F9 shows me the output screen in a vim buffer,
Clicking F2 shows me the output using valgrind in a vim buffer
You can do same for C++, just make a cpp.vim file in ~/.vim/after/ftplugin directory. And make another run file (like run_cpp), save it in your user bin(~/bin) file. Make some custom key bindings, and you are good to go.
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.
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
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.
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.
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.
I've just download sublime text 2 beta 2182 under ubuntu 10.10 with Exuberant Ctags 5.8
I want to use it for c++ coding and I need some auto completition and code navigation. (I was used to eclipse with cdt)
I googled and I found ctags a cool tool that can do it, and there is a plugin support for sublime text here.
The problem is that I want create tag file from:
c++ standard lib (std::vector std::map etc)
all classes of the framework i'm using.
Point 1 is (i think) the same of point 2, I just only have to create a tag list of std lib in my /usr/include/c++/4.4.5/
so I've downloaded the plugin and installed it, I made a taglist in this way:
$ cd /absolute_path_of_my_cpp_framework/
$ ctags -R *
I modified /home/me/.config/sublime-text-2/Packages/CTagss/CTags.sublime-settings with this line:
"extra_tag_files" : [".gemtags", "/absolute_path_of_my_cpp_framework/tags"]
Now I open a cpp file, point the cursor on a class name of my framework and used the key binding ctrl+t ctrl+t and nothing happened. Only this message in the bar in the bottom:
can't find "class_name"
Can someone help me?
I don't personally use Sublime Text, but assuming it uses tag files in a similar manner to vim, you need to generate additional info for C++ completion.
Use ctags with the following options:
ctags -R --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++
Info was taken from this article, which also supplies copies of the standard library headers that you can use to generate tags.
Shell Commands:
$ cd /absolute_path_of_my_cpp_framework/ (1)
$ ctags -R --languages=c++ --langmap=c++:+.inl --fields=+iaS --extra=+q --totals=yes --verbose=yes (2)
$ ctags -a -R --languages=c++ /usr/include/c++/4.4.5/ --fields=+iaS --extra=+q --totals=yes --verbose=yes (3)
$ subl . (4)
Description:
(1) Go to the root folder of your project to ensure that the tags file will be created there.
(2) Generate a new tags file for all C++ files in your project, adding support for .inl files, inheritance, access modifiers, class-qualified scoping etc.
(3) Append tags for the C++ standard lib headers to your generated tags file.
(4) Open the folder in Sublime Text.
References:
http://ctags.sourceforge.net/ctags.html
https://www.chromium.org/developers/sublime-text
http://www.tarosys.com/2014/07/adding-another-file-type-for-ctags.html
Exuberant ctags exclude directories
Vim and Ctags: Ignoring certain files while generating tags
https://www.topbug.net/blog/2012/03/17/generate-ctags-files-for-c-slash-c-plus-plus-source-files-and-all-of-their-included-header-files/
How do I enable auto completion in Vim?
I tried to do this one, but I'm not proficient with the vimrc file, etc., so it didn't work out. Can you give me step by step instructions on how to do this?
Edit
I tried installing OmniCppComplete. Followed the instructions, but when I try to use it I get the following error:
Error detected while processing function omni#cpp#complete#Main..24_InitComplete:
line 24:
E10: \ should be followed by /, ? or &
Vim by default will do completion based on words in the file using Ctrl-N or Ctrl-P, which is handy for recently referenced local variables etc, and works for code in any language or even ordinary text (handy for completing difficult to spell names). However it doesn't do this semantically or with reference to what actual types you're allowed in the particular context you're writing. For this you will need to install ctags, and then in /usr/include type:
ctags -f ~/.vim/stdtags -R --c++-kinds=+p --fields=+iaS --extra=+q .
And then add this to your .vimrc:
set nocp
filetype plugin on
map <C-L> :!ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .<CR><CR>
set tags=~/.vim/stdtags,tags,.tags,../tags
autocmd InsertLeave * if pumvisible() == 0|pclose|endif
That will also make Ctrl-L reload tags, and thus pick up new autocomplete tags, from the current directory.
Detailed instructions Auto complete (archive.org) Type in first few characters and press Ctrl->P(for backward search) or Ctrl->N(for forward search), list down all options available or completes it.
I use vim7.2 (auto complete was introduced in vim7) and these controls work just fine.
My favorite is clang_complete here. It's very easy to install and the default configuration in the ReadMe document works good. You don't need to generate the tags,
It automatically show the complete options when available. It also can highlight the
syntax errors.