AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 484764
Accepted
user938271
user938271
Asked: 2018-11-29 13:06:05 +0800 CST2018-11-29 13:06:05 +0800 CST 2018-11-29 13:06:05 +0800 CST

当 zle 小部件“edit-command-line”启动时,如何防止 Vim 将 Cj 翻译成 Cm?

  • 772

我的代码中有以下代码~/.zshrc:

autoload -Uz edit-command-line
zle -N edit-command-line
bindkey '^X^E' edit-command-line

它将edit-command-linezle 小部件绑定到 keysequence C-x C-e。该小部件在man zshcontrib(部分 ZLE FUNCTIONS,小节Widgets)中进行了描述:

edit-command-line 使用您的可视化编辑器编辑命令行,就像在 ksh 中一样。

          bindkey -M vicmd v edit-command-line

目的是能够编辑当前的 shell 命令行,在默认编辑器中,通过按C-x C-e,类似于 readline 函数edit-and-execute-command所做的(man bash, section READLINE, subsection Commands for Manipulating the History)。

edit-and-execute-command (C-xC-e) 在当前命令行调用编辑器,并将结果作为 shell 命令执行。Bash 尝试按顺序调用 $VISUAL、$EDITOR 和 emacs 作为编辑器。

我的默认编辑器是 Vim 8.1(包括补丁1-538)。我有 Vim 映射,使用键C-h, C-j, C-k, C-l, 将焦点移动到相邻窗口。它们可以归结为:

nnoremap <c-h> :<c-u>wincmd h<cr>
nnoremap <c-j> :<c-u>wincmd j<cr>
nnoremap <c-k> :<c-u>wincmd k<cr>
nnoremap <c-l> :<c-u>wincmd l<cr>

它们都在常规 Vim 实例中按预期工作(通过执行开始$ vim)。但是C-j当 Vim 由edit-command-line.

当我在 shell 命令行上按下C-x C-ewhile 时,zsh 会启动 Vim。如果我通过执行拆分窗口:split,然后按C-k移动到顶部窗口,我得到两个窗口,焦点移动到顶部。但是,如果我按下C-j返回底部窗口,则什么也不会发生。

我不知道这是否是问题的原因,但如果我尝试C-j在 Vim 缓冲区中插入一个文字(通过按C-v C-j),^M则会显示(回车符符号)。在一个常规的 Vim 实例中(通过执行 开始$ vim),插入一个字面值C-j会导致插入符号为^@(a NUL) 的字符。

我可以用这个最小值重现这个问题~/.zshrc:

export EDITOR=vim
autoload -Uz edit-command-line
zle -N edit-command-line
bindkey '^X^E' edit-command-line

这个最小的~/.vimrc:

nnoremap <c-j> :echom 'C-j has been pressed'<cr>

在 zsh 命令行上按下C-x C-e启动 Vim,然后按下C-j应该打印并记录消息:

C-j has been pressed

但什么也没有发生。

我无法在 bash 或 Neovim ( v0.3.2-752-g4d7c7f9) 中重现该问题。此外,在 Vim 中插入文字C-j,当后者在按下 后从 bash 启动时C-x C-e,会导致 NUL ( ^@)。在按下 后从 bash 或 zsh 启动 Neovim 时也是如此C-x C-e。

┌────────┬──────┬─────┐
│        │ bash │ zsh │
├────────┼──────┼─────┤
│ Vim    │ ^@   │ ^M  │
├────────┼──────┼─────┤
│ Neovim │ ^@   │ ^@  │
└────────┴──────┴─────┘

我想可能是某些 Vim 终端选项没有正确配置,所以我捕获了以下输出:

:set termcap

从 Vim 开始于$ vim,从 Vim 开始于C-x C-e。但是两种情况下的输出是相同的:

