Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何根据Bash中的VI模式更改光标形状?_Bash_Terminal_Xterm - Fatal编程技术网

如何根据Bash中的VI模式更改光标形状?

如何根据Bash中的VI模式更改光标形状?,bash,terminal,xterm,Bash,Terminal,Xterm,我的.bashrc中有以下行: set -o vi 当我处于插入模式时,我希望我的光标有一个管道形状,当我处于命令模式时,光标有一个块形状,就像我在我的.vimrc中放置以下内容时,我在Vim中会看到的一样: let &t_SI = "\e[6 q" let &t_SR = "\e[4 q" let &t_EI = "\e[2 q" 除了在这种情况下,我希望在命令行上有相同的行为。 我在这里找到了我问题的部分答案- -作者@gogolb 以下是答案: #!/bin

我的.bashrc中有以下行:

set -o vi
当我处于插入模式时,我希望我的光标有一个管道形状,当我处于命令模式时,光标有一个块形状,就像我在我的.vimrc中放置以下内容时,我在Vim中会看到的一样:

let &t_SI = "\e[6 q"
let &t_SR = "\e[4 q"
let &t_EI = "\e[2 q"
除了在这种情况下,我希望在命令行上有相同的行为。

我在这里找到了我问题的部分答案- -作者@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会话内部和外部工作


解决方案

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


别担心,解决方案不需要任何修补。;)

解决方案:

我把我自己的问题的答案贴在这里

此解决方案适用于Bash 4.4+,因为从该版本的Bash开始,使用了GNU readline库的7.0版本,其中包括必要的
vi cmd mode string
vi 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 string
vi ins mode string
,与命令提示符一起打印到您的终端,以便提供一种视觉指示器,指示您当前处于哪种模式(即命令模式与插入模式)

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

  • 命令模式:

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

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

vi cmd模式字符串((cmd))
当vi编辑模式处于活动状态且处于命令模式时,此字符串显示在主提示的最后一行之前。该值像键绑定一样展开,因此
标准的元前缀和控件前缀以及反斜杠转义序列集是可用的。使用\1和\2转义符开始和结束非打印字符的序列,这些字符可以是
用于将终端控制序列嵌入模式字符串中。
vi ins模式字符串((ins))
当vi编辑模式处于活动状态且处于插入模式时,此字符串显示在主提示的最后一行之前。该值像键绑定一样展开,因此
标准的元前缀和控件前缀以及反斜杠转义序列集是可用的。使用\1和\2转义符开始和结束非打印字符的序列,这些字符可以是
用于将终端控制序列嵌入模式字符串中。

因此,在我的上述解决方案中,我嵌入了终端控制序列,
\e[2 q
(将光标设置为竖条)和
\e[6 q
(将光标设置为管道),在这些\1和\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"

cmd
ins
将根据模式显示在提示符的左侧。

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

此参数的值在读取命令后和执行命令前由交互式Shell展开(请参见下面的PROMPING)并显示

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

PS0="\e[2 q"

这就是我正在使用的,是的,unicode。唯一的缺点是,当你没有运行X服务器时,unicode被破坏了!:-)


你应该让你的解决方案成为一个答案我该怎么做?在下面的问题中添加一个答案,然后在等待的时间之后(我想是一天左右)你可以接受它作为你问题的答案。你的解决方案帮了我的忙,所以我很想用一种恶作剧的方式向你扔一些假互联网点。:-)酷,谢谢!但是,这个解决方案有一个问题:当我把这3行代码放入
.inputrc
,vim中的光标(比如,当我编辑文件时)对管道符号也进行了更改。我不想这样-知道如何防止这种情况发生吗?我没有这个问题,因为某种原因。我正在使用Github的
NextJump/jarvis
,在我的
vimrc.local
文件中,我编写了
let&t_SI=“\e[6 q”
等命令(请参阅原始问题描述)…也许添加它可以解决您的问题。谢谢,确实如此。这在Windows上的Git Bash中有效,但光标不闪烁,您知道如何启用闪烁吗?如果您想要闪烁,可以尝试使用上述控制序列的闪烁版本。例如,闪烁b
 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