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) ?

2
  • 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. Commented Jun 7, 2016 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
    Commented Jun 7, 2016 at 9:49

2 Answers 2

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 /\@<=

5
  • 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
    Commented Jun 7, 2016 at 9:38
  • Yes let me update my answer :)
    – statox
    Commented Jun 7, 2016 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
    Commented Jun 7, 2016 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
    Commented Jun 7, 2016 at 10:04
  • 1
    Very nice explanation of the regexp, thank you ! And thanks for your comment on whose answer to accept :)
    – Feffe
    Commented Jun 7, 2016 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.

1
  • 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
    Commented Jun 8, 2016 at 10:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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