看这里:制表符与空格之间的典型圣战。

现在看这里:弹性制表符。解决了所有问题,并添加了一堆非常有用的新行为。



在制表符和空格讨论中是否甚至提到了弹性制表符?为什么不?弹性制表符的想法是否存在严重的缺陷,以至于没有人在流行的编辑器中实现过?

编辑:我为过于强调“为什么没有提到它们”而表示歉意。那不是我真正想要的。这个问题甚至可能不在主题之列。我真正的意思是,这样做最大的弊端是什么阻止了广泛采用明显有益的想法? (在一个已经一切都支持的理想世界中)

(结果是,Microsoft Connect上已经有一个关于弹性制表符的Visual Studio实现的请求,在Eclipse中也有一个请求。另外,还有一个问题询问其他使用弹性制表符的编辑器)

评论

对于ux.stackexchange.com,这将是一个很大的问题

在“制表符与空格”讨论中从未提及它们,因为工作的程序员几乎无法使用这些东西。也许如果您具有Eclipse,VS,gvim和emacs实现,则可能会发生变化。

我真的很喜欢这个主意,但是只有当您忍受了一个月左右的时间,您才真正知道这个陷阱是什么。像以往一样,在某些情况下肯定会发生您不希望看到的事情...

@ ChrisBurt-Brown总是有风险,是的。 IntelliSense也有其陷阱,例如在您不希望替换文本时将其替换。总体而言,C#中的IntelliSense是一个巨大的胜利。

我想要在记事本++中...我现在想要这个

#1 楼

圣战是主观的

尼克的弹性挡片是一个了不起的概念,可以帮助许多人达成可行的解决方案,尽管我高度怀疑这将彻底结束这场圣战:毕竟,这也是一个问题,即使付出了妥协的代价,许多程序员也不会在这个问题上离他们的位置一寸之遥。因此,这是第一个原因。
例如,“空间”方面的许多人仍然会不喜欢它,因为它需要在软件中添加其他逻辑以进行良好的渲染(例如只需在SCM的Web视图中查看变更集。)

实施问题

,但是最明显的原因仅仅是其进入技术壁垒:与之前的概念截然不同在IDE和文本编辑器中实现了很多年(如果不是几十年的话)。这将需要以完全不同的方式重写其中的一些以处理行,这使得较老的大型系统很难在其行处理代码中遭受深度和紧密耦合。但是,从头开始时,这样做会容易得多(想想尼克的演示或Go的制表程序包)。

关于个人轶事,我记得有一段时间联系作者如果看到emacs支持,在这种情况下,他提到这是它不重要的原因。他还向社区寻求帮助,以帮助实现此功能并将其推广到大众。

我们足够照顾吗?

第三个原因是,一些开发人员没有对此事挂上电话,也不在乎他们会去做那么多额外的努力来支持这项工作。在大多数情况下,spaces-vs-tabs冲突不是业务阻止程序,因此问题背后没有太多驱动力。

如果您想要它,则必须为它而战。这在开源软件中可行。而且,如果您对这些内容进行了足够的更改,那么封闭源代码的用户将不得不冒着失去部分用户群的风险,即使其中的一小部分也是如此。

因此,如果您愿意,请尼克帮忙。

评论


(主题外)我经常想知道其他“这很好,但非常次要”这类功能如何使其融入Visual Studio之类的产品中。似乎团队中的某人只是出于个人原因只是找到了实施它的时间。例如,考虑在Visual Studio中一次键入几行。不是像成千上万的人想要它,而是我更喜欢它。

–罗马·斯塔科夫
2012年2月28日在16:47



@romkyns:就很多事情而言,需要一个安静的内部人或一千个声音在大门口尖叫。

– Haylem
2012年2月28日在17:05



#2 楼

很多时候,我不得不与文字处理程序作斗争,以使文档看起来像我想要的样子,而没有一些隐藏的自动规则来控制文字的位置。我不想花一秒钟的时间来弄清楚为什么编辑家坚持要把那些词放在那儿。

评论


我也不会。我完全同情这种情绪,因为这样的规则也确实使我感到沮丧。但这在两个方面有所不同。一:就像现在的制表符一样,如果不想,也不必使用它们。如果使用同事的文本,则可以不理会他们。二:弹性制表符没有隐藏的规则,但是很明显。行为是完全自然的-甚至比传统的制表符更自然,传统的制表符出现在文本中任意任意的,通常不相关的位置。这就是为什么除了缩进以外,没有人再使用制表符了。

