3

This is probably easier to explain with an example. I prefer expressing things like

const array = { a: 1, b: 2, c: 3 }

on a single line at first but eventually I might want to switch to

const array = {
  a: 1,
  b: 2,
  c: 3,
  d: 4,
}

as the array gets longer. I realized that I'm not doing this very efficiently and I was wondering if there's some builtin way, or at least a more elegant way, to toggle between the two different styles.

  • 1
    I assume the d: 4, in the second array is an error? Or do you want Vim to add this? Also, which language is this? For some languages there are specialised plugins or tools that can help. – Martin Tournoij Sep 15 '16 at 20:13
  • I meant it just to illustrate that the desired format changes once the line length gets unwieldy. I definitely don't want vim to add the 'd: 4', I just want an easy way to toggle the two styles. I like the trailing comma but I don't mind adding that manually. The example is javascript but this is a more general issue for me and ideally I would like a solution that can deal with both '[', '{', and '(' brackets. – Ivanna Sep 15 '16 at 20:47
2

There's a plugin called SplitJoin.vim that aims to address exactly your problem. Find it here: https://github.com/AndrewRadev/splitjoin.vim

  • Welcome to our SE! Try to provide more than just a link in your answers. In this case you could give some instruction on how to use the plugin that you linked. – Tumbler41 Sep 28 '16 at 14:42
1

I think @nobe4's solution is more elegant, but I already wrote this :). So here's something I whipped up:

nnoremap <key> :call ToggleArrayFormat()<CR>

function! ToggleArrayFormat()
   let direction = search('}', 'cnp', line('.'))
   if (direction)
      normal! 0f{a^M
      while (search(',', 'cnp', line('.')))
         normal! f,a^M
      endwhile
      normal! f}i^M
   else
      echom "stuff"
      while !search('}', 'cnp', line('.'))
         normal! J
      endwhile
   endif
endfunction
  • ^M is not a literal "^M" and needs to be retyped with Ctrl+v, Enter (All three).
  • Replace <key> with whaveter key sequence you want.
  • Place your cursor anywhere on the first line of the array and press <key> to toggle the formatting

See :h search() and :h normal for more info.

Hope it helps.

1

Here is a slight workaround, which is interesting to learn new functionalities and can solve your problem:

If you consider having a , after each element in your array (which is valid, given the 2nd expression), you can use a substitution to do the job:

:s/\({\|,\)/\1\r/g

Let's break it down:

:s/                    create a substitution command
\(                     create a matching group for your regex
{\|,                   match a { OR a ,
\)                     end the matching group
/                      substitute the matched regex with 
\1                     the element matched in the group: a { or a ,
\r                     a end of line character
/g                     apply for all matching of the line

So you'll get:

const array = {
  a: 1,
  b: 2,
  c: 3,
  }

With your cursor on the last {, and from there << will de-indent the closing curly brace.


Now if you want to do the other way around, select your array in linewise Visual mode and simply press J.

This will Join the lines into one.

Or (as VanLaser) suggested, on the first or last line you can do:

V%J
  • V will enter linewise visual mode
  • % will go to the matching curly brace
  • J will join the lines

Some reading:

  • :h \|
  • :h \(
  • :h \1
  • :h v_J
  • :h %
  • 1
    For the 2nd part, "select your array in linewise Visual mode", V%J should do it :) if cursor is on 1st or last array line. – VanLaser Sep 15 '16 at 21:41

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.