如何在 VIM 中映射 CAPS LOCK 键?

Posted

技术标签:

【中文标题】如何在 VIM 中映射 CAPS LOCK 键?【英文标题】:How to map CAPS LOCK key in VIM? 【发布时间】:2011-01-11 16:52:01 【问题描述】:

我在 Windows 下使用 GVIM。 并想将 CAPSLOCK 映射到 Ctrl+^

有什么办法吗?

顺便说一句,我在网上看到大量示例如何使用注册表黑客交换 CAPS 和 Esc,但没有一个使用 VIM 映射命令,而是使用外部工具和注册表更改。

【问题讨论】:

我认为您应该在下面选择 Dan Andreatta 的答案。 在命令模式下意外按下大写锁定是我一天中最好的部分。 这个问题的几个旧答案建议使用 xmodmap 在 Linux 上映射 Caps Lock。但是,任何尝试在 2016 年执行此操作的人都应该使用 setxkbmap 命令,例如setxkbmap -option caps:escape。我在github.com/susam/uncap 有一个名为 Uncap 的小项目,它记录了所有这些,还为 Windows 提供了一个不显眼的小工具,将 Caps Lock 映射到 Escape。有关在 Linux 上使用 setxkbmap 的详细信息,请参阅 README 的 Alternatives 部分。 用于将CAPSLOCK 映射到CTRL(与其他键一起按下时)AND ESC(单独按下时)在 Windows 上,有一个不错的 SW (见下面的my answer)。 为 Linux 添加了一个解决方案,将 CAPSLOCK 映射到 CTRL AND ESC below 也是如此。 【参考方案1】:

Linux?对于 X,使用 xmodmap 更改键映射,例如

xmodmap -e 'clear Lock' -e 'keycode 0x42 = Escape'

将 Esc 映射到 CapsLock 键。谷歌了解更多示例。

【讨论】:

除了您说“Google 获取更多示例”而不是提供链接外,我会告诉您一点。每当有人这样做时,他们总是会出现在提到的 Google 结果的顶部:google.com/search?q=vim+remap+escape+capslock 在问题中明确指出,这(“注册表黑客”)是不可接受的。 喜欢这个技巧。但是当我的眼睛被大写锁定闪烁的 LED 分散注意力时,这很烦人。【参考方案2】:

如果您只是为了避免在 Vim 之外工作,您可以将这些行放在您的 .vimrc 中:

au VimEnter * !xmodmap -e 'clear Lock' -e 'keycode 0x42 = Escape'
au VimLeave * !xmodmap -e 'clear Lock' -e 'keycode 0x42 = Caps_Lock'

当您进入 Vim 时,第一行将转义映射到大写锁定键,当您退出时,第二行将正常功能返回到大写锁定。

这需要安装了 xorg-xmodmap 软件包的 Linux。

【讨论】:

您可以在!之前使用:silent进行修改,以避免press ENTER to continue提示。 要清楚,避免提示代码是au VimEnter * silent! !xmodmap -e 'clear Lock' -e 'keycode 0x42 = Escape'au VimLeave * silent! !xmodmap -e 'clear Lock' -e 'keycode 0x42 = Caps_Lock' 注意au是autocmd 在 .vimrc 中详细一点是件好事【参考方案3】:

对于 Mac OS,您可以在“系统偏好设置”中重新映射系统范围内的“大写锁定”键。

走这条路:

系统偏好设置 > 键盘 > 修饰键

然后点击“caps lock”旁边的下拉框并选择“^ Control”。

【讨论】:

它只会更改为控制。如何将其重新映射到 Esc 只需从下拉菜单中选择“Escape”即可:) 我认为该选项仅适用于 OS X 10.12【参考方案4】:

在窗户下?使用AutoHotkey。这不是 vim 映射,但正如其他人所说,您无法映射它。我使用 AHK 将我的 CAPSLOCK 映射到 CTRL。

【讨论】:

查看 Vim Tips wiki: Map caps lock to escape in Windows – AutoHotkey 中的示例 AutoHotkey 脚本。 在 Linux 下,Autokey 应用程序做同样的事情。应用程序页面在这里code.google.com/p/autokey,它有一个 ppa,可以在基于 debian 的发行版上轻松安装/更新。【参考方案5】:

在 Linux 系统中,这可以通过 xmodmap 完成。

将其保存在主文件夹中的文本文件中

! Swap caps lock and escape
remove Lock = Caps_Lock
keysym Escape = Caps_Lock
keysym Caps_Lock = Escape
add Lock = Caps_Lock

使用类似 .capstoescswitc 的名称保存此文件

然后通过终端执行这个文件。

xmodmap ~/.capstoescswitc 

如果要崇敬只需切换脚本文件中的关键变量即可。

更多信息请参考page

【讨论】:

小心,这个脚本每次执行都会交换Caps_LockEscape。请参阅上述 Vim wiki 页面中的 cmets。【参考方案6】:

