How to re-indent text according to type

23 views
Skip to first unread message

L A Walsh

unread,
Oct 10, 2020, 6:55:19 PM10/10/20
to Vim Users
Sometimes, I get some unformatted text, like HTML or XML that has all
the newlines removed.

To make it easier to read, I'll sometimes add newlines and pair
up adjacent tags, using something like:

:%s/>/>^M/g
:%s/<\([^>]\+\)>\n\([^>]\+\)<\/\1>/<\1>\2<\\\1>

But then I have an unindented file like:

<taga>
<line>
<tagb>xxx</tagb>
<tagc>yyy</tagc>
</line>
</taga>

Where if I had typed it in by hand, with auto indent and syntax set, I'd
get:

<taga>
<line>
<tagb>xxx</tagb>
<tagc>yyy</tagc>
</line>
</taga>

----
To get the above, for very short examples, I can just
join 1+2nd line, then hit enter with cursor before "<line>", join nxt lines
and hit enter and so on.

A __kludgy__ way for longer methods is to put the original in a file,
then in a non-paste aware TTY running vim, I can put all of the code
in my cut buffer, and paste it into the TTY window. It then acts like
it would if I'd typed it in, as it is unaware of the paste-mode (play
with paste/nopaste mode).

How can I just reformat the file as if I'd just typed it all in by hand
without making use of a TTY window running vim and pasting all the text?

Is there a format-type command as there is for text, where I can set
'tw' (:set tw=72), select a paragraph or whole page, and use:

:gqap to reflow the text.

Thanks MUCH, if there is an easy command to do this!












Gary Johnson

unread,
Oct 11, 2020, 2:11:04 AM10/11/20
to Vim Users
I don't know of a way to do that with one command, but I usually do
the newline insertion much as you do, then execute the following
normal-mode command.

gg=G

See

:help =

You might also search the web for HTML Tidy. I think it will
reformat an HTML file.

Regards,
Gary

L A Walsh

unread,
Oct 13, 2020, 2:05:56 AM10/13/20
to Vim Users
On 2020/10/10 23:10, Gary Johnson wrote:
> On 2020-10-10, L A Walsh wrote:
>
>> :%s/>/>^M/g
>> :%s/<\([^>]\+\)>\n\([^>]\+\)<\/\1>/<\1>\2<\\\1>
>>
>
> I don't know of a way to do that with one command, ....
> then execute the following
> normal-mode command.
>
> gg=G
>
---
close enough, as I gave 'ggap' as an example for text.

> You might also search the web for HTML Tidy. I think it will
> reformat an HTML file.
>
---
yeah, but it was xml and main requirement was to run
pretty much in (g)vim. You got like 100% for my original
question! But ran into a quirky special case that fails with
normal vim indenting as well (works if I split all
lines 1st), but if some of the close tags are on same line
as open, doesn't seem to unindent...

Example, starting with:
<xml>
<totalbytes>2952962267<\totalbytes>
<image index="1">
<dircount>13363<\dircount>
<filecount>64267<\filecount>
<totalbytes>11707704502<\totalbytes>
<creationtime>
<highpart>0x01cb8936<\highpart>
<lowpart>0x131f339a<\lowpart>
</creationtime>
<lastmodificationtime>
<highpart>0x01cb8950<\highpart>
<lowpart>0xbc4d774b<\lowpart>
</lastmodificationtime>
<doors>
<arch>9<\arch>
<hal>acpiapic<\hal>
<languages>
<language>en-us<\language>
<default>en-us<\default>
</languages>
<systemroot>doors<\systemroot>
</doors>
<hardlinkbytes>4497873056<\hardlinkbytes>
</image>
</xml>

Running '=' over that, (filetype=xml, syn=xml) using expand tab, I get:

<xml>
<totalbytes>2952962267<\totalbytes>
<image index="1">
<dircount>13363<\dircount>
<filecount>64267<\filecount>
<totalbytes>11707704502<\totalbytes>
<creationtime>
<highpart>0x01cb8936<\highpart>
<lowpart>0x131f339a<\lowpart>
</creationtime>
<lastmodificationtime>
<highpart>0x01cb8950<\highpart>
<lowpart>0xbc4d774b<\lowpart>
</lastmodificationtime>
<doors>
<arch>9<\arch>
<hal>acpiapic<\hal>
<languages>
<language>en-us<\language>
<default>en-us<\default>
</languages>
<systemroot>doors<\systemroot>
</doors>
<hardlinkbytes>4497873056<\hardlinkbytes>
</image>
</xml>

----
Seems if I have some closing tags on same line it doesn't
unindent (happens in normal insert as well). Seems unrelated
to the method you gave. I have seen the indent problem in other
languages as well, but am stymied coming up with
an example off the top of my head.

To emphasize, if all the tags (open+close) are on their
own line, it works just fine. But when some matching tags
are on same line, I get mixed/weird results.

Anyone seen such fun? And thanks again gary, for the '=',
don't recall ever seeing that.

*cheers*
-linda




Gary Johnson

unread,
Oct 13, 2020, 2:34:48 AM10/13/20
to Vim Users
You're welcome.

I am no expert in XML, but I thought that closing tags began with
a slash, not a backslash; that is, with "</", not "<\". Apparently
Vim's XML indent plugin thinks so, too.

I copied your example to another buffer, set its filetype to "xml",
replaced all backslashes with slashes, and executed "gg=G". The
result was indented as I think you and I expected it to be, like
this:

<xml>
<totalbytes>2952962267</totalbytes>
<image index="1">
<dircount>13363</dircount>
<filecount>64267</filecount>
<totalbytes>11707704502</totalbytes>
<creationtime>
<highpart>0x01cb8936</highpart>
<lowpart>0x131f339a</lowpart>
</creationtime>
<lastmodificationtime>
<highpart>0x01cb8950</highpart>
<lowpart>0xbc4d774b</lowpart>
</lastmodificationtime>
<doors>
<arch>9</arch>
<hal>acpiapic</hal>
<languages>
<language>en-us</language>
<default>en-us</default>
</languages>
<systemroot>doors</systemroot>
</doors>
<hardlinkbytes>4497873056</hardlinkbytes>
</image>
</xml>

Regards,
Gary

Christian Brabandt

unread,
Oct 13, 2020, 2:49:30 AM10/13/20
to Vim Users
Hi, xml runtime maintainer here.

This should work as mentioned. Alternatively, you might be able to use
the gq function together with :set formatexpr=xmlformat#Format()

If there are some problems, please report
https://github.com/chrisbra/vim-xml-runtime

Best,
Christian
--
Wenn etwas nützlich wird, hört es auf schön zu sein.
-- Théophile Gautier

L A Walsh

unread,
Oct 13, 2020, 8:59:27 AM10/13/20
to Vim Users
On 2020/10/12 23:34, Gary Johnson wrote:
>
>> Anyone seen such fun? And thanks again gary, for the '=',
>> don't recall ever seeing that.
>>
>
> You're welcome.
>
> I am no expert in XML, but I thought that closing tags began with
> a slash, not a backslash; that is, with "</", not "<\". Apparently
> Vim's XML indent plugin thinks so, too.
>
----
Some days, .... just shouldn't get out of bed.
Sigh. Sorry for the unnecessary bother. And
thanks again for the various clue sticks...

Reply all
Reply to author
Forward
0 new messages