为什么80列控制台上有11个tabstops?


2

您可以假设,由于每个选项卡默认向前移动8列,因此80列控制台将有10个制表位。这可以被驳斥:

$ printf "1\t2\t3\t4\t5\t6\t7\t8\t9\t0\ta"

人们可以期望输出为2行,因为有10个制表位,占据了所有80列的空间,加上一个单一的特征,即被推到下一行。但该命令在xterm,gnome-terminal和rxvt中生成单个输出行。

发生了什么事情,最后一个标签停止神奇地减少一个字符空间。

同时,expand(1)保持标签的空间为8

$ printf "1\t2\t3\t4\t5\t6\t7\t8\t9\t0\ta" | expand

会在80列控制台上神奇地产生2条线。

它似乎是某种标准。但我只是通过谷歌搜索找不到来源。

仅在Linux中测试过,但我担心所有unix都会共享它。


这些都不是游戏机。它们都是GUI终端仿真器。
JdeBP 2014年

Answers:


14

80列控制台上只有9个tabstops。

让我们首先扩展评论。您实际上没有测试过任何游戏机。这些都是GUI 终端模拟器程序。幸运的是,实际的控制台(至少在Linux和FreeBSD上)也表现出这种行为。

但这不是你声称的行为。它没有展示11个tabstops。它演示了9。

要正确理解tabstops,你需要扔掉“它们总是扩展到N个空格”。理念。如果您可以使用带有tabstops的机械打字机,那么请查看它是如何工作的(通过滑架上的突出销钉设置标签)。Unix和Linux世界中终端的Tabstops以这种方式工作

(可以配置线路规则来设置选项卡,在输出流中的选项卡字符在到达终端之前用空格字符替换。我们正在讨论由终端本身而不是线路规则执行的选项卡,尽管这里虽然使用硬标签,TAB会向终端发送一个骨骼字符。如果软标签打开,相反,您描述的行为不会首先出现。请尝试设置stty tab3并查看。)

初始化时,终端根本没有设置tabstops。早期getty,或者reset命令或类似的东西(它随系统而变化)输出一系列空格字符和转义序列,用于设置特定列的tabstops。有时列甚至转义序列都是硬连线的。但是,大多数情况下,该命令会查找termcap / terminfo数据库中的信息。提供清除所有标签的转义序列的terminfo功能是tbc; 该hts功能提供了在当前列设置选项卡的转义序列; 并且该 it功能指定默认情况下tabstops之间的列数。查找termcap,等效能力itctst

该命令获取终端大小(来自内核,通过系统调用,或来自terminfo / termcap记录的另一部分),查看列数,并重复输出it空格,然后输出st尽可能多列的序列,最后输出回车以返回#0列。这正是在许多机械打字机上设置一组tabstops的方式:重复空间到下一个tabstop,点击“set tabstop”杠杆推出一个引脚,重复直到右边距,将滑架推回到左边。

对于80列宽的终端,it通常给出8,命令执行9次,在第8,16,24,32,40,48,56,64和72列设置tabstops。

在第0列没有tabstop(除了程序错误)。这是你的第一个计数错误。第80列也没有禁忌,这是你的第二次计数错误。“为什么”,你可能会问,“是吗?” 首先,这是因为它不可能 80列设置一个制表位。光标从80列终端的第0列到第79列。

其次,必须考虑TAB角色的行为。它并没有,流行的看法相反,扩展到足够的空间移动到8列的下一个倍数。记住,Unix和Linux终端就像机械打字机一样工作。在机械打字机的世界中,标签键移动托架直到它被一个标签销或右边缘停止。(有些聪明的木头可能会在这一点上提到保证金的释放。出于显而易见的原因,这是机械打字机所拥有的Unix和Linux终端所没有的。)

TABUnix和Linux终端上的字符实际上以相同的方式工作。响应它,终端发出空格,直到到达下一个设置的tabstop 或最右边的列。这就是这里发生的事情。当光标位于第79列时,您可以根据需要编写任意数量的TAB字符,但不会发生任何事情。最右边的栏目之外没有标签。

termcap / terminfo系统允许可设置的硬标签是可选的。但是你测试过的程序都提供了一个“xterm”型终端模拟器。(它理解的转义序列是xtermtermcap / terminfo数据库中的条目/条目中给出的转义序列。)现在,FreeBSD虚拟控制台中的终端仿真器也是如此。Linux虚拟控制台中的终端仿真器实际上是指定的略有不同的终端类型linux。(这曾经是FreeBSD虚拟控制台的情况,它有一个cons25类型。FreeBSD在9.0版本中将其内核终端仿真器更改为xterm兼容,作为在虚拟控制台上获得UTF-8支持的项目的一部分。)所有这些xterm-alikes和Linux内核终端仿真器都具有完全可设置的硬件标签机制。

(对于那些喜欢阅读源代码的人:查看源代码中的函数TabNext()TabToNextStop()函数。)tabs.cxterm

你可以自己试试。运行以下命令:

tbc=$(tput tbc) hts=$(tput hts)
printf '%s\r%s\r\n' "${tbc}" "a${hts}aaa${hts}aaaaaaa${hts}aaaaaaaaaaaaa${hts}aaaaaaaaaaaaaaaaaa${hts}"

然后再次运行您的命令。整整5制表位已设置。计算${hts}命令,或查看a字符行。超过第五个TAB角色,这个角色导致隐喻式打字机车厢将所有其余部分一直旋转到右侧边缘。

下一个(打印,非TAB)字符会导致自动回车到左边距,并换行到下一行。在termcap / terminfo术语中,xterm终端类型具有自动边距。理论上,Unix和Linux可以使用没有自动边距的终端。printf在你写了回车票之前,你的命令会停留在第79栏,无论你输出多少。在实践中,这样的设备会使当今大多数人的思想陷入困境。


谢谢!在我看来,可设置的TAB提供了在控制台上构建电子表格软件的能力。但是没有一个被发现成熟 - 几年前我使用了一个这样的开源工具质量很差,名字被遗忘了。
Tankman六四2014年

顺便说一句,我实际上有一个控制台,一个带有嵌入式中文字体和Z-80 CPU的真正的控制台,自1997年以来我一直在使用它,虽然我没有把它弄脏以测试这个制表位。
Tankman六四年

答案应该在Hacker's Dictionary附录中。我在某种程度上在研究弹性tabstopsvim中的标签秘密时到了这里- 值得100%。我记得在奥林匹亚打字机上必须输入实际物理能量进入正确的右上方TAB键的感觉。
David Tonhofer
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.