首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在PSReadline中为Vi模式重新绑定转义

在PSReadline中为Vi模式重新绑定转义
EN

Stack Overflow用户
提问于 2016-09-17 21:22:47
回答 2查看 505关注 0票数 4

我已经为PowerShell安装了PSReadline模块,以便在PowerShell中从Bash获取键绑定。我启用了Vi-Mode,它工作得很好。

问题是:在Vim中,我总是使用j,k来退出insert-mode。这意味着:首先我输入j,然后非常快地输入k。如果我真的想输入j和k,那么我只需要在输入j之后等待超时。

如何在PSReadline的Vi模式下执行相同的操作?我已经尝试过了:Set-PSReadlineKeyHandler -Chord 'j', 'k' ViCommandMode,但是我再也不能输入jk了。有什么想法吗?

EN

回答 2

Stack Overflow用户

发布于 2020-02-13 00:25:24

要实现这一点,请在$Profile中添加以下内容:

代码语言:javascript
复制
Set-PSReadLineKeyHandler -Chord 'j' -ScriptBlock {
  if ([Microsoft.PowerShell.PSConsoleReadLine]::InViInsertMode()) {
    $key = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
    if ($key.Character -eq 'k') {
      [Microsoft.PowerShell.PSConsoleReadLine]::ViCommandMode()
    }
    else {
      [Microsoft.Powershell.PSConsoleReadLine]::Insert('j')
      [Microsoft.Powershell.PSConsoleReadLine]::Insert($key.Character)
    }
  }
}

但是,这可能会导致粘贴'j‘时出现问题。

票数 1
EN

Stack Overflow用户

发布于 2020-06-17 17:46:22

我很惊讶这个问题没有更受欢迎。Corben的答案的问题是,在按下'j‘之后,如果下一个按下的键是return或ctrl之类的修饰符,则会插入一个文字,而不是您期望使用的键。

我已经重写了答案来解决这两个问题,并将其转换为一个函数,以使其更易于重用(例如,当绑定两个不同的字母时,如jk)。

代码语言:javascript
复制
Set-PSReadLineKeyHandler -vimode insert -Chord "k" -ScriptBlock { mapTwoLetterNormal 'k' 'j' }
Set-PSReadLineKeyHandler -vimode insert -Chord "j" -ScriptBlock { mapTwoLetterNormal 'j' 'k' }
function mapTwoLetterNormal($a, $b){
  mapTwoLetterFunc $a $b -func $function:setViCommandMode
}
function setViCommandMode{
    [Microsoft.PowerShell.PSConsoleReadLine]::ViCommandMode()
}

function mapTwoLetterFunc($a,$b,$func) {
  if ([Microsoft.PowerShell.PSConsoleReadLine]::InViInsertMode()) {
    $key = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
    if ($key.Character -eq $b) {
        &$func
    } else {
      [Microsoft.Powershell.PSConsoleReadLine]::Insert("$a")
      # Representation of modifiers (like shift) when ReadKey uses IncludeKeyDown
      if ($key.Character -eq 0x00) {
        return
      } else {
        # Insert func above converts escape characters to their literals, e.g.
        # converts return to ^M. This doesn't.
        $wshell = New-Object -ComObject wscript.shell
        $wshell.SendKeys("{$($key.Character)}")
      }
    }
  }
}


# Bonus example
function replaceWithExit {
    [Microsoft.PowerShell.PSConsoleReadLine]::BackwardKillLine()
    [Microsoft.PowerShell.PSConsoleReadLine]::KillLine()
    [Microsoft.PowerShell.PSConsoleReadLine]::Insert('exit')
}
Set-PSReadLineKeyHandler -Chord ";" -ScriptBlock { mapTwoLetterFunc ';' 'q' -func $function:replaceWithExit }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39547321

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档