less icon indicating copy to clipboard operation
less copied to clipboard

Have an option to show tabs as tabs

Open guillaumebrunerie opened this issue 3 years ago • 2 comments

It would be nice to have an option to get less to show tabs as tabs (not convert them to spaces), so that for instance selecting text in the terminal window and pasting it into another program will include actual tab characters.

I found the following Stack Exchange question (and answer) https://unix.stackexchange.com/questions/412060/how-to-get-less-to-show-tabs-as-tabs, which suggest that it is currently impossible, but that it would be easy to change.

guillaumebrunerie avatar Apr 17 '21 18:04 guillaumebrunerie

I don't see how it would be possible to do this and still break lines correctly. Without knowing how many spaces the terminal uses for a tab, less wouldn't know how long the line is, so wouldn't know where the line breaks are or how many lines fit on a screen.

gwsw avatar Apr 17 '21 20:04 gwsw

Well I guess less could set hardware tabs to match the desired tabs set via -x, but this seems fairly nontrivial.

gwsw avatar Apr 17 '21 21:04 gwsw

I think it should use tabs. And wrap assuming 8 tabstop as that is what less default changes tabs too?

busterbeam avatar Oct 22 '22 15:10 busterbeam

Repeating my comment from #292 for reference:

It would be possible, but rather challenging to do this. For example, if the text had long lines which wrapped, then depending on the relationship between the tabstop settings and the width of the terminal, less would need to set different terminal tabs before printing every single line. Also if the text were scrolled horizontally with the arrow keys, tabs would need to be set to a "shifted" version of the -x settings. And I don't believe there's any way to read tab settings from a terminal, so when less exits there would be no way to restore tab settings to what they were before less was run. I notice that vim also uses spaces rather than hard tabs, presumably for similar reasons.

gwsw avatar Oct 22 '22 16:10 gwsw

@gwsw if you read my comment

wrap assuming 8 tabstop

as less (if not otherwise specified) assumes 8 spaces for tabs already, so use an actual tab character and assume it is 8 spaces. Then end user can setup the rest.

in fact some research... I think you should read into tabs command in linux/bash not unlike the clear command. and then use reset to return to initial conditions... have you ever read into any of this? I will admit I have not explored this repository much so I don't know exactly how it is all implemented but I imagine real tabs can be implemented

busterbeam avatar Oct 24 '22 14:10 busterbeam

I don't think you understood my previous comments. Yes, I understand that terminal tabs can be set using the "st" termcap capability ("set_tab" in terminfo) as the tabs command does, but that's only a small part of the issue.

Consider a simple case where user tabs (with -x) are set at 8 spaces, the terminal tabs are also set at 8 spaces, and the terminal is 81 characters wide. Now if a line is 100 characters long and has a tab in (zero-based) position 4 and 84, using hard tabs at 8 spaces won't work. The first tab wants to move from position 4 to position 8, which a hard tab can do. But the second tab wants to move from line position 84 (screen position 3) to line position 88 (screen position 7), which a hard tab set at 8 spaces can't do. So tabs would need to be changed before printing the second part of the line.

Now suppose an even simpler case, a short line with a tab in position 5. A hard tab can be used to move from position 5 to position 8. But now if the user scrolls the screen right one space, we now need a tab to move from screen position 4 to screen position 7. Again, tabs would need to be changed before displaying the line, and changed again after each horizontal scroll command.

If the user tabs (with -x) are set to something other than 8 spaces, it's even more complicated but we don't need to get into that to see that we can't use a hard tab to replace every input tab.

I don't really understand your "assume 8 spaces" comment. If tabs are just assumed to be 8 spaces and never changed by less, then the output won't match the input. A single input tab would sometimes be displayed as a tab plus some spaces, or just spaces, which is contrary to what I believe you are trying to achieve.

gwsw avatar Oct 24 '22 15:10 gwsw