How to map CAPS LOCK key in VIM?

吃可爱长大的小学妹 提交于 2019-11-27 06:47:46

Linux? With X, use xmodmap to alter the key mapping, e.g.

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

Will map Esc to the CapsLock key. Google for more examples.

If your intention is just to avoid working outside of Vim, you can put these lines in your .vimrc:

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

The first line maps escape to the caps lock key when you enter Vim, and the second line returns normal functionality to caps lock when you quit.

This requires Linux with the xorg-xmodmap package installed.

Under windows? Use AutoHotkey. It's not a vim mapping, but as the others have stated you can't map it. I use AHK to map my CAPSLOCK to CTRL.

For Mac OS, you can remap the 'caps lock' key system wide in 'system preferences'.

Follow this path:

system preferences > keyboard > modifier keys

Then click the drop down box next to 'caps lock' and choose '^ Control'.

Capslock (and Control, and Shift etc.) is a modifier key, which means that it's used with another normal key to modify the meaning of that key. AFAIK the OS does not pass the modifier keys to the application unless a normal key has also been pressed, e.g. pressing CTRL will not be seen by the application, but CTRL-C will be.

In Linux systems this can be done with xmodmap.

Save this in a text file in the home folder

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

Save this file with a name like .capstoescswitc

Then execute this file via the terminal.

xmodmap ~/.capstoescswitc 

If want to reveres it simply switch the key variables in the script file.

For more info refer this page

Solution that doesn't break Caps Lock outside of vim

Windows

  1. Install autohotkey.
  2. Run autohotkey script:
;caps_to_esc.ahk
#IfWinActive, ahk_class Vim ; vim window class
Capslock::Esc
#IfWinActive

Linux

Run this command:

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

Or perform these actions manually:

  1. sudo apt-get install xdotool xbindkeys. We will also use xprop and xset (should be installed by default).
  2. Create a ~/caps_to_esc.sh script:
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. Add new bindnig to ~/.xbindkeysrc:
"bash $HOME/caps_to_esc.sh"
Caps_Lock
  1. killall xbindkeys && xbindkeys

How it works:

  1. xbindkeys will detetect when Caps_Lock is pressed and call caps_to_esc.sh script
  2. in the script detect active window wm_class by xprop
  3. check if wm_class is of interest for us (gnome-terminal, vscode, gvim, chrome), exit if it is not
  4. send Escape key via xdotool
  5. check if Caps Lock is on via xset and if it is then send Caps_Lock key via xdotool
  6. xbindkeys will detect the Caps_Lock sent by us but we ignore it

I dont think you can. I believe CAPS-LOCK is probably translated by the OS before vim ever sees it. So you'd need to do a hack at the OS level, like the registry hacks you've already seen.

EDIT: autohotkey looks like it could be used to bridge the vim-OS gap. This way a thirdparty app is doing the hacks at the OS level, and you're just hooking that app.

Jakob

Since there is a solution for Linux and Windows(Autohotkey), I´d like to suggest to use pckeyboardhack for Mac to remap CapsLock everywhere.

I guess one of the reasons for doing this is to create a soft capslock, like others have mentioned, possibly to avoid keeping capslock on while in normal mode. I've used the vimcaps plugin to turn off capslock when leaving insert mode, seems to work okay.

On mac, it is also possible to use Karabiner (https://pqrs.org/osx/karabiner/)

$ brew cask install karabiner-elements

Once installed, you can map capslock key to esc key in the simple modifications tab. Caveat is this is system wide, meaning that you lose capslock key everywhere. IMO who needs capslock.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!