Delete till first character on next line - vim

I have code that looks like this:
DataAssociator::Impl::Impl(const VoxelHasherSettings& settings_voxelhasher,
const CameraSettings& settings_camera)
{
initialize(settings_camera);
}
When I position my cursor on the c of the first const and press either + or <CR> I move to the next const.
However pressing d+ / d<CR> deletes too much and leaves this:
{
initialize(settings_camera);
}
Why is that the case?
How do I achieve the effect of deleting till the first character on the next line?
I am using neovim.
Thanks in advance,
Richard

When you check out :help +, this mentions linewise. So when you use + in normal mode, it moves (as documented) to the first non-blank, but after an operator (like d or y), all touched lines will be included by default.
You can change that default behavior on a case-by-case basis via :help o_v: So dv+ instead of d+.
Alternatively, you can first go into visual mode; the selection will provide feedback on what text you'll be covering: v+d. A complication here is that depending on your 'selection' setting, this may select one character too much (with the default inclusive selection).

Yet another option for this specific case:
DJx

Related

How to go back to previous when doing find replace confirm in vi?

Frequently when I am doing a find and replace in vi I will do it like this:
:%s/find/replace/gc
This gives you the option to skip by pressing n, or replace by pressing y. But, sometimes I will accidentally skip over one in a large file by pressing n when I meant to press y.
How do I go backwards to the previous one and give me a second change?
Essentially, how to I find (search) the other direction temporarily? thanks.
I'm not sure if you would like to interrupt current find-replace operation and resume it again. But if that is acceptable, here is my suggestion:
Start your find-replace the way you mentioned:
:%s/find/replace/gc
After you accidentally skip over a substitution by pressing n, interrupt the search by pressing <ctrl-C>
Press <shift-N> to go back to the previous occurrence of your find term
Run find-replace a little differently while you are at this word: :.,$s/find/replace/gc
Continue the operation
All this functionality works with vim native capabilities without having to install any addon.
Note: The .,$ range specifier indicates to perform :s (substitute) operation over a range of lines that start with current line (indicated by .) and until last line (indicated by $).
Note2: It might be known to you, but reiterating for anyone else who stumbles upon this post searching for something similar - The % range specifier indicates to perform :s (substitute) operation over all lines of currently active buffer.
This is not answer to the question, but a very good alternative. I recently discovered the CtrlSF plugin and it improves the search /replace process dramatically.
Basically, you have the search results in a buffer and you can do all the replacements in this single buffer.
In your scenario, you first do :CtrlSF find, get a buffer with all the matches in all files and then you do /find and move with n over your targets and change them (of course, you can actually change only the first one and then repeat the replacement with .).
If you miss some target, you just hit N to go back to the previous result and replace it.
Seems like you can't back to previous match using this pattern. Appeared bar propose following commands y/n/a/q/l/^E/^Y but no one of them will return backward to previous match.
But you can use little different pattern described bellow:
Type this /pattern replacing pattern with interested word;
Your cursor is navigated to first occurrence, if you don't need to change it press n it will navigates you to the next occurrence;
Since you understand you need to replace a word, do this by typing cw, this command cuts the forward word and turns you to insertion mode;
Type in desired text on the released place and press ESC to switch back to command mode;
Now again press n until desired occurrence;
Since you realize that you need to change an occurrence, just press on . it will repeat previously mentioned actions;
If you want to go back just use N.

Move to the next row which has non-white space character in the same column in VIM?

As source code is usually indented, it will help navigate source code quickly if I can move to the next/previous row which has non-empty white character in the same column. Using below code snippet as example and the cursor in on the last }, is there a way to navigate the cursor to i which starts if?
if (condition) {
// some code
}
To search for the same screen column, you can use the special /\%v atom; the current column can be queried with virtcol('.'). Assert a non-whitespace (\S) at that position, and trigger a backwards search() for it:
:call search('\%' . virtcol('.') . 'v\S', 'bW')
You can easily turn this into a normal-mode mapping.
I've now implemented this motion in my JumpToVerticalOccurrence plugin; by default mapped to ]| / [|. There are other, related mappings like a ]V{char} mapping that works just like f, but vertically.
So if you don't mind installing a plugin (plus dependencies), this is more robust and functional (it supports [count] as well).
Not exactly what you're asking for, but if you start at } and hit %, the cursor moves to the matching {.
If your code has a defined indentation system, jeetsukumaran/vim-indentwise works well for relative, absolute, or block-scope movements across indented blocks.

