[comp.emacs] Updated tvi950.el

rbj@nav.icst.nbs.GOV (Root Boy Jim) (10/03/88)

Matt,
	Here is an updated version of the tvi950.el that you posted
awhile back. Besides the gratuitous binding changes (;-), I changed the
way that labels were done. I use alternating inverse video to delimit
the labels and the labels function toggles between 1-11 and 12-22.
I also documented all the possible tvi950 keys. Some functions may be
missing as I did not include my fns.el file. Hope you like it!

My `def-key' function is pretty much like define-key except that it takes
a keymap *name* instead of the keymap itself. What it does is define an
intermediate variable suffixed with the fourth argument and fsets its
function definition to the function provided. This way, any changes I
make to the standard bindings show up in describe-bindings.

To add to the madness, if the map is specified as `t' or `nil', the
current-{global,local}-map is used. Set-key is an interactive wrapper.

Note also that I defined ^Q as a prefix key. I am one of those people who
use ^Q/^S for flow control and map ^^/^_ to ^Q/^S via the
keyboard-translate-table. This the Home key becomes a prefix for the
other arrow keys. Thanks for the doing all the initial work.

	(Root Boy) Jim Cottrell	(301) 975-5688
	<rbj@nav.icst.nbs.gov> or <rbj@icst-cmr.arpa>
	Careful with that VAX Eugene!

;; tvi950 package for GNU emacs
;; January 1986; Matt Crawford
;; August  1988; Root Boy Jim hacked it unmercifully

;; This file makes the FUNCT key act like a meta key. It also
;; provides tvi-reset, tvi-setup, tvi-bind, and tvi-labels.
;; If tvi-arrows is bound and non-nil then the key bindings are
;; scrambled to accomodate the arrow keys (down up left right
;; are C-V C-K C-H C-L respectively.)

(defconst tvi-reset
  (concat "\eG0  01  \eG4  02  \eG0  03  \eG4  04  \eG0  05  \eG4  06  "
	  "\eG0  07  \eG4  08  \eG0  09  \eG4  10  \eG0  11  "
	  "\eG8  12  \eG<  13  \eG8  14  \eG<  15  \eG8  16  \eG<  17  "
	  "\eG8  18  \eG<  19  \eG8  20  \eG<  21  \eG8  22  ")
  "Original labels for tvi950 function keys")

(defvar tvi-labels tvi-reset "Status line labels for tvi950 function keys.")

(defvar tvi-toggle 0 "Toggle which labels are displayed")

(defun tvi-labels () "Display labels for tvi950 function keys."
  (interactive)
  (send-string-to-terminal
   (concat "\eg\ef"
	   (substring tvi-labels tvi-toggle (+ tvi-toggle 99))
	   "\^m"))
  (setq tvi-toggle (- 99 tvi-toggle)))

(defun tvi-reset (arg) "Reset tvi950 function keys and labels."
  (interactive "P")
  (setq tvi-labels tvi-reset
	tvi-toggle 0)
  (tvi-labels)
  (tvi-setup arg))

(defun tvi-meta ()
  "Make the tvi950 FUNCT key act like a META key."
  (interactive)
  (let ((save-key (read-char)))
    (if (/= (read-char) ?\^M)
	(error "Bad C-A or FUNCT key usage")
      (setq prefix-arg current-prefix-arg
	    unread-command-char (logior save-key 128)))))

