【问题标题】:Emacs: some programs only work in ansi-term, some programs only work in shellEmacs:有些程序只能在 ansi-term 下工作,有些程序只能在 shell 下工作
【发布时间】:2012-09-08 03:09:24
【问题描述】:

这里是相对 Emacs 新手,只是试图调整我的编程工作流程以适应 emacs。到目前为止,我已经发现了 shell-pop,并且我非常喜欢在需要敲击奇怪命令时弹出的按需终端。

到目前为止,我对 Emacs 的了解是,shell 是一个“哑”终端,不支持任何 ansi 控制代码,这使得它与试图在终端模拟器上绘制复杂 UI 的 ncurses 之类的东西不兼容.这就是为什么你不能在 shell 模式下使用 lesstop 或类似的。

但是,我似乎在使用 ansi-term 时遇到了问题,这并不是它所宣称的一切。当然,它运行lessgit log 甚至nano 都没有问题,但有一些东西在ansi-term 中运行时似乎无法正常显示,例如@987654329 @ 和 nosetests。我不太确定它的名称是什么,但apt-get 的输出的特点是实时更新最后一行显示的内容,然后在该行上方滚动出不变的文本行。它似乎介于less 之类的东西和cat 之类的更愚蠢的东西之间。不知何故ansi-term 根本不喜欢这个,而且我得到非常乱码的输出,它似乎只在一行上输出所有内容,或者只是通常丢失它的位置并随机输出所有内容。在nosetests 的情况下,它开始正常,但如果任何库吐出任何 STDERR,输出都会以类似的方式进入地狱。

通过一些摆弄,似乎可以通过混合 C-lRET 来解决这个问题,但它并不总是可靠的。

有人知道这里发生了什么吗?有什么方法可以修复ansi-term 以便它可以正确显示所有内容吗?或者是否有其他一些我不知道的更好的模式?理想情况下,我想要像 Gnome Terminal 这样轻松“正常工作”的东西,它可以运行上述所有程序而不会出现任何问题。

谢谢!

【问题讨论】:

  • term 的行为似乎比 ansi-term 稍好,但我不清楚这两者之间有什么区别。

标签: shell emacs terminal ansi-term


【解决方案1】:

我通过注释掉整个 .emacs.el 然后取消注释并重新启动文件中每一行的 emacs 解决了这个问题。我发现仅以下一行是导致该问题的原因:

   '(fringe-mode 0 nil (fringe))

(此行禁用自定义设置变量内部的边缘)。

我猜这是 Emacs 中的一个错误,当任何输出行超过 $COLUMN 列时,禁用边缘会导致 term-mode 严重混淆它的输出。

无论如何,我真的不太喜欢边缘,而且似乎我至少能够在不触发此问题的情况下禁用左边缘:

(set-fringe-mode (cons 0 8))

【讨论】:

  • 我不知道边缘模式是全局模式还是缓冲区本地模式,但如果它是缓冲区本地,您可能只能在术语缓冲区中启用它。
【解决方案2】:

也许 apt-get 会根据 $TERM 环境变量做不同的事情。如果设置TERM=dumb 会发生什么?如果这能让事情奏效,那么您可以尝试不同的值,直到找到一个支持足够功能但仍然有效的值。

【讨论】:

  • 我一直在摆弄这个,更改各种 emacs 设置,实际上看起来就像在 term 内,任何输出行长于终端宽度的命令都会导致这个问题。这就是为什么apt-get 只会间歇性地这样做,因为会话之间的行长不一致,这取决于互联网可以多快下载它正在下载的内容。我找到了一个文本文件,其中cat foo.txt 100% 可靠地导致了这个问题,但前提是终端缓冲区比它的最长行窄。让它更宽,就可以了。有什么想法吗?
  • 更摆弄,似乎将truncate-lines设置为nil,truncate-partial-width-windows设置为nil,word-wrap设置为t的具体组合似乎停止了乱码问题,给了我一个可行的shell,但是,它会导致外壳和 emacs 似乎无法就如何包装达成一致的地方进行看起来很傻的包装。例如,很长的一行将显示 emacs 在单词边界处换行,但随后终端在单词的中途再次换行,然后该行继续到下面的第三行……非常奇怪。
  • 是的,据我所知,任何超出窗口宽度的终端输出都会导致这种乱码,word-wrap 模式只是通过在行变得太长之前强制换行来防止它发生,即使这是一个丑陋的解决方案。不知道为什么会这样。
  • 在对我的 .emacs.el 进行详尽 逐行审核后,我发现此问题是由禁用边缘触发的。所有word-wrap 的东西只是一条红鲱鱼。注释掉'(fringe-mode 0 nil (fringe)) 行(来自custom-set-variables)已经解决了这个问题,并允许cat 在我的终端中正确工作。现在我想知道是否可以在除终端之外的所有地方禁用边缘......
  • 哈,好的。我给了你一些支持,因为你是唯一的响应者。感谢您的尝试!
【解决方案3】:

请注意,git 2.0.1(2014 年 6 月 25 日)现在在显示详细消息时可以更好地检测哑终端。
可能帮助 Emacs 更好地显示从 git 收到的一些消息,但上面报告的 fringe-mode 错误肯定是主要原因。

commit 38de156Michael Naumov (mnaoumov)

sideband.c: 不要在非终端上使用 ANSI 控制序列

在边带 #2 上从服务器端接收到的诊断消息被发送到标准错误,带有 ANSI 终端控制序列“\033[K”,该序列会擦除到附加在每行末尾的行尾。

但是,某些程序(例如 Windows 的 GitExtensions)在不了解终端控制序列的情况下读取和解释和/或显示消息,导致它们显示给最终用户。
为了帮助这些程序,当标准错误流没有被发送到 tty 时,压制控制序列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 2014-02-18
    • 2018-06-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多