– Timwi
2012年2月28日14:58

@Timwi:问题是列出缺点。是的

– mhoran_psprep
2012年2月28日在15:04

从GIF来看可能不是很明显,但是唯一可以弄清楚的是,当您按“ TAB”时,后面出现的所有内容都会正确地垂直对齐。就像文字处理程序一样。只需在我发布的链接上尝试实际的交互式演示,您就会发现它很自然。

–罗马·斯塔科夫
2012年2月28日15:11



@mhoran_psprep:公平地说,感谢您的投入。我想我们正在研究该问题的不同解释。您正在列出使用该功能的缺点,而我认为这是有关引入该功能的缺点(即使其可用而不是强制性的)。

– Timwi
2012-2-28 15:33

#3 楼

这是我第一次听到这些。不确定它们是否是一个好主意,但是它们似乎没什么用,因为我们已经拥有一些工具(例如indent)已经可以自动格式化代码了。

当我在vim中打开您聪明的弹性制表位并进行编辑时会发生什么?标签页会自动清理吗,还是一团糟?

主要的缺点,如我所见,可能是破坏了diff,版本控制,并且与不支持它们的编辑器不兼容。为了支持它们,可能需要进行大量的代码修改,并且还有比“还有另一个选项卡格式化代码”功能更重要的事情。毕竟,如果有内存,我们都可以使用indent来完成上述所有操作。

评论


多么落后的态度。让我们前进吧,因为人们最喜欢的旧的过时工具还无法解决! (当然,具有讽刺意味的是,这些工具(例如vim)是开源的,因此,如果它对您确实很重要,则可以(可能应该)为其添加弹性的制表位支持)

– Timwi
2012年2月28日在12:12

@Timwi:你完全错过了我的观点。当您的代码文件被不知道弹性制表符的东西解析时会发生什么?您会陷入困境还是可以应付?那版本控制和差异呢?只希望所有工具都支持$ feature是不现实的,即使这些工具是开源的也是如此。

–Sardathrion-反对SE滥用
2012年2月28日在12:31

@Timwi:您假设每个人都发现弹性制挡块与您认为的一样真棒。这可能不正确。

–Sardathrion-反对SE滥用
2012年2月28日在13:03

@Sardathrion是正确的。当我必须在没有窗口系统的情况下远程进入我的* nix服务器并且需要使用Vim / Emacs / Pico / Whatever检查某些代码时,会发生什么情况?如果有一种机制可以使人可读,那将是一件好事...否则将是一场噩梦。无论如何,我看不到弹性制表符停止的好处。我已经可以对我的代码进行自动格式化,以查看其在我使用的IDE中的表现。

–钻机
2012年2月28日在13:16

版本控制点是一个很好的选择-我认为人们不会喜欢一个编辑器,它会悄悄地开始更改代码中注释的位置/格式,使其远离正在修改的代码(请参见OP动画中的洋红色部分) gif)。可以使用一个参考实现会有所帮助,但是到目前为止,我所看到的并不明显-emacs已经完成了很多工作,仅需几次额外的击键(可以说是一件好事)。

–mcmcc
2012-2-28 15:10

#4 楼

一个缺点是,如果要在一组线上对齐然后在下一行上缩进,则无法使用,因为它会将相邻行的制表位分组。

def foo( bar,
         xyzzy ):
         wibble() # Too much indentation


我想要的是:

def foo( bar,
         xyzzy ):
    wibble()


对于花括号语言来说,这可能没什么问题,因为通常可以通过将开括号放在一行上来解决此问题。本身(就像在动画中一样),但是对于对空格敏感的语言,这很快变得很痛苦,您最终不得不退而求其次地使用空格。

评论


同意Nick的实现根本不适用于Python之类的语言。

–罗马·斯塔科夫
2012年2月28日在20:08



为什么不行呢?这不是基本限制,算法只需要了解语言即可。但是从某种程度上讲,即使在今天,这仍然是正确的,例如,Vim根据语言定义了不同的缩进规则。这可以轻松容纳Python缩进。

–康拉德·鲁道夫(Konrad Rudolph)
2012年2月28日在20:17

