gpt4 book ai didi

powershell - 在按下 ENTER 之前获取 powershell 当前行

转载 作者:行者123 更新时间:2023-12-04 04:25:31 27 4
gpt4 key购买 nike

我有一个想法,编写一个可视化工具,在您键入时显示 PowerShell 行的 AST。但要做到这一点,第一步是在提交之前(在按下 ENTER 之前)获取当前行的文本,但我找不到 API 函数或 Hook 来执行此操作。一个存在吗?
我在新的 Windows 终端上使用 PowerShell Core 7.1.0。
预测源
似乎 PSReadLine 的 PredictiveSource 选项可以用于此目的,前提是它可以在每个字母条目上调用,而不仅仅是在 TAB 上,但我在挖掘后找不到任何关于第 3 方插件类型契约(Contract)的信息通过文档和 C# 代码...
设置 PSReadLineKeyHandler
正如传说中的@mklement0 所建议的那样,也许 Set-PSReadLineKeyHandler可用于。它似乎是为键绑定(bind)设计的,但我仍在思考如何将它用于此目的。

最佳答案

虽然没有响应每个按键的官方机制,但您可以通过设置 来实现自己的机制。通过 Set-PSReadLineKeyHandler 为每个可打印字符和选择的几个控制字符的键处理程序小命令 .
在键处理程序中,您可以在输入行下方显示有关输入缓冲区当前状态的信息。
tl;博士:

  • 修改下面的代码通过修改 $metaInfo = ...行以确定要在其下方实时显示有关正在编辑的命令行的哪些信息。
  • 阅读 限制 在下一节中。

  • 笔记:
  • 它是设置 key 处理程序的前 256 个 Unicode 代码点中的可打印字符,这实际上是构成 ISO-8859-1 encoding 的字符集。 , 本身是 Windows-1252 的子集[1]。因此,所有 ASCII 范围的字母加上一些重音字母都被覆盖,但西里尔字母不会,例如。但是,您可以根据需要定制列表。
  • 出于说明目的,下面的代码不会尝试可视化 AST,而是以 System.ConsoleKeyInfo 的格式化表示形式打印有关刚刚按下的键的信息。实例。
  • 找到以 $metaInfo = 开头的行在下面的代码中自定义要显示的内容。
  • 获取表示缓冲区内容的 AST(抽象语法树)的命令是:
    $ast = $tokens = $errors = $cursor = $null
    [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref] $ast, [ref] $tokens, [ref] $errors, [ref] $cursor)

  • 该代码在常规 Windows 控制台窗口(conhost.exe)中效果最佳; 限制 :
  • 在 Windows 终端和 Unix 终端中,如果当前输入行太靠近窗口的底部边缘而无法容纳显示自定义信息所需的行,则需要解决方法:屏幕被清除,提示出现在窗口的第一行。
  • 但是,回滚缓冲区的内容被完全保留,因此如果需要,您可以向上滚动以查看滚动到 View 之外的屏幕内容。

  • 在 key 处理程序生效时通过模拟键入粘贴命令似乎得到 PSReadLine 模块对当前的终端线是什么感到困惑,因此自定义信息的多次打印操作最终可能会堆叠在一起,而不是在原地相互覆盖。
  • 这只能在 Windows 上避免 - 无论是在常规控制台窗口中还是在 Windows 终端中 - 使用 Ctrl-V 粘贴,在这种情况下,文本会真正粘贴在命令行上,尽管不会触发 key 处理程序(然后您必须键入另一个 ( dummy) 字符以根据粘贴的内容触发 key 处理程序)。
  • 相比之下,执行了触发所描述问题的模拟输入:
  • 总是在 Unix 终端
  • 在 Windows 上右键单击粘贴



  • # The printable characters to respond to.
    $printableChars = [char[]] (0x20..0x7e + 0xa0..0xff)
    # The control characters to respond to.
    $controlChars = 'Enter', 'Escape', 'Backspace', 'Delete'

    # Set up the key handler for all specified characters.
    $printableChars + $controlChars | ForEach-Object {

    Set-PSReadLineKeyHandler $_ {
    param($key, $arg)

    $line = $cursor = $null
    [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref] $null, [ref] $cursor)

    # Handle the key at hand.
    switch ($key.Key) {
    'Backspace' { [Microsoft.PowerShell.PSConsoleReadLine]::BackwardDeleteChar(); break }
    'Delete' { try { [Microsoft.PowerShell.PSConsoleReadLine]::Delete($cursor, 1) } catch { }; break } # ignore error with empty buffer
    'Escape' {
    [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref] $line, [ref] $null)
    [Microsoft.PowerShell.PSConsoleReadLine]::Delete($0, $line.Length)
    break
    }
    'Enter' {
    # Clear any previous meta-information output, so that it doesn't linger and get mixed with command output.
    try {
    # !! On conhost.exe (regular console) windows on Windows, [Console]::CursorTop and [Console]::WindowTop are *relative to the scrollback buffer*.
    # !! In Windows Terminal and on Unix, [Console]::WindowTop is always 0, and [Console]::CursorTop is relative to the screen height - even in the presence of a scrollback buffer.
    Write-Host -NoNewLine (, (' ' * [Console]::WindowWidth) * ([Console]::WindowTop + [Console]::WindowHeight - [Console]::CursorTop - 1) -join "`n")
    }
    catch { Write-Warning "`nClearing the screen below the current line failed: $_" } # This shouldn't happen.

    # !! Workaround for a display bug: If the cursor isn't at the very end of the line, everything to the
    # !! right is inexplicably *erased* on submission, even though the submission itself still works fine.
    # !! We detect that case and simply fill the entire buffer again, which leaves it drawn correctly on submission.
    # !! (Note that [Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($line.Length) does *not* work.)
    [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref] $line, [ref] $cursor)
    if ($cursor -ne $line.length) {
    [Microsoft.PowerShell.PSConsoleReadLine]::Delete(0, $line.Length)
    [Microsoft.PowerShell.PSConsoleReadLine]::Insert($line)
    }

    # Submit the command.
    [Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
    return # We're done.
    }
    Default { [Microsoft.PowerShell.PSConsoleReadLine]::Insert($key.KeyChar) }
    }

    # Get the updated buffer content and cursor position.
    [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref] $cursor)
    # Note: To get the *AST* (too), use the following:
    # $ast = $tokens = $errors = $cursor = $null
    # [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref] $ast, [ref] $tokens, [ref] $errors, [ref] $cursor)

    # Determine the meta-informaton to print:
    $metaInfo = $key | Out-String

    if ($env:OS -ne 'Windows_NT' -or $env:WT_SESSION) {
    # Workaround for all terminals except conhost.exe
    # See comments at the top of the answer.
    if ([Console]::CursorTop + $metaInfo.Count -gt [Console]::WindowTop + [Console]::WindowHeight) {
    [Microsoft.PowerShell.PSConsoleReadLine]::ClearScreen()
    }
    }

    # Print the desired information below the line being edited.
    # Note:
    # * The .PadRight() calls ensure that all lines are fully filled (padded with spaces),
    # in order to erase potential remnants from previously displayed information.
    # * This is NOT sufficient to deal with *varying line counts* being displayed, however.
    Write-Host # blank line
    Write-Host -NoNewLine -ForegroundColor Yellow ($metaInfo -split '\r?\n' | ForEach-Object PadRight ([Console]::WindowWidth-1), ' ')

    # Set the new cursor position.
    [Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($cursor)
    }
    }
    一个 截图示例关键处理程序的作用:
    key handler in action
    请注意正在编辑的命令行下方的信息如何反射(reflect)有关最近按下的键(大写字母 D)的信息。

    [1] ISO-8859-1 在可打印字符方面是 Windows-1252 的一个子集,因为它的 0x80-0x9f范围被所谓的 C1 控制字符占据,而 Windows-1252 包含此范围内的可打印字符(除了代码点 0x810x8d0x8f0x900x9d ,未定义)。

    关于powershell - 在按下 ENTER 之前获取 powershell 当前行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67136144/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com