Can not find the good syntax for a vim sustitute pattern - vim

I have a bunch of t_ prefixed fonction names in a header file and i would like to remove this prefix from some of them.
I have ended by typing :
:s/\(\s+\)t_\([^(]+\)(/\1\2(/c
But vim complains with Pattern not found
What is wrong in my pattern ?

You forgot to put a backslash before + to give it its quantifier meaning. You can also probably simplify it using \< to match the start of a word instead of capturing spaces.

I suggest breaking the problem down, first the search:
/\v\s+\zst_\ze.*\(
Now the substitution:
:s///\c
We can reuse a search pattern simply typing an empty search on the substitution
OBS: I suppose your functions have () at the end of the line, so .*().
Another thing; \zs and \ze to match only t_, for more see: :h \zs.
If you are using neovim you can see what happens befor hitting enter, just put these lines on your init.vim:
if has("nvim")
set inccommand=nosplit
endif

Related

vim multiple character substitute regex issue

I am little new to Vim world. I am trying to substitute *=, ~=(actually [special char]=) in to [whatever is symbol]=(adding space both sides). Here is my substitute command:
:%s/[~,\*]=/ = /g
the problem in this case is that I am not able to add respective special symbol before the equal sign. Can you help me...
This is a classic capture and replace use case. Capture the symbol part by enclosing it in \(...\), and then reference it in the replacement part via \1. You'll find more details at :help s/\1 (or :help :substitute in general):
:%s/\([~,\*]\)=/ \1= /g
Alternatively, you can start the match only on the = with \zs. This asserts that the symbol part is there, but as it isn't included in the match, you don't need to reference it:
:%s/[~,\*]\zs=/ = /g
The same trick can be applied with \ze at the end. As you can see, this often results in shorter commands.
This is probably the simplest answer to your question:
:%s/[~,\*]=/ & /
An& in the replace segment means 'entire match'.

vi replaces with empty when searching

In vi (from cygwin), when I do searching:
:%s/something
It just replaces the something with empty string like
:%s/something// .
I've googled for a while but nothing really mentions this. Is there anything I should add to the .vimrc or .exrc to make this work?
Thanks!
In vi and vim, when you search for a pattern, you can search it again by simply typing /. It is understood that the previous pattern has to be used when no pattern is specified for searching.
(Though, you can press n for finding next occurence)
Same way, when you give a source (pattern) and leave the replacement in substitute command, it assumes that the replacement is empty and hence the given pattern is replaced with no characters (in other words, the pattern is removed)
In your case, you should understand that % stand for whole file(buffer) and s for substitute. To search, you can simply use /, followed by a pattern. To substitute , you will use :s. You need not confuse searching and substituting. Hence, no need for such settings in ~/.exrc. Also, remember that / is enough to search the whole buffer and % isnt necessary with /. / searches the entire buffer implicitly.
You may also want to look at :g/Pattern/. Learn more about it by searching :help global or :help :g in command line.
The format of a substitution in vim is as follows:
:[range]s[ubstitute]/{pattern}/{string}/[flags] [count]
In your case you have omitted the string from the substitution command and here what vim documentation stated about it:
If the {string} is omitted the substitute is done as if it's empty.
Thus the matched pattern is deleted. The separator after {pattern}
can also be left out then. Example: >
:%s/TESTING This deletes "TESTING" from all lines, but only one per line.
For compatibility with Vi these two exceptions are allowed:
"/{string}/" and "\?{string}?" do the same as "//{string}/r".
"\&{string}&" does the same as "//{string}/".
E146
Instead of the '/' which surrounds the pattern and replacement string, you can
use any other single-byte character, but not an alphanumeric
character, '\', '"' or '|'. This is useful if you want to include a
'/' in the search pattern or replacement string. Example: >
:s+/+//+
In other words :%s/something and :%s;something or :%s,something have all the same behavior because the / ; and , in the last examples are considered only as SIMPLE SEPARATOR

Find and replace only part of a single line in Vim

Most substitution commands in vim perform an action on a full line or a set of lines, but I would like to only do this on part of a line (either from the cursor to end of the line or between set marks).
example
this_is_a_sentence_that_has_underscores = this_is_a_sentence_that_should_not_have_underscores
into
this_is_a_sentence_that_has_underscores = this is a sentence that should not have underscores
This task is very easy to do for the whole line :s/_/ /g, but seems to be much more difficult to only perform the replacement for anything after the =.
Can :substitution perform an action on half of a line?
Two solutions I can think of.
Option one, use the before/after column match atoms \%>123c and \%<456c.
In your example, the following command substitutes underscores only in the second word, between columns 42 and 94:
:s/\%>42c_\%<94c/ /g
Option two, use the Visual area match atom \%V.
In your example, Visual-select the second long word, leave Visual mode, then execute the following substitution:
:s/\%V_/ /g
These regular expression atoms are documented at :h /\%c and :h /\%V respectively.
Look-around
There is a big clue your post already:
only perform the replacement for anything after the =.
This often means using a positive look-behind, \#<=.
:%s/\(=.*\)\#<=_/ /g
This means match all _ that are after the following pattern =.*. Since all look-arounds (look-aheads and look-behinds) are zero width they do not take up space in the match and the replacement is simple.
Note: This is equivalent to (?<=...) in perl speak. See :h perl-patterns.
What about \zs?
\zs will set the start of a match at a certain point. On the face this sounds exactly what is needed. However \zs will not work correctly as it matches the pattern before the \zs first then the following pattern. This means there will only be one match. Look-behinds on the other hand match the part after \#<= then "look behind" to make sure the match is valid which makes it great for multiple replacement scenario.
It should be noted that if you can use \zs not only is it easy to type but it is also more efficient.
Note: \zs is like \K in perl speak.
More ways?!?
As #glts mentioned you can use other zero-width atoms to basically "anchor" your pattern. A list of a few common ways:
\%>a - after the 'a mark
\%V - match inside the visual area
\%>42c - match after column 42
The possible downside of using one of these methods they need you to set marks or count columns. There is nothing wrong with this but it means the substitution will maybe affected by side-effects so repeating the substitution may not work correctly.
For more help see:
:h /\#<=
:h /zero-width
:h perl-patterns
:h /\zs

VIM search for characters starting with ampersand

I have to search for something like &variable (and replace with &variable.test). I could just do \&variable, but vim also shows me all characters starting with &variable (&variableXXX for instance), which I do not want. I thought this - /\<\&variable\> would work, please let me know where am I going wrong.
The first problem is that \& is not a literal & its a special regex match that matches branches in vim. To match a literal & just use &.
The second problem is that \< matches the beginning of a keyword by looking to see if the next character is a keyword. However & is not normally a keyword so it always fails.
To get around this you can make & a keyword by doing
set iskeyword+=&
Then you can use the regex \<&variable\> to match the things you want.
Relevant help pages :h iskeyword, :h /\< and :h \&
Short answer: use /&variable\>.
You don't want the \ in front of the &. See help \&.
Your \< is in the wrong place -- it belongs after the &, not before, since & is not a keyword character (:help keyword).
In fact, you don't need the \< at all. You could search for &variable\> and you would find &variable but not &variableXXX. You don't have to use \< just because you're using \>.

How to do substitution only on highlighted text in vim?

Before doing substitution, I usually type /foo to search the pattern first.
Vim automatically highlight all strings match the pattern.
Then I figure out how to write the substitution command :%s/foo/bar/g.
When the pattern is complex, it's much harder to write the substitution command than the search command.
If I can do substitution only on highlighted strings. It becomes easy.
For example:
Question: Translate Part of a Line
I can figure out the search pattern: /\[\[\(http\)\#!.\{-}\]\]
But I cannot figure out the substitution command easily.
You can replace the previously searched pattern if you use an empty string as the search pattern in the substitute command:
After /foo type :%s//bar/g in normal mode to replace "foo" by "bar".
You could use the 'c' flag to tell Vim to confirm before replacing. It highlights and stops to ask before every match it finds to the given pattern.
:%s/foo/bar/gc
I just figured out:
:%s##\=substitute(submatch(0), '_', '/', '')#g
But is there any better ways?

Resources