Sometimes I want to clear a line in vim rather than delete it.
Before:
foo
bar
lineToClear
baz
After
foo
bar
baz
Of the vim commands I know, the closest I can get to this is D (upper case d), but usually this requires me to type 0 first to go to the beginning of the line.
I know, I'm lazy.
Does there exist a command that just clears the entire line, not just the characters after the cursor?
Maybe some sort of Containment-esque type of direct brain interface?
You can use S. It clears the line, then puts you into insert mode. If you don't want to do insert mode, 0D will be the quickest command set.
As glts mentioned, you can create a custom mapping by running one of the following commands. The first argument (S/D) can be changed to whatever you'd like.
:nnoremap S S<Esc>
or
:nnoremap D 0D
Reference
There is a slightly better way than 0D. It is still two keys, but does not require shift or going all the way up to the top row to press 0:
Simply just:
dd
Related
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
In vim I frequently find myself wanting to append a suffix to an identifier in my source code, and to then repeat it on other identifiers using '.'.
i.e. to transform:
foo bar baz faz
to:
foo_old bar_old baz_old faz_old
I would like to be able to do:
ea_old<ESC>w.w.w.
instead of:
ea_old<ESC>wea_old<ESC>wea_old<ESC>wea_old<ESC>
In other words, I want appending text to the end of a word to appear as a repeatable command in the history. Anyone know how to do this?
I can do:
nmap <C-a> ea
to create a slightly more convenient way to append at the end of a word, but it only repeats the "a". Ideally I want to be able to repeat the whole "eaarbitrarytext" sequence.
I have the repeat.vim plugin installed and tinkered a bit, but I don't really know what I'm doing in vimscript.
Clarifying the requirement: I want to be able to jump around using arbitrary movement commands until my cursor is somewhere on the identifier, and then hit "." to repeat the appending of a suffix. The above example is intended to be a special case.
ea_oldESCe.e.e. should work for you.
Another possible solution would be to use the c flag on a search and replace command:
:.s/\<[[:alnum:]]\+\>/&_old/gc
Then all you have to do is press y to confirm each replacement. This would be faster if you have a lot of replacements to do and want to confirm each one manually. If, on the other hand, you want to add _old to every word on a line, you can remove the c:
:.s/\<[[:alnum:]]\+\>/&_old/g
My guess is that the OP took a very simple example to illustrate a more generic problem that can be re-formulated as "I would like to repeat an arbitrarily big sequence of commands very easily".
And for that, there is the q command. Pick your favourite register for recording, say "q", then:
qq -- starts recording
(do any complicated set of actions here...)
q -- stops the ercording
#q -- plays back the recording
And as I am myself using this very often when programming, I ended up mapping the actions above to F2, F3 and F4 respectively on my keyboard. This allows to repeat your set of actions in really 1 key stroke. In .vimrc:
nmap <F2> qq
nmap <F3> q
nmap <F4> #q
For this specific case, you can use search and replace: s/ /_old /g.
Having this LOC:
printf("%s (%d)\t(%d)\t%d-%d\t", meta_scanner_token_name($ret['major']), $ret['major'], (string)$ret['dirty'], $ret['start_line'], $ret['minor']);
What is the fastest way in terms of key strokes to enclose the call to meta_scanner_token_name in another function call to foo, yelding:
printf("%s (%d)\t(%d)\t%d-%d\t", foo(meta_scanner_token_name($ret['major'])), $ret['major'], (string)$ret['dirty'], $ret['start_line'], $ret['minor']);
given that
first scenario: my cursor is on 'm' at the beginning of the function?
second scenario: my cursor is somewhere on meta_scanner_token_name?
va)oB would select the entire line, and ys%) would enclose only the m, resulting in:
... (m)eta_sca...
Please answer to both scenarios.
(I am using spf13-vim with default settings except some visual changes, if that has any relevance)
ifoo(<Esc> then f)i)<Esc>
bifoo(<Esc> then f)i)<Esc>
but I'm still a Vim noob
-- EDIT --
I see "Surrounding.vim" is a modified version of "Surround.vim" if it's compatible with Surround you can do:
Scenario 1
vt,sffoo<CR>
vt, to select everything until the first ,
s to launch Surround.vim
f to instruct Surround to input a "function"
foo the identifier
<CR> Enter key.
That's 6 keystrokes not including typing foo which — I think — can't really be avoided.
Scenario 2
bvt,sffoo<CR>
It's the same as scenario 1 except that you type b first to go back to the first letter of meta_scanner_token_name.
Using normal vim you could do this (prefix with b for scenario 2)
`cf)foo()<esc>P`
If your vim plugins add the closing paren for you, you can drop that from the sequence. Depending on where it leaves your cursor, you might need to use p instead of P.
In Vim, is there any way to repeat the last command regardless of whether it was an edit or not, and without having the foresight to first record a macro?
E.g. say I type :bn, and want to do it again (it was the wrong file). Pressing . obviously doesn't do it. Or maybe I'm doing gE and want to repeat that (with one keystroke since clearly gE is kinda painful to type).
Perhaps there are some plugins? Similar to this question.
(Even cooler would be to retroactively bind a number of commands to a macro, so one could type 5qa#a or something to repeat the last 5 commands...)
To repeat a command-line command, try #:, To repeat a normal/insert-mode command, try .,
Add below mapping to your .vimrc if you want to shortcut the same:-
:noremap <C-P> #:<CR> - This will map Ctrl+P to previous command-line command. You can map any other combo.
:help repeating will provide the typical repeat commands (like ., #:, etc.). You could try repeat.vim. That may get you closer to what you are looking for.
For motion commands there is no mechanism built into Vim. The Find and To commands (f/F/t/T) have ; and , to repeat and reverse. There are a couple of plugins which extend those bindings to repeat other motion commands:
http://www.vim.org/scripts/script.php?script_id=2174
http://www.vim.org/scripts/script.php?script_id=3665
The later should support repeating gE using ;
You can just use "."
Example:
You have "abc" at 10 places in your file and you want to replace it with "def" at 5 places of it.
Step 1: Find first occurance of abc by typing command "/abc"
Step 2: Once cursor is on "abc", Replace abc by command "cw" to take out word "abc"
Step 3: Type in "def" as replacement and press enter to go to command mode
Step 4: To repeat this action just type command "n" to go to next occurrence of abc and type command "." . The command remembers that you replaced "abc" with "def" last time and will perform the same here.
You can map #: to some key for more convenience:
:map <F2> #:
and then it's easier to use it with repeats.
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.