Move cursor to end of line in vim (to delete last word) - vim

I usually type the command db to remove one word backwards in Vim. Doing this at the end of a line without whitespace leaves the last character of the word since the cursor starts removing from the second last character.
I can press b followed by de instead, but I find this confusing sometimes when doing it many times in a row, leading to unneccesary mistakes. I was hoping there was a way to go to the end of the line and remove the last word backwards.
Is there a way to do this?

You should train yourself to stop using db and learn to love text objects instead. This problem happens even if you're not at the end of a line.
foo bar baz
^
and then db will give
foo r bax
^
Instead of using db or de or even dw, train yourself to use diw and daw. This might take some getting used to, but down the road it will become natural and be way more convenient to use. And once the text objects become natural to you, you can then start using other commands ('c' or 'y', etc.) or even other text objects. (I can't even count how many times I've used dap or ci()
For a short explanation of what these do, think of diw as (d)elete (i)nside this (w)ord and daw as (d)elete (a)round this (w)ord or (d)elete (a) (w)ord. For a more concrete example:
foo bar baz
^
typing diw gives
foo bar
^
(note the leading space)
But
foo bar baz
^
typing daw gives
foo bar
^
And as long as your cursor is over the same word, these will still do the same thing. So if we moved the cursor back to the 'a' or the 'b', you'll get the exact same results. This blog goes into more depth on text objects.

You can either:
use a mapping like this:
:nnoremap <silent> db :exe 'norm!' (col('.')==col('$')-1 ? 'daw' : 'db')<cr>
alternatively, you can do :set ve=onemore which allows you to go one
char past the end of line, then once your cursor is past the end (see command g$), simply use db.
EDIT (explanations)
:exe executes the string formed by its arguments as a command.
So if the cursor is at the end of line (col('.')==col('$')-1),
it will execute:
:norm! daw
otherwise it will execute:
:norm! db
:norm lets you run normal commands in the command line. For example if you're already in
normal mode, typing :norm db + return will do the same as just typing db.
It's useful inside commands. The ! prevents mappings to be used in the :norm commands.
See :h :norm.
<silent> makes a mapping silent: without it you would see
:exe 'norm!' (col('.')==col('$')-1 ? 'daw' : 'db') in the bottom of the
screen.
See :h <silent>.
<cr> is the key code for the return key. You can put this kind of codes inside mappings.
In this case, <cr> will validate the command just entered in the mapping.
See :h keycodes for details.

What about
$diw
$ - takes you to last character of the line
d - as you know is for delete
i - implies from inside. Read more on other powerful text objects :help text-objects
w - word
If you are not habituated using text-objects, start using. You will love it

Related

what's the difference between command cw and ciw in Vim?

Here's a link I find in stackoverflow about this question.
but I still cannot understand without a specific example about what's the difference between "change inner word" and "change word".
I test these two commands in my vim and finally find no differences ,Please give me an example to help me understand, thank you!
Here is an example:
foo bar baz
^
Typing cw and ciw will give the same result in this case (with the cursor positioned on the 'b' of 'bar').
Consider this:
foo bar baz
^
cw will yield
foo b baz
^
where ciw will yield
foo baz
^
so it changes the whole word, regardless of the cursor position. Very useful, i love this command.
Very useful is also the caw (or the aw) command:
foo bar baz
^
-> caw
foo baz
^
aw also contains the space. Try these commands with the v (visual) command, to see what they all do. Also, read motion.txt, part 6.
Above answers addressed HOW they behave different, i would like to share some idea on WHY they behave different.
First, in vim's world, w and iw have different semantics and can both be seen as target(see below):
w in cw refers to a Motion Object
while iw in ciw refers to a TextObject
Secondly, in Vim editing, Operator (c/change in your case, and y/yank, d/delete, =/indenting, >/shifting etc) and Target (w and iw in your case) helps you achieve what you want to do with less keystrokes compared to using visual selection + operator.
TextObject defines target range (start and end position).
Motion is essentially used to move cursor, so it only define final-target-position (destination to move).
Some good materials to read:
:h motion.txt part 4, 5
AdvancedTopicTutorial from atom-vim-mode-plus
someword
^ (cursor)
cw
some_
^ (cursor)
Changes from cursor to end of word. Leaves the start of the word.
Compared to
someword
^ (cursor)
ciw
_
^ (cursor)
Changes the entire word from start to end.
Mind you, cw has a bit 'unstandard' behavior by default in that it is behaves exactly like ce: It only works up until the end of the current word (like e, ce, de, ye) instead of including the whitespace up before the beginning of the next word (like w, dw, yw).
Therefore I recommend adding these mappings to your vimrc:
" Have `cw` adhere to its actual movement `w`, instead of duplicating `ce`.
nnoremap cw dwi
nnoremap cW dWi
and getting used to usually using ce. Typing ce is actually more efficient and less awkward than cw if you form the habit of pressing the e with your ring finger instead of middle finger when it comes right after c.
If you prefer to leave cw with its default assignment duplicating ce, then you can access its 'proper' functionality with an additional keystroke: dwi (or vwc).
(Mind you, I find dwi even more efficient to type than cw because of the positions of the keys, in spite of the additional key.)
Explanation of the second mapping: W (Shift+w) works on what vim calls "WORDS", which counts every non-blank character, e.g. punctuation, as part of a WORD; while w works on "words", which only consist of uninterrupted sequences of letters, digits and underscores (by default).

vim: command like f{char} but for series of chars instead of single char

In vim I can navigate to char in current line using f{char} -- To [count]'th occurrence of {char} to the right. The cursor is placed on {char} (inclusive).
Lets look on next line:
from fmodule import futility
-- there are three words starting from f letter and assume that I want to jump to futils. To do it (with cursor at the beginning of line) I will execute 2ff, but instead I would really like to do something like f{fut} (providing first chars of word not single one).
What are the ways to accomplish this task?
You can use the / search as a motion, also in visual mode and in combination with a command like d. You need to conclude the search with <Enter>, as usual. In contrast to f, this will also find matches in following lines. Some consider this a feature (and change f accordingly via plugins), others don't like this. If you're in the latter camp, the following mapping will restrict the pattern to the current line automatically:
noremap <expr> <Leader>/ '/\%' . line('.') . 'l'
You might also want to define <Leader>? for the opposite direction.

Vim - g command for deleting characters in specific columns

I want to delete 5 characters starting from column 11 in the whole file.
When I type
11|5x
it works for the line the cursor is on.
But when I type
:g/.*/11|5x
the editor closes.
How should I use the g command properly?
Understanding Vi(m) modes is key to mastering it.
The | command to jump to a screen column is a normal mode command, but the :global command takes Ex commands. The :normal Ex commands interprets following arguments as normal mode commands (with !: without considering mappings (which is safer)):
:g/.*/normal! 11|5x
PS: A shorter "match anywhere" pattern for :g is ^ instead of .*.
try
:g/./norm! 11|5x
you need the normal
The normal | motion bring the cursor to a screen column, which may not be expected when you have multi-column characters like <Tab> in a line.
Substitution globally like below can avoid this problem:
%s/\%10c.\{5}/, in which \%10c matches the column position of the 10th character.

How to run a search and replace command without cursor moving in Vim?

In Vim, when I run a substitution command like
:%s/foo/bar/g
it replaces all occurrences of foo with bar in the entire buffer. When it completes, the cursor moves to the last location where foo was replaced with bar.
How can I run :%s/foo/bar/g without having the cursor leave its original location where it was before the substitution command was issued?
Is there some option I can set in the .vimrc file?
When the :substitute command is run, prior to any replacements being
carried out, the current position of the cursor is stored in the jump
list (see :help jumplist).
In order to return to the position before the latest jump, one can use
the `` or '' Normal-mode commands. The former
jumps exactly to the stored position; the latter jumps to the first
non-whitespace character on the line the stored position belongs to.
It is possible to both invoke a substitution command and move
the cursor back afterwards, at once, by issuing the command
:%s/pat/str/g|norm!``
or, if jumping to the containing line is sufficient, by using
the command
:%s/pat/str/g|''
It is not necessary to preface '' with norm! in the latter
command, because the '' address is allowed by the range syntax
of Ex commands and refers to the same line the Normal-mode
command '' jumps to (see :help :range); both just look into
the contents of the ' psudo-mark.
I just type Ctrl+O after the replace to get back to the previous location.
It's old, but for anyone coming across this question, I wanted to share my solution since it will work correctly even if nothing is substituted:
:exe 'norm m`' | %s/pattern/substitution/eg | norm g``
exe is needed since norm treats the bar as an argument.

How to delete line(s) below current line in vim?

Is there a command to delete a line (or several lines) that is immediately below current line?
Currently I'm doing it as:
jdd and then . to repeat as needed.
Is there a command that would combine all these?
UPDATE: The reason I would like to have such command is that I don't like to move away from current position, yet be able to delete lines below.
The delete ex command will work nicely.
:+,$d
This will delete all the lines from current +1 till the end ($)
To delete the next 2 lines the follow range would work, +1,+2 or shorthand +,+2
:+,+2d
As #ib mentioned the :delete or :d command will move the cursor to the start of the line next to the deleted text. (Even with nostartofline set). To overcome this we can issue the `` normal mode command. `` will jump back to the exact position before the last jump, in this case the :d command. Our command is now
:+,+2denter``
Or as one ex command
:+,+2d|norm! ``
To make this easier we wrap this all up in a command:
command! -count=1 -register D :+,+<count>d <reg><bar>norm! ``
Now to delete the next following 3 lines:
:3D
This command can also take a {reg} like :delete and :yank do. So deleting the next 4 lines into register a would be:
:4D a
For more information
:h :d
:h :command
:h :command-register
:h :command-count
:h ``
dG should work.
This means delete all rows until end of file from current cursor.
This will delete ALL lines below the current one:
jdG
Unfortunately that will move the cursor to the beginning of current line after the deletion is made.
well, to do it simply you could use the xxdd command. Most of the time I know (at least have an idea) the size of the script I am editing. So, the command as below is usually more than enough :
99dd
999dd to remove 999lines starting at the cursor position.
9999dd
99999dd for very long script ;)
The other solutions are informative, but I feel it'd be simpler to use a macro for this:
qq (begins recording)
jddk (go down, delete the line, and go back up - i.e. the thing you want to do)
q (end recording)
Now you can do #q to perform this action, maintaining the cursor at the current position. You could also do something like 5#q to delete 5 lines below the cursor.
And finally, if you're repeating the action more than once, you could just type ## after the first time you run #q (this repeats the last used macro - in this case q)
This is a job for marks!
Try maj20dd`a
ma sets the file-specific mark 'a', j20dd does the deletion you want (20 lines in this case), and `a restores you to the mark's position (line and column).
Obviously this pattern can be extended to do anything you want before returning to the mark. If you use mA (or any other capital letter) the mark will actually be unique across files, so you can even edit elsewhere before returning. If you have a very frequent usage you could make it a macro as suggested above.
You could enter the number of lines to delete: j 20 dd k.
Just for the fun of it, you can define a little function that does
exactly what you described: deletes the next n lines below the
current line and restores the initial cursor position.
function! DeleteNextLines(n, reg)
let l = line('.')
let m = min([a:n, line('$')-l])
if m > 0
let c = col('.')
exe '+,+'.m 'd' a:reg
call cursor(l, c)
endif
endfunction
Also, you can define a command that accepts the number of lines
to delete (one, if omitted) and the register name to use as an
optional argument (just like the :delete command).
:command! -range=1 -register -bar D call DeleteNextLines(<count>, <q-reg>)
Additionally, you can define a mapping for triggering the above
:D command, if it is necessary.

Resources