In Vim, this has been happening to me and I'm wondering the best way to handle it. Example:
something(|)something, else // pipe is the cursor location
I'd like to end up with this:
something(something, else)
I'd also like to be able to do this:
something(something) else _// in case I only want the first word
Assuming you are in insert mode:
" first example
<Del><S-Right><S-Right><S-Right>)
and:
" second example
<Del><S-Right><Del>)
Assuming you are in normal mode, with the cursor on the closing parenthesis:
" first example
x$p
and:
" second example
xeplx
I assume the pair of paranthesis has no space in between so that it looks like ()word, another-word etc etc. Then
d EEp
changes it into (word, another-word) etc etc.
The d initiates a delete. The following space tells vim how much you want to delete: one character (this is the )). An E jumps over a word. So, the double EE jumps over two words. With the final p you insert (paste) what you have deleted (that is the )).
Related
Let's say I have got a line of text like this
Hello World "How are you" World
Now, i want to know, if there's a way to select everything outside the quotes, at once? So, I am expecting something like this where the bolded text is the selection
Hello World "How are you" World
I know it is possible but i am not able to find a way to get this done.
I am thinking of doing something like select both parts individually and join them somehow.
My goal in this is to be able to create a motion that can delete everything except the stuff between " or ' as a operator pending motion. So, the operation can be Delete, Yank or Cut/Change. So, is there any other way to solve the same issue?
That is not possible. In Vim there can only be one selection at once, although there exists a plugin multiselect that claims to do what you want. I have never tried it however.
Place cursor between double quotes, then
yi" # Yank text between double quotes
dd # Delete line
"0p # Paste register 0
Should do the trick.
Similar to #Jens answer:
yi" # Yank text between double quotes
V # Select line
p # Paste yanked text
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 😄
Let's say I have a line like this:
pick 22086f5 do something....
I can put my cursor on the "p" in pick and delete word, however the line then looks like:
22086f5 do something....
and I can do a replace on 2 and replace it with an "s", but that's not really what I want. What I want is a simple way to insert 1 character without going into insert mode.
It is probably easiest to just put the cursor on the p and do ces<esc>. If you have the letter s in a buffer, say in buffer a, you could do: de"aP. If you are always replacing the word pick, you could also do dtkrs.
You can use vehdrs to delete all letters without last one and then replace the last one with s. Or if space is not needed then ders will work nicely.
I would also normally use ces<Esc>, but sometimes muscle memory prefers two distinct actions. For these cases, a mapping like the following may be helpful:
:nnoremap <Space> i$<Esc>r
Let's say I have this text:
something "something else"
something here "just another quoted block"
I want to substitute "something else" with "just another quoted block", so I do:
/quot<enter> (to jump to second quoted block searching for the string "quot")
yi" (to yank inner text for current quoted block)
?else<enter> (to jump back to the first quoted block wich contains "else")
vi" (to visually select the quoted block)
p (to paste yanked text)
This works, but I would like to know if the two last steps can be replaced by a single one, to avoid visual mode. I know it's not a huge gain keystroke-wise, but I think that the Vim philosophy would encourage what I'm trying to do, and every time I do this my mind keeps asking for this command. :-P
What I tried so far:
r (replace) replaces just one character
c (change) throws me into Insert mode and does not let me paste the text.
"_di"P
Delete inside quotes to the blackhole register; paste last yanked before cursor.
Or
ci"<Ctrl-R>0<ESC>
Change inside quotes to retrieve last yank; leave insert mode.
With my ReplaceWithRegister plugin, the last two steps would be gri". It also offers grr (replace current / [count] lines); though it only saves a little typing, I find this indispensable.
Key stroke wise, j$yi"k then vi"p is actually probably the fastest. However, if you absolutely must go into insert mode you can j$yi"k then "_ci"<C-r>" or ci"<C-r>0. The :help i_CTRL-R operator allows you to put the contents of a register into insert mode.
I usually try to keep it simple, using what I feel is more intuitive with every day commands:
j
yi"
k
ci"
<ESC>
p
I am trying to use vim properly - to aid me I've mapped my arrow keys to "" so that I am forced to use {hjlk} to move around.
This is causing me a problem when I want to just surround a character with spaces, eg:
"2+3" is better formatted "2 + 3"
Previously I would have put my cursor over the + and typed:
i[space][arrow-right][space][Esc]
That's 5 presses.
To do this without the arrow I seem to need to put the cursor over the + and go:
i[space][Esc]lli[space][Esc]
That's 8 presses.
I can convert the "li" into an "a" which reduces it to 7 presses:
i[space][Esc]la[space][Esc]
Short of writing this into a macro is there a better way of doing it? Is there some magic vim command which will allow me to do it in less than even 5 presses - and some way to generalise it so that I can do it to entire words or symbols, eg if I want to convert 3==4 to 3 == 4?
Personally, I think it makes most sense to destroy what you want to surround, and then repaste it.
c w "" ESC P
Obviously, you can replace both the object and the quotes with whatever you like. To change just one character + to be [space]+[space], you would do
s [space] [space] ESC P
on the +
The first thing that jumps to mind after reading just the title is surround.vim which is an excellent script to do all kinds of useful things along the lines of what you've described.
To solve your specific problem, I would probably position the cursor on the + and:
s[space]+[space][esc]
To change 3==4 into 3 == 4, I might position the cursor on the first =, and:
i[space][esc]ww.
i have been wondering about this as well. i tried with surround.vim, but the naive approach
S<space>
(after making a visual selection) does not work since the space is already taken up as a modifier for adding space to other surrounding character pairs. S<space><cr> adds a ^M in the output. Ss almost works but inserts a space only before.
after asking at tpope/surround.vim on github:
S<space><space>
in visual mode works. alternatively, from normal mode, ysl<space><space> works for a single character
Hah! I've been trying to figure out how to surround a block in spaces for quite a while and I finally found the right combination.
Using surround.vim you say surround selector space space.
So for this specific case I would use visual mode (a good trick for operating on single characters under the cursor BTW) thus: "vs " <- four key presses!
I also have a habit of typing things like argument lists without spaces. With this technique you can just navigate to the second argument using w and say "vws " to visually select a word and surround with spaces.
I prefer visual select mode generally. Also the alternate surround syntax "ysw " excludes the word final comma that is caught by "vw".
You could create a macro with one of the described actions and call it everytime you need it (Like amphetamachine proposed while I was writing) or you could simply search & replace:
:%s/\(\d\)\(+\|-\)\(\d\)/\1 \2 \3/g
You probably have to execute this command two times because it will only find every second occurence of +/-.
EDIT:
This will replace everything without the need to be called twice:
:%s/\d\#<=+\|-\d\#=/ \0 /g
Try positioning your cursor over the '+' and typing this:
q1i[space][right arrow][space][left arrow][esc]q
This will record a quick macro in slot 1 that you can re-use whenever you feel like it, that will surround the character under the cursor with spaces. You can re-call it with #1.
There is also the more versatile one:
q1ea[space][esc]bi[space][right arrow][esc]q
Which will surround the word under the cursor ("==" counts as a word) with spaces when you hit #1.
You could set up a mapping like this (press enter in visual mode to wrap spaces):
:vnoremap <CR> <ESC>`<i<SPACE><ESC>`>la<SPACE><ESC>h
This method allows you to use . to repeat the command at the next +.
Put your cursor over the + and type:
s[SPACE][CTRL-R]"[SPACE][ESC]
I know this is and old thread, but this might be useful to someone. I've found that the map (map it to anything else you want!)
noremap <leader>ss diwi<SPACE><C-R>"<SPACE><ESC>B
works ok both for turning 'a+b' into 'a + b' (when used over the '+' char) and for turning 'a==b' into 'a == b' (when used over either the first or the second '=' sign).
I hope it's useful to someone.