skip to Main Content

I want to easily wrap my code in an argument. For example:

1 + 1;

I want this to be in console.log() after wrapping:

console.log(1+1);

I tried using Surround Vim, but it’s for HTML and not really suitable for JavaScript, because it does not move semicolon which is wrapped :

V for select entire line.
S for enter in

console.log(1 + 1;)

Do you know a better way or Vim plugin ?

This link does not apply to my specific case :
Wrapping a code block around code in VIM

I’m learning Vim 9 (in terminal). I’m going back to learning programming (with JS and soon PHP).

2

Answers


  1. V puts you into visual-line mode. If you don’t want to operate on the whole line, then there is no point using it.

    In this case, you should use plain visual mode, with v, and an appropriate motion:

    vt;            " visually select till semicolon
    S              " trigger Surround
    f              " enter "function" sub-mode
    console.log    " type name of function
    <CR>           " press enter
    

    or you could bypass visual mode entirely:

    yst;           " surround till semicolon
    f              " enter "function" sub-mode
    console.log    " type name of function
    <CR>           " press enter
    

    See :help ys (assuming Surround was installed properly), :help visual-mode, :help t, an :help navigation in general.

    FWIW, this is how you would do it without Surround:

    ct;            " change till semicolon
    console.log(   " insert function name and opening parenthesis
    <C-r>"         " insert changed text
    )              " insert closing parenthesis
    <Esc>          " leave insert mode
    

    See :help c and :help i_ctrl-r.

    Login or Signup to reply.
  2. Based on your question "do you know a better way?"

    I’d just do

    Iconsole.log(<Esc>$i)<Esc>
    

    Insert "console.log(" at the start of the line, jump to the end and insert the closing parenthesis before the semi-colon. Just text editing.

    Technically, that’s two insertions so you would e.g. have to press uu to undo both of them. This is a caveat and I’d happily ignore it.

    A slightly more complicated way to do it (and only worthwhile if you want to operate on several lines at once) is to use the :substitute command like this

    :[range]s/s*zs.*ze;/console.log(&)/
    

    Where [range] is the lines to operate on (leave out for current line only).

    Our actual match is anything or .*, contained in zs and ze to mark the start and end of match, respectively. Everything outside is not captured, that’s leading whitespace (if any) and the trailing semi-colon.

    This is replaced by "console.log()" with our captured match & inserted between the parentheses.

    For reference, see :help substitute, :help /zs and :help s/&.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search