How to delete, including the current character?

Let's say I've typed "abcdefg", with the cursor at the end. I want to delete back to the c, so that I only have "abc" left.
Is there a command like d that includes the current character? I know I could do dTcx, but the x feels like a work-around and I suppose there's a better solution.
No. Backward motions always start on the left of the current character for c, y and d which is somehow logical but also unnerving.
The only "clean" solutions I could think of either imply moving to the char after c first and then do a forward delete:
Tcde
or using visual mode:
vTcd
v3hd
But, given your sample and assuming you are entering normal mode just for that correction, the whole thing sounds extremely wasteful to me.
What about staying in insert mode and simply doing ←←←←?
try this:
TcD
this will leave abc for your example... well if the abcdefg is the last word of the line.
if it is not the last word in that line, you may do:
ldTc
or golfing, do it within 3 key-stroke:
3Xx or l4X
See this answer to a similar question : there is a setting to be allowed to go beyond the end of the line
From the doc :
Virtual editing means that the cursor can be positioned where there is
no actual character. This can be halfway into a tab or beyond the end
of the line. Useful for selecting a rectangle in Visual mode and
editing a table.
"onemore" is not the same, it will only allow moving the cursor just
after the last character of the line. This makes some commands more
consistent. Previously the cursor was always past the end of the line
if the line was empty. But it is far from Vi compatible. It may also
break some plugins or Vim scripts. For example because |l| can move
the cursor after the last character. Use with care!
Using the $ command will move to the last character in the line, not
past it. This may actually move the cursor to the left!
The g$ command will move to the end of the screen line.
It doesn't make sense to combine "all" with "onemore", but you will
not get a warning for it.
In short, you could try :set virtualedit=onemore, and see if your environment is stable or not with it.
Use d?c
That will start d mode, search back to 'c' and then delete up to your cursor position.
Edit: nope, that does not include current position...
I may be misunderstanding your request, but does 3hd$ do it?
I would use vFdd in this example. I think it's nicer than the other solutions since the command explicitly shows what to delete. It includes the current character and the specified character when deleting.
v: enter visual mode (mark text)
F: find/goto character backwards
d: the character "d" that will be included for removal.
d: delete command
Since it is visual mode, the cursor can also be moved before executing the actual removal d. This makes the command powerful even for deleting up to a non unique character by first marking a special character close to the character and then adjusting the position.

Vim copy and paste

