How can you get a formatted list inside comments with a leader?

23 views
Skip to first unread message

Benjamin Fritz

unread,
May 12, 2008, 1:03:38 PM5/12/08
to vim_use
I would like to make a formatted list inside of a c-style comment,
with * comment leaders on each line. For a simple example, with vim -N
-u NONE and :set tw=20, I would like to obtain the following with no
manual formatting:

/*
* 1. Mary had a
* little lamb
*/

This seems a simple task, but both methods I've tried have failed.

Method 1: using :set fo+=n formatlistpat=^\\s*\\*\\s*\\d\\+\\.\\s*

Idea: get Vim to recognize the list as a "numbered list" and format it
appropriately.

Typing exactly the same text gives:
/*
* 1. Mary had a
* ltle lamb
*
*/it

Note _two_ problems with this:

1. The comment leader is indented along with the text
2. The cursor, for whatever reason, is placed in the middle of the
word "little" when the automatic linebreak/indent happens.

This behavior puzzles me, but not yet ready to give up, I try method
2. (be sure to relaunch vim or set fo and flp to their defaults).

Method 2: using set comments=ns1:/*,nmb:*,nex:*/,nfb:1.

Idea: use 1. as a nested first-line-only comment. Obviously you
wouldn't actually do this for a numeric list, but bear with me...I'm
actually doing this for several specific key words.

Result:

/*
* 1. Mary had a
* 1. little lamb
*/

Note the problem: the "first line only" comment is included on the
second line as well. This bizzare behavior is made even worse if you
try typing the text on the first line instead, yielding:

/* 1. Mary had a
* little lamb
*/

Note that this is exactly the result we want, but it only works on the
first line of the outer comment. This inconsistency is puzzling, and
it also makes this unworkable as a general solution, where the list
can occur anywhere within the comment.

If anyone understands what is causing the problem with either method,
please enlighten me. If anyone knows a workaround or an alternate
method to accomplish this, that's even better.

I'm using Vim 7.1.297 Big for MS Windows, obtained from the "Cream"
download page on sourceforge.

Brett Stahlman

unread,
May 12, 2008, 1:45:14 PM5/12/08
to vim_use
Benjamin,
I have had success writing my own formatting function and using
'formatexpr' to bypass the builtin formatting completely when I
required non-standard formatting for special-purpose comments.
Although it puts more of the programming burden on you, it gives you
almost complete control over how the formatting is performed. Your
formatting function is free to consider any sort of leading or
trailing context necessary.

Hope it helps...
Brett S.

Benjamin Fritz

unread,
May 12, 2008, 2:56:57 PM5/12/08
to vim...@googlegroups.com

I considered going this route, but is there a way to have this
formatting function _only_ act when it matches the specific case I
want, and have the default behavior be applied in all other cases? I
don't want to re-write Vim's built-in autoformat capability!

Brett Stahlman

unread,
May 12, 2008, 6:33:23 PM5/12/08
to vim_use


On May 12, 1:56 pm, "Benjamin Fritz" <fritzophre...@gmail.com> wrote:
> don't want to re-write Vim's built-in autoformat capability!- Hide quoted text -

Your function will be called whenever the line is long enough that a
break might be required; however, if your function returns nonzero,
Vim will perform its standard internal formatting. This lets you
decide, based upon the context of the surrounding lines, whether you
need to do anything special. If not, you can simply return 1 to get
the default formatting.

Brett Stahlman
>
> - Show quoted text -

Benjamin Fritz

unread,
May 13, 2008, 10:25:30 AM5/13/08
to vim...@googlegroups.com
On 5/12/08, Brett Stahlman <bretts...@comcast.net> wrote:
>
>
>

Something weird is going on. Try this:

:set formatexpr=0 tw=10

Type: Mary had a little lamb

I get "Mary had a little lamb" all on one line, as expected.

Now :set formatexpr=1 and repeat.

I get:

Mary had a
little
lamb

Again, this is as expected.

But now, go to the first line (where "Mary had a little lamb" is all
on one line) and use gqq. Nothing happens!

:help gq says it uses 'formatexpr'

:help 'formatexpr' says it is "evaluated to format a range of lines
for the gq operator" but that it is "also evaluated when 'textwidth'
is set and adding text beyond that limit." It seems to be evaluated
_only_ in the second case.

