如何添加键盘快捷键来清除 Windows 终端中的回滚缓冲区?

如何添加键盘快捷键来清除 Windows 终端中的回滚缓冲区?

我希望能够使用键盘快捷键清除 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官方文档

将快捷方式绑定到清除缓冲区操作

清除 settings.json 中的缓冲区操作

Windows 终端 clearBuffer 操作示例


Cmd ⌘作为参考,这里是关于+KCtrl+之间区别的讨论LCtrl+L 和 Cmd+K 在清除终端屏幕方面有什么区别?

较长的答案

根据 Mike Griese (zadjii-msft在 GitHub 上),一位从事 Windows Terminal 工作的工程师:

为了向我说明清楚,cmd+k 不是由 bash 或 shell 处理的。这是终端本身处理键绑定,并清除缓冲区和回滚。

您描述的用户故事对我来说很有意义,因此我将把它放在待办事项中。

达斯汀·豪威特(DHowett-MSFT在 GitHub 上)继续说道:

[T]这个问题尤其棘手。为了与不需要连接终端的 Windows 控制台应用程序兼容,我们需要维护一个文本缓冲区供它们读取。就这样。因为我们没有办法清除该文本缓冲区(从终端端),而且我们还没有编写一个,所以它比清除本地屏幕更复杂。这不是所有终端的复杂性问题。

参考:https://github.com/microsoft/terminal/issues/1882

答案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+LCtrl+ 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 命令已默认受支持,因此无需额外配置。

相关内容