How does "daw" to delete a word in Vim work if "dw" only deletes part of the word? - vim

I'm a Vim user and I want to delete a keyword. I always use "dw" to delete a specific keyword, but it sometimes doesn't work well. For example, I want to delete "valule123" in sample program.
ex) public void function(int valule123)
When I put my cursor is on "2", and then I input "dw", only part of keyword is deleted and the result is "valule1". Why?
I tried another command, "daw". In this case, the result is just as expected! But what does "a" mean? I think "a" means "add".

The command/action/verb d in Vim acts on an object. For dw the object is "all text the cursor moves over with a w command". For daw you're actually using a Vim concept called a "text object". There are many of these, including aw (a word), as (a sentence), i} (inner {...} block, e.g. code within a block in C code), it (inner tag, useful for XML-like languages), and more.
See :help text-objects for the full list.
These can not only be used by the d command, but any command/action/verb that takes an object. For example, =aB will reindent an entire code block, cas will delete a sentence and drop you into insert mode to type a new one, and yit will yank/copy everything inside the current XML tag.

dw: deletes word from the cursor to the end of the word.
daw: deletes the word under the cursor.
There is also the option of writing caw, this one does the same as daw, but also puts you into insert mode.

If you type :help daw inside Vim console, you will see it means "delete a word". So, 'a' means a here. More from the doc:
For example, compare "dw" and "daw": "dw" deletes from the cursor
position to the start of the next word, "daw" deletes the word under
the cursor and the space after or before it.
If you don't want to delete the space after/before it, you can use diw (delete inner word).

For these cases, you can always use: diw that way it won't matter where your cursor is over the word it will always remove the entire word.
d: delete
i: internal/inner
w: word
Another useful use is ciw (change internal word) to delete the word and go into insert mode.
Cheers!

In case that I know the word to delete, my flow of deleting would be:
Find :/deleting-word and cursor at the end of the deleting word.
on -- INSERT --, combo [ctrl + w] to delete that word, or keep going for multiple words.

lbce may work well if you want to change a word in a english sentence despite where the cursor position in the word you want to delete.

When navigating around dw will delete a word. Of course w will navigate from the first character of a word to the next word, whilst b the previous word etc.
Given that you use the navigation keys j,k,h,l (down, up, left, right ), if you're in a word on a particular charachter, you can type d for delete then l and the character to the right will be deleted, or h and the character to the left will. It's more intuitve when your fingers are actually on the keys 😄

Related

Changing case at the end of a word in Vim

I know gUw will turn properties to PROPERTIES and stay at the first character of the word.
But if I use gUb, it will be PROPERTIEs and cursor at the first charactoer.
If I use gUge, it will be PROPERTIES but cursor at last word.
What should I do if I want to turn the word to upper case, and stay at the end of the word(so that i can keep on typing without a w)
All operator+motion edits will leave the cursor on the first character of the motion. From :help motion.txt:
After applying the operator the cursor is mostly left at the start of the text that was operated upon. For example, "yfe" doesn't move the cursor, but "yFe" moves the cursor leftwards to the "e" where the yank started.
So, assuming your cursor is on the last character of the current word:
properties
^
there is no built-in way to ensure that the cursor will stay there after an operator+motion edit.
One can leave a mark and jump back to it after the edit:
m'gUiw``
but that's more work than just pressing w. It could be turned into a mapping, though, if that's a common need:
nnoremap <key> m'gUiw``
but that doesn't sound very scalable.
Another approach would be to record your edit:
qq
m'gUiw``
q
and play it back as needed:
#q
But your last sentence is puzzling:
What should I do if I want to turn the word to upper case, and stay at the end of the word(so that i can keep on typing without a w)
If you are at the end of:
properties
^
and your edit leaves the cursor at the beginning of:
PROPERTIES
^
w will move the cursor to the beginning of the next word:
PROPERTIES foo
^
and not to the end of the current word.
We are missing some context, here.

the command y3s to copy three lines in Normal Mode in Vim