Capslock(和 Control,以及 Shift 等)是一个修饰键,这意味着它与另一个普通键一起使用来修改该键的含义。 AFAIK 操作系统不会将修改键传递给应用程序,除非还按下了普通键,例如应用程序不会看到按下CTRL,但会看到CTRL-C

【讨论】:

不完全。应用程序完全有可能检测 ctrl、shift、alt 和 windows 按键。 Caps Lock 和 Num Lock 等键的问题在于操作系统坚持将它们解释为切换键。 那么你能用它在插入和命令模式之间切换吗?还是您的陈述暗示了我不知道的某些内容? 是的,如果您编写了本机应用程序,您可以在大多数操作系统中这样做。不幸的是,如果您编写的应用程序从另一个应用程序(例如在终端应用程序中运行的 vim 或在浏览器中运行的 JS 应用程序)获取输入,您只能获得本机包装器传递给您的键盘事件。旧终端没有现代键盘事件。我不知道有任何终端应用程序会传递按键事件以按下大写锁定键或任何其他修饰键 - 只有修饰符+其他键,并且只有 some 其中。因此,在实践中,您不能将 capslock 键本身映射到 vim 中的任何操作。【参考方案7】:

在 vim 之外不会破坏 Caps Lock 的解决方案

窗口

    安装自动热键。 运行自动热键脚本:
;caps_to_esc.ahk
#IfWinActive, ahk_class Vim ; vim window class
Capslock::Esc
#IfWinActive

Ubuntu

运行这个命令:

wget -O - https://raw.githubusercontent.com/grabantot/scripts/master/install/install_caps_to_esc.sh | bash

或手动执行这些操作:

    sudo apt-get install xdotool xbindkeys。我们还将使用xpropxset(应该默认安装)。 创建~/caps_to_esc.sh 脚​​本:
debug_file=/dev/shm/caps_to_esc.debug
debug_msg () 
  echo $(date +%s%3N) "$@" >> $debug_file


caps_off () 
  is_caps_on="false"
  xset q | grep "Caps Lock:\s*on" && is_caps_on="true"
  debug_msg "is_caps_on ""$is_caps_on"

  [ "$is_caps_on" == "false" ] && return 3
  debug_msg "Sending Caps Lock"
  debug_msg "ignore_next"
  xdotool key Caps_Lock


should_ignore="false"
tail -n 1 $debug_file | grep "ignore_next" && should_ignore="true"

if [ "$should_ignore" == "true" ]; then
  debug_msg "ignored"
  exit 1
fi

echo -n "" > $debug_file

# get wm_class by 'xprop | grep WM_CLASS'
declare -a wm_classes=( \
  'WM_CLASS(STRING) = "gnome-terminal-server", "Gnome-terminal"' \
  'WM_CLASS(STRING) = "gvim", "Gvim"' \
  'WM_CLASS(STRING) = "code", "Code"' \
  'WM_CLASS(STRING) = "google-chrome", "Google-chrome"' \
)

active_window_id=$(xdotool getactivewindow)
active_window_wm_class=$(xprop -id $active_window_id WM_CLASS)
debug_msg "active_wm_class   ""$active_window_wm_class"

detected_wm_class=""
for wm_class in "$wm_classes[@]"; do
  # debug_msg "$wm_class"
  if [ "$active_window_wm_class" == "$wm_class" ]; then
    detected_wm_class="$wm_class"
    debug_msg "detected_wm_class ""$detected_wm_class"
  fi
done

[ "$detected_wm_class" == "" ] && exit 2
xdotool keyup "Caps_Lock" # !!! very important
caps_off
debug_msg "Sending Escape"
xdotool key "Escape"
debug_msg "sent"
    添加新的绑定到~/.xbindkeysrc:
"bash $HOME/caps_to_esc.sh"
Caps_Lock
    killall xbindkeys && xbindkeys

工作原理:

    xbindkeys 将检测 Caps_Lock 按下并调用 caps_to_esc.sh 脚本 在脚本中通过xprop检测活动窗口wm_class 检查 wm_class 是否对我们感兴趣(gnome-terminal、vscode、gvim、chrome),如果不感兴趣则退出 通过xdotool发送退出键 通过xset检查Caps Lock是否开启,如果开启则通过xdotool发送Caps_Lock键 xbindkeys 会检测到我们发送的 Caps_Lock 但我们忽略它

【讨论】:

这太棒了。我在办公室的 Windows 上工作(不能破解注册表,但安装了 AHK);家里的Linux。这两个地方实际上只是一个 KVM,现在我有更多更好的键盘可供选择(不仅仅是价格超高的小众 G60 类型)。做得很好!【参考方案8】:

我不认为你可以。 我相信 CAPS-LOCK 可能在 vim 看到它之前由操作系统翻译。 因此,您需要在操作系统级别进行黑客攻击,就像您已经看到的注册表黑客一样。

编辑:自动热键看起来可以用于bridge the vim-OS gap。这样一来,第三方应用程序就在操作系统级别进行黑客攻击,而您只是在挂钩该应用程序。

【讨论】:

【参考方案9】:

