changeset 83387:0181341f0aca

Fix Delete key on X by adapting normal-erase-is-backspace-mode for multi-tty. (Reported by Dan Waber and Dan Nicolaescu.) * lisp/frame.el (terminal-parameter-p): New function. (terminal-parameter): Use it. * lisp/simple.el (normal-erase-is-backspace): Add 'maybe option, set it as default. (normal-erase-is-backspace-mode): Rewrite for multiple display support. (normal-erase-is-backspace-setup-frame): New function. * lisp/frame.el (make-frame): Call it. * lisp/startup.el (command-line): Call it. git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-427
author Karoly Lorentey <lorentey@elte.hu>
date Sun, 23 Oct 2005 22:11:22 +0000
parents db4e74787e6f
children 0cd72d94a6c7
files README.multi-tty lisp/frame.el lisp/simple.el lisp/startup.el
diffstat 4 files changed, 101 insertions(+), 59 deletions(-) [+]
line wrap: on
line diff
--- a/README.multi-tty	Wed Oct 19 14:06:17 2005 +0000
+++ b/README.multi-tty	Sun Oct 23 22:11:22 2005 +0000
@@ -391,6 +391,9 @@
 ** Report GTK multi-display problems to GTK maintainers.  For extra
    credit, fix them.
 
+** Possibly turn off the double C-g feature when there is an X frame.
+   C.f. (emacs)Emergency Escape.
+
 ** frames-on-display-list should also accept frames.
 
 ** I smell something funny around pop_kboard's "deleted kboard" case.
@@ -483,6 +486,8 @@
    `last-command', but SELECTED_FRAME()->display->kboard to get the
    value of `function-key-map'.
 
+** I think keyboard-translate-table should be made terminal-local.
+
 ** The single-keyboard mode of MULTI_KBOARD is extremely confusing
    sometimes; Emacs does not respond to stimuli from other keyboards.
    At least a beep or a message would be important, if the single-mode
@@ -533,9 +538,6 @@
 
    See if xsmfns.c should be updated.
 
-** normal-erase-is-backspace-mode in simple.el needs to be updated for
-   multi-tty (rep. by Dan Waber).
-
 ** Hunt down display-related functions in frame.el and extend them all
    to accept display ids.
 
@@ -1249,5 +1251,11 @@
 
    (Fixed in patch-414 after detailed analysis by Kalle Olavi Niemitalo.)
 
+-- normal-erase-is-backspace-mode in simple.el needs to be updated for
+   multi-tty (rep. by Dan Waber).  (The Delete key is broken on X
+   because of this.)
+
+   (Fixed in patch-427.)
+
 ;;; arch-tag: 8da1619e-2e79-41a8-9ac9-a0485daad17d
 
--- a/lisp/frame.el	Wed Oct 19 14:06:17 2005 +0000
+++ b/lisp/frame.el	Sun Oct 23 22:11:22 2005 +0000
@@ -676,6 +676,7 @@
       (error "Don't know how to create a frame on window system %s" w))
     (run-hooks 'before-make-frame-hook)
     (setq frame (funcall frame-creation-function (append parameters (cdr (assq w window-system-default-frame-alist)))))
+    (normal-erase-is-backspace-setup-frame frame)
     (run-hook-with-args 'after-make-frame-functions frame)
     frame))
 
@@ -1450,12 +1451,22 @@
 selected frame's terminal)."
   (cdr (assq (terminal-id terminal) terminal-parameter-alist)))
 