--- Terminal codes ---

  t_AL=^[[%p1%dL      t_DL=^[[%p1%dM      t_mr=^[[7m          t_se=^[[27m         t_us=^[[4m
  t_al=^[[L           t_dl=^[[M           t_ms=y              t_Sf=               t_ut=
  t_bc=               t_EC=               t_nd=^[[C           t_SH=               t_vb=^[g
  t_BE=               t_EI=^[[2 q         t_op=^[[39;49m      t_SI=^[[6 q         t_vi=^[[?25l
  t_BD=               t_fs=^G             t_RF=               t_Si=               t_VS=
  t_cd=^[[J           t_GP=               t_RB=               t_so=^[[7m          t_vs=^[[34l
  t_ce=^[[K           t_IE=               t_RC=               t_SR=^[[4 q         t_WP=
  t_cl=^[[H^[[J       t_IS=               t_RI=^[[%p1%dC      t_sr=^[M            t_WS=
  t_Ce=               t_ke=^[[?1l^[>      t_Ri=               t_ST=               t_xn=y
  t_Co=256            t_ks=^[[?1h^[=      t_RS=               t_Te=               t_xs=
  t_CS=               t_le=^H             t_RT=               t_Ts=               t_ZH=^[[3m
  t_CV=               t_mb=^[[5m          t_RV=               t_ts=^[]0;          t_ZR=^[[23m
  t_da=               t_md=^[[1m          t_Sb=               t_u7=               t_8f=
  t_db=               t_me=^[[0m          t_SC=               t_ue=^[[24m         t_8b=
  t_AB=^[[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m
  t_AF=^[[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m
  t_cm=^[[%i%p1%d;%p2%dH
  t_Cs=^[]12;%p1%s^G
  t_cs=^[[%i%p1%d;%p2%dr
  t_te=^[[2 q^[[?1004l^[[?1049l
  t_ti=^[[2 q^[[?1004h^[[?1049h
  t_ve=^[[34h^[[?25h

--- Terminal keys ---

t_#2 <S-Home>    ^[[1;2H   t_k6 <F6>        ^[[17~    t_kh <Home>      ^[[1~          <ð>        ^[p
t_#4 <S-Left>    ^[[1;2D   t_k7 <F7>        ^[[18~    t_kl <Left>      ^[OD           <ô>        ^[t
t_%i <S-Right>   ^[[1;2C   t_k8 <F8>        ^[[19~    t_kr <Right>     ^[OC           <õ>        ^[u
t_*7 <S-End>     ^[[1;2F   t_k9 <F9>        ^[[20~    t_ku <Up>        ^[OA           <ù>        ^[y
t_@7 <End>       ^[[4~     t_k; <F10>       ^[[21~         <á>        ^[a            <ú>        ^[z
t_F1 <F11>       ^[[23~    t_kB <S-Tab>     ^[[Z           <â>        ^[b            <Mouse>     ^[[M
t_F2 <F12>       ^[[24~    t_kD <Del>       ^[[3~          <ä>        ^[d            <S-F18>     ^[[O
t_k1 <F1>        ^[OP      t_kI <Insert>    ^[[2~          <å>        ^[e            <S-F19>     ^[[I
t_k2 <F2>        ^[OQ      t_kN <PageDown>  ^[[6~          <æ>        ^[f            <xUp>       ^[[1;*A
t_k3 <F3>        ^[OR      t_kP <PageUp>    ^[[5~          <ç>        ^[g            <xDown>     ^[[1;*B
t_k4 <F4>        ^[OS      t_kb <BS>        ^?             <í>        ^[m            <xLeft>     ^[[1;*D
t_k5 <F5>        ^[[15~    t_kd <Down>      ^[OB           <î>        ^[n            <xRight>    ^[[1;*C

bash 和 zsh的输出$ stty -a也是相同的:

speed 38400 baud; rows 33; columns 119; 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

我正在使用zsh 5.6.2-dev-1 (x86_64-pc-linux-gnu).

是否应该设置 Vim 或 zsh 选项以防止 Vim在由 zle 小部件启动时转换C-j为?C-medit-command-line

zsh vim
  • 1 1 个回答
  • 229 Views

1 个回答

  • Voted
  1. Best Answer
    Stéphane Chazelas
    2018-12-03T03:01:41+08:002018-12-03T03:01:41+08:00

    如果你将你设置$EDITOR为一个脚本或函数stty -a,你会注意到当时的终端设置被 zlevim调用(其中导致终端设备驱动程序将 NL 转换为 CR 是在其他事情中) .edit-command-lineinlcr

    ^J是换行符,所以绑定它有点微妙。

    vim在这里,您可以通过将函数定义为以下方式来解决它:

    vim() STTY=sane command vim "$@"
    

    或者添加编辑STTY=sane(或STTY=-inlcr)到edit-command-line.

    • 3

相关问题

  • 什么情况下路径中最先找到的可执行文件不会被使用

  • 符号链接所有点文件和目录

  • 将默认编辑器更改为 vim for _ sudo systemctl edit [unit-file] _

  • 如何在`zsh`中增加一个动态命名的变量

  • 为什么我不能在 zsh 中定义一个名为 path 的只读变量?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    ssh 无法协商:“找不到匹配的密码”,正在拒绝 cbc

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    如何卸载内核模块“nvidia-drm”?

    • 13 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add 返回:“连接代理时出错:没有这样的文件或目录” 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve