我正在尝试创建一个小的 Python/curses 应用程序。
但据我所知,没有办法判断 CTRL+J是否Enter被按下。现在这可能是因为它们都具有相同的 ascii 代码 (10):
http://en.wikipedia.org/wiki/Control_character#In_ASCII
但是 VIM 是如何区分这两者的呢?
我正在尝试创建一个小的 Python/curses 应用程序。
但据我所知,没有办法判断 CTRL+J是否Enter被按下。现在这可能是因为它们都具有相同的 ascii 代码 (10):
http://en.wikipedia.org/wiki/Control_character#In_ASCII
但是 VIM 是如何区分这两者的呢?
Enter通常等于 Cm。但是,如果icrnl
tty 的标志是活动的(请参阅stty -a
),那么输入的 Cm 将自动转换为 Cj(因此只需按 即可轻松键入 Unix-ly 终止的行Enter)。
在纯 C 语言中,您可以使用termios函数tcgetattr(3)和tcsetattr(3)来取消设置 ICRNL 标志,c_iflag
以便 Cm 在输入时不会转换为 Cj。如果您想对输入和输出进行绝对控制,您将使用“原始”模式(禁用所有输入和输出处理)。看起来Python 有这些termios函数。
curses 库有一些用于处理 tty 模式的高级函数:savetty(3)、resetty(3)、nonl(3)、raw(3)、cbreak(3)等。看起来Python 也有这些curses功能。
如果您正在使用curses库的其他位,那么最好也使用它的函数来调整 ICRNL 标志(例如nonl(3))以避免破坏库所做的任何假设(即它假设 tty 是设置一种方式,但是您的termios级别调用会改变事情并打破该假设)。
我不认为<ctrl-J>
和Enter
相同。在 vim 中,<ctrl-j>
有 keycode 10,但Enter
有 13。
有一些等效的键,例如
<ctrl-M> and Enter
<ctrl-H> and backspace
<ctrl-[> and ESC
...
无论您处于哪种模式,您都可以在您的 vim 中进行测试,<ctrl-M>
并做同样的事情。Enter
<Enter>
其实还有一个组合键,用and也很难区分<Ctrl-M>
。就是<C-Enter>
不知道你想达到什么目的,你说你想做一些终端开发(ncurses),如果终端连那些键都分辨不出来,你就别管了。我没有ncurses的经验,如果我错了不要生气。^_^
如果您键入:h keycodes
您可以看到更多信息,下表是从 vim 帮助中复制的。
notation meaning equivalent decimal value(s) ~
-----------------------------------------------------------------------
<Nul> zero CTRL-@ 0 (stored as 10) *<Nul>*
<BS> backspace CTRL-H 8 *backspace*
<Tab> tab CTRL-I 9 *tab* *Tab*
*linefeed*
<NL> linefeed CTRL-J 10 (used for <Nul>)
<FF> formfeed CTRL-L 12 *formfeed*
<CR> carriage return CTRL-M 13 *carriage-return*
<Return> same as <CR> *<Return>*
<Enter> same as <CR> *<Enter>*
<Esc> escape CTRL-[ 27 *escape* *<Esc>*
<Space> space 32 *space*
<lt> less-than < 60 *<lt>*
<Bslash> backslash \ 92 *backslash* *<Bslash>*
<Bar> vertical bar | 124 *<Bar>*
<Del> delete 127
<CSI> command sequence intro ALT-Esc 155 *<CSI>*
<xCSI> CSI when typed in the GUI *<xCSI>*
<C-J>
等价于<NL>
,而不是<CR>
(对应于<C-M>
):
:echo "\<C-J>" ==# "\<CR>"
0
:echo "\<C-J>" ==# "\<NL>"
1
所以你的假设是错误的;甚至 Vim 也无法区分它们。由于键盘输入在内部处理的方式,并且由于终端及其 API 的悠久而复杂的历史,很难区分这些键,尽管(在大多数现代终端仿真器中),这在今天是可能的。
有些人(最重要的是 Paul LeoNerd Evans)想要解决 Vim 中的问题,并提出了各种建议,cp。http://groups.google.com/group/vim_dev/browse_thread/thread/626e83fa4588b32a/bfbcb22f37a8a1f8
但是截至今天,还没有补丁或志愿者出现,尽管许多人表示希望在未来的 Vim 8 主要版本中拥有它。我不知道如何在 Python 中解决这个问题,但您可能会从链接的讨论中找到一些见解。