@KonradRudolph不,他们不能。弹性制表符的绘制是一种能够自动缩进/缩进文本组的功能。一个简单的例子是“ if”语句的结尾:您尝试退出并取消缩进,因为您要退出该语句,但是“智能”弹性制表符决定您也要取消缩进上面的一两行,依此类推依此类推...如果您必须将文本明确分组在一起,那么-有什么意义?比自己修复缩进更多的工作...

–伊兹卡塔
2012年2月29日,下午3:25

@Izkata手动取消缩进将(应该)简单地结束当前组。为什么您要通过弹性挡片手动控制缩进?您不会这样做,因此算法知道在执行此操作时,它是结束一个块,而不是取消缩进上面的块。

–康拉德·鲁道夫(Konrad Rudolph)
2012年2月29日在8:07



哦,好点。嗯...也许您可以使参数重复缩进?那么wibble()只会有一个缩进,因此不会与函数参数对齐吗?

– Ajedi32
2014年2月7日在17:39

#5 楼

老实说,一旦您克服了最初的兴奋,我就发现它们没有用。例如,无论如何我都不喜欢在行尾添加评论-我总是将评论放在单独的行上。这样,弹性制表符就失去了主要用途。

之后,您当然仍然可以使用它们来对齐函数参数(和参数)和一长串的赋值。

但是对于前者,我倾向于将所有参数缩进一个附加级别,并且对我来说完全可以正常工作:

void foo(
    int x,
    int y,
    string z
)


我认为不需要更改

关于对齐作业,我不这样做。我在作业周围放了一个空格,就是这样。我也倾向于不将很多分配集中在一起,因此几乎没有任何可读性问题。

总而言之,弹性制表符对我的使用绝对为零。当然,这是一个非常个人的偏爱,可能会有所不同,但我发现它运作良好,并且我猜想缺少对弹性制表符的支持是因为其他人也有类似的想法。

如果编辑者可以实现它们,我仍然不会使用它们。

评论


感激。似乎只要您愿意也可以使用可变宽度的字体,因为无论如何,除了行首之外,您不会对齐其他任何内容。实际上,Visual Studio为此提供了很好的支持,并且可读性得到了很好的提高。

–罗马·斯塔科夫
2012年2月28日在16:15

@romkyns我们对此进行了讨论,在一个过程中,我尝试使用比例字体进行编程一段时间。结果是,即使不考虑缩进,等宽字体也可以更好地工作。除此之外,我目前只在Vim和控制台上工作,而这两种工具都绝不可能支持比例字体。

–康拉德·鲁道夫(Konrad Rudolph)
2012-2-28在16:22

@romkyns也就是说,这些问题是可以解决的(或者甚至可以解决,使用为编程设计的比例字体)。但是我仍然没有真正看到它的必要性。

–康拉德·鲁道夫(Konrad Rudolph)
2012年2月28日在16:25

#6 楼

为什么我们不仅仅使用垂直制表符(VT,ASCII 11)来指示使用弹性制表符?它在任何主流编程语言中都没有用,但在所有AFAIK中都被解析为有效的空格。

,这意味着使用弹性制表符不再是外部化的约定(例如,“文件的格式已设置为具有弹性的制表符,请打开它们“),但您需要根据具体情况选择启用这些选项。

现有的文本编辑器通常在垂直方向上显示字形或单个空格标签。这不是很理想,但IMO付出的代价很小。

#7 楼

之所以没有提及它们,是因为它们没有在大多数文本编辑器的IDE中实现。它们是在项目中几乎没有实际使用的新颖性。

自打孔卡时代以来,就一直在使用空格进行编程。制表符出现了,显然有人认为这是个好主意(他们误会了:p)。

当今,大多数现代编辑者可以将制表符自动转换为空格...这是毫无意义的。 br />
必须安装另一种工具来处理诸如制表符和空格之类的琐碎事情对我当然没有吸引力,而且我认为这对大多数同事都不适用。

评论


当他们陷入侮辱时,我已经清除了评论。

–ChrisF♦
2012年2月29日在16:49

只是想指出,我喜欢弹性制表符的想法的主要原因不是因为它解决了制表符与空格的问题,而是因为原始问题中GIF中显示的行为;自动,无痛对齐。另外,对于VCS差异,还有一个额外的好处,就是在该示例中无需更改空格。

– Ajedi32
2014年2月7日在17:25



“必须安装另一个工具...”这个说法还不够好……好像没有足够的工具正在使用中。

–Milind R
2014年12月4日下午16:53

