Vim shift * in reverse to move to function call - vim

When using vim,
I frequently shift-* my function calls to go to the function. If I know the function is above my cursor, but there are many functions below, how do I shift-* in reverse?

* in Normal mode will do a forward search of the word under the cursor. From there, you can press n to get the next instance of the word, or you can press N to get the previous instance of the word.
To answer the question of searching backwards, you can use the # to do a reverse search for the current word. From there, pressing n will get the next instance up, while N will reverse the reverse and search forward for the next instance.
To do what you really want to do, which is jump to a function definition, consider using ctags. If you create tags for your project with a utility like ctags or etags, you can use ctrl-] to jump to the definition of a function under the cursor. If it's in the same file (which considering you are doing a search to get this kind of functionality, should apply to your current situation), I think it may be able to work to some extent even without setting up the tags file.
If you are also interested in finding where a function is called (in c, at least), there's another utility called cscope that can be of help. Like with the ctags, you'll need to build the cscope.out file using the cscope utility. Once you do, you can use vim's cscope hooks. To get a list of calls to a function with cscope, you can invoke it with this (note that is CTRL-R):
:cs find c <C-R>=expand("<cword>")
That's a bit of a handful to write out all the time, so I put this in my .vimrc so it can be invoked g[:
nnoremap g[ :cs find c <C-R>=expand("<cword>")<CR><CR>

Related

What's the vim way to select multiple instances of current word and change them?

Anyone familiar with Sublime Text's multiple cursor feature will recognize the pattern of doing the following: press a hotkey multiple times to select multiple instances of the word under the cursor and automatically create a new cursor for each of those instances; then edit each instance simultaneously, e.g. by replacing the current word with another word or whatever you want.
The multiple cursors feature is available for vim via plugin. Before using that plugin, I want (as a new vim user), to check whether there is a more natively vim-like way to achieve the same task.
For instance, I know I could use the :s command to do a search and replace (per instructions here), but that requires me to (1) type in the word I want to replace (or use the <C-r><C-a> shortcut to do so), as opposed to simply using the current word and (2) define a range. Perhaps this is the native vim way to do it, perhaps (likely!) there's another way I don't know.
So what is the native vim way?
I use the *, gn, and the . to make changes.
Select current word with * (go back with N)
Change word with gn motion. e.g. cgnfoo<esc>
Repeat via . command
Note: If you have many changes then using a substitution command would probably be better.
There is a nice Vimcasts episode about the gn motion: Operating on search matches using gn.
For more help see:
:h *
:h gn
:h .
You can record macros in Vim by pressing q<letter>. Macros can include the n command to search for the next instance of a word. You can also go into insert mode while recording (e.g. using the c command with a motion such as iw to replace the current word). Press q to stop recording, and then press #<letter> to replay the macro once. After that, you can use ## to repeat the macro as many times as you like.
While waiting for other answers, I'm going to post what I'm experimenting with while waiting for vim experts to answer:
:.,$s/<C-r><C-a>/foobar/gc
to substitute (the s) from the current line (the .) to the last line ($) (with the comma denoting the line range), using the <C-r><C-a> combo to copy the current word into the command, then using gc to change with confirmation, so I can hit yes/no for each instance then quit when I've done enough.

Not highlighting search in vim if it is a part of a command

In my .vimrc I've enabled highlighting the searched text (which I find to be a handy feature and wouldn't want to disable it).
set hlsearch
And, following answers to this question, I've made a mapping to be able to clear the highlight:
nmap <silent> ,/ :nohlsearch<CR>
The problem comes with commands which include search. For example, delete to next character 'x':
d/x
This will automatically highlight all the instances of 'x'. To remove this highlight I have to punch ,/ to clear it, which is quite annoying.
The question. Is it possible to enforce :nohl if the search is a part of a preceding command? Maybe, it is possible at least for a selected list of commands (say, d, y and c) before / character is hit?
d/x does not work for me as you describe. (I'm on vim 7.3 here and it can't make sense of the / following d in normal mode, so disregards the d and starts a regular / search.)
If you want to delete to the next x, then dfx or dtx are what I would use (depending on whether you want to also delete the x itself or not).
No highlighting involved.
Hope that helps.
[Following some clarification in the comments.]
I'm thinking that it should be possible to write a custom function to do what you want, and then assign a custom key sequence to call that function.
I played around a little, but am not very well versed in vim functions and couldn't make it work.
Here's what I tried:
function! g:DeleteToSearchAndNohls(term)
:normal d/a:term
:nohlsearch
endfunc
If 'x' is on the same line than the cursor, you can use dtx (meaning delete to x).

