Question

I'm using Emacs 23 with xterm and am trying to bring my Linux system into the 21st century by switching from a POSIX locale to en_US.utf8. Problem: when I use the Alt key on the keyboard in this locale, xterm sends a two-character sequence. I'd like to fix emacs so that it sees, e.g., Alt-f as meta-f rather than the two-character sequence "\303\246". I think this might be a job for an input coding, but from the emacs documentation I have not figured out how to write one.

As an alternative I would be willing to add octal '\303' to a keymap so that emacs would treat it as a prefix character to introduce a meta escape. The way I would prefer to do this would be to bind '\303' to a function that then takes the next key and adjusts it as a meta key. But I can't quite figure out that one either.

Worst case I guess I write a loop that binds the meta keys for 'a' through 'z' or something equally horrid.

I've messed around with the set-terminal-coding-system, but the crux of the matter is that in a UTF-8 locale, xterm uses the Alt key to send non-ascii characters—the Alt key no longer behaves like meta. So setting the terminal coding system to UTF-8 merely enables me to enter Latin characters with diacritical marks. Not the behavior I hoped for.

I found a really horrid answer that involves guessing what xterm is doing around the meta key. Suggestions for improvement are welcome—I'd like to find code that could do this job cleanly.

(And FYI, I'm not the only one with this problem.)

Was it helpful?

Solution

Here's a truly horrible hack:

(unless (display-graphic-p)
  (defun make-meta-key ()
    (interactive)
    (let ((e (read-event)))
      (if (numberp e)
          (let ((keys  (vector (event-convert-list (list 'meta
                                                        (+ (event-basic-type e) 64))))))
            (let ((result (key-binding keys)))
              (command-execute result)))
        (error "this can't happen"))))
  (global-set-key [?\M-C] 'make-meta-key))

This seems to work around what xterm is doing.

ETA: revision to handle more meta sequences:

(unless (display-graphic-p) ;; deal with the Unicode sequences that xterm sends when Alt (meta) keys ;; are used. N.B. Works with Alt-letter, Alt-\, Alt-space, and Alt-Shift-: (defun make-meta-key () (interactive) (let ((e (read-event))) ;; (message "Got event %s; basic event is %s" e (event-basic-type e)) (if (numberp e) (let* ((basic (event-basic-type e)) (shifted (+ basic 64)) (basecode (if (<= shifted 127) shifted basic)) (keys (vector (event-convert-list (list 'meta basecode)))) (command (key-binding keys))) ;; (message "Result is %s; commandp says %s" command (commandp command)) (command-execute command)) (error "this can't happen")))) (global-set-key [?\M-C] 'make-meta-key) (defun do-nothing () (interactive) nil) (global-set-key [?\M-B] 'do-nothing))

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top