My previous question seems to be a bit ambiguous, I will rephrase it:
I have a file like this:
copythis abc
replacethis1 xyz
qwerty replacethis2
hasfshd replacethis3 fslfs
And so on...
NOTE: replacethis1, replacethis2, replacethis3, ... could be any words
How do I replace "replacethis1","replacethis2","replacethis3",.. word by "copythis" word by using minimum vim commands.
One way I can do is by these steps:
delete "replacethis1","replacethis2","replacethis3",.. by using 'dw'
copy "copythis" using 'yw'
move cursor to where "replacethis1" was and do 'p'; move cursor to where "replacethis2" was and do 'p' and so on...
Is there a better way to do this in VIM (using less number of vim commands)?
Since you changed your question, I'd do it this way:
Move to the first "replacethis1" and type cw (change word), then type "copythis" manually.
Move to the next "replacethis", hit . (repeat last operation)
Move to the next "replacethis", hit .,
and so on, and so on.
If "copythis" is a small word, I think this is the best solution.
The digit needs to be included, and there could be more than one instance per line:
:%s/replacethis\d/copythis/g
Given that "replacethis[1-3]" can be arbitrary unrelated words, the quickest/simplest way to do this globally would be:
:%s/replacethis1\|replacethis2\|replacethis3/copythis/g
(Note that you need to use \| to get the pipes to function as "or". Otherwise, vim will look for the literal | character.)
I've been struggling with this for a long time too, I think I just worked out the cleanest way:
Use whichever command is cleanest to put copythis into register r:
/copythis
"rye
Then go to the replacement and replace it with the contents of r:
/replacethis
cw<CTRL-R>r<ESC>
Then you can just n.n.n.n.n.n.n. for the rest of them, or if they're wildly different just go to the beginning of each and hit .
The key is replacing and pasting in one step so you can use . later.
:%s/copythis/replacethis/g
To replace all occurrences of copythis with replacethis. Or you can specify a range of line numbers like:
:8,10 s/copythis/replacethis/g
Note, the /g on the end will tell it to replace all occurrences. If you leave that off it will just do the first one.
create this mapping:
:map z cwcopythis^[
( ^[ is the escape character, you can type it in vim using Ctrl+V Ctrl+[ )
go to each word you want to replace and press z
if u need to do essentially the same action multiple times - swap 1st word of one line with second word of the next line, I say you could record a macro and call it whenever you need to
Have you tried string replacement?
%s/replacethis/copythis
A host of other parameters are possible to fine-tune the replacement. Dive into the Vim help for more details. Some more examples here.
You can remap e.g. the m key in normal mode to delete the word under the cursor and paste the buffer: :nnoremap m "_diwP.
Then you can just copy the desired word, move the cursor anywhere onto the to-be-replaced word and type m.
EDIT: Mapping to m is a bad idea since it is used to mark locations. But you can use e.g. ; anyway.

How to repeat a command with substitution in Vim?

In Unix the ^ allows you to repeat a command with some text substituted for new text. For example:
csh% grep "stuff" file1 >> Results
grep "stuff" file1
csh% ^file1^file2^
grep "stuff" file2
csh%
Is there a Vim equivalent? There are a lot of times I find myself editing minor things on the command line over and over again.
Specifically for subsitutions: use & to repeat your last substitution on the current line from normal mode.
To repeat for all lines, type :%&
q: to enter the command-line window (:help cmdwin).
You can edit and reuse previously entered ex-style commands in this window.
Once you hit :, you can type a couple characters and up-arrow, and it will character-match what you typed. e.g. type :set and it will climb back through your "sets". This also works for search - just type / and up-arrow. And /abc up-arrow will feed you matching search strings counterchronologically.
There are 2 ways.
You simply hit the . key to perform an exact replay of the very last command (other than movement). For example, I type cw then hello to change a word to "hello". After moving my cursor to a different word, I hit . to do it again.
For more advanced commands like a replace, after you have performed the substition, simply hit the : key then the ↑ up arrow key, and it fills your command line with the same command.
To repeat the previous substition on all lines with all of the same flags you can use the mapping g&.
If you have made a substitution in either normal mode :s/A/B/g (the current line) or visual mode :'<,>'s/A/B/g (lines included in the current selection) and you want to repeat that last substitution, you can:
Move to another line (normal mode) and simply press &, or if you like, :-&-<CR> (looks like :&), to affect the current line without highlighting, or
Highlight a range (visual mode) and press :-&-<CR> (looks like :'<,'>&) to affect the range of lines in the selection.
With my limited knowledge of Vim, this solves several problems. For one, the last visual substitution :'<,'>s/A/B/g is available as the last command (:-<UP>) from both normal and visual mode, but always produces an error from normal mode. (It still refers to the last selection from visual mode - not to the empty selection at the cursor like I assumed - and my example substitution exhausts every match in one pass.) Meanwhile, the last normal mode substitution starts with :s, not :'<,'>s, so you would need to modify it to use in visual mode. Finally, & is available directly from normal mode and so it accepts repetitions and other alternatives to selections, like 2& for the next two lines, and as user ruohola said, g& for the entire file.
In both versions, pressing : then & works as if you had pressed : and then retyped s/A/B/, so the mode you were in last time is irrelevant and only the current cursor line or selection determines the line(s) to be affected. (Note that the trailing flags like g are cleared too, but come next in this syntax too, as in :&g/: '<,'>&g. This is a mixed blessing in my opinion, as you can/must re-specify flags here, and standalone & doesn't seem to take flags at all. I must be missing something.)
I welcome suggestions and corrections. Most of this comes from experimentation just now so I'm sure there's a lot more to it, but hopefully it helps anyway.
Take a look at this: http://vim.wikia.com/wiki/Using_command-line_history for explanation.

Resources