![Ctrl-J 的特殊处理](https://linux22.com/image/200676/Ctrl-J%20%E7%9A%84%E7%89%B9%E6%AE%8A%E5%A4%84%E7%90%86.png)
当我Ctrl-V Ctrl-J在 shell 中按下(在 下urxvt
)时,它会开始一个新行(将光标定位在新行的开头),而不是打印^J
。
里面vim
印着^@
。
在虚拟控制台中也有同样的情况。
显然有一些预处理Ctrl-J。它是什么?我如何影响它?
$ stty -a
speed 38400 baud; rows 26; columns 101; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk brkint ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc -ixany imaxbel iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke -flusho -extproc
$ echo $TERM
rxvt-unicode-256color
$ urxvt --help |& head -1
rxvt-unicode (urxvt) v9.26 - released: 2021-05-14
UPD我正在配置tmux
,这种行为让我认为这bind-key C-j send-keys C-j
是行不通的。
答案1
Bash中的cv是通过readline处理的:
$ bind -p | grep '"\\C-v":'
"\C-v": quoted-insert
正如 readline(3) 中所解释的:
quoted-insert (C-q, C-v)
Add the next character that you type to the line verbatim. This
is how to insert characters like C-q, for example.
您可以使用 Cv 插入其他字符,例如 Cv Ci 将插入制表符。要知道哪个字母产生给定的字符 open
man ascii
:
Oct Dec Hex Char Oct Dec Hex Char
────────────────────────────────────────────────────────────────────────
000 0 00 NUL '\0' (null character) 100 64 40 @
001 1 01 SOH (start of heading) 101 65 41 A
002 2 02 STX (start of text) 102 66 42 B
003 3 03 ETX (end of text) 103 67 43 C
004 4 04 EOT (end of transmission) 104 68 44 D
005 5 05 ENQ (enquiry) 105 69 45 E
006 6 06 ACK (acknowledge) 106 70 46 F
007 7 07 BEL '\a' (bell) 107 71 47 G
010 8 08 BS '\b' (backspace) 110 72 48 H
011 9 09 HT '\t' (horizontal tab) 111 73 49 I
012 10 0A LF '\n' (new line) 112 74 4A J
013 11 0B VT '\v' (vertical tab) 113 75 4B K
014 12 0C FF '\f' (form feed) 114 76 4C L
015 13 0D CR '\r' (carriage ret) 115 77 4D M
正如您所看到的,J 与新行在同一行,I 与水平制表符在同一行。
您可以使用其他示例来检查自己,例如会产生铃声的 Cv Cg:
$ printf ^G| hexdump -C
00000000 07 |.|
00000001
答案2
正如 Arkadiusz Drabczyk 所说,readline
负责处理C-v
.特别C-v C-j
。它只是把手他们不同地。据说是因为C-j
( Enter
) 可以以有意义的方式表示,无需符号^*
。该符号中的字母是通过以下方式获得的或'ing0x40
如果您好奇的话,可以查看字符代码。或者你可能会说,0x01
对应于^A
、0x02
到^B
,等等。
至于vim
(^@
)也是这样代表换行符。文档中有几处提到:
您还可以使用
<NL>
与 相同的方式分隔命令'|'
。要插入一个<NL>
使用CTRL-V CTRL-J
."^@"
将显示。
https://github.com/vim/vim/blob/v8.2.4027/runtime/doc/cmdline.txt#L652-L653
NL 用于 Nul
技术细节:<Nul>
文件中的字符存储<NL>
在内存中。在显示屏中它们显示为"^@"
。翻译是在读写文件时完成的。要将 a 与搜索模式匹配,<Nul>
您只需输入CTRL-@
或"CTRL-V 000"
。这可能正是您所期望的。在内部,该字符<NL>
在搜索模式中被替换为 a 。不寻常的是,键入CTRL-V CTRL-J
还会插入 a ,因此也会 在文件中<NL>
搜索 a 。<Nul>
https://github.com/vim/vim/blob/v8.2.4027/runtime/doc/pattern.txt#L1273-L1280
可能它与将空字节存储为内存中的换行符有关。