VIM :changes list - direct jump to a specific change - vim

Is there any way to jump to the nth item in VIM change list?
I know that it is possible sequentially but I am looking for a direct jump solution.

Related

Vim shift * in reverse to move to function call

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>

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.

Cross buffer search result list for Vim?

After searching in Vim you can get a list of the search results with :g//# and with :bufdo g//# you can get list of matches in all buffers.
But using it with bufdo is not really realistic since it does not show the file where the match came from or give an option to jump to the match.
Is there a plugin that would allow that?
Note that I want this for the internal Vim search because I often use it via *, # and similar shortcuts. I know that LustyExplorer (LustyBufferGrep) allows to search from all buffers, but it uses its own search input... I want reuse the internal Vim search.
You can paste the contents of vim search register with CTRL-R+/. Other plug-ins that can do that include Buffersaurus.
It seems to be possible to integrate the internal Vim search to Buffersaurus like this:
map <Leader>b :Bsgrep <c-r>/<cr>
Hit Leader+b to open up the list.

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.

Is there a way to emulate ReSharper's "extend selection" feature in Vim?

ReSharper has a nice feature called "extend selection": by pressing CTRL+W (I think this is the default) repeatedly, you select more and more from your current caret location. First it's a word, then more and more words, a line, inner then outer block of lines (for example an if-block), then a function, etc...
Basically, by pressing the key combination repeatedly, you can end up selecting the entire file. I'm sure at least some of you will be familiar with it.
I have just started learning all the intricacies of vim and I don't have enough experience to see how something like this could be implemented in Vim (although I assume it's possible). So my question is meant for Vim gurus out there: can this be done and how?
Update: a bit of a background story. I've been talking to my ex-boss about all the benefits of Vim, and he thinks it's all great. His only question/problem was: does it have "extend selection"? My question so far has been no. So, if someone knows the answer, I'll finally win a discussion :P (and maybe create a new Vim convert:-))
I had a quick go at this problem. It doesn't work as is. Feel Free to make edits and post on the vim wiki or as a plugin if you get it refined.
chances are you'd want to make a g:resharp_list for each language (eg. one for paranthesised languages, etc.)
All that is needed is a marker for the original cursor position :he markers and a timeout autocommand that resets the index.
"resharp emulator
"TODO this needs a marker
"also c-w is bad mapping as it has a lag with all the other-
"window mappings
"
let g:resharp_index = 0
let g:resharp_select = ['iw', 'is', 'ip', 'ggVG']
func! ResharpSelect()
if g:resharp_index >= len (g:resharp_select)
let g:resharp_index = 0
endif
exe "norm \<esc>v" . g:resharp_select[g:resharp_index]
let g:resharp_index = g:resharp_index + 1
endfun
nnoremap <c-w> :call ResharpSelect()<cr>
vnoremap <c-w> :call ResharpSelect()<cr>
"Something to reset on timeout. TODO this doesn't work
au CursorHold :let g:resharp_index = 0<cr>
The answer is yes. Once in Visual mode you can use all the regular navigation methods as well as some extra ones.
Some of my favourites? First hit v while in normal mode to get to visual mode then hit:
iw - to select the inner word. Great for selecting a word while excluding surrounding braces or quotes
w - hit multiple times to keep selecting each subsequent word.
b - select wordwise backwords
^ - select all from current position to beginning of text on line
$ - select all from current position to end of line
I'm sure others here could add to this list as well. Oh and don't forget Visual Block mode C-v try it out in vim with the above commands it works in two dimensions :-)
If you're talking about Vim (and you should be :-), you can start marking text with the v command, then you have all the standard cursor movement commands (and, as you know, there are a lot of them) which will extend the selection, as well as moving the cursor.
Then you just do whatever you want with the selected text.
See here for the gory details.
One would need to write a function that would save the current selection, then try increasingly wide selections, until the new selection exceeds the saved one or selects all text. Some possible selections are:
viW - select word
vis - select sentence
vip - select paragraph
viB - select text within the innermost brackets
v2iB - select text within the next most innermost brackets
ggVG - select all text
I think Jeremy Wall's heading in the right direction. And to get a little further in that direction, you might look at the "surround.vim" script from Tim Pope. A good description is available on github. Or, if you'd rather, get it from vim.org. It'll probably help you do some of the things you'd like to do, though it doesn't seem to have a feature for say, simply selecting within a tag. Let me know if I'm wrong.
Ultimately, what you'd really like is a hierarchy of enclosing text-objects. You should read up on text-objects if you haven't. A nice overview is here. Note that you can grab multiple objects in one go using counts, or do this iteratively (try vawasap}}} from normal mode).
You can also get scripts which define other text-objects, like this one that uses indentation to define a text-object. It'll work for many languages if you're formatting according to common standards, and guaranteed for python.
One annoyance is that the cursor ends up at the end of the visual block, so, for example, you can't easily select everything between some ()'s, then get the function name that precedes them...
...BUT, I just found in this post that you can change this behavior with o. Cool!
I suspect you'll find yourself more efficient being able to skip over intermediate selections in the long run.
Anyway, I'll be curious to see if anyone else comes up with a more general solution as well!
In Rider [on a Mac with VS Mac bindings with IdeaVim], I bind:
Ctrl+= to Extend Selection
Ctrl+- to Shrink Selection
Doesn't clash with any other bindings of consequence and doesn't require a v for mode switching, and easier than Cmd+Option+-> and Cmd+Option+<-
Putting it here as I always hit this question with any Rider Vim selection searches. If I get enough harassment, I'll create a self-answered "How to use Extend Selection with Rider Vim mode".

Resources