According to Vim's Verb, Noun, and Modifier logic the command y3s should potentially copy three sentences, but in my version of Vim it doesn't do that. I am wondering if there is a reason for it. Looking up online it seems like there are other ways to copy a specific number of sentences, but I am curious why this approach doesn't work. Thanks!
Several misconceptions here. First, there is a difference between motions and text objects.
A motion (:help navigation) is a command that changes the position of the cursor: l for right, j for down, ) for sentence forward, 2Fx backward to before-previous x in the same line, /foo/e+2<CR> forward to 2 characters after the end of next foo, w start of next word. Commands whose argument is a motion operate on the text span from the current position to the new motion-specified position. dw thus deletes from current position to the start of the next word.
A text object (:help text-objects) specifies a semantic unit of text; it typically consists of two keypresses, the first of which is i (inside, inner) or a (a, an, around). i" inside double quotes, a( around parenthesis, is inner sentence (i.e. without spaces around it), 2aw twice a word. Thus daw delete around this word (including the space), or simpler, delete a word.
The difference is clear: if you are in the middle of a word, e.g. Some peng|uins fly (with | representing the cursor), dw gives you Some peng|fly (deleting from cursor to start of the next word), while daw gives you Some |fly (deleting the entire word penguins, along with the next space because of the "around" modifier). diw would give you Some | fly (not including the space into the deletion).
As you'll note, "sentence" has a different mapping in text motions (( sentence backward, ) sentence forward) and text objects (is inner sentence, as a sentence). Meanwhile, ( as a text object, equivalently to ) and b, is everything inside, or around, parentheses; and s as a text motion does not exist by default.
Thus, y2s is not a known mapping, since you are deleting by motion (no i or a), and there is no motion s; it will not do anything.
You can use y2), which would yank about a sentence and a half (i.e. from cursor to the start of the second next sentence); or you can use y2as to yank the current sentence and the next sentence and a space after it; or y2is for the same except without that last space; but you cannot use y2s. (You can also write all of those as 2y), 2yas, 2yis.)
In y2y (or equivalently 2yy), the second y is the duplication of the operator. It is almost a rule in Vim that the motion equal to the operator is a line: yy yank a line, dd delete a line, gqgq (or gqq) reformat a line, == filter a line, gugu (or guu) uppercase a line etc. The reason is a simple convenience: lines are what we operate on most frequently, and it's hard to make a faster incantation than the same key pressed twice. Thus, the second y by itself does not have a meaning: it signifies that the first y is working on lines (thus y2y or 2yy yank two lines).
The whole :help motion.txt page is a very useful read, I heartily recommend it.
If you want to copy 3 lines, you should do y3y, not y3s. y stands for Yank or copy.
Update,
#Amadan 's answer has more explanation and also for why y3y works.
Simpley 3Y will do, where Y will yank a line and 3 will repeat it 3 times. In Vim there are no sentences, only lines, words, and characters.

Where is '$' under the "normal mode" (after esc-pressing mode) in "Vim" text editor?

I have hard time realizing, as a beginner, why in "Vim" (Windows 10), when I want to delete a word with a d$ and when I simultaneously press shift+4 on non-numeric key above qwerty... why "Vim" does not recognize that as a $?
I strongly believe that you confusion stems from the fact that d$ is not actually meant to delete a word. Moreover, dw (which sound pretty much like "delete word") is not meant to delete a word either.
d is a command that will perform its action (deletion) on the next movement right after the command. Note that $ moves to the end of the line, and w moves to the beginning of the next word. Therefore:
d$ deletes from the cursor position until the end of the line.
dw deletes from the cursor position until the beginning of the next word.
For a better example you should try d3j. 3j moves three lines below, therefore d3j deletes the current lines and the next three lines as well.
To delete the word under the cursor (no matter where the cursor is in the word) there are several ways. Some ways to do it:
bdw first move to the beginning of the word then delete 'till the next word.
vawd visually select the word a word (including the space after the word) and delete it.
viwd visually select an inner word and delete it (this leaves the spaces around the word in peace).
daw delete a word (without going into visual).
diw delete inner word (without visual).
(Try the visual ones first to see how they work, then you can use the non-visual ones.)
Also, we have a vi.SE section of the website.
I've finnaly understand it... a cursor must be BEFORE a related "tail" to be eliminated.
PS: In fact problem was with "e212 error: can't write to file"... instead of changing proposed "sudo permissions", while I'm on Win 10 instead, I've just reinstalled a fresh Vim.
So, problem were not with "$" (as it was where always have been) but when one is unsure where problem lies, often makes a wrong diagnosis.

vim - How to delete a large block of text without counting the lines?

