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

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

Related

vim: replace all characters up to a given token

Using vim I would like to replace all characters up to a certain one with another character, say a blank space - without affecting the layout/number of characters in the line. Here's an example:
Before:
real(kind=R12), intent(out) :: my_var
After replacing , intent(out) with blanks (i.e. starting from ,, and going up to )):
real(kind=R12) :: my_var
I know about r to replace one character, and about nr to replace n characters, but I would like to know whether I can accomplish my task without first having to count the characters I want to replace.
Thanks a lot for your replies!
Visual mode is probably the shortest way here:
vt:r
v enter visual mode
t: select till :
r (note space after r) replace selected region with spaces.
In command mode type 'df?' to delete up to that (?) character. Then 'i' to go back to insert.
For example if the following sentence is in your view:
The wizard quickly jinxed the gnomes before they vaporized.
and you enter dfs
You will be left with:
before they vaporized.
I know about r to replace one character
Did you know that R will keep you in that replace mode? So you could hit R and then hold Space until you've replaced everything you want.
However, I'd still go with Thor's answer. Visual mode allows you to use the efficient text navigation methods in vim without having to count out characters.
But if you disagree, there's always EasyMotion.
You can use regular expression here (use (.*?) to reference all values up to a token).
For instance:
The regex: (.*?)foo will get rid of everything up to foo.

Vim jump back over spaces inside of curled braces

Lets say, I have wrote this piece of LaTeX in vim:
A_{\vec B}_
^
Cursor
The cursor is at the marked position. Now I want to add a \vec in front of the A.
I tried <Esc>Bi\vec <Esc>WW but I want B and W to jump over spaces which are inside of curled braces.
Any ideas how to do that?
Edit: Maybe I should've wrote, that I wanted to map this to a shortcut. A and B are just Examples for Strings which do not include spaces.
SOLUTION: I think I have found, what I was searching. With ? you can do a backward search with a regular expression.
You can't make B or W treat a braced string as a Word, but you can use % to jump from one end of a braced string to the other.
There are several ways to achieve a similar job. W and B only stop at whitespaces, as far as I know, so you can jump twice between words with 2B, or set insert mode at the beginning with I, or search for a letter, with f, F, t or T. Also 0 and $ to go to the beginning or end directly. There are many possibilities. I hope one of them can be useful instead.
FAi\vecESC$
Does it assuming that B is really at the end of the line

How to set initial caps in VIM?

In VIM, it's really easy to change a word of text to use uppercase or lowercase:
# in visual mode
# change word to uppercase
gUw
# change word to lowercase
guw
Is there a simple way to modify the word to use initial caps?
Assuming cursor is at the beginning of the word, use
gUl
(if the word was all-lowercase) or
gUllgue
to explicitly make the first letter capital and other lower case.
It's the same that you used, only instead of w (word motion) you use l (one symbol motion).
If the cursor is somewhere in the middle of the word, prepend b (go to the beginning of the word) to the commands above.
You can map some key to do this if you use it often.
I'd suggest moving to the beginning of the word with whatever motion command(s) you want, then pressing ~. This behavior is affected by the tildeop option, see :help ~ and :help tildeop for more info.
Depending on what your use-case is, any of the following may work.
Use ~ to toggle the case of the letter under your cursor.
Use :s/\<\(\w\)\(\w*\)\>/\u\1\L\2/ to search for a word, upper-case the first letter, and lower-case the rest.
guiwgUl to lower-case the word your cursor is on and then upper-case the first letter.
If you're on the word:
bgUl
If you're at the beginning of the word:
gUl
Unpacking that: b goes back one word (or to the beginning of the word you're on), gU upcases over movement, l moves right one character (which will be the first letter in the word).
Side note:
I have a plugin (well, it's not its main purpose though) that is able to convert names between camel case, underscore separated words, etc. Move the cursor on an identifier, and type :NameConvert lower_camel_case for instance (the command supports completion (<tab>, <c-d>) to display all the possible naming schemes)
To install it, you'll need lh-dev, and lh-vim-lib.
There is a function toupper which you can use to make conversion. Even in substitution you can use that. Like find all sentence beginnings, and convert the first character to upper case, as explained here: search and replace

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.

Resources