@MilindR无论您是否认为这是一个足够好的论点,这就是为什么(三年前)我对此不感兴趣的原因。有很多工具用来做有用的事情,并不是添加另一个确实不会对您的环境添加任何东西的工具的原因。

– TZHX
15年1月26日在10:29

这样的态度就是为什么像MS这样的公司决定强迫用户使用新的UX的原因……我不禁思考,如果将相同的态度应用于软盘-> CD过渡会发生什么。

–Milind R
15年1月26日在11:42

#8 楼

我认为,如果IDE支持它们(Microsoft!),它们会发现很多用处。一旦人们发现他们可以将他们的花箱拍到一边,并使其可读性好,他们就会这样做。您可能会突然在源代码中添加更多注释(这只会是一件好事)。

我想我们也可以在“如果...这样的列表中”添加注释“工具提示”。 ”,因此您的大注释块可以隐藏起来,并在需要时轻松查看。
也许我们也可以使用注释块来构成文档的一部分(不是沙堡类型的东西,不是嵌入在代码中的正确的用户可读文档片段,而不仅仅是方法标头)

缺点:如果实际上只修改了1行(如果编辑器保存了带有制表符转换为空格的文件),那么如果看起来像是更改了几行代码,则可能会使源diff看起来不好。或者,如果弹性制表符是用单个字符(或更可能是2个制表符)实现的,那么在编辑器之外查看源代码可能看起来很糟糕。

我想我喜欢这个想法,但在行尾使用“制表符”可以使注释框松紧,并在随后的行(具有双制表符间距)中排列所有注释。

#9 楼

我是这样看的:如果大多数流行的工具已经支持弹性制表符,那么很多人就会使用它们。 vi的导航/编辑模式,语法高亮显示以及后来的Intellisense也是如此。在每种情况下,既定的智慧是它没有用或不需要,但已被实施并获得了成功。

弹性制挡片的影响当然很小。大多数人对现状足够满意,因此不在乎。类似的推理适用于许多情况,在这些情况下,有些人只是对自己所拥有的感到满意,而没有理由转向更高级的东西。换句话说,弹性制挡片所面临的最大问题与几乎所有其他好主意都一样:它需要吸引人。

,但这并不意味着该功能不能逐步采用。即使整个团队需要一个新的编译器和一个新的IDE来开始使用它,也逐渐采用了每种编程语言。每个单独的硬件体系结构和许多其他示例都是如此。缺乏与现有工具的集成也不是阻碍因素:例如,“统一差异格式”(Unified-diff format)确实如此,它逐渐取代了自动工具仍能理解的较早可读性较低的格式(例如补丁)。这些工具已经随着时间的推移进行了升级。

我很感谢其他人提到的互操作性问题,但是尽管有这些问题,肯定会有一些团队(像我的团队)毫不犹豫地采用它。诸如diff,merger等的外部工具最初将不支持它,但是我们会尽力鼓励供应商加入该功能。这就是始终取得进展的方式。在暂时的过渡时期需要一些痛苦,但最后还是值得的。

评论


C vs C ++参数似乎有点误导。尽管“某些人”确实是这种情况(正如您正确地说的那样),但根据情况,有明显的理由坚持使用C或偏爱C ++。在默认设置下,C ++运行时的大小是其中之一。

– Haylem
2012年2月28日在17:10

我和海伦在一起。如果没有C对比C ++的比较,您的观点将会更加合理。它们是完全不同的语言。在我看来,C用于需要大量控制(例如VM)的系统编程和其他低级工作。 C ++更适合中级应用程序,在这些应用程序中抽象可用于管理复杂性(名称空间,STL容器和算法,模板),但是性能仍然是一个问题(游戏是最明显的例子)。

–琼·普迪(Jon Purdy)
2012年2月28日在18:20

@haylem:感谢您的反馈。我已经删除了对C / C ++的引用。

– Timwi
2012-2-28在21:02

@JonPurdy:感谢您的反馈。我已经删除了对C / C ++的引用。

– Timwi
2012-2-28在21:02

#10 楼

我会遇到的最大问题是整个文档中的间距不一致。我知道作为一名程序员,我会很讨厌看到循环或if语句使用“标准”缩进,然后注意到不同的缩进。我个人知道我喜欢在文档中看到所有花括号,而不仅仅是在我正在查看的代码块中。

总体而言,我认为这是一个不错的主意,但是我个人而言,不喜欢。