In vim, I often find myself deleting (or copying) large blocks of text. One can count the lines of text and say (for example) 50dd to delete 50 lines.
But how would one delete this large block of text without having to know how many lines to delete?
Go to the starting line and type ma (mark "a"). Then go to the last line and enter d'a (delete to mark "a").
That will delete all lines from the current to the marked one (inclusive). It's also compatible with vi as well as vim, on the off chance that your environment is not blessed with the latter.
I'm no vim guru, but what I use in this circumstance is "visual mode". In command mode, type V (capital). Then move up/down to highlight the block you want deleted (all the usual movement commands work). Then remove it with x or d.
You can use the visual mode also (some commands are usable with the delete option also)
vip vap to select paragraph, v2ap to select two paragraphs
dap works, d2ap also. You can delete within blocks of [ ] like da[
For reference: the types of objects.
From vim documentation : section 4. http://vimdoc.sourceforge.net/htmldoc/visual.html
4. Operating on the Visual area *visual-operators*
...
The objects that can be used are:
aw a word (with white space)
iw inner word
aW a WORD (with white space)
iW inner WORD
as a sentence (with white space)
is inner sentence
ap a paragraph (with white space)
ip inner paragraph
ab a () block (with parenthesis)
ib inner () block
aB a {} block (with braces)
iB inner {} block
a< a <> block (with <>)
i< inner <> block
a[ a [] block (with [])
i[ inner [] block
There are many better answers here, but for completeness I will mention the method I used to use before reading some of the great answers mentioned above.
Suppose you want to delete from lines 24-39. You can use the ex command
:24,39d
You can also yank lines using
:24,39y
And find and replace just over lines 24-39 using
:24,39s/find/replace/g
It sort of depends on what that large block is. Maybe you just mean to delete a paragraph in which case a dip would do.
If you turn on line numbers via set number you can simply dNNG which will delete to line NN from the current position. So you can navigate to the start of the line you wish to delete and simply d50G assuming that is the last line you wish to delete.
There are several possibilities, what's best depends on the text you work on.
Two possibilities come to mind:
switch to visual mode (V, S-V,
...), select the text with cursor
movement and press d
delete a whole paragraph with: dap
If the entire block is visible on the screen, you can use relativenumber setting. See :help relativenumber. Available in 7.3
Counting lines is too tedious for me, but counting 'paragraphs' isn't so bad. '{' and '}' move the cursor to the first empty line before and after the cursor, respectively. Cursor moving operations can be combined with deletion, and several other answers used a similar approach (dd for a line, dG for the end of the document, etc.)
For example:
/* Lorem ipsum dolor sit amet, consectetur adipiscing elit. */
Lorem *ipsum(void) {
return dolor(sit, amet);
}
If your cursor starts above the comment block, 'd}' deletes the comment block, and 'd2}' deletes both the comment block and the code block. If your cursor starts below the code block, 'd{' deletes the code, and 'd2{' deletes both. Of course, you can skip over one block by moving the cursor first: '{d{' or '}d}'.
If you're consistent with your whitespace, or you can count the paragraphs at a glance, this should work. The Vim help file has more cursor tricks if you're interested.
You could place your cursor at the beginning or end of the block and enter visual mode (shift-v). Then simply move up or down until the desired block is highlighted. Finally, copy the text by pressing y or cut the text by pressing d.
Alongside with other motions that are already mentioned here, there is also /{pattern}<CR> motion, so if you know that you want to delete to line that contains foo, you could do dV/foo<CR>. V is here to force motion be line-wise because by default / is characterwise.
You can also enter a very large number, and then press dd if you wish to delete all the lines below the cursor.
Deleting a block of text
Assuming your cursor sits at the beginning of the block:
V/^$<CR>d (where <CR> is the enter/return key)
Explanation
Enter "linewise-visual" mode: V
Highlight until the next empty line: /^$<CR>
Delete: d
Key binding
A more robust solution:
:set nowrapscan
:nnoremap D V/^\s*$\\|\%$<CR>d
Explanation
Disable search wrap: :set nowrapscan
Remap the D key (to the following commands): :nnoremap D
Enter "linewise-visual" mode: V
Highlight until the next empty/whitespace line or EOF: /^\s*$\\|\%$<CR>
Delete: d

How do I get fine-grained undo in Vim

I find Vim's undo to be a bit too coarse. E.g. if I type something like this:
a // to go into edit mode
to be or not to ve
<esc> // to exit insert mode
Oops! I made a typo. I want to start undoing so I press u, but then it clears the whole line. Is there a way to undo word-by-word or character-by-character?
You can break undos via :help i_ctrl-g_u. You can map this if you want for every character, but that might a little bit complicated. Mapping this to space button is a way.
:inoremap <Space> <Space><C-g>u
After that every word can be undo via u
So as you see from the others what you are asking for doesn't exist in Vi (AFAIK).
Undo undoes what your last action was. If your last action was to enter insert mode and then add a line and then exit insert mode. That will be undone, however if from the default mode you hit the "x" key then you will delete 1 character or if in visual mode with text selected the text will be deleted. If you hit undo then you will restore that one character or the text that was selected.
...You should think of this as an action, and actions can be atomically undone or restored
As mentioned previously if you wish to delete the previous word then you should be able to hit Ctrl + w and delete the previous word while remaining in insert mode.
If you exit insert mode you can navigate (motion) back a word with "b" forward a word with "w" to the end of a word with "e", and can cut (which leaves you in insert mode) with "c" or delete with "d". Both actions cut and delete can accept a motion following them so you can delete the current word / up to the next word with "dw" or cut the previous word with "cb"
This concept becomes more useful when you remember to use the "." command (in normal mode). This command is to repeat the last action. I have used this many times to find and replace a small group of words in a file (It is especially useful if you are paranoid about changing too much). The scenario would be the following:
File:
This is my post
really it is a test
this is the middle
This is the end
if I wanted to replace "is" with "was" I could write:
%s/\<is\>/was/g
however if I wanted to change the first line and the third line "is" to "was" (and I didn't know their line numbers, and I wanted to see if there were any other places I wanted to change is to was I could type
"/is"
hit "n" until I reach the place I want substituted, and then hit "cw" and type "was"
I can now hit "n" until I reach another place I want substituted and hit ".", and that will replace "is" with "was" (Note: my search string didn't limit to the word "is", just the two characters "is" so "This" & "this" will match in this case)
No, it is not possible and is actually not necessary either. Vim has a million ways of dealing with that. Try cb for example. Or bC. Or brb. Or Tspace to jump back instead of b. Or ciw.
You can, of course use most of these solutions in insert mode (by pressing CTRLo first), or bind one to your favorite key combination (:help map and :help imap).
On Linux, using control-w while in input mode deletes the last 'word'.

Resources