emacs drill down shortcut - c++

I am new to emacs. In Netbeans, you can right click on any object and it will send you directly to the header or implementation file. Is there a shortcut key to do this in emacs?

You have to create a TAGS file first.
If you're on linux:
$ ctags -e -R *.h *.cpp
// this will create tags for all .h and .cpp files,
// starting from the current directory, and recursing into subdirectories.
// -e : emacs tags (as oposed to vi tags, the default)
// -R : recursive
You can also add to an existing tags file by using the --append flag. For example:
$ ctags --append -e -R *.h *.cpp /home/user/jdoe/thirdparty
// This will add to the TAGS file in the current directory
When you want to jump to a symbol definition, in emacs use M-x find-tag, or M-.. It'll ask you where the TAGS file is, and you're set. To pop out, use M-x pop-tag-mark, by default mapped to M-*.
Note: ctags is alright, but since it's not a compiler, sometimes it'll take you to the wrong place.

You can use etags to provide a similar functionality. Once your TAGS file is created, you can use the M-. shortcut that invokes (find-tag).

As with everything: Emacs gives you several ways to do something, in this case a bunch of them don't work out of the box. You can either use etags or if you need a really big hammer semantic, which is part of the cedet project. This will give you much more then simply jumping into a header file, but maybe that is what you need.

Related

How to jump to a C/C++ function declaration instead of its definition?