(def-key t "\^A" 'tvi-meta ">")

(defvar tvi-map (make-keymap) "Keymap for tvi950 function keys")

(defvar tvi-prefix "\e_" "Prefix for tvi950 function key map")

(defvar tvi-base ?` "Function key values start (after) here")

(defun tvi-setup (arg)
  "Bind the tvi950 function keys with `tvi-prefix' starting after `tvi-base'."
  (if arg (setq tvi-map (make-keymap)))
  (fset 'tvi-map tvi-map)
  (def-key t tvi-prefix 'tvi-map "+")
  ;; save the following for later reference ...
  (let ((ps (tvi-quote tvi-prefix))
	(key 0))
    (while (< key 22)
      (setq key (1+ key))
      (send-string-to-terminal
       (concat "\e|"
	       (char-to-string (+ key ?0))
	       "1" ps
	       (char-to-string (+ key tvi-base))
	       "\^Y")))))

(defun tvi-quote (string)
  "Quote control chars in STRING with ^P, for tvi950 terminal."
  (let ((result ""))
    (while (> (length string) 0)
      (setq result (concat result
			   (and (or (< (string-to-char string) 32)
				    (= (string-to-char string) 127))
				"\^P")
			   (substring string 0 1)))
      (setq string (substring string 1)))
    result))

(defun tvi-bind (key command label) "\
Bind tvi950 function key number KEY to COMMAND.
Give it the 6 character LABEL on the 25th line.
Shifted keys are numbered 12 thru 22."
  (interactive "nKey number: \nCCommand: \nsLabel: ")
  (and (or (> key 22) (< key 1)) (error "Key number out of range!"))
  (def-key 'tvi-map (char-to-string (+ key tvi-base)) command "+")
  (if (string= label "") nil
    (setq tvi-toggle (if (> key 11) 99 0)
	  key (- (* 9 key) 6)
	  tvi-labels (concat (substring tvi-labels 0 key)
			     (substring (concat label "       ") 0 6)
			     (substring tvi-labels (+ key 6))))
    (tvi-labels)))

(tvi-reset nil)

;(tvi-bind  1 'undefined "")
;(tvi-bind  2 'undefined "")
;(tvi-bind  3 'undefined "")
;(tvi-bind  4 'undefined "")
;(tvi-bind  5 'undefined "")
;(tvi-bind  6 'undefined "")
;(tvi-bind  7 'undefined "")
;(tvi-bind  8 'undefined "")
;(tvi-bind  9 'undefined "")
(tvi-bind 10 'tvi-bind  "tvbind")
(tvi-bind 11 'tvi-labels "labels")

;(tvi-bind 12 'undefined "")
;(tvi-bind 13 'undefined "")
;(tvi-bind 14 'undefined "")
;(tvi-bind 15 'undefined "")
;(tvi-bind 16 'undefined "")
;(tvi-bind 17 'undefined "")
;(tvi-bind 18 'undefined "")
;(tvi-bind 19 'undefined "")
;(tvi-bind 20 'undefined "")
(tvi-bind 21 'tvi-reset "RESET")
(tvi-bind 22 'tvi-labels "LABELS")

(defvar tvi-arrows nil "Shuffle commands to use arrows if set")

(defun tvi-arrows ()
  "Make the arrow keys act in the intuitive fashion."
  (define-key global-map "\^v" 'next-line)	;down arrow
  (define-key global-map "\^k" 'previous-line)	;up arrow
  (define-key global-map "\^h" 'backward-char)	;left arrow
  (define-key global-map "\^l" 'forward-char)	;right arrow
  ;; move the old functions of the above
  (define-key global-map "\^n" 'scroll-up)
  (define-key global-map "\^p" 'scroll-down)
  (define-key global-map "\^_" 'help-command) (setq help-char ?\^_)
  ;; for consistency with arrows and C-N ...
  (define-key esc-map "\^v" 'other-window)     	;M-down
  (define-key esc-map "\^k" 'previous-window)	;M-up
  (define-key esc-map "\^h" 'backward-word)	;M-left
  (define-key esc-map "\^l" 'forward-word)	;M-right
  (define-key esc-map "n" 'scroll-other-window)
  (define-key esc-map "p" 'scroll-other-window-down)
  )

(if tvi-arrows (tvi-arrows))

;; Other functions keys, mainly for documentation. CAPS mean shifted.

(def-key t	"\eQ"	'quoted-insert 	"+")	;char insert
;(def-key t	"\eq"	')			;CHAR INSERT
(def-key t	"\eW"	'rubout-char	"+")	;char delete
;(def-key t	"\er"	')			;CHAR DELETE
(def-key t	"\eE"	'yank-rectangle	"+")	;line insert
(def-key t	"\eN"	'rubout-line	"+")	;LINE INSERT
(def-key t	"\eR"	'kill-rectangle	"+")	;line delete
(def-key t	"\eO"	'join-line	"+")	;LINE DELETE
(def-key t	"\eT"	'line-to-top	"+")	;line erase
;(def-key t	"\et"	')			;LINE ERASE
(def-key t	"\eY"	'line-to-bot	"+")	;page erase
;(def-key t	"\ey"	')			;PAGE ERASE
(def-key t	"\^Z"	'previous-window "+")	;clear space
;(def-key t	"\e*"	')			;CLEAR SPACE
(def-key t	"\eI"	'undo 		"+")	;BACK TAB
(def-key t	"\eP"	'scroll-up 	"+")	;print
(def-key t	"\eL"	'scroll-down 	"+")	;PRINT
(send-string-to-terminal "\e01S\e02s")		;program SEND key
(def-key t	"\eS"	'tvi-bind 	"+")	;send
;(def-key t	"\es"	')			;SEND

;;; Use the Home Key (^^ -> ^Q) as an Arrow Prefix

(def-key t	"\^q"	 nil)				; undefine ^Q
(def-key t	"\^q\^q" 'quoted-insert		"*")	; save old ^Q
(def-key t	"\^q\^v" 'scroll-up		"+")	; down
(def-key t	"\^q\^k" 'scroll-down		"+")	; up
(def-key t	"\^q\^h" 'scroll-other-window	"+")	; left
(def-key t	"\^q\^l" 'scroll-other-window-down "+")	; rite

;;; keys.el
(setq debug-on-error nil)
(defvar gubed nil "Debug Spelt Sideways!")

(defun def-key (map key cmd &optional suffix def) "\
In MAP, bind KEY to CMD.  Create an intermediate variable with SUFFIX
appended to cmd name & set its function definition to command.
If MAP is t, use global-map; if nil, use local map; else use
given map.  MAP must be the *name* of a map, *not* the map itself.
Optional fifth arg DEF is function definition."
  (if gubed (debug))
  (cond ((null map) (setq map '(current-local-map)))
	((eq map t) (setq map '(current-global-map))))
  (if def (fset cmd def))
  ;;  (or suffix (setq suffix "?"))
  (let ((name (concat (symbol-name cmd) suffix)))
    (and suffix (not (string= suffix ""))
	 (eval (read (concat "(fset '" name " cmd)"))))
    (define-key (eval map) key (intern name))
    (if load-in-progress nil
      (message "%s bound to %s in %s"
	       (key-description key) name map))))

(defun set-key (key cmd &optional map) "\
Interactive wrapper for def-key. Bind KEY to CMD in MAP.  MAP is
decoded from the prefix arg. If any prefix arg is supplied, use global
map, else use local map. Suffix is always '&'."
  (interactive "kSet Key: \nCCommand: \nP")
  (if gubed (debug))
  (def-key (not map) key cmd "&"))

;;; Random Conventions: Keys fall into various categorys and are
;;; designated by a third argument to `set-key' as follows:
;;;
;;;   Suffix			Category
;;;
;;;	"+"		New functions on new keys (additions)
;;;	">"		Old functions on new keys (displacements)
;;;	"<"		New functions on old keys (supercessions)
;;;	"*"		Old functions on old keys (relocations)
;;;	"@"	 	Old function no longer used

(defun tick (&optional map) "\
Define ` as ESC-prefix and `` as self insert.
Global definition if MAP is t, else local definition."
  (interactive)
  (def-key map	"`"	'ESC-prefix			"*")
  (def-key map	"\e`"	'self-insert-command		"+"))

(tick t)

;;; Control Key Map

(def-key t	"\^a"	'scroll-up			"*")
(def-key t	"\^s"	'transpose-chars		"*")
(def-key t	"\^t"	'isearch-forward		"*")
(def-key t	"\^v"	'beginning-of-line		"*")
(def-key t	"\^z"	'scroll-down			"*")
(def-key t	"\^]"	'other-window			"*")

;;; Meta Additions (FULL) _ is tvi950 function keys

(def-key t	"\e\^l"	'count-lines-region		">")
(def-key t	"\e\^m"	'scroll-other-window		"+")
(def-key t	"\e\^q"	'indent-region			">")
(def-key t	"\e\^r"	'isearch-backward-regexp	"+")
(def-key t	"\e\^v"	'scroll-other-window-down	">")
(def-key t	"\e\^y"	'eval-region			"+")
(def-key t	"\e\^z"	'eval-current-buffer		"+")
(def-key t	"\e\^_"	'abort-recursive-edit		"<")

(def-key t	"\e\^]"	'scroll-other-window-down	"+")
(def-key t	"\e "	'set-mark-command		"*")
(def-key t	"\e\""	'mail-quote			"+")
(def-key t	"\e#"	'spell-buffer			"+")
(def-key t	"\e*"	'set-key			"+")
(def-key t	"\e+"	'make-command-summary		"+")
(def-key t	"\e:"	'print-buffer			"+")
(def-key t	"\e="	'what-line			"<")
(def-key t	"\e?"	'print-region			"+")
(def-key t	"\en"	'rename-buffer			"+")
(def-key t	"\eo"	'occur				"+")
(def-key t	"\ep"	'pwd				"+")
(def-key t	"\eq"	'query-replace			"*")
(def-key t	"\er"	'query-replace-regexp		"<")
(def-key t	"\es"	'set-variable			"+")
(def-key t	"\ev"	'view-buffer			"<")
(def-key t	"\e\\"	'end-of-buffer			"<")

;;; ^X Map (FREE %& @_) ^@ is sun-mouse, # is server-edit

(def-key t	"\^x\^a" 'append-to-file		"<")
(def-key t	"\^x\^b" 'buffer-menu			"@")
(def-key t	"\^x\^h" 'fill-paragraph		"*")
(def-key t	"\^x\^j" 'backward-kill-sexp		"+")
(def-key t	"\^x\^k" 'bury-buffer			"+")
(def-key t	"\^x\^m" 'rmail-file			"+")
(def-key t	"\^x\^r" 'move-to-window-line		"@")
(def-key t	"\^x\^y" 'yowza				"+")
(def-key t	"\^x\^]" 'blink-paren			"+")
(def-key t	"\^x\^_" 'backward-kill-sexp		"+")

(def-key t	"\^x "	'just-one-space			">")
(def-key t	"\^x!"	'shell				"+")
(def-key t	"\^x\""	'mail-uucp			"+")
(def-key t	"\^x*"	'add-mode-abbrev		">")
(def-key t	"\^x,"	'inverse-add-mode-abbrev	">")
(def-key t	"\^x3"	'compare-windows		"+")
(def-key t	"\^x6"	'enlarge-window			"+")
(def-key t	"\^x7"	'shrink-window			"+")
(def-key t	"\^x8"	'scroll-up-in-place		"+")
(def-key t	"\^x9"	'scroll-down-in-place		"+")
(def-key t	"\^x:"	'lpr-buffer			"+")
(def-key t	"\^x?"	'lpr-region			"+")
(def-key t	"\^xc"	'cd				"+")
(def-key t	"\^xd"	'delete-matching-lines		"@")
(def-key t	"\^xt"	'tick				"+")
(def-key t	"\^xv"	'view-file			"+")
(def-key t	"\^xy"	'prev-complex-command		"+")
(def-key t	"\^xz"	'rerun-prev-command		"+")
(def-key t	"\^x\\"	'electric-command-history	"+")
(def-key t	"\^x|"	'recover-file			"+")
(def-key t	"\^x~"	'revert-buffer			"+")

;;; I like Control Key Help (FREE ^eopquxz)

(def-key t	"\^h\^a" 'command-apropos		">")
(def-key t	"\^h\^b" 'describe-bindings		">")
(def-key t	"\^h\^c" 'describe-key-briefly		"@")
(def-key t	"\^h\^d" 'dup-line			"@")
(def-key t	"\^h\^f" 'describe-function		">")
(def-key t	"\^h\^i" 'info				">")
(def-key t	"\^h\^j" 'goto-line			"+")
(def-key t	"\^h\^k" 'describe-key			">")
(def-key t	"\^h\^l" 'load-library			"+")
(def-key t	"\^h\^m" 'describe-mode			">")
(def-key t	"\^h\^n" 'next-error			"@")
(def-key t	"\^h\^r" 'byte-recompile-directory	"+")
(def-key t	"\^h\^s" 'describe-syntax		">")
(def-key t	"\^h\^t" 'help-with-tutorial		">")
(def-key t	"\^h\^v" 'describe-variable		">")
(def-key t	"\^h\^w" 'where-is			"@")
(def-key t	"\^h\^y" 'random-yow			"+")

;;; Now use ^h for a few other things (FREE ehijoprwxz)

(def-key t	"\^h "	'delete-horizontal-space	">")
(def-key t	"\^h."	'find-tag-other-window		"+")
(def-key t	"\^h;"	'kill-comment			"+")
(def-key t	"\^h="	'what-page			"+")
(def-key t	"\^ha"	'apropos			"<")
(def-key t	"\^hb"	'switch-to-buffer-other-window	"*")
(def-key t	"\^hc"	'compile			"<")
(def-key t	"\^hd"	'dired-other-window		"*")
(def-key t	"\^hf"	'find-file-other-window		"*")
(def-key t	"\^hg"	'grep				"+")
(def-key t	"\^hj"	'goto-char			"+")
(def-key t	"\^hk"	'kill-rectangle			"<")
(def-key t	"\^hl"	'list-tags			"@")
(def-key t	"\^hm"	'repeat-matching-complex-command ">")
(def-key t	"\^hn"	'next-file			"@")
(def-key t	"\^hq"	'tags-query-replace		"+")
(def-key t	"\^hs"	'tags-search			"+")
(def-key t	"\^ht"	'tags-apropos			"+")
(def-key t	"\^hu"	'undigestify-rmail-message	"+")
(def-key t	"\^hv"	'visit-tags-table		"<")
(def-key t	"\^hy"	'yank-rectangle			"+")

;;; end keys.el