Ticket #2988 (new enhancement)

Opened 12 months ago

Last modified 4 months ago

Mutt should recognize tab (width)

Reported by: pdmef Owned by: mutt-dev
Priority: major Milestone:
Component: mutt Version:
Keywords: Cc:

Description

In mutt_strwidth() there's a check for printable chars which excludes tab chars resulting in a width of 1. However, this is likely not the display width resulting in wrong wrapping and possibly other undesired effects.

Attachments

usetabs.diff (1.2 kB) - added by pdmef 12 months ago.
Recognize tabs for string width of tabs as 8 during calculation

Change History

Changed 12 months ago by Thomas Dickey

On Mon, 19 Nov 2007, Mutt wrote:

> #2988: Mutt should recognize tab (width)
>
> In mutt_strwidth() there's a check for printable chars which excludes tab
> chars resulting in a width of 1. However, this is likely not the display
> width resulting in wrong wrapping and possibly other undesired effects.

It's also important to check for tab, because more than one release of 
Solaris has some breakage in ctype for this character, categorizing it as 
a printable character...

Changed 12 months ago by Rocco Rutte

Hi,

* Thomas Dickey wrote:
>> In mutt_strwidth() there's a check for printable chars which excludes tab
>> chars resulting in a width of 1. However, this is likely not the display
>> width resulting in wrong wrapping and possibly other undesired effects.

> It's also important to check for tab, because more than one release of  
> Solaris has some breakage in ctype for this character, categorizing it as  
> a printable character...

Is there some easy way to do that? I've seen that termcap has various 
tab-related entries which could be used to guess more accurately what a 
string looks like on terminal. Or is there such a method already?

If not, simply assuming a tab is 8 chars wide won't hurt much I think 
(strings should be at worst shorter than they could be).

Rocco

Changed 12 months ago by Thomas Dickey

On Tue, 27 Nov 2007, Rocco Rutte wrote:

> Hi,
>
> * Thomas Dickey wrote:
>>> In mutt_strwidth() there's a check for printable chars which excludes tab
>>> chars resulting in a width of 1. However, this is likely not the display
>>> width resulting in wrong wrapping and possibly other undesired effects.
>
>> It's also important to check for tab, because more than one release of 
>> Solaris has some breakage in ctype for this character, categorizing it as 
>> a printable character...
>
> Is there some easy way to do that? I've seen that termcap has various 
> tab-related entries which could be used to guess more accurately what a 
> string looks like on terminal. Or is there such a method already?

Not reliably. terminfo/termcap have the "it" (init_tabs) value, but
it's not widely used outside of (n)curses.

> If not, simply assuming a tab is 8 chars wide won't hurt much I think 
> (strings should be at worst shorter than they could be).

That's the default.

Changed 12 months ago by pdmef

Recognize tabs for string width of tabs as 8 during calculation

Changed 12 months ago by pdmef

I've attached some experimental patch to trac. Here it seems to work and unbreaks some format=flowed mails I have where people indent paragraphs with tabs. I hope it doesn't break something elsewhere...

Changed 6 months ago by Derek Martin

Trouble is that the tab is a hardware feature (or pseudo hardware
feature) designed to allow for the alignment of text on a terminal
device; a full tab has a width of 8, but tab stops are at column
positions, not absolute character widths.  If the user starts typing
at column 0 and types 3 characters and then hits tab, that tab
character has a practical width of 5, not 8.

Also, the user can set the hardware tab stops to whatever value he
wants, and in the case where they do, assuming a width of 8 is not
really much better than using 1.  For example, if the user uses a ts
with of 3, and has 4 such tabs in the e-mail, mutt will think the line
is as much as 20 columns wider than it actually is...

It's also possible to specify tab stops at arbitrary terminal columns.
One might do this for the convenience of, say, editing source files,
or even editing mail (e.g. set a tab at column 2 or 4 to indent the
first line of a paragraph, instead of indenting to column 8, which
looks retarded).  I'm not suggesting that changing the tabs from the
defaults is a common practice; but it seems logical to me that Mutt
should behave sanely when it is done...

Perhaps the smartest thing to do, in the absence of a way to determine
what the terminal settings for tab stops actually are, is to ignore
the hardware tabs completely:  Mutt could instead, *only for the
purpose of display*, expand tabs to an equivalent number of spaces to
simulate tab stops, which then makes this a non-problem (space has a
width of 1).  I believe that GUI MUAs, lacking the concept of hardware
tabs, essentially behave this way (i.e. they choose their own tab
stops which are AFAIK generally not user-configurable), so I don't
think it's unreasonable for Mutt to do so also.  But for that matter,
Mutt's pseudo-tabs could be user configurable, if that were
desirable.

Changed 5 months ago by agriffis

IMHO pdmef's patch is the best approach for now. Trying to pervasively track absolute starting column for the sake of calculating tabstops would require a very invasive patch. It should be sufficient to pretend that a tab will consume 8 spaces. That means some lines might wrap *early* but at least they won't wrap *late*.

Regarding Derek's suggestion to s/tab/space/g for display, sure that would "fix" the wrapping but it would break lots of text display, for example inline code with tab indentation. pdmef's approach will allow tabs to be rendered correctly by the terminal.

Changed 4 months ago by pdmef

  • milestone 1.6 deleted

Moving out of 1.6's way as this is kind of an edge-case.

Note: See TracTickets for help on using tickets.