diff options
| -rw-r--r-- | lisp/term.el | 101 |
1 files changed, 36 insertions, 65 deletions
diff --git a/lisp/term.el b/lisp/term.el index fdcc39de722..e759bb8e4fd 100644 --- a/lisp/term.el +++ b/lisp/term.el | |||
| @@ -284,17 +284,6 @@ | |||
| 284 | ;; merge them into the master source. | 284 | ;; merge them into the master source. |
| 285 | ;; - Per Bothner (bothner@cygnus.com) | 285 | ;; - Per Bothner (bothner@cygnus.com) |
| 286 | 286 | ||
| 287 | ;; This file defines a general command-interpreter-in-a-buffer package | ||
| 288 | ;; (term mode). The idea is that you can build specific process-in-a-buffer | ||
| 289 | ;; modes on top of term mode -- e.g., lisp, shell, scheme, T, soar, .... | ||
| 290 | ;; This way, all these specific packages share a common base functionality, | ||
| 291 | ;; and a common set of bindings, which makes them easier to use (and | ||
| 292 | ;; saves code, implementation time, etc., etc.). | ||
| 293 | |||
| 294 | ;; For hints on converting existing process modes (e.g., tex-mode, | ||
| 295 | ;; background, dbx, gdb, kermit, prolog, telnet) to use term-mode | ||
| 296 | ;; instead of shell-mode, see the notes at the end of this file. | ||
| 297 | |||
| 298 | 287 | ||
| 299 | ;; Brief Command Documentation: | 288 | ;; Brief Command Documentation: |
| 300 | ;;============================================================================ | 289 | ;;============================================================================ |
| @@ -406,7 +395,9 @@ This emulates (more or less) the behavior of xterm.") | |||
| 406 | (defvar term-pager-count nil | 395 | (defvar term-pager-count nil |
| 407 | "Number of lines before we need to page; if nil, paging is disabled.") | 396 | "Number of lines before we need to page; if nil, paging is disabled.") |
| 408 | (defvar term-saved-cursor nil) | 397 | (defvar term-saved-cursor nil) |
| 409 | (defvar term-command-hook) | 398 | (define-obsolete-variable-alias 'term-command-hook |
| 399 | 'term-command-function "27.1") | ||
| 400 | (defvar term-command-function #'term-command-hook) | ||
| 410 | (defvar term-log-buffer nil) | 401 | (defvar term-log-buffer nil) |
| 411 | (defvar term-scroll-with-delete nil | 402 | (defvar term-scroll-with-delete nil |
| 412 | "If t, forward scrolling should be implemented by delete to | 403 | "If t, forward scrolling should be implemented by delete to |
| @@ -546,8 +537,7 @@ This means text can automatically reflow if the window is resized." | |||
| 546 | :type 'boolean | 537 | :type 'boolean |
| 547 | :group 'term) | 538 | :group 'term) |
| 548 | (make-obsolete-variable 'term-suppress-hard-newline nil | 539 | (make-obsolete-variable 'term-suppress-hard-newline nil |
| 549 | "27.1" | 540 | "27.1") |
| 550 | 'set) | ||
| 551 | 541 | ||
| 552 | ;; Where gud-display-frame should put the debugging arrow. This is | 542 | ;; Where gud-display-frame should put the debugging arrow. This is |
| 553 | ;; set by the marker-filter, which scans the debugger's output for | 543 | ;; set by the marker-filter, which scans the debugger's output for |
| @@ -582,7 +572,7 @@ These functions get one argument, a string containing the text to send. | |||
| 582 | 572 | ||
| 583 | This variable is buffer-local.") | 573 | This variable is buffer-local.") |
| 584 | 574 | ||
| 585 | (defvar term-input-sender (function term-simple-send) | 575 | (defvar term-input-sender #'term-simple-send |
| 586 | "Function to actually send to PROCESS the STRING submitted by user. | 576 | "Function to actually send to PROCESS the STRING submitted by user. |
| 587 | Usually this is just `term-simple-send', but if your mode needs to | 577 | Usually this is just `term-simple-send', but if your mode needs to |
| 588 | massage the input string, this is your hook. This is called from | 578 | massage the input string, this is your hook. This is called from |
| @@ -1039,8 +1029,6 @@ Entry to this mode runs the hooks on `term-mode-hook'." | |||
| 1039 | (set (make-local-variable 'term-last-input-start) (make-marker)) | 1029 | (set (make-local-variable 'term-last-input-start) (make-marker)) |
| 1040 | (set (make-local-variable 'term-last-input-end) (make-marker)) | 1030 | (set (make-local-variable 'term-last-input-end) (make-marker)) |
| 1041 | (set (make-local-variable 'term-last-input-match) "") | 1031 | (set (make-local-variable 'term-last-input-match) "") |
| 1042 | (set (make-local-variable 'term-command-hook) | ||
| 1043 | (symbol-function 'term-command-hook)) | ||
| 1044 | 1032 | ||
| 1045 | ;; These local variables are set to their local values: | 1033 | ;; These local variables are set to their local values: |
| 1046 | (make-local-variable 'term-saved-home-marker) | 1034 | (make-local-variable 'term-saved-home-marker) |
| @@ -1094,21 +1082,18 @@ Entry to this mode runs the hooks on `term-mode-hook'." | |||
| 1094 | (make-local-variable 'term-pager-old-local-map) | 1082 | (make-local-variable 'term-pager-old-local-map) |
| 1095 | (make-local-variable 'term-old-mode-map) | 1083 | (make-local-variable 'term-old-mode-map) |
| 1096 | (make-local-variable 'term-insert-mode) | 1084 | (make-local-variable 'term-insert-mode) |
| 1097 | (make-local-variable 'term-dynamic-complete-functions) | ||
| 1098 | (make-local-variable 'term-completion-fignore) | 1085 | (make-local-variable 'term-completion-fignore) |
| 1099 | (make-local-variable 'term-get-old-input) | 1086 | (make-local-variable 'term-get-old-input) |
| 1100 | (make-local-variable 'term-matching-input-from-input-string) | 1087 | (make-local-variable 'term-matching-input-from-input-string) |
| 1101 | (make-local-variable 'term-input-autoexpand) | 1088 | (make-local-variable 'term-input-autoexpand) |
| 1102 | (make-local-variable 'term-input-ignoredups) | 1089 | (make-local-variable 'term-input-ignoredups) |
| 1103 | (make-local-variable 'term-delimiter-argument-list) | 1090 | (make-local-variable 'term-delimiter-argument-list) |
| 1104 | (make-local-variable 'term-input-filter-functions) | ||
| 1105 | (make-local-variable 'term-input-filter) | 1091 | (make-local-variable 'term-input-filter) |
| 1106 | (make-local-variable 'term-input-sender) | 1092 | (make-local-variable 'term-input-sender) |
| 1107 | (make-local-variable 'term-eol-on-send) | 1093 | (make-local-variable 'term-eol-on-send) |
| 1108 | (make-local-variable 'term-scroll-to-bottom-on-output) | 1094 | (make-local-variable 'term-scroll-to-bottom-on-output) |
| 1109 | (make-local-variable 'term-scroll-show-maximum-output) | 1095 | (make-local-variable 'term-scroll-show-maximum-output) |
| 1110 | (make-local-variable 'term-ptyp) | 1096 | (make-local-variable 'term-ptyp) |
| 1111 | (make-local-variable 'term-exec-hook) | ||
| 1112 | (set (make-local-variable 'term-vertical-motion) 'vertical-motion) | 1097 | (set (make-local-variable 'term-vertical-motion) 'vertical-motion) |
| 1113 | (set (make-local-variable 'term-pending-delete-marker) (make-marker)) | 1098 | (set (make-local-variable 'term-pending-delete-marker) (make-marker)) |
| 1114 | (make-local-variable 'term-current-face) | 1099 | (make-local-variable 'term-current-face) |
| @@ -1144,7 +1129,7 @@ Entry to this mode runs the hooks on `term-mode-hook'." | |||
| 1144 | (while (setq fake-newline (next-single-property-change (point) | 1129 | (while (setq fake-newline (next-single-property-change (point) |
| 1145 | 'term-line-wrap)) | 1130 | 'term-line-wrap)) |
| 1146 | (goto-char fake-newline) | 1131 | (goto-char fake-newline) |
| 1147 | (assert (eq ?\n (char-after))) | 1132 | (cl-assert (eq ?\n (char-after))) |
| 1148 | (let ((inhibit-read-only t)) | 1133 | (let ((inhibit-read-only t)) |
| 1149 | (delete-char 1))))) | 1134 | (delete-char 1))))) |
| 1150 | 1135 | ||
| @@ -1329,16 +1314,14 @@ intervention from Emacs, except for the escape character (usually C-c)." | |||
| 1329 | (add-hook 'post-command-hook #'term-goto-process-mark-maybe nil t) | 1314 | (add-hook 'post-command-hook #'term-goto-process-mark-maybe nil t) |
| 1330 | 1315 | ||
| 1331 | ;; Send existing partial line to inferior (without newline). | 1316 | ;; Send existing partial line to inferior (without newline). |
| 1332 | (let ((pmark (process-mark (get-buffer-process (current-buffer)))) | 1317 | (let ((pmark (process-mark (get-buffer-process (current-buffer))))) |
| 1333 | (save-input-sender term-input-sender)) | ||
| 1334 | (when (> (point) pmark) | 1318 | (when (> (point) pmark) |
| 1335 | (unwind-protect | 1319 | (unwind-protect |
| 1336 | (progn | 1320 | (progn |
| 1337 | (setq term-input-sender | 1321 | (add-function :override term-input-sender #'term-send-string) |
| 1338 | (symbol-function 'term-send-string)) | ||
| 1339 | (end-of-line) | 1322 | (end-of-line) |
| 1340 | (term-send-input)) | 1323 | (term-send-input)) |
| 1341 | (setq term-input-sender save-input-sender)))) | 1324 | (remove-function term-input-sender #'term-send-string)))) |
| 1342 | (term-update-mode-line))) | 1325 | (term-update-mode-line))) |
| 1343 | 1326 | ||
| 1344 | (defun term-line-mode () | 1327 | (defun term-line-mode () |
| @@ -1468,8 +1451,8 @@ buffer. The hook `term-exec-hook' is run after each exec." | |||
| 1468 | ;; Jump to the end, and set the process mark. | 1451 | ;; Jump to the end, and set the process mark. |
| 1469 | (goto-char (point-max)) | 1452 | (goto-char (point-max)) |
| 1470 | (set-marker (process-mark proc) (point)) | 1453 | (set-marker (process-mark proc) (point)) |
| 1471 | (set-process-filter proc 'term-emulate-terminal) | 1454 | (set-process-filter proc #'term-emulate-terminal) |
| 1472 | (set-process-sentinel proc 'term-sentinel) | 1455 | (set-process-sentinel proc #'term-sentinel) |
| 1473 | ;; Feed it the startfile. | 1456 | ;; Feed it the startfile. |
| 1474 | (when startfile | 1457 | (when startfile |
| 1475 | ;;This is guaranteed to wait long enough | 1458 | ;;This is guaranteed to wait long enough |
| @@ -1598,7 +1581,7 @@ Nil if unknown.") | |||
| 1598 | (when (term--bash-needs-EMACSp) | 1581 | (when (term--bash-needs-EMACSp) |
| 1599 | (push (format "EMACS=%s (term:%s)" emacs-version term-protocol-version) | 1582 | (push (format "EMACS=%s (term:%s)" emacs-version term-protocol-version) |
| 1600 | process-environment)) | 1583 | process-environment)) |
| 1601 | (apply 'start-process name buffer | 1584 | (apply #'start-process name buffer |
| 1602 | "/bin/sh" "-c" | 1585 | "/bin/sh" "-c" |
| 1603 | (format "stty -nl echo rows %d columns %d sane 2>/dev/null;\ | 1586 | (format "stty -nl echo rows %d columns %d sane 2>/dev/null;\ |
| 1604 | if [ $1 = .. ]; then shift; fi; exec \"$@\"" | 1587 | if [ $1 = .. ]; then shift; fi; exec \"$@\"" |
| @@ -2092,7 +2075,7 @@ Argument 0 is the command name." | |||
| 2092 | (let ((n (or nth (1- count))) | 2075 | (let ((n (or nth (1- count))) |
| 2093 | (m (if mth (1- (- count mth)) 0))) | 2076 | (m (if mth (1- (- count mth)) 0))) |
| 2094 | (mapconcat | 2077 | (mapconcat |
| 2095 | (function (lambda (a) a)) (nthcdr n (nreverse (nthcdr m args))) " ")))) | 2078 | #'identity (nthcdr n (nreverse (nthcdr m args))) " ")))) |
| 2096 | 2079 | ||
| 2097 | ;;; | 2080 | ;;; |
| 2098 | ;;; Input processing stuff [line mode] | 2081 | ;;; Input processing stuff [line mode] |
| @@ -2172,10 +2155,7 @@ Similarly for Soar, Scheme, etc." | |||
| 2172 | (not (string-equal (ring-ref term-input-ring 0) | 2155 | (not (string-equal (ring-ref term-input-ring 0) |
| 2173 | history)))) | 2156 | history)))) |
| 2174 | (ring-insert term-input-ring history)) | 2157 | (ring-insert term-input-ring history)) |
| 2175 | (let ((functions term-input-filter-functions)) | 2158 | (run-hook-with-args 'term-input-filter-functions (concat input "\n")) |
| 2176 | (while functions | ||
| 2177 | (funcall (car functions) (concat input "\n")) | ||
| 2178 | (setq functions (cdr functions)))) | ||
| 2179 | (setq term-input-ring-index nil) | 2159 | (setq term-input-ring-index nil) |
| 2180 | 2160 | ||
| 2181 | ;; Update the markers before we send the input | 2161 | ;; Update the markers before we send the input |
| @@ -3009,7 +2989,7 @@ See `term-prompt-regexp'." | |||
| 3009 | (?\C-g ;; (terminfo: bel) | 2989 | (?\C-g ;; (terminfo: bel) |
| 3010 | (beep t)) | 2990 | (beep t)) |
| 3011 | (?\032 ; Emacs specific control sequence. | 2991 | (?\032 ; Emacs specific control sequence. |
| 3012 | (funcall term-command-hook | 2992 | (funcall term-command-function |
| 3013 | (decode-coding-string | 2993 | (decode-coding-string |
| 3014 | (substring str (1+ i) | 2994 | (substring str (1+ i) |
| 3015 | (- ctl-end | 2995 | (- ctl-end |
| @@ -3103,8 +3083,10 @@ See `term-prompt-regexp'." | |||
| 3103 | (setq term-terminal-undecoded-bytes (substring str (1- i))) | 3083 | (setq term-terminal-undecoded-bytes (substring str (1- i))) |
| 3104 | (aset term-terminal-undecoded-bytes 0 ?\r)) | 3084 | (aset term-terminal-undecoded-bytes 0 ?\r)) |
| 3105 | (goto-char (point-max))) | 3085 | (goto-char (point-max))) |
| 3086 | ;; FIXME: Use (add-function :override (process-filter proc) | ||
| 3106 | (make-local-variable 'term-pager-old-filter) | 3087 | (make-local-variable 'term-pager-old-filter) |
| 3107 | (setq term-pager-old-filter (process-filter proc)) | 3088 | (setq term-pager-old-filter (process-filter proc)) |
| 3089 | ;; FIXME: Where is `term-pager-filter' set to a function?! | ||
| 3108 | (set-process-filter proc term-pager-filter) | 3090 | (set-process-filter proc term-pager-filter) |
| 3109 | (setq i str-length)) | 3091 | (setq i str-length)) |
| 3110 | (setq i ctl-end))))) | 3092 | (setq i ctl-end))))) |
| @@ -3486,7 +3468,7 @@ The top-most line is line 0." | |||
| 3486 | ;; (setq term-current-row 0) | 3468 | ;; (setq term-current-row 0) |
| 3487 | ;; (term-goto row col)))) | 3469 | ;; (term-goto row col)))) |
| 3488 | 3470 | ||
| 3489 | ;; Default value for the symbol term-command-hook. | 3471 | ;; Default value for the symbol term-command-function. |
| 3490 | 3472 | ||
| 3491 | (defun term-command-hook (string) | 3473 | (defun term-command-hook (string) |
| 3492 | (cond ((equal string "") | 3474 | (cond ((equal string "") |
| @@ -4040,9 +4022,7 @@ Calls the functions in `term-dynamic-complete-functions' to perform | |||
| 4040 | completion until a function returns non-nil, at which point completion is | 4022 | completion until a function returns non-nil, at which point completion is |
| 4041 | assumed to have occurred." | 4023 | assumed to have occurred." |
| 4042 | (interactive) | 4024 | (interactive) |
| 4043 | (let ((functions term-dynamic-complete-functions)) | 4025 | (run-hook-with-args-until-success 'term-dynamic-complete-functions)) |
| 4044 | (while (and functions (null (funcall (car functions)))) | ||
| 4045 | (setq functions (cdr functions))))) | ||
| 4046 | 4026 | ||
| 4047 | 4027 | ||
| 4048 | (defun term-dynamic-complete-filename () | 4028 | (defun term-dynamic-complete-filename () |
| @@ -4142,7 +4122,6 @@ Returns `listed' if a completion listing was shown. | |||
| 4142 | See also `term-dynamic-complete-filename'." | 4122 | See also `term-dynamic-complete-filename'." |
| 4143 | (declare (obsolete completion-in-region "23.2")) | 4123 | (declare (obsolete completion-in-region "23.2")) |
| 4144 | (let* ((completion-ignore-case nil) | 4124 | (let* ((completion-ignore-case nil) |
| 4145 | (candidates (mapcar (function (lambda (x) (list x))) candidates)) | ||
| 4146 | (completions (all-completions stub candidates))) | 4125 | (completions (all-completions stub candidates))) |
| 4147 | (cond ((null completions) | 4126 | (cond ((null completions) |
| 4148 | (message "No completions of %s" stub) | 4127 | (message "No completions of %s" stub) |
| @@ -4367,9 +4346,9 @@ well as the newer ports COM10 and higher." | |||
| 4367 | (setq serial-name-history file-name-history)) | 4346 | (setq serial-name-history file-name-history)) |
| 4368 | (when (or (null x) (and (stringp x) (zerop (length x)))) | 4347 | (when (or (null x) (and (stringp x) (zerop (length x)))) |
| 4369 | (error "No serial port selected")) | 4348 | (error "No serial port selected")) |
| 4370 | (when (and (not (serial-port-is-file-p)) | 4349 | (when (not (or (serial-port-is-file-p) |
| 4371 | (not (string-match "\\\\" x))) | 4350 | (string-match "\\\\" x))) |
| 4372 | (set 'x (concat "\\\\.\\" x))) | 4351 | (setq x (concat "\\\\.\\" x))) |
| 4373 | x)) | 4352 | x)) |
| 4374 | 4353 | ||
| 4375 | (defun serial-read-speed () | 4354 | (defun serial-read-speed () |
| @@ -4423,8 +4402,8 @@ use in that buffer. | |||
| 4423 | (term-char-mode) | 4402 | (term-char-mode) |
| 4424 | (goto-char (point-max)) | 4403 | (goto-char (point-max)) |
| 4425 | (set-marker (process-mark process) (point)) | 4404 | (set-marker (process-mark process) (point)) |
| 4426 | (set-process-filter process 'term-emulate-terminal) | 4405 | (set-process-filter process #'term-emulate-terminal) |
| 4427 | (set-process-sentinel process 'term-sentinel)) | 4406 | (set-process-sentinel process #'term-sentinel)) |
| 4428 | (switch-to-buffer buffer) | 4407 | (switch-to-buffer buffer) |
| 4429 | buffer)) | 4408 | buffer)) |
| 4430 | 4409 | ||
| @@ -4561,27 +4540,19 @@ The return value may be nil for a special serial port." | |||
| 4561 | ;; term-mode will take care of it. The following example, from shell.el, | 4540 | ;; term-mode will take care of it. The following example, from shell.el, |
| 4562 | ;; is typical: | 4541 | ;; is typical: |
| 4563 | ;; | 4542 | ;; |
| 4564 | ;; (defvar shell-mode-map '()) | 4543 | ;; (defvar shell-mode-map |
| 4565 | ;; (cond ((not shell-mode-map) | 4544 | ;; (let ((map (make-sparse-keymap))) |
| 4566 | ;; (setq shell-mode-map (copy-keymap term-mode-map)) | 4545 | ;; (define-key map "\C-c\C-f" 'shell-forward-command) |
| 4567 | ;; (define-key shell-mode-map "\C-c\C-f" 'shell-forward-command) | 4546 | ;; (define-key map "\C-c\C-b" 'shell-backward-command) |
| 4568 | ;; (define-key shell-mode-map "\C-c\C-b" 'shell-backward-command) | 4547 | ;; (define-key map "\t" 'term-dynamic-complete) |
| 4569 | ;; (define-key shell-mode-map "\t" 'term-dynamic-complete) | 4548 | ;; (define-key map "\M-?" |
| 4570 | ;; (define-key shell-mode-map "\M-?" | 4549 | ;; 'term-dynamic-list-filename-completions))) |
| 4571 | ;; 'term-dynamic-list-filename-completions))) | ||
| 4572 | ;; | ||
| 4573 | ;; (defun shell-mode () | ||
| 4574 | ;; (interactive) | ||
| 4575 | ;; (term-mode) | ||
| 4576 | ;; (setq term-prompt-regexp shell-prompt-pattern) | ||
| 4577 | ;; (setq major-mode 'shell-mode) | ||
| 4578 | ;; (setq mode-name "Shell") | ||
| 4579 | ;; (use-local-map shell-mode-map) | ||
| 4580 | ;; (make-local-variable 'shell-directory-stack) | ||
| 4581 | ;; (setq shell-directory-stack nil) | ||
| 4582 | ;; (add-hook 'term-input-filter-functions 'shell-directory-tracker) | ||
| 4583 | ;; (run-mode-hooks 'shell-mode-hook)) | ||
| 4584 | ;; | 4550 | ;; |
| 4551 | ;; (define-derived-mode shell-mode term-mode "Shell" | ||
| 4552 | ;; "A shell mode." | ||
| 4553 | ;; (setq-local term-prompt-regexp shell-prompt-pattern) | ||
| 4554 | ;; (setq-local shell-directory-stack nil) | ||
| 4555 | ;; (add-hook 'term-input-filter-functions #'shell-directory-tracker nil t)) | ||
| 4585 | ;; | 4556 | ;; |
| 4586 | ;; Completion for term-mode users | 4557 | ;; Completion for term-mode users |
| 4587 | ;; | 4558 | ;; |