15

I have a line like this one:

function my_function(argument, another argument, but there are spaces)

I want to substitute the space characters (inside the argument's names) with underscore. I thus would like to use :

:s/\ /_/g

but how can I choose not to apply it to the whole line, but starting from, say, the cursor position ? (Or the third word) ?

  • 4
    In a regex, to describe the current cursor position you can use the atom \%#. So, you could use: :s/\v(%#.*)@<= /_/g. Which could be described as a space preceded by (@<=) characters after the cursor position. – user9433424 Jun 7 '16 at 9:40
  • 1
    You and Statox both proposed the \%# trick, I'll accept his answer if you don't write one... But could either of you explain the regexp with a bit more explicitly ? – Feffe Jun 7 '16 at 9:49
15

You could use the following solution:

First use v$ to select the text from the cursor to the end of the line. Then use the following command:

:s/\%V\ /_/g

The \%V indicate to change the text in the previously visually selected area, see :h /\%V.

If I take your example:

function my_function(argument, another argument, but there are spaces)

If my cursor is on the 40th column and I use the command I just wrote I get:

function my_function(argument, another argument,_but_there_are_spaces)

In answer to your comment you can also use

  • \%# which matches from the cursor position
  • \%>23c which matches after the 23rd column.
  • \%>'m which matches after the position of a mark

See :h /\%#, :h /\%>c and :h /\%>'m.

@User9433424 gave a way to use \%# in his comment. For the pattern with the mark you can set it wit ma and then use:

:s/\%>'a /_/g

An explanation of the pattern given by @User9433424 is the following:

:s/\v(%#.*)@<= /_/
:s/                    substitution command
   \v                  Enable the very magic mode
      %#.*             Any characters from the cursor position
           @<=         Check for matches just before what follows
              space    Followed by a space
               /_/     Substitute the matches by underscores

You'll want to see :h \v and :h /\@<=

  • It works fine ! But I'm not really used to visual selections and the whole process seems a little "heavy"... Do you think there could be something quicker ? – Feffe Jun 7 '16 at 9:38
  • Yes let me update my answer :) – statox Jun 7 '16 at 9:40
  • User9433424 gave this hint just before you, but you answered so I'm going to accept your answer if that's okay -- could you maybe explain the regexp pattern he uses a little more ? I'm still struggling with this... – Feffe Jun 7 '16 at 9:49
  • I tried to make the answer as clear as possible but if @User9433424 writes his own answer don't hesitate to accept it. – statox Jun 7 '16 at 10:04
  • 1
    Very nice explanation of the regexp, thank you ! And thanks for your comment on whose answer to accept :) – Feffe Jun 7 '16 at 10:06
5

You can use look behind (:h \@<=) to make sure there is a preceding '(', and an end-of-word boundary (:h \>) to make sure the substitution happens where you want it.

So, with the text:

function my_function(argument, another argument, but there are spaces)

running the command:

:s/\((.*\)\@<=\> /_/g

will produce:

function my_function(argument, another_argument, but_there_are_spaces)

This might be easier than having to position the cursor each time, provided the substitution always has a known starting point.

  • 2
    The substitution does not always have a known starting point : it was only to... correct a weird series of typo I made. But your answer is nonetheless interesting, thanks ! – Feffe Jun 8 '16 at 10:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.