VIM: How to delete 3 words from the end of line in normal mode? - vim

What is the shortest combo?
P.S. I usually do ACtrl+wCtrl+wCtrl+wEsc.
In other words, I have to jump into Insert mode.
P.P.S. d3b doesn't work.

This sequence of commands,
$3bD
is the shortest way to do it I can think of at the moment but it leaves out an ugly trailing space.
$3gelD
is another way that gets rid of the trailing space.
You can also think outside the box and play with spaces instead of words:
$3F D

$ 3b D which translates to
$ to the end of a line
3 three of whatever is next
b backward three [one without modifier] words
D delete the characters under the cursor until the end of the line
In addition, you can also use the normal command in ex mode to achieve the same
:norm! $3bD

$3bD
Or
$3bDx
...if you also want to delete the trailing space.

Go to the end of the line, go back 3 words, then delete to the end of the line: $ 3b D
or
Go to the end of the line, delete back 3 words, then delete the extra character: $ 3db x

As others have mentioned, $3bD is the shortest, and $3bDx will suffice to remove the remaining whitespace, assuming it's exactly one space or tab.
In order to account for all whitespace, $3gelD can be used. This option has the benefit of cleaning up properly in most cases, but it fails when a line contains exactly 3 words because the 3ge motion jumps back to the previous line.
An alternative approach is based on daw. Since 3daw acts forward, either $daw.. or $3b3daw must be used. For 3 words, $daw.. is shorter and probably more desirable, but $3b3daw is more Vim-esque and can easily be extended to more words.
b, ge, and w can be replaced with B, gE, and W in order to remove WORDs instead of words.

Related

Search and delete to end of line in vim

I am trying to clean up some code and I am trying to find a good way of achieving the following:
I am a #decent
guy
and I want:
I am a guy
I tried using
:g/#/d
but the whole line gets deleted and I only want to delete until the end of line. What is the best way to achieve this in vim?
Thank you.
That won't because the usage of that command:
:[range]g/pattern/cmd
defaults to range being the whole line, and you are not doing any substitution anyway.
Use:
:%s/#.\+\n//g
instead.
# Matches a literal #.
.\+\n Matches everything until the end of line, and a new line.
// Replaces the entire match with nothing.
With :global you would want something like
:global/#/normal! f#D | join
or
:global/#/substitute/#.*// | join
Try this instead:
:s/ # .*\n/ /
Explanation:
You were using the wrong command, as they may look similar to new users.
:[range]g/VRE/act Globally apply the "act"ion (one letter command) to all lines (in range, default all file) matching the VRE (pattern)
:[range]s/VRE/repl/f Substitute within lines (in range, default current line) the matching VRE (pattern) with the "repl"acement using optional "f"lags
Now about the pattern, I think this candidate cover most cases (all but comments at the beginning of a line and comments without space after pound sign)
# litteral space, then hash tag, then space again
.* dot for any character, star to mean the previous may occur many times or even be absent
$ dollar at end to stay at "end of line", but \n to catch en EOL here
press d + shift 4 or d + $, which means delete to end of the line
d means delete
shift 4 or $ means cursor to end of the line

vim - Prefix number to 3 letter combination bdw

I am learning Vim and I have come across this situation.
Hello, World!
-
I want to delete Hello, World. If I entered bdw (go to beginning of word, delete word) three times then it would delete it. However, I want to type 3bdwto save typing, but it goes three words back and deletes that word, leaving me with , World!. Is there any way to prefix a number to a three letter command or is there another command I should be looking at?
Move the cursor under !, then press
dFH (delete back until first H)
F=Shift+f
Is there any way to prefix a number to a three letter command or is there another command I should be looking at?
The problem is that it's not a 3-letter command, it's two seperate commands.
3b 3dw will do what you want, but it does require the extra 3.
EDIT: Years later... I notice a small optimization to this case w3db. The only small issue is that you need that leading w to correct the cursor position.
Hello, World!
Go to the beginning of line (by pressing 0) and type the following:
dt!
Explanation:
d delete
t until the character before ! in the line.
Move the cursor under the ! ($ or l)
Then write d0 (which means delete til beginning of line)
You can also do 0 (go to beginning of line) then dt! (delete until next !)

