我希望能够使用键盘快捷键清除 Windows 终端中的回滚缓冲区。
在 WSL 中,我可以点击Ctrl+ L,它会执行换页操作(相当于clear -x
命令),从而清除屏幕,但只能通过将上面的内容向上滚动到视图之外来清除。
例如,我想要做的是按Ctrl+ K(如 macOS 终端)以便能够clear
在 WSL 和 PowerShell 中正确清除屏幕(类似于发出普通命令)。
这可能吗?
更新:Windows Terminal 现在已原生支持此功能。我已在下面添加了自己的答案并自我接受,但有点隐蔽,因此这里有一个链接:https://superuser.com/a/1628815/2924
答案1
更新 2021-10-20:现在已原生支持版本 1.12(撰写本文时处于预览状态)。
看公关 #10906了解详细信息。
这将添加一个新动作
clearBuffer
。它接受 3 个清除类型的值:
"clear": "screen"
:清除终端视口内容。保持回滚不变。将光标行移动到视口顶部(未修改)。
"clear": "scrollback"
:清除回滚。保持视口不变。
"clear": "all"
:(默认)清除回滚和可见视口。将光标行移动到视口顶部(未修改)。“清除缓冲区”也已添加到
defaults.json
。
这些操作可以从命令面板调用,也可以通过设置 UI 绑定到键盘快捷键,也可以直接settings.json
在官方文档。
Cmd ⌘作为参考,这里是关于+K和Ctrl+之间区别的讨论L:Ctrl+L 和 Cmd+K 在清除终端屏幕方面有什么区别?
较长的答案
根据 Mike Griese (zadjii-msft在 GitHub 上),一位从事 Windows Terminal 工作的工程师:
为了向我说明清楚,cmd+k 不是由 bash 或 shell 处理的。这是终端本身处理键绑定,并清除缓冲区和回滚。
您描述的用户故事对我来说很有意义,因此我将把它放在待办事项中。
达斯汀·豪威特(DHowett-MSFT在 GitHub 上)继续说道:
[T]这个问题尤其棘手。为了与不需要连接终端的 Windows 控制台应用程序兼容,我们需要维护一个文本缓冲区供它们读取。就这样。因为我们没有办法清除该文本缓冲区(从终端端),而且我们还没有编写一个,所以它比清除本地屏幕更复杂。这不是所有终端的复杂性问题。
答案2
好吧,这变成了一条兔子小径 ;-) ...
我本以为使用 Windows Terminal 1.3 中引入的操作会非常简单sendInput
,但使用该方法我总是失败。我并不声称自己是按键绑定或终端转义序列方面的专家,但我正在尝试摸索。
首先,从 开始man clear
,“清除回滚”序列是Esc[3J
。这在 Windows 终端中通过以下方式运行:
- 电源外壳:
Write-Output "`e[3J"
- bash、zsh 或 fish:(
printf '\033[3J'
或等效项echo
)
当然,它需要与“清除整个屏幕”序列 ( \033[2J
) 和“光标到主位置” ( \033[H
) 结合使用(从这个答案)。
将它们放在一起,printf '\033[2J\033[3J\033[H'
我们就能得到clear
(没有参数的)行为。
因此我认为,sendInput
鉴于Windows Terminal 1.3 发行说明我们可以通过以下方式发送转义代码:
{ "command": { "action": "sendInput", "input": "\u001B[3J" }, "keys": "ctrl+shift+l"}
在"actions"
部分(以前称为"keybindings"
)。\u001b[A
示例(向上箭头)对我来说很好用,但“清除回滚”会导致 bash 中出现错误铃声并[3J
在 fish 中打印。对于只是尝试清除屏幕也会出现同样的情况\u001B[2J
。如果有人能找出我错在哪里,我很想知道。
但我们能重新绑定 shell 中的按键。但是,他们可能无法区分Ctrl+L和Ctrl+ Shift+L这个原因. 除了最近的 PSReadLine 2.0,它在键绑定上区分大小写。
因此,如果你确实想在 WSL 中的 PowerShell 和 Linux shell 中使用++ Ctrl,则需要分两步进行:Shiftl
sendInput
首先,使用未使用的键码设置 Windows 终端操作:
"actions":
// formerly "keybindings"
[
...
{ "command": { "action": "sendInput", "input": "\uAC12" }, "keys": "ctrl+shift+l"},
...
]
}
说实话,我不确定选择密钥代码的最佳方式是什么。我只是从韩语字符集(\uAC12
),因为我确信在现实生活中我永远不会遇到这种情况。请注意此评论建议使用“私人使用“E000-EFFF
范围,但它似乎在 Windows 终端上相当流行,而且我已经选择了韩语,所以我保留了下面使用的示例\uAC12
。
因此我们需要\uAC12
在每个 shell 中进行绑定以发送正确的转义序列:
重击:
首先,使用 获取要绑定的键序列
printf '\uAC12' | xxd
,结果为00000000: eab0 92
。然后,使用该输出,将 bind 命令编码为
bind -x '"\xEA\xB0\x92":"printf \\033[2J\\033[3J\\033[H"'
(xxd
来自这个答案。Zsh:看起来更复杂一些:
function clear-scrollback { clear && printf '\e[3J' zle && zle .reset-prompt && zle -R } zle -N clear-scrollback bindkey '\uAC12' clear-scrollback
(协助这个答案)。
鱼:
bind \uAC12 "printf '\033[2J\033[3J\033[H'; commandline -f repaint"
PowerShell:
Set-PSReadLineKeyHandler "$([char]0xAC12)" -ScriptBlock { Write-Output "`e[2J`e[3J"; [Microsoft.PowerShell.PSConsoleReadLine]::ClearScreen() }
. 协助进行[char]
转换这个答案,如果我没花点时间就找到一个例子在 ScriptBlock 中调用 PSReadline 函数。PowerShell Core:。
Set-PSReadLineKeyHandler "$([char]0xAC12)" -ScriptBlock { Write-Host "`e[2J`e[3J"; [Microsoft.PowerShell.PSConsoleReadLine]::ClearScreen() }
不确定为什么 PowerShell 和 PowerShell Core 在这里的行为不同。
欢迎提出更正或改进建议。
答案3
编辑您的~/.bashrc
alias cls='clear && echo -en "\e[3J"'
现在您可以键入cls
以清除屏幕并在 bash WSL 会话内向后滚动。
编辑 Windows 终端 JSON 文件
"actions":
[
// Command to reset terminal and scrollback
{
"command":
{
"action": "sendInput", "input": "cls\r"
},
"keys": "ctrl+k"
},
]
现在按CTRL+k将为您输入 CLS 命令。对于 PowerShell 或 CMD 提示符,CLS 命令已默认受支持,因此无需额外配置。