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))