Find global references to struct element using VIM - vim

I'm working with the Linux Kernel, so I installed ctags and cscope to help me find references. However, there's no way to find references to struct->element.
Then, I installed coc.nvim and ccls to see if that would help, but I'm only getting local references to struct->element.
Is there a way to find global references to a struct element inside of VIM?

Your best bet is probably the quickfix list, which can be set using
:grep
:vimgrep (handy when you only want to search, say, files in the argument list ##)
any tool for which you can configure either the output to match the default quickfix pattern-matching, or vice-versa
In your case, I would either do
vim -q <(git grep '->element')
Or I would use the git-jump script in git’s contrib folder:
git jump grep '->element'
You could also load up certain files you care about with one of
vim my files...
or
:args my files...
And then search those with
:vimgrep /->element/ ##

Related

VIM - Sourcing tags from multiple locations in project

Good day,
I typically work on relatively small (less than 20,000 lines of code) projects that are all self contained within a single directory, have their own Makefile, and are fairly easy to work with.
VIM is my preferred editor, and when I open a project, I typically build the ctags list via a mapping to the F10 key:
map <F10> :!ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .<CR>
This allows me to jump to the definition of a variable/struct/etc via moving the cursor over the text, and hitting CTRL+], as well as using code completion with a drop-down list via OmniCppComplete.
However, I am now working on a slightly larger project which makes use of LOTS of structures. Furthermore, many of these structures have arrays of other custom structures as members, so code completion is a very useful and important tool for me right now.
I have two paths that include a lot of .C files and .h files, and they may change from machine to machine. On each machine, however, we have an environment variable in our .bashrc file that points to them like so:
SDK_SRC_PLUS_HEADERS=/public/sdk
THIRD_PARTY_SDK=/private/sdk
I would like to be able to have VIM automatically refer to the contents of these additional paths when I attempt to do code completion (via VIM's built-in OmniCppComplete feature), or to jump to the files in these locations when I use CTRL+] in VIM to jump to the definition of a struct, function, variable, etc.
So, for both of the above paths, I cd into them, and generate the tags via ctags -R. Then, I modified my ~/.vimrc file to include additional tags paths, like so:
tags=./tags
tags+=$SDK_SRC_PLUS_HEADERS/tags
tags+=$THIRD_PARTY_SDK/tags
I then cd into my project at /home/user1/projects/test, start VIM, and hit F10 in VIM to index it. However, this does not work at all. In fact, it breaks my ability to even use tags just for the project itself (ie: CTRL+] now does nothing).
Does anyone have any suggestions on how I could have code completion source tags and jump-to-definitions using multiple source directories via environment variables?
Thank you all in advance for your time and assistance!
I wanted to add to the solution provided by #sehe.
This is the final set of changes I made to my .vimrc. The first lines are for adding expanded environment variable paths to my tags variable. The other is for auto-updating tags in the event that I have to update my SDK and don't want to be able to accidentally use out-of-date tags:
" CTAGS tag generation for OmniCppComplete
set tags+=./tags
exec expand("set tags+=$SDK_SRC_PLUS_HEADERS/tags")
exec expand("set tags+=$THIRD_PARTY_SDK/tags")
" Can verify taglist is correct via ":set verbose tags?" command
" Create a mapping to delete the old tags, re-generate them, and use them
map <F10> :!ctags -R --c++-kinds=+p --fields=+iaS --extra=+q . \| rm -f $SDK_SRC_PLUS_HEADERS/tags \| ctags -R -f $SDK_SRC_PLUS_HEADERS/tags $SDK_SRC_PLUS_HEADERS/tags \| rm -f $THIRD_PARTY_SDK/tags \| ctags -R -f $THIRD_PARTY_SDK/tags $THIRD_PARTY_SDK/tags \| echo "Done re-generating tags."<CR>
It indeed appears to be the problem that you can't use environment variables inside the tags setting.
I came up with this as a workaround:
:let &tags.=expand(",$SDK_SRC_PLUS_HEADERS/tags")
This might be slightly more friendly:
:exec expand("set tags+=$SDK_SRC_PLUS_HEADERS/tags")

How to get ctags working inside vim

