;;; 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)
(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)))))))