jump back to the first non-whitespace character in vim

I have a file like the following (with end-of-line shown as $)
233 $
Suppose my cursor is currently at one of the spaces between 3 and $. I want to be able to jump back to 3. Any available keybinding for that?
Thanks!
g_: To the last non-blank character of the line. It's one of the more obscure built-in motion.s
I think the best you can do is be:
b: back to the beginning of the previous word.
e: go to the end of the current word.
Depending on your need, use either ge or g_ or even F3

Vim: delete until character for all lines containing a pattern

I'm learning the power of g and want to delete all lines containing an expression, to the end of the sentence (marked by a period). Like so:
There was a little sheep. The sheep was black. There was another sheep.
(Run command to find all sentences like There was and delete to the next period).
The sheep was black.
I've tried:
:g/There was/d\/\. in an attempt to "delete forward until the next period" but I get a trailing characters error.
:g/There was/df. but get a df. is not an editor command error.
Any thoughts?
The action associated with g must be able to act on the line without needing position information from the pattern match that g implies. In the command you are using, the delete forward command needs a starting position that is not being provided.
The problem is that g only indicates a line match, not a specific character position for it's pattern match. I did the following and it did what I think you want:
:g/There was/s/There was[^.]*[.]//
This found lines that matched the pattern There was, and performed a substitution of the regular expression There was[^.]*[.] with the empty string.
This is equivalent to:
:1,$s/There was[^.]*[.]//g
I'm not sure what the g is getting you in your use case, except the automatic application to the entire file line range (same as 1,$ or %). The g in this latter example has to do with applying the substitution to all patterns on the same line, not with the range of lines affected by the substitution command.
I'd just use a regex:
%s/There was\_.\{-}\.\s\?//ge
Note how \_. allows for cross-line sentences
You can use :norm like this:
:g/There was/norm 0weldf.
This finds lines with "There was" then executes the normal commands 0weldf..
0: go to beginning of line
w: go to next word (in this case, "was")
e: go the end of the word (so cursor is on the 's' of "was")
l: move one character to the right (so we don't delete any of "was")
df.: delete until the next '.', inclusive.
If you want to keep the period use dt. instead of df..
If you don't want to delete from the beginning of the line and instead want to do sentences, the :%s command is probably more appropriate here. (e.g. :%s/\(There was\)[^.]*\./\1/g or %s/\(There was\)[^.]*\./\1./g if you want to keep the period at the end of the sentence.
Use search and replace:
:%s/There was[^.]*\.\s*//g

Vim jump back over spaces inside of curled braces

Lets say, I have wrote this piece of LaTeX in vim:
A_{\vec B}_
^
Cursor
The cursor is at the marked position. Now I want to add a \vec in front of the A.
I tried <Esc>Bi\vec <Esc>WW but I want B and W to jump over spaces which are inside of curled braces.
Any ideas how to do that?
Edit: Maybe I should've wrote, that I wanted to map this to a shortcut. A and B are just Examples for Strings which do not include spaces.
SOLUTION: I think I have found, what I was searching. With ? you can do a backward search with a regular expression.
You can't make B or W treat a braced string as a Word, but you can use % to jump from one end of a braced string to the other.
There are several ways to achieve a similar job. W and B only stop at whitespaces, as far as I know, so you can jump twice between words with 2B, or set insert mode at the beginning with I, or search for a letter, with f, F, t or T. Also 0 and $ to go to the beginning or end directly. There are many possibilities. I hope one of them can be useful instead.
FAi\vecESC$
Does it assuming that B is really at the end of the line

Resources