The topic has come up occasionally with various terminal emulators. The discussion in Debian #259828
xterm: whitespace after tabs represented as space characters in selections (for xterm) had this comment by urxvt's developer:
I thought about implementing this in rxvt-unicode: tabs could be represented
trivially in rxvt-unicode's data structure. However, there are semantic
Tabs are not characters, but cursor movements. As such, there is no good way
to represent them as tab characters, just as "cursor up" or "goto 5,6" will
not be represented in the selection text.
and went on to say (in effect) that urxvt supported the feature:
If anybody cares, here is how rxvt-unicode-3.8 implements HT characters
now, plus some initial experience on the effects.
When rxvt-unicode-3.8 received a HT, it first calculates the tab movement
(which is a relative cursor movement). Iff all characters skipped over
are spaces with the same attributes as the first space, it will replace
these spaces by a (very) wide tab character (which is easy to do in the
way rxvt-unicode handles wide characters, so the code changes were limited
to less than 15 lines within the scr_tab method). If any of the characters
are not spaces, or if there are attribute changes (e.g. colour), it will
only move the cursor.
Of course urxvt 3.8 is a while back. But consider the application problems which get in the way:
- just the terminal itself has to support the feature (store tabs-as-tabs and allow selecting those),
- the terminal has to do the right thing when a tab hits the right margin (that bug report notes cases which did not),
- the terminal has to be configured to use hard tabs (see
stty setting for this),
- applications (and libraries such as ncurses) have to be configured to use hard tabs, and
- applications such as screen/tmux have to (again) manage tabs-as-tabs so that when painting and re-painting the screen those are sent to the terminal as tabs.
Just because your application sends a tab to the screen doesn't mean that it gets to the terminal. It can be translated to spaces in more than one level, and optimized entirely away if an intermediate level decides that the screen would not change anyway.
A quick check with urxvt 9.15 shows me that the feature still works (in the simplest configuration, of course):
hello . world
00000000 68 65 6c 6c 6f 09 2e 09 77 6f 72 6c 64 0a |hello...world.|
$ cat /tmp/foo
printf 'hello\t.\tworld\n' |xclip
If it doesn't work for you, then your terminal may be set to soft tabs, or one of the other above-mentioned problems is in your way.