What's going on?

Tony Mechelynck

unread,
May 13, 2008, 10:53:44 AM5/13/08
to vim...@googlegroups.com
On 13/05/08 16:25, Benjamin Fritz wrote:

I don't get the same results: with formatexpr=0 and with formatexpr=1 I
get no formatting. With formatexpr= (the empty string) the line is
reformatted. This contradicts the help sentence "When the function
returns non-zero Vim will fall back to using the internal format
mechanism.".

Best regards,
Tony.
--
"There are three possibilities: Pioneer's solar panel has turned away
from the sun; there's a large meteor blocking transmission; or someone
loaded Star Trek 3.2 into our video processor."

Brett Stahlman

unread,
May 13, 2008, 11:08:07 AM5/13/08
to vim_use
> What's going on?-

Do you have any of the following flags in your 'formatoptions'
setting?

b, v, l

:help fo-table

Benjamin Fritz

unread,
May 13, 2008, 11:16:38 AM5/13/08
to vim...@googlegroups.com

For the example I gave, my formatoptions is set to "tcq"

Brett Stahlman

unread,
May 13, 2008, 11:42:15 AM5/13/08
to vim_use


On May 13, 10:16 am, "Benjamin Fritz" <fritzophre...@gmail.com> wrote:
> For the example I gave, my formatoptions is set to "tcq"- Hide quoted text -

Yes. Those flags don't appear to make a difference when formatexpr is
used. Hmmm. It's as though there's an implied 'l' in 'formatoptions'
when 'formatexpr' is invoked by gq. Strange... Using gw instead of gq
*does* appear to work, in spite of the fact that Vim help says gw
doesn't use formatexpr. (Actually, that is an issue I reported
sometime back, which Bram says he may attempt to fix in a backwards-
compatible way someday...)

Benjamin Fritz

unread,
May 13, 2008, 3:21:11 PM5/13/08
to vim...@googlegroups.com
On 5/13/08, Brett Stahlman <bretts...@comcast.net> wrote:
>
>
>

I'll think about that some more later. Probably will post it to vim_dev.

In the meantime...I'm having a lot of trouble making this function.

First problem:
I'm doing something like:

let subst_command = s/will_not_match/replace_pattern/
silent! execute subst_command

But even though the pattern does not match, v:errmsg is not set. Is
there a reason for this?

Also, I'm having a LOT of trouble trying to restore the cursor to
where it needs to be while inserting. I did find an example using
col() and cursor()...I'll have to give that a shot, but does anyone
know of a good, reliable method to restore cursor position within a
formatexpr function?

Finally, Brett:

Have you had any success with calling gw within the formatexpr as
discussed here:

http://tech.groups.yahoo.com/group/vim/message/87942?threaded=1&var=1&p=2

or have you discovered a better way to do this? I have a very similar
situation: I only want to apply special formatting to the lines
following the list headings, the rest of the lines can be formatted
normally.

Brett Stahlman

unread,
May 13, 2008, 4:19:48 PM5/13/08
to vim_use
It does get set for me.

>
> But even though the pattern does not match, v:errmsg is not set. Is
> there a reason for this?
>
> Also, I'm having a LOT of trouble trying to restore the cursor to
> where it needs to be while inserting. I did find an example using
> col() and cursor()...I'll have to give that a shot, but does anyone
> know of a good, reliable method to restore cursor position within a
> formatexpr function?
>
> Finally, Brett:
>
> Have you had any success with calling gw within the formatexpr as
> discussed here:
>
> http://tech.groups.yahoo.com/group/vim/message/87942?threaded=1&var=1...

As I recall, Bram never responded to my question about a "correct way"
to handle the normal case, and I let the thread die. I ended up
writing my own code to handle even the normal case, which was
definitely more work, but gave me more control. I guess part of the
reason I didn't want to use gw, even though it appeared to work, is
that it's not supposed to work, and I don't like relying upon
undocumented (or incorrectly documented) behavior.

Brett Stahlman

>
> or have you discovered a better way to do this? I have a very similar
> situation: I only want to apply special formatting to the lines
> following the list headings, the rest of the lines can be formatted
> normally.- Hide quoted text -
Reply all
Reply to author
Forward
0 new messages