I know CTRL+] to jump to definition of a function in various languages in vim.
What about jump to declaration in C/C++ header?
Since I have plenty of headers containing meaningful comments/explanations, I would frequently find function declarations among a large code base. Is there some sorts of shortcuts to do this?
ctags does not add function prototypes by default. You have to add the option
--c++-kinds=+p
to support function prototypes.
My ctags looks like this:
ctags --c++-kinds=+p --fields=+iaS --extra=+q *.h *.c
When you are at a tag, you can use the following editor commands to browser through the tags (Meaning the same tag occuring multiple times as definition/declaration)-
tn (Next Tag)
tp (Previous Tag)
Based on Bram's 7 habits, without any plugin, you can do
1) Set the path to your headers(This is crucial to work with point 2 below)
:set path+=/path/to/headers
2) Then do one of the following command
[I Display all list where keyword under cursor is in header files or
[<Tab> will jump there and you can come back to your file using Ctrl+6
I am satisfied with cscope, which includes header files in database.
Just put cscope_maps.vim in ~/.vim/plugin/ and then CTRL-] will list all choices if a cscope database is built.
To build a cscope database, just type
cscope -bR

auto fold for C++ sources and headers

I have heard that Vim has a built-in support of folding for the files written in various programming languages. Particularly I'm interested in cpp, h, hpp files. I would like to achieve such a behavior of Vim when all the function definitions are folded by default in every newly opened source file. I don't want to create every fold manually with zF.
I added the following lines to the end of ~/.vimrc file (which was inherited from spf13-vim distribution):
set foldenable
autocmd FileType c,cpp,h,hpp setlocal foldmethod=syntax
Unfortunately that did not resulted to the desired behaviour. All the files look just the same, and my attempt to hide the function with zc combo leads to error:
E490: No fold found
I would be glad if someone could explain how to enable folding by default in Vim 7.4.
UPD: The code above works good, but there is still an issue with the recently opened files. Say we work on the project called 'sc-client-server' and we've just appended those two lines to ~/.vimrc and now ready to get back to the last edited file:
$ vim ~/.vimrc //Modify config
$ reboot
$ vim ~/progs/sc-client-server/src/st.cpp //No fold found. BUT:
$ cp ~/progs/sc-client-server/src/st.cpp /tmp
$ vim /tmp/st.cpp //Auto fold works fine. OR:
$ cd ~/progs/sc-client-server/src/ && mv src source
$ vim ~/progs/sc-client-server/source/st.cpp //Auto fold works fine.
Is there any kind of cache or memory inside of Vim that prevents the desired file representation?
Answer
Remove all (or specific for you) files from ~/.vimviews folder.
To the off-topic voters https://meta.stackexchange.com/questions/25925/vim-questions-do-they-belong-to-stack-overflow-or-super-user/25930#25930?newreg=00a4918bba924cfa8b1d6a3e82061672

Vim, C++, YCM, and Syntastic include path problems

I feel that I have an awesome setup for C++ programming using Vim but I can't find a way to tell Vim, YCM, and Syntastic where to search for headers. It would be really annoying to have to manually set the include path variables for Vim, YCM, and Syntastic every time I want to work on a project when this information exists in the Makefile. Is there any automated solutions for setting a global include path?
Edit: It won't even find the headers if I set the path like this ":set path = ".,/usr/include,include,../include,/home/steven/ovgl/include,,""
Your headers should appear in your tag files (see :h tags if you don't know about it).
Then YouCompleteMe is able to read the information about your headers from the tag file, as explained in the plugin faq:
YCM does not read identifiers from my tags files
First, put let g:ycm_collect_identifiers_from_tags_files = 1 in your vimrc.
Make sure you are using Exuberant Ctags to produce your tags files since
the only supported tag format is the Exuberant Ctags format. The format
from "plain" ctags is NOT supported. The output of ctags --version should
list "Exuberant Ctags".
Ctags needs to be called with the --fields=+l (that's a lowercase L, not a
one) option because YCM needs the language:<lang> field in the tags
output.
NOTE: Mac OS X comes with "plain" ctags installed by default. brew install
ctags will get you the Exuberant Ctags version.
Also make sure that your Vim tags option is set correctly. See :h 'tags'
for details. If you want to see which tag files YCM will read for a given
buffer, run :echo tagfiles() with the relevant buffer active. Note that
that function will only list tag files that already exist.
You shold look for YCM-Generator. It is a script that generates ycm_extra_conf.py by running make and looking for all flags used. You run it once for project, and rerun only when make file changed.
I had faced a similar issue. I needed this for use with development using llvm.
I solved it by following the below steps:
Ctags -R --fields=+l * in your project/code base.
In your user .vimrc file, add let g:ycm_collect_identifiers_from_tags_files = 1
cp ~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp/ycm/.ycm_extra_conf.py ~/
Add another line in .vimrc let g:ycm_global_ycm_extra_conf = '/home/<user>/ycm_extra_conf.py'
reset terminal or hit bash
Note: You should start vim in the directory with the tags present in it. Or you may need to explicitly specify the directory where the tags are present.

Automatically fix filename cases in C++ codebase?

I am porting a C++ codebase which was developed on a Windows platform to Linux/GCC. It seems that the author didn't care for the case of filenames, so he used
#include "somefile.h"
instead of
#include "SomeFile.h"
to include the file which is actually called "SomeFile.h". I was wondering if there is any tool out there to automatically fix these includes? The files are all in one directory, so it would be easy for the tool to find the correct names.
EDIT: Before doing anything note that I'm assuming you either have copies of the files off ot the side or preferably that you have a baseline version in source control should you need to roll back for any reason.
You should be able to do this with sed: Something like sed -i 's/somefile\.h/SomeFile.H/I' *.[Ch]
This means take a case-insensitive somefile (trailing /I) and do an in-place (same file) replacement (-i) with the other text, SomeFile.H.
You can even do it in a loop (totally untested):
for file in *.[Ch]
do
sed -i "s/$file/$file/I" *.[Ch]
done
I should note that although I don't believe this applies to you, Solaris sed doesn't support -i and you'd have to install GNU sed or redirect to a file and rename.
Forgive my, I'm away from my linux environment right now so I can't test this myself, but I can tell you what utilities you would need to use to do it.
Open a terminal and use cd to navigate to the correct directory.
cd ~/project
Get a list of all of the .h files you need. You should be able to accomplish this with the shell's wildcard expansion without any effort.
ls include/*.h libs/include/*.h
Get a list of all of the files in the entire project (.c, .cpp, .h, .whatever), anything that can #include "header.h". Again, wildcard expansion.
ls include/*.h libs/include/*.h *.cpp libs/*.cpp
Iterate over each file in the project with a for loop
for f in ... # wildcard file list
do
echo "Looking in $f"
done
Iterate over each header file with a for loop
for h in ... # wildcard header list
do
echo "Looking for $h"
done
For each header in each project file, use sed to search for #include "headerfilename.h", and replace with #include "HeaderFileName.h" or whatever the correct case is.
Warning: Untested and probably dangerous: This stuff is a place to start and should be thoroughly tested before use.
h_escaped=$(echo $h | sed -e 's/\([[\/.*]\|\]\)/\\&/g') # escapes characters in file name
argument="(^\s*\#include\s*\")$h_escaped(\"\s*\$)" # I think this is right
sed -i -e "s/$argument/\$1$h\$2/gip"`
Yes, I know it looks awful.
Things to consider:
Rather than going straight to running this on your production codebase, test it thoroughly first.
sed can eat files like a VCR can eat tapes.
Make a backup.
Make another backup.
This is an O(N^2) operation involving hard disk access, and if your project is large it will run slowly. If your project is not gigantic, don't bother, but if it is, consider doing something to pipe sed's output to other seds.
Your search should be case insensitive: it should match #include, #INCLUDE, #iNcLuDe, and any combination of case present in the existing header filename, as well as any amount of whitespace between the include and the header. Bonus points if you preserve whitespace.
Use Notepad++ to do a 'Find in Files' and replace.
From toolbar:
Search - Find in Files.
Then complete the 'Find what' and 'Replace with'.

Help with automated renaming in C++

Here is my issue:
I have a large library of code where all of the class names begin with Agui. For example:
class AguiWidget
{
};
class AguiBitmap
{
};
also, all the hpp and cpp files are named like this also:
AguiWidget.hpp
etc.
The library also does not use a namespace.
all of the enums begin and use Agui:
ex:
enum AguiKeyEnum
{
AGUI_KEY_SPACE,
AGUI_KEY_ENTER
};
The include guards also use ex:
AGUI_WIDGET_HPP
So,
My task is to remove all the Agui, AGUI references from the entire project (all the classes and enums), then to encapsulate all the classes into namespace agui.
What would be the easiest way to do this. I also need the hpp and cpp files to no longer have Agui in the filename.
I use MSVC 2008 as an IDE if that helps.
Thanks!
You need to use a global find and replace tool. If you have Visual Studio 2008, then it is already built-in. Once you rename all the classes and namespaces, then use another tool to rename the files or build a script to do it for you.
As a Linux user (which you aren't, but you could use Cygwin or a separate machine), I'd use the program sed to strip the prefixes. I'd start with this, then review the diffs vs. source control:
sed -i 's/Agui//g; s/AGUI_//g' *.hpp *.cpp # and maybe *.sln *.proj
Then, renaming the files:
for f in *.hpp *.cpp; do mv $f ${f#Agui}; done # or source control's mv
Then all that's left is to add namespacing. You could probably get this done using sed as well, but if the number of files is not huge I'd just do it by hand. The namespace closing braces are trivial to add though:
for f in *.hpp *.cpp; do (echo '} // namespace agui' >> $f); done
The opening braces you might want to take a little more care to add, depending on your existing code's structure.
Oh, and look, sed for Windows: http://gnuwin32.sourceforge.net/packages/sed.htm (I haven't used this).
I would suggest either using
cygwin + recursive find + script - use sed for changing names, mv to change files
or figuring how to do the equivalent in powershell.
With the right regular expressions it should work fine.
Make sure to copy the entire directory structure before editing, as it may take a few iterations to debug.