Semimap - .Xmodmap with semicolon as an additional modifier
14 Feb 2015Today, I'll share my keyboard layout, based on QWERTY, that facilitates all tech-related activities, especially Emacs. I've been using a version of this for about three years now, and only a single key has been changed in the last two years. Without further ado, here it is:
The most visible change
I've made ; stop inserting ;
and instead act as
Mode_switch
: a modifier similar to control or meta.
- I'm pressing ;-j to enter ;
- I'm pressing ;-d to enter :
So I'm giving up the ability to press ; with a single key, and remapping : from one two-key combination to another two-key combination.
In return, I'm getting a QWERTY with all these wonderful shortcuts.
The RSI-savers
The general ones are:
- RET on ;-v (symmetric with C-m)
- DEL on ;-o
If you're writing a bunch of C++, _ on ;-s is very good.
Likewise, - on ;-a is great for LISP.
For LaTeX, \ on ;-w is good since I switched from a keyboard that had it near z to a keyboard that has it near RET.
I'm guessing ~ on ;-t isn't bad for shell, but I don't use it that much.
The basic remaps
These are just char-for-char remaps. They are composable, for instance
I have dired-jump
on C-:, which means that I'm pressing
C-;-d.
Some math symbols are mnemonic: e-equal,
l-lesser, g-greater.
If you're using lispy, it might become more clear for you
why I've put lispy-slurp
on > and lispy-barf
on <. Although
pressing these keys with a shift isn't the worst thing, having them on the home row is pretty cool.
The pairs
Here are the translations meant for pairs:
q - θ,
f - φ,
r - ρ,
c - σ.
These are meant for Emacs and .inputrc
. In both cases, e.g. φ should insert ()
and
go backward one char. Here's my .inputrc
:
set input-meta on
set output-meta on
set convert-meta off
"θ":""\C-b""
"ω":"'\C-b'"
"\e\C-l":"\C-e | less\C-m"
"υ":">\C-b<"
"σ":"}\C-b{"
"φ":")\C-b("
"ρ":"]\C-b["
set completion-ignore-case on
With this .inputrc
, it's like I have some kind of electric mode in my bash.
In Emacs, the pairs are bound in a straightforward way:
(defun ins-brackets ()
(interactive)
(cond ((eq major-mode 'term-mode)
(term-send-raw-string "[]")
(term-send-raw-string "^B"))
((region-active-p)
(lispy--surround-region "[" "]"))
(t
(insert "[]")
(backward-char))))
(global-set-key "ρ" 'ins-brackets)
For LISP, I use lispy
-specific bindings:
(define-key lispy-mode-map (kbd "φ") 'lispy-parens)
(define-key lispy-mode-map (kbd "σ") 'lispy-braces)
(define-key lispy-mode-map (kbd "ρ") 'lispy-brackets)
(define-key lispy-mode-map (kbd "θ") 'lispy-quotes)
(define-key lispy-mode-map (kbd "χ") 'lispy-right)
The rest of the Greek chars
These are bound to various Emacs functions. In fact, I initially started with all Greek chars, and bound e.g.:
(global-set-key (kbd "ε") "=")
When these remap-type bindings became mature, I've put them directly
into .Xmodmap
, which gave the advantage of being able to compose the
keys.
These bindings are as good and usable as the control plus lower case chars. Use them wisely and you can get a very ergonomic setup. Some ideas:
- switching buffers on ;-h
- switching windows on ;-n
- jumping to bookmarks on ;-m
The shifted digits
I find it much easier to press e.g. ;-4 to insert $
,
rather than S-4. I also restored the justice of 0
coming before 1
by mapping
;-` to 0
.
Outro
I hope that you'll find some use and enjoyment in these ramappings, if you're not afraid to experiment a little. The cost of losing the semicolon is pretty minor, the bigger issue is in finding the unmodified QWERTY extremely sluggish after using this approach.