How to map CAPS LOCK key in VIM?
I'm using GVIM under Windows. And want to map CAPSLOCK to Ctrl+^
Any way to do this?
Btw, I see tons of samples over the web how to swap CAPS and Esc using registry hack, but none of them use VIM map开发者_如何学Python command, instead external tools and registry changes.
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.
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'.
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.
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
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.
Solution that doesn't break Caps Lock
outside of vim
Windows
- Install autohotkey.
- Run autohotkey script:
;caps_to_esc.ahk
#IfWinActive, ahk_class Vim ; vim window class
Capslock::Esc
#IfWinActive
Ubuntu
Run this command:
wget -O - https://raw.githubusercontent.com/grabantot/scripts/master/install/install_caps_to_esc.sh | bash
Or perform these actions manually:
sudo apt-get install xdotool xbindkeys
. We will also usexprop
andxset
(should be installed by default).- 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"
- Add new bindnig to
~/.xbindkeysrc
:
"bash $HOME/caps_to_esc.sh"
Caps_Lock
killall xbindkeys && xbindkeys
How it works:
xbindkeys
will detetect when Caps_Lock is pressed and callcaps_to_esc.sh
script- in the script detect active window wm_class by
xprop
- check if wm_class is of interest for us (gnome-terminal, vscode, gvim, chrome), exit if it is not
- send Escape key via
xdotool
- check if Caps Lock is on via
xset
and if it is then send Caps_Lock key viaxdotool
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.
@rsoren's answer works. But the problem with that is if multiple buffers are opened, exiting from one, reverts the mapping for all of the others too. Replacing VimEnter and VimLeave with BufEnter and BufLeave, did the trick for me.
au BufEnter * silent! !xmodmap -e 'clear Lock' -e 'keycode 0x42 = Escape'
au BufLeave * silent! !xmodmap -e 'clear Lock' -e 'keycode 0x42 = Caps_Lock'
Since there is a solution for Linux and Windows(Autohotkey), I´d like to suggest to use pckeyboardhack for Mac to remap CapsLock everywhere.
Remap CAPSLOCK
to ESC
and CTRL
on Windows
If you want to remap CAPSLOCK
to both
- to
ESC
(when pressed alone) - to
CTRL
(when pressed with other keys) you can use this little piece of open source software by ililim.
You do not need Admin privileges for this and ESC
and CTRL
are still working as expected.
I use it to enjoy convenient CTRL + anything
presses without hurting my pinky and to toggle modes in Vim that I use via ssh in MobaXterm. For installation just follow this description.
Remap CAPSLOCK
to ESC
and CTRL
on Linux
To do the same on Linux, you can use XCAPE. To install it on Ubuntu use:
sudo apt install xcape
For the actual mapping do:
setxkbmap -option ctrl:nocaps
xcape -e 'Control_L=Escape'
The 1st command is to map CAPSLOCK
to ESC
whereas the 2nd one takes care of CTRL
pressed with other keys.
To have this permanently working in X sessions, you can add this to ~/.xprofile
.
I went through the answers to this question to do it my own, but I was looking for something slightly different:
- I'm using Linux
- I'm happy to change CAPS even outside Vim (I press almost always by mistake, and I can keep it on the Esc button anyhow for the goals I'm using it)
- I'd like to use the most common software as possible, not to require any further installation
- I'd prefer to KISS, and then even avoid the need of further lengthy scripts
- I'd like to have both
CAPS -> Esc
ANDCAPS + <something> -> Ctrl + <something>
, if possible
Then my current solution it is:
# ~/.xprofile
xmodmap $HOME/.xmodmap
and:
! ~/.xmodmap
clear lock
keycode 66 = Escape
keycode 9 = Caps_Lock
add lock = Caps_Lock
clear control
add control = Control_L Control_R Escape
Looks like it's working like a charm for the time being, but I'm looking for feedbacks :)
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.
A working example for a mere Mortal WINDOWS user like me as of 2020 is using AutoHotkey
Currently using this 1 line script:
Capslock::Esc
Run it and your problem is solved. Hope it helps. :)
With X (Linux), as @Dan Andreatta mentioned, use xmodmap
to alter the key mapping, e.g.
xmodmap -e 'clear Lock' -e 'keycode 0x42 = Escape'
Will map Esc to the CapsLock key.
You could also set this in stone by adding it into an X initialization file, such as .xinitrc
— which is run when using startx
—:
clear lock
keycode 0x42 = Escape
Typically, this is put inside an .Xmodmap
file and then it's run inside .xinitrc
.
Vim's documentation has an entire page dedicated to this topic, and the comments section is especially helful.
精彩评论