1

Is there a easy way to align phpdoc comment blocks in vim?

I want

/**
 * Call an API method.
 * @param string $method The API method to call, e.g. 'lists/list'
 * @param array $args An array of arguments to pass to the method. Will be json-encoded for you.
 * @return array Associative array of json decoded API response.
 */

to be formatted as

/**
 * Call an API method.
 * @param  string $method The API method to call, e.g. 'lists/list'
 * @param  array  $args   An array of arguments to pass to the method. Will be json-encoded for you.
 * @return array          Associative array of json decoded API response.
 */

Formatting the line that contains @return may be tough, because it doesn't contain the third column. So even if I can come up with a way to align only the lines that contain @param that would be great.

Edit:

I have already tried the tabular addon, but that doesn't work since in the above case, we can't use space as the delimeter.

Edit 2:

This is the second usecase for which @PeterRincker answer is failing

/**
 * Call an API method.
 * @since 1.7
 * @param string $method The API method to call, e.g. 'lists/list'
 * @param array $args An array of arguments to pass to the method. Will be json-encoded for you.
 * @return array Associative array of json decoded API response.
 */

It becomes

/**
 * Call an API method.
 * @since  1      .7
 * @param  string $method The API method to call, e.g. 'lists/list'
 * @param  array  $args   An array of arguments to pass to the method. Will be json-encoded for you.
 * @return array          Associative array of json decoded API response.
 */
3
  • Tabular vim plugin should do that. Commented Mar 31, 2014 at 14:59
  • @Amit I already tried the tabular plugin, but it won't for this case, because we can't use space as the delimiter. Commented Mar 31, 2014 at 15:11
  • It can align on a regex also. Commented Mar 31, 2014 at 15:28

1 Answer 1

3

I'm sure this could be simplified but it worked for your example case:

:Tabularize/@\w\+\s\+\zs\S\+\|\%(@\w\+.*\)\@<=\u.*/

Overview

The key to this is to pick good deliminators to split on because we want to align the @return line as well as the @param lines. Use Tabularize to split on the start of the WORD after an @-word and the first uppercase letter.

Explanation

  • \| creates a branches in a regex pattern. This means we can split on both deliminators
  • @\w\+ matches @ followed by a word. e.g. @param
  • \zs set the start of the match
  • @\w\+\s\+\zs\S\+ match an @-word followed by a WORD and set the start of the match a the start of the WORD
  • \u match an uppercase letter
  • \u.* match the uppercase letter followed the rest of the line to prevent more splits
  • \%(...\) a non-capturing group
  • \@<= is vim's positive look behind. \(foo\)\@<=bar matches bar after foo in foobar
  • \%(@\w\+.*\)\@<=\u match an uppercase letter that follows an @-word

Common Tabular alignment idioms

  • use \zs to set the start of a match
  • end with .* to consume the rest of the line and prevent more splitting

For more help see:

:h :Tabularize
:h /\|
:h /\S
:h WORD
:h /\zs
:h /\u
:h /\%(
:h /\@<=
Sign up to request clarification or add additional context in comments.

8 Comments

This works for this usecase, but fails for other similar usecases. But I can use this as a base and then try to modify it for other usecases. Can you kindly explain me briefly what is happening here. Thanks.
@Sudar I have added an explanation. You may want to provide some of the sample text that fails
@PeterRincker Thanks for the explanation. It fails when we have a dot (.) in the text. I have updated the question with that usecase. I should have included it before itself. Sorry about it.
This answer was near perfect for me. I did however change it as our doc blocks were not up to snuff and didn't start the comment of the param's with a capital letter. Doing the following works for me and hopefully will help someone else. :Tabularize/@\w\+\s\+\zs\S\+\|\%(@\w\+.*)\@<=\s\w.*/
This works fine for me, but how to mapping it the shortcut, I tried vmap ta :Tabularize/@\w\+\s\+\zs\S\+\|\%(@\w\+.*\)\@<=\u.*/<CR>, but it won't work
|

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.