如何分别映射Ctrl + A和Ctrl + Shift + A?


92

在终端中,无法区分Ctrl+ ACtrl+ Shift+,A因为它们都发出相同的键控代码,因此我可以理解为什么Vim无法做到这一点。但是gVim作为X应用程序可以区分Ctrl+ ACtrl+ Shift+ A。有没有办法以不同的方式映射这两件事?

首先,我想做以下事情:使“从剪贴板粘贴”像Gnome终端一样工作,同时保持Ctrl+ V处于可视模式。

:nmap <C-S-V> "+gP


3
@vivoconunxino该链接没有提及向ctrl-a添加shift修饰符。
graywh 2014年

Answers:


46

Gvim之所以不这样做,是因为vim无法做到(在正常情况下)。抱歉,就是这样。


然而...

某些终端(例如xterm和iterm2)可以配置为发送任意组合键的任意转义序列。

例如,下面添加到.Xresources为的xterm发送<Esc>[65;5uCtrlShiftA。然后可以在Vim中将其映射到<C-S-a>。(65是shift-a的十进制Unicode值,5是ctrl修饰符的位。在这种情况下,u表示“ unicode”。)

! .Xresources
XTerm*vt100.translations: #override Ctrl ~Meta Shift <Key>a: string(0x1b) string("[65;5u")

还可以将iTerm和[rxvt]配置为执行此操作(不提供示例)。

更多信息:http : //www.leonerd.org.uk/hacks/fixterms/


要重新映射多个键,请查看此文档:用分隔键条目\n。使用反斜线分割线。例如,也要映射<kbd> CSB </ kbd>和<kbd> CSF </ kbd>,请使用以下代码:XTerm*vt100.translations: #override Ctrl ~Meta Shift <Key>a: string(0x1b) string("[65;5u") \n Ctrl ~Meta Shift <Key>b: string(0x1b) string("[66;5u") \n Ctrl ~Meta Shift <Key>f: string(0x1b) string("[70;5u")
cfi

为了完整起见,也许还要在答案中添加如何在vi中对此进行映射?例如map <ESC>[66;5u :echo "ctrl-shift-b received"<CR>,映射ctrl-shift-b以在状态行中打印一条消息。在AskUbuntu上也有类似的问,我已经对此进行了总结
cfi

我们需要的是新的终端规范!xterm-256color(最近)遭受了太多限制。
杰罗姆Pouiller

@Jezz限制仅限于termcap本身,而不是的termcap文件xterm-256color
graywh 16/12/14

@graywh当然,新功能的termcap是必要的
杰罗姆Pouiller

9

如前所述,没有任何方法可以映射<C-S-A><C-A>

但是,使用autokey(对于Linux和Windows)或autohotkey(对于Windows)之类的工具,您可以重新映射<C-S-A>以针对特定应用程序发送不同的按键。

例如,在我的系统上,我在autokey以下位置有此设置:

$ cat ~/.config/autokey/data/gnome-terminal/ctrlshifta-gnome-terminal.py
#ctrl+shift+a sends '<S-F1>a'
keyboard.send_keys("<shift>+<f1>a") # Note that `f` in `f1` needs to be in lower case.

为其分配以下属性:

  1. 键盘快捷键为 ctrl+shift+a
  2. 窗口类: gnome-terminal-server.Gnome-terminal

然后,您~/.vimrc可以创建映射<S-F1>a以执行所需的任何操作。


笔记:

  1. 我已用作<S-F1>检测的领导钥匙<C-S>。这是因为我的终端不接受<F13>- <F37>等键。如果您的应用程序支持,(gvim我认为)建议使用这些键。
  2. 我主要vimgnome-terminal。所以我用作window class = gnome-terminal-server.Gnome-terminal过滤器。修改它以gvim在需要时使用。autokey支持用于捕获其他任何窗口属性(例如类/标题)的按钮。

谢谢堆。关于使用自动键进行键重映射有很多东西,但是没有如何使用它的实际说明。最后,您的答案就可以了。我不敢相信没有其他人支持您。
pickle323 '17

1
该死的汽车钥匙!我已尽我所能,但无法在Ubuntu 16.04上安装它。
yukashima huksay

apt install autokey-gtk
anishsane

1
在安装其他软件之前,您可能需要检查窗口管理器是否直接处理此问题。例如,在i3中,我的.config包含以下内容:bindsym --release Control+Shift+h exec --no-startup-id xdotool key --clearmodifiers comma w m h,wmh当我按下时按下<C-S-h>,然后vim知道如何处理,wmh
MatrixManAtYrService

^^这也很好。但是,我想将键转换限制为仅gnome-terminal或gvim。没有其他应用程序。<C-S-H>当我按此按钮时,其他应用程序应继续接收。
阿西珊(Anishsane)'18 -10-24


3

NeoVim现在为其终端和GUI客户提供此功能。参见:h nvim-features-new


3
除非您在终端中启用CSI代码,否则不完全是。Neovim开箱即用支持的CTRL-SHIFT变体大多是不可打印的字符(示例列在neovim.org/doc/user/vim_diff.html#nvim-features-new)。但是,和弦(包括<m-s-...>变体)大多数情况下确实是开箱即用的。
贾斯汀·凯斯

该文档说ALT (|META|) chords always work (even in the |TUI|). Map |<M-| with any key: <M-1>, <M-BS>, <M-Del>, <M-Ins>, <M-/>, <M-\>, <M-Space>, <M-Enter>, etc. Case-sensitive: <M-a> and <M-A> are two different keycodes.“区分大小写:”部分前有一个换行符,这使它变得模棱两可。感谢您的更正@ JustinM.Keyes。此外时,Vim 8.1出现之间进行区分<M-a><M-A>为好。
亚当·卡兹

@ justin-m-keyes <c-s-l>是与众不同的<c-l>Konsole没有任何额外的麻烦
Slava

3

由于键盘输入是在内部处理的,因此,即使在GVIM中,今天也很难实现这一点。某些键组合(例如Ctrl+非字母)无法映射,并且Ctrl+字母与Ctrl+ Shift+ +字母无法区分。(除非您的终端为此发送了一个不同的termcap代码,但大多数情况下不会这样做。)在插入或命令行模式下,尝试键入组合键。如果没有任何反应/未插入,则无法使用该组合键。这也适用于<Tab>/ <C-I><CR>/ <C-M>/ <Esc>/ <C-[>等(唯一的例外是<BS>/<C-H>。)这是一个已知的痛点,也是有关vim_dev和#vim IRC通道的各种讨论的主题。

有些人(最重要的是Paul LeoNerd Evans)想解决此问题(即使对于支持此功能的终端机中的控制台Vim),并提出了各种建议cp。http://groups.google.com/group/vim_dev/browse_thread/thread/626e83fa4588b32a/bfbcb22f37a8a1f8

但是到目前为止,还没有补丁或志愿者出现,尽管许多人表示希望在将来的Vim版本中使用它。


1

如前所述,您将获得相同的键码。因此,区分它们的唯一方法是检查Shift事件处理功能中键的状态。当然,如果您在按键和处理之间的延迟时间超过0.5秒,则会错过一些匹配。


1
我想我的问题的重点是,鉴于gvim能够做出这样的区分(即使普通的vim无法做到),我是否可以依靠任何gvim特定的扩展来区分Ctrl + Shift + V与Ctrl + V 。
川口浩辅

9
如何检查狗屎钥匙的状态?我进行了搜索,但没有发现任何有用的东西。
bolov
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.