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

3
;; Copyright (C) 1988, 1990, 1992, 1994, 1995, 2002, 2003,
4
;;   2004, 2005, 2006 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 15 16 17 18 19 20 21 22 23 24
;; 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
;; the Free Software Foundation; either version 2, or (at your option)
;; 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 411 412
  :group 'processes
  :group 'unix)

Richard M. Stallman's avatar
Richard M. Stallman committed
413 414 415 416 417 418 419 420

;;; 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
421 422 423 424
;; 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
425 426 427 428 429 430
;;;     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           ...
431
;;;     term-get-old-input    - function     Hooks for specific
Richard M. Stallman's avatar
Richard M. Stallman committed
432 433 434 435 436
;;;     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...
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461
(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)
462
(defvar term-current-face 'default)
463 464 465 466 467 468 469 470 471 472 473 474
(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
;;		by moving term-home-marker.  It is set to t iff there is a
;;		(non-default) scroll-region OR the alternate buffer is used.
475 476 477
(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.
478 479 480 481
(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
482

483 484 485 486
(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
487 488

(defvar term-prompt-regexp "^"
489
  "Regexp to recognize prompts in the inferior process.
Richard M. Stallman's avatar
Richard M. Stallman committed
490 491 492 493 494 495 496 497 498 499 500 501 502
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 ()
503
  "List of characters to recognize as separate arguments in input.
Richard M. Stallman's avatar
Richard M. Stallman committed
504 505 506 507 508
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.

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

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

513
(defcustom term-input-autoexpand nil
Richard M. Stallman's avatar
Richard M. Stallman committed
514 515 516 517 518 519 520 521
  "*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'.

522 523 524
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
525

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

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

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

538 539 540
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
541

542
(defcustom term-scroll-to-bottom-on-output nil
Richard M. Stallman's avatar
Richard M. Stallman committed
543 544 545 546 547 548 549 550
  "*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'.
551 552 553
This variable is buffer-local."
  :type 'boolean
  :group 'term)
Richard M. Stallman's avatar
Richard M. Stallman committed
554

555
(defcustom term-scroll-show-maximum-output nil
Richard M. Stallman's avatar
Richard M. Stallman committed
556 557 558 559
  "*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'.
560 561 562
This variable is buffer-local."
  :type 'boolean
  :group 'term)
Richard M. Stallman's avatar
Richard M. Stallman committed
563 564 565 566 567 568 569 570 571 572 573

;; 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
574 575
`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
576 577 578 579 580 581 582 583 584 585 586 587 588

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

(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.
599
Usually this is just `term-simple-send', but if your mode needs to
600
massage the input string, this is your hook.  This is called from
601
the user command `term-send-input'.  `term-simple-send' just sends
Richard M. Stallman's avatar
Richard M. Stallman committed
602 603
the string plus a newline.")

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

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

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

(defvar term-mode-map nil)
(defvar term-raw-map nil
  "Keyboard map for sending characters directly to the inferior process.")
628
(defvar term-escape-char nil
629
  "Escape character for char sub-mode of term mode.
630
Do not change it directly;  use `term-set-escape-char' instead.")
Richard M. Stallman's avatar
Richard M. Stallman committed
631 632 633 634 635 636
(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.
637
This is to work around a bug in Emacs process signaling.")
Richard M. Stallman's avatar
Richard M. Stallman committed
638 639 640

(defvar term-last-input-match ""
  "Last string searched for by term input history search, for defaulting.
641
Buffer local variable.")
Richard M. Stallman's avatar
Richard M. Stallman committed
642 643 644 645 646 647 648 649 650

(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,
651
; assuming this is Emacs 19.20 or newer.
Richard M. Stallman's avatar
Richard M. Stallman committed
652 653 654 655 656 657 658 659 660 661 662 663 664
(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)))
665 666 667 668 669 670 671
;; 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
672

673 674 675 676 677 678 679 680
;;; 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)
681
(defvar term-ansi-current-bold nil)
682
(defvar term-ansi-current-color 0)
683
(defvar term-ansi-face-already-done nil)
684
(defvar term-ansi-current-bg-color 0)
685 686 687
(defvar term-ansi-current-underline nil)
(defvar term-ansi-current-reverse nil)
(defvar term-ansi-current-invisible nil)
688 689 690 691 692 693 694 695 696 697

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

698
(defcustom term-default-fg-color 'unspecified
699 700 701 702
  "Default color for foreground in `term'."
  :group 'term
  :type 'string)

703
(defcustom term-default-bg-color 'unspecified
704 705 706 707
  "Default color for background in `term'."
  :group 'term
  :type 'string)

Dan Nicolaescu's avatar
Dan Nicolaescu committed
708
;;; Use the same colors that xterm uses, see `xterm-standard-colors'.
709
(defvar ansi-term-color-vector
Dan Nicolaescu's avatar
Dan Nicolaescu committed
710 711
  [unspecified "black" "red3" "green3" "yellow3" "blue2"
   "magenta3" "cyan3" "white"])
712 713 714 715 716 717 718 719

;;; 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.
Notice that a setting of 0 means 'don't truncate anything'.  This variable
is buffer-local.")
;;;
720

721 722 723 724 725 726 727
(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
728

729
(unless term-mode-map
Richard M. Stallman's avatar
Richard M. Stallman committed
730 731 732 733 734
  (setq term-mode-map (make-sparse-keymap))
  (define-key term-mode-map "\ep" 'term-previous-input)
  (define-key term-mode-map "\en" 'term-next-input)
  (define-key term-mode-map "\er" 'term-previous-matching-input)
  (define-key term-mode-map "\es" 'term-next-matching-input)
735 736 737 738
  (unless (featurep 'xemacs)
    (define-key term-mode-map [?\A-\M-r]
      'term-previous-matching-input-from-input)
    (define-key term-mode-map [?\A-\M-s] 'term-next-matching-input-from-input))
Richard M. Stallman's avatar
Richard M. Stallman committed
739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755
  (define-key term-mode-map "\e\C-l" 'term-show-output)
  (define-key term-mode-map "\C-m" 'term-send-input)
  (define-key term-mode-map "\C-d" 'term-delchar-or-maybe-eof)
  (define-key term-mode-map "\C-c\C-a" 'term-bol)
  (define-key term-mode-map "\C-c\C-u" 'term-kill-input)
  (define-key term-mode-map "\C-c\C-w" 'backward-kill-word)
  (define-key term-mode-map "\C-c\C-c" 'term-interrupt-subjob)
  (define-key term-mode-map "\C-c\C-z" 'term-stop-subjob)
  (define-key term-mode-map "\C-c\C-\\" 'term-quit-subjob)
  (define-key term-mode-map "\C-c\C-m" 'term-copy-old-input)
  (define-key term-mode-map "\C-c\C-o" 'term-kill-output)
  (define-key term-mode-map "\C-c\C-r" 'term-show-output)
  (define-key term-mode-map "\C-c\C-e" 'term-show-maximum-output)
  (define-key term-mode-map "\C-c\C-l" 'term-dynamic-list-input-ring)
  (define-key term-mode-map "\C-c\C-n" 'term-next-prompt)
  (define-key term-mode-map "\C-c\C-p" 'term-previous-prompt)
  (define-key term-mode-map "\C-c\C-d" 'term-send-eof)
756 757 758
  (define-key term-mode-map "\C-c\C-k" 'term-char-mode)
  (define-key term-mode-map "\C-c\C-j" 'term-line-mode)
  (define-key term-mode-map "\C-c\C-q" 'term-pager-toggle)
Richard M. Stallman's avatar
Richard M. Stallman committed
759 760

;  ;; completion:
761
;  (define-key term-mode-map [menu-bar completion]
Richard M. Stallman's avatar
Richard M. Stallman committed
762 763 764 765 766 767 768 769 770 771 772 773 774 775 776
;    (cons "Complete" (make-sparse-keymap "Complete")))
;  (define-key term-mode-map [menu-bar completion complete-expand]
;    '("Expand File Name" . term-replace-by-expanded-filename))
;  (define-key term-mode-map [menu-bar completion complete-listing]
;    '("File Completion Listing" . term-dynamic-list-filename-completions))
;  (define-key term-mode-map [menu-bar completion complete-file]
;    '("Complete File Name" . term-dynamic-complete-filename))
;  (define-key term-mode-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))
  )

;; Menu bars:
777
(unless (featurep 'xemacs)
778 779 780 781 782 783 784 785 786 787 788
  ;; terminal:
  (let (newmap)
    (setq newmap (make-sparse-keymap "Terminal"))
    (define-key newmap [terminal-pager-enable]
      '("Enable paging" . term-fake-pager-enable))
    (define-key newmap [terminal-pager-disable]
      '("Disable paging" . term-fake-pager-disable))
    (define-key newmap [terminal-char-mode]
      '("Character mode" . term-char-mode))
    (define-key newmap [terminal-line-mode]
      '("Line mode" . term-line-mode))
789
    (setq term-terminal-menu (cons "Terminal" newmap))
790 791 792

    ;; completion:  (line mode only)
    (defvar term-completion-menu (make-sparse-keymap "Complete"))
793
    (define-key term-mode-map [menu-bar completion]
794 795 796 797 798 799 800 801 802 803 804 805
      (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"))
806
    (define-key term-mode-map [menu-bar inout]
807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832
      (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]
833 834
      '("Previous Matching Current Input" .
		term-previous-matching-input-from-input))
835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853
    (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 newmap [eof] '("EOF" . term-send-eof))
    (define-key newmap [kill] '("KILL" . term-kill-subjob))
    (define-key newmap [quit] '("QUIT" . term-quit-subjob))
    (define-key newmap [cont] '("CONT" . term-continue-subjob))
    (define-key newmap [stop] '("STOP" . term-stop-subjob))
    (define-key newmap [] '("BREAK" . term-interrupt-subjob))
    (define-key term-mode-map [menu-bar signals]
      (setq term-signals-menu (cons "Signals" newmap)))
854
    ))
855 856 857 858 859

;; Set up term-raw-map, etc.

(defun term-set-escape-char (c)
  "Change term-escape-char and keymaps that depend on it."
860 861
  (when term-escape-char
    (define-key term-raw-map term-escape-char 'term-send-raw))
862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881
  (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
882
    ;; Avoid O and [. They are used in escape sequences for various keys.
883
    (unless (or (eq i ?O) (eq i 91))
Dan Nicolaescu's avatar
Dan Nicolaescu committed
884
		(define-key esc-map (make-string 1 i) 'term-send-raw-meta))
885 886 887 888 889 890 891 892 893 894
    (setq i (1+ i)))
  (dolist (elm (generic-character-list))
    (define-key map (vector elm) 'term-send-raw))
  (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

895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914
  (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))
915 916

(term-set-escape-char ?\C-c)
Kim F. Storm's avatar
Kim F. Storm committed
917 918 919 920

(defun term-window-width ()
  (if (featurep 'xemacs)
      (1- (window-width))
921
    (if (and window-system overflow-newline-into-fringe)
Kim F. Storm's avatar
Kim F. Storm committed
922 923 924
	(window-width)
      (1- (window-width)))))

925 926 927

(put 'term-mode 'mode-class 'special)

928 929 930 931 932 933 934

;;; 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
935
    (setq i 0)
936 937 938
    (while (< i 10)
      (aset dt i (vector i))
      (setq i (1+ i)))
939
    (setq i 11)
940 941 942 943 944 945 946 947 948
    (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))

949 950 951 952 953 954
(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
955 956
`term-escape-char') is sent immediately to the subprocess.
The escape character is equivalent to the usual meaning of C-x.
957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976

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.

977
This mode can be customized to create specific modes for running
978 979 980 981 982 983 984 985 986 987 988 989 990
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
991

992 993 994 995 996 997 998
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)
999 1000 1001
  ;; we do not want indent to sneak in any tabs
  (setq indent-tabs-mode nil)
  (setq buffer-display-table term-display-table)
1002 1003 1004 1005 1006
  (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)
Kim F. Storm's avatar
Kim F. Storm committed
1007
  (setq term-width (term-window-width))
1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 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
  (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)

1061 1062 1063 1064 1065 1066 1067
  (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)

1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102
  (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)
  (make-local-variable 'term-pending-frame)
  (setq term-pending-frame nil)
1103 1104
  ;; Cua-mode's keybindings interfere with the term keybindings, disable it. 
  (set (make-local-variable 'cua-mode) nil)
Lute Kamstra's avatar
Lute Kamstra committed
1105
  (run-mode-hooks 'term-mode-hook)
1106 1107 1108
  (when (featurep 'xemacs)
    (set-buffer-menubar
     (append current-menubar (list term-terminal-menu))))
1109 1110 1111 1112
  (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
1113 1114 1115 1116 1117 1118
(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)
1119
  (term-set-scroll-region 0 height))
Richard M. Stallman's avatar
Richard M. Stallman committed
1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144

;; 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))))))
1145 1146
      (when (not found)
	(goto-char save-point)))
Richard M. Stallman's avatar
Richard M. Stallman committed
1147 1148 1149
    found))

(defun term-check-size (process)
1150 1151 1152 1153
  (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
1154 1155 1156 1157 1158 1159 1160 1161

(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))
1162 1163
      (when (term-pager-enabled)
	(setq term-pager-count (term-current-row)))
1164
      (process-send-string proc chars))))
Richard M. Stallman's avatar
Richard M. Stallman committed
1165 1166 1167

(defun term-send-raw ()
  "Send the last character typed through the terminal-emulator
1168
without any interpretation."
Richard M. Stallman's avatar
Richard M. Stallman committed
1169 1170
  (interactive)
 ;; Convert `return' to C-m, etc.
1171 1172 1173
  (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
1174 1175 1176 1177
  (term-send-raw-string (make-string 1 last-input-char)))

(defun term-send-raw-meta ()
  (interactive)
1178 1179
  (let ((char last-input-char))
    (when (symbolp last-input-char)
1180
      ;; Convert `return' to C-m, etc.
1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193
      (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
1194 1195 1196 1197

(defun term-mouse-paste (click arg)
  "Insert the last stretch of killed text at the position clicked on."
  (interactive "e\nP")
1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210
  (if (featurep 'xemacs)
      (term-send-raw-string 
       (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
1211

1212 1213 1214 1215 1216
(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
1217
;; Which would be better:  "\e[A" or "\eOA"? readline accepts either.
1218 1219
;; For my configuration it's definitely better \eOA but YMMV. -mm
;; For example: vi works with \eOA while elm wants \e[A ...
1220
;;; (terminfo: kcuu1, kcud1, kcuf1, kcub1, khome, kend, kpp, knp, kdch1, kbs)
1221 1222 1223 1224
(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"))
1225
(defun term-send-home  () (interactive) (term-send-raw-string "\e[1~"))
1226
(defun term-send-insert() (interactive) (term-send-raw-string "\e[2~"))
1227
(defun term-send-end   () (interactive) (term-send-raw-string "\e[4~"))
1228 1229
(defun term-send-prior () (interactive) (term-send-raw-string "\e[5~"))
(defun term-send-next  () (interactive) (term-send-raw-string "\e[6~"))
1230 1231
(defun term-send-del   () (interactive) (term-send-raw-string "\e[3~"))
(defun term-send-backspace  () (interactive) (term-send-raw-string "\C-?"))
1232

Richard M. Stallman's avatar
Richard M. Stallman committed
1233
(defun term-char-mode ()
1234 1235
  "Switch to char (\"raw\") sub-mode of term mode.
Each character you type is sent directly to the inferior without
1236
intervention from Emacs, except for the escape character (usually C-c)."
Richard M. Stallman's avatar
Richard M. Stallman committed
1237 1238
  (interactive)
  ;; FIXME: Emit message? Cfr ilisp-raw-message
1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254
  (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
1255 1256

(defun term-line-mode  ()
1257
  "Switch to line (\"cooked\") sub-mode of term mode.
1258
This means that Emacs editing commands work as normally, until
1259
you type \\[term-send-input] which sends the current line to the inferior."
Richard M. Stallman's avatar
Richard M. Stallman committed
1260
  (interactive)
1261 1262 1263
  (when (term-in-char-mode)
    (use-local-map term-old-mode-map)
    (term-update-mode-line)))
1264 1265 1266 1267 1268 1269

(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"))))
1270
  (force-mode-line-update))
Richard M. Stallman's avatar
Richard M. Stallman committed
1271 1272 1273

(defun term-check-proc (buffer)
  "True if there is a process associated w/buffer BUFFER, and
1274
it is alive (status RUN or STOP).  BUFFER can be either a buffer or the
1275
name of one."
Richard M. Stallman's avatar
Richard M. Stallman committed
1276 1277 1278 1279 1280 1281 1282 1283
  (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.
1284
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
1285 1286 1287
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
1288
    ;; term mode.  Otherwise, leave buffer and existing process alone.
Richard M. Stallman's avatar
Richard M. Stallman committed
1289 1290 1291 1292 1293 1294 1295 1296 1297
    (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)
1298 1299 1300 1301 1302
  "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
1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314
  (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.
1315
Blasts any old process running in the buffer.  Doesn't set the buffer mode.
Richard M. Stallman's avatar
Richard M. Stallman committed
1316
You can use this to cheaply run a series of processes in the same term
1317
buffer.  The hook term-exec-hook is run after each exec."
Richard M. Stallman's avatar
Richard M. Stallman committed
1318 1319 1320
  (save-excursion
    (set-buffer buffer)
    (let ((proc (get-buffer-process buffer)))	; Blast any old process.
1321
      (when proc (delete-process proc)))
Richard M. Stallman's avatar
Richard M. Stallman committed
1322 1323 1324
    ;; Crank up a new process
    (let ((proc (term-exec-1 name buffer command switches)))
      (make-local-variable 'term-ptyp)
Pavel Janík's avatar
Pavel Janík committed
1325
      (setq term-ptyp process-connection-type) ; t if pty, nil if pipe.
Richard M. Stallman's avatar
Richard M. Stallman committed
1326 1327 1328 1329
      ;; Jump to the end, and set the process mark.
      (goto-char (point-max))
      (set-marker (process-mark proc) (point))
      (set-process-filter proc 'term-emulate-terminal)
1330
      (set-process-sentinel proc 'term-sentinel)
Richard M. Stallman's avatar
Richard M. Stallman committed
1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346
      ;; Feed it the startfile.
      (cond (startfile
	     ;;This is guaranteed to wait long enough
	     ;;but has bad results if the term does not prompt at all
	     ;;	     (while (= size (buffer-size))
	     ;;	       (sleep-for 1))
	     ;;I hope 1 second is enough!
	     (sleep-for 1)
	     (goto-char (point-max))
	     (insert-file-contents startfile)
	     (setq startfile (buffer-substring (point) (point-max)))
	     (delete-region (point) (point-max))
	     (term-send-string proc startfile)))
    (run-hooks 'term-exec-hook)
    buffer)))

1347 1348 1349 1350
(defun term-sentinel  (proc msg)
  "Sentinel for term buffers.
The main purpose is to get rid of the local keymap."
  (let ((buffer (process-buffer proc)))
1351 1352 1353 1354 1355 1356