+(defun terminal-parameter-p (terminal parameter)
+  "Return non-nil if PARAMETER is a terminal parameter on TERMINAL.
+
+The actual value returned in that case is a cell (PARAMETER . VALUE),
+where VALUE is the current value of PARAMETER.
+
+TERMINAL can be a terminal id, a frame, or nil (meaning the
+selected frame's terminal)."
+  (assq parameter (cdr (assq (terminal-id terminal) terminal-parameter-alist))))
+
 (defun terminal-parameter (terminal parameter)
   "Return TERMINAL's value for parameter PARAMETER.
 
 TERMINAL can be a terminal id, a frame, or nil (meaning the
 selected frame's terminal)."
-  (cdr (assq parameter (cdr (assq (terminal-id terminal) terminal-parameter-alist)))))
+  (cdr (terminal-parameter-p terminal parameter)))
 
 (defun set-terminal-parameter (terminal parameter value)
   "Set TERMINAL's value for parameter PARAMETER to VALUE.
--- a/lisp/simple.el	Wed Oct 19 14:06:17 2005 +0000
+++ b/lisp/simple.el	Sun Oct 23 22:11:22 2005 +0000
@@ -5237,36 +5237,33 @@
 
 ;;; Handling of Backspace and Delete keys.
 
-(defcustom normal-erase-is-backspace
-  (and (not noninteractive)
-       (or (memq system-type '(ms-dos windows-nt))
-	   (eq initial-window-system 'mac)
-	   (and (memq initial-window-system '(x))
-		(fboundp 'x-backspace-delete-keys-p)
-		(x-backspace-delete-keys-p))
-	   ;; If the terminal Emacs is running on has erase char
-	   ;; set to ^H, use the Backspace key for deleting
-	   ;; backward and, and the Delete key for deleting forward.
-	   (and (null initial-window-system)
-		(eq tty-erase-char ?\^H))))
-  "If non-nil, Delete key deletes forward and Backspace key deletes backward.
-
-On window systems, the default value of this option is chosen
-according to the keyboard used.  If the keyboard has both a Backspace
-key and a Delete key, and both are mapped to their usual meanings, the
-option's default value is set to t, so that Backspace can be used to
-delete backward, and Delete can be used to delete forward.
-
-If not running under a window system, customizing this option accomplishes
-a similar effect by mapping C-h, which is usually generated by the
-Backspace key, to DEL, and by mapping DEL to C-d via
-`keyboard-translate'.  The former functionality of C-h is available on
-the F1 key.  You should probably not use this setting if you don't
-have both Backspace, Delete and F1 keys.
+(defcustom normal-erase-is-backspace 'maybe
+  "Set the default behaviour of the Delete and Backspace keys.
+
+If set to t, Delete key deletes forward and Backspace key deletes
+backward.
+
+If set to nil, both Delete and Backspace keys delete backward.
+
+If set to 'maybe (which is the default), Emacs automatically
+selects a behaviour.  On window systems, the behaviour depends on
+the keyboard used.  If the keyboard has both a Backspace key and
+a Delete key, and both are mapped to their usual meanings, the
+option's default value is set to t, so that Backspace can be used
+to delete backward, and Delete can be used to delete forward.
+
+If not running under a window system, customizing this option
+accomplishes a similar effect by mapping C-h, which is usually
+generated by the Backspace key, to DEL, and by mapping DEL to C-d
+via `keyboard-translate'.  The former functionality of C-h is
+available on the F1 key.  You should probably not use this
+setting if you don't have both Backspace, Delete and F1 keys.
 
 Setting this variable with setq doesn't take effect.  Programmatically,
 call `normal-erase-is-backspace-mode' (which see) instead."
-  :type 'boolean
+  :type '(choice (const :tag "Off" nil)
+		 (const :tag "Maybe" maybe)
+		 (other :tag "On" t))
   :group 'editing-basics
   :version "21.1"
   :set (lambda (symbol value)
@@ -5276,17 +5273,40 @@
 	     (normal-erase-is-backspace-mode (or value 0))
 	   (set-default symbol value))))
 
+(defun normal-erase-is-backspace-setup-frame (&optional frame)
+  "Set up `normal-erase-is-backspace-mode' on FRAME, if necessary."
+  (unless frame (setq frame (selected-frame)))
+  (with-selected-frame frame
+    (unless (terminal-parameter-p nil 'normal-erase-is-backspace)
+      (if (cond ((terminal-parameter-p nil 'normal-erase-is-backspace)
+		 (terminal-parameter nil 'normal-erase-is-backspace))
+		((eq normal-erase-is-backspace 'maybe)
+		 (and (not noninteractive)
+		      (or (memq system-type '(ms-dos windows-nt))
+			  (eq window-system 'mac)
+			  (and (memq window-system '(x))
+			       (fboundp 'x-backspace-delete-keys-p)
+			       (x-backspace-delete-keys-p))
+			  ;; If the terminal Emacs is running on has erase char
+			  ;; set to ^H, use the Backspace key for deleting
+			  ;; backward and, and the Delete key for deleting forward.
+			  (and (null window-system)
+			       (eq tty-erase-char ?\^H)))))
+		(t
+		 normal-erase-is-backspace))
+	  (normal-erase-is-backspace-mode 1)
+	(normal-erase-is-backspace-mode 0)))))
 
 (defun normal-erase-is-backspace-mode (&optional arg)
   "Toggle the Erase and Delete mode of the Backspace and Delete keys.
 
 With numeric arg, turn the mode on if and only if ARG is positive.
 
-On window systems, when this mode is on, Delete is mapped to C-d and
-Backspace is mapped to DEL; when this mode is off, both Delete and
-Backspace are mapped to DEL.  (The remapping goes via
-`function-key-map', so binding Delete or Backspace in the global or
-local keymap will override that.)
+On window systems, when this mode is on, Delete is mapped to C-d
+and Backspace is mapped to DEL; when this mode is off, both
+Delete and Backspace are mapped to DEL.  (The remapping goes via
+`local-function-key-map', so binding Delete or Backspace in the
+global or local keymap will override that.)
 
 In addition, on window systems, the bindings of C-Delete, M-Delete,
 C-M-Delete, C-Backspace, M-Backspace, and C-M-Backspace are changed in
@@ -5308,33 +5328,34 @@
 
 See also `normal-erase-is-backspace'."
   (interactive "P")
-  (setq normal-erase-is-backspace
-	(if arg
-	    (> (prefix-numeric-value arg) 0)
-	  (not normal-erase-is-backspace)))
+  (set-terminal-parameter
+   nil 'normal-erase-is-backspace
+   (if arg
+       (> (prefix-numeric-value arg) 0)
+     (not (terminal-parameter nil 'normal-erase-is-backspace))))
 
   (cond ((or (memq window-system '(x w32 mac pc))
 	     (memq system-type '(ms-dos windows-nt)))
-	 (let ((bindings
-		`(([C-delete] [C-backspace])
-		  ([M-delete] [M-backspace])
-		  ([C-M-delete] [C-M-backspace])
-		  (,esc-map
-		   [C-delete] [C-backspace])))
-	       (old-state (lookup-key function-key-map [delete])))
-
-	   (if normal-erase-is-backspace
+	 (let* ((lfkm (terminal-local-value 'local-function-key-map nil))
+		(bindings
+		 `(([C-delete] [C-backspace])
+		   ([M-delete] [M-backspace])
+		   ([C-M-delete] [C-M-backspace])
+		   (,esc-map
+		    [C-delete] [C-backspace])))
+		(old-state (lookup-key lfkm [delete])))
+
+	   (if (terminal-parameter nil 'normal-erase-is-backspace)
 	       (progn
-		 ;; XXX Perhaps this mode should be terminal-local, not global -- lorentey
-		 (define-key function-key-map [delete] [?\C-d])
-		 (define-key function-key-map [kp-delete] [?\C-d])
-		 (define-key function-key-map [backspace] [?\C-?]))
-	     (define-key function-key-map [delete] [?\C-?])
-	     (define-key function-key-map [kp-delete] [?\C-?])
-	     (define-key function-key-map [backspace] [?\C-?]))
+		 (define-key lfkm [delete] [?\C-d])
+		 (define-key lfkm [kp-delete] [?\C-d])
+		 (define-key lfkm [backspace] [?\C-?]))
+	     (define-key lfkm [delete] [?\C-?])
+	     (define-key lfkm [kp-delete] [?\C-?])
+	     (define-key lfkm [backspace] [?\C-?]))
 
 	   ;; Maybe swap bindings of C-delete and C-backspace, etc.
-	   (unless (equal old-state (lookup-key function-key-map [delete]))
+	   (unless (equal old-state (lookup-key lfkm [delete]))
 	     (dolist (binding bindings)
 	       (let ((map global-map))
 		 (when (keymapp (car binding))
@@ -5346,8 +5367,9 @@
 		   (define-key map key1 binding2)
 		   (define-key map key2 binding1)))))))
 	 (t
-	  (if normal-erase-is-backspace
+	  (if (terminal-parameter nil 'normal-erase-is-backspace)
 	      (progn
+		;; XXX This should be terminal-local -- lorentey
 		(keyboard-translate ?\C-h ?\C-?)
 		(keyboard-translate ?\C-? ?\C-d))
 	    (keyboard-translate ?\C-h ?\C-h)
--- a/lisp/startup.el	Wed Oct 19 14:06:17 2005 +0000
+++ b/lisp/startup.el	Sun Oct 23 22:11:22 2005 +0000
@@ -756,9 +756,10 @@
   ;; Can't do this init in defcustom because the relevant variables
   ;; are not set.
   (custom-reevaluate-setting 'blink-cursor-mode)
-  (custom-reevaluate-setting 'normal-erase-is-backspace)
   (custom-reevaluate-setting 'tooltip-mode)
 
+  (normal-erase-is-backspace-setup-frame)
+
   ;; Register default TTY colors for the case the terminal hasn't a
   ;; terminal init file.
   ;; We do this regardles of whether the terminal supports colors