Wednesday, April 20, 2016

Re: Right Aligning Mid-line After a Marker?

On 20 April 2016, Mike K. <lists@koralatov.com> wrote:
> I'm trying to work out how to make vim right-align comments in my
> various config files whilst leaving the rest of the line where it is.
>
> Here's what my .muttrc currently looks like:
>
> set attribution = "* %n wrote on %D:" # Date in ISO 8601 format
> set include = yes # Include original message in reply
> set indent_string = "> " # Use `>' as quote character
> set nomarkers # Don't add marker to wrapped lines
>
> And here's what I'm trying to make it look like:
>
> set attribution = "* %n wrote on %D:" # Date in ISO 8601 format
> set include = yes # Include original message in reply
> set indent_string = "> " # Use `>' as quote character
> set nomarkers # Don't add marker to wrapped lines
>
> So, my question is this: is it possible to get vim to insert the
> required number of spaces to get all the text after the `#' to align
> on the right, say in column 78? I've tried googling and came up with
> nothing.

Yeah, you can do it if you're really determined. Add this to your
vimrc:


function! Hashalign(text)
let width = strdisplaywidth(a:text)
return width < &tw ? substitute(a:text, '^.\{-}\\\@<!\%(\\\\\)*\zs\ze#',
\ repeat(' ', &tw - width), '') : a:text
endfunction

autocmd BufWritePre *
\ if &ft ==# 'muttrc' |
\ %s/.*\\\@<!\%(\\\\\)*#.*/\=Hashalign(submatch(0))/ |
\ endif


Sketch of how this is supposed to work:

strdisplaywidth() is a smarter strlen(). It counts screen cells.
It knows about unicode, tabs, wide characters, and the like.

The \\\@<! thing is negative lookbehind. It means "no preceding
backslash".

\%(\\\\\)* finds an even number of backslashes. Together with
\\\@<! and the following #, it makes sure you don't try to align \# and
the like.

^.\{-} is non-greedy match. It makes sure you align the first
unescaped #, rather than the last one.

\zs\ze marks the point of insertion. Spaces are inserted just
before the first unescaped #.

The autocmd aligns comments just before the file is written to disk,
but only if it has type muttrc.

\= in %s/// is expression evaluation, and submatch(0) is the entire
string matched. Since the pattern on the left matches entire lines,
Hashalign() is called for all lines with comments.

That's about all. The result is still flawed, since tabs inside
comments can still mess up alignment. Fixing that is left as an
exercise. :)

/lcd

--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

No comments: