]> code.delx.au - gnu-emacs/blobdiff - lisp/term.el
(cancel-change-group): Add listp around pending-undo-list.
[gnu-emacs] / lisp / term.el
index b7d2d4c59b03ae0446a95c9ec83440704a28f05a..62728f45a0808ccae916d983c89393a368a24080 100644 (file)
@@ -1,6 +1,7 @@
 ;;; term.el --- general command interpreter in a window stuff
 
-;;; Copyright (C) 1988, 1990, 1992, 1994, 1995, 2004 Free Software Foundation, Inc.
+;; Copyright (C) 1988, 1990, 1992, 1994, 1995, 2002, 2003,
+;;   2004, 2005 Free Software Foundation, Inc.
 
 ;; Author: Per Bothner <per@bothner.com>
 ;; Maintainer: Dan Nicolaescu <dann@ics.uci.edu>, Per Bothner <per@bothner.com>
@@ -21,8 +22,8 @@
 
 ;; You should have received a copy of the GNU General Public License
 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
 
 ;;; Marck 13 2001
 ;;; Fixes for CJK support by Yong Lu <lyongu@yahoo.com>.
 (require 'ehelp)
 
 (defgroup term nil
-  "General command interpreter in a window"
+  "General command interpreter in a window."
   :group 'processes
   :group 'unix)
 
@@ -570,8 +571,8 @@ This variable is buffer-local."
   "Function that submits old text in term mode.
 This function is called when return is typed while the point is in old text.
 It returns the text to be submitted as process input.  The default is
-term-get-old-input-default, which grabs the current line, and strips off
-leading text matching term-prompt-regexp")
+`term-get-old-input-default', which grabs the current line, and strips off
+leading text matching `term-prompt-regexp'.")
 
 (defvar term-dynamic-complete-functions
   '(term-replace-by-expanded-history term-dynamic-complete-filename)
@@ -585,7 +586,7 @@ This is a good thing to set in mode hooks.")
   (function (lambda (str) (not (string-match "\\`\\s *\\'" str))))
   "Predicate for filtering additions to input history.
 Only inputs answering true to this function are saved on the input
-history list.  Default is to save anything that isn't all whitespace")
+history list.  Default is to save anything that isn't all whitespace.")
 
 (defvar term-input-filter-functions '()
   "Functions to call before input is sent to the process.
@@ -595,9 +596,9 @@ This variable is buffer-local.")
 
 (defvar term-input-sender (function term-simple-send)
   "Function to actually send to PROCESS the STRING submitted by user.
-Usually this is just 'term-simple-send, but if your mode needs to
+Usually this is just `term-simple-send', but if your mode needs to
 massage the input string, this is your hook.  This is called from
-the user command term-send-input.  `term-simple-send' just sends
+the user command `term-send-input'.  `term-simple-send' just sends
 the string plus a newline.")
 
 (defcustom term-eol-on-send t
@@ -607,16 +608,16 @@ See `term-send-input'."
   :group 'term)
 
 (defcustom term-mode-hook '()
-  "Called upon entry into term-mode
+  "Called upon entry into term mode.
 This is run before the process is cranked up."
   :type 'hook
   :group 'term)
 
 (defcustom term-exec-hook '()
-  "Called each time a process is exec'd by term-exec.
+  "Called each time a process is exec'd by `term-exec'.
 This is called after the process is cranked up.  It is useful for things that
-must be done each time a process is executed in a term-mode buffer (e.g.,
-\(process-kill-without-query)).  In contrast, the term-mode-hook is only
+must be done each time a process is executed in a term mode buffer (e.g.,
+`process-kill-without-query').  In contrast, `term-mode-hook' is only
 executed once when the buffer is created."
   :type 'hook
   :group 'term)
@@ -625,7 +626,7 @@ executed once when the buffer is created."
 (defvar term-raw-map nil
   "Keyboard map for sending characters directly to the inferior process.")
 (defvar term-escape-char nil
-  "Escape character for char-sub-mode of term mode.
+  "Escape character for char sub-mode of term mode.
 Do not change it directly;  use `term-set-escape-char' instead.")
 (defvar term-raw-escape-map nil)
 
@@ -1102,6 +1103,8 @@ Entry to this mode runs the hooks on `term-mode-hook'."
   (make-local-variable 'term-current-face)
   (make-local-variable 'term-pending-frame)
   (setq term-pending-frame nil)
+  ;; Cua-mode's keybindings interfere with the term keybindings, disable it. 
+  (set (make-local-variable 'cua-mode) nil)
   (run-mode-hooks 'term-mode-hook)
   (term-if-xemacs
    (set-buffer-menubar
@@ -1218,6 +1221,7 @@ without any interpretation."
 ;; Which would be better:  "\e[A" or "\eOA"? readline accepts either.
 ;; For my configuration it's definitely better \eOA but YMMV. -mm
 ;; For example: vi works with \eOA while elm wants \e[A ...
+;;; (terminfo: kcuu1, kcud1, kcuf1, kcub1, khome, kend, kpp, knp, kdch1, kbs)
 (defun term-send-up    () (interactive) (term-send-raw-string "\eOA"))
 (defun term-send-down  () (interactive) (term-send-raw-string "\eOB"))
 (defun term-send-right () (interactive) (term-send-raw-string "\eOC"))
@@ -1390,7 +1394,7 @@ The main purpose is to get rid of the local keymap."
 
 ;;; Name to use for TERM.
 ;;; Using "emacs" loses, because bash disables editing if TERM == emacs.
-(defvar term-term-name "eterm")
+(defvar term-term-name "eterm-color")
 ; Format string, usage:
 ; (format term-termcap-string emacs-term-name "TERMCAP=" 24 80)
 (defvar term-termcap-format
@@ -1402,8 +1406,8 @@ The main purpose is to get rid of the local keymap."
 :UP=\\E[%%dA:DO=\\E[%%dB:LE=\\E[%%dD:RI=\\E[%%dC\
 :kl=\\EOD:kd=\\EOB:kr=\\EOC:ku=\\EOA:kN=\\E[6~:kP=\\E[5~:@7=\\E[4~:kh=\\E[1~\
 :mk=\\E[8m:cb=\\E[1K:op=\\E[39;49m:Co#8:pa#64:AB=\\E[4%%dm:AF=\\E[3%%dm:cr=^M\
-:bl=^G:do=^J:le=^H:ta=^I:se=\E[27m:ue=\E24m\
-:kb=^?:kD=^[[3~:sc=\E7:rc=\E8:r1=\Ec:"
+:bl=^G:do=^J:le=^H:ta=^I:se=\\E[27m:ue=\\E24m\
+:kb=^?:kD=^[[3~:sc=\\E7:rc=\\E8:r1=\\Ec:"
 ;;; : -undefine ic
 ;;; don't define :te=\\E[2J\\E[?47l\\E8:ti=\\E7\\E[?47h\
   "termcap capabilities supported")
@@ -1574,7 +1578,7 @@ See also `term-read-input-ring'."
       (sit-for 0)
       (message "Hit space to flush")
       (let ((ch (read-event)))
-       (if (eq ch ?\ )
+       (if (eq ch ?\s)
            (set-window-configuration conf)
          (setq unread-command-events (list ch)))))))
 
@@ -2683,13 +2687,17 @@ See `term-prompt-regexp'."
           (buffer-undo-list t)
           (selected (selected-window))
           last-win
+           handled-ansi-message
           (str-length (length str)))
       (save-selected-window
 
        ;; Let's handle the messages. -mm
 
-       (setq str (term-handle-ansi-terminal-messages str))
-       (setq str-length (length str))
+        (let* ((newstr (term-handle-ansi-terminal-messages str)))
+          (if (not (eq str newstr))
+              (setq handled-ansi-message t
+                    str newstr)))
+        (setq str-length (length str))
 
        (if (marker-buffer term-pending-delete-marker)
            (progn
@@ -2816,7 +2824,7 @@ See `term-prompt-regexp'."
                               (1- (- term-width (term-current-column)))))
                            (when (= term-width (term-current-column))
                              (term-move-columns -1))))
-                        ((eq char ?\r)
+                        ((eq char ?\r)  ;; (terminfo: cr)
                          ;; Optimize CRLF at end of buffer:
                          (cond ((and (< (setq temp (1+ i)) str-length)
                                      (eq (aref str temp) ?\n)
@@ -2832,7 +2840,7 @@ See `term-prompt-regexp'."
                                (t ;; Not followed by LF or can't optimize:
                                 (term-vertical-motion 0)
                                 (setq term-current-column term-start-line-column))))
-                        ((eq char ?\n)
+                        ((eq char ?\n)  ;; (terminfo: cud1, ind)
                          (if (not (and term-kill-echo-list
                                        (term-check-kill-echo-list)))
                              (term-down 1 t)))
@@ -2843,16 +2851,16 @@ See `term-prompt-regexp'."
                         ((eq char 0))         ; NUL: Do nothing
                         ((eq char ?\016))     ; Shift Out - ignored
                         ((eq char ?\017))     ; Shift In - ignored
-                        ((eq char ?\^G)
-                         (beep t))     ; Bell
-                        ((eq char ?\032)
+                        ((eq char ?\^G) ;; (terminfo: bel)
+                         (beep t))
+                        ((and (eq char ?\032)
+                               (not handled-ansi-message))
                          (let ((end (string-match "\r?$" str i)))
                            (if end
                                (funcall term-command-hook
                                         (prog1 (substring str (1+ i) end)
                                           (setq i (match-end 0))))
-                             (setq term-terminal-parameter
-                                   (substring str i))
+                             (setq term-terminal-parameter (substring str i))
                              (setq term-terminal-state 4)
                              (setq i str-length))))
                         (t   ; insert char FIXME: Should never happen
@@ -3069,7 +3077,7 @@ See `term-prompt-regexp'."
    ((eq parameter 5)
     (setq term-ansi-current-bold t))
 
-;;; Reverse
+;;; Reverse (terminfo: smso)
    ((eq parameter 7)
     (setq term-ansi-current-reverse t))
 
@@ -3077,11 +3085,11 @@ See `term-prompt-regexp'."
    ((eq parameter 8)
     (setq term-ansi-current-invisible t))
 
-;;; Reset underline (i.e. terminfo rmul)
+;;; Reset underline (terminfo: rmul)
    ((eq parameter 24)
     (setq term-ansi-current-underline nil))
 
-;;; Reset reverse (i.e. terminfo rmso)
+;;; Reset reverse (terminfo: rmso)
    ((eq parameter 27)
     (setq term-ansi-current-reverse nil))
 
@@ -3186,7 +3194,7 @@ See `term-prompt-regexp'."
 
 (defun term-handle-ansi-escape (proc char)
   (cond
-   ((or (eq char ?H)  ; cursor motion (terminfo: cup)
+   ((or (eq char ?H)  ; cursor motion (terminfo: cup,home)
        ;; (eq char ?f) ; xterm seems to handle this sequence too, not
        ;; needed for now
        )
@@ -3208,7 +3216,7 @@ See `term-prompt-regexp'."
    ;; \E[B - cursor down (terminfo: cud)
    ((eq char ?B)
     (term-down (max 1 term-terminal-parameter) t))
-   ;; \E[C - cursor right (terminfo: cuf)
+   ;; \E[C - cursor right (terminfo: cuf, cuf1)
    ((eq char ?C)
     (term-move-columns
      (max 1
@@ -3227,14 +3235,14 @@ See `term-prompt-regexp'."
    ;; \E[L - insert lines (terminfo: il, il1)
    ((eq char ?L)
     (term-insert-lines (max 1 term-terminal-parameter)))
-   ;; \E[M - delete lines
+   ;; \E[M - delete lines (terminfo: dl, dl1)
    ((eq char ?M)
     (term-delete-lines (max 1 term-terminal-parameter)))
-   ;; \E[P - delete chars
+   ;; \E[P - delete chars (terminfo: dch, dch1)
    ((eq char ?P)
     (term-delete-chars (max 1 term-terminal-parameter)))
-   ;; \E[@ - insert spaces
-   ((eq char ?@) ;; (terminfo: ich)
+   ;; \E[@ - insert spaces (terminfo: ich)
+   ((eq char ?@)
     (term-insert-spaces (max 1 term-terminal-parameter)))
    ;; \E[?h - DEC Private Mode Set
    ((eq char ?h)
@@ -3612,21 +3620,32 @@ all pending output has been dealt with."))
 (defun term-down (down &optional check-for-scroll)
   "Move down DOWN screen lines vertically."
   (let ((start-column (term-horizontal-column)))
-    (if (and check-for-scroll (or term-scroll-with-delete term-pager-count))
-       (setq down (term-handle-scroll down)))
-    (term-adjust-current-row-cache down)
-    (if (or (/= (point) (point-max)) (< down 0))
-       (setq down (- down (term-vertical-motion down))))
-    ;; Extend buffer with extra blank lines if needed.
+    (when (and check-for-scroll (or term-scroll-with-delete term-pager-count))
+      (setq down (term-handle-scroll down)))
+    (unless (and (= term-current-row 0) (< down 0))
+      (term-adjust-current-row-cache down)
+      (when (or (/= (point) (point-max)) (< down 0))
+       (setq down (- down (term-vertical-motion down)))))
     (cond ((> down 0)
+          ;; Extend buffer with extra blank lines if needed.
           (term-insert-char ?\n down)
           (setq term-current-column 0)
           (setq term-start-line-column 0))
          (t
-          (setq term-current-column nil)
+          (when (= term-current-row 0)
+            ;; Insert lines if at the beginning.
+            (save-excursion (term-insert-char ?\n (- down)))
+            (save-excursion
+              (let (p)
+                ;; Delete lines from the end.
+                (forward-line term-height)
+                (setq p (point))
+                (forward-line (- down))
+                (delete-region p (point)))))
+          (setq term-current-column 0)
           (setq term-start-line-column (current-column))))
-    (if start-column
-       (term-move-columns start-column))))
+    (when start-column
+      (term-move-columns start-column))))
 
 ;; Assuming point is at the beginning of a screen line,
 ;; if the line above point wraps around, add a ?\n to undo the wrapping.
@@ -3692,7 +3711,7 @@ Should only be called when point is at the start of a screen line."
 
 ;;; Insert COUNT spaces after point, but do not change any of
 ;;; following screen lines.  Hence we may have to delete characters
-;;; at teh end of this screen line to make room.
+;;; at the end of this screen line to make room.
 
 (defun term-insert-spaces (count)
   (let ((save-point (point)) (save-eol) (point-at-eol))
@@ -4045,7 +4064,7 @@ Typing SPC flushes the help buffer."
          (progn
            (mouse-choose-completion first)
            (set-window-configuration conf))
-       (if (eq first ?\ )
+       (if (eq first ?\s)
            (set-window-configuration conf)
          (setq unread-command-events (listify-key-sequence key)))))))