【问题标题】:How to change cursor shape depending on VI mode in Bash?如何根据 Bash 中的 VI 模式更改光标形状?
【发布时间】:2017-06-14 02:59:09
【问题描述】:

我的 .bashrc 中有以下行:

set -o vi

并且我希望我的光标在我处于插入模式时具有管道形状,而在我处于命令模式时具有块形状,就像我在 Vim 中将以下内容放在我的 .vimrc 中一样:

let &t_SI = "\e[6 q"
let &t_SR = "\e[4 q"
let &t_EI = "\e[2 q"

除了在这种情况下,我希望在命令行上具有等效的行为。

我在这里找到了我的问题的部分答案 - https://unix.stackexchange.com/questions/22527/change-cursor-shape-or-color-to-indicate-vi-mode-in-bash - 由 @gogolb 编写。

这是答案,复制:

#!/bin/bash
# Script "kmtest.sh"

TEST=`bind -v | awk '/keymap/ {print $NF}'`
if [ "$TEST" = 'vi-insert' ]; then
    echo -ne "\033]12;Green\007"
else
    echo -ne "\033]12;Red\007"
fi

export PS1="\u@\h \$(kmtest.sh)> "

不幸的是,尽管如答案中所述,示例脚本仅在回车后更改光标形状,而我想要的是当我点击 时光标形状会改变(即当我更改模式时)。

我在 Linux 上运行本机终端应用程序,使用 Bash 4.4.7 和我的 $TERM 变量设置为 xterm-256color。另外,我不知道 tmux 是否对我的要求有任何影响,但理想情况下,我希望该解决方案在 tmux 会话内部和外部都可以工作。


解决方案

我最终自己发现了这个问题的答案,我在我发布的另一个问题中对此进行了描述:

How to correctly link patched GNU readline library to all existing programs?

不用担心,该解决方案不需要任何补丁。 ;)

【问题讨论】:

    标签: bash terminal xterm


    【解决方案1】:

    解决方案:

    我按照建议在这里发布我对自己问题的回答。

    此解决方案适用于 Bash 4.4+,因为从该版本的 Bash 开始,使用的是 GNU readline 库的 7.0 版,其中包括必要添加的 vi-cmd-mode-stringvi-ins-mode-string 变量。

    这些变量可以在你的 .inputrc 文件中设置如下,以实现我上面描述的功能:

    set show-mode-in-prompt on
    set vi-cmd-mode-string "\1\e[2 q\2"
    set vi-ins-mode-string "\1\e[6 q\2"
    

    解释:

    对于那些真正对上述解决方案的工作原理感兴趣的人。

    vi-cmd-mode-stringvi-ins-mode-string 这两个变量与命令提示符一起打印到您的终端,以便提供一种关于您当前处于哪种模式的可视指示符(即命令模式与插入模式)。

    这两个变量的默认值分别是命令和插入模式的“(cmd)”和“(ins)”。因此,如果您只是将它们保留为默认值并有一个命令提示符,例如 PS1='>>>',那么您的提示符将如下所示:

    • 命令模式:

        (cmd) >>>
      
    • 插入模式:

        (ins) >>>
      

    根据 readline 的手册页(见下文),您还可以通过在 \1 和 \2 转义之间嵌入序列来指定不可打印的字符,例如终端控制序列字符。

    vi-cmd-mode-string ((cmd))
           This  string  is  displayed immediately before the last line of the primary prompt when vi editing mode is active and in command mode.  The value is expanded like a key binding, so the
           standard set of meta- and control prefixes and backslash escape sequences is available.  Use the \1 and \2 escapes to begin and end sequences of non-printing characters, which  can  be
           used to embed a terminal control sequence into the mode string.
    vi-ins-mode-string ((ins))
           This  string is displayed immediately before the last line of the primary prompt when vi editing mode is active and in insertion mode.  The value is expanded like a key binding, so the
           standard set of meta- and control prefixes and backslash escape sequences is available.  Use the \1 and \2 escapes to begin and end sequences of non-printing characters, which  can  be
           used to embed a terminal control sequence into the mode string.
    

    因此,在我的上述解决方案中,我在这些 \1 和 \2 转义字符之间嵌入了终端控制序列 \e[2 q(使光标成为竖线)和 \e[6 q(使光标成为管道) ,导致我的光标在命令模式下具有垂直条的形状,而在插入模式下具有管道形状。

    【讨论】:

    • 酷,谢谢!但是,我对这个解决方案有一个问题:当我将这 3 行放入 .inputrc 时,vim 中的光标(例如,当我编辑文件时)也会变为管道符号。我不希望这样 - 知道如何防止这种情况发生吗?
    • 由于某种原因我没有这个问题。我正在使用来自 Github 的NextJump/jarvis,在我的vimrc.local 文件中,我编写了let &t_SI = "\e[6 q" 等命令(请参阅原始问题描述)......也许添加它可以解决您的问题。跨度>
    • 谢谢,确实如此。
    • 这在 Windows 上的 Git Bash 中有效,但光标不闪烁,你知道如何启用闪烁吗?
    • 如果您想要闪烁,您可以尝试使用上述控制序列的闪烁版本。例如。闪烁块光标 = "\e[1 q", 闪烁下划线光标 = "\e[3 q", 闪烁竖条光标 = "\e[5 q"。
    【解决方案2】:

    这太棒了。我想补充一点,除了调整光标之外,还可以有文本模式状态消息。此代码有效:

    set show-mode-in-prompt on
    set vi-cmd-mode-string "\1\e[2 q\2cmd"
    set vi-ins-mode-string "\1\e[6 q\2ins"
    

    cmdins 将根据模式显示在提示的左侧。

    【讨论】:

      【解决方案3】:

      如果您想在其他程序运行之前将光标重置为正常,那么您可以使用环境变量PS0。来自man bash

      此参数的值在读取命令之后和执行命令之前被扩展(见下面的 PROMPING)并由交互式 shell 显示。

      使用此命令设置 PS0 将使其光标恢复到非闪烁块:

      PS0="\e[2 q"
      

      【讨论】:

        【解决方案4】:

        Alan Barnett 的回答:

        使用此命令设置 PS0 将使其光标恢复到非闪烁块:

        PS0="\e[2 q"

        解决了我的 Vim 问题,但我写的不是PS0="\e[2 q",而是PS0="\e[2 q\2"。 Alan 的回答不知何故在我的任何命令的终端输出中添加了 ]

        【讨论】:

          【解决方案5】:

          这就是我正在使用的,是的 unicode。唯一的缺点是,当您不运行 X 服务器时,unicode 会很糟糕! :-)

           set show-mode-in-prompt on
           set vi-ins-mode-string \1\e[34;1m\2└──[ins] \1\e[0m\2
           set vi-cmd-mode-string \1\e[33;1m\2└──[ cmd] \1\e[0m\2
          

          【讨论】:

            猜你喜欢
            • 2017-10-26
            • 1970-01-01
            • 1970-01-01
            • 2012-12-18
            • 2012-01-03
            • 1970-01-01
            • 1970-01-01
            • 2017-02-03
            • 2012-08-15
            相关资源
            最近更新 更多