How to change var[foo] to foo using Vim substitution? - vim

Today I came across this situation where I need to change var[name] to var [name] and a lot of other place where name could be description or other string. Can I do something like the following command:
%s/var[$variable]/$variable/g

Based on the title of the question, the following expression should change var[foo] to foo:
:%s/\vvar\[(.{-})\]/\1/g
But in the details you mentioned that you need to change var[name] to var [name], following should do that:
:%s/\v(var)(\[.{-}\])/\1 \2/g
Other ways of doing the second substitution from comments:
:%s/var\zs\ze\[.*\]/ /g
or
:%s/var\zs\ze\[[^]]*\]/ /g

Related: (g)vim replace regex
The thing to know, if you already know about regex and captures in general, is in this context you apparently have to escape the group characters, rather than it being the other way around:
%s/var[\(variable\)]/\1/g
Without more info, I can't be more helpful.

Related

Complex replacement in gVim

I have been a terrible person as of late when it comes to Minecraft. I have over-modded it to the point that I need to completely re-write the IDs of them all.
The only problem is that... It'll take about a couple of hours jut to re-write them ONCE, not to mention if any of them collide with the original game. So, in order to save time, I figured I'd use Vim, but after reading through several of the helpful posts on here, I still only know a minimal amount about the replacement feature/command. Here's what I'm trying to do:
Replace this
I:exampleModnamePath.id=16389
I:exampleModnamePat2.id=19657
Etc.
With this
I:exampleModnamePath.id=20000
I:exampleModnamePath.id=20001
Etc.
This continues for a while, and to those who answer, could you please inform me of how it works, so I don't have to ask these questions all the time?
For your perusal:
:let g:num = 1
:g/\.id=\d\+$/exec 's!\.id=\d\+$!.id='.g:num.'! | let g:num=g:num+1'
This is slightly simplified version of my code for (re)numbering chapters in the ebooks.
Idea in a nutshell: use :g to run something over affected lines; use :exec to generate/run new substitution command AND increment the counter. Tried it once and was surprised to find that the trick worked. Was inspired by my previous toying with :g//s/// combo.
I'm not sure what is the rule you are using to choose which number to use for replacement but if all you need
is just a new number that doesn't collide with previous ones you could try just replacing the first digit
with something in a range not used. Something like replacing 16389 with 76389
To do that you could use this :s/Path.id=.\(.*\)/Path.id=7\1
That would search for the string Path.id= followed by a single character and then a group of more characters.
I will replace it with the string Path.id=7 and the group previously selected.
You could make it more selectiv adding letters before Path.id to match only certain types of paths.

Perform search & replace using a callback command

I'm trying to search & replace inside my file for all occurrences of a particular pattern, then call toupper() on each match. In practice, there aren't that many occurrences that I couldn't just do this by hand, but I'm curious to improve my Vim skills and find a (simple) way to get Vim to do this for me. I say simple, otherwise I'll just forget.
From a read over the Vim help for s/, I should be able to do something like this:
:%s/\vfunction ([a-z0-9_]+)/\="function " . toupper("\1")/g
(Assuming I'm uppercasing all function definition names).
This actually just replaces the function names with the control character ^A though. How do I refer to the capturing group in the regexp?
Apologies. I should read more closely. I'll answer my own question anyway, instead of deleting it. You need to use submatch(n) to refer to the capturing group:
:%s/\vfunction ([a-z0-9_]+)/\="function " . toupper(submatch(1))/g
Use \U in the replacement pattern.
:%s/\vfunction ([a-z0-9_]+)/function \U\1/

Is there a way to get a snippet to work immediately after a word?

Whenever I try to use a snippet (using snipMate) after a word, without a space, it does not work. So I have to hit space, type my snippet, hit tab, and then eliminate the space. Is there a better way of doing this? Is there a way to get the snipppets to work even immediately after a word? Here is what I mean:
let us say my snippet is this:
snippet test
<some code>${1}</code>${2}
typical use:
hello test[TAB]
turns into this:
hello <some code>|</code>
but if I try this:
hellotest[TAB]
it turns into this:
hellotest_____
the _ being white space. Is there a way to fix this?
Vim abbreviations can be of three types (full-id, end-id, and non-id, cp. :help abbreviations), which help solve this problem. snipMate, however, allows all non-whitespace characters for snippet names, and therefore has to rely on whitespace for separation.
You have to modify the parsing of the snippet name, in plugin/snipMate.vim, it's in the function TriggerSnippet():
let word = matchstr(getline('.'), '\S\+\%'.col('.').'c')
There's no setting to that effect if that's what you ask. You will have to look at the source and do the change there yourself, I'm afraid.
Also, it can probably seen as a limitation but it's definetely not a bug so what you are after is an improvement, not a "fix". My advice, though, is to use it as it was designed: having triggers work even if they are part of another word makes no sense at all. Spaces are the most natural way of separating ideas and words.

Vim replace two words with one another

How would one replace all instances of 'foo' with 'bar' and 'bar' with 'foo' in vim?
Take a look at this: how to write only one pattern to exchange two strings in two-ways in vim
:s/foo\|bar/\={'foo':'bar','bar':'foo'}[submatch(0)]/g
Aside from using a temporary word for the change, you could also use abolish plugin like this:
:%SubVert/{foo,bar}/{bar,foo}/g
:%s/foo/bbaarr/g
:%s/bar/foo/g
:%s/bbaarr/foo/g
It must exist an smartest way to do it, but this one will work for sure !
You can do it using temp word. Just be sure that it doesn't exists in the current document.
/\<asd123\>
:%s/\<foo\>/asd123/g
:%s/\<asd123\>/bar/g
:%s/\<bar\>/foo/g

Advanced searching in Vim

Is there a way to search for multiple strings simultaneously in Vim? I recall reading somewhere that it was possible but somehow forgot the technique.
So for example, I have a text file and I want to search for "foo" and "bar" simultaneously (not necessarily as a single string, can be in different lines altogether).
How do I achieve that?
/^joe.*fred.*bill/ : find joe AND fred AND Bill (Joe at start of line)
/fred\|joe : Search for FRED OR JOE
Actually I found the answer soon after I posted this (yes I did google earlier but was unable to locate it. Probably was just searching wrong)
The right solution is
/(foo\|bar)
#Paul Betts: The pipe has to be escaped
Vim supports regular expressions by starting in command mode with a '/'.
So using something like "/(foo\|bar)" (as was stated before) would solve the problem. It's good to know why that works and what you are using (regular expressions).
/(foo|bar)

Resources