I'm new to vim and wanted to get ctags integration working so I can more easily navigate a large java project.
I've pulled down the zip from source forge and extracted it but from here I'm not sure how to get it working with vim
Any help for a novice vim user would be great!
As nobody has given one critical function in these answers, I'll provide one more slightly superior answer.
The easiest way to use ctags with vim is by calling:
ctags -R *
from the root of your source repository. This will generate a tags file in that same directory.
In your ~/.vimrc file, add this short block:
" ctags optimization
set autochdir
set tags=tags;
" denotes a comment. set autochdir tells vim that if it doesn't find a tags file in the $PWD it will look in the directory parent for the tags file, recursively. set tags=tags; tells vim that the name of your tags file will always be the same as the default tags file generated by ctags.
So long as you run ctags -R * in your root source directory the first time and occasionally to update it (if you pull new changes from others) then you'll always have a fast and intuitive ctags symbol lookup in vim.
Using exuberant ctags, I use something like this in my project's base directory (excluding the "log" directory):
ctags -R --exclude=log *
You have to run the ctags command with the source files as arguments. This will create a tags file containing all information. Then you can open a file with vim, and e.g. press Ctrl-] when on a line with a function to jump to the code of that function. If vi isn't started in the same directory as the tag file, you can set it with :set tags=<file>
This is what I'm doing:
ctags -n -f [OUTPUT] [SOURCE] to generate the tags (NOTE: the -n applies to me but may not be necessary for your usage)
exec "set tags=" . [OUTPUT] inside of .vimrc to let vim become of aware of the tags
EDIT: I'm using
Exuberant Ctags 5.5.2
VIM 6.1
Additional info:
See ctags usages here
Tips and tricks from SO
look at this article: vim-easytags. i haven't tried this, but it looks quite good. manually creating and updating tags was really annoying. hope this will help. :)

Vim: Search in Open Buffers

One features I like with Visual Studio is the ability to search in open files only. For example, if I recently did changes to some files and I would like to trace those changes, I might search for a certain word, but only in those files to avoid getting a large list of necessary matches.
Is this possible with Vim?! What I am interested in is being able to open the files I have changed so for using:
gvim `git diff --name-only`
then search those files for what I want.
A nice way to do that is to use vim's internal grep command (:vim):
:vim /pattern/ `git diff --name-only`
:copen
This will open a small window (called quickfix) with the search results and links to open the corresponding files (they don't have to be open).
If you want vim to open up all the files in their own buffers for files that match your diff, you could try this:
gvim $(grep -l pattern $(git diff --relative --name-only))
git diff --relative --name-only shows the changed files in the index but with filenames relative to the current working directory.
grep -l pattern <list of files> will report the filenames that contain a match on pattern. (Note that the pattern just has to exist in the files, not in the git diff output.)
POSIX $() instead of backticks makes using nested commands possible.

Separate srcdir and objdir with vim and gcc

When I'm working in vim, my current working directory (./) contains all my source. I build in an objdir, let's call it ./builddir/. When I build from vim, using makeprg=make\ -C\ builddir, the compiler warnings and errors all have a prefix of ../, which means vim brings the cursor to a file which doesn't exist.
If I try a different tactic, launching vim from the objdir, then I can't do commands like gf or :e myfile.h simply.
Is there a middle ground where all of this will work, like giving vim a second directory to search from if it can't find files in the current working directory? Or maybe getting gcc to use a different prefix?
The most simple solution would be to filter make outputs with sed to replace the output pathnames. (I've implemented a very similar thing to convert cygwin pathnames into windows pathnames for the win32 flavour of vim).
Something like:
:let &makeprg .= '2>&1 | sed "s#^\.\./##g"'
(It may be \| and not |, I don't remember)

How to search across a directory of files in vim?

A common programming task for me in vim is:
:s/some pattern/
do some work
n # finds the next entry
do some work
n # finds the next entry
...
Now, s/.... only searches in the current file.
Is there a way I can do this, but search across a directory of files? Say do "s/..../" over all files in subdirectoires of pwd that ends in .hpp of .cpp ?
Thanks!
You can simply use the :grep command: or for a more complete integration of search tools, use the grep.vim extension.
Simply type :help grep to get a nice documentation of what is available out of the box in Vim.
Using :grep foo *.?pp should do what you want.
This will open the QuickFix list, just like the one you get using :make, enabling to jump to the found occurrences.
There is a fantastic plugin named ctrlsf.vim ,which makes you search in vim efficiently.
Here is a snapshot of it.Quite cool ,isn't it?
For instance , If you want search word like "hello" in current dir , after installation , all you need to do is Simply type:
:CtrlSF "hello"
then you'll get what you expect.
Have fun!
:help windo
:help bufdo
man find
man xargs
find ./start/point -iname "*.cpp" -print0 | xargs -0 vim
:bufdo s/baar/foo/gc
:wall
:qall
gc "global confirm", wall (write all), qall (quite all). To see file list :ls top jump to next file :wn (write next) or :bn (buffer next). By the way, xargs manage large chunks of file in memory to deliver to vim withou erros.

Resources