1

Within a given line, I would like to search for a text and replace it with a different text at a specific column number within the same line. for example, I would like to replace,

port_a,

port_xyz,

with,

port_a          (port_a),

port_xyz          (port_xyz),

I understand we can use,

%s/\(\w\+\)/          (\1),/g

But, this will always give me 10 spaces (assuming I added 10 spaces in the command above) between the word and following '('.

But, I would like to have the '(' aligned at column number 10 on each line. Is there a way using regexp that I can achieve this, maybe, by specifying column number in the command?

I tried the command I specified above and manually align the '('. But, I would like to understand if there is an easier way to achieve this.

1
  • There are a couple of plugins which will help with aligning text. It might be easier to insert those 10 spaces and then use a plugin to make it look neat. Commented May 20 at 7:24

1 Answer 1

1

Vim's regular expressions dialect allows you to match text at a specific column but there is no equivalent in the "replace" part of a substitution, which doesn't use regular expressions.

The only way to put some logic in the replacement part is to use a vimscript expression by way of the :help \= notation, which would look like this:

:%s/\(\w\+\)/\=<your expression>/g

Let's iterate…

  1. Reuse the match in the replacement with :help submatch().

    Here we use a tab as separator, just to have something in between the two members of the line:

    :%s/\(\w\+\)/\=submatch(0).."\t("..submatch(0)..")"/g
    

    Outcome:

    port_a   (port_a),
    
    port_xyz (port_xyz),
    
  2. Insert an arbitrary number of spaces with :help repeat():

    :%s/\(\w\+\)/\=submatch(0)..repeat(' ',10).."("..submatch(0)..")"/g
    

    Outcome:

    port_a          (port_a),
    
    port_xyz          (port_xyz),
    
  3. Calculate the number of spaces to insert based on the length of the match.

    :%s/\(\w\+\)/\=submatch(0)..repeat(' ',10-submatch(0)->len()).."("..submatch(0)..")"/g
    

    where the number of repetitions is the result of 10 (the target column number) minus the length of the match. See :help len().

    Outcome:

    port_a    (port_a),
    
    port_xyz  (port_xyz),
    

Note that this demonstrates the general technique, which happens to work well with the simple sample that you provided. In the real world, you might come across double-width characters or tabs that would require something smarter than len(). Or your match might not be all the text that is on the line, which would make the computation trickier. Etc.

To handle that complexity, the best course of action is to dig into :help function-list, and :help string-functions specifically, and build our command according to your specific needs.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.