我已将CtrlVmy映射.bash_profile
到一个使用 fzf 在 Vim 中打开文件的函数。它工作得很好,但是每当我退出 Python REPL 时,映射就不会工作,直到我获取我的.bash_profile
两次或启动一个全新的 shell 会话。
重现步骤:
使用这个最小的方法
.bash_profile
来重现问题:stty lnext ^- bind -x '"\C-v": "echo mapping works"'
启动 Bash 会话。
按CtrlV-> 查看输出
mapping works
。跑步
python3
。使用
exit()
或CtrlD退出 REPL。CtrlV返回到其默认行为。
source ~/.bash_profile
映射仍然不起作用?source ~/.bash_profile
现在CtrlV正确生成mapping works
,如何?
为什么启动/退出 Python REPL 会影响我的CtrlV映射(这不会发生在我的其他映射上)?为什么我需要两次获取我的个人资料才能使映射开始工作?
这是运行的示例输出stty -a | grep lnext
:
~ $ stty -a | grep lnext
lnext = <undef>; min = 1; quit = ^\; reprint = ^R; start = ^Q;
~ $ python3
Python 3.8.2 (v3.8.2:7b3ab5921f, Feb 24 2020, 17:52:18)
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> exit()
~ $ stty -a | grep lnext
eol2 = <undef>; erase = ^?; intr = ^C; kill = ^U; lnext = ^V;
~ $ source ~/.bash_profile
~ $ stty -a | grep lnext
lnext = <undef>; min = 1; quit = ^\; reprint = ^R; start = ^Q;
~ $ source ~/.bash_profile
~ $ stty -a | grep lnext
lnext = <undef>; min = 1; quit = ^\; reprint = ^R; start = ^Q;
以下是我的系统的一些信息,python3
来自 python.org 的安装程序和bash
Homebrew:
~ $ which python3
/usr/local/bin/python3
~ $ python3 --version
Python 3.8.2
~ $ which bash
/usr/local/bin/bash
~ $ bash --version
GNU bash, version 5.0.17(1)-release (x86_64-apple-darwin19.4.0)
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
~ $ sw_vers
ProductName: Mac OS X
ProductVersion: 10.15.5
BuildVersion: 19F101
以下是有关我的系统的更多信息:
~ $ echo $BASH_VERSION
5.0.17(1)-release
~ $ lsof -p $$
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 78982 eero cwd DIR 1,5 1568 359056 /Users/eero
bash 78982 eero txt REG 1,5 991320 4660332 /usr/local/Cellar/bash/5.0.17/bin/bash
bash 78982 eero txt REG 1,5 1568368 1152921500312627066 /usr/lib/dyld
bash 78982 eero 0u CHR 16,2 0t3107 985 /dev/ttys002
bash 78982 eero 1u CHR 16,2 0t3107 985 /dev/ttys002
bash 78982 eero 2u CHR 16,2 0t3107 985 /dev/ttys002
bash 78982 eero 255u CHR 16,2 0t3107 985 /dev/ttys002
~ $ /usr/local/bin/bash -li
~ $
答案1
我无法重现离开 REPL python 更改 lnext 的问题。
但我可以确认您需要两次获取文件才能使绑定密钥起作用( 的输出mapping works
)。
请注意,您需要启动一个记录bash 会话才能被.bash_profile
阅读。像这样的文件:
$ cat ~/.bash_profile
echo bash_profile read
#stty lnext ^-
stty lnext ''
仅当 bash 被调用时才有效bash -l
。只要检查你bash_profile read
启动 bash 时是否得到了。
解决方案:
最好的办法是在文件中设置键绑定~/.inputrc
:
$ cat ~/.inputrc
#bind -x '"\C-v": "echo mapping works"'
\C-v: "echo mapping works\C-m"
然后,可以使用 读取绑定Ctrl-x Ctrl-r
,不需要其他任何东西,一旦执行,键绑定就可以在 bash 中工作。并且,当 bash 启动时将会读取它。
如果您仍然需要删除相同的tty 中的键绑定:
$ cat ~/.bash_profile
echo bash_profile read
#stty lnext ^-
stty lnext ''
使用lnext ''
IME 的效果更加一致。需要时删除或注释回声。
添加
没有办法(完全)模仿bind -x
执行方式壳命令。
但什么是命令呢?只不过是一个以 Enter 结尾的字符串。
将其放在~/.inputrc
\C-v: "echo 'yes\!. It works.'\n"
重新读取~/.inputrc
文件并尝试\C-v
。
请注意,(IME)最好使用\C-m
.
如果您希望在键入命令之前清除该行,请使用
\C-v: "\C-e\C-x\C-?echo 'yes\!. It works.'\C-m\C-y"
但是,请记住,越复杂的绑定更有可能因未知原因而失败。只要尝试一下,也许它会对你有用。如果确实如此,与正常情况的唯一区别bind -x
是执行的命令会进入历史记录(恕我直言,没什么重要的)。
有关的:
答案2
@艾萨克的回答是正确的并且工作得很好,但最终的解决方案更加简单。我可以stty lnext ...
从我的中删除整行.bash_profile
,然后CtrlV映射就可以正常工作了。