term.el 163 KB
Newer Older
Richard M. Stallman's avatar
Richard M. Stallman committed
1 2
;;; term.el --- general command interpreter in a window stuff

Glenn Morris's avatar
Glenn Morris committed
3
;; Copyright (C) 1988, 1990, 1992, 1994, 1995, 2001, 2002, 2003,
Glenn Morris's avatar
Glenn Morris committed
4
;;   2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
Richard M. Stallman's avatar
Richard M. Stallman committed
5

Richard M. Stallman's avatar
Richard M. Stallman committed
6 7
;; Author: Per Bothner <per@bothner.com>
;; Maintainer: Dan Nicolaescu <dann@ics.uci.edu>, Per Bothner <per@bothner.com>
8 9
;; Based on comint mode written by: Olin Shivers <shivers@cs.cmu.edu>
;; Keywords: processes
Richard M. Stallman's avatar
Richard M. Stallman committed
10

11 12 13 14
;; This file is part of GNU Emacs.

;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
15
;; the Free Software Foundation; either version 3, or (at your option)
16 17 18 19 20 21 22 23 24
;; any later version.

;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; 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
Lute Kamstra's avatar
Lute Kamstra committed
25 26
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.
27

28 29 30
;;; Marck 13 2001
;;; Fixes for CJK support by Yong Lu <lyongu@yahoo.com>.

31 32
;;; Dir/Hostname tracking and ANSI colorization by
;;; Marco Melgazzi <marco@techie.com>.
Richard M. Stallman's avatar
Richard M. Stallman committed
33

34
;;; To see what I've modified and where it came from search for '-mm'
Richard M. Stallman's avatar
Richard M. Stallman committed
35

36 37
;;; Commentary:

