Instead of using an external fmt
program to format your text by filtering it through the external command, consider using Vim built-in commands gq
or gw
.
Both commands take a motion or text object to determine which lines of text to act on (by the way, the same is true for the !
command, which also takes a motion, so you can use !}fmt
to format from the current line until the next blank line.)
So you can use gq}
to format from the current line to the next blank line, gqip
to format the current paragraph (block delimited by blank lines), gqG
to format from the current line to the end of the file, gggqG
to format the whole buffer (first gg
jumps to the first line.) Additionally, you can select lines in Visual mode and use just gq
to format the lines in the Visual selection. Finally, there's gqq
(or gqgq
) and gww
(or gwgw
) to format the current line only.
These commands will respect the Vim settings you're using, such as 'textwidth'
to determine how long lines can be, and 'expandtab'
to determine whether to use tabs or spaces. Since they're built-ins, they can have easy access to the settings you're already using, which is not the case when you're filtering the text through an external command, which will most surely not know about the settings you had inside Vim.
The difference between gq
and gw
is that gq
may be customized using Vimscript. You can write your own formatter function and set 'formatexpr'
to call that function. This is quite useful when using it to format code, where the 'formatexpr'
can be made aware of the language it's formatting and can then wrap it correctly while maintaining the correct syntax.
The gq
command can also use a 'formatprg'
pointing at an external binary to use as a filter. So you could even have it configured to actually use fmt
under the hood if you wanted to!
The gw
command on the other hand doesn't use any of the customizations, so it will always give you access to Vim's native formatter, even if you have a 'formatexpr'
or 'formatprg'
set. As a bonus, gw
will preserve the cursor position across formatting the block (which is not often done by the custom formatters, since it's usually hard to do so in a function, and would be virtually impossible when using an external filter, where there's really no protocol to communicate that information of cursor position back to Vim.)
Hopefully you'll find these commands useful and see how they're much superior to filtering through an external fmt
. Not to mention they should easily prevent the issue you're having with fmt
adding tabs to your text.
fmt
is that it will use tabs if you have any tabs in your input... Otherwise, it will use spaces.fmt
- not Linux's GNUfmt
. It's funny, because the man page for BSD fmt actually saysFor instance, within visual mode of the ex(1) editor (e.g., vi(1)) the command !}fmt will reformat a paragraph, evening the lines.
. So this is something it's actually meant to do, but doesn't appear to do properly. As a side-note, not sure why it says!}fmt
. Why the}
?gq
(and alsogw
, but maybe that's a recent addition in Vim) that can do formatting for you. It's a built-in, so it respects your Vim settings. I'll post an answer about it... But kinda busy right now, will do so later.}
is a motion, to filter through the externalfmt
command until the next blank line ..:%retab
(possibly with a bang) to change out the tabs for spaces