powershell 清除终端导致奇怪的行为[关闭]

3phpmpom  于 2023-05-07  发布在  Shell
关注(0)|答案(1)|浏览(124)

**已关闭。**此问题不符合Stack Overflow guidelines。目前不接受答复。

这个问题似乎不是关于在help center定义的范围内编程。
23天前关闭
Improve this question
我正在使用VSCODE和Powershell终端。有时我想清除我的终端由于很多错误和警告,所以我想键入clear将做到这一点,但这并不清除缓冲区。
因此,我找到了一个解决方案,即将以下内容添加到keybindings.json文件中:

// Place your key bindings in this file to override the defaults
[
    {
        "key": "ctrl+k",
        "command": "workbench.action.terminal.clear",
        "when": "terminalFocus"
    }
]

现在,虽然这工作得很好,但它在我的终端中产生了奇怪的行为。如我插入的图片所示,它允许我在第一行键入两个字符,但随后它会跳到最后一行,让我完成。我该怎么解决这个问题?

dced5bon

dced5bon1#

您在PSReadLine模块的PowerShell中看到了一个错误,最高版本至少为v7.3.3(包括Windows PowerShell)/ v2.2.6,并且看起来可能在 * 两者 * 中都存在错误:

  • 卸载PSReadLineRemove-Module PSReadLine)(故障排除期间;卸载此模块 * 不是 * 一个可行的解决方案,因为它严重降低了命令行编辑体验)只会使问题在 Windows 上消失:
  • 注意:在PowerShell extension提供的PIC(PowerShell集成控制台)中,卸载无效,因为它似乎使用了无法卸载的私有副本。
  • 在macOS上(也可能在Linux上)),即使卸载了PSReadLine也会出现问题(同样在常规终端/通用shell中,即在PIC之外)。

具体来说,当Visual Studio Code的集成终端通过键盘快捷键(而不是使用从终端内部提交的命令)被清除时(包括回滚缓冲区),PowerShell /PSReadLine不知道这一事实,并且随后的键盘输入出现在 original 行上,即光标在屏幕被清除之前所处的位置。
相关bug报告

  • 对于PSReadLineGitHub issue #841
  • 对于PowerShell本身:GitHub issue #19479
    解决方法
    备注
  • 下面的解决方法必须放在您的keybindings.json文件中,在顶级数组([ … ])内;使用Preferences: Open Keyboard Shortcuts (JSON)从命令面板打开这个文件进行编辑.

如果有预先存在的定义,并且您希望将对象放在它们下面 * 之后 *,请确保将,放在最后一个预先存在的定义的结束}之后;要把它们放在先前存在的那些之前,必须在下面最后一个关闭的}后面附加一个,

  • 如果您从未将cmd.exe作为shell使用,则可以从每个解决方案中 * 省略 * 第一个定义,并从第二个解决方案的"when":属性中删除&& terminalShellType == 'pwsh'部分。对于大多数shell来说,发送额外的Ctrl-L在这种情况下是一个良性的无操作(它也会清除屏幕,但保留回滚缓冲区),而cmd.exe不理解这个键弦,而是 * 打印 * ^L
    Visual Studio Code v1.77+解决方法

Visual Studio Code v1.77+现在支持执行 * 多个 * 命令以响应单个键盘快捷键-请参阅文档。
正如您自己所发现的,除了Ctrl-K之外,还按Ctrl+L* 可以让PowerShell知道新的光标位置,从而解决问题。
由于Ctrl+L转换为控制字符FF(换页),后者可以作为键弦发送到终端,在运行"workbench.action.terminal.clear"命令之后。
因此:

注意事项:下面的定义使用*ctrl+shift+k而不是ctrl-k**,因为后者似乎不适用于runCommands由于Visual Studio Code v1.77.3中的明显bug-请参阅GitHub issue #179724

// General definition for all shells *except* PowerShell.
{
    "key": "ctrl+shift+k",
    "when": "terminalFocus && terminalShellType != 'pwsh'",
    // Clear the screen and the scrollback buffer.
    // For shells other than PowerShell that is sufficient.
    "command": "workbench.action.terminal.clear"
},

// Override for PowerShell, to compensate for the following bugs:
// * https://github.com/PowerShell/PSReadLine/issues/841
// * https://github.com/PowerShell/PowerShell/issues/19479
{
    "key": "ctrl+shift+k",
    "when": "terminalFocus && terminalShellType == 'pwsh'",
    "command": "runCommands",
    "args": {
        "commands": [
            // Clear the screen and the scrollback buffer.
            "workbench.action.terminal.clear",
            // Additionally send Ctrl-L to PowerShell to clear only the current 
            // screen, which makes PowerShell aware of the new cursor position.
            {
                "command": "workbench.action.terminal.sendSequence",
                "args": {
                    "text": "\u000c" // Ctrl-L (FF)            
                }
            }
        ]
    }
}

*即使在v1.77.3(可能更早版本)中, 确实 * 适用于ctrl+k**的替代解决方案:

也就是说,如果您向提供等效功能的PowerShell终端发送一个发出VT / ANSI转义序列的命令,但请注意,您可能会短暂地看到该命令被“键入”(当文本由Visual Studio Code发送时,以自动方式),这可能会在视觉上造成破坏

// General definition for all shells *except* PowerShell.
{
    "key": "ctrl+k",
    "when": "terminalFocus && terminalShellType != 'pwsh'",
    // Clear the screen and the scrollback buffer.
    // For shells other than PowerShell that is sufficient.
    "command": "workbench.action.terminal.clear"
},

// Override for PowerShell, to compensate for the following bugs:
// * https://github.com/PowerShell/PSReadLine/issues/841
// * https://github.com/PowerShell/PowerShell/issues/19479
{
    "key": "ctrl+k",
    "when": "terminalFocus && terminalShellType == 'pwsh'",
    // Send a VT / ANSI escape sequence that clears the screen and
    // and the scrollback buffers and resets the cursor position.
    "command": "workbench.action.terminal.sendSequence",
    "args": {
        "text": "[Console]::Write(\"$([char] 0x1b)[2J$([char] 0x1b)[3J$([char] 0x1b)[H\")\u000d"
    }
}

相关问题