Tuesday, January 31, 2012

Re: A Versatile fmt command

Hi howard!

On Di, 31 Jan 2012, howard Schwartz wrote:

> hi, More adventures with my Blind friend. Sun's version of fmt, let
> all lines starting with a dot (.) alone, in deferrence to he unix
> markup language, Troff. The Redhat version of fmt, does not do that.
>
> I love Vim's versatile internal fmt command. However, it defines a paragraph
> as a text block bounded either by blank lines, or one of the 2 character
> (troff) dot commands, set with the paragraph variable (e.g., .IP .LP etc.).
> My friend uses tons of dot commands and, so needs a fmt command that treats
> virtually every ``dot'' command as a paragraph boundary. That could approach
> 100 commands or so to set paragraphs to.
>
> So - I wrote a little script that ignore's dot commands (see below), and
> formats a single ``paragraph'' bounded only by blank lines. Here it is:
>
> keepmarks
> kA
> /^ *$\|\%$/
> kB
> 'A,'B/^[^\.]/s/^\([^\.]\)/>\1/
> 'A,'B!fmt -p '>'
> .,/^ *$\|\%$//^>/s/^>//
> 'A

There are some issues with this script. I am not sure, what you need the
keepmarks command there. I think you want rather:
:keepmarks 'A,'B!fmt -p '>'

The /^[^\.] matches lines, that do not start with either a dot or a
backspace (so you don't need to escape the . in a collation) and I am
not sure, if you need the search command in front of the :s command.

Then I think you can do something like /^ *$\|\%$kB

> It is mapped to, v which was simply map v !}fmt before. I learned one must
> unmap v first, before a new map will work.

I am not sure this is true. It should work without unmapping v first,
but it is probably cleaner to unmap v first. See also :h hasmapto(),
:h maparg() and :h mapcheck()

> Im now interested in expanding the script in two ways: Make it format an
> arbitary block of text, and make it format those quotes within emails like
> this:
>
> > Small line
> > a much larger and larger and larger line
>
> In so - a command that treats all dot commands are paragraph boundaries, that
> formats a single paragraph by default, and that formats quoted text (even
> interspersed with dot commands) within emails. Here is a try that does not
> work:
>
> if search("^>", 'cn') > 0
> %!fmt -p '>'
> elseif line("'>") > 0
> '<,'>/^[^\.]/s/^\([^\.]\)/>\1/
> '<,'>'!fmt -p '>'
> '<,'>/^>/s/^>//
> endif
> keepmarks
> kA
> /^ *$\|\%$/
> kB
> 'A,'B/^[^\.]/s/^\([^\.]\)/>\1/
> 'A,'B!fmt -p '>'
> .,/^ *$\|\%$//^>/s/^>//
> 'A
> endif
>
>
> The idea was to use the marks like '> set by visual mode, after hitting <ESC>,
> for arbitrary blocks. These marks to persis, but a script does not seem to
> be aware of them. Also, given both a range and pattern for substitute commands

A script sees the '< and '> marks just fine.

> is to avoid ``pattern not found'' messages when lines do not have what is
> being searched for.

You can use the :sil command for that, or specifically for the :s
command, use the e flag. See :h :sil and :h :s_flags

> Possible solutions: Somehow fool vim's paragraphs variable into accepting
> every line that begins with a dot. Figure a script test for a mark like mA,
> set on an initial line. Then I got to the end of a block and run the script.
> trouble is, A (or whatever) may be already defined in a buffer, so how to test
> that it was just set now? Or someway for a script to recognize the marks set
> by the highlight mode.

I am unsure, what you want to do. So here are only some basic tips.
Check with getpos("'A") the position of mark A see :h getpos() but using
the '< and '> marks is really the correct solution and works from within
scripts (but I think only after visual mode has been exited) as well. I
do this with the NrrwRgn plugin.

regards,
Christian

--
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

No comments: