How to jump to a specific character in vim? - vim

How can I jump to the next character X in vim?
I frequently use, e.g., dt: or ct: to delete/change everything up until a colon (or some other character).
Is there any short key combo to simply move my cursor position to that character?

You can type f<character> to put the cursor on the next character and F<character> for the previous one.

t and f work without a command as well, so to move to colon use f: and to move to right before colon use t:

If you do a search for that character with /, you can then hit n to move to the next occurrence of it.

Maybe you are just searching for a pure vim combination but EasyMotion is a plugin that worth trying. HTH. :)

Related

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

Command in VIM to replace something by the same character many times

Is there a vim command to replace something (a word, an inner object, a motion, etc) by a character but as many time as there are character to replace.
Exemple:
The cursor is at the beginning of the word foo
I want X and replace foo by XXX.
(I don't want to have to count the number of letter, so 3rX is not a valid answer)
I don't want a script or a mapping, I just want to know if there is already a command to achieve that.
I think this works:
verX
Of course the 'e' could be a different movement command.
If you have the cursor at the beginning of a word then you can do the following:
v Go in visual mode
w Select the word ( here you can use other motions too)
r replace with
X here you puts the character you want to use.
verX in normal mode to replace a word with Xs
Similar to Colin's answer, but using the "inner word" selection lets you be less picky about the cursor position:
viwrX
visual inner word replace X

Command to surround a character with spaces in vim

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.

Vim copy and paste

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.

Vim split line command [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I insert a linebreak where the cursor is without entering into insert mode in Vim?
In vim, J joins the next line to the current line. Is there a similar one-key (or relatively short) command to split a line at a given cursor position? I know it be done with a simple macro, but it seems like if the J-command exists there should be a similar function. I've tried searching for it, but can't seem to find an answer.
rEnter while on whitespace will do it. That's two keystrokes.
I don't think that there is a single key command for this. The best you can do with stock vim is probably i Enter Esc.
My solution was to remap the K key since I never use the default action (look up the word under cursor with "man"), and my previous editor used Alt+j and Alt+k to join and split lines, respectively.
:nnoremap K i<CR><Esc>
This rolls those three annoying keystrokes into one.
There's probably a more sophisticated way to also eliminate any trailing whitespace, but I prefer to strip all trailing whitespace on write.
No. I've now read enough answers to conclude that there is no such command.
Easy answer:
Pressing 'Enter' while in insert will do it; but you're right, there oughtta be a key for it in command mode. I've wondered, too.
Since everyone has a favorite workaround, I will share mine. The assumption is that I will do anything to avoid having to reach for the Esc key.
ylprX ... where 'X' is the inserted character, which can even be a newline.
So, 'yl' is yank on char to the right, 'p' = paste the char, 'r' is replace that char; then you just type the new char. That's how much I hate using Escape.
(That was 'l', as in "move right", BTW)
Old thread, but I dont use "K" for the man page lookup or whatever magic it does. So I have this mapping in my .vimrc:
map K i<Enter><Esc>
I figured since "J" is join, "K" can be krack or something. :)
You can split lines if you can create a regular expression for the location to add the split. For example if you want to split the lines at each semicolon, you can use the following substitution:
%s/;/^v^m/g
to great effect
Jed's answer is most useful. I would like to add that I needed the "control-V-alternative", i.e. control-Q:
%s/;/^q^m/g

Resources