Vim - Commands to visually select a regex match? - vim

Can't figure out how to automatically select a regex match in visual mode.
For example, manually, I could search for a word
/word
It lands the cursor on the first character of the match "word".
Then I press v to enter Visual mode, and press llll to select the whole "word".
Now I want to do this by a macro, and I don't know the length of the match ahead of time.
I expected that Vim would automatically define some built-in marks at the beginning and end of the current match, so that I could ` to them. But I couldn't find any information on that.
What I want is to reassign Ctrl+n to a macro to take me to the next match and select it in visual mode, i.e. not just highlight the match. (To parallel how n takes you to the next match.)
If you're wondering why, its because I want to create folds based on regex matches (like Ctrl+n, zf), but I'm sure it will come in handy in other cases too.

//e takes you to the end character of last search.
More info -- :help {offset}.
You can find how to restore old search buffer here.

For the benefit of folks who stumble across this question in the future, vim now has this feature built-in: gn (and its close sibling gN) will jump to the next (respectively, previous) match and visually select it. It can also be used as a motion; e.g. cgn will jump to the next match and change it.

:noremap <C-n> //s<CR>v//e+1<CR>
Edit summary: was //e, but //e+1 worked for me (selected the last character of the match too).

Related

Go to search result without having to press enter in vim

I would like for my cursor to automatically go to the search result after I stop typing. For example, I type in /new, after 100ms (or whatever the debounce/delay is), I'd like the cursor to automatically go to the first match (if it exists) rather than me having to constantly hit return with my pinkie, which gets a bit sore having to press return 100 times per day.
Is there a setting to do this in vim, or how could something like this be achieved if there is not? From vim's help for incsearch:
You
still need to finish the search command with <Enter> to move the
cursor to the match.
First, important information:
When you are performing a search and incsearch is set, the current match will be highlighted as the highlight group IncSearch. If you also have hlsearch set, then the other non-current matches on your screen will also be highlighted, instead as the highlight group Search. For example, if you search for thing and the word thing appears three times on screen in your current file, the first match after your cursor will be the 'current match' and highlighted so. The other matches will be highlighted differently.
Now to answer your question
You can move between matches while searching without ending the search by pressing <Enter>. This is done with <C-G> and <C-T> (That's CTRL-G and CTRL-T). Reference :h /_ctrl-g and :h /_ctrl-t. This allows you to move through the file and see all the matches of the pattern you have already typed without actually ending the search. This also allows you to use <C-L> to add characters to the search. I'll let you look that one up (:h /_ctrl-l>).

Vim: substitute once, starting from CURSOR position (not line)

Is there a simple way (without too many keystrokes), to substitute the next occurrence of a pattern (in the line or in the whole document, both would be interesting), starting from the cursor position?
So far, I've only come up with selecting onwards, going to normal mode, and doing :s/\%Vpattern/rep. It's too cumbersome. Perhaps there's a nice way to select the next occurrance of a pattern, and then one can "change" the selection?
Thanks
You can use the confirm option with your substitution. Use the command
:%s/pattern/replacement/gc
It will take you through each occurrence of the pattern. Type y to replace, n to move on without replacing, and q to quit the search.
You can use gn
Just search for the pattern, using /
Select using gn
Once selected, you can perform any action on it. Like y to copy, c to change etc
:h gn

How to insert a block of white spaces starting at the cursor position in vi?

Suppose I have the piece of text below with the cursor staying at the first A currently,
AAAA
BBB
CC
D
How can I add spaces in front of each line to make it like, and it would be great if the number of columns of spaces can be specified on-the-fly, e.g., two here.
AAAA
BBB
CC
D
I would imagine there is a way to do it quickly in visual mode, but any ideas?
Currently I'm copying the first column of text in visual mode twice, and replace the entire two column to spaces, which involves > 5 keystrokes, too cumbersome.
Constraint:
Sorry that I didn't state the question clearly and might create some confusions.
The target is only part of a larger file, so it would be great if the number of rows and columns starting from the first A can be specified.
Edit:
Thank both #DeepYellow and #Johnsyweb, apparently >} and >ap are all great tips that I was not aware of, and they both could be valid answers before I clarified on the specific requirement for the answer to my question, but in any case, #luser droog 's answer stands out as the only viable answer. Thank you everyone!
I'd use :%s/^/ /
You could also specify a range of lines :10,15s/^/ /
Or a relative range :.,+5s/^/ /
Or use regular expressions for the locations :/A/,/D/>.
For copying code to paste on SO, I usually use sed from the terminal sed 's/^/ /' filename
Shortcut
I just learned a new trick for this. You enter visual mode v, select the region (with regular movement commands), then hit : which gives you this:
:'<,'>
ready for you to type just the command part of the above commands, the marks '< and '> being automatically set to the bounds of the visual selection.
To select and indent the current paragraph:
vip>
or
vip:>
followed by enter.
Edit:
As requested in the comments, you can also add spaces to the middle of a line using a regex quantifier \{n} on the any meta-character ..
:%s/^.\{14}/& /
This adds a space 14 chars from the left on each line. Of course % could be replaced by any of the above options for specifying the range of an ex command.
When on the first A, I'd go in block visual mode ctrl-v, select the lines you want to modify, press I (insert mode with capital i), and apply any changes I want for the first line. Leaving visual mode esc will apply all changes on the first line to all lines.
Probably not the most efficient on number of key-strokes, but gives you all the freedom you want before leaving visual mode. I don't like it when I have to specify by hand the line and column range in a regex command.
I'd use >}.
Where...
>: Shifts right and
}: means until the end of the paragraph
Hope this helps.
Ctrl + v (to enter in visual mode)
Use the arrow keys to select the lines
Shift + i (takes you to insert mode)
Hit space keys or whatever you want to type in front of the selected lines.
Save the changes (Use :w) and now you will see the changes in all the selected lines.
I would do like Nigu. Another solution is to use :normal:
<S-v> to enter VISUAL-LINE mode
3j or jjj or /D<CR> to select the lines
:norm I<Space><Space>, the correct range ('<,'>) being inserted automatically
:normal is probably a bit overkill for this specific case but sometimes you may want to perform a bunch of complex operations on a range of lines.
You can select the lines in visual mode, and type >. This assumes that you've set your tabs up to insert spaces, e.g.:
setl expandtab
setl shiftwidth=4
setl tabstop=4
(replace 4 with your preference in indentation)
If the lines form a paragraph, >ap in normal mode will shift the whole paragraph above and below the current position.
Let's assume you want to shift a block of code:
setup the count of spaces used by each shift command, :set shiftwidth=1, default is 8.
press Ctrl+v in appropriate place and move cursor up k or down j to select some area.
press > to shift the block and . to repeat the action until desired position (if cursor is missed, turn back with h or b).
Another thing you could try is a macro. If you do not know already, you start a macro with q and select the register to save the macro... so to save your macro in register a you would type qa in normal mode.
At the bottom there should be something that says recording. Now just do your movement as you would like.
So in this case you wanted 2 spaces in front of every line, so with your cursor already at the beginning of the first line, go into insert mode, and hit space twice. Now hit escape to go to normal mode, then down to the next line, then to the beginning of that line, and press q. This ends and saves the macro
(so that it is all in one place, this is the full list of key combinations you would do, where <esc> is when you press the escape key, and <space> is where you hit the space bar: qai<space><space><esc>j0q This saves the macro in register a )
Now to play the macro back you do # followed by the register you saved it in... so in this example #a. Now the second line will also have 2 spaces in front of them.
Macros can also run multiple times, so if I did 3#a the macro would run 3 times, and you would be done with this.
I like using macros for this like this because it is more intuitive to me, because I can do exactly what I want it to do, and just replay it multiple times.
I was looking for similar solution, and use this variation
VG:norm[N]I
N = numbers of spaces to insert.
V=Crtl-V
*** Notice *** put space immediate after I.

How to do column editing in vim?

Vim is pretty powerful when editing by line - the search/replace tools are modeled to work linewise.
But what if I want to change a particular column across all lines? For example, how can I change the 80th column in my file to a # easily?
To edit a column, follow these steps:
Stand on the beginning of the column
Press Ctrl+v, then mark across the column you want to edit.
Press Shift+i to insert text at the beginning of the column, Shift+a to append text, r to replace highlighted text, d to delete, c to change... etc.
Hit ESC when done.
I think people (me) sometimes map the column editing keys to Ctrl+Q so it won't collide with visual select line (V) or paste-text if you mapped it as such.
...I couldn't follow the steps of sa125 (facepalm) so I looked someplace else and found a simpler explanation at: https://blog.pivotal.io/labs/labs/column-edit-mode-in-vi
Ctrl+v [ and select what ever you want]
Shift+i [and write whatever...(check out ** below)]
Esc
*c without Shift can be used instead of step 2, to delete selection before insert. And also r to replace.
**!! Attention Don't be discouraged by the fact that only the first row is changed when you 'write whatever...'!!
Hope it helps!
You can use a substitution where the pattern matches a specific column (\%c):
:%s/\%80c/#/<CR>
Or you can use block-wise visual mode:
gg80|CTRL+vGr#
The 'virtualedit' option can be used to allow positioning the cursor to
positions where there is no actual character:
:set virtualedit
I may be totally off topic here, but if your idea is to avoid long lines, you could have a look at the colorcolumn option of vim 7.3.
For column-wise editing, vis.vim is really useful. You can block-select your column of interest, and manipulate it with normal commands, and even arbitrary Ex commands. From the example on that page, I have often used the pattern:
:'<,'>B s/abc/ABC/g
You can Vundle/Pathogen install vis.vim from github:
Plugin 'taku-o/vim-vis'

Move to start and end of search lookup

In vim/gvim I would like to be able to move to the front and end of the current search lookup. Is this possible?
For example, with this file:
A dog and a cat
A hat and a bat
I would like to be able to perform a search, for example /dog\sand and then be able to move from the beginning of the 'dog and' expression to the end and back so that my cursor starts on column 3, under the letter 'd' of the word 'dog' and then moves to column 9 under the letter 'd' or the word 'and'.
The reason I want to be able to do this is so that I can search for an expression and then use the change command, c, combined with a movement command to replace that particular search expression. I don't want to use substitue and replace here, I want to perform this operation using the change command and a movement key.
You are looking for cgn. From :help gn:
Search forward for the last used search pattern, like
with `n`, and start Visual mode to select the match.
If the cursor is on the match, visually selects it.
If an operator is pending, operates on the match.
E.g., "dgn" deletes the text of the next match.
If Visual mode is active, extends the selection
until the end of the next match.
The beauty of this is you can do cgn and then repeat the command with . and, yes, it will do the same operation on the next search pattern match. This becomes extraordinarily useful when you start searching with complicated regular expressions.
Try ths:
/pattern<cr> to place the cursor at the start of search pattern
/pattern/e<cr> to place the cursor at the end of search pattern
You can change to the end of the match with c//e<CR>. And //<CR> will take you to the beginning of the next match. You could probably work out some kind of bindings for those that make sense. For instance I just tried the following, and it seems to work nicely:
:onoremap <silent>m //e<CR>
So that you can say cm for change match. I'm not sure what I would map //<CR> to, though. I tried mapping it to n, and it seemed to work fine. Don't know if that would be a problem for you.
:nnoremap <silent>n //<CR>
Since you know just how many words you're searching for, why not just move there and then back using word movement commands? I.e., "2w" to go to end of current search result, and "2b" to go back.

Resources