Jos*_*ley 4 bash command-line prompt readline inputrc
我在 bash 中使用 vi 编辑模式。我在 ~/.inputrc 中将“show-mode-in-prompt”设置为“on”。
显示模式提示(关闭)
如果设置为 On,则在提示开头添加一个字符串,指示编辑模式:emacs、vi 命令或 vi 插入。模式字符串是用户可设置的(例如,emacs-mode-string)。
所以现在我可以在我的提示开头看到编辑模式。
i:$ # This is ins mode
c?$ # This is cmd mode
i:$ cat ~/.inputrc
set editing-mode vi
set show-mode-in-prompt on
set vi-ins-mode-string "\1\e[1;32m\2i:\1\e[0m\2"
set vi-cmd-mode-string "\1\e[1;31m\2c?\1\e[0m\2"
set colored-stats on
i:$ echo $PS1
$
Run Code Online (Sandbox Code Playgroud)
不过,我真的很喜欢在我的提示末尾添加这个,并在当前目录前面加上,即
/current/dir/here $ i:
Run Code Online (Sandbox Code Playgroud)
但我不确定这是否可以实现。我的第一个想法是在 PS1 中使用回车,但不幸的是这会覆盖模式字符串。
i:$ PS1='\r\w $ '
~/projects $
Run Code Online (Sandbox Code Playgroud)
我的第二个想法是以某种方式获取模式字符串并将其插入 $PROMPT_COMMAND,而不是让 readline 将其写入提示。我可以通过以下方式获取当前模式:
i:$ bind -v | grep keymap | awk '{print $3}'
vi-insert
Run Code Online (Sandbox Code Playgroud)
但是 PROMPT_COMMAND 值仅在发出提示之前执行,因此我不会看到模式更改。
第 3 次尝试包括填充我的模式字符串,以便为目录留出空间。这可以工作,但我不知道如何使空间量可变。此外,提示将在模式字符串之前开始,模式字符串将被我的命令覆盖,如果我切换模式,我输入的文本将被整个模式字符串替换,由于空格而有效地将其清除。
i: cat ~/.inputrc
set editing-mode vi
set show-mode-in-prompt on
set vi-ins-mode-string " \1\e[1;32m\2i:\1\e[0m\2"
set vi-cmd-mode-string " \1\e[1;31m\2c?\1\e[0m\2"
set colored-stats on
i: PS1="\r\w $ "
~/projects $ i:
~/projects $ # typing stuff i:
~/projects $ # typing more stuff overwrites the mode line
~/projects $ c?verwrites the mode line
Run Code Online (Sandbox Code Playgroud)
有没有其他聪明的方法来做到这一点?也许像回车这样的控制字符跳到行首但不覆盖现有字符?
i:$ echo $BASH_VERSION
5.0.7(1)-release
Run Code Online (Sandbox Code Playgroud)
您可以通过为 cmd 和插入模式设置一个很长的模式字符串来实现这一点,其中包括您想要的提示中的其他项目。请注意,这意味着您将无法使用 PS1 中可用的特殊快捷方式,例如\w“漂亮”打印当前目录。但是您可能可以在执行相同操作的 shell 代码中实现相同的功能。
您可以使用bind "set vi-ins-mode-string \"...\""和bind "set vi-cmd-mode-string \"...\""命令设置 readline 变量。(help bind有关更多详细信息,请参阅。)并且您可以从您的 中进行设置PROMPT_COMMAND,以便在每次提示之前将其重置(因此如果您包含它们,它将反映目录、日期和时间的更改等)
引用可能会变得棘手:-)
对于您自己使用的示例:
/current/dir/here $ i:
Run Code Online (Sandbox Code Playgroud)
你可以用这个:
reset_readline_prompt_mode_strings () {
bind "set vi-ins-mode-string \"$PWD \$ \1\e[1;32m\2i:\1\e[0m\2\""
bind "set vi-cmd-mode-string \"$PWD \$ \1\e[1;31m\2c?\1\e[0m\2\""
}
PROMPT_COMMAND=reset_readline_prompt_mode_strings
PS1=' '
Run Code Online (Sandbox Code Playgroud)
如前所述, 的扩展$PWD将包括完整路径,并且不会使用来自~等的相对路径。
通过使用 bash 的运算符扩展,您可以获得与提示中使用的相同的${variable@P}扩展:
EMBEDDED_PS1='\w $ '
reset_readline_prompt_mode_strings () {
bind "set vi-ins-mode-string \"${EMBEDDED_PS1@P}\1\e[1;32m\2i:\1\e[0m\2\""
bind "set vi-cmd-mode-string \"${EMBEDDED_PS1@P}\1\e[1;31m\2c?\1\e[0m\2\""
}
Run Code Online (Sandbox Code Playgroud)
请注意,您需要PS1设置为非空的内容,否则根本不会打印任何提示。在这种情况下,您可以使用单个空格。您可能需要考虑PS2适当地设置行延续。
顺便说一句,我对ins和cmd模式字符串的符号和颜色的建议是:
cmd应该使用:(与您可以:在 Vim 的正常模式下键入命令相同)并且应该使用绿色(因为这是“正常”模式状态行中的lightline设置的默认颜色。)ins应该使用+(这是 Vim 用来显示缓冲区被修改的符号,当你插入时,你修改它)并且应该使用蓝色(在“插入”模式的状态行中,lightline使用的默认颜色。)就个人而言,我认为以下这些很酷:
EMBEDDED_PS1='\w $ '
reset_readline_prompt_mode_strings () {
bind "set vi-ins-mode-string \"${EMBEDDED_PS1@P}\1\e[32m\2: >\1\e[92m\2>\1\e[0m\2>\""
bind "set vi-cmd-mode-string \"${EMBEDDED_PS1@P}\1\e[34m\2+ >\1\e[94m\2>\1\e[0m\2>\""
}
PROMPT_COMMAND=reset_readline_prompt_mode_strings
PS1=' '
PS2=' ... '
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
937 次 |
| 最近记录: |