Reputation: 1642
I have this piece of C code:
options->file_extension = DEFAULT_FILE_EXTENSION;
options->config = "";
options->max_file_bytes = DEFAULT_MAX_FILE_BYTES;
options->msg_sort_type = SORT_TYPE_NONE;
options->msg_sort_buffer_max_size = DEFAULT_SORT_BUFFER_MAX_SIZE;
options->msg_sort_buffer_flush_time = DEFAULT_SORT_BUFFER_FLUSH_TIME;
Is there any easy way in vim to align this so it becomes e.g. ?
options->file_extension = DEFAULT_FILE_EXTENSION;
options->config = "";
options->max_file_bytes = DEFAULT_MAX_FILE_BYTES;
options->msg_sort_type = SORT_TYPE_NONE;
options->msg_sort_buffer_max_size = DEFAULT_SORT_BUFFER_MAX_SIZE;
options->msg_sort_buffer_flush_time = DEFAULT_SORT_BUFFER_FLUSH_TIME;
Or even if I wrote the first line here as
options->file_extension = DEFAULT_FILE_EXTENSION;
options->config|<--cursor her now
Would there be a quick way to jump the cursor on the 2. line up to the =
of the previous line?
Upvotes: 2
Views: 378
Reputation: 2436
For a quick, non-robust, vimmy, non-plugin way to accomplish this task, consider the following command
.,+6s/\(\S*\)\s*=/\=submatch(1) . repeat(' ', 15 - len(submatch(1))) . '='
Analysis by component:
.,+6s
substitute command over the appropriate range
/\(\S*\)\s*=/
Pattern (regular expression) designed to match LHS of assignment (as many non-space characters as possible followed by as many space characters as possible followed by an assignment operator (=))
\=
Starts the "sub-replace-expression" context. Vim will "evaluate" the expression and use it to replace the matched text.
submatch(1) .
In the "sub-replace-expression" context, submatch(1)
will be replaced with the first submatch (similar to \1
). The .
is the concatenation operator.
repeat(' ', 15 - len(submatch(1)))
This expression does the "heavy lifting" of alignment. repeat
will create a list or string depending on the first argument, the ' '
says "repeat a single space", and 15-len(submatch(1))
says "repeat it that many times." Of course, 15 could be replaced with whatever column + initial nonspace character the assignments should be aligned at.
. '='
Puts the assignment operator back on. Note that we can't just type =
, because this is an expression, so to add it we must "concatenate it" with . '='
.
I say this is "non-robust," because as is it won't work with definitions (declarations with assignments), which is probably desirable. However, by changing the initial regular expression, a great deal of flexibility can be obtained. It's also worth knowing, because it exposes a pretty powerful tool within vim, and can probably do a lot of good work without having to depend on a plugin.
Further reading:
:help :sub-replace-expression
:help :repeat()
Upvotes: 1
Reputation: 10260
I use Align and I think it does the job:
:Align =
<leader>t=
or :'<,'>Align =
(i.e. :
from visual line). There's also Tabular:
:Tab /=
<leader>a=
PS: Tabular seems to be the most popular choice, but I can't tell why. Is there something with it that Align doesn't do?
Upvotes: 3