Search code examples
vimindentation

How to align code with left and right indentaion in VIM


I have this code:

struct
  {
     uint32_t                rsvd0           :  8;
     uint32_t                tag             :  8;       
     uint32_t                status_qualifer : 16;
  } dw0;

I want to format it like following:

struct
  {
     uint32_t                rsvd0 :  8;
     uint32_t                  tag :  8;
     uint32_t      status_qualifer : 16;
  } dw0;

How do I do this in vim.

Thanks


Solution

  • I've came up with something like this:

    /\v\s{10}(<\w+>)(\s{2,})?\ze :
    :%s//\2\1
    

    NOTE: I'm using very magic search \v to make the search easier

    In the substitution part we are using regex groups (), so we are ignoring 10 spaces before the second word \s{10}. You can change how many spaces do you want to get rid of. Then we are creating a group that matches the second word (<\w+>). Following that two spaces or more (optional) \s{2,})?. We then, finish the match by using the awesome vim \ze, a space and colon.

    The command uses the last search // which is replaced by group 2 followed by group 1.

    My final result was:

    struct
      {
         uint32_t                rsvd0 :  8;
         uint32_t                  tag :  8;
         uint32_t      status_qualifer : 16;
      } dw0;
    

    Another approach involves two global commands, where the first one just removes a bunchh of spaces between the columns.

    :g/_t/normal wel10x
    :g/  :/normal wwelldt:bP
    

    NOTE: you can select the lines above and run: :@+. I've tested those commands, and the same applies to the first solution.

    the first global command executes a normal command at the lines that match _t the command is:

    we ....................... jump to the first word and to the end of it
    l ........................ move one position to the right
    10x ...................... erases 10 chars
    

    The seccond global command runs over lines that match : at least two spaces followed by coma.

    ww ....................... jump to the second word
    e ........................ jump to the end of the word
    ll ....................... move the cursor twice to the right
    dt: ...................... delete until before :
    bP ....................... move to the word before and pastes the default register
    

    For more information:

    :h \ze
    :h magic
    :h regex
    :h normal
    :h global