terminal input coding

Julian Bradfield jcb+xeb at jcbradfield.org
Sat Nov 29 11:33:07 EST 2008


Aidan Kehoe wrote:

>It’s broken on 21.4. I don’t see any prospect of it getting fixed on
>21.4. See 21.5 for a working implementation. 

Oh well.

In case anybody else out there has a crying need for utf-8 terminal
input on 21.4, I post the following workaround, which is good enough
for my needs. I can't see how to do better without effectively
implementing a command loop.

File utf8input.el:

; This file fakes up utf8 terminal input for XEmacs 21.4 with mule-ucs.
; It's not perfect, but good enough for my purposes.
; obviously, it requires no "high-bit-is-meta braindamage" on the
; desired terminal, but it doesn't enforce that itself.

(require 'unicode)
(defvar utf8-octets-left 0)
(defvar utf8-char-so-far nil)

(defun utf8-handle-octet()
  (interactive)
  (let ((c (char-int last-command-char)))
    (cond ((< c 128)
	   (if utf8-char-so-far
	       (warn "Discarded partial utf-8 character from terminal input"))
	   (setq utf8-octets-left 0)
	   (setq utf8-char-so-far nil)
	   (setq overriding-terminal-local-map nil)
	   (dispatch-event last-command-event))
	  ((> c 247)
	   (warn "Bad utf-8 prefix %d received" c)
	   (setq utf8-octets-left 0)
	   (setq utf8-char-so-far nil))
	  ((>= c 240)
	   (if utf8-char-so-far
	       (warn "Discarded partial utf-8 character from terminal input"))
	   (setq overriding-terminal-local-map 'utf8-map)
	   (setq utf8-octets-left 3)
	   (setq utf8-char-so-far (logand c 7)))
	  ((>= c 224)
	   (if utf8-char-so-far
	       (warn "Discarded partial utf-8 character from terminal input"))
	   (setq overriding-terminal-local-map 'utf8-map)
	   (setq utf8-octets-left 2)
	   (setq utf8-char-so-far (logand c 15)))
	  ((>= c 192)
	   (if utf8-char-so-far
	       (warn "Discarded partial utf-8 character from terminal input"))
	   (setq overriding-terminal-local-map 'utf8-map)
	   (setq utf8-octets-left 1)
	   (setq utf8-char-so-far (logand c 31)))
	  ((equal utf8-octets-left 0) ; but we've got a medial byte
	   (warn "Discarded partial utf-8 character from terminal input")
	   (setq overriding-terminal-local-map nil))
	  (t ; medial byte, and expecting it
	   (setq utf8-char-so-far (logior (lsh utf8-char-so-far 6)
					 (logand c 63)))
	   (setq utf8-octets-left (1- utf8-octets-left))
	   (when (equal utf8-octets-left 0)
	     (setq overriding-terminal-local-map nil)
	     (setq last-command-char (ucs-to-char utf8-char-so-far))
	     (setq utf8-char-so-far nil)
	     (if isearch-mode
		 (isearch-process-search-char
		  (make-event 'key-press `(key ,last-command-char)))
	       (self-insert-command 1))
	     )))))


(defvar utf8-map
  (let ((km (make-keymap))
	(i 0))
    (while (< i 32)
      (define-key km `(control ,(+ 64 i)) 'utf8-handle-octet)
      (setq i (1+ i)))
    (while (< i 256)
      (define-key km i 'utf8-handle-octet)
      (setq i (1+ i)))
    km))

(let ((i 128))
  (while (< i 256)
    (define-key global-map i 'utf8-handle-octet)
    (setq i (1+ i))))

(put 'utf8-handle-octet 'isearch-command t)

(provide 'utf8input)




More information about the XEmacs-Beta mailing list