7

I am working with Emacs on Cygwin, which actually has 3 types of Emacsen:

  • Win32 Emacs, which is a graphical Emacs compiled to use native Windows GUI (so no X windows is required)
  • Terminal Emacs, which displays in the mintty terminal by default
  • X Windows Emacs (requires X, and not relevant to this question)

I am trying to bind the APPS key (the one with the little menu on it, usually to the right of the right-hand Windows key, I think it is properly known as the MENU key, https://en.wikipedia.org/wiki/Menu_key) to the "super" modifier (gotta love those short key sequences). In Win32 Emacs this is pretty easy:

(when (equal window-system 'w32)
    (setq w32-pass-apps-to-system nil
          w32-apps-modifier 'super))

This makes Emacs treat APPS as super and stops it passing it onto the OS. It then becomes trivial to make bindings such as

(define-key global-map (kbd "s-r") 'recentf-open-files)

Problem

How to make terminal mode Emacs also treat APPS as super? Firstly it was necessary to have mintty changed to pass through the APPS key to Emacs; this has been done already by the maintainer (see https://github.com/mintty/mintty/issues/494) and we can now configure mintty to send any escape sequence we want through to Emacs.

As I said in the issue, the initial suggestion of Key_Menu=29 (which results in ESC [ 2 9 ~ appearing in the view-lossage log), appears to be interpreted by Emacs as the "<print>" key, so that I can succesfully bind using

(global-set-key (kbd "<print> r") 'recentf-open-files)

The above, while it is a great advance, is not ideal because 2 sets of bindings would be required, one for terminal mode and one for graphical windowed mode.

Things that I don't know

  • How does Emacs translate a sequence of input characters into a logical key?
  • Why does terminal Emacs think the ESC 29 sequence is the print key?
  • Does terminal Emacs even know about the APPS key?

Question

  • How can I configure W32 Emacs and terminal Emacs so that they both treat APPS/MENU as the super modifier, thus enabling a single set of keybindings to be used in both cases?
4
  • 1
    Please edit the post so that it asks one clear question. If you have multiple questions, feel free to make multiple posts.
    – Dan
    Nov 20, 2015 at 10:57
  • Interesting question! I don't have an answer, but if you're using mintty, this page may have part of your answer: code.google.com/p/mintty/wiki/Keycodes . Nov 20, 2015 at 13:42
  • 1
    I found out why Emacs thinks it is the print key. There is a line in list\term\xterm.el.gz which maps that sequence to print: (define-key map "\e[29~" [print]) Nov 22, 2015 at 11:22
  • Please consider accepting your own answer. This question still shows up on the unanswered list. Thx.
    – Drew
    Feb 11, 2019 at 17:55

1 Answer 1

6

I made quite a bit of progress on this. Reading up on key translation I found this Emacs manual page on Translation keymaps which has an interesting hyperify function

(defun hyperify (prompt)
  (let ((e (read-event)))
    (vector (if (numberp e)
                (logior (lsh 1 24) e)
              (if (memq 'hyper (event-modifiers e))
                  e
                (add-event-modifier "H-" e))))))

(defun add-event-modifier (string e)
  (let ((symbol (if (symbolp e) e (car e))))
    (setq symbol (intern (concat string
                                 (symbol-name symbol))))
    (if (symbolp e)
        symbol
      (cons symbol (cdr e)))))

(define-key local-function-key-map "\C-ch" 'hyperify)

An equivalent superify function can be written by replacing the lsh 1 24 with lsh 1 23 (see Emacs page on character modifier bits). However, googling hyperify resulted in a hit on the Emacs wiki called "StickyModifiers" which mentions a built in function to achieve this called event-apply-super-modifier. I guess the manual is a bit out of date or it was just for pedagogical purposes. In any case, this will make APPS/MENU into a super key in both terminal and W32 Emacs under mintty:

(if (equal system-type 'cygwin)
     (if (equal window-system 'w32)
         (setq w32-pass-apps-to-system nil
               w32-apps-modifier 'super)
       (define-key local-function-key-map (kbd "<print>") 'event-apply-super-modifier)))

 (define-key global-map (kbd "s-h") (lambda () (interactive) (message "hello from menu key via s- prefix")))

Problem It is not perfect however, because holding the APPS key down results in the string [29~ being repeatedly written into the buffer, so you have to be quick. Contrast this with the way that the Alt key works: you can hold it down for as long as you want.

Alternative Technique Over at ErgoEmacs I found an article talking about leader keys, which unfortunately I cannot post because reputation is no longer high enough having given it all to bounty. SIGH. Anyway, it is called "emacs_menu_app_keys". Using this technique:

(if (equal system-type 'cygwin)
     (if (equal window-system 'w32)
         (setq w32-pass-apps-to-system nil
               w32-apps-modifier nil)
       (progn ;; force all alternatives to <apps> so we can write one set of keybindings.
         (define-key key-translation-map (kbd "<print>") (kbd "<apps>"))
         (define-key key-translation-map (kbd "<menu>") (kbd "<apps>")))))

 (define-key global-map (kbd "<apps> h")
    (lambda () (interactive) (message "hello from menu key via <apps> leader key")))

This works great, you press and release APPS before pressing H. I think I prefer it to the first technique as it is easier to type and this prefix key will be reserved for mnemonic-style, one-shot function bindings anyway i.e. nothing that I need to press repeatedly like C-n.

Bounty If anybody can come up with something better, especially if they can get the first technique to work as perfectly as using the Alt or Ctrl keys I will still award the bounty to them.

2
  • Sadly, I don't have a menu/apps key, and I can't seem to reproduce the problem without it.
    – PythonNut
    Nov 26, 2015 at 22:28
  • Late comment: for some other keys I have written "debouncing" code in AutoHotKey outside of emacs. used for a PTT Push(-and-hold) To Talk key with a speech recognition system, so it wasn't emitting modified characters, just turning the microphone on and off, and had to kill the multiple key down events produced by autorepeat. I am not sure that I recommend this because it is timing sensitive, but it solved my immediate problem - but eventually I found a completely different non-PTT approach and I'm no longer using PTT. // Unfortunately, I cannot try it on your AppsKey right now.
    – Krazy Glew
    Jan 17, 2022 at 22:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.