【问题标题】:How to map Ctrl+A and Ctrl+Shift+A differently?如何以不同方式映射 Ctrl+A 和 Ctrl+Shift+A?
【发布时间】:2010-12-03 04:01:44
【问题描述】:

在终端中,无法区分 Ctrl+ACtrl+Shift+A 因为它们都发出相同的密钥代码,所以我明白为什么 Vim 不能这样做。但是 gVim 作为 X 应用程序,可以区分 Ctrl+ACtrl+Shift+A 。有什么方法可以不同地映射这两个东西吗?

对于初学者,我想做如下的事情:让“从剪贴板粘贴”像 Gnome 终端一样工作,同时保持 Ctrl+V 到可视化模式。

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

【问题讨论】:

标签: vim key-bindings


【解决方案1】:

Gvim 不这样做是因为 vim 不能这样做(在正常情况下)。对不起,但就是这样。


不过……

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

例如,将以下内容添加到.Xresources for xterm 以发送&lt;Esc&gt;[65;5u for CtrlShiftA。然后,您可以在 Vim 中将其映射到 &lt;C-S-a&gt;。 (65 是 shift-a 的十进制 Unicode 值,5 是 ctrl 修饰符的位。在这种情况下,u 代表“unicode”。)

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

iTerm 和 [u]rxvt 也可以配置为执行此操作(未提供示例)。

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

【讨论】:

  • 要重新映射多个键,请查看this document:用\n 分隔键条目。使用反斜杠分割行。例如。也映射 C-S-BC-S-F 使用这个:XTerm*vt100.translations: #override Ctrl ~Meta Shift &lt;Key&gt;a: string(0x1b) string("[65;5u") \n Ctrl ~Meta Shift &lt;Key&gt;b: string(0x1b) string("[66;5u") \n Ctrl ~Meta Shift &lt;Key&gt;f: string(0x1b) string("[70;5u")
  • 为了完整起见,也许还可以添加到答案中,如何在 vi 中映射它?例如。 map &lt;ESC&gt;[66;5u :echo "ctrl-shift-b received"&lt;CR&gt; 映射 ctrl-shift-b 以在状态行中打印一条消息。在 AskUbuntu 上也有类似的问题,我 summarizedthis。
  • 如果你摸不着头脑:我在这个答案的启发下写了一个更详细、更完整的问答,并附有几个例子。 unix.stackexchange.com/q/631241
【解决方案2】:

正如已经指出的,没有办法将&lt;C-S-A&gt;&lt;C-A&gt; 不同地映射。

但是,使用 autokey(适用于 linux 和 windows)或 autohotkey(适用于 windows)之类的工具,您可以重新映射 &lt;C-S-A&gt; 以针对特定应用程序发送不同的击键。

例如在我的系统上,我在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 可以为&lt;S-F1&gt;a 创建映射来做任何你想做的事情。


注意事项:

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

【讨论】:

  • 非常感谢。那里有很多关于使用 Autokey 进行键重映射的内容,但没有关于如何执行此操作的实际说明。最后你的答案做到了。我不敢相信没有人支持你。
  • 该死的自动键!我已尽我所能,但无法在我的 ubuntu 16.04 上安装它。
  • apt install autokey-gtk ?
  • 在安装额外的软件之前,您可能会检查您的窗口管理器是否直接处理这个问题。例如,在 i3 中我的 .config 有这个:bindsym --release Control+Shift+h exec --no-startup-id xdotool key --clearmodifiers comma w m h,当我按下 &lt;C-S-h&gt; 时按下 ,wmh,然后 vim 知道如何处理 ,wmh
  • ^^ 这也不错。但是,我想将键翻译限制为仅 gnome-terminal 或 gvim。不是其他应用程序。当我按下它时,其他应用程序应该会继续收到&lt;C-S-H&gt;
【解决方案3】:

由于键盘输入是在内部处理的,遗憾的是,即使在 GVIM 中,这在今天通常也是不可能的。某些组合键,如 Ctrl + 非字母无法映射,Ctrl + 字母 vs. Ctrl + Shift + 字母无法区分。 (除非您的终端为它发送一个独特的 termcap 代码,但大多数情况下不会。)在插入或命令行模式下,尝试键入组合键。如果没有任何反应/插入,则不能使用该组合键。这也适用于&lt;Tab&gt;/&lt;C-I&gt;&lt;CR&gt;/&lt;C-M&gt;/&lt;Esc&gt;/&lt;C-[&gt; 等(唯一的例外是&lt;BS&gt;/&lt;C-H&gt;。)这是一个已知的痛点,并且vim_dev 和#vim IRC 频道上各种讨论的主题。

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

但截至今天,还没有补丁或志愿者出现,尽管许多人表示希望在未来的 Vim 版本中提供此功能。

【讨论】:

    【解决方案4】:

    如果困扰您的是失去现有的 C-V 功能,您可以改用 C-Q。看,:help CTRL-V-alternative。

    【讨论】:

      【解决方案5】:

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

      【讨论】:

      • 不完全是,除非您在终端中启用 CSI 代码。 Neovim 确实 支持开箱即用的 CTRL-SHIFT 变体大多是不可打印的字符(在neovim.org/doc/user/vim_diff.html#nvim-features-new 中列出的示例)。然而,meta 和弦(包括&lt;m-s-...&gt; 变体)do 大多是完全开箱即用的。
      • 那个文件说ALT (|META|) chords always work (even in the |TUI|). Map |&lt;M-| with any key: &lt;M-1&gt;, &lt;M-BS&gt;, &lt;M-Del&gt;, &lt;M-Ins&gt;, &lt;M-/&gt;, &lt;M-\&gt;, &lt;M-Space&gt;, &lt;M-Enter&gt;, etc. Case-sensitive: &lt;M-a&gt; and &lt;M-A&gt; are two different keycodes.在“区分大小写:”部分之前有一个换行符,这使得这个模棱两可。感谢您的更正,@JustinM.Keyes。此外,vim 8.1 似乎也区分了 &lt;M-a&gt;&lt;M-A&gt;
      • @justin-m-keyes &lt;c-s-l&gt;Konsole 中的&lt;c-l&gt; 完全不同,没有任何额外的麻烦
      • 第一条评论的更正网址:neovim.io/doc/user/vim_diff.html#nvim-features
      【解决方案6】:

      正如您所指出的,您会得到相同的密钥代码。因此,区分它们的唯一方法是检查事件处理函数中 Shift 键的状态。当然,如果你在按键和处理之间有超过 0.5 秒的延迟,你会错过一些点击。

      【讨论】:

      • 我想我的问题的重点是,鉴于 gvim 能够做出这样的区分(即使普通 vim 不能),是否有任何特定于 gvim 的扩展可以用来区分 Ctrl +Shift+V 与 Ctrl+V。
      • 如何查看Shit键的状态?我搜索了,但没有找到任何有用的东西。
      【解决方案7】:

      默认情况下,大多数终端仿真器将控制和移位简单地视为控制。相反,您通常会将这些组合键映射到转义序列,然后在终端应用程序中进行监听。

      第 1 步: 配置终端模拟器以将 Ctrl+Shift+A 绑定到序列 Esc,A.

      您的终端模拟器是显示终端实际窗口的程序。通过 SSH 访问服务器时,终端仿真器是本地计算机上的程序。绑定键在不同的终端仿真器中的工作方式不同。例如:

      • 对于 urxvt,将 URxvt.keysym.Control-Shift-A: \033A 添加到 ~/.Xresources 配置文件并使用 xrdb ~/.Xresources 重新加载。
      • 对于 iTerm2,打开 Preferences -> Keys,添加一个条目,然后将 Ctrl+Shift+A 绑定到“Send Escape”操作序列”并在下面的字段中输入A

      步骤 2:Esc,A 绑定到 Vim 中的命令。

      将键映射添加到您的~/.vimrc 配置并使用:source ~/.vimrc 重新加载:

      nnoremap <esc>a your command here
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-11
        • 2011-06-04
        • 1970-01-01
        • 2019-10-17
        • 2014-06-01
        • 2013-01-01
        • 1970-01-01
        • 2023-01-01
        相关资源
        最近更新 更多