"Find next" in Vim

To search forward in Vim for cake, I'd type /cake, but the cursor jumps to the first match when I press return. Is there a Vim command analogous to "find next"?
It is n for next and N for previous.
And if you use reverse search with ? (for example, ?cake) instead of /, it is the other way round.
If it is installed on your system, you should try to run vimtutor command from your terminal, which will start a tutorial of the basic Vim commands.
Rob Wells advice about * and # is also very pertinent.
The most useful shortcut in Vim, IMHO, is the * key.
Put the cursor on a word and hit the * key and you will jump to the next instance of that word.
The # key does the same, but it jumps to the previous instance of the word.
It is truly a time saver.
When I was beginning I needed to watch a demo.
How to search in Vim
type /
type search term e.g. "var"
press enter
for next instance press n (for previous N)
You may be looking for the n key.
Typing n will go to the next match.
As discussed, there are several ways to search:
/pattern
?pattern
* (and g*, which I sometimes use in macros)
# (and g#)
plus, navigating prev/next with N and n.
You can also edit/recall your search history by pulling up the search prompt with / and then cycle with C-p/C-n. Even more useful is q/, which takes you to a window where you can navigate the search history.
Also for consideration is the all-important 'hlsearch' (type :hls to enable). This makes it much easier to find multiple instances of your pattern. You might even want make your matches extra bright with something like:
hi Search ctermfg=yellow ctermbg=red guifg=...
But then you might go crazy with constant yellow matches all over your screen. So you’ll often find yourself using :noh. This is so common that a mapping is in order:
nmap <leader>z :noh<CR>
I easily remember this one as z since I used to constantly type /zz<CR> (which is a fast-to-type uncommon occurrence) to clear my highlighting. But the :noh mapping is way better.
If you press Ctrl + Enter after you press something like "/wordforsearch", then you can find the word "wordforsearch" in the current line. Then press n for the next match; press N for previous match.

ctags: prevent jump to first result for ctrl + ]

I wanted to prevent jumping to the first result without user intervention upon ctrl +] (or left click) in vim. In effect, when I click (ctrl +]) on an identifier, it should list all the occurance (like tag search) and should jump to the selection (1,2..) when user input 1,2 etc. I remember using it by setting an option in .vimrc (something like cscope mode), but couldn't recollect now.
Are you looking for tag-matchlist?
Sounds like you want g]. It shows the matching tags.
While I don't think there's an option to make Ctrl+] show a list if there's only one result, if you set cscopetag and set cscopetagorder=0, then you'll search your cscope database which will likely show more results than your tags. (Especially if you're using C++ and have --c++-kinds=+p which will include function prototypes and the implementations -- you almost always have two of the same thing. I use that setting because it's required by omnicppcomplete.)
You still won't get a list if you only have one result. For that, you'd have to make maps to swap Ctrl+] and g].
You can add the following line in .vimrc
map <C-]> g]

Jump to function definition in vim, without using plugins or ctags

is it possible to jump to function definitions in vim without using plugins or ctags?
and if so, how?
a related question:
Jump to function definition in vim
Were it possible, why would anybody write a plug-in or use ctags?
So let us assume that it is not.
You can use # and * to search backwards and forwards (respectively) for the word under your cursor in the current buffer.
Or you can use :vimgrep and CTRL-R CTRL-W to search for the word under the cursor in a given path.
Of course these match words, not function definitions, so they may match calls to a given function or variables with the same name. But that's th price you'd have to pay for not using ctags, I guess.

Resources