38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337
;;; Speed considerations and a few caveats
;;; --------------------------------------
;;;
;;; While the message passing and the colorization surely introduce some
;;; overhead this has became so small that IMHO is surely outweighted by
;;; the benefits you get but, as usual, YMMV
;;;
;;; Important caveat, when deciding the cursor/'grey keys' keycodes I had to
;;; make a choice: on my Linux box this choice allows me to run all the
;;; ncurses applications without problems but make these keys
;;; uncomprehensible to all the cursesX programs.  Your mileage may vary so
;;; you may consider changing the default 'emulation'.  Just search for this
;;; piece of code and modify it as you like:
;;;
;;; ;; 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 ...
;;; (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"))
;;; (defun term-send-left  () (interactive) (term-send-raw-string "\eOD"))
;;;
;;;
;;; IMPORTANT: additions & changes
;;; ------------------------------
;;;
;;;  With this enhanced ansi-term.el you will get a reliable mechanism of
;;; directory/username/host tracking: the only drawback is that you will
;;; have to modify your shell start-up script.  It's worth it, believe me :).
;;;
;;; When you rlogin/su/telnet and the account you access has a modified
;;; startup script, you will be able to access the remote files as usual
;;; with C-x C-f, if it's needed you will have to enter a password,
;;; otherwise the file should get loaded straight away.
;;;
;;; This is useful even if you work only on one host: it often happens that,
;;; for maintenance reasons, you have to edit files 'as root': before
;;; patching term.el, I su-ed in a term.el buffer and used vi :), now I
;;; simply do a C-x C-f and, via ange-ftp, the file is automatically loaded
;;; 'as-root'.  ( If you don't want to enter the root password every time you
;;; can put it in your .netrc: note that this is -not- advisable if you're
;;; connected to the internet or if somebody else works on your workstation!)
;;;
;;; If you use wu-ftpd you can use some of its features to avoid root ftp
;;; access to the rest of the world: just put in /etc/ftphosts something like
;;;
;;; # Local access
;;; allow	root		127.0.0.1
;;;
;;; # By default nobody can't do anything
;;; deny	root		*
;;;
;;;
;;;             ----------------------------------------
;;;
;;;  If, instead of 'term', you call 'ansi-term', you get multiple term
;;; buffers, after every new call ansi-term opens a new *ansi-term*<xx> window,
;;; where <xx> is, as usual, a number...
;;;
;;;             ----------------------------------------
;;;
;;;  With the term-buffer-maximum-size you can finally decide how many
;;; scrollback lines to keep: its default is 2048 but you can change it as
;;; usual.
;;;
;;;             ----------------------------------------
;;;
;;;
;;;  ANSI colorization should work well, I've decided to limit the interpreter
;;; to five outstanding commands (like ESC [ 01;04;32;41;07m.
;;;  You shouldn't need more, if you do, tell me and I'll increase it.  It's
;;; so easy you could do it yourself...
;;;
;;;  Blink, is not supported.  Currently it's mapped as bold.
;;;
;;; Important caveat:
;;; -----------------
;;;   if you want custom colors in term.el redefine term-default-fg-color
;;;  and term-default-bg-color BEFORE loading it.
;;;
;;;             ----------------------------------------
;;;
;;;  If you'd like to check out my complete configuration, you can download
;;; it from http://www.polito.it/~s64912/things.html, it's ~500k in size and
;;; contains my .cshrc, .emacs and my whole site-lisp subdirectory.  (notice
;;; that this term.el may be newer/older than the one in there, please
;;; check!)
;;;
;;;  This complete configuration contains, among other things, a complete
;;; rectangular marking solution (based on rect-mark.el and
;;; pc-bindings.el) and should be a good example of how extensively Emacs
;;; can be configured on a ppp-connected ws.
;;;
;;;             ----------------------------------------
;;;
;;;  TODO:
;;;
;;;  - Add hooks to allow raw-mode keys to be configurable
;;;  - Which keys are better ? \eOA or \e[A ?
;;;
;;;
;;;  Changes:
;;;
;;; V4.0 January 1997
;;;
;;;   - Huge reworking of the faces code: now we only have roughly 20-30
;;;     faces for everything so we're even faster than the old md-term.el !
;;;   - Finished removing all the J-Shell code.
;;;
;;;  V3.0 January 1997
;;;
;;;  - Now all the supportable ANSI commands work well.
;;;  - Reworked a little the code: much less jsh-inspired stuff
;;;
;;;  V2.3 November
;;;
;;;  - Now all the faces are accessed through an array: much cleaner code.
;;;
;;;  V2.2 November 4 1996
;;;
;;;  - Implemented ANSI output colorization ( a bit rough but enough for
;;;    color_ls )
;;;
;;;  - Implemented a maximum limit for the scroll buffer (stolen from
;;;    comint.el)
;;;
;;;  v2.1 October 28 1996, first public release
;;;
;;;  - Some new keybindings for term-char mode ( notably home/end/...)
;;;  - Directory, hostname and username tracking via ange-ftp
;;;  - Multi-term capability via the ansi-term call
;;;
;;;  ----------------------------------------------------------------
;;;  You should/could have something like this in your .emacs to take
;;;  full advantage of this package
;;;
;;;  (add-hook 'term-mode-hook
;;;  		  (function
;;;  		   (lambda ()
;;;  			 (setq term-prompt-regexp "^[^#$%>\n]*[#$%>] *")
;;;  			 (make-local-variable 'mouse-yank-at-point)
;;;  			 (make-local-variable 'transient-mark-mode)
;;;  			 (setq mouse-yank-at-point t)
;;;  			 (setq transient-mark-mode nil)
;;;  			 (auto-fill-mode -1)
;;;  			 (setq tab-width 8 ))))
;;;
;;;
;;;             ----------------------------------------
;;;
;;;  If you want to use color ls the best setup is to have a different file
;;; when you use eterm ( see above, mine is named .emacs_dircolors ).  This
;;; is necessary because some terminals, rxvt for example, need non-ansi
;;; hacks to work ( for example on my rxvt white is wired to fg, and to
;;; obtain normal white I have to do bold-white :)
;;;
;;;             ----------------------------------------
;;;
;;;
;;;  # Configuration file for the color ls utility
;;;  # This file goes in the /etc directory, and must be world readable.
;;;  # You can copy this file to .dir_colors in your $HOME directory to
;;;  # override the system defaults.
;;;
;;;  # COLOR needs one of these arguments: 'tty' colorizes output to ttys, but
;;;  # not pipes.  'all' adds color characters to all output.  'none' shuts
;;;  # colorization off.
;;;  COLOR tty
;;;  OPTIONS -F
;;;
;;;  # Below, there should be one TERM entry for each termtype that is
;;;  # colorizable
;;;  TERM eterm
;;;
;;;  # EIGHTBIT, followed by '1' for on, '0' for off.  (8-bit output)
;;;  EIGHTBIT 1
;;;
;;;  # Below are the color init strings for the basic file types.  A color init
;;;  # string consists of one or more of the following numeric codes:
;;;  # Attribute codes:
;;;  # 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
;;;  # Text color codes:
;;;  # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
;;;  # Background color codes:
;;;  # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
;;;  NORMAL 00	# global default, although everything should be something.
;;;  FILE 00 		# normal file
;;;  DIR 00;37 	# directory
;;;  LINK 00;36 	# symbolic link
;;;  FIFO 00;37	# pipe
;;;  SOCK 40;35	# socket
;;;  BLK 33;01	# block device driver
;;;  CHR 33;01 	# character device driver
;;;
;;;  # This is for files with execute permission:
;;;  EXEC 00;32
;;;
;;;  # List any file extensions like '.gz' or '.tar' that you would like ls
;;;  # to colorize below.  Put the extension, a space, and the color init
;;;  # string.  (and any comments you want to add after a '#')
;;;  .tar 01;33 # archives or compressed
;;;  .tgz 01;33
;;;  .arj 01;33
;;;  .taz 01;33
;;;  .lzh 01;33
;;;  .zip 01;33
;;;  .z   01;33
;;;  .Z   01;33
;;;  .gz  01;33
;;;  .jpg 01;35 # image formats
;;;  .gif 01;35
;;;  .bmp 01;35
;;;  .xbm 01;35
;;;  .xpm 01;35
;;;
;;;
;;;             ----------------------------------------
;;;
;;;  Notice: for directory/host/user tracking you need to have something
;;; like this in your shell startup script ( this is for tcsh but should
;;; be quite easy to port to other shells )
;;;
;;;             ----------------------------------------
;;;
;;;
;;;  	 set os = `uname`
;;;  	 set host = `hostname`
;;;  	 set date = `date`
;;;
;;;  # su does not change this but I'd like it to
;;;
;;;  	 set user = `whoami`
;;;
;;;  # ...
;;;
;;;  	 if ( eterm =~ $TERM ) then
;;;
;;;  		echo --------------------------------------------------------------
;;;  		echo Hello $user
;;;  		echo Today is $date
;;;  		echo We are on $host running $os under Emacs term mode
;;;  		echo --------------------------------------------------------------
;;;
;;;  		setenv EDITOR emacsclient
;;;
;;;   # Notice: $host and $user have been set before to 'hostname' and 'whoami'
;;;   # this is necessary because, f.e., certain versions of 'su' do not change
;;;   # $user, YMMV: if you don't want to fiddle with them define a couple
;;;   # of new variables and use these instead.
;;;   # NOTICE that there is a space between "AnSiT?" and $whatever NOTICE
;;;
;;;   # These are because we want the real cwd in the messages, not the login
;;;   # time one !
;;;
;;; 		set cwd_hack='$cwd'
;;; 		set host_hack='$host'
;;; 		set user_hack='$user'
;;;
;;;   # Notice that the ^[ character is an ESC, not two chars.  You can
;;;   # get it in various ways, for example by typing
;;;   # echo -e '\033' > escape.file
;;;   # or by using your favourite editor
;;;
;;; 		foreach temp (cd pushd)
;;; 			alias $temp "$temp \!* ; echo 'AnSiTc' $cwd_hack"
;;; 		end
;;;   		alias popd 'popd ;echo "AnSiTc" $cwd'
;;;
;;;   # Every command that can modify the user/host/directory should be aliased
;;;   # as follows for the tracking mechanism to work.
;;;
;;; 		foreach temp ( rlogin telnet rsh sh ksh csh tcsh zsh bash tcl su )
;;; 			alias $temp "$temp \!* ; echo 'AnSiTh' $host_hack ; \
;;; 					echo 'AnSiTu' $user_hack ;echo 'AnSiTc' $cwd_hack"
;;; 		end
;;;
;;;   # Start up & use color ls
;;;
;;; 		echo "AnSiTh" $host
;;; 		echo "AnSiTu" $user
;;; 		echo "AnSiTc" $cwd
;;;
;;;   # some housekeeping
;;;
;;; 		unset cwd_hack
;;; 		unset host_hack
;;; 		unset user_hack
;;; 		unset temp
;;;
;;; 		eval `/bin/dircolors /home/marco/.emacs_dircolors`
;;;    endif
;;;
;;;  # ...
;;;
;;;  # Let's not clutter user space
;;;
;;;  	 unset os
;;;  	 unset date
;;;
;;;
Richard M. Stallman's avatar
Richard M. Stallman committed
338

339 340
;;; Original Commentary:
;;; --------------------
Richard M. Stallman's avatar
Richard M. Stallman committed
341

Erik Naggum's avatar
Erik Naggum committed
342
;; The changelog is at the end of this file.
Richard M. Stallman's avatar
Richard M. Stallman committed
343

Erik Naggum's avatar
Erik Naggum committed
344 345 346
;; Please send me bug reports, bug fixes, and extensions, so that I can
;; merge them into the master source.
;;     - Per Bothner (bothner@cygnus.com)
Richard M. Stallman's avatar
Richard M. Stallman committed
347

Erik Naggum's avatar
Erik Naggum committed
348
;; This file defines a general command-interpreter-in-a-buffer package
349
;; (term mode).  The idea is that you can build specific process-in-a-buffer
Erik Naggum's avatar
Erik Naggum committed
350
;; modes on top of term mode -- e.g., lisp, shell, scheme, T, soar, ....
351
;; This way, all these specific packages share a common base functionality,
Erik Naggum's avatar
Erik Naggum committed
352 353
;; and a common set of bindings, which makes them easier to use (and
;; saves code, implementation time, etc., etc.).
Richard M. Stallman's avatar
Richard M. Stallman committed
354

Erik Naggum's avatar
Erik Naggum committed
355 356 357
;; For hints on converting existing process modes (e.g., tex-mode,
;; background, dbx, gdb, kermit, prolog, telnet) to use term-mode
;; instead of shell-mode, see the notes at the end of this file.
Richard M. Stallman's avatar
Richard M. Stallman committed
358 359


Erik Naggum's avatar
Erik Naggum committed
360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390
;; Brief Command Documentation:
;;============================================================================
;; Term Mode Commands: (common to all derived modes, like cmushell & cmulisp
;; mode)
;;
;; m-p	    term-previous-input    	  Cycle backwards in input history
;; m-n	    term-next-input  	    	  Cycle forwards
;; m-r     term-previous-matching-input  Previous input matching a regexp
;; m-s     comint-next-matching-input      Next input that matches
;; return  term-send-input
;; c-c c-a term-bol                      Beginning of line; skip prompt.
;; c-d	    term-delchar-or-maybe-eof     Delete char unless at end of buff.
;; c-c c-u term-kill-input	    	    ^u
;; c-c c-w backward-kill-word    	    ^w
;; c-c c-c term-interrupt-subjob 	    ^c
;; c-c c-z term-stop-subjob	    	    ^z
;; c-c c-\ term-quit-subjob	    	    ^\
;; c-c c-o term-kill-output		    Delete last batch of process output
;; c-c c-r term-show-output		    Show last batch of process output
;; c-c c-h term-dynamic-list-input-ring  List input history
;;
;; Not bound by default in term-mode
;; term-send-invisible			Read a line w/o echo, and send to proc
;; (These are bound in shell-mode)
;; term-dynamic-complete		Complete filename at point.
;; term-dynamic-list-completions	List completions in help buffer.
;; term-replace-by-expanded-filename	Expand and complete filename at point;
;;					replace with expanded/completed name.
;; term-kill-subjob			No mercy.
;; term-show-maximum-output            Show as much output as possible.
;; term-continue-subjob		Send CONT signal to buffer's process
391
;;					group.  Useful if you accidentally
Erik Naggum's avatar
Erik Naggum committed
392 393
;;					suspend your process (with C-c C-z).

394
;; term-mode-hook is the term mode hook.  Basically for your keybindings.
Erik Naggum's avatar
Erik Naggum committed
395 396
;; term-load-hook is run after loading in this package.

397
;;; Code:
Erik Naggum's avatar
Erik Naggum committed
398 399 400

;; This is passed to the inferior in the EMACS environment variable,
;; so it is important to increase it if there are protocol-relevant changes.
401
(defconst term-protocol-version "0.96")
Richard M. Stallman's avatar
Richard M. Stallman committed
402

403 404
(eval-when-compile
  (require 'ange-ftp))
Richard M. Stallman's avatar
Richard M. Stallman committed
405 406
(require 'ring)
(require 'ehelp)
407 408

(defgroup term nil
409
  "General command interpreter in a window."
410
  :group 'processes)
411

Richard M. Stallman's avatar
Richard M. Stallman committed
412 413 414 415 416 417 418 419

;;; Buffer Local Variables:
;;;============================================================================
;;; Term mode buffer local variables:
;;;     term-prompt-regexp    - string       term-bol uses to match prompt.
;;;     term-delimiter-argument-list - list  For delimiters and arguments
;;;     term-last-input-start - marker       Handy if inferior always echoes
;;;     term-last-input-end   - marker       For term-kill-output command
420 421 422 423
;; For the input history mechanism:
(defvar term-input-ring-size 32 "Size of input history ring.")
;;;     term-input-ring-size  - integer
;;;     term-input-ring       - ring
Richard M. Stallman's avatar
Richard M. Stallman committed
424 425 426 427 428 429
;;;     term-input-ring-index - number           ...
;;;     term-input-autoexpand - symbol           ...
;;;     term-input-ignoredups - boolean          ...
;;;     term-last-input-match - string           ...
;;;     term-dynamic-complete-functions - hook   For the completion mechanism
;;;     term-completion-fignore - list           ...
430
;;;     term-get-old-input    - function     Hooks for specific
Richard M. Stallman's avatar
Richard M. Stallman committed
431 432 433 434 435
;;;     term-input-filter-functions - hook     process-in-a-buffer
;;;     term-input-filter     - function         modes.
;;;     term-input-send	- function
;;;     term-scroll-to-bottom-on-output - symbol ...
;;;     term-scroll-show-maximum-output - boolean...
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460
(defvar term-height) ;; Number of lines in window.
(defvar term-width) ;; Number of columns in window.
(defvar term-home-marker) ;; Marks the "home" position for cursor addressing.
(defvar term-saved-home-marker nil) ;; When using alternate sub-buffer,
;;		contains saved term-home-marker from original sub-buffer .
(defvar term-start-line-column 0) ;; (current-column) at start of screen line,
;;		or nil if unknown.
(defvar term-current-column 0) ;; If non-nil, is cache for (current-column).
(defvar term-current-row 0) ;; Current vertical row (relative to home-marker)
;;		or nil if unknown.
(defvar term-insert-mode nil)
(defvar term-vertical-motion)
(defvar term-terminal-state 0) ;; State of the terminal emulator:
;;		state 0: Normal state
;;		state 1: Last character was a graphic in the last column.
;;		If next char is graphic, first move one column right
;;		(and line warp) before displaying it.
;;		This emulates (more or less) the behavior of xterm.
;;		state 2: seen ESC
;;		state 3: seen ESC [ (or ESC [ ?)
;;		state 4: term-terminal-parameter contains pending output.
(defvar term-kill-echo-list nil) ;; A queue of strings whose echo
;;		we want suppressed.
(defvar term-terminal-parameter)
(defvar term-terminal-previous-parameter)
461
(defvar term-current-face 'default)
462 463 464 465 466 467 468 469 470 471
(defvar term-scroll-start 0) ;; Top-most line (inclusive) of scrolling region.
(defvar term-scroll-end) ;; Number of line (zero-based) after scrolling region.
(defvar term-pager-count nil) ;; If nil, paging is disabled.
;;		Otherwise, number of lines before we need to page.
(defvar term-saved-cursor nil)
(defvar term-command-hook)
(defvar term-log-buffer nil)
(defvar term-scroll-with-delete nil) ;; term-scroll-with-delete is t if
;;		forward scrolling should be implemented by delete to
;;		top-most line(s); and nil if scrolling should be implemented
472
;;		by moving term-home-marker.  It is set to t if there is a
473
;;		(non-default) scroll-region OR the alternate buffer is used.
474 475 476
(defvar term-pending-delete-marker) ;; New user input in line mode needs to
;;		be deleted, because it gets echoed by the inferior.
;;		To reduce flicker, we defer the delete until the next output.
477 478 479 480
(defvar term-old-mode-map nil) ;; Saves the old keymap when in char mode.
(defvar term-old-mode-line-format) ;; Saves old mode-line-format while paging.
(defvar term-pager-old-local-map nil) ;; Saves old keymap while paging.
(defvar term-pager-old-filter) ;; Saved process-filter while paging.
Richard M. Stallman's avatar
Richard M. Stallman committed
481

482 483 484 485
(defcustom explicit-shell-file-name nil
  "*If non-nil, is file name to use for explicitly requested inferior shell."
  :type '(choice (const nil) file)
  :group 'term)
Richard M. Stallman's avatar
Richard M. Stallman committed
486 487

(defvar term-prompt-regexp "^"
488
  "Regexp to recognize prompts in the inferior process.
Richard M. Stallman's avatar
Richard M. Stallman committed
489 490 491 492 493 494 495 496 497 498 499 500 501
Defaults to \"^\", the null string at BOL.

Good choices:
  Canonical Lisp: \"^[^> \\n]*>+:? *\" (Lucid, franz, kcl, T, cscheme, oaklisp)
  Lucid Common Lisp: \"^\\\\(>\\\\|\\\\(->\\\\)+\\\\) *\"
  franz: \"^\\\\(->\\\\|<[0-9]*>:\\\\) *\"
  kcl: \"^>+ *\"
  shell: \"^[^#$%>\\n]*[#$%>] *\"
  T: \"^>+ *\"

This is a good thing to set in mode hooks.")

(defvar term-delimiter-argument-list ()
502
  "List of characters to recognize as separate arguments in input.
Richard M. Stallman's avatar
Richard M. Stallman committed
503 504 505 506 507
Strings comprising a character in this list will separate the arguments
surrounding them, and also be regarded as arguments in their own right (unlike
whitespace).  See `term-arguments'.
Defaults to the empty list.

508
For shells, a good value is (?\\| ?& ?< ?> ?\\( ?\\) ?\\;).
Richard M. Stallman's avatar
Richard M. Stallman committed
509 510 511

This is a good thing to set in mode hooks.")

512
(defcustom term-input-autoexpand nil
Richard M. Stallman's avatar
Richard M. Stallman committed
513 514 515 516 517 518 519 520
  "*If non-nil, expand input command history references on completion.
This mirrors the optional behavior of tcsh (its autoexpand and histlit).

If the value is `input', then the expansion is seen on input.
If the value is `history', then the expansion is only when inserting
into the buffer's input ring.  See also `term-magic-space' and
`term-dynamic-complete'.

521 522 523
This variable is buffer-local."
  :type '(choice (const nil) (const t) (const input) (const history))
  :group 'term)
Richard M. Stallman's avatar
Richard M. Stallman committed
524

525
(defcustom term-input-ignoredups nil
Richard M. Stallman's avatar
Richard M. Stallman committed
526 527 528
  "*If non-nil, don't add input matching the last on the input ring.
This mirrors the optional behavior of bash.

529 530 531
This variable is buffer-local."
  :type 'boolean
  :group 'term)
Richard M. Stallman's avatar
Richard M. Stallman committed
532

533
(defcustom term-input-ring-file-name nil
Richard M. Stallman's avatar
Richard M. Stallman committed
534 535 536
  "*If non-nil, name of the file to read/write input history.
See also `term-read-input-ring' and `term-write-input-ring'.

537 538 539
This variable is buffer-local, and is a good thing to set in mode hooks."
  :type 'boolean
  :group 'term)
Richard M. Stallman's avatar
Richard M. Stallman committed
540

541
(defcustom term-scroll-to-bottom-on-output nil
Richard M. Stallman's avatar
Richard M. Stallman committed
542 543 544 545 546 547 548 549
  "*Controls whether interpreter output causes window to scroll.
If nil, then do not scroll.  If t or `all', scroll all windows showing buffer.
If `this', scroll only the selected window.
If `others', scroll only those that are not the selected window.

The default is nil.

See variable `term-scroll-show-maximum-output'.
550 551 552
This variable is buffer-local."
  :type 'boolean
  :group 'term)
Richard M. Stallman's avatar
Richard M. Stallman committed
553

554
(defcustom term-scroll-show-maximum-output nil
Richard M. Stallman's avatar
Richard M. Stallman committed
555 556 557 558
  "*Controls how interpreter output causes window to scroll.
If non-nil, then show the maximum output when the window is scrolled.

See variable `term-scroll-to-bottom-on-output'.
559 560 561
This variable is buffer-local."
  :type 'boolean
  :group 'term)
Richard M. Stallman's avatar
Richard M. Stallman committed
562 563 564 565 566 567 568 569 570 571 572

;; Where gud-display-frame should put the debugging arrow.  This is
;; set by the marker-filter, which scans the debugger's output for
;; indications of the current pc.
(defvar term-pending-frame nil)

;;; Here are the per-interpreter hooks.
(defvar term-get-old-input (function term-get-old-input-default)
  "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
573 574
`term-get-old-input-default', which grabs the current line, and strips off
leading text matching `term-prompt-regexp'.")
Richard M. Stallman's avatar
Richard M. Stallman committed
575 576 577 578 579 580 581 582 583 584 585 586 587

(defvar term-dynamic-complete-functions
  '(term-replace-by-expanded-history term-dynamic-complete-filename)
  "List of functions called to perform completion.
Functions should return non-nil if completion was performed.
See also `term-dynamic-complete'.

This is a good thing to set in mode hooks.")

(defvar term-input-filter
  (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
588
history list.  Default is to save anything that isn't all whitespace.")
Richard M. Stallman's avatar
Richard M. Stallman committed
589 590 591 592 593 594 595 596 597

(defvar term-input-filter-functions '()
  "Functions to call before input is sent to the process.
These functions get one argument, a string containing the text to send.

This variable is buffer-local.")

(defvar term-input-sender (function term-simple-send)
  "Function to actually send to PROCESS the STRING submitted by user.
598
Usually this is just `term-simple-send', but if your mode needs to
599
massage the input string, this is your hook.  This is called from
600
the user command `term-send-input'.  `term-simple-send' just sends
Richard M. Stallman's avatar
Richard M. Stallman committed
601 602
the string plus a newline.")

603
(defcustom term-eol-on-send t
604
  "*Non-nil means go to the end of the line before sending input.
605 606 607
See `term-send-input'."
  :type 'boolean
  :group 'term)
608

609
(defcustom term-mode-hook '()
610
  "Called upon entry into term mode.
611 612 613
This is run before the process is cranked up."
  :type 'hook
  :group 'term)
Richard M. Stallman's avatar
Richard M. Stallman committed
614

615
(defcustom term-exec-hook '()
616
  "Called each time a process is exec'd by `term-exec'.
Richard M. Stallman's avatar
Richard M. Stallman committed
617
This is called after the process is cranked up.  It is useful for things that
618 619
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
620 621 622
executed once when the buffer is created."
  :type 'hook
  :group 'term)
Richard M. Stallman's avatar
Richard M. Stallman committed
623

624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670
(defvar term-mode-map 
  (let ((map (make-sparse-keymap)))
    (define-key map "\ep" 'term-previous-input)
    (define-key map "\en" 'term-next-input)
    (define-key map "\er" 'term-previous-matching-input)
    (define-key map "\es" 'term-next-matching-input)
    (unless (featurep 'xemacs)
      (define-key map [?\A-\M-r]
	'term-previous-matching-input-from-input)
      (define-key map [?\A-\M-s] 'term-next-matching-input-from-input))
    (define-key map "\e\C-l" 'term-show-output)
    (define-key map "\C-m" 'term-send-input)
    (define-key map "\C-d" 'term-delchar-or-maybe-eof)
    (define-key map "\C-c\C-a" 'term-bol)
    (define-key map "\C-c\C-u" 'term-kill-input)
    (define-key map "\C-c\C-w" 'backward-kill-word)
    (define-key map "\C-c\C-c" 'term-interrupt-subjob)
    (define-key map "\C-c\C-z" 'term-stop-subjob)
    (define-key map "\C-c\C-\\" 'term-quit-subjob)
    (define-key map "\C-c\C-m" 'term-copy-old-input)
    (define-key map "\C-c\C-o" 'term-kill-output)
    (define-key map "\C-c\C-r" 'term-show-output)
    (define-key map "\C-c\C-e" 'term-show-maximum-output)
    (define-key map "\C-c\C-l" 'term-dynamic-list-input-ring)
    (define-key map "\C-c\C-n" 'term-next-prompt)
    (define-key map "\C-c\C-p" 'term-previous-prompt)
    (define-key map "\C-c\C-d" 'term-send-eof)
    (define-key map "\C-c\C-k" 'term-char-mode)
    (define-key map "\C-c\C-j" 'term-line-mode)
    (define-key map "\C-c\C-q" 'term-pager-toggle)

    ;;  ;; completion:
    ;;  (define-key map [menu-bar completion]
    ;;    (cons "Complete" (make-sparse-keymap "Complete")))
    ;;  (define-key map [menu-bar completion complete-expand]
    ;;    '("Expand File Name" . term-replace-by-expanded-filename))
    ;;  (define-key map [menu-bar completion complete-listing]
    ;;    '("File Completion Listing" . term-dynamic-list-filename-completions))
    ;;  (define-key map [menu-bar completion complete-file]
    ;;    '("Complete File Name" . term-dynamic-complete-filename))
    ;;  (define-key map [menu-bar completion complete]
    ;;    '("Complete Before Point" . term-dynamic-complete))
    ;;  ;; Put them in the menu bar:
    ;;  (setq menu-bar-final-items (append '(terminal completion inout signals)
    ;;				     menu-bar-final-items))
    map))

Richard M. Stallman's avatar
Richard M. Stallman committed
671 672
(defvar term-raw-map nil
  "Keyboard map for sending characters directly to the inferior process.")
673
(defvar term-escape-char nil
674
  "Escape character for char sub-mode of term mode.
675
Do not change it directly; use `term-set-escape-char' instead.")
Richard M. Stallman's avatar
Richard M. Stallman committed
676 677 678 679 680 681
(defvar term-raw-escape-map nil)

(defvar term-pager-break-map nil)

(defvar term-ptyp t
  "True if communications via pty; false if by pipe.  Buffer local.
682
This is to work around a bug in Emacs process signaling.")
Richard M. Stallman's avatar
Richard M. Stallman committed
683 684 685

(defvar term-last-input-match ""
  "Last string searched for by term input history search, for defaulting.
686
Buffer local variable.")
Richard M. Stallman's avatar
Richard M. Stallman committed
687 688 689 690 691 692 693 694 695

(defvar term-input-ring nil)
(defvar term-last-input-start)
(defvar term-last-input-end)
(defvar term-input-ring-index nil
  "Index of last matched history element.")
(defvar term-matching-input-from-input-string ""
  "Input previously used to match input history.")
; This argument to set-process-filter disables reading from the process,
696
; assuming this is Emacs 19.20 or newer.
Richard M. Stallman's avatar
Richard M. Stallman committed
697 698 699 700 701 702 703 704 705 706 707 708 709
(defvar term-pager-filter t)

(put 'term-replace-by-expanded-history 'menu-enable 'term-input-autoexpand)
(put 'term-input-ring 'permanent-local t)
(put 'term-input-ring-index 'permanent-local t)
(put 'term-input-autoexpand 'permanent-local t)
(put 'term-input-filter-functions 'permanent-local t)
(put 'term-scroll-to-bottom-on-output 'permanent-local t)
(put 'term-scroll-show-maximum-output 'permanent-local t)
(put 'term-ptyp 'permanent-local t)

(defmacro term-in-char-mode () '(eq (current-local-map) term-raw-map))
(defmacro term-in-line-mode () '(not (term-in-char-mode)))
710 711 712 713 714 715 716
;; True if currently doing PAGER handling.
(defmacro term-pager-enabled () 'term-pager-count)
(defmacro term-handling-pager () 'term-pager-old-local-map)
(defmacro term-using-alternate-sub-buffer () 'term-saved-home-marker)

(defvar term-signals-menu)
(defvar term-terminal-menu)
Richard M. Stallman's avatar
Richard M. Stallman committed
717

718 719 720 721 722 723 724 725
;;; Let's silence the byte-compiler -mm
(defvar term-ansi-at-host nil)
(defvar term-ansi-at-dir nil)
(defvar term-ansi-at-user nil)
(defvar term-ansi-at-message nil)
(defvar term-ansi-at-save-user nil)
(defvar term-ansi-at-save-pwd nil)
(defvar term-ansi-at-save-anon nil)
726
(defvar term-ansi-current-bold nil)
727
(defvar term-ansi-current-color 0)
728
(defvar term-ansi-face-already-done nil)
729
(defvar term-ansi-current-bg-color 0)
730 731 732
(defvar term-ansi-current-underline nil)
(defvar term-ansi-current-reverse nil)
(defvar term-ansi-current-invisible nil)
733 734 735 736 737 738 739 740 741 742

;;; Four should be enough, if you want more, just add. -mm
(defvar term-terminal-more-parameters 0)
(defvar term-terminal-previous-parameter-2 -1)
(defvar term-terminal-previous-parameter-3 -1)
(defvar term-terminal-previous-parameter-4 -1)
;;;

;;; faces -mm

743
(defcustom term-default-fg-color (face-foreground term-current-face)
744 745 746 747
  "Default color for foreground in `term'."
  :group 'term
  :type 'string)

748
(defcustom term-default-bg-color (face-background term-current-face)
749 750 751 752
  "Default color for background in `term'."
  :group 'term
  :type 'string)

Dan Nicolaescu's avatar
Dan Nicolaescu committed
753
;;; Use the same colors that xterm uses, see `xterm-standard-colors'.
754
(defvar ansi-term-color-vector
Dan Nicolaescu's avatar
Dan Nicolaescu committed
755 756
  [unspecified "black" "red3" "green3" "yellow3" "blue2"
   "magenta3" "cyan3" "white"])
757 758 759 760 761

;;; Inspiration came from comint.el -mm
(defvar term-buffer-maximum-size 2048
  "*The maximum size in lines for term buffers.
Term buffers are truncated from the top to be no greater than this number.
762
Notice that a setting of 0 means \"don't truncate anything\".  This variable
763 764
is buffer-local.")
;;;
765

766 767 768 769 770 771 772
(when (featurep 'xemacs)
  (defvar term-terminal-menu
    '("Terminal"
      [ "Character mode" term-char-mode (term-in-line-mode)]
      [ "Line mode" term-line-mode (term-in-char-mode)]
      [ "Enable paging" term-pager-toggle (not term-pager-count)]
      [ "Disable paging" term-pager-toggle term-pager-count])))
Richard M. Stallman's avatar
Richard M. Stallman committed
773 774

;; Menu bars:
775
(unless (featurep 'xemacs)
776 777 778 779
  ;; terminal:
  (let (newmap)
    (setq newmap (make-sparse-keymap "Terminal"))
    (define-key newmap [terminal-pager-enable]
780 781
      '(menu-item "Enable paging" term-fake-pager-enable
		  :help "Enable paging feature"))
782
    (define-key newmap [terminal-pager-disable]
783 784
      '(menu-item "Disable paging" term-fake-pager-disable
		  :help "Disable paging feature"))
785
    (define-key newmap [terminal-char-mode]
786 787
      '(menu-item "Character mode" term-char-mode
		  :help "Switch to char (raw) sub-mode of term mode"))
788
    (define-key newmap [terminal-line-mode]
789
      '(menu-item "Line mode" term-line-mode
Dan Nicolaescu's avatar
Dan Nicolaescu committed
790
		  :help "Switch to line (cooked) sub-mode of term mode"))
791
    (setq term-terminal-menu (cons "Terminal" newmap))
792 793 794

    ;; completion:  (line mode only)
    (defvar term-completion-menu (make-sparse-keymap "Complete"))
795
    (define-key term-mode-map [menu-bar completion]
796 797 798 799 800 801 802 803 804 805 806 807
      (cons "Complete" term-completion-menu))
    (define-key term-completion-menu [complete-expand]
      '("Expand File Name" . term-replace-by-expanded-filename))
    (define-key term-completion-menu [complete-listing]
      '("File Completion Listing" . term-dynamic-list-filename-completions))
    (define-key term-completion-menu [menu-bar completion complete-file]
      '("Complete File Name" . term-dynamic-complete-filename))
    (define-key term-completion-menu [menu-bar completion complete]
      '("Complete Before Point" . term-dynamic-complete))

    ;; Input history: (line mode only)
    (defvar term-inout-menu (make-sparse-keymap "In/Out"))
808
    (define-key term-mode-map [menu-bar inout]
809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834
      (cons "In/Out" term-inout-menu))
    (define-key term-inout-menu [kill-output]
      '("Kill Current Output Group" . term-kill-output))
    (define-key term-inout-menu [next-prompt]
      '("Forward Output Group" . term-next-prompt))
    (define-key term-inout-menu [previous-prompt]
      '("Backward Output Group" . term-previous-prompt))
    (define-key term-inout-menu [show-maximum-output]
      '("Show Maximum Output" . term-show-maximum-output))
    (define-key term-inout-menu [show-output]
      '("Show Current Output Group" . term-show-output))
    (define-key term-inout-menu [kill-input]
      '("Kill Current Input" . term-kill-input))
    (define-key term-inout-menu [copy-input]
      '("Copy Old Input" . term-copy-old-input))
    (define-key term-inout-menu [forward-matching-history]
      '("Forward Matching Input..." . term-forward-matching-input))
    (define-key term-inout-menu [backward-matching-history]
      '("Backward Matching Input..." . term-backward-matching-input))
    (define-key term-inout-menu [next-matching-history]
      '("Next Matching Input..." . term-next-matching-input))
    (define-key term-inout-menu [previous-matching-history]
      '("Previous Matching Input..." . term-previous-matching-input))
    (define-key term-inout-menu [next-matching-history-from-input]
      '("Next Matching Current Input" . term-next-matching-input-from-input))
    (define-key term-inout-menu [previous-matching-history-from-input]
835 836
      '("Previous Matching Current Input" .
		term-previous-matching-input-from-input))
837 838 839 840 841 842 843 844 845 846 847 848 849
    (define-key term-inout-menu [next-history]
      '("Next Input" . term-next-input))
    (define-key term-inout-menu [previous-history]
      '("Previous Input" . term-previous-input))
    (define-key term-inout-menu [list-history]
      '("List Input History" . term-dynamic-list-input-ring))
    (define-key term-inout-menu [expand-history]
      '("Expand History Before Point" . term-replace-by-expanded-history))

    ;; Signals
    (setq newmap (make-sparse-keymap "Signals"))
    (define-key term-mode-map [menu-bar signals]
      (setq term-signals-menu (cons "Signals" newmap)))
850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867
    (define-key newmap [eof]
      '(menu-item "EOF" term-send-eof
		  :help "Send an EOF to the current buffer's process"))
    (define-key newmap [kill]
      '(menu-item "KILL" term-kill-subjob
		  :help "Send kill signal to the current subjob"))
    (define-key newmap [quit]
      '(menu-item "QUIT" term-quit-subjob
		  :help "Send quit signal to the current subjob."))
    (define-key newmap [cont]
      '(menu-item "CONT" term-continue-subjob
		  :help "Send CONT signal to process buffer's process group"))
    (define-key newmap [stop]
      '(menu-item "STOP" term-stop-subjob
		  :help "Stop the current subjob"))
    (define-key newmap [brk]
      '(menu-item "BREAK" term-interrupt-subjob
		  :help "Interrupt the current subjob"))
868
    ))
869 870 871 872

;; Set up term-raw-map, etc.

(defun term-set-escape-char (c)
873
  "Change `term-escape-char' and keymaps that depend on it."
874 875
  (when term-escape-char
    (define-key term-raw-map term-escape-char 'term-send-raw))
876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895
  (setq c (make-string 1 c))
  (define-key term-raw-map c term-raw-escape-map)
  ;; Define standard bindings in term-raw-escape-map
  (define-key term-raw-escape-map "\C-v"
    (lookup-key (current-global-map) "\C-v"))
  (define-key term-raw-escape-map "\C-u"
    (lookup-key (current-global-map) "\C-u"))
  (define-key term-raw-escape-map c 'term-send-raw)
  (define-key term-raw-escape-map "\C-q" 'term-pager-toggle)
  ;; The keybinding for term-char-mode is needed by the menubar code.
  (define-key term-raw-escape-map "\C-k" 'term-char-mode)
  (define-key term-raw-escape-map "\C-j" 'term-line-mode)
  ;; It's convenient to have execute-extended-command here.
  (define-key term-raw-escape-map [?\M-x] 'execute-extended-command))

(let* ((map (make-keymap))
       (esc-map (make-keymap))
       (i 0))
  (while (< i 128)
    (define-key map (make-string 1 i) 'term-send-raw)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
896
    ;; Avoid O and [. They are used in escape sequences for various keys.
897
    (unless (or (eq i ?O) (eq i 91))
Dan Nicolaescu's avatar
Dan Nicolaescu committed
898
		(define-key esc-map (make-string 1 i) 'term-send-raw-meta))
899 900 901 902 903 904 905 906
    (setq i (1+ i)))
  (define-key map "\e" esc-map)
  (setq term-raw-map map)
  (setq term-raw-escape-map
	(copy-keymap (lookup-key (current-global-map) "\C-x")))

;;; Added nearly all the 'grey keys' -mm

907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926
  (if (featurep 'xemacs)
      (define-key term-raw-map [button2] 'term-mouse-paste)
    (define-key term-raw-map [mouse-2] 'term-mouse-paste)
    (define-key term-raw-map [menu-bar terminal] term-terminal-menu)
    (define-key term-raw-map [menu-bar signals] term-signals-menu))
  (define-key term-raw-map [up] 'term-send-up)
  (define-key term-raw-map [down] 'term-send-down)
  (define-key term-raw-map [right] 'term-send-right)
  (define-key term-raw-map [left] 'term-send-left)
  (define-key term-raw-map [delete] 'term-send-del)
  (define-key term-raw-map [deletechar] 'term-send-del)
  (define-key term-raw-map [backspace] 'term-send-backspace)
  (define-key term-raw-map [home] 'term-send-home)
  (define-key term-raw-map [end] 'term-send-end)
  (define-key term-raw-map [insert] 'term-send-insert)
  (define-key term-raw-map [S-prior] 'scroll-down)
  (define-key term-raw-map [S-next] 'scroll-up)
  (define-key term-raw-map [S-insert] 'term-paste)
  (define-key term-raw-map [prior] 'term-send-prior)
  (define-key term-raw-map [next] 'term-send-next))
927 928

(term-set-escape-char ?\C-c)
Kenichi Handa's avatar
Kenichi Handa committed
929 930 931 932

(defun term-window-width ()
  (if (featurep 'xemacs)
      (1- (window-width))
933
    (if (and window-system overflow-newline-into-fringe)
Kenichi Handa's avatar
Kenichi Handa committed
934 935 936
	(window-width)
      (1- (window-width)))))

937 938 939

(put 'term-mode 'mode-class 'special)

940 941 942 943 944 945 946

;;; Use this variable as a display table for `term-mode'.
(defvar term-display-table
  (let ((dt (or (copy-sequence standard-display-table)
		(make-display-table)))
        i)
    ;; avoid changing the display table for ^J
947
    (setq i 0)
948 949 950
    (while (< i 10)
      (aset dt i (vector i))
      (setq i (1+ i)))
951
    (setq i 11)
952 953 954 955 956 957 958 959 960
    (while (< i 32)
      (aset dt i (vector i))
      (setq i (1+ i)))
    (setq i 128)
    (while (< i 256)
      (aset dt i (vector i))
      (setq i (1+ i)))
    dt))

961 962 963 964 965 966
(defun term-mode ()
  "Major mode for interacting with an inferior interpreter.
The interpreter name is same as buffer name, sans the asterisks.

There are two submodes: line mode and char mode.  By default, you are
in char mode.  In char sub-mode, each character (except
967 968
`term-escape-char') is sent immediately to the subprocess.
The escape character is equivalent to the usual meaning of C-x.
969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988

In line mode, you send a line of input at a time; use
\\[term-send-input] to send.

In line mode, this maintains an input history of size
`term-input-ring-size', and you can access it with the commands
\\[term-next-input], \\[term-previous-input], and
\\[term-dynamic-list-input-ring].  Input ring history expansion can be
achieved with the commands \\[term-replace-by-expanded-history] or
\\[term-magic-space].  Input ring expansion is controlled by the
variable `term-input-autoexpand', and addition is controlled by the
variable `term-input-ignoredups'.

Input to, and output from, the subprocess can cause the window to scroll to
the end of the buffer.  See variables `term-scroll-to-bottom-on-input',
and `term-scroll-to-bottom-on-output'.

If you accidentally suspend your process, use \\[term-continue-subjob]
to continue it.

989
This mode can be customized to create specific modes for running
990 991 992 993 994 995 996 997 998 999 1000 1001 1002
particular subprocesses.  This can be done by setting the hooks
`term-input-filter-functions', `term-input-filter',
`term-input-sender' and `term-get-old-input' to appropriate functions,
and the variable `term-prompt-regexp' to the appropriate regular
expression.

Commands in raw mode:

\\{term-raw-map}

Commands in line mode:

\\{term-mode-map}
Richard M. Stallman's avatar
Richard M. Stallman committed
1003

1004 1005 1006 1007 1008 1009 1010
Entry to this mode runs the hooks on `term-mode-hook'."
  (interactive)
  ;; Do not remove this.  All major modes must do this.
  (kill-all-local-variables)
  (setq major-mode 'term-mode)
  (setq mode-name "Term")
  (use-local-map term-mode-map)
1011 1012 1013
  ;; we do not want indent to sneak in any tabs
  (setq indent-tabs-mode nil)
  (setq buffer-display-table term-display-table)
1014 1015 1016 1017 1018
  (make-local-variable 'term-home-marker)
  (setq term-home-marker (copy-marker 0))
  (make-local-variable 'term-saved-home-marker)
  (make-local-variable 'term-height)
  (make-local-variable 'term-width)
Kenichi Handa's avatar
Kenichi Handa committed
1019
  (setq term-width (term-window-width))
1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072
  (setq term-height (1- (window-height)))
  (make-local-variable 'term-terminal-parameter)
  (make-local-variable 'term-saved-cursor)
  (make-local-variable 'term-last-input-start)
  (setq term-last-input-start (make-marker))
  (make-local-variable 'term-last-input-end)
  (setq term-last-input-end (make-marker))
  (make-local-variable 'term-last-input-match)
  (setq term-last-input-match "")
  (make-local-variable 'term-prompt-regexp) ; Don't set; default
  (make-local-variable 'term-input-ring-size) ; ...to global val.
  (make-local-variable 'term-input-ring)
  (make-local-variable 'term-input-ring-file-name)
  (or (and (boundp 'term-input-ring) term-input-ring)
      (setq term-input-ring (make-ring term-input-ring-size)))
  (make-local-variable 'term-input-ring-index)
  (or (and (boundp 'term-input-ring-index) term-input-ring-index)
      (setq term-input-ring-index nil))

  (make-local-variable 'term-command-hook)
  (setq term-command-hook (symbol-function 'term-command-hook))

;;; I'm not sure these saves are necessary but, since I
;;; haven't tested the whole thing on a net connected machine with
;;; a properly configured ange-ftp, I've decided to be conservative
;;; and put them in. -mm

  (make-local-variable 'term-ansi-at-host)
  (setq term-ansi-at-host (system-name))

  (make-local-variable 'term-ansi-at-dir)
  (setq term-ansi-at-dir default-directory)

  (make-local-variable 'term-ansi-at-message)
  (setq term-ansi-at-message nil)

;;; For user tracking purposes -mm
  (make-local-variable 'ange-ftp-default-user)
  (make-local-variable 'ange-ftp-default-password)
  (make-local-variable 'ange-ftp-generate-anonymous-password)

;;; You may want to have different scroll-back sizes -mm
  (make-local-variable 'term-buffer-maximum-size)

;;; Of course these have to be buffer-local -mm
  (make-local-variable 'term-ansi-current-bold)
  (make-local-variable 'term-ansi-current-color)
  (make-local-variable 'term-ansi-face-already-done)
  (make-local-variable 'term-ansi-current-bg-color)
  (make-local-variable 'term-ansi-current-underline)
  (make-local-variable 'term-ansi-current-reverse)
  (make-local-variable 'term-ansi-current-invisible)

1073 1074 1075 1076 1077 1078 1079
  (make-local-variable 'term-terminal-parameter)
  (make-local-variable 'term-terminal-previous-parameter)
  (make-local-variable 'term-terminal-previous-parameter-2)
  (make-local-variable 'term-terminal-previous-parameter-3)
  (make-local-variable 'term-terminal-previous-parameter-4)
  (make-local-variable 'term-terminal-more-parameters)

1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112
  (make-local-variable 'term-terminal-state)
  (make-local-variable 'term-kill-echo-list)
  (make-local-variable 'term-start-line-column)
  (make-local-variable 'term-current-column)
  (make-local-variable 'term-current-row)
  (make-local-variable 'term-log-buffer)
  (make-local-variable 'term-scroll-start)
  (make-local-variable 'term-scroll-end)
  (setq term-scroll-end term-height)
  (make-local-variable 'term-scroll-with-delete)
  (make-local-variable 'term-pager-count)
  (make-local-variable 'term-pager-old-local-map)
  (make-local-variable 'term-old-mode-map)
  (make-local-variable 'term-insert-mode)
  (make-local-variable 'term-dynamic-complete-functions)
  (make-local-variable 'term-completion-fignore)
  (make-local-variable 'term-get-old-input)
  (make-local-variable 'term-matching-input-from-input-string)
  (make-local-variable 'term-input-autoexpand)
  (make-local-variable 'term-input-ignoredups)
  (make-local-variable 'term-delimiter-argument-list)
  (make-local-variable 'term-input-filter-functions)
  (make-local-variable 'term-input-filter)
  (make-local-variable 'term-input-sender)
  (make-local-variable 'term-eol-on-send)
  (make-local-variable 'term-scroll-to-bottom-on-output)
  (make-local-variable 'term-scroll-show-maximum-output)
  (make-local-variable 'term-ptyp)
  (make-local-variable 'term-exec-hook)
  (make-local-variable 'term-vertical-motion)
  (make-local-variable 'term-pending-delete-marker)
  (setq term-pending-delete-marker (make-marker))
  (make-local-variable 'term-current-face)
1113 1114
  (setq term-current-face (list :background term-default-bg-color
				:foreground term-default-fg-color))
1115 1116
  (make-local-variable 'term-pending-frame)
  (setq term-pending-frame nil)
1117
  ;; Cua-mode's keybindings interfere with the term keybindings, disable it.
1118
  (set (make-local-variable 'cua-mode) nil)
Lute Kamstra's avatar
Lute Kamstra committed
1119
  (run-mode-hooks 'term-mode-hook)
1120 1121 1122
  (when (featurep 'xemacs)
    (set-buffer-menubar
     (append current-menubar (list term-terminal-menu))))
1123 1124 1125 1126
  (or term-input-ring
      (setq term-input-ring (make-ring term-input-ring-size)))
  (term-update-mode-line))

Richard M. Stallman's avatar
Richard M. Stallman committed
1127 1128 1129 1130 1131 1132
(defun term-reset-size (height width)
  (setq term-height height)
  (setq term-width width)
  (setq term-start-line-column nil)
  (setq term-current-row nil)
  (setq term-current-column nil)
1133
  (term-set-scroll-region 0 height))
Richard M. Stallman's avatar
Richard M. Stallman committed
1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158

;; Recursive routine used to check if any string in term-kill-echo-list
;; matches part of the buffer before point.
;; If so, delete that matched part of the buffer - this suppresses echo.
;; Also, remove that string from the term-kill-echo-list.
;; We *also* remove any older string on the list, as a sanity measure,
;; in case something gets out of sync.  (Except for type-ahead, there
;; should only be one element in the list.)

(defun term-check-kill-echo-list ()
  (let ((cur term-kill-echo-list) (found nil) (save-point (point)))
    (unwind-protect
	(progn
	  (end-of-line)
	  (while cur
	    (let* ((str (car cur)) (len (length str)) (start (- (point) len)))
	      (if (and (>= start (point-min))
		       (string= str (buffer-substring start (point))))
		  (progn (delete-backward-char len)
			 (setq term-kill-echo-list (cdr cur))
			 (setq term-current-column nil)
			 (setq term-current-row nil)
			 (setq term-start-line-column nil)
			 (setq cur nil found t))
		(setq cur (cdr cur))))))
1159 1160
      (when (not found)
	(goto-char save-point)))
Richard M. Stallman's avatar
Richard M. Stallman committed
1161 1162 1163
    found))

(defun term-check-size (process)
1164 1165 1166 1167
  (when (or (/= term-height (1- (window-height)))
	    (/= term-width (term-window-width)))
    (term-reset-size (1- (window-height)) (term-window-width))
    (set-process-window-size process term-height term-width)))
Richard M. Stallman's avatar
Richard M. Stallman committed
1168 1169 1170 1171 1172 1173 1174 1175

(defun term-send-raw-string (chars)
  (let ((proc (get-buffer-process (current-buffer))))
    (if (not proc)
	(error "Current buffer has no process")
      ;; Note that (term-current-row) must be called *after*
      ;; (point) has been updated to (process-mark proc).
      (goto-char (process-mark proc))
1176 1177
      (when (term-pager-enabled)
	(setq term-pager-count (term-current-row)))
1178
      (process-send-string proc chars))))
Richard M. Stallman's avatar
Richard M. Stallman committed
1179 1180 1181

(defun term-send-raw ()
  "Send the last character typed through the terminal-emulator
1182
without any interpretation."
Richard M. Stallman's avatar
Richard M. Stallman committed
1183 1184
  (interactive)
 ;; Convert `return' to C-m, etc.
1185 1186 1187
  (when (and (symbolp last-input-char)
	     (get last-input-char 'ascii-character))
    (setq last-input-char (get last-input-char 'ascii-character)))
Richard M. Stallman's avatar
Richard M. Stallman committed
1188 1189 1190 1191
  (term-send-raw-string (make-string 1 last-input-char)))

(defun term-send-raw-meta ()
  (interactive)
1192 1193
  (let ((char last-input-char))
    (when (symbolp last-input-char)
1194
      ;; Convert `return' to C-m, etc.
1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207
      (let ((tmp (get char 'event-symbol-elements)))
	(when tmp
	  (setq char (car tmp)))
	(when (symbolp char)
	  (setq tmp (get char 'ascii-character))
	  (when tmp
	    (setq char tmp)))))
    (setq char (event-basic-type char))
    (term-send-raw-string (if (and (numberp char)
				   (> char 127)
				   (< char 256))
			      (make-string 1 char)
			    (format "\e%c" char)))))
Richard M. Stallman's avatar
Richard M. Stallman committed
1208 1209 1210 1211

(defun term-mouse-paste (click arg)
  "Insert the last stretch of killed text at the position clicked on."
  (interactive "e\nP")
1212
  (if (featurep 'xemacs)
1213
      (term-send-raw-string
1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224
       (or (condition-case () (x-get-selection) (error ()))
	   (x-get-cutbuffer)
	   (error "No selection or cut buffer available")))
    ;; Give temporary modes such as isearch a chance to turn off.
    (run-hooks 'mouse-leave-buffer-hook)
    (setq this-command 'yank)
    (mouse-set-point click)
    (term-send-raw-string (current-kill (cond
					 ((listp arg) 0)
					 ((eq arg '-) -1)
					 (t (1- arg)))))))
Richard M. Stallman's avatar
Richard M. Stallman committed
1225

1226 1227 1228 1229 1230
(defun term-paste ()
  "Insert the last stretch of killed text at point."
  (interactive)
   (term-send-raw-string (current-kill 0)))

Richard M. Stallman's avatar
Richard M. Stallman committed
1231
;; Which would be better:  "\e[A" or "\eOA"? readline accepts either.
1232 1233
;; For my configuration it's definitely better \eOA but YMMV. -mm
;; For example: vi works with \eOA while elm wants \e[A ...
1234
;;; (terminfo: kcuu1, kcud1, kcuf1, kcub1, khome, kend, kpp, knp, kdch1, kbs)
1235 1236 1237 1238
(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"))
(defun term-send-left  () (interactive) (term-send-raw-string "\eOD"))
1239
(defun term-send-home  () (interactive) (term-send-raw-string "\e[1~"))
1240
(defun term-send-insert() (interactive) (term-send-raw-string "\e[2~"))
1241
(defun term-send-end   () (interactive) (term-send-raw-string "\e[4~"))
1242 1243
(defun term-send-prior () (interactive) (term-send-raw-string "\e[5~"))
(defun term-send-next  () (interactive) (term-send-raw-string "\e[6~"))
1244 1245
(defun term-send-del   () (interactive) (term-send-raw-string "\e[3~"))
(defun term-send-backspace  () (interactive) (term-send-raw-string "\C-?"))
1246

Richard M. Stallman's avatar
Richard M. Stallman committed
1247
(defun term-char-mode ()
1248 1249
  "Switch to char (\"raw\") sub-mode of term mode.
Each character you type is sent directly to the inferior without
1250
intervention from Emacs, except for the escape character (usually C-c)."
Richard M. Stallman's avatar
Richard M. Stallman committed
1251 1252
  (interactive)
  ;; FIXME: Emit message? Cfr ilisp-raw-message
1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268
  (when (term-in-line-mode)
    (setq term-old-mode-map (current-local-map))
    (use-local-map term-raw-map)

    ;; Send existing partial line to inferior (without newline).
    (let ((pmark (process-mark (get-buffer-process (current-buffer))))
	  (save-input-sender term-input-sender))
      (when (> (point) pmark)
	(unwind-protect
	    (progn
	      (setq term-input-sender
		    (symbol-function 'term-send-string))
	      (end-of-line)
	      (term-send-input))
	  (setq term-input-sender save-input-sender))))
    (term-update-mode-line)))
Richard M. Stallman's avatar
Richard M. Stallman committed
1269 1270

(defun term-line-mode  ()
1271
  "Switch to line (\"cooked\") sub-mode of term mode.
1272
This means that Emacs editing commands work as normally, until
1273
you type \\[term-send-input] which sends the current line to the inferior."
Richard M. Stallman's avatar
Richard M. Stallman committed
1274
  (interactive)
1275 1276 1277
  (when (term-in-char-mode)
    (use-local-map term-old-mode-map)
    (term-update-mode-line)))
1278 1279 1280 1281 1282 1283

(defun term-update-mode-line ()
  (setq mode-line-process
	(if (term-in-char-mode)
	    (if (term-pager-enabled) '(": char page %s") '(": char %s"))
	  (if (term-pager-enabled) '(": line page %s") '(": line %s"))))
1284
  (force-mode-line-update))
Richard M. Stallman's avatar
Richard M. Stallman committed
1285 1286 1287

(defun term-check-proc (buffer)
  "True if there is a process associated w/buffer BUFFER, and
1288
it is alive (status RUN or STOP).  BUFFER can be either a buffer or the
1289
name of one."
Richard M. Stallman's avatar
Richard M. Stallman committed
1290 1291 1292 1293 1294 1295 1296 1297
  (let ((proc (get-buffer-process buffer)))
    (and proc (memq (process-status proc) '(run stop)))))

;;;###autoload
(defun make-term (name program &optional startfile &rest switches)
"Make a term process NAME in a buffer, running PROGRAM.
The name of the buffer is made by surrounding NAME with `*'s.
If there is already a running process in that buffer, it is not restarted.
1298
Optional third arg STARTFILE is the name of a file to send the contents of to
Richard M. Stallman's avatar
Richard M. Stallman committed
1299 1300 1301
the process.  Any more args are arguments to PROGRAM."
  (let ((buffer (get-buffer-create (concat "*" name "*"))))
    ;; If no process, or nuked process, crank up a new one and put buffer in
1302
    ;; term mode.  Otherwise, leave buffer and existing process alone.
Richard M. Stallman's avatar
Richard M. Stallman committed
1303 1304 1305 1306 1307 1308 1309 1310 1311
    (cond ((not (term-check-proc buffer))
	   (save-excursion
	     (set-buffer buffer)
	     (term-mode)) ; Install local vars, mode, keymap, ...
	   (term-exec buffer name program startfile switches)))
    buffer))

;;;###autoload
(defun term (program)
1312 1313 1314 1315 1316
  "Start a terminal-emulator in a new buffer.
The buffer is in Term mode; see `term-mode' for the
commands to use in that buffer.

\\<term-raw-map>Type \\[switch-to-buffer] to switch to another buffer."
Richard M. Stallman's avatar
Richard M. Stallman committed
1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328
  (interactive (list (read-from-minibuffer "Run program: "
					   (or explicit-shell-file-name
					       (getenv "ESHELL")
					       (getenv "SHELL")
					       "/bin/sh"))))
  (set-buffer (make-term "terminal" program))
  (term-mode)
  (term-char-mode)
  (switch-to-buffer "*terminal*"))

(defun term-exec (buffer name command startfile switches)
  "Start up a process in buffer for term modes.
1329
Blasts any old process running in the buffer.  Doesn't set the buffer mode.
Richard M. Stallman's avatar
Richard M. Stallman committed
1330
You can use this to cheaply run a series of processes in the same term
1331
buffer.  The hook `term-exec-hook' is run after each exec."