(install-arch-dep): Don't depend on install-arch-indep.
[bpt/emacs.git] / lisp / comint.el
dissimilarity index 71%
index d660ff4..f0e717e 100644 (file)
-;;; comint.el --- general command interpreter in a window stuff
-
-;; Copyright (C) 1988, 1990, 1992, 1993 Free Software Foundation, Inc.
-
-;; Author: Olin Shivers <shivers@cs.cmu.edu>
-;; Keywords: processes
-
-;; 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 Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;;; Commentary:
-
-;;; The changelog is at the end of this file.
-
-;;; Please send me bug reports, bug fixes, and extensions, so that I can
-;;; merge them into the master source.
-;;;     - Olin Shivers (shivers@cs.cmu.edu)
-
-;;; This file defines a general command-interpreter-in-a-buffer package
-;;; (comint mode). The idea is that you can build specific process-in-a-buffer
-;;; modes on top of comint mode -- e.g., lisp, shell, scheme, T, soar, ....
-;;; This way, all these specific packages share a common base functionality, 
-;;; and a common set of bindings, which makes them easier to use (and
-;;; saves code, implementation time, etc., etc.).
-
-;;; Several packages are already defined using comint mode:
-;;; - shell.el defines a shell-in-a-buffer mode.
-;;; - cmulisp.el defines a simple lisp-in-a-buffer mode.
-;;;
-;;; - The file cmuscheme.el defines a scheme-in-a-buffer mode.
-;;; - The file tea.el tunes scheme and inferior-scheme modes for T.
-;;; - The file soar.el tunes lisp and inferior-lisp modes for Soar.
-;;; - cmutex.el defines tex and latex modes that invoke tex, latex, bibtex,
-;;;   previewers, and printers from within emacs.
-;;; - background.el allows csh-like job control inside emacs.
-;;; It is pretty easy to make new derived modes for other processes.
-
-;;; For documentation on the functionality provided by comint mode, and
-;;; the hooks available for customising it, see the comments below.
-;;; For further information on the standard derived modes (shell, 
-;;; inferior-lisp, inferior-scheme, ...), see the relevant source files.
-
-;;; For hints on converting existing process modes (e.g., tex-mode,
-;;; background, dbx, gdb, kermit, prolog, telnet) to use comint-mode
-;;; instead of shell-mode, see the notes at the end of this file.
-
-\f
-;;; Brief Command Documentation:
-;;;============================================================================
-;;; Comint Mode Commands: (common to all derived modes, like shell & cmulisp
-;;; mode)
-;;;
-;;; m-p            comint-previous-input           Cycle backwards in input history
-;;; m-n            comint-next-input               Cycle forwards
-;;; m-r     comint-previous-matching-input   Previous input matching a regexp
-;;; m-s     comint-next-matching-input       Next input that matches
-;;; return  comint-send-input
-;;; c-a     comint-bol                      Beginning of line; skip prompt.
-;;; c-d            comint-delchar-or-maybe-eof     Delete char unless at end of buff.
-;;; c-c c-u comint-kill-input              ^u
-;;; c-c c-w backward-kill-word             ^w
-;;; c-c c-c comint-interrupt-subjob        ^c
-;;; c-c c-z comint-stop-subjob             ^z
-;;; c-c c-\ comint-quit-subjob             ^\
-;;; c-c c-o comint-kill-output             Delete last batch of process output
-;;; c-c c-r comint-show-output             Show last batch of process output
-;;;
-;;; Not bound by default in comint-mode
-;;; send-invisible                     Read a line w/o echo, and send to proc
-;;; (These are bound in shell-mode)
-;;; comint-dynamic-complete            Complete filename at point.
-;;; comint-dynamic-list-completions    List completions in help buffer.
-;;; comint-replace-by-expanded-filename        Expand and complete filename at point;
-;;;                                    replace with expanded/completed name.
-;;; comint-kill-subjob                 No mercy.
-;;; comint-continue-subjob             Send CONT signal to buffer's process
-;;;                                    group. Useful if you accidentally
-;;;                                    suspend your process (with C-c C-z).
-;;;
-;;; These used to be bound for RMS -- I prefer the input history stuff,
-;;; but you might like 'em.
-;;; m-P           comint-msearch-input         Search backwards for prompt
-;;; m-N    comint-psearch-input                Search forwards for prompt
-;;; C-cR   comint-msearch-input-matching Search backwards for prompt & string
-
-;;; comint-mode-hook is the comint mode hook. Basically for your keybindings.
-;;; comint-load-hook is run after loading in this package.
-
-;;; Code:
-
-(defconst comint-version "2.03")
-
-(require 'ring)
-\f
-;;; Buffer Local Variables:
-;;;============================================================================
-;;; Comint mode buffer local variables:
-;;;     comint-prompt-regexp    - string       comint-bol uses to match prompt.
-;;;     comint-last-input-start - marker       Handy if inferior always echos
-;;;     comint-last-input-end   - marker       For comint-kill-output command
-;;;     comint-input-ring-size  - integer      For the input history
-;;;     comint-input-ring       - ring             mechanism
-;;;     comint-input-ring-index - number           ...
-;;;     comint-last-input-match - string           ...
-;;;     comint-get-old-input    - function     Hooks for specific 
-;;;     comint-input-sentinel   - function         process-in-a-buffer
-;;;     comint-input-filter     - function         modes.
-;;;     comint-input-send      - function
-;;;     comint-eol-on-send     - boolean
-;;;     comint-process-echoes   - boolean
-
-(defvar comint-prompt-regexp "^"
-  "Regexp to recognise prompts in the inferior process.
-Defaults to \"^\", the null string at BOL.
-
-Good choices:
-  Canonical Lisp: \"^[^> ]*>+:? *\" (Lucid, franz, kcl, T, cscheme, oaklisp)
-  Lucid Common Lisp: \"^\\\\(>\\\\|\\\\(->\\\\)+\\\\) *\"
-  franz: \"^\\\\(->\\\\|<[0-9]*>:\\\\) *\"
-  kcl: \"^>+ *\"
-  shell: \"^[^#$%>]*[#$%>] *\"
-  T: \"^>+ *\"
-
-This is a good thing to set in mode hooks.")
-
-(defvar comint-input-ring-size 30
-  "Size of input history ring.")
-
-(defvar comint-process-echoes nil
-  "*If non-nil, assume that the subprocess echoes any input.
-If so, delete one copy of the input so that only one copy eventually
-appears in the buffer. 
-
-This variable is buffer-local.")
-
-;;; Here are the per-interpreter hooks.
-(defvar comint-get-old-input (function comint-get-old-input-default)
-  "Function that submits old text in comint 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
-`comint-get-old-input-default', which grabs the current line, and strips off
-leading text matching `comint-prompt-regexp'.")
-
-(defvar comint-input-sentinel (function ignore)
-  "Called on each input submitted to comint mode process by `comint-send-input'.
-Thus it can, for instance, track cd/pushd/popd commands issued to the csh.")
-
-(defvar comint-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
-history list.  Default is to save anything that isn't all whitespace")
-
-(defvar comint-input-sender (function comint-simple-send)
-  "Function to actually send to PROCESS the STRING submitted by user.
-Usually this is just `comint-simple-send', but if your mode needs to 
-massage the input string, put a different function here.
-`comint-simple-send' just sends the string plus a newline.
-This is called from the user command `comint-send-input'.")
-
-(defvar comint-eol-on-send t
-  "*Non-nil means go to the end of the line before sending input to process.
-See `comint-send-input'.")
-
-(defvar comint-mode-hook '()
-  "Called upon entry into comint-mode
-This is run before the process is cranked up.")
-
-(defvar comint-exec-hook '()
-  "Called each time a process is exec'd by `comint-exec'.
-This is called after the process is cranked up.  It is useful for things that
-must be done each time a process is executed in a comint mode buffer (e.g.,
-`(process-kill-without-query)').  In contrast, the `comint-mode-hook' is only
-executed once when the buffer is created.")
-
-(defvar comint-mode-map nil)
-
-(defvar comint-ptyp t
-  "True if communications via pty; false if by pipe.  Buffer local.
-This is to work around a bug in Emacs process signalling.")
-
-;;(defvar comint-last-input-match ""
-;;  "Last string searched for by comint input history search, for defaulting.
-;;Buffer local variable.") 
-
-(defvar comint-input-ring nil)
-(defvar comint-last-input-start)
-(defvar comint-last-input-end)
-(defvar comint-input-ring-index)
-(put 'comint-input-ring 'permanent-local t)
-(put 'comint-ptyp 'permanent-local t)
-
-(defun comint-mode ()
-  "Major mode for interacting with an inferior interpreter.
-Interpreter name is same as buffer name, sans the asterisks.
-Return at end of buffer sends line as input.
-Return not at end copies rest of line to end and sends it.
-Setting variable `comint-eol-on-send' means jump to the end of the line
-before submitting new input.
-
-This mode is typically customised to create Inferior Lisp mode,
-Shell mode, etc.  This can be done by setting the hooks
-`comint-input-sentinel', `comint-input-filter', `comint-input-sender' and
-`comint-get-old-input' to appropriate functions, and the variable
-`comint-prompt-regexp' to the appropriate regular expression.
-
-An input history is maintained of size `comint-input-ring-size', and
-can be accessed with the commands \\[comint-next-input] and \\[comint-previous-input].
-Commands with no default key bindings include `send-invisible',
-`comint-dynamic-complete', and `comint-list-dynamic-completions'.
-
-If you accidentally suspend your process, use \\[comint-continue-subjob]
-to continue it.
-
-\\{comint-mode-map}
-
-Entry to this mode runs the hooks on comint-mode-hook"
-  (interactive)
-    ;; Do not remove this.  All major modes must do this.
-    (kill-all-local-variables)
-    (setq major-mode 'comint-mode)
-    (setq mode-name "Comint")
-    (setq mode-line-process '(": %s"))
-    (use-local-map comint-mode-map)
-    (make-local-variable 'comint-last-input-start)
-    (setq comint-last-input-start (make-marker))
-    (make-local-variable 'comint-last-input-end)
-    (setq comint-last-input-end (make-marker))
-;;;    (make-local-variable 'comint-last-input-match)
-;;;    (setq comint-last-input-match "")
-    (make-local-variable 'comint-prompt-regexp) ; Don't set; default
-    (make-local-variable 'comint-input-ring-size)      ; ...to global val.
-    (make-local-variable 'comint-input-ring)
-    (make-local-variable 'comint-input-ring-index)
-    (setq comint-input-ring-index 0)
-    (make-local-variable 'comint-get-old-input)
-    (make-local-variable 'comint-input-sentinel)
-    (make-local-variable 'comint-input-filter)  
-    (make-local-variable 'comint-input-sender)
-    (make-local-variable 'comint-eol-on-send)
-    (make-local-variable 'comint-ptyp)
-    (make-local-variable 'comint-exec-hook)
-    (make-local-variable 'comint-process-echoes)
-    (run-hooks 'comint-mode-hook)
-    (or comint-input-ring
-       (setq comint-input-ring (make-ring comint-input-ring-size))))
-
-(if comint-mode-map
-    nil
-  (setq comint-mode-map (make-sparse-keymap))
-  (define-key comint-mode-map "\ep" 'comint-previous-input)
-  (define-key comint-mode-map "\en" 'comint-next-input)
-  (define-key comint-mode-map "\er" 'comint-previous-matching-input)
-  (define-key comint-mode-map "\es" 'comint-next-matching-input)
-  (define-key comint-mode-map "\C-m" 'comint-send-input)
-  (define-key comint-mode-map "\C-d" 'comint-delchar-or-maybe-eof)
-  (define-key comint-mode-map "\C-a" 'comint-bol)
-  (define-key comint-mode-map "\C-c\C-u" 'comint-kill-input)
-  (define-key comint-mode-map "\C-c\C-w" 'backward-kill-word)
-  (define-key comint-mode-map "\C-c\C-c" 'comint-interrupt-subjob)
-  (define-key comint-mode-map "\C-c\C-z" 'comint-stop-subjob)
-  (define-key comint-mode-map "\C-c\C-\\" 'comint-quit-subjob)
-  (define-key comint-mode-map "\C-c\C-o" 'comint-kill-output)
-  (define-key comint-mode-map "\C-c\C-r" 'comint-show-output)
-  ;;; prompt-search commands commented out 3/90 -Olin
-; (define-key comint-mode-map "\eP" 'comint-msearch-input)
-; (define-key comint-mode-map "\eN" 'comint-psearch-input)
-; (define-key comint-mode-map "\C-cR" 'comint-msearch-input-matching)
-  (define-key comint-mode-map "\C-c\C-n" 'comint-next-prompt)
-  (define-key comint-mode-map "\C-c\C-p" 'comint-prev-prompt)
-  (define-key comint-mode-map "\C-c\C-d" 'comint-send-eof)
-  (define-key comint-mode-map "\C-c\C-y" 'comint-previous-input) ;v18 binding
-  )
-
-
-;;; This function is used to make a full copy of the comint mode map,
-;;; so that client modes won't interfere with each other. This function
-;;; isn't necessary in emacs 18.5x, but we keep it around for 18.4x versions.
-(defun full-copy-sparse-keymap (km)
-  "Recursively copy the sparse keymap KM."
-  (cond ((consp km)
-        (cons (full-copy-sparse-keymap (car km))
-              (full-copy-sparse-keymap (cdr km))))
-       (t km)))
-
-(defun comint-check-proc (buffer)
-  "True if there is a living process associated w/buffer BUFFER.
-Living means the status is `run' or `stop'.
-BUFFER can be either a buffer or the name of one."
-  (let ((proc (get-buffer-process buffer)))
-    (and proc (memq (process-status proc) '(run stop)))))
-
-;;; Note that this guy, unlike shell.el's make-shell, barfs if you pass it ()
-;;; for the second argument (program).
-;;;###autoload
-(defun make-comint (name program &optional startfile &rest switches)
-  "Make a comint 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.
-Optional third arg STARTFILE is the name of a file to send the contents of to 
-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
-    ;; comint mode.  Otherwise, leave buffer and existing process alone.
-    (cond ((not (comint-check-proc buffer))
-          (save-excursion
-            (set-buffer buffer)
-            (comint-mode)) ; Install local vars, mode, keymap, ...
-          (comint-exec buffer name program startfile switches)))
-    buffer))
-
-(defun comint-exec (buffer name command startfile switches)
-  "Start up a process in buffer BUFFER for comint modes.
-Blasts any old process running in the buffer.  Doesn't set the buffer mode.
-You can use this to cheaply run a series of processes in the same comint
-buffer.  The hook `comint-exec-hook' is run after each exec."
-  (save-excursion
-    (set-buffer buffer)
-    (let ((proc (get-buffer-process buffer)))  ; Blast any old process.
-      (if proc (delete-process proc)))
-    ;; Crank up a new process
-    (let ((proc (comint-exec-1 name buffer command switches)))
-      (set-process-filter proc 'comint-filter)
-      (make-local-variable 'comint-ptyp)
-      (setq comint-ptyp process-connection-type) ; T if pty, NIL if pipe.
-      ;; Jump to the end, and set the process mark.
-      (goto-char (point-max))
-      (set-marker (process-mark proc) (point))
-      ;; Feed it the startfile.
-      (cond (startfile
-            ;;This is guaranteed to wait long enough
-            ;;but has bad results if the comint 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))
-            (comint-send-string proc startfile)))
-    (run-hooks 'comint-exec-hook)
-    buffer)))
-
-;;; This auxiliary function cranks up the process for comint-exec in
-;;; the appropriate environment.
-
-(defun comint-exec-1 (name buffer command switches)
-  (let ((process-environment
-        (comint-update-env process-environment
-                           (list (format "TERMCAP=emacs:co#%d:tc=unknown"
-                                         (frame-width))
-                                 "TERM=emacs"
-                                 "EMACS=t"))))
-    (apply 'start-process name buffer command switches)))
-            
-
-
-;; This is just (append new old-env) that compresses out shadowed entries.
-;; It's also pretty ugly, mostly due to lisp's horrible iteration structures.
-(defun comint-update-env (old-env new)
-  (let ((ans (reverse new))
-       (vars (mapcar (function (lambda (vv)
-                       (and (string-match "^[^=]*=" vv)
-                            (substring vv 0 (match-end 0)))))
-                     new)))
-    (while old-env
-      (let* ((vv (car old-env)) ; vv is var=value
-            (var (and (string-match "^[^=]*=" vv)
-                      (substring vv 0 (match-end 0)))))
-       (setq old-env (cdr old-env))
-       (cond ((not (and var (member var vars)))
-              (if var (setq var (cons var vars)))
-              (setq ans (cons vv ans))))))
-    (nreverse ans)))
-
-\f
-;;; Input history retrieval commands
-;;; M-p -- previous input    M-n -- next input
-;;; M-C-r -- previous input matching
-;;; ===========================================================================
-
-(defun comint-previous-input (arg)
-  "Cycle backwards through input history."
-  (interactive "*p")
-  (let ((len (ring-length comint-input-ring)))
-    (cond ((<= len 0)
-          (message "Empty input ring")
-          (ding))
-         ((not (comint-after-pmark-p))
-          (message "Not after process mark")
-          (ding))
-         (t
-          (delete-region (point)
-                         (process-mark (get-buffer-process (current-buffer))))
-          ;; Initialize the index on the first use of this command
-          ;; so that the first M-p gets index 0, and the first M-n gets
-          ;; index -1.
-          (if (null comint-input-ring-index)
-              (setq comint-input-ring-index
-                    (if (> arg 0) -1
-                        (if (< arg 0) 1 0))))
-          (setq comint-input-ring-index
-                (ring-mod (+ comint-input-ring-index arg) len))
-          (message "%d" (1+ comint-input-ring-index))
-          (insert (ring-ref comint-input-ring comint-input-ring-index))))))
-
-(defun comint-next-input (arg)
-  "Cycle forwards through input history."
-  (interactive "*p")
-  (comint-previous-input (- arg)))
-
-(defun comint-previous-matching-input (regexp arg)
-  "Search backwards through input history for match for REGEXP.
-\(Previous history elements are earlier commands.)
-With prefix argument N, search for Nth previous match.
-If N is negative, find the next or Nth next match."
-  (interactive
-   (let* ((minibuffer-history-sexp-flag nil)
-         ;; Don't clobber this.
-         (last-command last-command)
-         (regexp (read-from-minibuffer "Previous input matching (regexp): "
-                                       nil
-                                       minibuffer-local-map
-                                       nil
-                                       'minibuffer-history-search-history)))
-     (list (if (string= regexp "")
-              (setcar minibuffer-history-search-history
-                      (nth 1 minibuffer-history-search-history))
-            regexp)
-          (prefix-numeric-value current-prefix-arg))))
-  (if (null comint-input-ring-index)
-      (setq comint-input-ring-index -1))
-  (let* ((len (ring-length comint-input-ring))
-        (motion (if (> arg 0) 1 -1))
-        (n comint-input-ring-index))
-    ;; Do the whole search as many times as the argument says.
-    (while (/= arg 0)
-      (let ((prev n))
-       ;; Step once.
-       (setq n (ring-mod (+ n motion) len))
-       ;; If we haven't reached a match, step some more.
-       (while (and (< n len)
-                   (not (string-match regexp (ring-ref comint-input-ring n))))
-         (setq n (ring-mod (+ n motion) len))
-         ;; If we have gone all the way around in this search, error.
-         (if (= n prev)
-             (error "Not found"))))
-      (setq arg (if (> arg 0) (1- arg) (1+ arg))))
-    ;; Now that we know which ring element to use,
-    ;; substitute that for the current input.
-    (comint-previous-input (- n comint-input-ring-index))))
-
-(defun comint-next-matching-input (regexp arg)
-  "Search forwards through input history for match for REGEXP.
-\(Later history elements are more recent commands.)
-With prefix argument N, search for Nth following match.
-If N is negative, find the previous or Nth previous match."
-  (interactive
-   (let ((minibuffer-history-sexp-flag nil)
-        ;; Don't clobber this.
-        (last-command last-command)
-        (regexp (read-from-minibuffer "Previous input matching (regexp): "
-                                      nil
-                                      minibuffer-local-map
-                                      nil
-                                      'minibuffer-history-search-history)))
-     (list (if (string= regexp "")
-              (setcar minibuffer-history-search-history
-                      (nth 1 minibuffer-history-search-history))
-            regexp)
-          (prefix-numeric-value current-prefix-arg))))
-  (comint-previous-matching-input regexp (- arg)))
-\f
-;;; These next three commands are alternatives to the input history commands
-;;; They search through the process buffer
-;;; text looking for occurrences of the prompt.  Bound to M-P, M-N, and C-c R
-;;; (uppercase P, N, and R) for now. Try'em out. Go with what you like...
-
-;;; comint-msearch-input-matching prompts for a string, not a regexp.
-;;; This could be considered to be the wrong thing. I decided to keep it
-;;; simple, and not make the user worry about regexps. This, of course,
-;;; limits functionality.
-
-;;; These commands were deemed non-winning and have been commented out.
-;;; Feel free to re-enable them if you like. -Olin 3/91
-
-;(defun comint-psearch-input ()
-;  "Search forwards for next occurrence of prompt and skip to end of line.
-;\(prompt is anything matching regexp comint-prompt-regexp)"
-;  (interactive)
-;  (if (re-search-forward comint-prompt-regexp (point-max) t)
-;      (end-of-line)
-;      (error "No occurrence of prompt found")))
-;
-;(defun comint-msearch-input ()
-;  "Search backwards for previous occurrence of prompt and skip to end of line.
-;Search starts from beginning of current line."
-;  (interactive)
-;  (let ((p (save-excursion
-;           (beginning-of-line)
-;           (cond ((re-search-backward comint-prompt-regexp (point-min) t)
-;                  (end-of-line)
-;                  (point))
-;                 (t nil)))))
-;    (if p (goto-char p)
-;      (error "No occurrence of prompt found"))))
-;
-;(defun comint-msearch-input-matching (str)
-;  "Search backwards for occurrence of prompt followed by STRING.
-;STRING is prompted for, and is NOT a regular expression."
-;  (interactive (let ((s (read-from-minibuffer 
-;                       (format "Command (default %s): "
-;                               comint-last-input-match))))
-;               (list (if (string= s "") comint-last-input-match s))))
-;; (interactive "sCommand: ")
-;  (setq comint-last-input-match str) ; update default
-;  (let* ((r (concat comint-prompt-regexp (regexp-quote str)))
-;       (p (save-excursion
-;            (beginning-of-line)
-;            (cond ((re-search-backward r (point-min) t)
-;                   (end-of-line)
-;                   (point))
-;                  (t nil)))))
-;    (if p (goto-char p)
-;      (error "No match"))))
-
-;;;
-;;; Similar input -- contributed by ccm and highly winning.
-;;;
-;;; Reenter input, removing back to the last insert point if it exists. 
-;;;
-;;(defvar comint-last-similar-string "" 
-;;  "The string last used in a similar string search.")
-
-;;(defun comint-previous-similar-input (arg)
-;;  "Fetch the previous (older) input that matches the string typed so far.
-;;Successive repetitions find successively older matching inputs.
-;;A prefix argument serves as a repeat count; a negative argument
-;;fetches following (more recent) inputs."
-;;  (interactive "p")
-;;  (if (not (comint-after-pmark-p))
-;;      (error "Not after process mark"))
-;;  (if (null comint-input-ring-index)
-;;      (setq comint-input-ring-index
-;;         (if (> arg 0) -1
-;;           (if (< arg 0) 1 0))))
-;;  (if (not (or (eq last-command 'comint-previous-similar-input)
-;;            (eq last-command 'comint-next-similar-input)))
-;;      (setq comint-last-similar-string 
-;;         (buffer-substring 
-;;          (process-mark (get-buffer-process (current-buffer)))
-;;          (point))))
-;;  (let* ((size (length comint-last-similar-string))
-;;      (len (ring-length comint-input-ring))
-;;      (n (+ comint-input-ring-index arg))
-;;      entry)
-;;    (while (and (< n len) 
-;;             (or (< (length (setq entry (ring-ref comint-input-ring n))) size)
-;;                 (not (equal comint-last-similar-string 
-;;                             (substring entry 0 size)))))
-;;      (setq n (+ n arg)))
-;;    (cond ((< n len)
-;;        (setq comint-input-ring-index n)
-;;        (if (or (eq last-command 'comint-previous-similar-input)
-;;                (eq last-command 'comint-next-similar-input))
-;;            (delete-region (mark) (point)) ; repeat
-;;            (push-mark (point)))           ; 1st time
-;;        (insert (substring entry size)))
-;;       (t (error "Not found")))
-;;    (message "%d" (1+ comint-input-ring-index))))
-
-;;(defun comint-next-similar-input (arg)
-;;  "Fetch the next (newer) input that matches the string typed so far.
-;;Successive repetitions find successively newer matching inputs.
-;;A prefix argument serves as a repeat count; a negative argument
-;;fetches previous (older) inputs."
-;;  (interactive "p")
-;;  (comint-previous-similar-input (- arg)))
-\f
-(defun comint-send-input () 
-  "Send input to process.
-After the process output mark, sends all text from the process mark to
-point as input to the process.  Before the process output mark, calls value
-of variable `comint-get-old-input' to retrieve old input, copies it to the
-process mark, and sends it.  If variable `comint-process-echoes' is nil,
-a terminal newline is also inserted into the buffer and sent to the process
-\(if it is non-nil, all text from the process mark to point is deleted,
-since it is assumed the remote process will re-echo it).
-
-The value of variable `comint-input-sentinel' is called on the input
-before sending it.  The input is entered into the input history ring,
-if the value of variable `comint-input-filter' returns non-nil when
-called on the input.
-
-If variable `comint-eol-on-send' is non-nil, then point is moved to the
-end of line before sending the input.
-
-`comint-get-old-input', `comint-input-sentinel', and `comint-input-filter'
-are chosen according to the command interpreter running in the buffer.  E.g.,
-If the interpreter is the csh,
-    comint-get-old-input is the default: take the current line, discard any
-        initial string matching regexp comint-prompt-regexp.
-    comint-input-sentinel monitors input for \"cd\", \"pushd\", and \"popd\" 
-        commands. When it sees one, it cd's the buffer.
-    comint-input-filter is the default: returns T if the input isn't all white
-       space.
-
-If the comint is Lucid Common Lisp, 
-    comint-get-old-input snarfs the sexp ending at point.
-    comint-input-sentinel does nothing.
-    comint-input-filter returns NIL if the input matches input-filter-regexp,
-        which matches (1) all whitespace (2) :a, :c, etc.
-
-Similarly for Soar, Scheme, etc."
-  (interactive)
-  ;; Note that the input string does not include its terminal newline.
-  (let ((proc (get-buffer-process (current-buffer))))
-    (if (not proc) (error "Current buffer has no process")
-       (let* ((pmark (process-mark proc))
-              (pmark-val (marker-position pmark))
-              (input (if (>= (point) pmark-val)
-                         (progn (if comint-eol-on-send (end-of-line))
-                                (buffer-substring pmark (point)))
-                       (let ((copy (funcall comint-get-old-input)))
-                         (goto-char pmark)
-                         (insert copy)
-                         copy))))
-          (if comint-process-echoes
-              (delete-region pmark (point))
-            (insert ?\n))
-         (if (funcall comint-input-filter input)
-             (ring-insert comint-input-ring input))
-         (funcall comint-input-sentinel input)
-         (funcall comint-input-sender proc input)
-         (setq comint-input-ring-index nil)
-         (set-marker comint-last-input-start pmark)
-         (set-marker comint-last-input-end (point))
-         (set-marker (process-mark proc) (point))))))
-
-;; The sole purpose of using this filter for comint processes
-;; is to keep comint-last-input-end from moving forward
-;; when output is inserted.
-(defun comint-filter (process string)
-  (let ((obuf (current-buffer))
-       opoint obeg oend)
-    (set-buffer (process-buffer process))
-    (setq opoint (point))
-    (setq obeg (point-min))
-    (setq oend (point-max))
-    (let ((buffer-read-only nil)
-         (nchars (length string)))
-      (widen)
-      (goto-char (process-mark process))
-      (if (<= (point) opoint)
-         (setq opoint (+ opoint nchars)))
-      ;; Insert after old_begv, but before old_zv.
-      (if (< (point) obeg)
-         (setq obeg (+ obeg nchars)))
-      (if (<= (point) oend)
-         (setq oend (+ oend nchars)))
-
-      (insert-before-markers string)
-      ;; Don't insert initial prompt outside the top of the window.
-      (if (= (window-start (selected-window)) (point))
-         (set-window-start (selected-window) (- (point) (length string))))
-
-      (and comint-last-input-end
-          (marker-buffer comint-last-input-end)
-          (= (point) comint-last-input-end)
-          (set-marker comint-last-input-end
-                      (- comint-last-input-end nchars)))
-      (set-marker (process-mark process) (point) nil)
-      (force-mode-line-update))
-
-    (narrow-to-region obeg oend)
-    (goto-char opoint)
-    (set-buffer obuf)))
-
-(defun comint-get-old-input-default ()
-  "Default for `comint-get-old-input'.
-Take the current line, and discard any initial text matching
-`comint-prompt-regexp'."
-  (save-excursion
-    (beginning-of-line)
-    (comint-skip-prompt)
-    (let ((beg (point)))
-      (end-of-line)
-      (buffer-substring beg (point)))))
-
-(defun comint-skip-prompt ()
-  "Skip past the text matching regexp `comint-prompt-regexp'.
-If this takes us past the end of the current line, don't skip at all."
-  (let ((eol (save-excursion (end-of-line) (point))))
-    (if (and (looking-at comint-prompt-regexp)
-            (<= (match-end 0) eol))
-       (goto-char (match-end 0)))))
-
-
-(defun comint-after-pmark-p ()
-  "Is point after the process output marker?"
-  ;; Since output could come into the buffer after we looked at the point
-  ;; but before we looked at the process marker's value, we explicitly 
-  ;; serialise. This is just because I don't know whether or not emacs
-  ;; services input during execution of lisp commands.
-  (let ((proc-pos (marker-position
-                  (process-mark (get-buffer-process (current-buffer))))))
-    (<= proc-pos (point))))
-
-(defun comint-simple-send (proc string)
-  "Default function for sending to PROC input STRING.
-This just sends STRING plus a newline. To override this,
-set the hook `comint-input-sender'."
-  (comint-send-string proc string)
-  (comint-send-string proc "\n"))
-
-(defun comint-bol (arg)
-  "Goes to the beginning of line, then skips past the prompt, if any.
-If a prefix argument is given (\\[universal-argument]), then no prompt skip 
--- go straight to column 0.
-
-The prompt skip is done by skipping text matching the regular expression
-`comint-prompt-regexp', a buffer local variable.
-
-If you don't like this command, bind C-a to `beginning-of-line' 
-in your hook, `comint-mode-hook'."
-  (interactive "P")
-  (beginning-of-line)
-  (if (null arg) (comint-skip-prompt)))
-
-;;; These two functions are for entering text you don't want echoed or
-;;; saved -- typically passwords to ftp, telnet, or somesuch.
-;;; Just enter m-x send-invisible and type in your line.
-
-(defun comint-read-noecho (prompt &optional stars)
-  "Read a single line of text from user without echoing, and return it. 
-Prompt with argument PROMPT, a string.  Optional argument STARS causes
-input to be echoed with '*' characters on the prompt line.  Input ends with
-RET, LFD, or ESC.  DEL or C-h rubs out.  C-u kills line.  C-g aborts (if
-`inhibit-quit' is set because e.g. this function was called from a process
-filter and C-g is pressed, this function returns nil rather than a string).
-
-Note that the keystrokes comprising the text can still be recovered
-\(temporarily) with \\[view-lossage].  This may be a security bug for some
-applications."
-  (let ((ans "")
-       (c 0)
-       (echo-keystrokes 0)
-       (cursor-in-echo-area t)
-        (done nil))
-    (while (not done)
-      (if stars
-          (message "%s%s" prompt (make-string (length ans) ?*))
-        (message prompt))
-      (setq c (read-char))
-      (cond ((= c ?\C-g)
-             ;; This function may get called from a process filter, where
-             ;; inhibit-quit is set.  In later versions of emacs read-char
-             ;; may clear quit-flag itself and return C-g.  That would make
-             ;; it impossible to quit this loop in a simple way, so
-             ;; re-enable it here (for backward-compatibility the check for
-             ;; quit-flag below would still be necessary, so this is seems
-             ;; like the simplest way to do things).
-             (setq quit-flag t
-                   done t))
-            ((or (= c ?\r) (= c ?\n) (= c ?\e))
-             (setq done t))
-            ((= c ?\C-u)
-             (setq ans ""))
-            ((and (/= c ?\b) (/= c ?\177))
-             (setq ans (concat ans (char-to-string c))))
-            ((> (length ans) 0)
-             (setq ans (substring ans 0 -1)))))
-    (if quit-flag
-        ;; Emulate a true quit, except that we have to return a value.
-        (prog1
-            (setq quit-flag nil)
-          (message "Quit")
-          (beep t))
-      (message "")
-      ans)))
-
-(defun send-invisible (str)
-  "Read a string without echoing.
-Then send it to the process running in the current buffer.  A new-line
-is additionally sent.  String is not saved on comint input history list.
-Security bug: your string can still be temporarily recovered with
-\\[view-lossage]."
-; (interactive (list (comint-read-noecho "Enter non-echoed text")))
-  (interactive "P") ; Defeat snooping via C-x esc
-  (let ((proc (get-buffer-process (current-buffer))))
-    (if (not proc) (error "Current buffer has no process")
-       (comint-send-string proc
-                           (if (stringp str) str
-                               (comint-read-noecho "Non-echoed text: " t)))
-       (comint-send-string proc "\n"))))
-
-\f
-;;; Low-level process communication
-
-(defvar comint-input-chunk-size 512
-  "*Long inputs are sent to comint processes in chunks of this size.
-If your process is choking on big inputs, try lowering the value.")
-
-(defun comint-send-string (proc str)
-  "Send PROCESS the contents of STRING as input.
-This is equivalent to `process-send-string', except that long input strings
-are broken up into chunks of size `comint-input-chunk-size'.  Processes
-are given a chance to output between chunks.  This can help prevent processes
-from hanging when you send them long inputs on some OS's."
-  (let* ((len (length str))
-        (i (min len comint-input-chunk-size)))
-    (process-send-string proc (substring str 0 i))
-    (while (< i len)
-      (let ((next-i (+ i comint-input-chunk-size)))
-       (accept-process-output)
-       (process-send-string proc (substring str i (min len next-i)))
-       (setq i next-i)))))
-
-(defun comint-send-region (proc start end)
-  "Sends to PROC the region delimited by START and END.
-This is a replacement for `process-send-region' that tries to keep
-your process from hanging on long inputs.  See `comint-send-string'."
-  (comint-send-string proc (buffer-substring start end)))
-
-\f
-;;; Random input hackage
-
-(defun comint-kill-output ()
-  "Kill all output from interpreter since last input."
-  (interactive)
-  (let ((pmark (process-mark (get-buffer-process (current-buffer)))))
-    (kill-region comint-last-input-end pmark)
-    (goto-char pmark)    
-    (insert "*** output flushed ***\n")
-    (set-marker pmark (point))))
-
-(defun comint-show-output ()
-  "Display start of this batch of interpreter output at top of window.
-Also put cursor there."
-  (interactive)
-  (goto-char comint-last-input-end)
-  (backward-char)
-  (beginning-of-line)
-  (set-window-start (selected-window) (point))
-  (end-of-line))
-
-(defun comint-interrupt-subjob ()
-  "Interrupt the current subjob."
-  (interactive)
-  (interrupt-process nil comint-ptyp))
-
-(defun comint-kill-subjob ()
-  "Send kill signal to the current subjob."
-  (interactive)
-  (kill-process nil comint-ptyp))
-
-(defun comint-quit-subjob ()
-  "Send quit signal to the current subjob."
-  (interactive)
-  (quit-process nil comint-ptyp))
-
-(defun comint-stop-subjob ()
-  "Stop the current subjob.
-WARNING: if there is no current subjob, you can end up suspending
-the top-level process running in the buffer. If you accidentally do
-this, use \\[comint-continue-subjob] to resume the process. (This
-is not a problem with most shells, since they ignore this signal.)"
-  (interactive)
-  (stop-process nil comint-ptyp))
-
-(defun comint-continue-subjob ()
-  "Send CONT signal to process buffer's process group.
-Useful if you accidentally suspend the top-level process."
-  (interactive)
-  (continue-process nil comint-ptyp))
-
-(defun comint-kill-input ()
-  "Kill all text from last stuff output by interpreter to point."
-  (interactive)
-  (let* ((pmark (process-mark (get-buffer-process (current-buffer))))
-        (p-pos (marker-position pmark)))
-    (if (> (point) p-pos)
-       (kill-region pmark (point)))))
-
-(defun comint-delchar-or-maybe-eof (arg)
-  "Delete ARG characters forward, or send an EOF to process if at end of buffer."
-  (interactive "p")
-  (if (eobp)
-      (process-send-eof)
-      (delete-char arg)))
-
-(defun comint-send-eof ()
-  "Send an EOF to the current buffer's process."
-  (interactive)
-  (process-send-eof))
-
-(defun comint-next-prompt (n)
-  "\
-Move to end of next prompt in the buffer (with prefix arg, Nth next).
-See `comint-prompt-regexp'."
-  (interactive "p")
-  (re-search-forward comint-prompt-regexp nil nil n))
-
-(defun comint-prev-prompt (n)
-  "\
-Move to end of previous prompt in the buffer (with prefix arg, Nth previous).
-See `comint-prompt-regexp'."
-  (interactive "p")
-  (if (= (save-excursion (re-search-backward comint-prompt-regexp nil t)
-                        (match-end 0))
-        (point))
-      (setq n (1+ n)))
-  (re-search-backward comint-prompt-regexp nil nil n)
-  (goto-char (match-end 0)))
-\f
-;;; Support for source-file processing commands.
-;;;============================================================================
-;;; Many command-interpreters (e.g., Lisp, Scheme, Soar) have
-;;; commands that process files of source text (e.g. loading or compiling
-;;; files). So the corresponding process-in-a-buffer modes have commands
-;;; for doing this (e.g., lisp-load-file). The functions below are useful
-;;; for defining these commands.
-;;;
-;;; Alas, these guys don't do exactly the right thing for Lisp, Scheme
-;;; and Soar, in that they don't know anything about file extensions.
-;;; So the compile/load interface gets the wrong default occasionally.
-;;; The load-file/compile-file default mechanism could be smarter -- it
-;;; doesn't know about the relationship between filename extensions and
-;;; whether the file is source or executable. If you compile foo.lisp
-;;; with compile-file, then the next load-file should use foo.bin for
-;;; the default, not foo.lisp. This is tricky to do right, particularly
-;;; because the extension for executable files varies so much (.o, .bin,
-;;; .lbin, .mo, .vo, .ao, ...).
-
-
-;;; COMINT-SOURCE-DEFAULT -- determines defaults for source-file processing
-;;; commands.
-;;;
-;;; COMINT-CHECK-SOURCE -- if FNAME is in a modified buffer, asks you if you
-;;; want to save the buffer before issuing any process requests to the command
-;;; interpreter.
-;;;
-;;; COMINT-GET-SOURCE -- used by the source-file processing commands to prompt
-;;; for the file to process.
-
-;;; (COMINT-SOURCE-DEFAULT previous-dir/file source-modes)
-;;;============================================================================
-;;; This function computes the defaults for the load-file and compile-file
-;;; commands for tea, soar, cmulisp, and cmuscheme modes. 
-;;; 
-;;; - PREVIOUS-DIR/FILE is a pair (directory . filename) from the last 
-;;; source-file processing command. NIL if there hasn't been one yet.
-;;; - SOURCE-MODES is a list used to determine what buffers contain source
-;;; files: if the major mode of the buffer is in SOURCE-MODES, it's source.
-;;; Typically, (lisp-mode) or (scheme-mode).
-;;; 
-;;; If the command is given while the cursor is inside a string, *and*
-;;; the string is an existing filename, *and* the filename is not a directory,
-;;; then the string is taken as default. This allows you to just position
-;;; your cursor over a string that's a filename and have it taken as default.
-;;;
-;;; If the command is given in a file buffer whose major mode is in
-;;; SOURCE-MODES, then the the filename is the default file, and the
-;;; file's directory is the default directory.
-;;; 
-;;; If the buffer isn't a source file buffer (e.g., it's the process buffer),
-;;; then the default directory & file are what was used in the last source-file
-;;; processing command (i.e., PREVIOUS-DIR/FILE).  If this is the first time
-;;; the command has been run (PREVIOUS-DIR/FILE is nil), the default directory
-;;; is the cwd, with no default file. (\"no default file\" = nil)
-;;; 
-;;; SOURCE-REGEXP is typically going to be something like (tea-mode)
-;;; for T programs, (lisp-mode) for Lisp programs, (soar-mode lisp-mode)
-;;; for Soar programs, etc.
-;;; 
-;;; The function returns a pair: (default-directory . default-file).
-
-(defun comint-source-default (previous-dir/file source-modes)
-  (cond ((and buffer-file-name (memq major-mode source-modes))
-        (cons (file-name-directory    buffer-file-name)
-              (file-name-nondirectory buffer-file-name)))
-       (previous-dir/file)
-       (t
-        (cons default-directory nil))))
-
-
-;;; (COMINT-CHECK-SOURCE fname)
-;;;============================================================================
-;;; Prior to loading or compiling (or otherwise processing) a file (in the CMU
-;;; process-in-a-buffer modes), this function can be called on the filename.
-;;; If the file is loaded into a buffer, and the buffer is modified, the user
-;;; is queried to see if he wants to save the buffer before proceeding with
-;;; the load or compile.
-
-(defun comint-check-source (fname)
-  (let ((buff (get-file-buffer fname)))
-    (if (and buff
-            (buffer-modified-p buff)
-            (y-or-n-p (format "Save buffer %s first? "
-                              (buffer-name buff))))
-       ;; save BUFF.
-       (let ((old-buffer (current-buffer)))
-         (set-buffer buff)
-         (save-buffer)
-         (set-buffer old-buffer)))))
-
-
-;;; (COMINT-GET-SOURCE prompt prev-dir/file source-modes mustmatch-p)
-;;;============================================================================
-;;; COMINT-GET-SOURCE is used to prompt for filenames in command-interpreter
-;;; commands that process source files (like loading or compiling a file).
-;;; It prompts for the filename, provides a default, if there is one,
-;;; and returns the result filename.
-;;; 
-;;; See COMINT-SOURCE-DEFAULT for more on determining defaults.
-;;; 
-;;; PROMPT is the prompt string. PREV-DIR/FILE is the (directory . file) pair
-;;; from the last source processing command.  SOURCE-MODES is a list of major
-;;; modes used to determine what file buffers contain source files.  (These
-;;; two arguments are used for determining defaults). If MUSTMATCH-P is true,
-;;; then the filename reader will only accept a file that exists.
-;;; 
-;;; A typical use:
-;;; (interactive (comint-get-source "Compile file: " prev-lisp-dir/file
-;;;                                 '(lisp-mode) t))
-
-;;; This is pretty stupid about strings. It decides we're in a string
-;;; if there's a quote on both sides of point on the current line.
-(defun comint-extract-string ()
-  "Return string around POINT that starts the current line, or nil." 
-  (save-excursion
-    (let* ((point (point))
-          (bol (progn (beginning-of-line) (point)))
-          (eol (progn (end-of-line) (point)))
-          (start (progn (goto-char point) 
-                        (and (search-backward "\"" bol t) 
-                             (1+ (point)))))
-          (end (progn (goto-char point)
-                      (and (search-forward "\"" eol t)
-                           (1- (point))))))
-      (and start end
-          (buffer-substring start end)))))
-
-(defun comint-get-source (prompt prev-dir/file source-modes mustmatch-p)
-  (let* ((def (comint-source-default prev-dir/file source-modes))
-         (stringfile (comint-extract-string))
-        (sfile-p (and stringfile
-                      (condition-case ()
-                          (file-exists-p stringfile)
-                        (error nil))
-                      (not (file-directory-p stringfile))))
-        (defdir  (if sfile-p (file-name-directory stringfile)
-                      (car def)))
-        (deffile (if sfile-p (file-name-nondirectory stringfile)
-                      (cdr def)))
-        (ans (read-file-name (if deffile (format "%s(default %s) "
-                                                 prompt    deffile)
-                                 prompt)
-                             defdir
-                             (concat defdir deffile)
-                             mustmatch-p)))
-    (list (expand-file-name (substitute-in-file-name ans)))))
-
-;;; I am somewhat divided on this string-default feature. It seems
-;;; to violate the principle-of-least-astonishment, in that it makes
-;;; the default harder to predict, so you actually have to look and see
-;;; what the default really is before choosing it. This can trip you up.
-;;; On the other hand, it can be useful, I guess. I would appreciate feedback
-;;; on this.
-;;;     -Olin
-
-\f
-;;; Simple process query facility.
-;;; ===========================================================================
-;;; This function is for commands that want to send a query to the process
-;;; and show the response to the user. For example, a command to get the
-;;; arglist for a Common Lisp function might send a "(arglist 'foo)" query
-;;; to an inferior Common Lisp process.
-;;; 
-;;; This simple facility just sends strings to the inferior process and pops
-;;; up a window for the process buffer so you can see what the process
-;;; responds with.  We don't do anything fancy like try to intercept what the
-;;; process responds with and put it in a pop-up window or on the message
-;;; line. We just display the buffer. Low tech. Simple. Works good.
-
-;;; Send to the inferior process PROC the string STR. Pop-up but do not select
-;;; a window for the inferior process so that its response can be seen.
-(defun comint-proc-query (proc str)
-  (let* ((proc-buf (process-buffer proc))
-        (proc-mark (process-mark proc)))
-    (display-buffer proc-buf)
-    (set-buffer proc-buf) ; but it's not the selected *window*
-    (let ((proc-win (get-buffer-window proc-buf))
-         (proc-pt (marker-position proc-mark)))
-      (comint-send-string proc str) ; send the query
-      (accept-process-output proc)  ; wait for some output
-      ;; Try to position the proc window so you can see the answer.
-      ;; This is bogus code. If you delete the (sit-for 0), it breaks.
-      ;; I don't know why. Wizards invited to improve it.
-      (if (not (pos-visible-in-window-p proc-pt proc-win))
-         (let ((opoint (window-point proc-win)))
-           (set-window-point proc-win proc-mark) (sit-for 0)
-           (if (not (pos-visible-in-window-p opoint proc-win))
-               (push-mark opoint)
-               (set-window-point proc-win opoint)))))))
-
-\f
-;;; Filename completion in a buffer
-;;; ===========================================================================
-;;; Useful completion functions, courtesy of the Ergo group.
-
-;;; Three commands:
-;;; comint-dynamic-complete            Complete filename at point.
-;;; comint-dynamic-list-completions    List completions in help buffer.
-;;; comint-replace-by-expanded-filename        Expand and complete filename at point;
-;;;                                    replace with expanded/completed name.
-
-;;; These are not installed in the comint-mode keymap. But they are
-;;; available for people who want them. Shell-mode installs them:
-;;; (define-key shell-mode-map "\t" 'comint-dynamic-complete)
-;;; (define-key shell-mode-map "\M-?"  'comint-dynamic-list-completions)))
-;;;
-;;; Commands like this are fine things to put in load hooks if you
-;;; want them present in specific modes.
-
-
-(defun comint-match-partial-pathname ()
-  "Return the filename at point, or signal an error."
-  (save-excursion
-    (if (re-search-backward "[^~/A-Za-z0-9_.$#,=-]" nil 'move)
-       (forward-char 1))
-    ;; Anchor the search forwards.
-    (if (not (looking-at "[~/A-Za-z0-9_.$#,=-]")) (error ""))
-    (re-search-forward "[~/A-Za-z0-9_.$#,=-]+")
-    (substitute-in-file-name
-     (buffer-substring (match-beginning 0) (match-end 0)))))
-
-
-(defun comint-replace-by-expanded-filename ()
-  "Expand the filename at point.
-Replace the filename with an expanded, canonicalised, and completed
- replacement.
-\"Expanded\" means environment variables (e.g., $HOME) and ~'s are
-replaced with the corresponding directories.  \"Canonicalised\" means ..
-and \. are removed, and the filename is made absolute instead of relative.
-See functions `expand-file-name' and `substitute-in-file-name'.  See also
-`comint-dynamic-complete'."
-  (interactive)
-  (let* ((pathname (comint-match-partial-pathname))
-        (pathdir (file-name-directory pathname))
-        (pathnondir (file-name-nondirectory pathname))
-        (completion (file-name-completion pathnondir
-                                          (or pathdir default-directory))))
-    (cond ((null completion)
-          (message "No completions of %s" pathname)
-          (ding))
-         ((eql completion t)
-          (message "Sole completion"))
-         (t                            ; this means a string was returned.
-          (delete-region (match-beginning 0) (match-end 0))
-          (insert (expand-file-name (concat pathdir completion)))))))
-
-
-(defun comint-dynamic-complete ()
-  "Dynamically complete the filename at point.
-This function is similar to `comint-replace-by-expanded-filename', except
-that it won't change parts of the filename already entered in the buffer; 
-it just adds completion characters to the end of the filename."
-  (interactive)
-  (if (and (interactive-p)
-          (eq last-command this-command))
-      ;; If you hit TAB twice in a row, you get a completion list.
-      (comint-dynamic-list-completions)
-    (let* ((pathname (comint-match-partial-pathname))
-          (pathdir (file-name-directory pathname))
-          (pathnondir (file-name-nondirectory pathname))
-          (completion (file-name-completion
-                       pathnondir
-                       ;; It is important to expand PATHDIR because
-                       ;; default-directory might be a handled name, and the
-                       ;; unexpanded PATHDIR won't necessarily match the
-                       ;; handler regexp.
-                       (if pathdir
-                           (expand-file-name pathdir)
-                         default-directory))))
-      (cond ((null completion)
-            (message "No completions of %s" pathname)
-            (ding))
-           ((eql completion t)
-            (message "Sole completion"))
-           (t                          ; this means a string was returned.
-            (goto-char (match-end 0))
-            (insert (substring completion (length pathnondir))))))))
-
-(defun comint-dynamic-list-completions ()
-  "List in help buffer all possible completions of the filename at point."
-  (interactive)
-  (let* ((pathname (comint-match-partial-pathname))
-        (pathdir (file-name-directory pathname))
-        (pathnondir (file-name-nondirectory pathname))
-        (completions
-         (file-name-all-completions pathnondir
-                                    (if pathdir
-                                        (expand-file-name pathdir)
-                                      default-directory))))
-    (cond ((null completions)
-          (message "No completions of %s" pathname)
-          (ding))
-         (t
-          (let ((conf (current-window-configuration)))
-            (with-output-to-temp-buffer "*Help*"
-              (display-completion-list completions))
-            (sit-for 0)
-            (message "Hit space to flush")
-            (let ((ch (read-event)))
-              (if (eq ch ?\ )
-                  (set-window-configuration conf)
-                (setq unread-command-events (list ch)))))))))
-\f
-;;; Converting process modes to use comint mode
-;;; ===========================================================================
-;;; The code in the Emacs 19 distribution has all been modified to use comint
-;;; where needed.  However, there are `third-party' packages out there that
-;;; still use the old shell mode.  Here's a guide to conversion.
-;;;
-;;; Renaming variables
-;;; Most of the work is renaming variables and functions. These are the common
-;;; ones:
-;;; Local variables:
-;;;    last-input-start        comint-last-input-start
-;;;    last-input-end          comint-last-input-end
-;;;    shell-prompt-pattern    comint-prompt-regexp
-;;;     shell-set-directory-error-hook <no equivalent>
-;;; Miscellaneous:
-;;;    shell-set-directory     <unnecessary>
-;;;    shell-mode-map          comint-mode-map
-;;; Commands:
-;;;    shell-send-input        comint-send-input
-;;;    shell-send-eof          comint-delchar-or-maybe-eof
-;;;    kill-shell-input        comint-kill-input
-;;;    interrupt-shell-subjob  comint-interrupt-subjob
-;;;    stop-shell-subjob       comint-stop-subjob
-;;;    quit-shell-subjob       comint-quit-subjob
-;;;    kill-shell-subjob       comint-kill-subjob
-;;;    kill-output-from-shell  comint-kill-output
-;;;    show-output-from-shell  comint-show-output
-;;;    copy-last-shell-input   Use comint-previous-input/comint-next-input
-;;;
-;;; SHELL-SET-DIRECTORY is gone, its functionality taken over by
-;;; SHELL-DIRECTORY-TRACKER, the shell mode's comint-input-sentinel.
-;;; Comint mode does not provide functionality equivalent to
-;;; shell-set-directory-error-hook; it is gone.
-;;;
-;;; comint-last-input-start is provided for modes which want to munge
-;;; the buffer after input is sent, perhaps because the inferior
-;;; insists on echoing the input.  The LAST-INPUT-START variable in
-;;; the old shell package was used to implement a history mechanism,
-;;; but you should think twice before using comint-last-input-start
-;;; for this; the input history ring often does the job better.
-;;; 
-;;; If you are implementing some process-in-a-buffer mode, called foo-mode, do
-;;; *not* create the comint-mode local variables in your foo-mode function.
-;;; This is not modular.  Instead, call comint-mode, and let *it* create the
-;;; necessary comint-specific local variables. Then create the
-;;; foo-mode-specific local variables in foo-mode.  Set the buffer's keymap to
-;;; be foo-mode-map, and its mode to be foo-mode.  Set the comint-mode hooks
-;;; (comint-prompt-regexp, comint-input-filter, comint-input-sentinel,
-;;; comint-get-old-input) that need to be different from the defaults.  Call
-;;; foo-mode-hook, and you're done. Don't run the comint-mode hook yourself;
-;;; comint-mode will take care of it. The following example, from shell.el,
-;;; is typical:
-;;; 
-;;; (defun shell-mode ()
-;;;   (interactive)
-;;;   (comint-mode)
-;;;   (setq comint-prompt-regexp shell-prompt-pattern)
-;;;   (setq major-mode 'shell-mode)
-;;;   (setq mode-name "Shell")
-;;;   (cond ((not shell-mode-map)
-;;;         (setq shell-mode-map (full-copy-sparse-keymap comint-mode-map))
-;;;         (define-key shell-mode-map "\M-\t" 'comint-dynamic-complete)
-;;;         (define-key shell-mode-map "\M-?"
-;;;                      'comint-dynamic-list-completions)))
-;;;   (use-local-map shell-mode-map)
-;;;   (make-local-variable 'shell-directory-stack)
-;;;   (setq shell-directory-stack nil)
-;;;   (setq comint-input-sentinel 'shell-directory-tracker)
-;;;   (run-hooks 'shell-mode-hook))
-;;;
-;;;
-;;; Note that make-comint is different from make-shell in that it
-;;; doesn't have a default program argument. If you give make-shell
-;;; a program name of NIL, it cleverly chooses one of explicit-shell-name,
-;;; $ESHELL, $SHELL, or /bin/sh. If you give make-comint a program argument
-;;; of NIL, it barfs. Adjust your code accordingly...
-;;;
-\f
-;;; Do the user's customisation...
-
-(defvar comint-load-hook nil
-  "This hook is run when comint is loaded in.
-This is a good place to put keybindings.")
-       
-(run-hooks 'comint-load-hook)
-
-;;; Change log:
-;;; 9/12/89 
-;;;  - Souped up the filename expansion procedures.
-;;;    Doc strings are much clearer and more detailed.
-;;;    Fixed a bug where doing a filename completion when the point
-;;;    was in the middle of the filename instead of at the end would lose.
-;;;
-;;; 2/17/90 
-;;;  - Souped up the command history stuff so that text inserted
-;;;    by comint-previous-input-matching is removed by following
-;;;    command history recalls. comint-next/previous-input-matching
-;;;    is now much more smoothly integrated w/the command history stuff.
-;;;  - Added comint-eol-on-send flag and comint-input-sender hook.
-;;;    Comint-input-sender based on code contributed by Jeff Peck
-;;;    (peck@sun.com).
-;;;
-;;; 3/13/90 ccm@cmu.cs.edu
-;;;  - Added comint-previous-similar-input for looking up similar inputs.
-;;;  - Added comint-send-and-get-output to allow snarfing input from
-;;;    buffer. 
-;;;  - Added the ability to pick up a source file by positioning over
-;;;    a string in comint-get-source.
-;;;  - Added add-hook to make it a little easier for the user to use
-;;;    multiple hooks.
-;;;  
-;;; 5/22/90 shivers
-;;; - Moved Chris' multiplexed ipc stuff to comint-ipc.el.
-;;; - Altered Chris' comint-get-source string feature. The string
-;;;   is only offered as a default if it names an existing file.
-;;; - Changed comint-exec to directly crank up the process, instead
-;;;   of calling the env program. This made background.el happy.
-;;; - Added new buffer-local var comint-ptyp. The problem is that
-;;;   the signalling functions don't work as advertised. If you are
-;;;   communicating via pipes, the CURRENT-GROUP arg is supposed to
-;;;   be ignored, but, unfortunately it seems to be the case that you
-;;;   must pass a NIL for this arg in the pipe case. COMINT-PTYP
-;;;   is a flag that tells whether the process is communicating
-;;;   via pipes or a pty. The comint signalling functions use it
-;;;   to determine the necessary CURRENT-GROUP arg value. The bug
-;;;   has been reported to the Gnu folks.
-;;; - comint-dynamic-complete flushes the help window if you hit space
-;;;   after you execute it.
-;;; - Added functions comint-send-string, comint-send-region and var 
-;;;   comint-input-chunk-size.  comint-send-string tries to prevent processes
-;;;   from hanging when you send them long strings by breaking them into
-;;;   chunks and allowing process output between chunks. I got the idea from
-;;;   Eero Simoncelli's Common Lisp package. Note that using
-;;;   comint-send-string means that the process buffer's contents can change
-;;;   during a call!  If you depend on process output only happening between
-;;;   toplevel commands, this could be a problem. In such a case, use
-;;;   process-send-string instead. If this is a problem for people, I'd like
-;;;   to hear about it.
-;;; - Added comint-proc-query as a simple mechanism for commands that
-;;;   want to query an inferior process and display its response. For a
-;;;   typical use, see lisp-show-arglist in cmulisp.el.
-;;; - Added constant comint-version, which is now "2.01".
-;;;
-;;; 6/14/90 shivers
-;;; - Had comint-update-env defined twice. Removed extra copy. Also
-;;;   renamed mem to be comint-mem, for modularity. The duplication
-;;;   was reported by Michael Meissner.
-;;; 6/16/90 shivers
-;;; - Emacs has two different mechanisms for maintaining the process
-;;;   environment, determined at compile time by the MAINTAIN-ENVIRONMENT
-;;;   #define. One uses the process-environment global variable, and
-;;;   one uses a getenv/setenv interface. comint-exec assumed the
-;;;   process-environment interface; it has been generalised (with
-;;;   comint-exec-1) to handle both cases. Pretty bogus. We could,
-;;;   of course, skip all this and just use the etc/env program to
-;;;   handle the environment tweaking, but that obscures process
-;;;   queries that other modules (like background.el) depend on. etc/env
-;;;   is also fairly bogus. This bug, and some of the fix code was
-;;;   reported by Dan Pierson.
-;;;
-;;; 9/5/90 shivers
-;;; - Changed make-variable-buffer-local's to make-local-variable's.
-;;;   This leaves non-comint-mode buffers alone. Stephane Payrard
-;;;   reported the sloppy usage.
-;;; - You can now go from comint-previous-similar-input to
-;;;   comint-previous-input with no problem.
-;;;
-;;; 12/21/90 shivers
-;;; - Added a condition-case to comint-get-source. Bogus strings
-;;;   beginning with ~ were making the file-exists-p barf.
-;;; - Added "=" to the set of chars recognised by file completion
-;;;   as constituting a filename.
-;;;
-;;; 1/90 shivers
-;;; These changes comprise release 2.02:
-;;; - Removed the kill-all-local-variables in comint-mode. This
-;;;   made it impossible for client modes to set things before calling
-;;;   comint-mode. (In particular, it messed up ilisp.el) In general,
-;;;   the client mode should be responsible for a k-a-l-v's.
-;;; - Fixed comint-match-partial-pathname so that it works in
-;;;   more cases: if the filename begins at the start-of-buffer;
-;;;   if point is on the first char of the filename. Just a question
-;;;   of getting the tricky bits right.
-;;; - Added a hook, comint-exec-hook that is run each time a process
-;;;   is cranked up. Useful for things like process-kill-without-query.
-;;;
-;;; These two were pointed out by tale:
-;;; - Improved the doc string in comint-send-input a little bit.
-;;; - Tweaked make-comint to check process status with comint-check-proc
-;;;   instead of equivalent inline code. 
-;;;
-;;; - Prompt-search history commands have been commented out. I never
-;;;   liked them; I don't think anyone used them.
-;;; - Made comint-exec-hook a local var, as it should have been.
-;;;   (This way, for instance, you can have shell procs kill-w/o-query,
-;;;    but let Scheme procs be default.)
-;;;
-;;; 7/91 Shivers
-;;; - Souped up comint-read-noecho with an optional argument, STARS.
-;;;   Suggested by mjlx@EAGLE.CNSF.CORNELL.EDU.
-;;; - Moved comint-previous-input-matching from C-c r to C-M-r.
-;;;   C-c <letter> bindings are reserved for the user.
-;;;   These bindings were done by Jim Blandy.
-;;; These changes comprise version 2.03.
-
-(provide 'comint)
-
-;;; comint.el ends here
+;;; comint.el --- general command interpreter in a window stuff
+
+;; Copyright (C) 1988, 90, 92, 93, 94, 95 Free Software Foundation, Inc.
+
+;; Author: Olin Shivers <shivers@cs.cmu.edu>
+;; Adapted-by: Simon Marshall <simon@gnu.ai.mit.edu>
+;; Keywords: processes
+
+;; 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
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; Please send me bug reports, bug fixes, and extensions, so that I can
+;; merge them into the master source.
+;;     - Olin Shivers (shivers@cs.cmu.edu)
+;;     - Simon Marshall (simon@gnu.ai.mit.edu)
+
+;; This file defines a general command-interpreter-in-a-buffer package
+;; (comint mode). The idea is that you can build specific process-in-a-buffer
+;; modes on top of comint mode -- e.g., lisp, shell, scheme, T, soar, ....
+;; This way, all these specific packages share a common base functionality, 
+;; and a common set of bindings, which makes them easier to use (and
+;; saves code, implementation time, etc., etc.).
+
+;; Several packages are already defined using comint mode:
+;; - shell.el defines a shell-in-a-buffer mode.
+;; - cmulisp.el defines a simple lisp-in-a-buffer mode.
+;;
+;; - The file cmuscheme.el defines a scheme-in-a-buffer mode.
+;; - The file tea.el tunes scheme and inferior-scheme modes for T.
+;; - The file soar.el tunes lisp and inferior-lisp modes for Soar.
+;; - cmutex.el defines tex and latex modes that invoke tex, latex, bibtex,
+;;   previewers, and printers from within emacs.
+;; - background.el allows csh-like job control inside emacs.
+;; It is pretty easy to make new derived modes for other processes.
+
+;; For documentation on the functionality provided by comint mode, and
+;; the hooks available for customising it, see the comments below.
+;; For further information on the standard derived modes (shell, 
+;; inferior-lisp, inferior-scheme, ...), see the relevant source files.
+
+;; For hints on converting existing process modes (e.g., tex-mode,
+;; background, dbx, gdb, kermit, prolog, telnet) to use comint-mode
+;; instead of shell-mode, see the notes at the end of this file.
+
+\f
+;; Brief Command Documentation:
+;;============================================================================
+;; Comint Mode Commands: (common to all derived modes, like shell & cmulisp
+;; mode)
+;;
+;; m-p     comint-previous-input           Cycle backwards in input history
+;; m-n     comint-next-input               Cycle forwards
+;; m-r     comint-previous-matching-input  Previous input matching a regexp
+;; m-s     comint-next-matching-input      Next input that matches
+;; m-c-l   comint-show-output              Show last batch of process output
+;; return  comint-send-input
+;; c-d     comint-delchar-or-maybe-eof     Delete char unless at end of buff
+;; c-c c-a comint-bol                      Beginning of line; skip prompt
+;; c-c c-u comint-kill-input               ^u
+;; c-c c-w backward-kill-word              ^w
+;; c-c c-c comint-interrupt-subjob         ^c
+;; c-c c-z comint-stop-subjob              ^z
+;; c-c c-\ comint-quit-subjob              ^\
+;; c-c c-o comint-kill-output              Delete last batch of process output
+;; c-c c-r comint-show-output              Show last batch of process output
+;; c-c c-l comint-dynamic-list-input-ring  List input history
+;;
+;; Not bound by default in comint-mode (some are in shell mode)
+;; comint-run                          Run a program under comint-mode
+;; send-invisible                      Read a line w/o echo, and send to proc
+;; comint-dynamic-complete-filename    Complete filename at point.
+;; comint-dynamic-complete-variable    Complete variable name at point.
+;; comint-dynamic-list-filename-completions List completions in help buffer.
+;; comint-replace-by-expanded-filename Expand and complete filename at point;
+;;                                     replace with expanded/completed name.
+;; comint-replace-by-expanded-history  Expand history at point;
+;;                                     replace with expanded name.
+;; comint-magic-space                  Expand history and add (a) space(s).
+;; comint-kill-subjob                  No mercy.
+;; comint-show-maximum-output          Show as much output as possible.
+;; comint-continue-subjob              Send CONT signal to buffer's process
+;;                                     group. Useful if you accidentally
+;;                                     suspend your process (with C-c C-z).
+
+;; comint-mode-hook is the comint mode hook. Basically for your keybindings.
+
+;;; Code:
+
+(require 'ring)
+\f
+;; Buffer Local Variables:
+;;============================================================================
+;; Comint mode buffer local variables:
+;;     comint-prompt-regexp    - string       comint-bol uses to match prompt
+;;     comint-delimiter-argument-list - list  For delimiters and arguments
+;;     comint-last-input-start - marker       Handy if inferior always echoes
+;;     comint-last-input-end   - marker       For comint-kill-output command
+;;     comint-input-ring-size  - integer      For the input history
+;;     comint-input-ring       - ring             mechanism
+;;     comint-input-ring-index - number           ...
+;;     comint-input-autoexpand - symbol           ...
+;;     comint-input-ignoredups - boolean          ...
+;;     comint-last-input-match - string           ...
+;;     comint-dynamic-complete-functions - hook   For the completion mechanism
+;;     comint-completion-fignore - list           ...
+;;     comint-file-name-quote-list - list         ...
+;;     comint-get-old-input    - function     Hooks for specific 
+;;     comint-input-filter-functions - hook     process-in-a-buffer
+;;     comint-output-filter-functions - hook    function modes.
+;;     comint-input-filter     - function         ...
+;;     comint-input-sender     - function         ...
+;;     comint-eol-on-send      - boolean          ...
+;;     comint-process-echoes   - boolean          ...
+;;     comint-scroll-to-bottom-on-input - symbol For scroll behavior
+;;     comint-scroll-to-bottom-on-output - symbol ...
+;;     comint-scroll-show-maximum-output - boolean...
+;;
+;; Comint mode non-buffer local variables:
+;;     comint-completion-addsuffix - boolean/cons  For file name completion
+;;     comint-completion-autolist  - boolean      behavior
+;;     comint-completion-recexact  - boolean      ...
+
+(defvar comint-prompt-regexp "^"
+  "Regexp to recognise prompts in the inferior process.
+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 comint-delimiter-argument-list ()
+  "List of characters to recognise as separate arguments in input.
+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 `comint-arguments'.
+Defaults to the empty list.
+
+For shells, a good value is (?\\| ?& ?< ?> ?\\( ?\\) ?;).
+
+This is a good thing to set in mode hooks.")
+
+(defvar comint-input-autoexpand nil
+  "*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 `comint-magic-space' and
+`comint-dynamic-complete'.
+
+This variable is buffer-local.")
+
+(defvar comint-input-ignoredups nil
+  "*If non-nil, don't add input matching the last on the input ring.
+This mirrors the optional behavior of bash.
+
+This variable is buffer-local.")
+
+(defvar comint-input-ring-file-name nil
+  "*If non-nil, name of the file to read/write input history.
+See also `comint-read-input-ring' and `comint-write-input-ring'.
+
+This variable is buffer-local, and is a good thing to set in mode hooks.")
+
+(defvar comint-scroll-to-bottom-on-input nil
+  "*Controls whether input to interpreter 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.
+
+The default is nil.
+
+See `comint-preinput-scroll-to-bottom'.  This variable is buffer-local.")
+
+(defvar comint-scroll-to-bottom-on-output nil
+  "*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 `comint-scroll-show-maximum-output' and function
+`comint-postoutput-scroll-to-bottom'.  This variable is buffer-local.")
+
+(defvar comint-scroll-show-maximum-output nil
+  "*Controls how interpreter output causes window to scroll.
+If non-nil, then show the maximum output when the window is scrolled.
+
+See variable `comint-scroll-to-bottom-on-output' and function
+`comint-postoutput-scroll-to-bottom'.  This variable is buffer-local.")
+
+(defvar comint-buffer-maximum-size 1024
+  "*The maximum size in lines for comint buffers.
+Comint buffers are truncated from the top to be no greater than this number, if
+the function `comint-truncate-buffer' is on `comint-output-filter-functions'.")
+
+(defvar comint-input-ring-size 32
+  "Size of input history ring.")
+
+(defvar comint-process-echoes nil
+  "*If non-nil, assume that the subprocess echoes any input.
+If so, delete one copy of the input so that only one copy eventually
+appears in the buffer.
+
+This variable is buffer-local.")
+
+(defvar comint-password-prompt-regexp
+  "\\(\\([Oo]ld \\|[Nn]ew \\|^\\)[Pp]assword\\|pass phrase\\):\\s *\\'"
+  "*Regexp matching prompts for passwords in the inferior process.
+This is used by `comint-watch-for-password-prompt'.")
+
+;; Here are the per-interpreter hooks.
+(defvar comint-get-old-input (function comint-get-old-input-default)
+  "Function that returns old text in comint 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
+`comint-get-old-input-default', which grabs the current line, and strips off
+leading text matching `comint-prompt-regexp'.")
+
+(defvar comint-dynamic-complete-functions
+  '(comint-replace-by-expanded-history comint-dynamic-complete-filename)
+  "List of functions called to perform completion.
+Functions should return non-nil if completion was performed.
+See also `comint-dynamic-complete'.
+
+This is a good thing to set in mode hooks.")
+
+(defvar comint-input-filter
+  (function (lambda (str) (not (string-match "\\`\\s *\\'" str))))
+  "Predicate for filtering additions to input history.
+Takes one argument, the input.  If non-nil, the input may be saved on the input
+history list.  Default is to save anything that isn't all whitespace.")
+
+(defvar comint-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 comint-output-filter-functions '(comint-postoutput-scroll-to-bottom) 
+  "Functions to call after output is inserted into the buffer.
+One possible function is `comint-postoutput-scroll-to-bottom'.
+These functions get one argument, a string containing the text just inserted.
+
+This variable is buffer-local.")
+
+(defvar comint-input-sender (function comint-simple-send)
+  "Function to actually send to PROCESS the STRING submitted by user.
+Usually this is just `comint-simple-send', but if your mode needs to 
+massage the input string, put a different function here.
+`comint-simple-send' just sends the string plus a newline.
+This is called from the user command `comint-send-input'.")
+
+(defvar comint-eol-on-send t
+  "*Non-nil means go to the end of the line before sending input.
+See `comint-send-input'.")
+
+(defvar comint-mode-hook '()
+  "Called upon entry into comint-mode
+This is run before the process is cranked up.")
+
+(defvar comint-exec-hook '()
+  "Called each time a process is exec'd by `comint-exec'.
+This is called after the process is cranked up.  It is useful for things that
+must be done each time a process is executed in a comint mode buffer (e.g.,
+`(process-kill-without-query)').  In contrast, the `comint-mode-hook' is only
+executed once when the buffer is created.")
+
+(defvar comint-mode-map nil)
+
+(defvar comint-ptyp t
+  "Non-nil if communications via pty; false if by pipe.  Buffer local.
+This is to work around a bug in Emacs process signaling.")
+
+(defvar comint-input-ring nil)
+(defvar comint-last-input-start)
+(defvar comint-last-input-end)
+(defvar comint-last-output-start)
+(defvar comint-input-ring-index nil
+  "Index of last matched history element.")
+(defvar comint-matching-input-from-input-string ""
+  "Input previously used to match input history.")
+
+(put 'comint-replace-by-expanded-history 'menu-enable 'comint-input-autoexpand)
+(put 'comint-input-ring 'permanent-local t)
+(put 'comint-input-ring-index 'permanent-local t)
+(put 'comint-input-autoexpand 'permanent-local t)
+(put 'comint-input-filter-functions 'permanent-local t)
+(put 'comint-output-filter-functions 'permanent-local t)
+(put 'comint-scroll-to-bottom-on-input 'permanent-local t)
+(put 'comint-scroll-to-bottom-on-output 'permanent-local t)
+(put 'comint-scroll-show-maximum-output 'permanent-local t)
+(put 'comint-ptyp 'permanent-local t)
+
+(defun comint-mode ()
+  "Major mode for interacting with an inferior interpreter.
+Interpreter name is same as buffer name, sans the asterisks.
+Return at end of buffer sends line as input.
+Return not at end copies rest of line to end and sends it.
+Setting variable `comint-eol-on-send' means jump to the end of the line
+before submitting new input.
+
+This mode is customised to create major modes such as Inferior Lisp
+mode, Shell mode, etc.  This can be done by setting the hooks
+`comint-input-filter-functions', `comint-input-filter', `comint-input-sender'
+and `comint-get-old-input' to appropriate functions, and the variable
+`comint-prompt-regexp' to the appropriate regular expression.
+
+An input history is maintained of size `comint-input-ring-size', and
+can be accessed with the commands \\[comint-next-input], \\[comint-previous-input], and \\[comint-dynamic-list-input-ring].
+Input ring history expansion can be achieved with the commands
+\\[comint-replace-by-expanded-history] or \\[comint-magic-space].
+Input ring expansion is controlled by the variable `comint-input-autoexpand',
+and addition is controlled by the variable `comint-input-ignoredups'.
+
+Commands with no default key bindings include `send-invisible',
+`comint-dynamic-complete', `comint-dynamic-list-filename-completions', and 
+`comint-magic-space'.
+
+Input to, and output from, the subprocess can cause the window to scroll to
+the end of the buffer.  See variables `comint-output-filter-functions',
+`comint-scroll-to-bottom-on-input', and `comint-scroll-to-bottom-on-output'.
+
+If you accidentally suspend your process, use \\[comint-continue-subjob]
+to continue it.
+
+\\{comint-mode-map}
+
+Entry to this mode runs the hooks on `comint-mode-hook'."
+  (interactive)
+  ;; Do not remove this.  All major modes must do this.
+  (kill-all-local-variables)
+  (setq major-mode 'comint-mode)
+  (setq mode-name "Comint")
+  (setq mode-line-process '(":%s"))
+  (use-local-map comint-mode-map)
+  (make-local-variable 'comint-last-input-start)
+  (setq comint-last-input-start (make-marker))
+  (set-marker comint-last-input-start (point-min))
+  (make-local-variable 'comint-last-input-end)
+  (setq comint-last-input-end (make-marker))
+  (set-marker comint-last-input-end (point-min))
+  (make-local-variable 'comint-last-output-start)
+  (setq comint-last-output-start (make-marker))
+  (make-local-variable 'comint-prompt-regexp)        ; Don't set; default
+  (make-local-variable 'comint-input-ring-size)      ; ...to global val.
+  (make-local-variable 'comint-input-ring)
+  (make-local-variable 'comint-input-ring-file-name)
+  (or (and (boundp 'comint-input-ring) comint-input-ring)
+      (setq comint-input-ring (make-ring comint-input-ring-size)))
+  (make-local-variable 'comint-input-ring-index)
+  (or (and (boundp 'comint-input-ring-index) comint-input-ring-index)
+      (setq comint-input-ring-index nil))
+  (make-local-variable 'comint-matching-input-from-input-string)
+  (make-local-variable 'comint-input-autoexpand)
+  (make-local-variable 'comint-input-ignoredups)
+  (make-local-variable 'comint-delimiter-argument-list)
+  (make-local-hook 'comint-dynamic-complete-functions)
+  (make-local-variable 'comint-completion-fignore)
+  (make-local-variable 'comint-get-old-input)
+  (make-local-hook 'comint-input-filter-functions)
+  (make-local-variable 'comint-input-filter)
+  (make-local-variable 'comint-input-sender)
+  (make-local-variable 'comint-eol-on-send)
+  (make-local-variable 'comint-scroll-to-bottom-on-input)
+  (make-local-variable 'comint-scroll-to-bottom-on-output)
+  (make-local-variable 'comint-scroll-show-maximum-output)
+  (make-local-variable 'pre-command-hook)
+  (add-hook 'pre-command-hook 'comint-preinput-scroll-to-bottom)
+  (make-local-hook 'comint-output-filter-functions)
+  (make-local-variable 'comint-ptyp)
+  (make-local-variable 'comint-exec-hook)
+  (make-local-variable 'comint-process-echoes)
+  (make-local-variable 'comint-file-name-quote-list)
+  (run-hooks 'comint-mode-hook))
+
+(if comint-mode-map
+    nil
+  ;; Keys:
+  (setq comint-mode-map (make-sparse-keymap))
+  (define-key comint-mode-map "\ep" 'comint-previous-input)
+  (define-key comint-mode-map "\en" 'comint-next-input)
+  (define-key comint-mode-map [C-up] 'comint-previous-input)
+  (define-key comint-mode-map [C-down] 'comint-next-input)
+  (define-key comint-mode-map "\er" 'comint-previous-matching-input)
+  (define-key comint-mode-map "\es" 'comint-next-matching-input)
+  (define-key comint-mode-map [?\A-\M-r] 'comint-previous-matching-input-from-input)
+  (define-key comint-mode-map [?\A-\M-s] 'comint-next-matching-input-from-input)
+  (define-key comint-mode-map "\e\C-l" 'comint-show-output)
+  (define-key comint-mode-map "\C-m" 'comint-send-input)
+  (define-key comint-mode-map "\C-d" 'comint-delchar-or-maybe-eof)
+  (define-key comint-mode-map "\C-c\C-a" 'comint-bol)
+  (define-key comint-mode-map "\C-c\C-u" 'comint-kill-input)
+  (define-key comint-mode-map "\C-c\C-w" 'backward-kill-word)
+  (define-key comint-mode-map "\C-c\C-c" 'comint-interrupt-subjob)
+  (define-key comint-mode-map "\C-c\C-z" 'comint-stop-subjob)
+  (define-key comint-mode-map "\C-c\C-\\" 'comint-quit-subjob)
+  (define-key comint-mode-map "\C-c\C-m" 'comint-copy-old-input)
+  (define-key comint-mode-map "\C-c\C-o" 'comint-kill-output)
+  (define-key comint-mode-map "\C-c\C-r" 'comint-show-output)
+  (define-key comint-mode-map "\C-c\C-e" 'comint-show-maximum-output)
+  (define-key comint-mode-map "\C-c\C-l" 'comint-dynamic-list-input-ring)
+  (define-key comint-mode-map "\C-c\C-n" 'comint-next-prompt)
+  (define-key comint-mode-map "\C-c\C-p" 'comint-previous-prompt)
+  (define-key comint-mode-map "\C-c\C-d" 'comint-send-eof)
+  ;; Menu bars:
+  ;; completion:
+  (define-key comint-mode-map [menu-bar completion] 
+    (cons "Complete" (make-sparse-keymap "Complete")))
+  (define-key comint-mode-map [menu-bar completion complete-expand]
+    '("Expand File Name" . comint-replace-by-expanded-filename))
+  (define-key comint-mode-map [menu-bar completion complete-listing]
+    '("File Completion Listing" . comint-dynamic-list-filename-completions))
+  (define-key comint-mode-map [menu-bar completion complete-file]
+    '("Complete File Name" . comint-dynamic-complete-filename))
+  (define-key comint-mode-map [menu-bar completion complete]
+    '("Complete Before Point" . comint-dynamic-complete))
+  ;; Input history:
+  (define-key comint-mode-map [menu-bar inout] 
+    (cons "In/Out" (make-sparse-keymap "In/Out")))
+  (define-key comint-mode-map [menu-bar inout kill-output]
+    '("Kill Current Output Group" . comint-kill-output))
+  (define-key comint-mode-map [menu-bar inout next-prompt]
+    '("Forward Output Group" . comint-next-prompt))
+  (define-key comint-mode-map [menu-bar inout previous-prompt]
+    '("Backward Output Group" . comint-previous-prompt))
+  (define-key comint-mode-map [menu-bar inout show-maximum-output]
+    '("Show Maximum Output" . comint-show-maximum-output))
+  (define-key comint-mode-map [menu-bar inout show-output]
+    '("Show Current Output Group" . comint-show-output))
+  (define-key comint-mode-map [menu-bar inout kill-input]
+    '("Kill Current Input" . comint-kill-input))
+  (define-key comint-mode-map [menu-bar inout copy-input]
+    '("Copy Old Input" . comint-copy-old-input))
+  (define-key comint-mode-map [menu-bar inout forward-matching-history]
+    '("Forward Matching Input..." . comint-forward-matching-input))
+  (define-key comint-mode-map [menu-bar inout backward-matching-history]
+    '("Backward Matching Input..." . comint-backward-matching-input))
+  (define-key comint-mode-map [menu-bar inout next-matching-history]
+    '("Next Matching Input..." . comint-next-matching-input))
+  (define-key comint-mode-map [menu-bar inout previous-matching-history]
+    '("Previous Matching Input..." . comint-previous-matching-input))
+  (define-key comint-mode-map [menu-bar inout next-matching-history-from-input]
+    '("Next Matching Current Input" . comint-next-matching-input-from-input))
+  (define-key comint-mode-map [menu-bar inout previous-matching-history-from-input]
+    '("Previous Matching Current Input" . comint-previous-matching-input-from-input))
+  (define-key comint-mode-map [menu-bar inout next-history]
+    '("Next Input" . comint-next-input))
+  (define-key comint-mode-map [menu-bar inout previous-history]
+    '("Previous Input" . comint-previous-input))
+  (define-key comint-mode-map [menu-bar inout list-history]
+    '("List Input History" . comint-dynamic-list-input-ring))
+  (define-key comint-mode-map [menu-bar inout expand-history]
+    '("Expand History Before Point" . comint-replace-by-expanded-history))
+  ;; Signals
+  (define-key comint-mode-map [menu-bar signals]
+    (cons "Signals" (make-sparse-keymap "Signals")))
+  (define-key comint-mode-map [menu-bar signals eof]
+    '("EOF" . comint-send-eof))
+  (define-key comint-mode-map [menu-bar signals kill]
+    '("KILL" . comint-kill-subjob))
+  (define-key comint-mode-map [menu-bar signals quit]
+    '("QUIT" . comint-quit-subjob))
+  (define-key comint-mode-map [menu-bar signals cont]
+    '("CONT" . comint-continue-subjob))
+  (define-key comint-mode-map [menu-bar signals stop]
+    '("STOP" . comint-stop-subjob))
+  (define-key comint-mode-map [menu-bar signals break]
+    '("BREAK" . comint-interrupt-subjob))
+  ;; Put them in the menu bar:
+  (setq menu-bar-final-items (append '(completion inout signals)
+                                    menu-bar-final-items))
+  )
+
+(defun comint-check-proc (buffer)
+  "Return t if there is a living process associated w/buffer BUFFER.
+Living means the status is `open', `run', or `stop'.
+BUFFER can be either a buffer or the name of one."
+  (let ((proc (get-buffer-process buffer)))
+    (and proc (memq (process-status proc) '(open run stop)))))
+
+;; Note that this guy, unlike shell.el's make-shell, barfs if you pass it ()
+;; for the second argument (program).
+;;;###autoload
+(defun make-comint (name program &optional startfile &rest switches)
+  "Make a comint process NAME in a buffer, running PROGRAM.
+The name of the buffer is made by surrounding NAME with `*'s.
+PROGRAM should be either a string denoting an executable program to create
+via `start-process', or a cons pair of the form (HOST . SERVICE) denoting a TCP
+connection to be opened via `open-network-stream'.  If there is already a
+running process in that buffer, it is not restarted.  Optional third arg
+STARTFILE is the name of a file to send the contents of to the process.
+
+If PROGRAM is a string, any more args are arguments to PROGRAM."
+  (or (fboundp 'start-process)
+      (error "Multi-processing is not supported for this system"))
+  (let ((buffer (get-buffer-create (concat "*" name "*"))))
+    ;; If no process, or nuked process, crank up a new one and put buffer in
+    ;; comint mode.  Otherwise, leave buffer and existing process alone.
+    (cond ((not (comint-check-proc buffer))
+          (save-excursion
+            (set-buffer buffer)
+            (comint-mode)) ; Install local vars, mode, keymap, ...
+          (comint-exec buffer name program startfile switches)))
+    buffer))
+
+;;;###autoload
+(defun comint-run (program)
+  "Run PROGRAM in a comint buffer and switch to it.
+The buffer name is made by surrounding the file name of PROGRAM with `*'s.
+The file name is used to make a symbol name, such as `comint-sh-hook', and any
+hooks on this symbol are run in the buffer.
+See `make-comint' and `comint-exec'."
+  (interactive "sRun program: ")
+  (let ((name (file-name-nondirectory program)))
+    (switch-to-buffer (make-comint name program))
+    (run-hooks (intern-soft (concat "comint-" name "-hook")))))
+
+(defun comint-exec (buffer name command startfile switches)
+  "Start up a process in buffer BUFFER for comint modes.
+Blasts any old process running in the buffer.  Doesn't set the buffer mode.
+You can use this to cheaply run a series of processes in the same comint
+buffer.  The hook `comint-exec-hook' is run after each exec."
+  (save-excursion
+    (set-buffer buffer)
+    (let ((proc (get-buffer-process buffer)))  ; Blast any old process.
+      (if proc (delete-process proc)))
+    ;; Crank up a new process
+    (let ((proc
+          (if (consp command)
+              (open-network-stream name buffer (car command) (cdr command))
+            (comint-exec-1 name buffer command switches))))
+      (set-process-filter proc 'comint-output-filter)
+      (make-local-variable 'comint-ptyp)
+      (setq comint-ptyp process-connection-type) ; T if pty, NIL if pipe.
+      ;; Jump to the end, and set the process mark.
+      (goto-char (point-max))
+      (set-marker (process-mark proc) (point))
+      ;; Feed it the startfile.
+      (cond (startfile
+            ;;This is guaranteed to wait long enough
+            ;;but has bad results if the comint 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))
+            (comint-send-string proc startfile)))
+    (run-hooks 'comint-exec-hook)
+    buffer)))
+
+;; This auxiliary function cranks up the process for comint-exec in
+;; the appropriate environment.
+
+(defun comint-exec-1 (name buffer command switches)
+  (let ((process-environment
+        (nconc
+         ;; If using termcap, we specify `emacs' as the terminal type
+         ;; because that lets us specify a width.
+         ;; If using terminfo, we specify `unknown' because that is
+         ;; a defined terminal type.  `emacs' is not a defined terminal type
+         ;; and there is no way for us to define it here.
+         ;; Some programs that use terminfo get very confused
+         ;; if TERM is not a valid terminal type.
+         (if (and (boundp 'system-uses-terminfo) system-uses-terminfo)
+             (list "TERM=unknown"
+                   (format "COLUMNS=%d" (frame-width)))
+           (list "TERM=emacs"
+                 (format "TERMCAP=emacs:co#%d:tc=unknown:" (frame-width))))
+         (if (getenv "EMACS") nil (list "EMACS=t"))
+         process-environment))
+       (default-directory
+         (if (file-directory-p default-directory)
+             default-directory
+           "/")))
+    (apply 'start-process name buffer command switches)))
+\f
+;; Input history processing in a buffer
+;; ===========================================================================
+;; Useful input history functions, courtesy of the Ergo group.
+
+;; Eleven commands:
+;; comint-dynamic-list-input-ring      List history in help buffer.
+;; comint-previous-input               Previous input...
+;; comint-previous-matching-input      ...matching a string.
+;; comint-previous-matching-input-from-input ... matching the current input.
+;; comint-next-input                   Next input...
+;; comint-next-matching-input          ...matching a string.
+;; comint-next-matching-input-from-input     ... matching the current input.
+;; comint-backward-matching-input      Backwards input...
+;; comint-forward-matching-input       ...matching a string.
+;; comint-replace-by-expanded-history  Expand history at point;
+;;                                     replace with expanded history.
+;; comint-magic-space                  Expand history and insert space.
+;;
+;; Three functions:
+;; comint-read-input-ring              Read into comint-input-ring...
+;; comint-write-input-ring             Write to comint-input-ring-file-name.
+;; comint-replace-by-expanded-history-before-point Workhorse function.
+
+(defun comint-read-input-ring (&optional silent)
+  "Sets the buffer's `comint-input-ring' from a history file.
+The name of the file is given by the variable `comint-input-ring-file-name'.
+The history ring is of size `comint-input-ring-size', regardless of file size.
+If `comint-input-ring-file-name' is nil this function does nothing.
+
+If the optional argument SILENT is non-nil, we say nothing about a
+failure to read the history file.
+
+This function is useful for major mode commands and mode hooks.
+
+The structure of the history file should be one input command per line,
+with the most recent command last.
+See also `comint-input-ignoredups' and `comint-write-input-ring'."
+  (cond ((or (null comint-input-ring-file-name)
+            (equal comint-input-ring-file-name ""))
+        nil)
+       ((not (file-readable-p comint-input-ring-file-name))
+        (or silent
+            (message "Cannot read history file %s"
+                     comint-input-ring-file-name)))
+       (t
+        (let ((history-buf (get-buffer-create " *temp*"))
+              (file comint-input-ring-file-name)
+              (count 0)
+              (ring (make-ring comint-input-ring-size)))
+          (unwind-protect
+              (save-excursion
+                (set-buffer history-buf)
+                (widen)
+                (erase-buffer)
+                (insert-file-contents file)
+                ;; Save restriction in case file is already visited...
+                ;; Watch for those date stamps in history files!
+                (goto-char (point-max))
+                (while (and (< count comint-input-ring-size)
+                            (re-search-backward "^[ \t]*\\([^#\n].*\\)[ \t]*$"
+                                                nil t))
+                  (let ((history (buffer-substring (match-beginning 1)
+                                                   (match-end 1))))
+                    (if (or (null comint-input-ignoredups)
+                            (ring-empty-p ring)
+                            (not (string-equal (ring-ref ring 0) history)))
+                        (ring-insert-at-beginning ring history)))
+                  (setq count (1+ count))))
+            (kill-buffer history-buf))
+          (setq comint-input-ring ring
+                comint-input-ring-index nil)))))
+
+(defun comint-write-input-ring ()
+  "Writes the buffer's `comint-input-ring' to a history file.
+The name of the file is given by the variable `comint-input-ring-file-name'.
+The original contents of the file are lost if `comint-input-ring' is not empty.
+If `comint-input-ring-file-name' is nil this function does nothing.
+
+Useful within process sentinels.
+
+See also `comint-read-input-ring'."
+  (cond ((or (null comint-input-ring-file-name)
+            (equal comint-input-ring-file-name "")
+            (null comint-input-ring) (ring-empty-p comint-input-ring))
+        nil)
+       ((not (file-writable-p comint-input-ring-file-name))
+        (message "Cannot write history file %s" comint-input-ring-file-name))
+       (t
+        (let* ((history-buf (get-buffer-create " *Temp Input History*"))
+               (ring comint-input-ring)
+               (file comint-input-ring-file-name)
+               (index (ring-length ring)))
+          ;; Write it all out into a buffer first.  Much faster, but messier,
+          ;; than writing it one line at a time.
+          (save-excursion
+            (set-buffer history-buf)
+            (erase-buffer)
+            (while (> index 0)
+              (setq index (1- index))
+              (insert (ring-ref ring index) ?\n))
+            (write-region (buffer-string) nil file nil 'no-message)
+            (kill-buffer nil))))))
+
+
+(defun comint-dynamic-list-input-ring ()
+  "List in help buffer the buffer's input history."
+  (interactive)
+  (if (or (not (ring-p comint-input-ring))
+         (ring-empty-p comint-input-ring))
+      (message "No history")
+    (let ((history nil)
+         (history-buffer " *Input History*")
+         (index (1- (ring-length comint-input-ring)))
+         (conf (current-window-configuration)))
+      ;; We have to build up a list ourselves from the ring vector.
+      (while (>= index 0)
+       (setq history (cons (ring-ref comint-input-ring index) history)
+             index (1- index)))
+      ;; Change "completion" to "history reference"
+      ;; to make the display accurate.
+      (with-output-to-temp-buffer history-buffer
+       (display-completion-list history)
+       (set-buffer history-buffer)
+       (forward-line 3)
+       (while (search-backward "completion" nil 'move)
+         (replace-match "history reference")))
+      (sit-for 0)
+      (message "Hit space to flush")
+      (let ((ch (read-event)))
+       (if (eq ch ?\ )
+           (set-window-configuration conf)
+         (setq unread-command-events (list ch)))))))
+
+
+(defun comint-regexp-arg (prompt)
+  ;; Return list of regexp and prefix arg using PROMPT.
+  (let* ((minibuffer-history-sexp-flag nil)
+        ;; Don't clobber this.
+        (last-command last-command)
+        (regexp (read-from-minibuffer prompt nil nil nil
+                                      'minibuffer-history-search-history)))
+    (list (if (string-equal regexp "")
+             (setcar minibuffer-history-search-history
+                     (nth 1 minibuffer-history-search-history))
+           regexp)
+         (prefix-numeric-value current-prefix-arg))))
+
+(defun comint-search-arg (arg)
+  ;; First make sure there is a ring and that we are after the process mark
+  (cond ((not (comint-after-pmark-p))
+        (error "Not at command line"))
+       ((or (null comint-input-ring)
+            (ring-empty-p comint-input-ring))
+        (error "Empty input ring"))
+       ((zerop arg)
+        ;; arg of zero resets search from beginning, and uses arg of 1
+        (setq comint-input-ring-index nil)
+        1)
+       (t
+        arg)))
+
+(defun comint-search-start (arg)
+  ;; Index to start a directional search, starting at comint-input-ring-index
+  (if comint-input-ring-index
+      ;; If a search is running, offset by 1 in direction of arg
+      (mod (+ comint-input-ring-index (if (> arg 0) 1 -1))
+          (ring-length comint-input-ring))
+    ;; For a new search, start from beginning or end, as appropriate
+    (if (>= arg 0)
+       0                                      ; First elt for forward search
+      (1- (ring-length comint-input-ring)))))  ; Last elt for backward search
+
+(defun comint-previous-input-string (arg)
+  "Return the string ARG places along the input ring.
+Moves relative to `comint-input-ring-index'."
+  (ring-ref comint-input-ring (if comint-input-ring-index
+                                 (mod (+ arg comint-input-ring-index) 
+                                      (ring-length comint-input-ring))
+                               arg)))
+
+(defun comint-previous-input (arg)
+  "Cycle backwards through input history."
+  (interactive "*p")
+  (comint-previous-matching-input "." arg))
+
+(defun comint-next-input (arg)
+  "Cycle forwards through input history."
+  (interactive "*p")
+  (comint-previous-input (- arg)))
+
+(defun comint-previous-matching-input-string (regexp arg)
+  "Return the string matching REGEXP ARG places along the input ring.
+Moves relative to `comint-input-ring-index'."
+  (let* ((pos (comint-previous-matching-input-string-position regexp arg)))
+    (if pos (ring-ref comint-input-ring pos))))
+
+(defun comint-previous-matching-input-string-position (regexp arg &optional start)
+  "Return the index matching REGEXP ARG places along the input ring.
+Moves relative to START, or `comint-input-ring-index'."
+  (if (or (not (ring-p comint-input-ring))
+         (ring-empty-p comint-input-ring))
+      (error "No history"))
+  (let* ((len (ring-length comint-input-ring))
+        (motion (if (> arg 0) 1 -1))
+        (n (mod (- (or start (comint-search-start arg)) motion) len))
+        (tried-each-ring-item nil)
+        (prev nil))
+    ;; Do the whole search as many times as the argument says.
+    (while (and (/= arg 0) (not tried-each-ring-item))
+      ;; Step once.
+      (setq prev n
+           n (mod (+ n motion) len))
+      ;; If we haven't reached a match, step some more.
+      (while (and (< n len) (not tried-each-ring-item)
+                 (not (string-match regexp (ring-ref comint-input-ring n))))
+       (setq n (mod (+ n motion) len)
+             ;; If we have gone all the way around in this search.
+             tried-each-ring-item (= n prev)))
+      (setq arg (if (> arg 0) (1- arg) (1+ arg))))
+    ;; Now that we know which ring element to use, if we found it, return that.
+    (if (string-match regexp (ring-ref comint-input-ring n))
+       n)))
+
+(defun comint-previous-matching-input (regexp arg)
+  "Search backwards through input history for match for REGEXP.
+\(Previous history elements are earlier commands.)
+With prefix argument N, search for Nth previous match.
+If N is negative, find the next or Nth next match."
+  (interactive (comint-regexp-arg "Previous input matching (regexp): "))
+  (setq arg (comint-search-arg arg))
+  (let ((pos (comint-previous-matching-input-string-position regexp arg)))
+    ;; Has a match been found?
+    (if (null pos)
+       (error "Not found")
+      (setq comint-input-ring-index pos)
+      (message "History item: %d" (1+ pos))
+      (delete-region 
+       ;; Can't use kill-region as it sets this-command
+       (process-mark (get-buffer-process (current-buffer))) (point))
+      (insert (ring-ref comint-input-ring pos)))))
+
+(defun comint-next-matching-input (regexp arg)
+  "Search forwards through input history for match for REGEXP.
+\(Later history elements are more recent commands.)
+With prefix argument N, search for Nth following match.
+If N is negative, find the previous or Nth previous match."
+  (interactive (comint-regexp-arg "Next input matching (regexp): "))
+  (comint-previous-matching-input regexp (- arg)))
+
+(defun comint-previous-matching-input-from-input (arg)
+  "Search backwards through input history for match for current input.
+\(Previous history elements are earlier commands.)
+With prefix argument N, search for Nth previous match.
+If N is negative, search forwards for the -Nth following match."
+  (interactive "p")
+  (if (not (memq last-command '(comint-previous-matching-input-from-input
+                               comint-next-matching-input-from-input)))
+      ;; Starting a new search
+      (setq comint-matching-input-from-input-string
+           (buffer-substring 
+            (process-mark (get-buffer-process (current-buffer))) 
+            (point))
+           comint-input-ring-index nil))
+  (comint-previous-matching-input
+   (concat "^" (regexp-quote comint-matching-input-from-input-string))
+   arg))
+
+(defun comint-next-matching-input-from-input (arg)
+  "Search forwards through input history for match for current input.
+\(Following history elements are more recent commands.)
+With prefix argument N, search for Nth following match.
+If N is negative, search backwards for the -Nth previous match."
+  (interactive "p")
+  (comint-previous-matching-input-from-input (- arg)))
+
+
+(defun comint-replace-by-expanded-history (&optional silent)
+  "Expand input command history references before point.
+Expansion is dependent on the value of `comint-input-autoexpand'.
+
+This function depends on the buffer's idea of the input history, which may not
+match the command interpreter's idea, assuming it has one.
+
+Assumes history syntax is like typical Un*x shells'.  However, since emacs
+cannot know the interpreter's idea of input line numbers, assuming it has one,
+it cannot expand absolute input line number references.
+
+If the optional argument SILENT is non-nil, never complain
+even if history reference seems erroneous.
+
+See `comint-magic-space' and `comint-replace-by-expanded-history-before-point'.
+
+Returns t if successful."
+  (interactive)
+  (if (and comint-input-autoexpand
+          (string-match "[!^]" (funcall comint-get-old-input))
+          (save-excursion (beginning-of-line)
+                          (looking-at comint-prompt-regexp)))
+      ;; Looks like there might be history references in the command.
+      (let ((previous-modified-tick (buffer-modified-tick)))
+       (message "Expanding history references...")
+       (comint-replace-by-expanded-history-before-point silent)
+       (/= previous-modified-tick (buffer-modified-tick)))))
+
+
+(defun comint-replace-by-expanded-history-before-point (silent)
+  "Expand directory stack reference before point.
+See `comint-replace-by-expanded-history'.  Returns t if successful."
+  (save-excursion
+    (let ((toend (- (save-excursion (end-of-line nil) (point)) (point)))
+         (start (progn (comint-bol nil) (point))))
+      (while (progn
+              (skip-chars-forward "^!^"
+                                  (save-excursion
+                                    (end-of-line nil) (- (point) toend)))
+              (< (point)
+                 (save-excursion
+                   (end-of-line nil) (- (point) toend))))
+       ;; This seems a bit complex.  We look for references such as !!, !-num,
+       ;; !foo, !?foo, !{bar}, !?{bar}, ^oh, ^my^, ^god^it, ^never^ends^.
+       ;; If that wasn't enough, the plings can be suffixed with argument
+       ;; range specifiers.
+       ;; Argument ranges are complex too, so we hive off the input line,
+       ;; referenced with plings, with the range string to `comint-args'.
+       (setq comint-input-ring-index nil)
+       (cond ((or (= (preceding-char) ?\\)
+                  (comint-within-quotes start (point)))
+              ;; The history is quoted, or we're in quotes.
+              (goto-char (1+ (point))))
+             ((looking-at "![0-9]+\\($\\|[^-]\\)")
+              ;; We cannot know the interpreter's idea of input line numbers.
+              (goto-char (match-end 0))
+              (message "Absolute reference cannot be expanded"))
+             ((looking-at "!-\\([0-9]+\\)\\(:?[0-9^$*-]+\\)?")
+              ;; Just a number of args from `number' lines backward.
+              (let ((number (1- (string-to-number
+                                 (buffer-substring (match-beginning 1)
+                                                   (match-end 1))))))
+                (if (<= number (ring-length comint-input-ring))
+                    (progn
+                      (replace-match
+                       (comint-args (comint-previous-input-string number)
+                                    (match-beginning 2) (match-end 2))
+                       t t)
+                      (setq comint-input-ring-index number)
+                      (message "History item: %d" (1+ number)))
+                  (goto-char (match-end 0))
+                  (message "Relative reference exceeds input history size"))))
+             ((or (looking-at "!!?:?\\([0-9^$*-]+\\)") (looking-at "!!"))
+              ;; Just a number of args from the previous input line.
+              (replace-match
+               (comint-args (comint-previous-input-string 0)
+                            (match-beginning 1) (match-end 1))
+               t t)
+              (message "History item: previous"))
+             ((looking-at
+               "!\\??\\({\\(.+\\)}\\|\\(\\sw+\\)\\)\\(:?[0-9^$*-]+\\)?")
+              ;; Most recent input starting with or containing (possibly
+              ;; protected) string, maybe just a number of args.  Phew.
+              (let* ((mb1 (match-beginning 1)) (me1 (match-end 1))
+                     (mb2 (match-beginning 2)) (me2 (match-end 2))
+                     (exp (buffer-substring (or mb2 mb1) (or me2 me1)))
+                     (pref (if (save-match-data (looking-at "!\\?")) "" "^"))
+                     (pos (save-match-data
+                            (comint-previous-matching-input-string-position
+                             (concat pref (regexp-quote exp)) 1))))
+                (if (null pos)
+                    (progn
+                      (goto-char (match-end 0))
+                      (or silent
+                          (progn (message "Not found")
+                                 (ding))))
+                  (setq comint-input-ring-index pos)
+                  (replace-match
+                   (comint-args (ring-ref comint-input-ring pos)
+                                (match-beginning 4) (match-end 4))
+                   t t)
+                  (message "History item: %d" (1+ pos)))))
+             ((looking-at "\\^\\([^^]+\\)\\^?\\([^^]*\\)\\^?")
+              ;; Quick substitution on the previous input line.
+              (let ((old (buffer-substring (match-beginning 1) (match-end 1)))
+                    (new (buffer-substring (match-beginning 2) (match-end 2)))
+                    (pos nil))
+                (replace-match (comint-previous-input-string 0) t t)
+                (setq pos (point))
+                (goto-char (match-beginning 0))
+                (if (not (search-forward old pos t))
+                    (or silent
+                        (error "Not found"))
+                  (replace-match new t t)
+                  (message "History item: substituted"))))
+             (t
+              (goto-char (match-end 0))))))))
+
+
+(defun comint-magic-space (arg)
+  "Expand input history references before point and insert ARG spaces.
+A useful command to bind to SPC.  See `comint-replace-by-expanded-history'."
+  (interactive "p")
+  (comint-replace-by-expanded-history)
+  (self-insert-command arg))
+\f
+(defun comint-within-quotes (beg end)
+  "Return t if the number of quotes between BEG and END is odd.
+Quotes are single and double."
+  (let ((countsq (comint-how-many-region "\\(^\\|[^\\\\]\\)\'" beg end))
+       (countdq (comint-how-many-region "\\(^\\|[^\\\\]\\)\"" beg end)))
+    (or (= (mod countsq 2) 1) (= (mod countdq 2) 1))))
+
+(defun comint-how-many-region (regexp beg end)
+  "Return number of matches for REGEXP from BEG to END."
+  (let ((count 0))
+    (save-excursion
+      (save-match-data
+       (goto-char beg)
+       (while (re-search-forward regexp end t)
+         (setq count (1+ count)))))
+    count))
+
+(defun comint-args (string begin end)
+  ;; From STRING, return the args depending on the range specified in the text
+  ;; from BEGIN to END.  If BEGIN is nil, assume all args.  Ignore leading `:'.
+  ;; Range can be x-y, x-, -y, where x/y can be [0-9], *, ^, $.
+  (save-match-data
+    (if (null begin)
+       (comint-arguments string 0 nil)
+      (let* ((range (buffer-substring
+                    (if (eq (char-after begin) ?:) (1+ begin) begin) end))
+            (nth (cond ((string-match "^[*^]" range) 1)
+                       ((string-match "^-" range) 0)
+                       ((string-equal range "$") nil)
+                       (t (string-to-number range))))
+            (mth (cond ((string-match "[-*$]$" range) nil)
+                       ((string-match "-" range)
+                        (string-to-number (substring range (match-end 0))))
+                       (t nth))))
+       (comint-arguments string nth mth)))))
+
+;; Return a list of arguments from ARG.  Break it up at the
+;; delimiters in comint-delimiter-argument-list.  Returned list is backwards.
+(defun comint-delim-arg (arg)
+  (if (null comint-delimiter-argument-list)
+      (list arg)
+    (let ((args nil)
+         (pos 0)
+         (len (length arg)))
+      (while (< pos len)
+       (let ((char (aref arg pos))
+             (start pos))
+         (if (memq char comint-delimiter-argument-list)
+             (while (and (< pos len) (eq (aref arg pos) char))
+               (setq pos (1+ pos)))
+           (while (and (< pos len)
+                       (not (memq (aref arg pos)
+                                  comint-delimiter-argument-list)))
+             (setq pos (1+ pos))))
+         (setq args (cons (substring arg start pos) args))))
+      args)))
+
+(defun comint-arguments (string nth mth)
+  "Return from STRING the NTH to MTH arguments.
+NTH and/or MTH can be nil, which means the last argument.
+Returned arguments are separated by single spaces.
+We assume whitespace separates arguments, except within quotes.
+Also, a run of one or more of a single character
+in `comint-delimiter-argument-list' is a separate argument.
+Argument 0 is the command name."
+  (let ((argpart "[^ \n\t\"'`]+\\|\\(\"[^\"]*\"\\|'[^']*'\\|`[^`]*`\\)")
+       (args ()) (pos 0)
+       (count 0)
+       beg str value quotes)
+    ;; Build a list of all the args until we have as many as we want.
+    (while (and (or (null mth) (<= count mth))
+               (string-match argpart string pos))
+      (if (and beg (= pos (match-beginning 0)))
+         ;; It's contiguous, part of the same arg.
+         (setq pos (match-end 0)
+               quotes (or quotes (match-beginning 1)))
+       ;; It's a new separate arg.
+       (if beg
+           ;; Put the previous arg, if there was one, onto ARGS.
+           (setq str (substring string beg pos)
+                 args (if quotes (cons str args)
+                        (nconc (comint-delim-arg str) args))
+                 count (1+ count)))
+       (setq quotes (match-beginning 1))
+       (setq beg (match-beginning 0))
+       (setq pos (match-end 0))))
+    (if beg
+       (setq str (substring string beg pos)
+             args (if quotes (cons str args)
+                    (nconc (comint-delim-arg str) args))
+             count (1+ count)))
+    (let ((n (or nth (1- count)))
+         (m (if mth (1- (- count mth)) 0)))
+      (mapconcat
+       (function (lambda (a) a)) (nthcdr n (nreverse (nthcdr m args))) " "))))
+\f
+;;
+;; Input processing stuff
+;;
+
+(defun comint-send-input () 
+  "Send input to process.
+After the process output mark, sends all text from the process mark to
+point as input to the process.  Before the process output mark, calls value
+of variable `comint-get-old-input' to retrieve old input, copies it to the
+process mark, and sends it.  If variable `comint-process-echoes' is nil,
+a terminal newline is also inserted into the buffer and sent to the process
+\(if it is non-nil, all text from the process mark to point is deleted,
+since it is assumed the remote process will re-echo it).
+
+Any history reference may be expanded depending on the value of the variable
+`comint-input-autoexpand'.  The list of function names contained in the value
+of `comint-input-filter-functions' is called on the input before sending it.
+The input is entered into the input history ring, if the value of variable
+`comint-input-filter' returns non-nil when called on the input.
+
+If variable `comint-eol-on-send' is non-nil, then point is moved to the
+end of line before sending the input.
+
+The values of `comint-get-old-input', `comint-input-filter-functions', and
+`comint-input-filter' are chosen according to the command interpreter running
+in the buffer.  E.g.,
+
+If the interpreter is the csh,
+    comint-get-old-input is the default: take the current line, discard any
+        initial string matching regexp comint-prompt-regexp.
+    comint-input-filter-functions monitors input for \"cd\", \"pushd\", and
+        \"popd\" commands. When it sees one, it cd's the buffer.
+    comint-input-filter is the default: returns t if the input isn't all white
+       space.
+
+If the comint is Lucid Common Lisp, 
+    comint-get-old-input snarfs the sexp ending at point.
+    comint-input-filter-functions does nothing.
+    comint-input-filter returns nil if the input matches input-filter-regexp,
+        which matches (1) all whitespace (2) :a, :c, etc.
+
+Similarly for Soar, Scheme, etc."
+  (interactive)
+  ;; Note that the input string does not include its terminal newline.
+  (let ((proc (get-buffer-process (current-buffer))))
+    (if (not proc) (error "Current buffer has no process")
+       (let* ((pmark (process-mark proc))
+              (intxt (if (>= (point) (marker-position pmark))
+                         (progn (if comint-eol-on-send (end-of-line))
+                                (buffer-substring pmark (point)))
+                       (let ((copy (funcall comint-get-old-input)))
+                         (goto-char pmark)
+                         (insert copy)
+                         copy)))
+              (input (if (not (eq comint-input-autoexpand 'input))
+                         ;; Just whatever's already there
+                         intxt
+                       ;; Expand and leave it visible in buffer
+                       (comint-replace-by-expanded-history t)
+                       (buffer-substring pmark (point))))
+              (history (if (not (eq comint-input-autoexpand 'history))
+                           input
+                         ;; This is messy 'cos ultimately the original
+                         ;; functions used do insertion, rather than return
+                         ;; strings.  We have to expand, then insert back.
+                         (comint-replace-by-expanded-history t)
+                         (let ((copy (buffer-substring pmark (point))))
+                           (delete-region pmark (point))
+                           (insert input)
+                           copy))))
+          (if comint-process-echoes
+              (delete-region pmark (point))
+           (insert ?\n))
+         (if (and (funcall comint-input-filter history)
+                  (or (null comint-input-ignoredups)
+                      (not (ring-p comint-input-ring))
+                      (ring-empty-p comint-input-ring)
+                      (not (string-equal (ring-ref comint-input-ring 0)
+                                         history))))
+             (ring-insert comint-input-ring history))
+         (run-hook-with-args 'comint-input-filter-functions
+                             (concat input "\n"))
+         (setq comint-input-ring-index nil)
+         ;; Update the markers before we send the input
+         ;; in case we get output amidst sending the input.
+         (set-marker comint-last-input-start pmark)
+         (set-marker comint-last-input-end (point))
+         (set-marker (process-mark proc) (point))
+         (funcall comint-input-sender proc input)
+         (comint-output-filter proc "")))))
+
+;; The purpose of using this filter for comint processes
+;; is to keep comint-last-input-end from moving forward
+;; when output is inserted.
+(defun comint-output-filter (process string)
+  ;; First check for killed buffer
+  (let ((oprocbuf (process-buffer process)))
+    (if (and oprocbuf (buffer-name oprocbuf))
+       (let ((obuf (current-buffer))
+             (opoint nil) (obeg nil) (oend nil))
+         (set-buffer oprocbuf)
+         (setq opoint (point))
+         (setq obeg (point-min))
+         (setq oend (point-max))
+         (let ((buffer-read-only nil)
+               (nchars (length string))
+               (ostart nil))
+           (widen)
+           (goto-char (process-mark process))
+           (setq ostart (point))
+           (if (<= (point) opoint)
+               (setq opoint (+ opoint nchars)))
+           ;; Insert after old_begv, but before old_zv.
+           (if (< (point) obeg)
+               (setq obeg (+ obeg nchars)))
+           (if (<= (point) oend)
+               (setq oend (+ oend nchars)))
+           (insert-before-markers string)
+           ;; Don't insert initial prompt outside the top of the window.
+           (if (= (window-start (selected-window)) (point))
+               (set-window-start (selected-window) (- (point) (length string))))
+           (if (and comint-last-input-end
+                    (marker-buffer comint-last-input-end)
+                    (= (point) comint-last-input-end))
+               (set-marker comint-last-input-end (- comint-last-input-end nchars)))
+           (set-marker comint-last-output-start ostart)
+           (set-marker (process-mark process) (point))
+           (force-mode-line-update))
+
+         (narrow-to-region obeg oend)
+         (goto-char opoint)
+         (run-hook-with-args 'comint-output-filter-functions string)
+         (set-buffer obuf)))))
+
+(defun comint-preinput-scroll-to-bottom ()
+  "Go to the end of buffer in all windows showing it.
+Movement occurs if point in the selected window is not after the process mark,
+and `this-command' is an insertion command.  Insertion commands recognised
+are `self-insert-command', `comint-magic-space', `yank', and `hilit-yank'.
+Depends on the value of `comint-scroll-to-bottom-on-input'.
+
+This function should be a pre-command hook."
+  (if (and comint-scroll-to-bottom-on-input
+          (memq this-command '(self-insert-command comint-magic-space yank
+                               hilit-yank)))
+      (let* ((selected (selected-window))
+            (current (current-buffer))
+            (process (get-buffer-process current))
+            (scroll comint-scroll-to-bottom-on-input))
+       (if (and process (< (point) (process-mark process)))
+           (if (eq scroll 'this)
+               (goto-char (point-max))
+             (walk-windows
+              (function (lambda (window)
+                (if (and (eq (window-buffer window) current)
+                         (or (eq scroll t) (eq scroll 'all)))
+                    (progn
+                      (select-window window)
+                      (goto-char (point-max))
+                      (select-window selected)))))
+              nil t))))))
+
+(defun comint-postoutput-scroll-to-bottom (string)
+  "Go to the end of buffer in all windows showing it.
+Does not scroll if the current line is the last line in the buffer.
+Depends on the value of `comint-scroll-to-bottom-on-output' and
+`comint-scroll-show-maximum-output'.
+
+This function should be in the list `comint-output-filter-functions'."
+  (let* ((selected (selected-window))
+        (current (current-buffer))
+        (process (get-buffer-process current))
+        (scroll comint-scroll-to-bottom-on-output))
+    (unwind-protect
+       (if process
+           (walk-windows
+            (function (lambda (window)
+              (if (eq (window-buffer window) current)
+                  (progn
+                    (select-window window)
+                    (if (and (< (point) (process-mark process))
+                             (or (eq scroll t) (eq scroll 'all)
+                                 ;; Maybe user wants point to jump to the end.
+                                 (and (eq scroll 'this) (eq selected window))
+                                 (and (eq scroll 'others) (not (eq selected window)))
+                                 ;; If point was at the end, keep it at the end.
+                                 (>= (point)
+                                     (- (process-mark process) (length string)))))
+                        (goto-char (process-mark process)))
+                    ;; Optionally scroll so that the text
+                    ;; ends at the bottom of the window.
+                    (if (and comint-scroll-show-maximum-output
+                             (>= (point) (process-mark process)))
+                        (save-excursion
+                          (goto-char (point-max))
+                          (recenter -1)))
+                    (select-window selected)))))
+            nil t))
+      (set-buffer current))))
+
+(defun comint-truncate-buffer (&optional string)
+  "Truncate the buffer to `comint-buffer-maximum-size'.
+This function could be on `comint-output-filter-functions' or bound to a key."
+  (interactive)
+  (save-excursion
+    (goto-char (point-max))
+    (forward-line (- comint-buffer-maximum-size))
+    (beginning-of-line)
+    (delete-region (point-min) (point))))
+
+(defun comint-strip-ctrl-m (&optional string)
+  "Strip trailing `^M' characters from the current output group.
+This function could be on `comint-output-filter-functions' or bound to a key."
+  (interactive)
+  (let ((pmark (process-mark (get-buffer-process (current-buffer)))))
+    (save-excursion
+      (goto-char
+       (if (interactive-p) comint-last-input-end comint-last-output-start))
+      (while (re-search-forward "\r+$" pmark t)
+       (replace-match "" t t)))))
+(defalias 'shell-strip-ctrl-m 'comint-strip-ctrl-m)
+
+(defun comint-show-maximum-output ()
+  "Put the end of the buffer at the bottom of the window."
+  (interactive)
+  (goto-char (point-max))
+  (recenter -1))
+
+(defun comint-get-old-input-default ()
+  "Default for `comint-get-old-input'.
+Take the current line, and discard any initial text matching
+`comint-prompt-regexp'."
+  (save-excursion
+    (beginning-of-line)
+    (comint-skip-prompt)
+    (let ((beg (point)))
+      (end-of-line)
+      (buffer-substring beg (point)))))
+
+(defun comint-copy-old-input ()
+  "Insert after prompt old input at point as new input to be edited.
+Calls `comint-get-old-input' to get old input."
+  (interactive)
+  (let ((input (funcall comint-get-old-input))
+       (process (get-buffer-process (current-buffer))))
+    (if (not process)
+       (error "Current buffer has no process")
+      (goto-char (process-mark process))
+      (insert input))))
+
+(defun comint-skip-prompt ()
+  "Skip past the text matching regexp `comint-prompt-regexp'.
+If this takes us past the end of the current line, don't skip at all."
+  (let ((eol (save-excursion (end-of-line) (point))))
+    (if (and (looking-at comint-prompt-regexp)
+            (<= (match-end 0) eol))
+       (goto-char (match-end 0)))))
+
+(defun comint-after-pmark-p ()
+  "Return t if point is after the process output marker."
+  (let ((pmark (process-mark (get-buffer-process (current-buffer)))))
+    (<= (marker-position pmark) (point))))
+
+(defun comint-simple-send (proc string)
+  "Default function for sending to PROC input STRING.
+This just sends STRING plus a newline. To override this,
+set the hook `comint-input-sender'."
+  (comint-send-string proc string)
+  (comint-send-string proc "\n"))
+
+(defun comint-bol (arg)
+  "Goes to the beginning of line, then skips past the prompt, if any.
+If prefix argument is given (\\[universal-argument]) the prompt is not skipped. 
+
+The prompt skip is done by skipping text matching the regular expression
+`comint-prompt-regexp', a buffer local variable."
+  (interactive "P")
+  (beginning-of-line)
+  (if (null arg) (comint-skip-prompt)))
+
+;; These three functions are for entering text you don't want echoed or
+;; saved -- typically passwords to ftp, telnet, or somesuch.
+;; Just enter m-x send-invisible and type in your line, or add
+;; `comint-watch-for-password-prompt' to `comint-output-filter-functions'.
+
+(defun comint-read-noecho (prompt &optional stars)
+  "Read a single line of text from user without echoing, and return it. 
+Prompt with argument PROMPT, a string.  Optional argument STARS causes
+input to be echoed with '*' characters on the prompt line.  Input ends with
+RET, LFD, or ESC.  DEL or C-h rubs out.  C-u kills line.  C-g aborts (if
+`inhibit-quit' is set because e.g. this function was called from a process
+filter and C-g is pressed, this function returns nil rather than a string).
+
+Note that the keystrokes comprising the text can still be recovered
+\(temporarily) with \\[view-lossage].  This may be a security bug for some
+applications."
+  (let ((ans "")
+       (c 0)
+       (echo-keystrokes 0)
+       (cursor-in-echo-area t)
+       (message-log-max nil)
+       (done nil))
+    (while (not done)
+      (if stars
+         (message "%s%s" prompt (make-string (length ans) ?*))
+       (message "%s" prompt))
+      ;; Use this instead of `read-char' to avoid "Non-character input-event".
+      (setq c (read-char-exclusive))
+      (cond ((= c ?\C-g)
+            ;; This function may get called from a process filter, where
+            ;; inhibit-quit is set.  In later versions of emacs read-char
+            ;; may clear quit-flag itself and return C-g.  That would make
+            ;; it impossible to quit this loop in a simple way, so
+            ;; re-enable it here (for backward-compatibility the check for
+            ;; quit-flag below would still be necessary, so this seems
+            ;; like the simplest way to do things).
+            (setq quit-flag t
+                  done t))
+           ((or (= c ?\r) (= c ?\n) (= c ?\e))
+            (setq done t))
+           ((= c ?\C-u)
+            (setq ans ""))
+           ((and (/= c ?\b) (/= c ?\177))
+            (setq ans (concat ans (char-to-string c))))
+           ((> (length ans) 0)
+            (setq ans (substring ans 0 -1)))))
+    (if quit-flag
+        ;; Emulate a true quit, except that we have to return a value.
+        (prog1
+            (setq quit-flag nil)
+          (message "Quit")
+          (beep t))
+      (message "")
+      ans)))
+
+(defun send-invisible (str)
+  "Read a string without echoing.
+Then send it to the process running in the current buffer.
+The string is sent using `comint-input-sender'.
+Security bug: your string can still be temporarily recovered with
+\\[view-lossage]."
+  (interactive "P") ; Defeat snooping via C-x esc
+  (let ((proc (get-buffer-process (current-buffer))))
+    (if (not proc)
+       (error "Current buffer has no process")
+      (funcall comint-input-sender proc
+       (if (stringp str) str (comint-read-noecho "Non-echoed text: " t))))))
+
+(defun comint-watch-for-password-prompt (string) 
+  "Prompt in the minibuffer for password and send without echoing.
+This function uses `send-invisible' to read and send a password to the buffer's
+process if STRING contains a password prompt defined by 
+`comint-password-prompt-regexp'.
+
+This function could be in the list `comint-output-filter-functions'."
+  (if (string-match comint-password-prompt-regexp string)
+      (send-invisible nil)))
+\f
+;; Low-level process communication
+
+(defalias 'comint-send-string 'process-send-string)
+(defalias 'comint-send-region 'process-send-region)
+\f
+;; Random input hackage
+
+(defun comint-kill-output ()
+  "Kill all output from interpreter since last input.
+Does not delete the prompt."
+  (interactive)
+  (let ((proc (get-buffer-process (current-buffer)))
+       (replacement nil))
+    (save-excursion
+      (let ((pmark (progn (goto-char (process-mark proc))
+                         (beginning-of-line nil)
+                         (point-marker))))
+       (delete-region comint-last-input-end pmark)
+       (goto-char (process-mark proc))
+       (setq replacement (concat "*** output flushed ***\n"
+                                 (buffer-substring pmark (point))))
+       (delete-region pmark (point))))
+    ;; Output message and put back prompt
+    (comint-output-filter proc replacement)))
+
+(defun comint-show-output ()
+  "Display start of this batch of interpreter output at top of window.
+Sets mark to the value of point when this command is run."
+  (interactive)
+  (push-mark)
+  (let ((pos (point)))
+    (goto-char (or (marker-position comint-last-input-end) (point-max)))
+    (beginning-of-line 0)
+    (set-window-start (selected-window) (point))
+    (comint-skip-prompt)))
+
+(defun comint-interrupt-subjob ()
+  "Interrupt the current subjob."
+  (interactive)
+  (interrupt-process nil comint-ptyp))
+
+(defun comint-kill-subjob ()
+  "Send kill signal to the current subjob."
+  (interactive)
+  (kill-process nil comint-ptyp))
+
+(defun comint-quit-subjob ()
+  "Send quit signal to the current subjob."
+  (interactive)
+  (quit-process nil comint-ptyp))
+
+(defun comint-stop-subjob ()
+  "Stop the current subjob.
+WARNING: if there is no current subjob, you can end up suspending
+the top-level process running in the buffer. If you accidentally do
+this, use \\[comint-continue-subjob] to resume the process. (This
+is not a problem with most shells, since they ignore this signal.)"
+  (interactive)
+  (stop-process nil comint-ptyp))
+
+(defun comint-continue-subjob ()
+  "Send CONT signal to process buffer's process group.
+Useful if you accidentally suspend the top-level process."
+  (interactive)
+  (continue-process nil comint-ptyp))
+
+(defun comint-kill-input ()
+  "Kill all text from last stuff output by interpreter to point."
+  (interactive)
+  (let ((pmark (process-mark (get-buffer-process (current-buffer)))))
+    (if (> (point) (marker-position pmark))
+       (kill-region pmark (point)))))
+
+(defun comint-delchar-or-maybe-eof (arg)
+  "Delete ARG characters forward, or (if at eob) send an EOF to subprocess."
+  (interactive "p")
+  (if (eobp)
+      (process-send-eof)
+    (delete-char arg)))
+
+(defun comint-send-eof ()
+  "Send an EOF to the current buffer's process."
+  (interactive)
+  (process-send-eof))
+
+
+(defun comint-backward-matching-input (regexp arg)
+  "Search backward through buffer for match for REGEXP.
+Matches are searched for on lines that match `comint-prompt-regexp'.
+With prefix argument N, search for Nth previous match.
+If N is negative, find the next or Nth next match."
+  (interactive (comint-regexp-arg "Backward input matching (regexp): "))
+  (let* ((re (concat comint-prompt-regexp ".*" regexp))
+        (pos (save-excursion (end-of-line (if (> arg 0) 0 1))
+                             (if (re-search-backward re nil t arg)
+                                 (point)))))
+    (if (null pos)
+       (progn (message "Not found")
+              (ding))
+      (goto-char pos)
+      (comint-bol nil))))
+
+(defun comint-forward-matching-input (regexp arg)
+  "Search forward through buffer for match for REGEXP.
+Matches are searched for on lines that match `comint-prompt-regexp'.
+With prefix argument N, search for Nth following match.
+If N is negative, find the previous or Nth previous match."
+  (interactive (comint-regexp-arg "Forward input matching (regexp): "))
+  (comint-backward-matching-input regexp (- arg)))
+
+
+(defun comint-next-prompt (n)
+  "Move to end of Nth next prompt in the buffer.
+See `comint-prompt-regexp'."
+  (interactive "p")
+  (let ((paragraph-start comint-prompt-regexp))
+    (end-of-line (if (> n 0) 1 0))
+    (forward-paragraph n)
+    (comint-skip-prompt)))
+
+(defun comint-previous-prompt (n)
+  "Move to end of Nth previous prompt in the buffer.
+See `comint-prompt-regexp'."
+  (interactive "p")
+  (comint-next-prompt (- n)))
+\f
+;; Support for source-file processing commands.
+;;============================================================================
+;; Many command-interpreters (e.g., Lisp, Scheme, Soar) have
+;; commands that process files of source text (e.g. loading or compiling
+;; files). So the corresponding process-in-a-buffer modes have commands
+;; for doing this (e.g., lisp-load-file). The functions below are useful
+;; for defining these commands.
+;;
+;; Alas, these guys don't do exactly the right thing for Lisp, Scheme
+;; and Soar, in that they don't know anything about file extensions.
+;; So the compile/load interface gets the wrong default occasionally.
+;; The load-file/compile-file default mechanism could be smarter -- it
+;; doesn't know about the relationship between filename extensions and
+;; whether the file is source or executable. If you compile foo.lisp
+;; with compile-file, then the next load-file should use foo.bin for
+;; the default, not foo.lisp. This is tricky to do right, particularly
+;; because the extension for executable files varies so much (.o, .bin,
+;; .lbin, .mo, .vo, .ao, ...).
+
+
+;; COMINT-SOURCE-DEFAULT -- determines defaults for source-file processing
+;; commands.
+;;
+;; COMINT-CHECK-SOURCE -- if FNAME is in a modified buffer, asks you if you
+;; want to save the buffer before issuing any process requests to the command
+;; interpreter.
+;;
+;; COMINT-GET-SOURCE -- used by the source-file processing commands to prompt
+;; for the file to process.
+
+;; (COMINT-SOURCE-DEFAULT previous-dir/file source-modes)
+;;============================================================================
+;; This function computes the defaults for the load-file and compile-file
+;; commands for tea, soar, cmulisp, and cmuscheme modes. 
+;; 
+;; - PREVIOUS-DIR/FILE is a pair (directory . filename) from the last 
+;; source-file processing command. NIL if there hasn't been one yet.
+;; - SOURCE-MODES is a list used to determine what buffers contain source
+;; files: if the major mode of the buffer is in SOURCE-MODES, it's source.
+;; Typically, (lisp-mode) or (scheme-mode).
+;; 
+;; If the command is given while the cursor is inside a string, *and*
+;; the string is an existing filename, *and* the filename is not a directory,
+;; then the string is taken as default. This allows you to just position
+;; your cursor over a string that's a filename and have it taken as default.
+;;
+;; If the command is given in a file buffer whose major mode is in
+;; SOURCE-MODES, then the the filename is the default file, and the
+;; file's directory is the default directory.
+;; 
+;; If the buffer isn't a source file buffer (e.g., it's the process buffer),
+;; then the default directory & file are what was used in the last source-file
+;; processing command (i.e., PREVIOUS-DIR/FILE).  If this is the first time
+;; the command has been run (PREVIOUS-DIR/FILE is nil), the default directory
+;; is the cwd, with no default file. (\"no default file\" = nil)
+;; 
+;; SOURCE-REGEXP is typically going to be something like (tea-mode)
+;; for T programs, (lisp-mode) for Lisp programs, (soar-mode lisp-mode)
+;; for Soar programs, etc.
+;; 
+;; The function returns a pair: (default-directory . default-file).
+
+(defun comint-source-default (previous-dir/file source-modes)
+  (cond ((and buffer-file-name (memq major-mode source-modes))
+        (cons (file-name-directory    buffer-file-name)
+              (file-name-nondirectory buffer-file-name)))
+       (previous-dir/file)
+       (t
+        (cons default-directory nil))))
+
+
+;; (COMINT-CHECK-SOURCE fname)
+;;============================================================================
+;; Prior to loading or compiling (or otherwise processing) a file (in the CMU
+;; process-in-a-buffer modes), this function can be called on the filename.
+;; If the file is loaded into a buffer, and the buffer is modified, the user
+;; is queried to see if he wants to save the buffer before proceeding with
+;; the load or compile.
+
+(defun comint-check-source (fname)
+  (let ((buff (get-file-buffer fname)))
+    (if (and buff
+            (buffer-modified-p buff)
+            (y-or-n-p (format "Save buffer %s first? " (buffer-name buff))))
+       ;; save BUFF.
+       (let ((old-buffer (current-buffer)))
+         (set-buffer buff)
+         (save-buffer)
+         (set-buffer old-buffer)))))
+
+
+;; (COMINT-GET-SOURCE prompt prev-dir/file source-modes mustmatch-p)
+;;============================================================================
+;; COMINT-GET-SOURCE is used to prompt for filenames in command-interpreter
+;; commands that process source files (like loading or compiling a file).
+;; It prompts for the filename, provides a default, if there is one,
+;; and returns the result filename.
+;; 
+;; See COMINT-SOURCE-DEFAULT for more on determining defaults.
+;; 
+;; PROMPT is the prompt string. PREV-DIR/FILE is the (directory . file) pair
+;; from the last source processing command.  SOURCE-MODES is a list of major
+;; modes used to determine what file buffers contain source files.  (These
+;; two arguments are used for determining defaults). If MUSTMATCH-P is true,
+;; then the filename reader will only accept a file that exists.
+;; 
+;; A typical use:
+;; (interactive (comint-get-source "Compile file: " prev-lisp-dir/file
+;;                                 '(lisp-mode) t))
+
+;; This is pretty stupid about strings. It decides we're in a string
+;; if there's a quote on both sides of point on the current line.
+(defun comint-extract-string ()
+  "Return string around POINT that starts the current line, or nil." 
+  (save-excursion
+    (let* ((point (point))
+          (bol (progn (beginning-of-line) (point)))
+          (eol (progn (end-of-line) (point)))
+          (start (progn (goto-char point) 
+                        (and (search-backward "\"" bol t) 
+                             (1+ (point)))))
+          (end (progn (goto-char point)
+                      (and (search-forward "\"" eol t)
+                           (1- (point))))))
+      (and start end
+          (buffer-substring start end)))))
+
+(defun comint-get-source (prompt prev-dir/file source-modes mustmatch-p)
+  (let* ((def (comint-source-default prev-dir/file source-modes))
+         (stringfile (comint-extract-string))
+        (sfile-p (and stringfile
+                      (condition-case ()
+                          (file-exists-p stringfile)
+                        (error nil))
+                      (not (file-directory-p stringfile))))
+        (defdir  (if sfile-p (file-name-directory stringfile)
+                      (car def)))
+        (deffile (if sfile-p (file-name-nondirectory stringfile)
+                      (cdr def)))
+        (ans (read-file-name (if deffile (format "%s(default %s) "
+                                                 prompt    deffile)
+                                 prompt)
+                             defdir
+                             (concat defdir deffile)
+                             mustmatch-p)))
+    (list (expand-file-name (substitute-in-file-name ans)))))
+
+;; I am somewhat divided on this string-default feature. It seems
+;; to violate the principle-of-least-astonishment, in that it makes
+;; the default harder to predict, so you actually have to look and see
+;; what the default really is before choosing it. This can trip you up.
+;; On the other hand, it can be useful, I guess. I would appreciate feedback
+;; on this.
+;;     -Olin
+
+\f
+;; Simple process query facility.
+;; ===========================================================================
+;; This function is for commands that want to send a query to the process
+;; and show the response to the user. For example, a command to get the
+;; arglist for a Common Lisp function might send a "(arglist 'foo)" query
+;; to an inferior Common Lisp process.
+;; 
+;; This simple facility just sends strings to the inferior process and pops
+;; up a window for the process buffer so you can see what the process
+;; responds with.  We don't do anything fancy like try to intercept what the
+;; process responds with and put it in a pop-up window or on the message
+;; line. We just display the buffer. Low tech. Simple. Works good.
+
+;; Send to the inferior process PROC the string STR. Pop-up but do not select
+;; a window for the inferior process so that its response can be seen.
+(defun comint-proc-query (proc str)
+  (let* ((proc-buf (process-buffer proc))
+        (proc-mark (process-mark proc)))
+    (display-buffer proc-buf)
+    (set-buffer proc-buf) ; but it's not the selected *window*
+    (let ((proc-win (get-buffer-window proc-buf))
+         (proc-pt (marker-position proc-mark)))
+      (comint-send-string proc str) ; send the query
+      (accept-process-output proc)  ; wait for some output
+      ;; Try to position the proc window so you can see the answer.
+      ;; This is bogus code. If you delete the (sit-for 0), it breaks.
+      ;; I don't know why. Wizards invited to improve it.
+      (if (not (pos-visible-in-window-p proc-pt proc-win))
+         (let ((opoint (window-point proc-win)))
+           (set-window-point proc-win proc-mark)
+           (sit-for 0)
+           (if (not (pos-visible-in-window-p opoint proc-win))
+               (push-mark opoint)
+             (set-window-point proc-win opoint)))))))
+
+\f
+;; Filename/command/history completion in a buffer
+;; ===========================================================================
+;; Useful completion functions, courtesy of the Ergo group.
+
+;; Six commands:
+;; comint-dynamic-complete             Complete or expand command, filename,
+;;                                     history at point.
+;; comint-dynamic-complete-filename    Complete filename at point.
+;; comint-dynamic-list-filename-completions List completions in help buffer.
+;; comint-replace-by-expanded-filename Expand and complete filename at point;
+;;                                     replace with expanded/completed name.
+;; comint-dynamic-simple-complete      Complete stub given candidates.
+
+;; These are not installed in the comint-mode keymap. But they are
+;; available for people who want them. Shell-mode installs them:
+;; (define-key shell-mode-map "\t" 'comint-dynamic-complete)
+;; (define-key shell-mode-map "\M-?"
+;;             'comint-dynamic-list-filename-completions)))
+;;
+;; Commands like this are fine things to put in load hooks if you
+;; want them present in specific modes.
+
+(defvar comint-completion-autolist nil
+  "*If non-nil, automatically list possibilities on partial completion.
+This mirrors the optional behavior of tcsh.")
+
+(defvar comint-completion-addsuffix t
+  "*If non-nil, add a `/' to completed directories, ` ' to file names.
+If a cons pair, it should be of the form (DIRSUFFIX . FILESUFFIX) where
+DIRSUFFIX and FILESUFFIX are strings added on unambiguous or exact completion.
+This mirrors the optional behavior of tcsh.")
+
+(defvar comint-completion-recexact nil
+  "*If non-nil, use shortest completion if characters cannot be added.
+This mirrors the optional behavior of tcsh.
+
+A non-nil value is useful if `comint-completion-autolist' is non-nil too.")
+
+(defvar comint-completion-fignore nil
+  "*List of suffixes to be disregarded during file completion.
+This mirrors the optional behavior of bash and tcsh.
+
+Note that this applies to `comint-dynamic-complete-filename' only.")
+
+(defvar comint-file-name-prefix ""
+  "Prefix prepended to absolute file names taken from process input.
+This is used by comint's and shell's completion functions, and by shell's
+directory tracking functions.")
+
+(defvar comint-file-name-quote-list nil
+  "List of characters to quote with `\' when in a file name.
+
+This is a good thing to set in mode hooks.")
+
+
+(defun comint-directory (directory)
+  ;; Return expanded DIRECTORY, with `comint-file-name-prefix' if absolute.
+  (expand-file-name (if (file-name-absolute-p directory)
+                       (concat comint-file-name-prefix directory)
+                     directory)))
+
+
+(defun comint-word (word-chars)
+  "Return the word of WORD-CHARS at point, or nil if non is found.
+Word constituents are considered to be those in WORD-CHARS, which is like the
+inside of a \"[...]\" (see `skip-chars-forward')."
+  (save-excursion
+    (let ((non-word-chars (concat "[^\\\\" word-chars "]")) (here (point)))
+      (while (and (re-search-backward non-word-chars nil 'move)
+                 ;(memq (char-after (point)) shell-file-name-quote-list)
+                 (eq (preceding-char) ?\\))
+       (backward-char 1))
+      ;; Don't go forward over a word-char (this can happen if we're at bob).
+      (if (or (not (bobp)) (looking-at non-word-chars))
+         (forward-char 1))
+      ;; Set match-data to match the entire string.
+      (if (< (point) here)
+         (progn (store-match-data (list (point) here))
+                (match-string 0))))))
+
+
+(defun comint-match-partial-filename ()
+  "Return the filename at point, or nil if non is found.
+Environment variables are substituted.  See `comint-word'."
+  (let ((filename (comint-word "~/A-Za-z0-9+@:_.$#%,={}-")))
+    (and filename (substitute-in-file-name (comint-unquote-filename filename)))))
+
+
+(defun comint-quote-filename (filename)
+  "Return FILENAME with magic characters quoted.
+Magic characters are those in `comint-file-name-quote-list'."
+  (if (null comint-file-name-quote-list)
+      filename
+    (let ((regexp
+          (format "\\(^\\|[^\\]\\)\\([%s]\\)"
+           (mapconcat 'char-to-string comint-file-name-quote-list ""))))
+      (save-match-data
+       (while (string-match regexp filename)
+         (setq filename (replace-match "\\1\\\\\\2" nil nil filename)))
+       filename))))
+
+(defun comint-unquote-filename (filename)
+  "Return FILENAME with quoted characters unquoted."
+  (if (null comint-file-name-quote-list)
+      filename
+    (save-match-data
+      (while (string-match "\\\\\\(.\\)" filename)
+       (setq filename (replace-match "\\1" nil nil filename)))
+      filename)))
+
+
+(defun comint-dynamic-complete ()
+  "Dynamically perform completion at point.
+Calls the functions in `comint-dynamic-complete-functions' to perform
+completion until a function returns non-nil, at which point completion is
+assumed to have occurred."
+  (interactive)
+  (run-hook-with-args-until-success 'comint-dynamic-complete-functions))
+
+
+(defun comint-dynamic-complete-filename ()
+  "Dynamically complete the filename at point.
+Completes if after a filename.  See `comint-match-partial-filename' and
+`comint-dynamic-complete-as-filename'.
+This function is similar to `comint-replace-by-expanded-filename', except that
+it won't change parts of the filename already entered in the buffer; it just
+adds completion characters to the end of the filename.  A completions listing
+may be shown in a help buffer if completion is ambiguous.
+
+Completion is dependent on the value of `comint-completion-addsuffix',
+`comint-completion-recexact' and `comint-completion-fignore', and the timing of
+completions listing is dependent on the value of `comint-completion-autolist'.
+
+Returns t if successful."
+  (interactive)
+  (if (comint-match-partial-filename)
+      (prog2 (or (window-minibuffer-p (selected-window))
+                (message "Completing file name..."))
+         (comint-dynamic-complete-as-filename))))
+
+
+(defun comint-dynamic-complete-as-filename ()
+  "Dynamically complete at point as a filename.
+See `comint-dynamic-complete-filename'.  Returns t if successful."
+  (let* ((completion-ignore-case nil)
+        (completion-ignored-extensions comint-completion-fignore)
+        (file-name-handler-alist nil)
+        (minibuffer-p (window-minibuffer-p (selected-window)))
+        (success t)
+        (dirsuffix (cond ((not comint-completion-addsuffix) "")
+                         ((not (consp comint-completion-addsuffix)) "/")
+                         (t (car comint-completion-addsuffix))))
+        (filesuffix (cond ((not comint-completion-addsuffix) "")
+                          ((not (consp comint-completion-addsuffix)) " ")
+                          (t (cdr comint-completion-addsuffix))))
+        (filename (or (comint-match-partial-filename) ""))
+        (pathdir (file-name-directory filename))
+        (pathnondir (file-name-nondirectory filename))
+        (directory (if pathdir (comint-directory pathdir) default-directory))
+        (completion (file-name-completion pathnondir directory)))
+    (cond ((null completion)
+           (message "No completions of %s" filename)
+          (setq success nil))
+          ((eq completion t)            ; Means already completed "file".
+           (insert filesuffix)
+           (or minibuffer-p (message "Sole completion")))
+          ((string-equal completion "") ; Means completion on "directory/".
+           (comint-dynamic-list-filename-completions))
+          (t                            ; Completion string returned.
+           (let ((file (concat (file-name-as-directory directory) completion)))
+            (insert (comint-quote-filename
+                     (substring (directory-file-name completion)
+                                (length pathnondir))))
+             (cond ((symbolp (file-name-completion completion directory))
+                    ;; We inserted a unique completion.
+                   (insert (if (file-directory-p file) dirsuffix filesuffix))
+                    (or minibuffer-p (message "Completed")))
+                   ((and comint-completion-recexact comint-completion-addsuffix
+                         (string-equal pathnondir completion)
+                         (file-exists-p file))
+                    ;; It's not unique, but user wants shortest match.
+                    (insert (if (file-directory-p file) dirsuffix filesuffix))
+                    (or minibuffer-p (message "Completed shortest")))
+                   ((or comint-completion-autolist
+                        (string-equal pathnondir completion))
+                    ;; It's not unique, list possible completions.
+                    (comint-dynamic-list-filename-completions))
+                   (t
+                    (or minibuffer-p (message "Partially completed")))))))
+    success))
+
+
+(defun comint-replace-by-expanded-filename ()
+  "Dynamically expand and complete the filename at point.
+Replace the filename with an expanded, canonicalised and completed replacement.
+\"Expanded\" means environment variables (e.g., $HOME) and `~'s are replaced
+with the corresponding directories.  \"Canonicalised\" means `..'  and `.' are
+removed, and the filename is made absolute instead of relative.  For expansion
+see `expand-file-name' and `substitute-in-file-name'.  For completion see
+`comint-dynamic-complete-filename'."
+  (interactive)
+  (replace-match (expand-file-name (comint-match-partial-filename)) t t)
+  (comint-dynamic-complete-filename))
+
+
+(defun comint-dynamic-simple-complete (stub candidates)
+  "Dynamically complete STUB from CANDIDATES list.
+This function inserts completion characters at point by completing STUB from
+the strings in CANDIDATES.  A completions listing may be shown in a help buffer
+if completion is ambiguous.
+
+Returns nil if no completion was inserted.
+Returns `sole' if completed with the only completion match.
+Returns `shortest' if completed with the shortest of the completion matches.
+Returns `partial' if completed as far as possible with the completion matches.
+Returns `listed' if a completion listing was shown.
+
+See also `comint-dynamic-complete-filename'."
+  (let* ((completion-ignore-case nil)
+        (suffix (cond ((not comint-completion-addsuffix) "")
+                      ((not (consp comint-completion-addsuffix)) " ")
+                      (t (cdr comint-completion-addsuffix))))
+        (candidates (mapcar (function (lambda (x) (list x))) candidates))
+        (completions (all-completions stub candidates)))
+    (cond ((null completions)
+          (message "No completions of %s" stub)
+          nil)
+         ((= 1 (length completions))   ; Gotcha!
+          (let ((completion (car completions)))
+            (if (string-equal completion stub)
+                (message "Sole completion")
+              (insert (substring completion (length stub)))
+              (message "Completed"))
+            (insert suffix)
+            'sole))
+         (t                            ; There's no unique completion.
+          (let ((completion (try-completion stub candidates)))
+            ;; Insert the longest substring.
+            (insert (substring completion (length stub)))
+            (cond ((and comint-completion-recexact comint-completion-addsuffix
+                        (string-equal stub completion)
+                        (member completion completions))
+                   ;; It's not unique, but user wants shortest match.
+                   (insert suffix)
+                   (message "Completed shortest")
+                   'shortest)
+                  ((or comint-completion-autolist
+                       (string-equal stub completion))
+                   ;; It's not unique, list possible completions.
+                   (comint-dynamic-list-completions completions)
+                   'listed)
+                  (t
+                   (message "Partially completed")
+                   'partial)))))))
+
+
+(defun comint-dynamic-list-filename-completions ()
+  "List in help buffer possible completions of the filename at point."
+  (interactive)
+  (let* ((completion-ignore-case nil)
+        (file-name-handler-alist nil)
+        (filename (or (comint-match-partial-filename) ""))
+        (pathdir (file-name-directory filename))
+        (pathnondir (file-name-nondirectory filename))
+        (directory (if pathdir (comint-directory pathdir) default-directory))
+        (completions (file-name-all-completions pathnondir directory)))
+    (if (not completions)
+       (message "No completions of %s" filename)
+      (comint-dynamic-list-completions
+       (mapcar 'comint-quote-filename completions)))))
+
+
+(defun comint-dynamic-list-completions (completions)
+  "List in help buffer sorted COMPLETIONS.
+Typing SPC flushes the help buffer."
+  (let ((conf (current-window-configuration)))
+    (with-output-to-temp-buffer "*Completions*"
+      (display-completion-list (sort completions 'string-lessp)))
+    (message "Hit space to flush")
+    (let (key first)
+      (if (save-excursion
+           (set-buffer (get-buffer "*Completions*"))
+           (setq key (read-key-sequence nil)
+                 first (aref key 0))
+           (and (consp first) (consp (event-start first))
+                (eq (window-buffer (posn-window (event-start first)))
+                    (get-buffer "*Completions*"))
+                (eq (key-binding key) 'mouse-choose-completion)))
+         ;; If the user does mouse-choose-completion with the mouse,
+         ;; execute the command, then delete the completion window.
+         (progn
+           (mouse-choose-completion first)
+           (set-window-configuration conf))
+       (if (eq first ?\ )
+           (set-window-configuration conf)
+         (setq unread-command-events (listify-key-sequence key)))))))
+\f
+;; Converting process modes to use comint mode
+;; ===========================================================================
+;; The code in the Emacs 19 distribution has all been modified to use comint
+;; where needed.  However, there are `third-party' packages out there that
+;; still use the old shell mode.  Here's a guide to conversion.
+;;
+;; Renaming variables
+;; Most of the work is renaming variables and functions. These are the common
+;; ones:
+;; Local variables:
+;;     last-input-start        comint-last-input-start
+;;     last-input-end          comint-last-input-end
+;;     shell-prompt-pattern    comint-prompt-regexp
+;;     shell-set-directory-error-hook <no equivalent>
+;; Miscellaneous:
+;;     shell-set-directory     <unnecessary>
+;;     shell-mode-map          comint-mode-map
+;; Commands:
+;;     shell-send-input        comint-send-input
+;;     shell-send-eof          comint-delchar-or-maybe-eof
+;;     kill-shell-input        comint-kill-input
+;;     interrupt-shell-subjob  comint-interrupt-subjob
+;;     stop-shell-subjob       comint-stop-subjob
+;;     quit-shell-subjob       comint-quit-subjob
+;;     kill-shell-subjob       comint-kill-subjob
+;;     kill-output-from-shell  comint-kill-output
+;;     show-output-from-shell  comint-show-output
+;;     copy-last-shell-input   Use comint-previous-input/comint-next-input
+;;
+;; SHELL-SET-DIRECTORY is gone, its functionality taken over by
+;; SHELL-DIRECTORY-TRACKER, the shell mode's comint-input-filter-functions.
+;; Comint mode does not provide functionality equivalent to
+;; shell-set-directory-error-hook; it is gone.
+;;
+;; comint-last-input-start is provided for modes which want to munge
+;; the buffer after input is sent, perhaps because the inferior
+;; insists on echoing the input.  The LAST-INPUT-START variable in
+;; the old shell package was used to implement a history mechanism,
+;; but you should think twice before using comint-last-input-start
+;; for this; the input history ring often does the job better.
+;; 
+;; If you are implementing some process-in-a-buffer mode, called foo-mode, do
+;; *not* create the comint-mode local variables in your foo-mode function.
+;; This is not modular.  Instead, call comint-mode, and let *it* create the
+;; necessary comint-specific local variables. Then create the
+;; foo-mode-specific local variables in foo-mode.  Set the buffer's keymap to
+;; be foo-mode-map, and its mode to be foo-mode.  Set the comint-mode hooks
+;; (comint-{prompt-regexp, input-filter, input-filter-functions,
+;; get-old-input) that need to be different from the defaults.  Call
+;; foo-mode-hook, and you're done. Don't run the comint-mode hook yourself;
+;; comint-mode will take care of it. The following example, from shell.el,
+;; is typical:
+;; 
+;; (defvar shell-mode-map '())
+;; (cond ((not shell-mode-map)
+;;        (setq shell-mode-map (copy-keymap comint-mode-map))
+;;        (define-key shell-mode-map "\C-c\C-f" 'shell-forward-command)
+;;        (define-key shell-mode-map "\C-c\C-b" 'shell-backward-command)
+;;        (define-key shell-mode-map "\t" 'comint-dynamic-complete)
+;;        (define-key shell-mode-map "\M-?"
+;;          'comint-dynamic-list-filename-completions)))
+;;
+;; (defun shell-mode ()
+;;   (interactive)
+;;   (comint-mode)
+;;   (setq comint-prompt-regexp shell-prompt-pattern)
+;;   (setq major-mode 'shell-mode)
+;;   (setq mode-name "Shell")
+;;   (use-local-map shell-mode-map)
+;;   (make-local-variable 'shell-directory-stack)
+;;   (setq shell-directory-stack nil)
+;;   (add-hook 'comint-input-filter-functions 'shell-directory-tracker)
+;;   (run-hooks 'shell-mode-hook))
+;;
+;;
+;; Note that make-comint is different from make-shell in that it
+;; doesn't have a default program argument. If you give make-shell
+;; a program name of NIL, it cleverly chooses one of explicit-shell-name,
+;; $ESHELL, $SHELL, or /bin/sh. If you give make-comint a program argument
+;; of NIL, it barfs. Adjust your code accordingly...
+;;
+;; Completion for comint-mode users
+;; 
+;; For modes that use comint-mode, comint-dynamic-complete-functions is the
+;; hook to add completion functions to.  Functions on this list should return
+;; non-nil if completion occurs (i.e., further completion should not occur).
+;; You could use comint-dynamic-simple-complete to do the bulk of the
+;; completion job.
+\f
+(provide 'comint)
+
+;; comint.el ends here