#11 楼

我刚刚尝试了jEdit的弹性制表符实现,它与我所熟悉的编程语言(主要是HTML / XML和类似C的语言)惊人地兼容。但是,使用Python代码时,它的呈现方式是这样(用空格代替制表符来说明事物如何对齐):

 def foo(x):
             '''<1 tab before the docstring.
No tab       <tab
No tab       <tab
             <tab  <another tab
             <tab  <another tab
             <tab'''
             if 1 or 2:    #<Tab before this comment
                           yield True
  

对于像Python这样依赖间隔的语言,除非您禁用弹性制表位提供的功能,否则这是一个大问题。如果您知道该选项的名称以及如何禁用它,像Vim和Emacs这样的编辑器就可以使大多数功能的禁用变得简单,但是对于上述代码,则必须禁用此功能。

那有人说,这对于x86 ASM,C,C ++,Go,XML,HTML和其他不太依赖空格的代码非常有用:

 import (
    "fmt"    // We love formatting functions.
    "io"     // Because I/O is useful.
    "os"     // Can't open a file without os.Open!
)

type Foo struct {
    Field1              int          // This is properly aligned
    ReallyLongField2    string       // with this.
    privateField        io.Reader    // Elastic tabstops are great for Go.
}
 


我会说,诸如Scheme之类的Lisp方言有其自己的约定,这也将使弹性制表符表达“丑陋”的代码。如果更改Tabstop设置以匹配2列的约定,并在不寻常的位置(在函数及其参数之间)插入Tabstop:



 (let loop ((n 1))
  (if  (> n 10)
        '()
        (cons  n
               (loop (+ n 1)))))
 


vs。更具可读性:

 (let loop ((n 1))
  (if (> n 10)
      '()
      (cons n
            (loop (+ n 1)))))
 


当然,这还不如Python差例如,但它肯定会降低代码的可读性。虽然我非常喜欢使用C#或C ++之类的代码进行编码时的功能,但我却讨厌使用诸如Python或Scheme这样的语言(其中空格在功能上和/或视觉上有帮助)进行编码的功能。弹性制表符专门用于创建帮助而无需单独的缩进实用程序,但显然并非所有编程语言都适用。

评论


至少lisp的示例只是错误地使用了弹性制表符。如果要对齐某些内容,请在其行的开头使用相同数量的标签。您不仅要为以前使用的行使用不同数量的制表符,而且还要绕过以前使用的非弹性制表符。

–mtraceur
20-05-29在5:05

我也没有看到Python示例有任何真正的问题-为什么您要在行注释中加上标签-仅使用两个空格,除非您要使其对齐。这就是制表符的含义-想要对齐(如在表中)-弹性制表符只是使您行中的制表符数量与其对齐(动态定位)列之间具有一对一的相关性。如果您使用标签,则表示要与下一行的内容对齐。如果您不选择注释,则不会这样做。

–mtraceur
20-05-29在5:09



但我对此回答+1,因为这表明弹性制表符的一个问题是人们只会使用他们现有的制表习惯(仅对固定制表符有意义),然后将其视为弹性制表符的问题,而不是采用花费几分钟的时间来了解弹性制表符如何使他们使用制表键来更有效地实现所需的功能。

–mtraceur
20 May 29'5:13

#12 楼

Emacs已经在有未封闭括号的情况下处理缩进,并将使wilma与fred对齐。我不知道为什么Eclipse不这样做。好的,我有个主意,但这不是免费的。

您也可以让Emacs对齐注释,而不会带来太多麻烦,但是AFAIK却没有人,但是您曾经想要过。

评论


我只能将您的最后一句话解释为拖钓,因为显然至少有另一个人希望它足够糟糕,以至于无法创建一个参数良好的页面,一个Java实现和一个GIF来说明它为什么很好。如果您仔细阅读答案,您会发现尼克也不是一个人。哦,等等,也看这里。

–罗马·斯塔科夫
2012-2-28在18:31



顺便说一句,Emacs是否在进行编辑(例如更改函数名称的长度)时重新缩进通配符?如果确实如此,那将非常接近弹性制表位。

–罗马·斯塔科夫
2012年2月28日在18:43



@romkyns:我并不是故意要拖钓,我只是说我从未在EMACS中看到过这种缩进风格。通常,您输入时EMACS不会重新缩进多行,但是也可以更改。

–kevin cline
2012年2月28日在22:08