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

Cha*_*per 4 keyboard terminal keyboard-shortcuts windows-subsystem-for-linux windows-terminal

我希望能够使用键盘快捷键清除 Windows 终端中的回滚缓冲区。

在 WSL 中,我可以点击Ctrl+L并执行换页(相当于clear -x命令),它清除屏幕,但只能通过将上面的内容向上滚动并移出视图。

例如,我想要做的是,在 WSL 和 PowerShell 中点击Ctrl+ K(如 macOS 终端)以便能够正确清除屏幕(类似于发出普通clear命令)。

这可能吗?

Cha*_*per 19

2021-10-20 更新:从版本 1.12开始,现在已原生支持此功能(在撰写本文时为预览版)。

\n

有关完整详细信息,请参阅PR #10906 。

\n
\n

这添加了一个新动作,clearBuffer。它接受 3 个清晰\n类型值:

\n
    \n
  • "clear": "screen":清除终端视口内容。保持回滚不变。将光标行移动到视口顶部\n(未修改)。

    \n
  • \n
  • "clear": "scrollback":清除回滚。保持视口不变。

    \n
  • \n
  • "clear": "all":(默认)清除回滚和可见视口。将光标行移动到视口顶部\n(未修改)。

    \n
  • \n
  • “清除缓冲区”也已添加到defaults.json.

    \n
  • \n
\n
\n

这些操作可以从命令面板调用,也可以通过设置 UI 绑定到键盘快捷键,并直接在官方文档settings.json中介绍。

\n

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

\n

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

\n

Windows 终端 clearBuffer 操作示例

\n
\n

作为参考,这里讨论Cmd \xe2\x8c\x98+KCtrl+之间的区别LWhat is the Difference Between Ctrl+L and Cmd+K for Clearing the Terminal Screen?

\n

更长的答案

\n

据从事Windows Terminal 工作的工程师 Mike Griese(GitHub 上的zadjii-msft )介绍:

\n
\n

为了将来我澄清 - cmd+k 不是由 bash 或 shell 处理的东西。这是终端本身处理键绑定,并清除缓冲区和回滚。

\n

您描述了一个对我来说有意义的用户故事,所以我将把它放在待办事项中。

\n
\n

Dustin Howett( GitHub 上的DHowett-MSFT)继续说道:

\n
\n

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

\n
\n

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

\n


小智 8

编辑你的~/.bashrc

alias cls='clear && echo -en "\e[3J"'
Run Code Online (Sandbox Code Playgroud)

现在,您可以在 bash WSL 会话中键入cls以清除屏幕并回滚。

编辑 Windows 终端 JSON 文件

"actions": 
[
    // Command to reset terminal and scrollback
    { 
        "command": 
        { 
            "action": "sendInput", "input": "cls\r" 
        }, 
        "keys": "ctrl+k"
    },
]
Run Code Online (Sandbox Code Playgroud)

现在按CTRL+k将为您输入 CLS 命令。对于 PowerShell 或 CMD 提示符,默认情况下已支持 CLS 命令,因此无需额外配置。


Not*_*1ds 6

好吧,这变成了一条半兔子小道;-) ...

我原以为这sendInput对于 Windows Terminal 1.3 中引入的操作会非常简单,但我一直在使用这种方法。我并不声称自己是键绑定或终端转义序列方面的专家,但我正在努力解决这个问题。

首先,从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(没有参数的)行为。

所以我认为,鉴于Windows Terminal 1.3 发行说明中的sendInput示例,我们可以通过以下方式发送该转义码:

{ "command": { "action": "sendInput", "input": "\u001B[3J" }, "keys": "ctrl+shift+l"}
Run Code Online (Sandbox Code Playgroud)

"actions"部分(以前的"keybindings")中。该\u001b[A示例(向上箭头)对我来说效果很好,但是“清除回滚”会导致 bash 中出现错误铃声并[3J在 fish 中打印。\u001B[2J仅尝试清除屏幕也会发生同样的情况。如果有人能弄清楚我哪里出错了,我很想知道。

但是......我们可以重新绑定shell中的键。但是,由于这个原因,他们可能无法分辨Ctrl+LCtrl+ Shift+之间的区别。除了最近的 PSReadLine 2.0,它在键绑定上区分大小写。L

所以,如果你真的想使用Ctrl+ Shift+l在WSL都PowerShell和Linux的壳,你需要做的是在两个步骤:

首先,sendInput使用未使用的键码设置 Windows 终端操作:

"actions":
// formerly "keybindings"
    [
      ...
        { "command": { "action": "sendInput", "input": "\uAC12" }, "keys": "ctrl+shift+l"},
      ...
    ]
}
Run Code Online (Sandbox Code Playgroud)

老实说,我不确定选择键码的最佳方式是什么。我刚刚使用了Hangul字符集 ( \uAC12) 中的一些内容,因为我相当确定我永远不会在现实生活中遇到它。请注意,此评论建议使用“私人使用E000-EFFF范围,但它在 Windows 终端上似乎相当多,而且我已经选择了韩文,因此我使用\uAC12.

那么我们需要\uAC12在每个 shell 中绑定以发送正确的转义序列:

  • 重击:

    首先,获取要绑定到的键序列printf '\uAC12' | xxd,结果为00000000: eab0 92

    然后,使用该输出,将绑定命令编码为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
    
    
    Run Code Online (Sandbox Code Playgroud)

    (在此答案的帮助下)。

  • 鱼: bind \uAC12 "printf '\033[2J\033[3J\033[H'; commandline -f repaint"

  • 威力:Set-PSReadLineKeyHandler "$([char]0xAC12)" -ScriptBlock { Write-Output "`e[2J`e[3J"; [Microsoft.PowerShell.PSConsoleReadLine]::ClearScreen() }. 协助对[char]从铸造这个答案,而当如果它不带我一段时间才能找到一个实例调用的脚本块一个PSReadline功能。

  • PowerShell 核心:Set-PSReadLineKeyHandler "$([char]0xAC12)" -ScriptBlock { Write-Host "`e[2J`e[3J"; [Microsoft.PowerShell.PSConsoleReadLine]::ClearScreen() }. 不知道为什么 PowerShell 和 PowerShell Core 在这里表现不同。

欢迎更正或改进建议。