;;; 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>
;; 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)
"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)
(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.
(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
: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)
(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)
(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
;; 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"))
;;; 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
: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")
(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)))))))
(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
(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)
(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)))
((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
((eq parameter 5)
(setq term-ansi-current-bold t))
-;;; Reverse
+;;; Reverse (terminfo: smso)
((eq parameter 7)
(setq term-ansi-current-reverse t))
((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))
(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
)
;; \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
;; \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)
(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.
;;; 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))
(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)))))))