由于有适用于 Linux 和 Windows 的解决方案(Autohotkey),我建议在 Mac 上使用 pckeyboardhack 重新映射 CapsLock。

【讨论】:

您可以使用系统偏好设置在 Mac OS 上重新映射大写锁定。有关详细信息,请参阅我的答案。【参考方案10】:

@rsoren's 的回答有效。但这样做的问题是,如果打开 多个 缓冲区,从一个缓冲区退出,也会恢复所有其他缓冲区的映射。用 BufEnter 和 BufLeave 替换 VimEnter 和 VimLeave,对我有用。

au BufEnter * silent! !xmodmap -e 'clear Lock' -e 'keycode 0x42 = Escape'
au BufLeave * silent! !xmodmap -e 'clear Lock' -e 'keycode 0x42 = Caps_Lock'

【讨论】:

另一种方法是将转义键重新映射到kj 通过将此行添加到.vimrc。 " esc in command mode cnoremap kj <C-C> " esc in insert mode inoremap kj <esc> 【参考方案11】:

在 Windows 上将 CAPSLOCK 重新映射为 ESCCTRL

如果您想将CAPSLOCK 重新映射到两者

    ESC(单独按下时) 到CTRL(与其他键一起按下时) 你可以使用this little piece of open source software by ililim

您不需要管理员权限,ESCCTRL 仍按预期工作。

我用它来享受方便的CTRL + anything 按压而不伤到我的小指,并在我通过 MobaXterm 中的 ssh 使用的 Vim 中切换模式。安装只需关注this description。

在 Linux 上将 CAPSLOCK 重新映射为 ESCCTRL

要在 Linux 上执行相同操作,您可以使用 XCAPE。要在 Ubuntu 上安装它,请使用:

sudo apt install xcape

对于实际的映射做:

setxkbmap -option ctrl:nocaps
xcape -e 'Control_L=Escape'

第一个命令是将CAPSLOCK 映射到ESC,而第二个命令处理CTRL 被其他键按下。

要让它在 X 会话中永久运行,您可以将其添加到 ~/.xprofile

【讨论】:

【参考方案12】:

我想这样做的原因之一是创建一个软大写锁定,就像其他人提到的那样,可能是为了避免在正常模式下保持大写锁定。 我使用vimcaps 插件在离开插入模式时关闭大写锁定,似乎工作正常。

【讨论】:

【参考方案13】:

在mac上,也可以使用Karabiner (https://pqrs.org/osx/karabiner/)

$ brew cask install karabiner-elements

安装后,您可以将 capslock 键映射到简单修改选项卡中的 esc 键。需要注意的是,这是系统范围的,这意味着您到处都丢失了 capslock 密钥。需要大写锁定的 IMO。

【讨论】:

【参考方案14】:

截至 2020 年,像我这样的普通 WINDOWS 用户的一个工作示例是使用 AutoHotkey

目前使用这个 1 行脚本:

Capslock::Esc

运行它,您的问题就解决了。希望能帮助到你。 :)

【讨论】:

【参考方案15】:

我自己完成了这个问题的答案,但我正在寻找一些稍微不同的东西:

    我正在使用 Linux 我很高兴更改 CAPS 即使在 Vim 之外(我几乎总是按错,而且我可以将它保持在 Esc 按钮上以实现我正在使用的目标) 我想尽可能使用最常用的软件,不需要任何进一步的安装 我更喜欢KISS,然后甚至避免需要更多冗长的脚本 如果可能,我希望同时拥有 CAPS -> EscCAPS + <something> -> Ctrl + <something>

那么我目前的解决方案是:

# ~/.xprofile
xmodmap $HOME/.xmodmap

和:

! ~/.xmodmap
clear lock
keycode 66 = Escape
keycode 9 = Caps_Lock
add lock = Caps_Lock

clear control
add control = Control_L Control_R Escape

看起来它暂时就像一个魅力,但我正在寻找反馈:)

【讨论】:

【参考方案16】:

对于 X (Linux),正如 @Dan Andreatta 提到的,使用 xmodmap 更改键映射,例如

xmodmap -e 'clear Lock' -e 'keycode 0x42 = Escape'

Esc 映射到 CapsLock 键。

您也可以通过将其添加到 X 初始化文件中来设置它,例如 .xinitrc — 当使用 startx 时运行 —:

clear lock
keycode 0x42 = Escape

通常,它被放在 .Xmodmap 文件中,然后在 .xinitrc 中运行。

Vim 的文档有一整页专门讨论这个主题,comments section 特别有用。

【讨论】:

以上是关于如何在 VIM 中映射 CAPS LOCK 键?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 Vim 中将 Esc 重新映射到 CAPS LOCK 如此复杂?

OSX:以编程方式重新映射 Caps Lock 的功能(通过系统偏好设置)?

我如何知道在 Dev-C++ 中 Caps Lock 是不是打开?

交换左Ctrl键和Caps lock键

Selenium webdriver怎么模拟键盘敲下Caps Lock键

是否可以通过编程方式禁用 Windows 上的 Caps Lock 键?