1

When working in the C language, sometimes you have to write multi line macros like the following.

#define SOME_FUNCTION_LIKE_MACRO(a,b)     \
   foo(a);                                \
   bar(b);                                \
   baz(a+b);

Typically, after a few iterations of editing your code, the backslashes end up unaligned like:

#define SOME_FUNCTION_LIKE_MACRO(a,b)             \
   foo(a);                 \
   bar(b);                                  \
   baz(a+b);

And it drives me crazy. I always end up wasting a lot of time manually aligning them.

Is there a plugin/mapping/function/whatever for automatically aligning the line continuation characters? Something like select lines in visual line mode, hit a key combination and voila, you have aligned backslashes at the end.

2

Plugin vim-lion

by Tom McDonald

Install and add following line to your vimrc:

let g:lion_squeeze_spaces = 1

Now you can change

#define SOME_FUNCTION_LIKE_MACRO(a,b)             \
   foo(a);                 \
   bar(b);                                  \
   baz(a+b);

by pressing glip\ to

#define SOME_FUNCTION_LIKE_MACRO(a,b) \
   foo(a);                            \
   bar(b);                            \
   baz(a+b);

Alternatives to vim-lion

Vim-lion is a very small plugin (190 sloc) and has a few limitations (see example given by the plugin Align). There are more feature rich alternatives:

  • vim-easy-align (#4520) by Junegunn Choi. It has no default rule for \. However, it is not difficult to define one:

    let g:easy_align_delimiters = {
      \ '\': {
      \     'pattern': '\\$',
      \ },
      \ }
    

    With the default mapping ga you can re-align your code now with gaip\. Note, ga overwrites a builtin mapping (:h ga) (and competes with vim-characterize). The choice gl of vim-lion might be better:

    xmap gl <Plug>(EasyAlign)
    nmap gl <Plug>(EasyAlign)
    
  • Tabular by Matt Wozniski. By default no mappings exist, only the command :Tab[ularize] /\\$<CR>. Note that you do not need a visual selection or to specify a range before :[range]Tab[ularize] (but you can), Tabular tries to be smart to figure out the correct range (:h :Tabularize). See e.g. this vimcast for an introduction and suggestions for mappings. You can also use following from the plugin Align

    if exists(":Tabularize")
      nmap <Leader>tml :Tabularize /\\$<CR>
      vmap <Leader>tml :Tabularize /\\$<CR>
    endif
    
  • Align (#294) by DrChip (Charles Campbell) with default mapping \tml. From the documentation:

    Original: illustrates aligning multi-line continuation marks

    one \
    two three \
    four five six \
    seven \\ \
    eight \nine \
    ten \
    

    Becomes:

    one           \
    two three     \
    four five six \
    seven \\      \
    eight \nine   \
    ten           \
    

    Note, vim-lion struggles with this example. My vim-easy-align and Tabular proposals work fine.

I personally use vim-easy-align with the mapping gl.

0

I came up with this a few minutes after asking the question here.

You hit if you want to add backslashes at the end of a line, or multiple selected lines. You hit \ if you want to align all backslashes in the whole file or in the selected lines.

" Aligns backslash characters at the end of lines. 
" Useful when writing multiline macros or multiline strings.
function AlignBackslash()
  :silent! s@\s\+\\$@ \\@
  :silent! s/s*\\$/\=repeat(' ', 80-col('.')).'\'
  :let @/ = ""
endfunction

function RemoveDuplicateBackslash()
  :silent! s/\\\\$/\\/g
endfunction

" In normal mode align the whole file. 
nmap \\ mxggVG:call RemoveDuplicateBackslash()<cr>ggVG:call AlignBackslash()<cr>'x

" In visual select mode align selected lines.
vmap \\ :call RemoveDuplicateBackslash()<cr>gv:call AlignBackslash()<cr>

" Insert backslash at the end of current line and align it
nmap <c-\> A\<esc>:call AlignBackslash()<cr>

" Insert backslash at the end of selected lines and align them
vmap <c-\> :norm A\<esc>gv:call AlignBackslash()<cr>

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.