I've got a keyboard, where pressing M-C-S is uncomfortable (Meta and control are under the thumbs and Shift is on the far end of the keyboard). However, PageUp, PageDown, Home and End are in a very comfortable place. I never use any of those keys though, so I was thinking, if it was possible to remap, say, Home to act like M-C-S, that would make my life a lot easier. I would be even happier, if the solution wasn't Emacs-only, but on the system level (it is okay if it is Linux-only).
-
1You want `Home` to be `Meta-Control-Shift-`? – abo-abo Dec 26 '14 at 14:25
-
@abo-abo Either that, or Control-Shift, it's right under Meta, so it would be ok to press them both at once. – wvxvw Dec 26 '14 at 14:56
-
@Malabarba, it's not a duplicate. The question is quite interesting and apparently can't be solved with `xmodmap`. – abo-abo Dec 26 '14 at 15:14
-
@abo-abo the answer to the other question was "it can't be done with emacs". I don't think the additional complexity of this question will lead to a different answer. Still, I'll err on the side of niceness right now, and leave it open. The community can still vote to close if they agree with me. – Malabarba Dec 26 '14 at 15:19
-
@Malabarba, but OP isn't asking for specifically an "in-emacs" answer. A system-specific setting would be acceptable. – abo-abo Dec 26 '14 at 15:25
-
This is the closes to the answer I found so far: http://unix.stackexchange.com/questions/11182/mapping-key-combination-with-xmodmap but I hoped there could be an alternative. – wvxvw Dec 26 '14 at 15:42
-
Unlike the situation in http://unix.stackexchange.com/questions/11182/mapping-key-combination-with-xmodmap this one can be solved at the system level with XKB (but not with xmodmap, which is simpler but less powerful). I'm not an XKB expert but someone on [unix.se] surely knows how to do it. Alternatively, you can solve this in a not very nice way with xmodmap and Emacs, by making e.g. the `End` key the `super` modifier and translating each super-key key combination to C-M-S-key. – Gilles 'SO- stop being evil' Dec 26 '14 at 23:21
-
[This Unix & Linux question](http://unix.stackexchange.com/questions/157834/how-to-bind-altgr-to-ctrl-alt) asks how to do this with XKB. On second thoughts it doesn't seem to be possible. – Gilles 'SO- stop being evil' Dec 26 '14 at 23:50
1 Answers
A pure Emacs solution that doesn't do exactly what you're asking, but close, would be to make e.g. Home be a key that adds the Ctrl, Shift and Alt modifiers to the next key that you press. That is, rather than press Home+key, you would press Homethen key.
Emacs has a built-in feature to add a modifier to the next key, bound to the unwieldy C-x @ letter
by default, e.g. if you type C-x @ m a
it's interpreted as M-a
. This is implemented via function-key-map
. Bindings in function-key-map
are overridden by key bindings in most maps, including the global keymap; if you want your binding to take precedence, define it in input-decode-map
instead. I've written a bit about it here.
You can adapt this mechanism to bind home
to event-apply-control-meta-shift-modifiers
.
(defun event-symbol-add-modifiers (symbol prefixes)
(let* ((name (symbol-name symbol))
(parts (split-string name "-"))
(old-modifiers nil))
(while parts
(if (= (length (car parts)) 1)
(setq old-modifiers (cons (aref (car parts) 0) old-modifiers)))
(setq parts (cdr parts)))
(while prefixes
(if (not (memq (car prefixes) old-modifiers))
(setq name (concat (list (car prefixes) ?-) name)))
(setq prefixes (cdr prefixes)))
(intern name)))
(defun event-apply-modifiers (event mask prefixes)
(cond
((numberp event)
(logior mask event))
((symbolp event)
(event-symbol-add-modifiers event prefixes))
((consp event)
(cons (event-symbol-add-modifiers (car event) prefixes) (cdr event)))
(t event)))
(defun event-apply-control-meta-shift-modifiers (ignore-prompt)
"\\<function-key-map>Add the Ctrl, Meta and Shift modifier to the following event.
For example, type \\[event-apply-control-meta-shift-modifiers] & to enter Ctrl-Meta-Shift-&."
(vector (event-apply-modifiers (read-event) #xe000000 '(?C ?M ?S))))
(define-key input-decode-map [home] 'event-apply-control-meta-shift-modifiers)
(event-apply-modifiers
is a highly simplified version of Emacs's event-apply-modifier
and may be inferior in some circumstances. Minimally tested.)

- 21,702
- 4
- 53
- 89
-
hi, this doesn't work with shift modifiers. Do you have any idea how to improve this? (defun event-apply-control-shift-modifier (_ignore-prompt) (vector (event-apply-modifiers (read-event) #x6000000 '(?C ?S)))) it doesn't trigger my C-S-s key binding – Amos Aug 13 '17 at 02:03
-
@Amos I forgot to mention that if you're using a key that already has a global binding and you want to bypass that binding, you need to use `input-decode-map` instead of `function-key-map`. – Gilles 'SO- stop being evil' Aug 13 '17 at 20:37
-
well it still doesn't work. here is my config file https://la.wentropy.com/LbMM and i use urxvt to send \030@aS – Amos Aug 13 '17 at 20:47
-
@Amos Ah. If you're in a terminal, the terminal sends an escape sequence which is translated to `home`. The result of the translation doesn't undergo translation again. You need to bind the escape sequence to `event-apply-…` directly, something like `(define-key input-decode-map "\eOH" 'event-apply-…)`. Check what escape sequence the `home` key sends by pressing `C-q home` in the `*scratch*` buffer. The first `^[` is an escape character, written `\e` in a string literal. – Gilles 'SO- stop being evil' Aug 13 '17 at 22:12
-
-
1@Amos In your question, you asked how to “remap, say, Home to act like M-C-S”. What are you trying to do exactly? If you're now trying to do something different, you should ask a new question. – Gilles 'SO- stop being evil' Aug 13 '17 at 23:14
-
well, `the terminal sends an escape sequence which is translated to home`. i have no idea i did that. i just need terminal emacs to accept `Ctrl-Shift-s` hotkey – Amos Aug 14 '17 at 00:05
-
@Amos What do you mean by “accept Ctrl-Shift-s hotkey”? Do you want to type `Ctrl+Shift+s` or `Home` then `s`? – Gilles 'SO- stop being evil' Aug 14 '17 at 00:10
-
I mean typing `Ctrl+Shift+s` and make terminal emacs react on that. I have never use `Home` ... – Amos Aug 14 '17 at 00:59
-
1@Amos Well that's a completely different question! Which has been answered before for xterm: https://emacs.stackexchange.com/questions/1020/problems-with-keybindings-when-using-terminal/13957#13957 In urxvt, you need to manually configure different escape sequences for modifier combinations such as Ctrl+Shfit with the `URxvt.keysym.` resources. – Gilles 'SO- stop being evil' Aug 14 '17 at 01:13