繁体   English   中英

如何在 VIM 中映射 CAPS LOCK 键?

[英]How to map CAPS LOCK key in VIM?

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

有没有办法做到这一点?

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

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

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

将 Esc 映射到 CapsLock 键。 谷歌获取更多示例。

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

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

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

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

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

按照这个路径:

系统首选项 > 键盘 > 修饰键

然后单击“大写锁定”旁边的下拉框并选择“^ 控制”。

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

在 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 

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

有关更多信息,请参阅此页面

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

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

视窗

  1. 安装自动热键。
  2. 运行自动热键脚本:
;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

或者手动执行这些操作:

  1. sudo apt-get install xdotool xbindkeys 我们还将使用xpropxset (应该默认安装)。
  2. 创建一个~/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"
  1. 将新的 bindnig 添加到~/.xbindkeysrc
"bash $HOME/caps_to_esc.sh"
Caps_Lock
  1. killall xbindkeys && xbindkeys

这个怎么运作:

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

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

编辑: autohotkey 看起来可以用来弥合 vim-OS gap 通过这种方式,第三方应用程序正在操作系统级别进行黑客攻击,而您只是在挂钩该应用程序。

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

在 Windows 上将CAPSLOCK重新映射到ESCCTRL

如果要将CAPSLOCK重新映射到两者

  1. ESC (单独按下时)
  2. CTRL (当用其他键按下时)你可以使用ililim 的这个小开源软件

为此,您不需要管理员权限,并且ESCCTRL仍在按预期工作。

我用它来享受方便的CTRL + anything按下而不会伤害我的小指,并在 Vim 中切换我通过 MobaXterm 中的 ssh 使用的模式。 安装只需按照此说明进行

在 Linux 上将CAPSLOCK重新映射到ESCCTRL

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

sudo apt install xcape

对于实际映射,请执行以下操作:

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

第一个命令是将CAPSLOCK映射到ESC而第二个命令负责用其他键按下CTRL

要使其在 X 会话中永久工作,您可以将其添加到~/.xprofile

@rsoren 的回答有效。 但问题是如果打开多个缓冲区,从一个缓冲区退出,也会恢复所有其他缓冲区的映射。 用 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'

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

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

$ brew cask install karabiner-elements

安装后,您可以在简单修改选项卡中将大写锁定键映射到esc键。 需要注意的是,这是系统范围内的,这意味着您会在任何地方丢失大写锁定键。 需要大写锁定的 IMO。

截至 2020 年,仅适用于像我这样的凡人 WINDOWS 用户的工作示例是使用AutoHotkey

目前使用这个 1 行脚本:

Capslock::Esc

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

我浏览了这个问题的答案以自己做,但我正在寻找稍微不同的东西:

  1. 我正在使用Linux
  2. 我很高兴甚至在 Vim 之外更改大写字母(我几乎总是错误地按下,无论如何我可以将它保留在 Esc 按钮上以实现我正在使用的目标)
  3. 我想尽可能使用最常用的软件,不需要任何进一步的安装
  4. 我更喜欢KISS ,然后甚至避免需要进一步冗长的脚本
  5. 如果可能的CAPS + <something> -> Ctrl + <something> ,我想要同时使用CAPS -> Esc AND CAPS + <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

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

对于 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 的文档有一整页专门讨论这个主题, 评论部分特别有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM