如何在底部提示时启动XTerm?


12

启动XTerm时,提示从终端的第一行开始。运行命令时,提示会向下移动直到到达底部,然后一直停留在底部(甚至不行Shift- Page Down否则鼠标可以更改此值)。并非让终端生命周期的开始是“特殊的” 而是提示应始终位于终端的底部。请注意,我有多行提示

当然,它应该像以前一样工作(可调整大小,可滚动,输出中没有不必要的换行符,并且输出不会神秘地消失),因此PROMPT_COMMAND='echo;echo;...',类似的选择是不可行的。理想情况下,解决方案不应是特定于外壳的。

编辑:目前的解决方案,在简单的情况下工作时,有几个问题:

  • 它是针对Bash的。理想的解决方案应可移植到其他外壳。
  • 如果其他进程进行了修改,PS1它将失败。一个例子是的virtualenv,这增加了(virtualenv)开始PS1,然后总是消失只是倍以上。
  • Ctrl- l现在删除历史记录的最后一页。

除了分叉XTerm之外,还有什么方法可以避免这些问题?


不知何故,我们需要在Xterm的滚动条缓冲区中引入空白字符。
2014年

3
实际上,通过执行clear命令,可以随时轻松将提示移回顶部。
潜水员2014年

@SHW我希望对此有一个设置,而不是一个hack。在我的经验中,终端黑客倾向于引入非常细微的错误。
l0b0

@werediver但是我永远都不想让它排在首位。
l0b0

1
由于只有外壳程序知道何时输出提示,因此任何解决方案都必须在外壳程序上下文中。甚至分叉XTerm也无济于事,因为XTerm不知道要求其输出的内容是否是提示。对于终端,shell提示符只是另一个字符序列,与它可能收到的任何其他字符序列没有什么不同。
celtschk 2014年

Answers:


11

如果使用bash,则应使用以下技巧:

TOLASTLINE=$(tput cup "$LINES")
PS1="\[$TOLASTLINE\]$PS1"

或(效率不高,因为它tput在每个提示符之前运行一个命令,但在调整终端窗口的大小之后才起作用):

PS1='\[$(tput cup "$LINES")\]'$PS1

为了防止tput更改退出代码,可以显式保存并重置它:

PS1='\[$(retval=$?;tput cup "$LINES";exit $retval)\]'$PS1

注意该变量retval是局部变量。它不会影响retval您可能已经在shell中定义的任何变量。

由于大多数终端cup功能是相同的\e[y;xH,因此您也可以对其进行硬编码:

PS1='\[\e[$LINES;1H\]'$PS1

如果您希望它对以后重置PS1而言是安全的,则也可以使用该PROMPT_COMMAND变量。如果设置,它将输出提示之前作为命令运行。所以效果也可以通过

PROMPT_COMMAND='(retval=$?;tput cup "$LINES";exit $retval)'

当然,虽然重置PS1不会影响此设置,但是其他一些软件也可能会更改PROMPT_COMMAND


如何tput从众多不同echo的命令?(出于好奇)
SHW 2014年

@ l0b0,可能不值得单独回答。我希望celtschk不会介意我编辑了他/她的答案。
斯特凡Chazelas

'\[$(tput cup "$LINES")\]' 工作精美。谢谢!
l0b0

有一个问题tput:似乎已重置$exit_code。使用修复\[\e[$LINES;1H\]
l0b0

1
@ l0b0:我现在使用tput保留退出代码的版本。
celtschk 2014年

4

作为对先前答案的略微简化,我发现运行起来更容易:

tput cup $LINES

.bashrc或的开头.zshrc。它只是完成工作。

优点:

  • 启动外壳程序时,它只会打印一次

缺点:

  • 与^大号清画面时,未打印和混叠clearclear; tput ...没有帮助;
  • 调整终端大小时,提示会移到其他地方

2

使用的答案$LINES不必要地不可移植。就像在中所做的那样resize,您可以简单地要求xterm将位置设置为任意大的行号,例如

tput cup 9999 0

(假设您的窗口小于1万行,而无需考虑向后滚动)。

由于字符串不会因为调整窗口大小而改变,因此您可以计算一次,然后将其作为常量粘贴到提示字符串中,例如,

TPUT_END=$(tput cup 9999 0)

然后

PS1="${TPUT_END} myprompt: "

根据您的喜好。

至于其他流程修改PS1PS1这些更改之后,您将必须重新计算,以确保它看起来像您想要的。但是,这个问题中没有足够的细节指出要在哪里进行更改。

最后,由于bash的假设,制表符完成的行为与此类更改不符。


您的意思是“制表符完成行为与此类更改不符”是什么意思?
l0b0

我认为您的意思是PS1="${TPUT_END} myprompt: ",甚至PS1="${TPUT_END}${PS1}"
–l0b0

对于后者-对(从生成文件的思考中得出的错字)。对于前者,我要记住,bash的命令编辑依赖于能够重新打印行(带有提示),并且由于命令完成而与滚动结合时,您会得到一些奇怪的行为。
Thomas Dickey
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.