我正在寻找一个可以在终端中自动关闭括号和引号的工具。例如,当我输入
echo "
它应该自动扩展为
echo ""
并将光标放在中间。
这在 vim 和许多其他编辑器中已经可以实现,我也希望在终端中拥有同样的功能。
答案1
假设你的 shell 是 bash 并且你使用 emacs 编辑模式(set -o emacs
),这回答了你关于括号和双引号的问题。
为了解释那里发生了什么,这里有一个适用于{}
:
bind '"{" "\C-v{}\e[D"'
让我们来看看 的内部'
。在第一对中,"
我们有:
{
这很简单,它只是意味着用下面的内容替换左花括号。
第二对"
开始于:
\C-v{}
这里我们插入了左括号和右括号。我们需要这两个括号,因为我们要替换最初输入的内容,而不是追加内容。 是\C-v
一个Control-v字符,代表逐字插入 (终端键简史)。这样我们就可以插入{
而不会再次触发此绑定。最后,我们有:
\e[D
这只是左箭头键的转义代码,因此它将光标移动到括号之间。
答案2
如果在 bash 中使用 readline 的 vi 模式,则更好的方法是:
set editing-mode vi
set keymap vi-insert
"\C-b": backward-char
"(": "\C-v()\C-b"
"[": "\C-v[]\C-b"
"{": "\C-v{}\C-b"
"\"": "\C-v\"\C-v\"\C-b"
"\'": "\C-v\'\C-v\'\C-b"
答案3
我最终创建了如下五个 bash 脚本:
# terminal_autocomplete_brackets.sh
#!/bin/bash
myw=$(xdotool getactivewindow)
if [[ \
$(xprop -id ${myw} | egrep 'bash .* Konsole') || \
$(xprop -id ${myw} | egrep 'WM_CLASS.*Navigator.*Firefox') || \
$(xprop -id ${myw} | egrep 'WM_CLASS.*google-chrome') \
]]
then
xvkbd -xsendevent -text "[]\[Left]" >/dev/null 2>&1
else
xvkbd -xsendevent -text "[" >/dev/null 2>&1
fi
# terminal_autocomplete_curly.sh
#!/bin/bash
myw=$(xdotool getactivewindow)
if [[ \
$(xprop -id ${myw} | egrep 'bash .* Konsole') || \
$(xprop -id ${myw} | egrep 'WM_CLASS.*Navigator.*Firefox') || \
$(xprop -id ${myw} | egrep 'WM_CLASS.*google-chrome') \
]]
then
xvkbd -xsendevent -text "{}\[Left]" >/dev/null 2>&1
else
xvkbd -xsendevent -text "{" >/dev/null 2>&1
fi
# terminal_autocomplete_parentheses.sh
#!/bin/bash
myw=$(xdotool getactivewindow)
if [[ \
$(xprop -id ${myw} | egrep 'bash .* Konsole') || \
$(xprop -id ${myw} | egrep 'WM_CLASS.*Navigator.*Firefox') || \
$(xprop -id ${myw} | egrep 'WM_CLASS.*google-chrome') \
]]
then
xvkbd -xsendevent -text "()\[Left]" >/dev/null 2>&1
else
xvkbd -xsendevent -text "(" >/dev/null 2>&1
fi
# terminal_autocomplete_quotes.sh
#!/bin/bash
myw=$(xdotool getactivewindow)
if [[ \
$(xprop -id ${myw} | egrep 'bash .* Konsole') || \
$(xprop -id ${myw} | egrep 'WM_CLASS.*Navigator.*Firefox') || \
$(xprop -id ${myw} | egrep 'WM_CLASS.*google-chrome') \
]]
then
xvkbd -xsendevent -text "\"\"\[Left]" >/dev/null 2>&1
else
xvkbd -xsendevent -text "\"" >/dev/null 2>&1
fi
# terminal_autocomplete_squotes.sh
#!/bin/bash
myw=$(xdotool getactivewindow)
if [[ \
$(xprop -id ${myw} | egrep 'bash .* Konsole') || \
$(xprop -id ${myw} | egrep 'WM_CLASS.*Navigator.*Firefox') || \
$(xprop -id ${myw} | egrep 'WM_CLASS.*google-chrome') \
]]
then
xvkbd -xsendevent -text "''\[Left]" >/dev/null 2>&1
else
xvkbd -xsendevent -text "'" >/dev/null 2>&1
fi
然后您可以使用 xbindkeys 将“'[{(”绑定到这五个脚本中的每一个,效果很好。