aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1993-10-22 02:57:36 +0000
committerRichard M. Stallman1993-10-22 02:57:36 +0000
commit3ee91e68a0289a1c915af370306ecb4249060335 (patch)
tree30f6c6e9583de7d9d9b32d1e3b8b99f3576428c5
parentd76b71afe39a724f5fc819c84f9bc9e34df34240 (diff)
downloademacs-3ee91e68a0289a1c915af370306ecb4249060335.tar.gz
emacs-3ee91e68a0289a1c915af370306ecb4249060335.zip
(comint-after-partial-file-name-command):
Renamed from comint-after-partial-pathname-command. (comint-match-partial-file-name, comint-after-partial-file-name): Renamed from comint-match-partial-pathname, etc. (comint-last-output-start): New variable to record where most recent process output started from. (comint-mode): Initialise it. (comint-output-filter): Set it. (comint-previous-matching-input-string): Moved to comint-previous-matching-input-position. (comint-previous-matching-input-string): Use it. (comint-search-arg, comint-search-start, comint-previous-input-string): New subroutines. (comint-previous-input, comint-next-input, comint-previous-matching-input, comint-next-matching-input, comint-previous-matching-input-from-input, comint-next-matching-input-from-input): Use them. (comint-mode-map): Added signal menu-bar. Moved comint-backward/forward-matching-input to output menu-bar, since they move within the buffer rather than do input. (comint-send-input, comint-after-pmark-p, comint-kill-input, comint-proc-query): Removed serialisation of obtaining the process mark's marker-position. Commented out comint-load-hooks. (comint-dynamic-simple-complete): New subroutine. (comint-dynamic-complete-filename-command): New variable. (comint-after-partial-pathname-command): New variable. (comint-after-partial-pathname): New subroutine. (comint-dynamic-complete): Use them. (comint-mode): Make them local. Renamed comint-dynamic-complete-command to comint-dynamic-complete-command-command for consistency. Renamed comint-file-name-addsuffix/autolist/recexact to comint-completion-addsuffix/autolist/recexact for consistency. (comint-replace-by-expanded-history): Check if input ring size is not big enough for relative reference. (comint-read-input-ring, comint-input-ring-file-name): From shell.el. (shell-write-input-ring): New subroutine. (comint-file-name-prefix): New variable. (comint-directory): New inline subroutine. (comint-dynamic-complete-filename, comint-dynamic-complete-variable, comint-dynamic-list-filename-completions): Use it. (comint-dynamic-complete-filename, comint-dynamic-complete-variable, comint-dynamic-list-filename-completions): Make sure local completion-ignore-case is nil. (comint-next-prompt, comint-previous-prompt): Use paragraph-start and paragraph motion commands rather than re-search-forward and re-search-backward commands. (comint-dynamic-list-input-ring, comint-previous-matching-input-string): Use ring-empty-p rather than zerop and ring-length. (comint-input-ignoredups): New variable. (comint-send-input, shell-read-input-ring): Use it. (comint-mode): Make comint-input-ignoredups local. Doc fix. (comint-scroll-to-bottom-on-input): New variable. (comint-scroll-to-bottom-on-output): New variable. (comint-scroll-show-maximum-output): New variable. (comint-output-filter-hook): New variable, defaults to comint-postoutput-scroll-to-bottom. (comint-output-filter): Renamed from comint-filter for consistency. Now calls comint-output-filter-hook. (comint-preinput-scroll-to-bottom): New subroutine. (comint-postoutput-scroll-to-bottom): New subroutine. (comint-show-maximum-output): New command. (comint-copy-old-input): New command. (comint-send-input): Run comint-output-filter-hook if necessary as a kludge to prevent messy redisplays. (comint-mode-map): Added comint-show-maximum-output to C-c C-e and menu-bar output, and comint-copy-old-input to C-c C-i and menu-bar input. (comint-mode): Make local variables comint-scroll-to-bottom-on-input, before-change-function, comint-scroll-to-bottom-on-output, comint-scroll-show-maximum-output, and comint-output-filter-hook. (comint-version): Deleted--no need for separate version. (comint-input-ring-index): Make this a permanent local. (comint-mode): Don't alter comint-input-ring-index or comint-input-ring if already set meaningfully. (comint-mode-map): Added keys M-R/S for comint-previous/next-matching-input-from-input and to completion menu-bar. Added comint-forward/backward-matching-input and comint-previous/next-matching-input to completion menu-bar. (comint-mode): Doc fix for functionality. (comint-exec-1): Uses setenv. (comint-update-env): Removed. (comint-input-ring-size): Incremented to 32, as with command history. (comint-dynamic-list-input-ring): Check for zero length ring. Use ring length, not ring size, when generating list. Use buffer " *Input History*". (comint-previous-matching-input-string): Check for zero-length ring. Check last item in case at end of cycle and it's a match. (comint-searching-input-ring): New subroutine. (comint-regexp-arg): New subroutine. (comint-previous-matching-input-from-input): New command. (comint-next-matching-input-from-input): New command. (comint-replace-by-expanded-history): Fix for matching inside quotes. Fix to allow argument subrange specifiers. Fix to identify and reject absolute input number references. (comint-within-quotes): New subroutine. (comint-how-many-region): New subroutine. (comint-args): New subroutine. (comint-delim-arg): New subroutine. (comint-arguments): New subroutine. (comint-delimiter-argument-list): New variable. (comint-send-input): Inserts input arguments into ring separated by single spaces. (comint-filter): Checks the buffer's process to make sure it's still there. Otherwise, set-buffer will fail. (comint-backward-matching-input): New command. (comint-forward-matching-input): New command. (comint-next-prompt, comint-previous-prompt): Error if reach beg/end of buffer. (comint-dynamic-complete): Fix for absolute input number references. (comint-dynamic-complete-filename): Changed listings function to comint-dynamic-list-filename-completions. Uses file-directory-p rather than string-match to test for directories. (comint-dynamic-list-completions): Changed to list the list of completions supplied as the function argument. Use buffer " *Completions*". (comint-match-partial-pathname): New subroutine. (comint-dynamic-complete-variable): New command. (comint-dynamic-list-filename-completions): New function. (comint-previous-input): Don't use replace-match; just insert before deleting. (comint-magic-space): Use self-insert command. (comint-history-file-name): New variable. (comint-mode): Initialize comint-input-ring before running comint-mode-hook. (comint-input-autoexpand): New variable. (comint-dynamic-complete-command): New variable. (comint-get-current-command): New variable. (comint-read-input-ring): New function. (comint-send-input): Handle history expansion. (comint-input-sentinel): Doc fix. (comint-mode-map): Added key binding for C-c C-h. Added menu bars for completion, input and output. (comint-dynamic-list-input-ring): New function. (comint-previous-input-string): New subroutine. (comint-previous-input): Use it. (comint-previous-matching-input-string): New subroutine. (comint-previous-matching-input): Use it. (comint-replace-by-expanded-history): New command. (comint-magic-space): New command. (comint-replace-by-expanded-filename): Now replaces expanded match for a filename, and then calls filename completion comint-dynamic-complete-filename to do file name completion. (comint-kill-output): Don't kill prompt. (comint-show-output): Don't move point if it's visible where it is, and if point is moved, put it after prompt. (comint-dynamic-complete): Totally new definition. (comint-dynamic-complete-filename): New name for old function comint-dynamic-complete, completes files and lists candidates, souped up for configurability. (comint-dynamic-complete-variable): New command. (comint-file-name-autolist): New variable. (comint-file-name-addsuffix): New variable, (comint-file-name-recexact): New variable.
-rw-r--r--lisp/comint.el1835
1 files changed, 1225 insertions, 610 deletions
diff --git a/lisp/comint.el b/lisp/comint.el
index 216d622c1ae..c4f8630e851 100644
--- a/lisp/comint.el
+++ b/lisp/comint.el
@@ -3,6 +3,7 @@
3;; Copyright (C) 1988, 1990, 1992, 1993 Free Software Foundation, Inc. 3;; Copyright (C) 1988, 1990, 1992, 1993 Free Software Foundation, Inc.
4 4
5;; Author: Olin Shivers <shivers@cs.cmu.edu> 5;; Author: Olin Shivers <shivers@cs.cmu.edu>
6;; Adapted-by: Simon Marshall <s.marshall@dcs.hull.ac.uk>
6;; Keywords: processes 7;; Keywords: processes
7 8
8;; This file is part of GNU Emacs. 9;; This file is part of GNU Emacs.
@@ -23,11 +24,10 @@
23 24
24;;; Commentary: 25;;; Commentary:
25 26
26;;; The changelog is at the end of this file.
27
28;;; Please send me bug reports, bug fixes, and extensions, so that I can 27;;; Please send me bug reports, bug fixes, and extensions, so that I can
29;;; merge them into the master source. 28;;; merge them into the master source.
30;;; - Olin Shivers (shivers@cs.cmu.edu) 29;;; - Olin Shivers (shivers@cs.cmu.edu)
30;;; - Simon Marshall (s.marshall@dcs.hull.ac.uk)
31 31
32;;; This file defines a general command-interpreter-in-a-buffer package 32;;; This file defines a general command-interpreter-in-a-buffer package
33;;; (comint mode). The idea is that you can build specific process-in-a-buffer 33;;; (comint mode). The idea is that you can build specific process-in-a-buffer
@@ -65,11 +65,12 @@
65;;; 65;;;
66;;; m-p comint-previous-input Cycle backwards in input history 66;;; m-p comint-previous-input Cycle backwards in input history
67;;; m-n comint-next-input Cycle forwards 67;;; m-n comint-next-input Cycle forwards
68;;; m-r comint-previous-matching-input Previous input matching a regexp 68;;; m-r comint-previous-matching-input Previous input matching a regexp
69;;; m-s comint-next-matching-input Next input that matches 69;;; m-s comint-next-matching-input Next input that matches
70;;; m-c-r comint-previous-input-matching Search backwards in input history
70;;; return comint-send-input 71;;; return comint-send-input
71;;; c-a comint-bol Beginning of line; skip prompt. 72;;; c-a comint-bol Beginning of line; skip prompt
72;;; c-d comint-delchar-or-maybe-eof Delete char unless at end of buff. 73;;; c-d comint-delchar-or-maybe-eof Delete char unless at end of buff
73;;; c-c c-u comint-kill-input ^u 74;;; c-c c-u comint-kill-input ^u
74;;; c-c c-w backward-kill-word ^w 75;;; c-c c-w backward-kill-word ^w
75;;; c-c c-c comint-interrupt-subjob ^c 76;;; c-c c-c comint-interrupt-subjob ^c
@@ -77,50 +78,60 @@
77;;; c-c c-\ comint-quit-subjob ^\ 78;;; c-c c-\ comint-quit-subjob ^\
78;;; c-c c-o comint-kill-output Delete last batch of process output 79;;; c-c c-o comint-kill-output Delete last batch of process output
79;;; c-c c-r comint-show-output Show last batch of process output 80;;; c-c c-r comint-show-output Show last batch of process output
81;;; c-c c-h comint-dynamic-list-input-ring List input history
80;;; 82;;;
81;;; Not bound by default in comint-mode 83;;; Not bound by default in comint-mode (some are in shell mode)
82;;; send-invisible Read a line w/o echo, and send to proc 84;;; send-invisible Read a line w/o echo, and send to proc
83;;; (These are bound in shell-mode) 85;;; comint-dynamic-complete-filename Complete filename at point.
84;;; comint-dynamic-complete Complete filename at point. 86;;; comint-dynamic-complete-variable Complete variable name at point.
85;;; comint-dynamic-list-completions List completions in help buffer. 87;;; comint-dynamic-list-filename-completions List completions in help buffer.
86;;; comint-replace-by-expanded-filename Expand and complete filename at point; 88;;; comint-replace-by-expanded-filename Expand and complete filename at point;
87;;; replace with expanded/completed name. 89;;; replace with expanded/completed name.
90;;; comint-replace-by-expanded-history Expand history at point;
91;;; replace with expanded name.
92;;; comint-magic-space Expand history and add (a) space(s).
88;;; comint-kill-subjob No mercy. 93;;; comint-kill-subjob No mercy.
94;;; comint-show-maximum-output Show as much output as possible.
89;;; comint-continue-subjob Send CONT signal to buffer's process 95;;; comint-continue-subjob Send CONT signal to buffer's process
90;;; group. Useful if you accidentally 96;;; group. Useful if you accidentally
91;;; suspend your process (with C-c C-z). 97;;; suspend your process (with C-c C-z).
92;;;
93;;; These used to be bound for RMS -- I prefer the input history stuff,
94;;; but you might like 'em.
95;;; m-P comint-msearch-input Search backwards for prompt
96;;; m-N comint-psearch-input Search forwards for prompt
97;;; C-cR comint-msearch-input-matching Search backwards for prompt & string
98 98
99;;; comint-mode-hook is the comint mode hook. Basically for your keybindings. 99;;; comint-mode-hook is the comint mode hook. Basically for your keybindings.
100;;; comint-load-hook is run after loading in this package.
101 100
102;;; Code: 101;;; Code:
103 102
104(defconst comint-version "2.03")
105
106(require 'ring) 103(require 'ring)
107 104
108;;; Buffer Local Variables: 105;;; Buffer Local Variables:
109;;;============================================================================ 106;;;============================================================================
110;;; Comint mode buffer local variables: 107;;; Comint mode buffer local variables:
111;;; comint-prompt-regexp - string comint-bol uses to match prompt. 108;;; comint-prompt-regexp - string comint-bol uses to match prompt
112;;; comint-last-input-start - marker Handy if inferior always echos 109;;; comint-delimiter-argument-list - list For delimiters and arguments
110;;; comint-last-input-start - marker Handy if inferior always echoes
113;;; comint-last-input-end - marker For comint-kill-output command 111;;; comint-last-input-end - marker For comint-kill-output command
114;;; comint-input-ring-size - integer For the input history 112;;; comint-input-ring-size - integer For the input history
115;;; comint-input-ring - ring mechanism 113;;; comint-input-ring - ring mechanism
116;;; comint-input-ring-index - number ... 114;;; comint-input-ring-index - number ...
115;;; comint-input-autoexpand - symbol ...
116;;; comint-input-ignoredups - boolean ...
117;;; comint-last-input-match - string ... 117;;; comint-last-input-match - string ...
118;;; comint-get-old-input - function Hooks for specific 118;;; comint-get-old-input - function Hooks for specific
119;;; comint-input-sentinel - function process-in-a-buffer 119;;; comint-get-current-command - function process-in-a-buffer
120;;; comint-input-filter - function modes. 120;;; comint-dynamic-complete-command-command - function modes.
121;;; comint-input-send - function 121;;; comint-after-partial-filename-command -
122;;; comint-eol-on-send - boolean 122;;; comint-input-sentinel - function ...
123;;; comint-process-echoes - boolean 123;;; comint-input-filter - function ...
124;;; comint-input-send - function ...
125;;; comint-eol-on-send - boolean ...
126;;; comint-process-echoes - boolean ...
127;;; comint-scroll-to-bottom-on-input - symbol For scroll behaviour
128;;; comint-scroll-to-bottom-on-output - symbol ...
129;;; comint-scroll-show-maximum-output - boolean ...
130;;;
131;;; Comint mode non-buffer local variables:
132;;; comint-completion-addsuffix - boolean For file name completion
133;;; comint-completion-autolist - boolean behaviour
134;;; comint-completion-recexact - boolean ...
124 135
125(defvar comint-prompt-regexp "^" 136(defvar comint-prompt-regexp "^"
126 "Regexp to recognise prompts in the inferior process. 137 "Regexp to recognise prompts in the inferior process.
@@ -136,33 +147,129 @@ Good choices:
136 147
137This is a good thing to set in mode hooks.") 148This is a good thing to set in mode hooks.")
138 149
139(defvar comint-input-ring-size 30 150(defvar comint-delimiter-argument-list ()
151 "List of characters to recognise as separate arguments in input.
152Strings comprising a character in this list will separate the arguments
153surrounding them, and also be regarded as arguments in their own right (unlike
154whitespace). See `comint-arguments'.
155Defaults to (), the empty list.
156
157Good choices:
158 shell: \(\"|\" \"&\" \"<\" \">\" \"\(\" \")\" \";\")
159
160This is a good thing to set in mode hooks.")
161
162(defvar comint-input-autoexpand 'history
163 "*If non-nil, expand input command history references on completion.
164This mirrors the optional behaviour of the tcsh (its autoexpand and histlit).
165
166If the value is `input', then the expansion is seen on input.
167If the value is `history', then the expansion is only when inserting
168into the buffer's input ring. See also `comint-magic-space' and
169`comint-dynamic-complete'.
170
171This variable is buffer-local.")
172
173(defvar comint-input-ignoredups nil
174 "*If non-nil, don't add input matching the last on the input ring.
175This mirrors the optional behaviour of the bash.
176
177This variable is buffer-local.")
178
179(defvar comint-input-ring-file-name nil
180 "*If non-nil, name of the file to read/write input history.
181See also `comint-read-input-ring' and `comint-write-input-ring'.
182
183This variable is buffer-local, and is a good thing to set in mode hooks.")
184
185(defvar comint-scroll-to-bottom-on-input 'this
186 "*Controls whether input to interpreter causes window to scroll.
187If nil, then do not scroll. If t or `all', scroll all windows showing buffer.
188If `this', scroll only the selected window.
189
190See `comint-preinput-scroll-to-bottom'. This variable is buffer-local.")
191
192(defvar comint-scroll-to-bottom-on-output 'this
193 "*Controls whether interpreter output causes window to scroll.
194If nil, then do not scroll. If t or `all', scroll all windows showing buffer.
195If `this', scroll only the selected window.
196If `others', scroll only those that are not the selected window.
197
198See variable `comint-scroll-show-maximum-output' and function
199`comint-postoutput-scroll-to-bottom'. This variable is buffer-local.")
200
201(defvar comint-scroll-show-maximum-output t
202 "*Controls how interpreter output causes window to scroll.
203If non-nil, then show the maximum output when the window is scrolled.
204
205See variable `comint-scroll-to-bottom-on-output' and function
206`comint-postoutput-scroll-to-bottom'. This variable is buffer-local.")
207
208(defvar comint-input-ring-size 32
140 "Size of input history ring.") 209 "Size of input history ring.")
141 210
142(defvar comint-process-echoes nil 211(defvar comint-process-echoes nil
143 "*If non-nil, assume that the subprocess echoes any input. 212 "*If non-nil, assume that the subprocess echoes any input.
144If so, delete one copy of the input so that only one copy eventually 213If so, delete one copy of the input so that only one copy eventually
145appears in the buffer. 214appears in the buffer.
146 215
147This variable is buffer-local.") 216This variable is buffer-local.")
148 217
149;;; Here are the per-interpreter hooks. 218;;; Here are the per-interpreter hooks.
150(defvar comint-get-old-input (function comint-get-old-input-default) 219(defvar comint-get-old-input (function comint-get-old-input-default)
151 "Function that submits old text in comint mode. 220 "Function that returns old text in comint mode.
152This function is called when return is typed while the point is in old text. 221This function is called when return is typed while the point is in old text.
153It returns the text to be submitted as process input. The default is 222It returns the text to be submitted as process input. The default is
154`comint-get-old-input-default', which grabs the current line, and strips off 223`comint-get-old-input-default', which grabs the current line, and strips off
155leading text matching `comint-prompt-regexp'.") 224leading text matching `comint-prompt-regexp'.")
156 225
226(defvar comint-filename-prefix ""
227 "Prefix prepended to all absolute file names taken from process input.
228This is used by the completion functions, and by directory tracking in shell
229mode.")
230
231(defvar comint-after-partial-filename-command 'comint-after-partial-filename
232 "Function that returns non-nil if point is after a file name.
233By default this is `comint-after-partial-filename'.
234
235This is a good thing to set in mode hooks.")
236
237(defvar comint-dynamic-complete-filename-command
238 'comint-dynamic-complete-filename
239 "Function that dynamically completes the file name at point.
240By default this is `comint-dynamic-complete-filename', though an alternative is
241`comint-replace-by-expanded-filename'.
242
243This is a good thing to set in mode hooks.")
244
245(defvar comint-dynamic-complete-command-command
246 'comint-dynamic-complete-filename
247 "Function that dynamically completes the command at point.
248By default this is `comint-dynamic-complete-filename'.
249
250This is a good thing to set in mode hooks.")
251
252(defvar comint-get-current-command 'comint-get-old-input-default
253 "Function that returns the current command including arguments.
254By default this is `comint-get-old-input-default', meaning the whole line.
255
256This is a good thing to set in mode hooks.")
257
157(defvar comint-input-sentinel (function ignore) 258(defvar comint-input-sentinel (function ignore)
158 "Called on each input submitted to comint mode process by `comint-send-input'. 259 "Called on each input submitted to comint mode process by `comint-send-input'.
159Thus it can, for instance, track cd/pushd/popd commands issued to the csh.") 260Thus it can, for instance, track cd/pushd/popd commands issued to a shell.")
160 261
161(defvar comint-input-filter 262(defvar comint-input-filter
162 (function (lambda (str) (not (string-match "\\`\\s *\\'" str)))) 263 (function (lambda (str) (not (string-match "\\`\\s *\\'" str))))
163 "Predicate for filtering additions to input history. 264 "Predicate for filtering additions to input history.
164Only inputs answering true to this function are saved on the input 265Takes one argument, the input. If non-nil, the input may be saved on the input
165history list. Default is to save anything that isn't all whitespace") 266history list. Default is to save anything that isn't all whitespace.")
267
268(defvar comint-output-filter-hook '(comint-postoutput-scroll-to-bottom)
269 "Functions to call after output is inserted into the buffer.
270Possible function is `comint-postoutput-scroll-to-bottom'.
271
272This variable is buffer-local.")
166 273
167(defvar comint-input-sender (function comint-simple-send) 274(defvar comint-input-sender (function comint-simple-send)
168 "Function to actually send to PROCESS the STRING submitted by user. 275 "Function to actually send to PROCESS the STRING submitted by user.
@@ -172,7 +279,7 @@ massage the input string, put a different function here.
172This is called from the user command `comint-send-input'.") 279This is called from the user command `comint-send-input'.")
173 280
174(defvar comint-eol-on-send t 281(defvar comint-eol-on-send t
175 "*Non-nil means go to the end of the line before sending input to process. 282 "*Non-nil means go to the end of the line before sending input.
176See `comint-send-input'.") 283See `comint-send-input'.")
177 284
178(defvar comint-mode-hook '() 285(defvar comint-mode-hook '()
@@ -189,18 +296,23 @@ executed once when the buffer is created.")
189(defvar comint-mode-map nil) 296(defvar comint-mode-map nil)
190 297
191(defvar comint-ptyp t 298(defvar comint-ptyp t
192 "True if communications via pty; false if by pipe. Buffer local. 299 "Non-nil if communications via pty; false if by pipe. Buffer local.
193This is to work around a bug in Emacs process signalling.") 300This is to work around a bug in Emacs process signalling.")
194 301
195;;(defvar comint-last-input-match ""
196;; "Last string searched for by comint input history search, for defaulting.
197;;Buffer local variable.")
198
199(defvar comint-input-ring nil) 302(defvar comint-input-ring nil)
200(defvar comint-last-input-start) 303(defvar comint-last-input-start)
201(defvar comint-last-input-end) 304(defvar comint-last-input-end)
202(defvar comint-input-ring-index) 305(defvar comint-input-ring-index nil
306 "Index of last matched history element.")
307(defvar comint-matching-input-from-input-string ""
308 "Input previously used to match input history.")
203(put 'comint-input-ring 'permanent-local t) 309(put 'comint-input-ring 'permanent-local t)
310(put 'comint-input-ring-index 'permanent-local t)
311(put 'comint-input-autoexpand 'permanent-local t)
312(put 'comint-output-filter-hook 'permanent-local t)
313(put 'comint-scroll-to-bottom-on-input 'permanent-local t)
314(put 'comint-scroll-to-bottom-on-output 'permanent-local t)
315(put 'comint-scroll-show-maximum-output 'permanent-local t)
204(put 'comint-ptyp 'permanent-local t) 316(put 'comint-ptyp 'permanent-local t)
205 317
206(defun comint-mode () 318(defun comint-mode ()
@@ -211,60 +323,89 @@ Return not at end copies rest of line to end and sends it.
211Setting variable `comint-eol-on-send' means jump to the end of the line 323Setting variable `comint-eol-on-send' means jump to the end of the line
212before submitting new input. 324before submitting new input.
213 325
214This mode is typically customised to create Inferior Lisp mode, 326This mode is customised to create major modes such as Inferior Lisp
215Shell mode, etc. This can be done by setting the hooks 327mode, Shell mode, etc. This can be done by setting the hooks
216`comint-input-sentinel', `comint-input-filter', `comint-input-sender' and 328`comint-input-sentinel', `comint-input-filter', `comint-input-sender'
217`comint-get-old-input' to appropriate functions, and the variable 329and `comint-get-old-input' to appropriate functions, and the variable
218`comint-prompt-regexp' to the appropriate regular expression. 330`comint-prompt-regexp' to the appropriate regular expression.
219 331
220An input history is maintained of size `comint-input-ring-size', and 332An input history is maintained of size `comint-input-ring-size', and
221can be accessed with the commands \\[comint-next-input] and \\[comint-previous-input]. 333can be accessed with the commands \\[comint-next-input], \\[comint-previous-input], and \\[comint-dynamic-list-input-ring].
334Input ring history expansion can be achieved with the commands
335\\[comint-replace-by-expanded-history] or \\[comint-magic-space].
336Input ring expansion is controlled by the variable `comint-input-autoexpand',
337and addition is controlled by the variable `comint-input-ignoredups'.
338
222Commands with no default key bindings include `send-invisible', 339Commands with no default key bindings include `send-invisible',
223`comint-dynamic-complete', and `comint-list-dynamic-completions'. 340`comint-dynamic-complete', `comint-list-dynamic-completions', and
341`comint-magic-space'.
342
343Input to, and output from, the subprocess can cause the window to scroll to
344the end of the buffer. See variables `comint-output-filter-hook',
345`comint-scroll-to-bottom-on-input', and `comint-scroll-to-bottom-on-output'.
224 346
225If you accidentally suspend your process, use \\[comint-continue-subjob] 347If you accidentally suspend your process, use \\[comint-continue-subjob]
226to continue it. 348to continue it.
227 349
228\\{comint-mode-map} 350\\{comint-mode-map}
229 351
230Entry to this mode runs the hooks on comint-mode-hook" 352Entry to this mode runs the hooks on `comint-mode-hook'."
231 (interactive) 353 (interactive)
232 ;; Do not remove this. All major modes must do this. 354 ;; Do not remove this. All major modes must do this.
233 (kill-all-local-variables) 355 (kill-all-local-variables)
234 (setq major-mode 'comint-mode) 356 (setq major-mode 'comint-mode)
235 (setq mode-name "Comint") 357 (setq mode-name "Comint")
236 (setq mode-line-process '(": %s")) 358 (setq mode-line-process '(": %s"))
237 (use-local-map comint-mode-map) 359 (use-local-map comint-mode-map)
238 (make-local-variable 'comint-last-input-start) 360 (make-local-variable 'comint-last-input-start)
239 (setq comint-last-input-start (make-marker)) 361 (setq comint-last-input-start (make-marker))
240 (make-local-variable 'comint-last-input-end) 362 (make-local-variable 'comint-last-input-end)
241 (setq comint-last-input-end (make-marker)) 363 (setq comint-last-input-end (make-marker))
242;;; (make-local-variable 'comint-last-input-match) 364 (make-local-variable 'comint-last-output-start)
243;;; (setq comint-last-input-match "") 365 (setq comint-last-output-start (make-marker))
244 (make-local-variable 'comint-prompt-regexp) ; Don't set; default 366 (make-local-variable 'comint-prompt-regexp) ; Don't set; default
245 (make-local-variable 'comint-input-ring-size) ; ...to global val. 367 (make-local-variable 'comint-input-ring-size) ; ...to global val.
246 (make-local-variable 'comint-input-ring) 368 (make-local-variable 'comint-input-ring)
247 (make-local-variable 'comint-input-ring-index) 369 (make-local-variable 'comint-input-ring-file-name)
248 (setq comint-input-ring-index 0) 370 (or (and (boundp 'comint-input-ring) comint-input-ring)
249 (make-local-variable 'comint-get-old-input) 371 (setq comint-input-ring (make-ring comint-input-ring-size)))
250 (make-local-variable 'comint-input-sentinel) 372 (make-local-variable 'comint-input-ring-index)
251 (make-local-variable 'comint-input-filter) 373 (or (and (boundp 'comint-input-ring-index) comint-input-ring-index)
252 (make-local-variable 'comint-input-sender) 374 (setq comint-input-ring-index nil))
253 (make-local-variable 'comint-eol-on-send) 375 (make-local-variable 'comint-matching-input-from-input-string)
254 (make-local-variable 'comint-ptyp) 376 (make-local-variable 'comint-input-autoexpand)
255 (make-local-variable 'comint-exec-hook) 377 (make-local-variable 'comint-input-ignoredups)
256 (make-local-variable 'comint-process-echoes) 378 (make-local-variable 'comint-delimiter-argument-list)
257 (run-hooks 'comint-mode-hook) 379 (make-local-variable 'comint-after-partial-filename-command)
258 (or comint-input-ring 380 (make-local-variable 'comint-dynamic-complete-filename-command)
259 (setq comint-input-ring (make-ring comint-input-ring-size)))) 381 (make-local-variable 'comint-dynamic-complete-command-command)
382 (make-local-variable 'comint-get-current-command)
383 (make-local-variable 'comint-get-old-input)
384 (make-local-variable 'comint-input-sentinel)
385 (make-local-variable 'comint-input-filter)
386 (make-local-variable 'comint-input-sender)
387 (make-local-variable 'comint-eol-on-send)
388 (make-local-variable 'comint-scroll-to-bottom-on-input)
389 (make-local-variable 'comint-scroll-to-bottom-on-output)
390 (make-local-variable 'comint-scroll-show-maximum-output)
391 (make-local-variable 'before-change-function)
392 (setq before-change-function 'comint-preinput-scroll-to-bottom)
393 (make-local-variable 'comint-output-filter-hook)
394 (make-local-variable 'comint-ptyp)
395 (make-local-variable 'comint-exec-hook)
396 (make-local-variable 'comint-process-echoes)
397 (run-hooks 'comint-mode-hook))
260 398
261(if comint-mode-map 399(if comint-mode-map
262 nil 400 nil
401 ;; Keys:
263 (setq comint-mode-map (make-sparse-keymap)) 402 (setq comint-mode-map (make-sparse-keymap))
264 (define-key comint-mode-map "\ep" 'comint-previous-input) 403 (define-key comint-mode-map "\ep" 'comint-previous-input)
265 (define-key comint-mode-map "\en" 'comint-next-input) 404 (define-key comint-mode-map "\en" 'comint-next-input)
266 (define-key comint-mode-map "\er" 'comint-previous-matching-input) 405 (define-key comint-mode-map "\er" 'comint-previous-matching-input)
267 (define-key comint-mode-map "\es" 'comint-next-matching-input) 406 (define-key comint-mode-map "\es" 'comint-next-matching-input)
407 (define-key comint-mode-map [?\A-\M-r] 'comint-previous-matching-input-from-input)
408 (define-key comint-mode-map [?\A-\M-s] 'comint-next-matching-input-from-input)
268 (define-key comint-mode-map "\C-m" 'comint-send-input) 409 (define-key comint-mode-map "\C-m" 'comint-send-input)
269 (define-key comint-mode-map "\C-d" 'comint-delchar-or-maybe-eof) 410 (define-key comint-mode-map "\C-d" 'comint-delchar-or-maybe-eof)
270 (define-key comint-mode-map "\C-a" 'comint-bol) 411 (define-key comint-mode-map "\C-a" 'comint-bol)
@@ -273,15 +414,91 @@ Entry to this mode runs the hooks on comint-mode-hook"
273 (define-key comint-mode-map "\C-c\C-c" 'comint-interrupt-subjob) 414 (define-key comint-mode-map "\C-c\C-c" 'comint-interrupt-subjob)
274 (define-key comint-mode-map "\C-c\C-z" 'comint-stop-subjob) 415 (define-key comint-mode-map "\C-c\C-z" 'comint-stop-subjob)
275 (define-key comint-mode-map "\C-c\C-\\" 'comint-quit-subjob) 416 (define-key comint-mode-map "\C-c\C-\\" 'comint-quit-subjob)
417 ;; " ; Stops emacs-19.19's hilit getting confused.
418 (define-key comint-mode-map "\C-c\C-m" 'comint-copy-old-input)
276 (define-key comint-mode-map "\C-c\C-o" 'comint-kill-output) 419 (define-key comint-mode-map "\C-c\C-o" 'comint-kill-output)
277 (define-key comint-mode-map "\C-c\C-r" 'comint-show-output) 420 (define-key comint-mode-map "\C-c\C-r" 'comint-show-output)
278 ;;; prompt-search commands commented out 3/90 -Olin 421 (define-key comint-mode-map "\C-c\C-e" 'comint-show-maximum-output)
279; (define-key comint-mode-map "\eP" 'comint-msearch-input) 422 (define-key comint-mode-map "\C-c\C-h" 'comint-dynamic-list-input-ring)
280; (define-key comint-mode-map "\eN" 'comint-psearch-input)
281; (define-key comint-mode-map "\C-cR" 'comint-msearch-input-matching)
282 (define-key comint-mode-map "\C-c\C-n" 'comint-next-prompt) 423 (define-key comint-mode-map "\C-c\C-n" 'comint-next-prompt)
283 (define-key comint-mode-map "\C-c\C-p" 'comint-prev-prompt) 424 (define-key comint-mode-map "\C-c\C-p" 'comint-previous-prompt)
284 (define-key comint-mode-map "\C-c\C-d" 'comint-send-eof) 425 (define-key comint-mode-map "\C-c\C-d" 'comint-send-eof)
426 ;; Menu bars:
427 ;; completion:
428 (define-key comint-mode-map [menu-bar completion]
429 (cons "Completion" (make-sparse-keymap "Completion")))
430 (define-key comint-mode-map [menu-bar completion complete-expand]
431 '("Expand File Name" . comint-replace-by-expanded-filename))
432 (define-key comint-mode-map [menu-bar completion complete-listing]
433 '("File Completion Listing" . comint-dynamic-list-filename-completions))
434 (define-key comint-mode-map [menu-bar completion complete-variable]
435 '("Complete Variable Name" . comint-dynamic-complete-variable))
436 (define-key comint-mode-map [menu-bar completion complete-command]
437 '("Complete Command Name" . (lambda () (interactive)
438 (funcall
439 comint-dynamic-complete-command-command))))
440 (define-key comint-mode-map [menu-bar completion complete-file]
441 '("Complete File Name" . comint-dynamic-complete-filename))
442 (define-key comint-mode-map [menu-bar completion complete]
443 '("Complete Before Point" . comint-dynamic-complete))
444 ;; Input history:
445 (define-key comint-mode-map [menu-bar input]
446 (cons "Input" (make-sparse-keymap "Input")))
447 (define-key comint-mode-map [menu-bar input kill-input]
448 '("Kill Current Input" . comint-kill-input))
449 (define-key comint-mode-map [menu-bar input copy-input]
450 '("Copy Old Input" . comint-copy-old-input))
451 (define-key comint-mode-map [menu-bar input next-matching-history]
452 '("Next Matching Input..." . comint-next-matching-input))
453 (define-key comint-mode-map [menu-bar input previous-matching-history]
454 '("Previous Matching Input..." . comint-previous-matching-input))
455 (define-key comint-mode-map [menu-bar input next-matching-history-from-input]
456 '("Next Matching Current Input" . comint-next-matching-input-from-input))
457 (define-key comint-mode-map [menu-bar input previous-matching-history-from-input]
458 '("Previous Matching Current Input" . comint-previous-matching-input-from-input))
459 (define-key comint-mode-map [menu-bar input next-history]
460 '("Next Input" . comint-next-input))
461 (define-key comint-mode-map [menu-bar input previous-history]
462 '("Previous Input" . comint-previous-input))
463 (define-key comint-mode-map [menu-bar input list-history]
464 '("List Input History" . comint-dynamic-list-input-ring))
465 (define-key comint-mode-map [menu-bar input expand-history]
466 '("Expand History Before Point" . comint-replace-by-expanded-history))
467 ;; Output:
468 (define-key comint-mode-map [menu-bar output]
469 (cons "Output" (make-sparse-keymap "Output")))
470 (define-key comint-mode-map [menu-bar output kill-output]
471 '("Kill Current Output Group" . comint-kill-output))
472 (define-key comint-mode-map [menu-bar input forward-matching-history]
473 '("Forward Matching Input..." . comint-forward-matching-input))
474 (define-key comint-mode-map [menu-bar input backward-matching-history]
475 '("Backward Matching Input..." . comint-backward-matching-input))
476 (define-key comint-mode-map [menu-bar output next-prompt]
477 '("Forward Output Group" . comint-next-prompt))
478 (define-key comint-mode-map [menu-bar output previous-prompt]
479 '("Backward Output Group" . comint-previous-prompt))
480 (define-key comint-mode-map [menu-bar output show-maximum-output]
481 '("Show Maximum Output" . comint-show-maximum-output))
482 (define-key comint-mode-map [menu-bar output show-output]
483 '("Show Current Output Group" . comint-show-output))
484 ;; Signals
485 (define-key comint-mode-map [menu-bar signals]
486 (cons "Signals" (make-sparse-keymap "Signals")))
487 (define-key comint-mode-map [menu-bar signals eof]
488 '("EOF" . comint-send-eof))
489 (define-key comint-mode-map [menu-bar signals kill]
490 '("KILL" . comint-kill-subjob))
491 (define-key comint-mode-map [menu-bar signals quit]
492 '("QUIT" . comint-quit-subjob))
493 (define-key comint-mode-map [menu-bar signals cont]
494 '("CONT" . comint-continue-subjob))
495 (define-key comint-mode-map [menu-bar signals stop]
496 '("STOP" . comint-stop-subjob))
497 (define-key comint-mode-map [menu-bar signals break]
498 '("BREAK" . comint-interrupt-subjob))
499 ;; Put them in the menu bar:
500 (setq menu-bar-final-items (append '(completion input output signals)
501 menu-bar-final-items))
285 ) 502 )
286 503
287 504
@@ -296,7 +513,7 @@ Entry to this mode runs the hooks on comint-mode-hook"
296 (t km))) 513 (t km)))
297 514
298(defun comint-check-proc (buffer) 515(defun comint-check-proc (buffer)
299 "True if there is a living process associated w/buffer BUFFER. 516 "Return t if there is a living process associated w/buffer BUFFER.
300Living means the status is `run' or `stop'. 517Living means the status is `run' or `stop'.
301BUFFER can be either a buffer or the name of one." 518BUFFER can be either a buffer or the name of one."
302 (let ((proc (get-buffer-process buffer))) 519 (let ((proc (get-buffer-process buffer)))
@@ -332,7 +549,7 @@ buffer. The hook `comint-exec-hook' is run after each exec."
332 (if proc (delete-process proc))) 549 (if proc (delete-process proc)))
333 ;; Crank up a new process 550 ;; Crank up a new process
334 (let ((proc (comint-exec-1 name buffer command switches))) 551 (let ((proc (comint-exec-1 name buffer command switches)))
335 (set-process-filter proc 'comint-filter) 552 (set-process-filter proc 'comint-output-filter)
336 (make-local-variable 'comint-ptyp) 553 (make-local-variable 'comint-ptyp)
337 (setq comint-ptyp process-connection-type) ; T if pty, NIL if pipe. 554 (setq comint-ptyp process-connection-type) ; T if pty, NIL if pipe.
338 ;; Jump to the end, and set the process mark. 555 ;; Jump to the end, and set the process mark.
@@ -358,238 +575,452 @@ buffer. The hook `comint-exec-hook' is run after each exec."
358;;; the appropriate environment. 575;;; the appropriate environment.
359 576
360(defun comint-exec-1 (name buffer command switches) 577(defun comint-exec-1 (name buffer command switches)
361 (let ((process-environment 578 (let ((process-environment process-environment))
362 (comint-update-env process-environment 579 (setenv "TERMCAP" (format "emacs:co#%d:tc=unknown" (frame-width)))
363 (list (format "TERMCAP=emacs:co#%d:tc=unknown" 580 (setenv "TERM" "emacs")
364 (frame-width)) 581 (setenv "EMACS" "t")
365 "TERM=emacs"
366 "EMACS=t"))))
367 (apply 'start-process name buffer command switches))) 582 (apply 'start-process name buffer command switches)))
368
369
370
371;; This is just (append new old-env) that compresses out shadowed entries.
372;; It's also pretty ugly, mostly due to lisp's horrible iteration structures.
373(defun comint-update-env (old-env new)
374 (let ((ans (reverse new))
375 (vars (mapcar (function (lambda (vv)
376 (and (string-match "^[^=]*=" vv)
377 (substring vv 0 (match-end 0)))))
378 new)))
379 (while old-env
380 (let* ((vv (car old-env)) ; vv is var=value
381 (var (and (string-match "^[^=]*=" vv)
382 (substring vv 0 (match-end 0)))))
383 (setq old-env (cdr old-env))
384 (cond ((not (and var (member var vars)))
385 (if var (setq var (cons var vars)))
386 (setq ans (cons vv ans))))))
387 (nreverse ans)))
388
389 583
390;;; Input history retrieval commands 584;;; Input history processing in a buffer
391;;; M-p -- previous input M-n -- next input
392;;; M-C-r -- previous input matching
393;;; =========================================================================== 585;;; ===========================================================================
586;;; Useful input history functions, courtesy of the Ergo group.
587
588;;; Eleven commands:
589;;; comint-dynamic-list-input-ring List history in help buffer.
590;;; comint-previous-input Previous input...
591;;; comint-previous-matching-input ...matching a string.
592;;; comint-previous-matching-input-from-input ... matching the current input.
593;;; comint-next-input Next input...
594;;; comint-next-matching-input ...matching a string.
595;;; comint-next-matching-input-from-input ... matching the current input.
596;;; comint-backward-matching-input Backwards input...
597;;; comint-forward-matching-input ...matching a string.
598;;; comint-replace-by-expanded-history Expand history at point;
599;;; replace with expanded history.
600;;; comint-magic-space Expand history and insert space.
601;;;
602;;; Two functions:
603;;; comint-read-input-ring Read into comint-input-ring...
604;;; comint-write-input-ring Write to comint-input-ring-file-name.
605
606(defun comint-read-input-ring ()
607 "Sets the buffer's `comint-input-ring' from a history file.
608The name of the file is given by the variable `comint-input-ring-file-name'.
609The history ring is of size `comint-input-ring-size', regardless of file size.
610If `comint-input-ring-file-name' is nil this function does nothing.
611
612Useful within mode or mode hooks.
613
614The structure of the history file should be one input command per line, and
615most recent command last.
616See also `comint-input-ignoredups' and `comint-write-input-ring'."
617 (cond ((null comint-input-ring-file-name)
618 nil)
619 ((not (file-readable-p comint-input-ring-file-name))
620 (message "Cannot read history file %s" comint-input-ring-file-name))
621 (t
622 (let ((history-buf (get-file-buffer comint-input-ring-file-name))
623 (ring (make-ring comint-input-ring-size)))
624 (save-excursion
625 (set-buffer (or history-buf
626 (find-file-noselect comint-input-ring-file-name)))
627 ;; Save restriction in case file is already visited...
628 ;; Watch for those date stamps in history files!
629 (save-excursion
630 (save-restriction
631 (widen)
632 (goto-char (point-min))
633 (while (re-search-forward "^\\s *\\([^#].*\\)\\s *$" nil t)
634 (let ((history (buffer-substring (match-beginning 1)
635 (match-end 1))))
636 (if (or (null comint-input-ignoredups)
637 (ring-empty-p ring)
638 (not (string-equal (ring-ref ring 0) history)))
639 (ring-insert ring history)))))
640 ;; Kill buffer unless already visited.
641 (if (null history-buf)
642 (kill-buffer nil))))
643 (setq comint-input-ring ring
644 comint-input-ring-index nil)))))
645
646(defun comint-write-input-ring ()
647 "Writes the buffer's `comint-input-ring' to a history file.
648The name of the file is given by the variable `comint-input-ring-file-name'.
649The original contents of the file are lost if `comint-input-ring' is not empty.
650If `comint-input-ring-file-name' is nil this function does nothing.
651
652Useful within process sentinels.
653
654See also `comint-read-input-ring'."
655 (cond ((or (null comint-input-ring-file-name)
656 (null comint-input-ring) (ring-empty-p comint-input-ring))
657 nil)
658 ((not (file-writable-p comint-input-ring-file-name))
659 (message "Cannot write history file %s" comint-input-ring-file-name))
660 (t
661 (let* ((history-buf (get-buffer-create " *Temp Input History*"))
662 (ring comint-input-ring)
663 (file comint-input-ring-file-name)
664 (index (ring-length ring)))
665 ;; Write it all out into a buffer first. Much faster, but messier,
666 ;; than writing it one line at a time.
667 (save-excursion
668 (set-buffer history-buf)
669 (erase-buffer)
670 (while (> index 0)
671 (setq index (1- index))
672 (insert (ring-ref ring index) ?\n))
673 (write-region (buffer-string) nil file nil 'no-message)
674 (kill-buffer nil))))))
675
676
677(defun comint-dynamic-list-input-ring ()
678 "List in help buffer the buffer's input history."
679 (interactive)
680 (if (or (not (ring-p comint-input-ring))
681 (ring-empty-p comint-input-ring))
682 (message "No history")
683 (let ((history nil)
684 (history-buffer " *Input History*")
685 (index (1- (ring-length comint-input-ring)))
686 (conf (current-window-configuration)))
687 ;; We have to build up a list ourselves from the ring vector.
688 (while (>= index 0)
689 (setq history (cons (ring-ref comint-input-ring index) history)
690 index (1- index)))
691 ;; Change "completion" to "history reference"
692 ;; to make the display accurate.
693 (with-output-to-temp-buffer history-buffer
694 (display-completion-list history)
695 (set-buffer history-buffer)
696 (forward-line 3)
697 (while (search-backward "completion" nil 'move)
698 (replace-match "history reference")))
699 (sit-for 0)
700 (message "Hit space to flush")
701 (let ((ch (read-event)))
702 (if (eq ch ?\ )
703 (set-window-configuration conf)
704 (setq unread-command-events (list ch)))))))
705
706
707(defun comint-regexp-arg (prompt)
708 ;; Return list of regexp and prefix arg using PROMPT.
709 (let* ((minibuffer-history-sexp-flag nil)
710 ;; Don't clobber this.
711 (last-command last-command)
712 (regexp (read-from-minibuffer prompt nil nil nil
713 'minibuffer-history-search-history)))
714 (list (if (string-equal regexp "")
715 (setcar minibuffer-history-search-history
716 (nth 1 minibuffer-history-search-history))
717 regexp)
718 (prefix-numeric-value current-prefix-arg))))
719
720(defun comint-search-arg (arg)
721 ;; First make sure there is a ring and that we are after the process mark
722 (cond ((not (comint-after-pmark-p))
723 (error "Not at command line"))
724 ((or (null comint-input-ring)
725 (ring-empty-p comint-input-ring))
726 (error "Empty input ring"))
727 ((zerop arg)
728 ;; arg of zero resets search from beginning, and uses arg of 1
729 (setq comint-input-ring-index nil)
730 1)
731 (t
732 arg)))
733
734(defun comint-search-start (arg)
735 ;; Index to start a directional search, starting at comint-input-ring-index
736 (if comint-input-ring-index
737 ;; If a search is running, offset by 1 in direction of arg
738 (mod (+ comint-input-ring-index (if (> arg 0) 1 -1))
739 (ring-length comint-input-ring))
740 ;; For a new search, start from beginning or end, as appropriate
741 (if (>= arg 0)
742 0 ; First elt for forward search
743 (1- (ring-length comint-input-ring))))) ; Last elt for backward search
744
745(defun comint-previous-input-string (arg)
746 "Return the string ARG places along the input ring.
747Moves relative to `comint-input-ring-index'."
748 (ring-ref comint-input-ring (if comint-input-ring-index
749 (mod (+ arg comint-input-ring-index)
750 (ring-length comint-input-ring))
751 arg)))
394 752
395(defun comint-previous-input (arg) 753(defun comint-previous-input (arg)
396 "Cycle backwards through input history." 754 "Cycle backwards through input history."
397 (interactive "*p") 755 (interactive "*p")
398 (let ((len (ring-length comint-input-ring))) 756 (comint-previous-matching-input "." arg))
399 (cond ((<= len 0)
400 (message "Empty input ring")
401 (ding))
402 ((not (comint-after-pmark-p))
403 (message "Not after process mark")
404 (ding))
405 (t
406 (delete-region (point)
407 (process-mark (get-buffer-process (current-buffer))))
408 ;; Initialize the index on the first use of this command
409 ;; so that the first M-p gets index 0, and the first M-n gets
410 ;; index -1.
411 (if (null comint-input-ring-index)
412 (setq comint-input-ring-index
413 (if (> arg 0) -1
414 (if (< arg 0) 1 0))))
415 (setq comint-input-ring-index
416 (mod (+ comint-input-ring-index arg) len))
417 (message "%d" (1+ comint-input-ring-index))
418 (insert (ring-ref comint-input-ring comint-input-ring-index))))))
419 757
420(defun comint-next-input (arg) 758(defun comint-next-input (arg)
421 "Cycle forwards through input history." 759 "Cycle forwards through input history."
422 (interactive "*p") 760 (interactive "*p")
423 (comint-previous-input (- arg))) 761 (comint-previous-input (- arg)))
424 762
763(defun comint-previous-matching-input-string (regexp arg)
764 "Return the string matching REGEXP ARG places along the input ring.
765Moves relative to `comint-input-ring-index'."
766 (let* ((pos (comint-previous-matching-input-string-position regexp arg)))
767 (if pos (ring-ref comint-input-ring pos))))
768
769(defun comint-previous-matching-input-string-position (regexp arg &optional start)
770 "Return the index matching REGEXP ARG places along the input ring.
771Moves relative to START, or `comint-input-ring-index'."
772 (if (or (not (ring-p comint-input-ring))
773 (ring-empty-p comint-input-ring))
774 (error "No history"))
775 (let* ((len (ring-length comint-input-ring))
776 (motion (if (> arg 0) 1 -1))
777 (n (mod (- (or start (comint-search-start arg)) motion) len))
778 (tried-each-ring-item nil)
779 (prev nil))
780 ;; Do the whole search as many times as the argument says.
781 (while (and (/= arg 0) (not tried-each-ring-item))
782 ;; Step once.
783 (setq prev n
784 n (mod (+ n motion) len))
785 ;; If we haven't reached a match, step some more.
786 (while (and (< n len) (not tried-each-ring-item)
787 (not (string-match regexp (ring-ref comint-input-ring n))))
788 (setq n (mod (+ n motion) len)
789 ;; If we have gone all the way around in this search.
790 tried-each-ring-item (= n prev)))
791 (setq arg (if (> arg 0) (1- arg) (1+ arg))))
792 ;; Now that we know which ring element to use, if we found it, return that.
793 (if (string-match regexp (ring-ref comint-input-ring n))
794 n)))
795
425(defun comint-previous-matching-input (regexp arg) 796(defun comint-previous-matching-input (regexp arg)
426 "Search backwards through input history for match for REGEXP. 797 "Search backwards through input history for match for REGEXP.
427\(Previous history elements are earlier commands.) 798\(Previous history elements are earlier commands.)
428With prefix argument N, search for Nth previous match. 799With prefix argument N, search for Nth previous match.
429If N is negative, find the next or Nth next match." 800If N is negative, find the next or Nth next match."
430 (interactive 801 (interactive (comint-regexp-arg "Previous input matching (regexp): "))
431 (let* ((minibuffer-history-sexp-flag nil) 802 (setq arg (comint-search-arg arg))
432 ;; Don't clobber this. 803 (let ((pos (comint-previous-matching-input-string-position regexp arg)))
433 (last-command last-command) 804 ;; Has a match been found?
434 (regexp (read-from-minibuffer "Previous input matching (regexp): " 805 (if (null pos)
435 nil 806 (error "Not found")
436 minibuffer-local-map 807 (setq comint-input-ring-index pos)
437 nil 808 (message "History item: %d" (1+ pos))
438 'minibuffer-history-search-history))) 809 (delete-region
439 (list (if (string= regexp "") 810 ;; Can't use kill-region as it sets this-command
440 (setcar minibuffer-history-search-history 811 (process-mark (get-buffer-process (current-buffer))) (point))
441 (nth 1 minibuffer-history-search-history)) 812 (insert (ring-ref comint-input-ring pos)))))
442 regexp)
443 (prefix-numeric-value current-prefix-arg))))
444 (if (null comint-input-ring-index)
445 (setq comint-input-ring-index -1))
446 (let* ((len (ring-length comint-input-ring))
447 (motion (if (> arg 0) 1 -1))
448 (n comint-input-ring-index))
449 ;; Do the whole search as many times as the argument says.
450 (while (/= arg 0)
451 (let ((prev n))
452 ;; Step once.
453 (setq n (mod (+ n motion) len))
454 ;; If we haven't reached a match, step some more.
455 (while (and (< n len)
456 (not (string-match regexp (ring-ref comint-input-ring n))))
457 (setq n (mod (+ n motion) len))
458 ;; If we have gone all the way around in this search, error.
459 (if (= n prev)
460 (error "Not found"))))
461 (setq arg (if (> arg 0) (1- arg) (1+ arg))))
462 ;; Now that we know which ring element to use,
463 ;; substitute that for the current input.
464 (comint-previous-input (- n comint-input-ring-index))))
465 813
466(defun comint-next-matching-input (regexp arg) 814(defun comint-next-matching-input (regexp arg)
467 "Search forwards through input history for match for REGEXP. 815 "Search forwards through input history for match for REGEXP.
468\(Later history elements are more recent commands.) 816\(Later history elements are more recent commands.)
469With prefix argument N, search for Nth following match. 817With prefix argument N, search for Nth following match.
470If N is negative, find the previous or Nth previous match." 818If N is negative, find the previous or Nth previous match."
471 (interactive 819 (interactive (comint-regexp-arg "Next input matching (regexp): "))
472 (let ((minibuffer-history-sexp-flag nil)
473 ;; Don't clobber this.
474 (last-command last-command)
475 (regexp (read-from-minibuffer "Previous input matching (regexp): "
476 nil
477 minibuffer-local-map
478 nil
479 'minibuffer-history-search-history)))
480 (list (if (string= regexp "")
481 (setcar minibuffer-history-search-history
482 (nth 1 minibuffer-history-search-history))
483 regexp)
484 (prefix-numeric-value current-prefix-arg))))
485 (comint-previous-matching-input regexp (- arg))) 820 (comint-previous-matching-input regexp (- arg)))
486
487;;; These next three commands are alternatives to the input history commands
488;;; They search through the process buffer
489;;; text looking for occurrences of the prompt. Bound to M-P, M-N, and C-c R
490;;; (uppercase P, N, and R) for now. Try'em out. Go with what you like...
491
492;;; comint-msearch-input-matching prompts for a string, not a regexp.
493;;; This could be considered to be the wrong thing. I decided to keep it
494;;; simple, and not make the user worry about regexps. This, of course,
495;;; limits functionality.
496
497;;; These commands were deemed non-winning and have been commented out.
498;;; Feel free to re-enable them if you like. -Olin 3/91
499
500;(defun comint-psearch-input ()
501; "Search forwards for next occurrence of prompt and skip to end of line.
502;\(prompt is anything matching regexp comint-prompt-regexp)"
503; (interactive)
504; (if (re-search-forward comint-prompt-regexp (point-max) t)
505; (end-of-line)
506; (error "No occurrence of prompt found")))
507;
508;(defun comint-msearch-input ()
509; "Search backwards for previous occurrence of prompt and skip to end of line.
510;Search starts from beginning of current line."
511; (interactive)
512; (let ((p (save-excursion
513; (beginning-of-line)
514; (cond ((re-search-backward comint-prompt-regexp (point-min) t)
515; (end-of-line)
516; (point))
517; (t nil)))))
518; (if p (goto-char p)
519; (error "No occurrence of prompt found"))))
520;
521;(defun comint-msearch-input-matching (str)
522; "Search backwards for occurrence of prompt followed by STRING.
523;STRING is prompted for, and is NOT a regular expression."
524; (interactive (let ((s (read-from-minibuffer
525; (format "Command (default %s): "
526; comint-last-input-match))))
527; (list (if (string= s "") comint-last-input-match s))))
528;; (interactive "sCommand: ")
529; (setq comint-last-input-match str) ; update default
530; (let* ((r (concat comint-prompt-regexp (regexp-quote str)))
531; (p (save-excursion
532; (beginning-of-line)
533; (cond ((re-search-backward r (point-min) t)
534; (end-of-line)
535; (point))
536; (t nil)))))
537; (if p (goto-char p)
538; (error "No match"))))
539 821
822(defun comint-previous-matching-input-from-input (arg)
823 "Search backwards through input history for match for current input.
824\(Previous history elements are earlier commands.)
825With prefix argument N, search for Nth previous match.
826If N is negative, find the next or Nth next match."
827 (interactive "p")
828 (if (not (memq last-command '(comint-previous-matching-input-from-input
829 comint-next-matching-input-from-input)))
830 ;; Starting a new search
831 (setq comint-matching-input-from-input-string
832 (buffer-substring
833 (process-mark (get-buffer-process (current-buffer)))
834 (point))
835 comint-input-ring-index nil))
836 (comint-previous-matching-input
837 (concat "^" (regexp-quote comint-matching-input-from-input-string))
838 arg))
839
840(defun comint-next-matching-input-from-input (arg)
841 "Search forwards through input history for match for current input.
842\(Previous history elements are earlier commands.)
843With prefix argument N, search for Nth previous match.
844If N is negative, find the next or Nth next match."
845 (interactive "p")
846 (comint-previous-matching-input-from-input (- arg)))
847
848
849(defun comint-replace-by-expanded-history ()
850 "Expand input command history references before point.
851This function depends on the buffer's idea of the input history, which may not
852match the command interpreter's idea, assuming it has one.
853
854Assumes history syntax is like typical Un*x shells'. However, since emacs
855cannot know the interpreter's idea of input line numbers, assuming it has one,
856it cannot expand absolute input line number references.
857
858See also `comint-magic-space'."
859 (interactive)
860 (save-excursion
861 (let ((toend (- (save-excursion (end-of-line nil) (point)) (point)))
862 (start (progn (comint-bol nil) (point))))
863 (while (re-search-forward
864 "[!^]" (save-excursion (end-of-line nil) (- (point) toend)) t)
865 ;; This seems a bit complex. We look for references such as !!, !-num,
866 ;; !foo, !?foo, !{bar}, !?{bar}, ^oh, ^my^, ^god^it, ^never^ends^.
867 ;; If that wasn't enough, the plings can be suffixed with argument
868 ;; range specifiers.
869 ;; Argument ranges are complex too, so we hive off the input line,
870 ;; referenced with plings, with the range string to `comint-args'.
871 (setq comint-input-ring-index nil)
872 (goto-char (match-beginning 0))
873 (cond ((or (= (preceding-char) ?\\)
874 (comint-within-quotes start (point)))
875 ;; The history is quoted, or we're in quotes.
876 (goto-char (match-end 0)))
877 ((looking-at "![0-9]+\\($\\|[^-]\\)")
878 ;; We cannot know the interpreter's idea of input line numbers.
879 (goto-char (match-end 0))
880 (message "Absolute reference cannot be expanded"))
881 ((looking-at "!-\\([0-9]+\\)\\(:?[0-9^$*-]+\\)?")
882 ;; Just a number of args from `number' lines backward.
883 (let ((number (1- (string-to-number
884 (buffer-substring (match-beginning 1)
885 (match-end 1))))))
886 (if (<= number (ring-length comint-input-ring))
887 (progn
888 (replace-match
889 (comint-args (comint-previous-input-string number)
890 (match-beginning 2) (match-end 2)) t t)
891 (setq comint-input-ring-index number)
892 (message "History item: %d" (1+ number)))
893 (goto-char (match-end 0))
894 (message "Relative reference exceeds input history size"))))
895 ((or (looking-at "!!?:?\\([0-9^$*-]+\\)") (looking-at "!!"))
896 ;; Just a number of args from the previous input line.
897 (replace-match
898 (comint-args (comint-previous-input-string 0)
899 (match-beginning 1) (match-end 1)) t t))
900 ((looking-at
901 "!\\??\\({\\(.+\\)}\\|\\(\\sw+\\)\\)\\(:?[0-9^$*-]+\\)?")
902 ;; Most recent input starting with or containing (possibly
903 ;; protected) string, maybe just a number of args. Phew.
904 (let* ((mb1 (match-beginning 1)) (me1 (match-end 1))
905 (mb2 (match-beginning 2)) (me2 (match-end 2))
906 (exp (buffer-substring (or mb2 mb1) (or me2 me1)))
907 (pref (if (save-match-data (looking-at "!\\?")) "" "^"))
908 (pos (save-match-data
909 (comint-previous-matching-input-string-position
910 (concat pref (regexp-quote exp)) 1))))
911 (if (null pos)
912 (progn (message "Not found")
913 (goto-char (match-end 0))
914 (ding))
915 (setq comint-input-ring-index pos)
916 (message "History item: %d" (1+ pos))
917 (replace-match
918 (comint-args (ring-ref comint-input-ring pos)
919 (match-beginning 4) (match-end 4))
920 t t))))
921 ((looking-at "\\^\\([^^]+\\)\\^?\\([^^]*\\)\\^?")
922 ;; Quick substitution on the previous input line.
923 (let ((old (buffer-substring (match-beginning 1) (match-end 1)))
924 (new (buffer-substring (match-beginning 2) (match-end 2)))
925 (pos nil))
926 (replace-match (comint-previous-input-string 0) t t)
927 (setq pos (point))
928 (goto-char (match-beginning 0))
929 (if (search-forward old pos t)
930 (replace-match new t t)
931 (message "Not found")
932 (ding))))
933 (t
934 (goto-char (match-end 0))))))))
935
936
937(defun comint-magic-space (arg)
938 "Expand input history references before point and insert ARG spaces.
939A useful command to bind to SPC. See `comint-replace-by-expanded-history'."
940 (interactive "p")
941 (comint-replace-by-expanded-history)
942 (self-insert-command arg))
943
944(defun comint-within-quotes (beg end)
945 "Return t if the number of quotes between BEG and END is odd.
946Quotes are single and double."
947 (let ((countsq (comint-how-many-region "\\(^\\|[^\\\\]\\)\'" beg end))
948 (countdq (comint-how-many-region "\\(^\\|[^\\\\]\\)\"" beg end)))
949 (or (= (mod countsq 2) 1) (= (mod countdq 2) 1))))
950
951(defun comint-how-many-region (regexp beg end)
952 "Return number of matches for REGEXP from BEG to END."
953 (let ((count 0))
954 (save-excursion
955 (save-match-data
956 (goto-char beg)
957 (while (re-search-forward regexp end t)
958 (setq count (1+ count)))))
959 count))
960
961(defun comint-args (string begin end)
962 ;; From STRING, return the args depending on the range specified in the text
963 ;; from BEGIN to END. If BEGIN is nil, assume all args. Ignore leading `:'.
964 ;; Range can be x-y, x-, -y, where x/y can be [0-9], *, ^, $.
965 (save-match-data
966 (if (null begin)
967 (comint-arguments string 0 nil)
968 (let* ((range (buffer-substring
969 (if (eq (char-after begin) ?:) (1+ begin) begin) end))
970 (nth (cond ((string-match "^[*^]" range) 1)
971 ((string-match "^-" range) 0)
972 ((string-equal range "$") nil)
973 (t (string-to-number range))))
974 (mth (cond ((string-match "[-*$]$" range) nil)
975 ((string-match "-" range)
976 (string-to-number (substring range (match-end 0))))
977 (t nth))))
978 (comint-arguments string nth mth)))))
979
980(defun comint-delim-arg (arg)
981 ;; Return a list of arguments from ARG. If there's a quote in there, just
982 ;; a list of the arg, otherwise try and break up using characters in
983 ;; comint-delimiter-argument-list. Returned list is backwards.
984 (if (or (null comint-delimiter-argument-list)
985 (string-match "[\"\'\`]" arg))
986 (list arg)
987 (let ((not-delim (format "[^%s]+" (mapconcat
988 (function (lambda (d) (regexp-quote d)))
989 comint-delimiter-argument-list "")))
990 (delim-str (mapconcat (function (lambda (d)
991 (concat (regexp-quote d) "+")))
992 comint-delimiter-argument-list "\\|"))
993 (args ()) (pos 0))
994 (while (or (eq pos (string-match not-delim arg pos))
995 (eq pos (string-match delim-str arg pos)))
996 (setq pos (match-end 0)
997 args (cons (substring arg (match-beginning 0) pos) args)))
998 args)))
999
1000(defun comint-arguments (string nth mth)
1001 "Return from STRING the NTH to MTH arguments.
1002NTH and/or MTH can be nil, which means the last argument.
1003Returned arguments are separated by single spaces. Arguments are assumed to be
1004delimited by whitespace. Strings comprising characters in the variable
1005`comint-delimiter-argument-list' are treated as delimiters and arguments.
1006Argument 0 is the command name."
1007 (let ((arg "\\(\\S \\|\\(\"[^\"]*\"\\|\'[^\']*\'\\|\`[^\`]*\`\\)\\)+")
1008 (args ()) (pos 0) (str nil))
1009 ;; We build a list of all the args. Unnecessary, but more efficient, when
1010 ;; ranges of args are required, than picking out one by one and recursing.
1011 (while (string-match arg string pos)
1012 (setq pos (match-end 0)
1013 str (substring string (match-beginning 0) pos)
1014 args (nconc (comint-delim-arg str) args)))
1015 (let ((n (or nth (1- (length args))))
1016 (m (if mth (1- (- (length args) mth)) 0)))
1017 (mapconcat
1018 (function (lambda (a) a)) (nthcdr n (nreverse (nthcdr m args))) " "))))
1019
540;;; 1020;;;
541;;; Similar input -- contributed by ccm and highly winning. 1021;;; Input processing stuff
542;;;
543;;; Reenter input, removing back to the last insert point if it exists.
544;;; 1022;;;
545;;(defvar comint-last-similar-string "" 1023
546;; "The string last used in a similar string search.")
547
548;;(defun comint-previous-similar-input (arg)
549;; "Fetch the previous (older) input that matches the string typed so far.
550;;Successive repetitions find successively older matching inputs.
551;;A prefix argument serves as a repeat count; a negative argument
552;;fetches following (more recent) inputs."
553;; (interactive "p")
554;; (if (not (comint-after-pmark-p))
555;; (error "Not after process mark"))
556;; (if (null comint-input-ring-index)
557;; (setq comint-input-ring-index
558;; (if (> arg 0) -1
559;; (if (< arg 0) 1 0))))
560;; (if (not (or (eq last-command 'comint-previous-similar-input)
561;; (eq last-command 'comint-next-similar-input)))
562;; (setq comint-last-similar-string
563;; (buffer-substring
564;; (process-mark (get-buffer-process (current-buffer)))
565;; (point))))
566;; (let* ((size (length comint-last-similar-string))
567;; (len (ring-length comint-input-ring))
568;; (n (+ comint-input-ring-index arg))
569;; entry)
570;; (while (and (< n len)
571;; (or (< (length (setq entry (ring-ref comint-input-ring n))) size)
572;; (not (equal comint-last-similar-string
573;; (substring entry 0 size)))))
574;; (setq n (+ n arg)))
575;; (cond ((< n len)
576;; (setq comint-input-ring-index n)
577;; (if (or (eq last-command 'comint-previous-similar-input)
578;; (eq last-command 'comint-next-similar-input))
579;; (delete-region (mark) (point)) ; repeat
580;; (push-mark (point))) ; 1st time
581;; (insert (substring entry size)))
582;; (t (error "Not found")))
583;; (message "%d" (1+ comint-input-ring-index))))
584
585;;(defun comint-next-similar-input (arg)
586;; "Fetch the next (newer) input that matches the string typed so far.
587;;Successive repetitions find successively newer matching inputs.
588;;A prefix argument serves as a repeat count; a negative argument
589;;fetches previous (older) inputs."
590;; (interactive "p")
591;; (comint-previous-similar-input (- arg)))
592
593(defun comint-send-input () 1024(defun comint-send-input ()
594 "Send input to process. 1025 "Send input to process.
595After the process output mark, sends all text from the process mark to 1026After the process output mark, sends all text from the process mark to
@@ -600,10 +1031,11 @@ a terminal newline is also inserted into the buffer and sent to the process
600\(if it is non-nil, all text from the process mark to point is deleted, 1031\(if it is non-nil, all text from the process mark to point is deleted,
601since it is assumed the remote process will re-echo it). 1032since it is assumed the remote process will re-echo it).
602 1033
603The value of variable `comint-input-sentinel' is called on the input 1034Any history reference may be expanded depending on the value of the variable
604before sending it. The input is entered into the input history ring, 1035`comint-input-autoexpand'. The value of variable `comint-input-sentinel' is
605if the value of variable `comint-input-filter' returns non-nil when 1036called on the input before sending it. The input is entered into the input
606called on the input. 1037history ring, if the value of variable `comint-input-filter' returns non-nil
1038when called on the input.
607 1039
608If variable `comint-eol-on-send' is non-nil, then point is moved to the 1040If variable `comint-eol-on-send' is non-nil, then point is moved to the
609end of line before sending the input. 1041end of line before sending the input.
@@ -615,13 +1047,13 @@ If the interpreter is the csh,
615 initial string matching regexp comint-prompt-regexp. 1047 initial string matching regexp comint-prompt-regexp.
616 comint-input-sentinel monitors input for \"cd\", \"pushd\", and \"popd\" 1048 comint-input-sentinel monitors input for \"cd\", \"pushd\", and \"popd\"
617 commands. When it sees one, it cd's the buffer. 1049 commands. When it sees one, it cd's the buffer.
618 comint-input-filter is the default: returns T if the input isn't all white 1050 comint-input-filter is the default: returns t if the input isn't all white
619 space. 1051 space.
620 1052
621If the comint is Lucid Common Lisp, 1053If the comint is Lucid Common Lisp,
622 comint-get-old-input snarfs the sexp ending at point. 1054 comint-get-old-input snarfs the sexp ending at point.
623 comint-input-sentinel does nothing. 1055 comint-input-sentinel does nothing.
624 comint-input-filter returns NIL if the input matches input-filter-regexp, 1056 comint-input-filter returns nil if the input matches input-filter-regexp,
625 which matches (1) all whitespace (2) :a, :c, etc. 1057 which matches (1) all whitespace (2) :a, :c, etc.
626 1058
627Similarly for Soar, Scheme, etc." 1059Similarly for Soar, Scheme, etc."
@@ -630,64 +1062,155 @@ Similarly for Soar, Scheme, etc."
630 (let ((proc (get-buffer-process (current-buffer)))) 1062 (let ((proc (get-buffer-process (current-buffer))))
631 (if (not proc) (error "Current buffer has no process") 1063 (if (not proc) (error "Current buffer has no process")
632 (let* ((pmark (process-mark proc)) 1064 (let* ((pmark (process-mark proc))
633 (pmark-val (marker-position pmark)) 1065 (intxt (if (>= (point) (marker-position pmark))
634 (input (if (>= (point) pmark-val)
635 (progn (if comint-eol-on-send (end-of-line)) 1066 (progn (if comint-eol-on-send (end-of-line))
636 (buffer-substring pmark (point))) 1067 (buffer-substring pmark (point)))
637 (let ((copy (funcall comint-get-old-input))) 1068 (let ((copy (funcall comint-get-old-input)))
638 (goto-char pmark) 1069 (goto-char pmark)
639 (insert copy) 1070 (insert copy)
640 copy)))) 1071 copy)))
1072 (input (if (not (eq comint-input-autoexpand 'input))
1073 ;; Just whatever's already there
1074 intxt
1075 ;; Expand and leave it visible in buffer
1076 (comint-replace-by-expanded-history)
1077 (buffer-substring pmark (point))))
1078 (history (if (not (eq comint-input-autoexpand 'history))
1079 (comint-arguments input 0 nil)
1080 ;; This is messy 'cos ultimately the original
1081 ;; functions used do insertion, rather than return
1082 ;; strings. We have to expand, then insert back.
1083 (comint-replace-by-expanded-history)
1084 (let ((copy (buffer-substring pmark (point))))
1085 (delete-region pmark (point))
1086 (insert input)
1087 (comint-arguments copy 0 nil)))))
641 (if comint-process-echoes 1088 (if comint-process-echoes
642 (delete-region pmark (point)) 1089 (delete-region pmark (point))
643 (insert ?\n)) 1090 (insert ?\n))
644 (if (funcall comint-input-filter input) 1091 (if (and (funcall comint-input-filter history)
645 (ring-insert comint-input-ring input)) 1092 (or (null comint-input-ignoredups)
1093 (not (ring-p comint-input-ring))
1094 (ring-empty-p comint-input-ring)
1095 (not (string-equal (ring-ref comint-input-ring 0)
1096 history))))
1097 (ring-insert comint-input-ring history))
646 (funcall comint-input-sentinel input) 1098 (funcall comint-input-sentinel input)
647 (funcall comint-input-sender proc input) 1099 (funcall comint-input-sender proc input)
648 (setq comint-input-ring-index nil) 1100 (setq comint-input-ring-index nil)
649 (set-marker comint-last-input-start pmark) 1101 (set-marker comint-last-input-start pmark)
650 (set-marker comint-last-input-end (point)) 1102 (set-marker comint-last-input-end (point))
651 (set-marker (process-mark proc) (point)))))) 1103 (set-marker (process-mark proc) (point))
1104 ;; A kludge to prevent the delay between insert and process output
1105 ;; affecting the display. A case for a comint-send-input-hook?
1106 (run-hooks 'comint-output-filter-hook)))))
652 1107
653;; The sole purpose of using this filter for comint processes 1108;; The purpose of using this filter for comint processes
654;; is to keep comint-last-input-end from moving forward 1109;; is to keep comint-last-input-end from moving forward
655;; when output is inserted. 1110;; when output is inserted.
656(defun comint-filter (process string) 1111(defun comint-output-filter (process string)
657 (let ((obuf (current-buffer)) 1112 ;; First check for killed buffer
658 opoint obeg oend) 1113 (if (not (comint-check-proc (process-buffer process)))
659 (set-buffer (process-buffer process)) 1114 (message
660 (setq opoint (point)) 1115 "comint-output-filter: buffer %s received output with no process"
661 (setq obeg (point-min)) 1116 (process-buffer process))
662 (setq oend (point-max)) 1117 (let ((obuf (current-buffer))
663 (let ((buffer-read-only nil) 1118 (opoint nil) (obeg nil) (oend nil))
664 (nchars (length string))) 1119 (set-buffer (process-buffer process))
665 (widen) 1120 (setq opoint (point))
666 (goto-char (process-mark process)) 1121 (setq obeg (point-min))
667 (if (<= (point) opoint) 1122 (setq oend (point-max))
668 (setq opoint (+ opoint nchars))) 1123 (let ((buffer-read-only nil)
669 ;; Insert after old_begv, but before old_zv. 1124 (nchars (length string))
670 (if (< (point) obeg) 1125 (ostart nil))
671 (setq obeg (+ obeg nchars))) 1126 (widen)
672 (if (<= (point) oend) 1127 (goto-char (process-mark process))
673 (setq oend (+ oend nchars))) 1128 (setq ostart (point))
674 1129 (if (<= (point) opoint)
675 (insert-before-markers string) 1130 (setq opoint (+ opoint nchars)))
676 ;; Don't insert initial prompt outside the top of the window. 1131 ;; Insert after old_begv, but before old_zv.
677 (if (= (window-start (selected-window)) (point)) 1132 (if (< (point) obeg)
678 (set-window-start (selected-window) (- (point) (length string)))) 1133 (setq obeg (+ obeg nchars)))
679 1134 (if (<= (point) oend)
680 (and comint-last-input-end 1135 (setq oend (+ oend nchars)))
681 (marker-buffer comint-last-input-end) 1136 (insert-before-markers string)
682 (= (point) comint-last-input-end) 1137 ;; Don't insert initial prompt outside the top of the window.
683 (set-marker comint-last-input-end 1138 (if (= (window-start (selected-window)) (point))
684 (- comint-last-input-end nchars))) 1139 (set-window-start (selected-window) (- (point) (length string))))
685 (set-marker (process-mark process) (point) nil) 1140 (if (and comint-last-input-end
686 (force-mode-line-update)) 1141 (marker-buffer comint-last-input-end)
687 1142 (= (point) comint-last-input-end))
688 (narrow-to-region obeg oend) 1143 (set-marker comint-last-input-end (- comint-last-input-end nchars)))
689 (goto-char opoint) 1144 (set-marker comint-last-output-start ostart)
690 (set-buffer obuf))) 1145 (set-marker (process-mark process) (point))
1146 (force-mode-line-update))
1147
1148 (narrow-to-region obeg oend)
1149 (goto-char opoint)
1150 (run-hooks 'comint-output-filter-hook)
1151
1152 (set-buffer obuf))))
1153
1154(defun comint-preinput-scroll-to-bottom (beg end)
1155 "Go to the end of buffer in all windows showing it.
1156Movement occurs if point in the selected window is not after the process mark,
1157and `this-command' is an insertion command. Insertion commands recognised
1158are `self-insert-command', `yank', `mouse-yank-at-click', and `hilit-yank'.
1159Depends on the value of `comint-scroll-to-bottom-on-input'.
1160
1161This function should be bound to `before-change-function'."
1162 (if (and comint-scroll-to-bottom-on-input
1163 (memq this-command '(self-insert-command yank mouse-yank-at-click
1164 hilit-yank)))
1165 (let* ((selected (selected-window))
1166 (current (current-buffer))
1167 (process (get-buffer-process current))
1168 (scroll comint-scroll-to-bottom-on-input))
1169 (if (and process (< (point) (process-mark process))
1170 scroll (not (window-minibuffer-p selected)))
1171 (walk-windows
1172 (function (lambda (window)
1173 (if (and (eq (window-buffer window) current)
1174 (or (eq scroll t) (eq scroll 'all)
1175 (and (eq scroll 'this) (eq selected window))))
1176 (progn
1177 (select-window window)
1178 (goto-char (point-max))
1179 (select-window selected)))))
1180 'not-minibuf t)))))
1181
1182(defun comint-postoutput-scroll-to-bottom ()
1183 "Go to the end of buffer in all windows showing it.
1184Does not scroll if the current line is the last line in the buffer.
1185Depends on the value of `comint-scroll-to-bottom-on-output' and
1186`comint-scroll-show-maximum-output'.
1187
1188This function should be bound to `comint-output-filter-hook'."
1189 (let* ((selected (selected-window))
1190 (current (current-buffer))
1191 (process (get-buffer-process current))
1192 (scroll comint-scroll-to-bottom-on-output))
1193 (if (and process scroll (not (window-minibuffer-p selected)))
1194 (walk-windows
1195 (function (lambda (window)
1196 (if (and (eq (window-buffer window) current)
1197 (or (eq scroll t) (eq scroll 'all)
1198 (and (eq scroll 'this) (eq selected window))
1199 (and (eq scroll 'others) (not (eq selected window)))))
1200 (progn
1201 (select-window window)
1202 (if (not (save-excursion (end-of-line nil) (eobp)))
1203 (goto-char (process-mark process)))
1204 (if comint-scroll-show-maximum-output
1205 (recenter -1))
1206 (select-window selected)))))
1207 'not-minibuf t))))
1208
1209(defun comint-show-maximum-output ()
1210 "Put the end of the buffer at the bottom of the window."
1211 (interactive)
1212 (goto-char (point-max))
1213 (recenter -1))
691 1214
692(defun comint-get-old-input-default () 1215(defun comint-get-old-input-default ()
693 "Default for `comint-get-old-input'. 1216 "Default for `comint-get-old-input'.
@@ -700,6 +1223,17 @@ Take the current line, and discard any initial text matching
700 (end-of-line) 1223 (end-of-line)
701 (buffer-substring beg (point))))) 1224 (buffer-substring beg (point)))))
702 1225
1226(defun comint-copy-old-input ()
1227 "Insert after prompt old input at point as new input to be edited.
1228Calls `comint-get-old-input' to get old input."
1229 (interactive)
1230 (let ((input (funcall comint-get-old-input))
1231 (process (get-buffer-process (current-buffer))))
1232 (if (not process)
1233 (error "Current buffer has no process")
1234 (goto-char (process-mark process))
1235 (insert input))))
1236
703(defun comint-skip-prompt () 1237(defun comint-skip-prompt ()
704 "Skip past the text matching regexp `comint-prompt-regexp'. 1238 "Skip past the text matching regexp `comint-prompt-regexp'.
705If this takes us past the end of the current line, don't skip at all." 1239If this takes us past the end of the current line, don't skip at all."
@@ -708,16 +1242,10 @@ If this takes us past the end of the current line, don't skip at all."
708 (<= (match-end 0) eol)) 1242 (<= (match-end 0) eol))
709 (goto-char (match-end 0))))) 1243 (goto-char (match-end 0)))))
710 1244
711
712(defun comint-after-pmark-p () 1245(defun comint-after-pmark-p ()
713 "Is point after the process output marker?" 1246 "Return t if point is after the process output marker."
714 ;; Since output could come into the buffer after we looked at the point 1247 (let ((pmark (process-mark (get-buffer-process (current-buffer)))))
715 ;; but before we looked at the process marker's value, we explicitly 1248 (<= (marker-position pmark) (point))))
716 ;; serialise. This is just because I don't know whether or not emacs
717 ;; services input during execution of lisp commands.
718 (let ((proc-pos (marker-position
719 (process-mark (get-buffer-process (current-buffer))))))
720 (<= proc-pos (point))))
721 1249
722(defun comint-simple-send (proc string) 1250(defun comint-simple-send (proc string)
723 "Default function for sending to PROC input STRING. 1251 "Default function for sending to PROC input STRING.
@@ -728,8 +1256,7 @@ set the hook `comint-input-sender'."
728 1256
729(defun comint-bol (arg) 1257(defun comint-bol (arg)
730 "Goes to the beginning of line, then skips past the prompt, if any. 1258 "Goes to the beginning of line, then skips past the prompt, if any.
731If a prefix argument is given (\\[universal-argument]), then no prompt skip 1259If prefix argument is given (\\[universal-argument]) the prompt is not skipped.
732-- go straight to column 0.
733 1260
734The prompt skip is done by skipping text matching the regular expression 1261The prompt skip is done by skipping text matching the regular expression
735`comint-prompt-regexp', a buffer local variable. 1262`comint-prompt-regexp', a buffer local variable.
@@ -798,7 +1325,6 @@ Then send it to the process running in the current buffer. A new-line
798is additionally sent. String is not saved on comint input history list. 1325is additionally sent. String is not saved on comint input history list.
799Security bug: your string can still be temporarily recovered with 1326Security bug: your string can still be temporarily recovered with
800\\[view-lossage]." 1327\\[view-lossage]."
801; (interactive (list (comint-read-noecho "Enter non-echoed text")))
802 (interactive "P") ; Defeat snooping via C-x esc 1328 (interactive "P") ; Defeat snooping via C-x esc
803 (let ((proc (get-buffer-process (current-buffer)))) 1329 (let ((proc (get-buffer-process (current-buffer))))
804 (if (not proc) (error "Current buffer has no process") 1330 (if (not proc) (error "Current buffer has no process")
@@ -826,6 +1352,7 @@ from hanging when you send them long inputs on some OS's."
826 (while (< i len) 1352 (while (< i len)
827 (let ((next-i (+ i comint-input-chunk-size))) 1353 (let ((next-i (+ i comint-input-chunk-size)))
828 (accept-process-output) 1354 (accept-process-output)
1355 (sit-for 0)
829 (process-send-string proc (substring str i (min len next-i))) 1356 (process-send-string proc (substring str i (min len next-i)))
830 (setq i next-i))))) 1357 (setq i next-i)))))
831 1358
@@ -834,28 +1361,33 @@ from hanging when you send them long inputs on some OS's."
834This is a replacement for `process-send-region' that tries to keep 1361This is a replacement for `process-send-region' that tries to keep
835your process from hanging on long inputs. See `comint-send-string'." 1362your process from hanging on long inputs. See `comint-send-string'."
836 (comint-send-string proc (buffer-substring start end))) 1363 (comint-send-string proc (buffer-substring start end)))
837
838 1364
839;;; Random input hackage 1365;;; Random input hackage
840 1366
841(defun comint-kill-output () 1367(defun comint-kill-output ()
842 "Kill all output from interpreter since last input." 1368 "Kill all output from interpreter since last input.
1369Does not delete the prompt."
843 (interactive) 1370 (interactive)
844 (let ((pmark (process-mark (get-buffer-process (current-buffer))))) 1371 (let ((pmark (progn (goto-char
1372 (process-mark (get-buffer-process (current-buffer))))
1373 (beginning-of-line nil)
1374 (point-marker))))
845 (kill-region comint-last-input-end pmark) 1375 (kill-region comint-last-input-end pmark)
846 (goto-char pmark)
847 (insert "*** output flushed ***\n") 1376 (insert "*** output flushed ***\n")
1377 (comint-skip-prompt)
848 (set-marker pmark (point)))) 1378 (set-marker pmark (point))))
849 1379
850(defun comint-show-output () 1380(defun comint-show-output ()
851 "Display start of this batch of interpreter output at top of window. 1381 "Display start of this batch of interpreter output at top of window.
852Also put cursor there." 1382Also put cursor there if the current position is not visible."
853 (interactive) 1383 (interactive)
854 (goto-char comint-last-input-end) 1384 (let ((pos (point)))
855 (backward-char) 1385 (goto-char comint-last-input-end)
856 (beginning-of-line) 1386 (beginning-of-line 0)
857 (set-window-start (selected-window) (point)) 1387 (set-window-start (selected-window) (point))
858 (end-of-line)) 1388 (if (pos-visible-in-window-p pos)
1389 (goto-char pos)
1390 (comint-skip-prompt))))
859 1391
860(defun comint-interrupt-subjob () 1392(defun comint-interrupt-subjob ()
861 "Interrupt the current subjob." 1393 "Interrupt the current subjob."
@@ -890,41 +1422,62 @@ Useful if you accidentally suspend the top-level process."
890(defun comint-kill-input () 1422(defun comint-kill-input ()
891 "Kill all text from last stuff output by interpreter to point." 1423 "Kill all text from last stuff output by interpreter to point."
892 (interactive) 1424 (interactive)
893 (let* ((pmark (process-mark (get-buffer-process (current-buffer)))) 1425 (let ((pmark (process-mark (get-buffer-process (current-buffer)))))
894 (p-pos (marker-position pmark))) 1426 (if (> (point) (marker-position pmark))
895 (if (> (point) p-pos)
896 (kill-region pmark (point))))) 1427 (kill-region pmark (point)))))
897 1428
898(defun comint-delchar-or-maybe-eof (arg) 1429(defun comint-delchar-or-maybe-eof (arg)
899 "Delete ARG characters forward, or send an EOF to process if at end of buffer." 1430 "Delete ARG characters forward, or (if at eob) send an EOF to subprocess."
900 (interactive "p") 1431 (interactive "p")
901 (if (eobp) 1432 (if (eobp)
902 (process-send-eof) 1433 (process-send-eof)
903 (delete-char arg))) 1434 (delete-char arg)))
904 1435
905(defun comint-send-eof () 1436(defun comint-send-eof ()
906 "Send an EOF to the current buffer's process." 1437 "Send an EOF to the current buffer's process."
907 (interactive) 1438 (interactive)
908 (process-send-eof)) 1439 (process-send-eof))
909 1440
1441
1442(defun comint-backward-matching-input (regexp arg)
1443 "Search backward through buffer for match for REGEXP.
1444Matches are searched for on lines that match `comint-prompt-regexp'.
1445With prefix argument N, search for Nth previous match.
1446If N is negative, find the next or Nth next match."
1447 (interactive (comint-regexp-arg "Backward input matching (regexp): "))
1448 (let* ((re (concat comint-prompt-regexp ".*" regexp))
1449 (pos (save-excursion (end-of-line (if (> arg 0) 0 1))
1450 (if (re-search-backward re nil t arg)
1451 (point)))))
1452 (if (null pos)
1453 (progn (message "Not found")
1454 (ding))
1455 (goto-char pos)
1456 (comint-bol nil))))
1457
1458(defun comint-forward-matching-input (regexp arg)
1459 "Search forward through buffer for match for REGEXP.
1460Matches are searched for on lines that match `comint-prompt-regexp'.
1461With prefix argument N, search for Nth following match.
1462If N is negative, find the previous or Nth previous match."
1463 (interactive (comint-regexp-arg "Forward input matching (regexp): "))
1464 (comint-backward-matching-input regexp (- arg)))
1465
1466
910(defun comint-next-prompt (n) 1467(defun comint-next-prompt (n)
911 "\ 1468 "Move to end of Nth next prompt in the buffer.
912Move to end of next prompt in the buffer (with prefix arg, Nth next).
913See `comint-prompt-regexp'." 1469See `comint-prompt-regexp'."
914 (interactive "p") 1470 (interactive "p")
915 (re-search-forward comint-prompt-regexp nil nil n)) 1471 (let ((paragraph-start comint-prompt-regexp))
1472 (end-of-line (if (> n 0) 1 0))
1473 (forward-paragraph n)
1474 (comint-skip-prompt)))
916 1475
917(defun comint-prev-prompt (n) 1476(defun comint-previous-prompt (n)
918 "\ 1477 "Move to end of Nth previous prompt in the buffer.
919Move to end of previous prompt in the buffer (with prefix arg, Nth previous).
920See `comint-prompt-regexp'." 1478See `comint-prompt-regexp'."
921 (interactive "p") 1479 (interactive "p")
922 (if (= (save-excursion (re-search-backward comint-prompt-regexp nil t) 1480 (comint-next-prompt (- n)))
923 (match-end 0))
924 (point))
925 (setq n (1+ n)))
926 (re-search-backward comint-prompt-regexp nil nil n)
927 (goto-char (match-end 0)))
928 1481
929;;; Support for source-file processing commands. 1482;;; Support for source-file processing commands.
930;;;============================================================================ 1483;;;============================================================================
@@ -1009,8 +1562,7 @@ See `comint-prompt-regexp'."
1009 (let ((buff (get-file-buffer fname))) 1562 (let ((buff (get-file-buffer fname)))
1010 (if (and buff 1563 (if (and buff
1011 (buffer-modified-p buff) 1564 (buffer-modified-p buff)
1012 (y-or-n-p (format "Save buffer %s first? " 1565 (y-or-n-p (format "Save buffer %s first? " (buffer-name buff))))
1013 (buffer-name buff))))
1014 ;; save BUFF. 1566 ;; save BUFF.
1015 (let ((old-buffer (current-buffer))) 1567 (let ((old-buffer (current-buffer)))
1016 (set-buffer buff) 1568 (set-buffer buff)
@@ -1112,148 +1664,319 @@ See `comint-prompt-regexp'."
1112 ;; I don't know why. Wizards invited to improve it. 1664 ;; I don't know why. Wizards invited to improve it.
1113 (if (not (pos-visible-in-window-p proc-pt proc-win)) 1665 (if (not (pos-visible-in-window-p proc-pt proc-win))
1114 (let ((opoint (window-point proc-win))) 1666 (let ((opoint (window-point proc-win)))
1115 (set-window-point proc-win proc-mark) (sit-for 0) 1667 (set-window-point proc-win proc-mark)
1668 (sit-for 0)
1116 (if (not (pos-visible-in-window-p opoint proc-win)) 1669 (if (not (pos-visible-in-window-p opoint proc-win))
1117 (push-mark opoint) 1670 (push-mark opoint)
1118 (set-window-point proc-win opoint))))))) 1671 (set-window-point proc-win opoint)))))))
1119 1672
1120 1673
1121;;; Filename completion in a buffer 1674;;; Filename/command/history completion in a buffer
1122;;; =========================================================================== 1675;;; ===========================================================================
1123;;; Useful completion functions, courtesy of the Ergo group. 1676;;; Useful completion functions, courtesy of the Ergo group.
1124 1677
1125;;; Three commands: 1678;;; Six functions:
1126;;; comint-dynamic-complete Complete filename at point. 1679;;; comint-dynamic-complete Complete or expand command, filename,
1127;;; comint-dynamic-list-completions List completions in help buffer. 1680;;; history at point.
1681;;; comint-dynamic-complete-filename Complete filename at point.
1682;;; comint-dynamic-complete-variable Complete variable at point.
1683;;; comint-dynamic-list-filename-completions List completions in help buffer.
1128;;; comint-replace-by-expanded-filename Expand and complete filename at point; 1684;;; comint-replace-by-expanded-filename Expand and complete filename at point;
1129;;; replace with expanded/completed name. 1685;;; replace with expanded/completed name.
1686;;; comint-dynamic-simple-complete Complete stub given candidates.
1687
1688;;; Four hooks (defined above):
1689;;; comint-dynamic-complete-filename-command Complete file name at point.
1690;;; comint-dynamic-complete-command-command Complete command at point.
1691;;; comint-get-current-command Return command at point.
1692;;; comint-after-partial-filename-command Return non-nil if after file.
1130 1693
1131;;; These are not installed in the comint-mode keymap. But they are 1694;;; These are not installed in the comint-mode keymap. But they are
1132;;; available for people who want them. Shell-mode installs them: 1695;;; available for people who want them. Shell-mode installs them:
1133;;; (define-key shell-mode-map "\t" 'comint-dynamic-complete) 1696;;; (define-key shell-mode-map "\t" 'comint-dynamic-complete)
1134;;; (define-key shell-mode-map "\M-?" 'comint-dynamic-list-completions))) 1697;;; (define-key shell-mode-map "\M-?"
1698;;; 'comint-dynamic-list-filename-completions)))
1135;;; 1699;;;
1136;;; Commands like this are fine things to put in load hooks if you 1700;;; Commands like this are fine things to put in load hooks if you
1137;;; want them present in specific modes. 1701;;; want them present in specific modes.
1138 1702
1703(defvar comint-completion-autolist nil
1704 "*If non-nil, automatically list possiblities on partial completion.
1705This mirrors the optional behaviour of the tcsh.")
1706
1707(defvar comint-completion-addsuffix t
1708 "*If non-nil, add a `/' to completed directories, ` ' to file names.
1709This mirrors the optional behaviour of the tcsh.")
1710
1711(defvar comint-completion-recexact nil
1712 "*If non-nil, use shortest completion if characters cannot be added.
1713This mirrors the optional behaviour of the tcsh.
1714
1715A non-nil value is useful if `comint-completion-autolist' is non-nil too.")
1716
1717(defvar comint-file-name-prefix ""
1718 "Prefix prepended to absolute file names taken from process input.
1719This is used by comint's and shell's completion functions, and by shell's
1720directory tracking functions.")
1139 1721
1140(defun comint-match-partial-pathname () 1722
1141 "Return the filename at point, or signal an error." 1723(defun comint-directory (directory)
1724 ;; Return expanded DIRECTORY, with `comint-file-name-prefix' if absolute.
1725 (expand-file-name (if (file-name-absolute-p directory)
1726 (concat comint-file-name-prefix directory)
1727 directory)))
1728
1729
1730(defun comint-match-partial-filename ()
1731 "Return the filename at point, or signal an error.
1732Environment variables are substituted."
1142 (save-excursion 1733 (save-excursion
1143 (if (re-search-backward "[^~/A-Za-z0-9_.$#,=-]" nil 'move) 1734 (if (re-search-backward "[^~/A-Za-z0-9_.$#,={}()-]" nil 'move)
1144 (forward-char 1)) 1735 (forward-char 1))
1145 ;; Anchor the search forwards. 1736 ;; Anchor the search forwards.
1146 (if (not (looking-at "[~/A-Za-z0-9_.$#,=-]")) (error "")) 1737 (if (not (looking-at "[~/A-Za-z0-9_.$#,={}()-]")) (error ""))
1147 (re-search-forward "[~/A-Za-z0-9_.$#,=-]+") 1738 (re-search-forward "[~/A-Za-z0-9_.$#,={}()-]+")
1148 (substitute-in-file-name 1739 (substitute-in-file-name
1149 (buffer-substring (match-beginning 0) (match-end 0))))) 1740 (buffer-substring (match-beginning 0) (match-end 0)))))
1150 1741
1151(defvar comint-filename-prefix nil
1152 "Prefix prepended to all absolute file names taken from process input.
1153This is used by the completion functions, and by directory tracking in shell
1154mode.")
1155 1742
1156(defun comint-replace-by-expanded-filename () 1743(defun comint-match-partial-variable ()
1157 "Expand the filename at point. 1744 "Return the variable at point, or signal an error."
1158Replace the filename with an expanded, canonicalised, and completed 1745 (save-excursion
1159 replacement. 1746 (if (re-search-backward "[^A-Za-z0-9_${}]" nil 'move)
1160\"Expanded\" means environment variables (e.g., $HOME) and ~'s are 1747 (forward-char 1))
1161replaced with the corresponding directories. \"Canonicalised\" means .. 1748 ;; Anchor the search forwards.
1162and \. are removed, and the filename is made absolute instead of relative. 1749 (if (not (looking-at "\\$")) (error ""))
1163See functions `expand-file-name' and `substitute-in-file-name'. See also 1750 (re-search-forward "\\${?[A-Za-z0-9_]+}?")
1164`comint-dynamic-complete'." 1751 (buffer-substring (match-beginning 0) (match-end 0))))
1165 (interactive) 1752
1166 (let* ((pathname (comint-match-partial-pathname)) 1753
1167 (pathdir (file-name-directory pathname)) 1754(defun comint-after-partial-filename ()
1168 (pathnondir (file-name-nondirectory pathname)) 1755 "Returns t if point is after a file name.
1169 (completion (file-name-completion 1756File names are assumed to contain `/'s or not be the first item in the input.
1170 pathnondir 1757
1171 (if pathdir 1758See also `comint-bol'."
1172 ;; It is important to expand PATHDIR because 1759 (let ((filename (comint-match-partial-filename)))
1173 ;; default-directory might be a handled name, and 1760 (or (save-match-data (string-match "/" filename))
1174 ;; the unexpanded PATHDIR won't necessarily match 1761 (not (eq (match-beginning 0)
1175 ;; the handler regexp. 1762 (save-excursion (comint-bol nil) (point)))))))
1176 (expand-file-name (concat
1177 (if (file-name-absolute-p pathdir)
1178 comint-filename-prefix)
1179 pathdir))
1180 default-directory))))
1181 (cond ((null completion)
1182 (message "No completions of %s" pathname)
1183 (ding))
1184 ((eql completion t)
1185 (message "Sole completion"))
1186 (t ; this means a string was returned.
1187 (delete-region (match-beginning 0) (match-end 0))
1188 (insert (expand-file-name (concat pathdir completion)))))))
1189 1763
1190 1764
1191(defun comint-dynamic-complete () 1765(defun comint-dynamic-complete ()
1766 "Dynamically complete/expand the command/filename/history at point.
1767If the text contains (a non-absolute line reference) `!' or `^' and
1768`comint-input-autoexpand' is non-nil, then an attempt is made to complete the
1769history. The value of the variable `comint-after-partial-filename-command' is
1770used to match file names. Otherwise, an attempt is made to complete the
1771command.
1772
1773See also the variables `comint-after-partial-filename-command',
1774`comint-dynamic-complete-filename-command', and
1775`comint-dynamic-complete-command-command', and functions
1776`comint-replace-by-expanded-history' and `comint-magic-space'."
1777 (interactive)
1778 (let ((previous-modified-tick (buffer-modified-tick)))
1779 (if (and comint-input-autoexpand
1780 (string-match "[!^]" (funcall comint-get-current-command)))
1781 ;; Looks like there might be history references in the command.
1782 (comint-replace-by-expanded-history))
1783 (if (= previous-modified-tick (buffer-modified-tick))
1784 ;; No references were expanded, so maybe they were none after all.
1785 (cond ((funcall comint-after-partial-filename-command)
1786 ;; It's a file name.
1787 (funcall comint-dynamic-complete-filename-command))
1788 (t
1789 ;; Assume it's a command.
1790 (funcall comint-dynamic-complete-command-command))))))
1791
1792
1793(defun comint-dynamic-complete-filename ()
1192 "Dynamically complete the filename at point. 1794 "Dynamically complete the filename at point.
1193This function is similar to `comint-replace-by-expanded-filename', except 1795This function is similar to `comint-replace-by-expanded-filename', except that
1194that it won't change parts of the filename already entered in the buffer; 1796it won't change parts of the filename already entered in the buffer; it just
1195it just adds completion characters to the end of the filename." 1797adds completion characters to the end of the filename. A completions listing
1798may be shown in a help buffer if completion is ambiguous.
1799
1800Completion is dependent on the value of `comint-completion-addsuffix' and
1801`comint-completion-recexact', and the timing of completions listing is
1802dependent on the value of `comint-completion-autolist'."
1803 (interactive)
1804 (let* ((completion-ignore-case nil)
1805 (filename (comint-match-partial-filename))
1806 (pathdir (file-name-directory filename))
1807 (pathnondir (file-name-nondirectory filename))
1808 (directory (if pathdir (comint-directory pathdir) default-directory))
1809 (completion (file-name-completion pathnondir directory)))
1810 (cond ((null completion)
1811 (message "No completions of %s" filename)
1812 (ding))
1813 ((eq completion t) ; Means already completed "file".
1814 (if comint-completion-addsuffix (insert " "))
1815 (message "Sole completion"))
1816 ((string-equal completion "") ; Means completion on "directory/".
1817 (comint-dynamic-list-filename-completions))
1818 (t ; Completion string returned.
1819 (let ((file (concat (file-name-as-directory directory) completion)))
1820 (goto-char (match-end 0))
1821 (insert (substring (directory-file-name completion)
1822 (length pathnondir)))
1823 (cond ((symbolp (file-name-completion completion directory))
1824 ;; We inserted a unique completion.
1825 (if comint-completion-addsuffix
1826 (insert (if (file-directory-p file) "/" " ")))
1827 (message "Completed"))
1828 ((and comint-completion-recexact comint-completion-addsuffix
1829 (string-equal pathnondir completion)
1830 (file-exists-p file))
1831 ;; It's not unique, but user wants shortest match.
1832 (insert (if (file-directory-p file) "/" " "))
1833 (message "Completed shortest"))
1834 ((or comint-completion-autolist
1835 (string-equal pathnondir completion))
1836 ;; It's not unique, list possible completions.
1837 (comint-dynamic-list-filename-completions))
1838 (t
1839 (message "Partially completed"))))))))
1840
1841
1842(defun comint-replace-by-expanded-filename ()
1843 "Dynamically expand and complete the filename at point.
1844Replace the filename with an expanded, canonicalised and completed replacement.
1845\"Expanded\" means environment variables (e.g., $HOME) and `~'s are replaced
1846with the corresponding directories. \"Canonicalised\" means `..' and `.' are
1847removed, and the filename is made absolute instead of relative. For expansion
1848see `expand-file-name' and `substitute-in-file-name'. For completion see
1849`comint-dynamic-complete-filename'."
1196 (interactive) 1850 (interactive)
1197 (if (and (interactive-p) 1851 (replace-match (expand-file-name (comint-match-partial-filename)) t t)
1198 (eq last-command this-command)) 1852 (comint-dynamic-complete-filename))
1199 ;; If you hit TAB twice in a row, you get a completion list. 1853
1200 (comint-dynamic-list-completions) 1854
1201 (let* ((pathname (comint-match-partial-pathname)) 1855(defun comint-dynamic-complete-variable ()
1202 (pathdir (file-name-directory pathname)) 1856 "Dynamically complete the environment variable at point.
1203 (pathnondir (file-name-nondirectory pathname)) 1857This function is similar to `comint-dynamic-complete-filename', except that it
1204 (completion (file-name-completion 1858searches `process-environment' for completion candidates. Note that this may
1205 pathnondir 1859not be the same as the interpreter's idea of variable names. The main
1206 (if pathdir 1860problem with this type of completion is that `process-environment' is the
1207 ;; It is important to expand PATHDIR because 1861environment which Emacs started with. Emacs does not track changes to the
1208 ;; default-directory might be a handled name, and 1862environment made by the interpreter. Perhaps it would be more accurate if this
1209 ;; the unexpanded PATHDIR won't necessarily match 1863function was called `comint-dynamic-complete-process-environment-variable'.
1210 ;; the handler regexp. 1864
1211 (expand-file-name 1865See also `comint-dynamic-complete-filename'."
1212 (concat (if (file-name-absolute-p pathdir)
1213 comint-filename-prefix)
1214 pathdir))
1215 default-directory))))
1216 (cond ((null completion)
1217 (message "No completions of %s" pathname)
1218 (ding))
1219 ((eql completion t)
1220 (message "Sole completion"))
1221 (t ; this means a string was returned.
1222 (goto-char (match-end 0))
1223 (insert (substring completion (length pathnondir))))))))
1224
1225(defun comint-dynamic-list-completions ()
1226 "List in help buffer all possible completions of the filename at point."
1227 (interactive) 1866 (interactive)
1228 (let* ((pathname (comint-match-partial-pathname)) 1867 (let* ((completion-ignore-case nil)
1229 (pathdir (file-name-directory pathname)) 1868 (variable (comint-match-partial-variable))
1230 (pathnondir (file-name-nondirectory pathname)) 1869 (varname (substring variable (string-match "[^$({]" variable)))
1231 (completions 1870 (protection (cond ((string-match "{" variable) "}")
1232 (file-name-all-completions 1871 ((string-match "(" variable) ")")
1233 pathnondir 1872 (t "")))
1234 (if pathdir 1873 (variables (mapcar (function (lambda (x)
1235 ;; It is important to expand PATHDIR because 1874 (list (substring x 0 (string-match "=" x)))))
1236 ;; default-directory might be a handled name, and 1875 process-environment))
1237 ;; the unexpanded PATHDIR won't necessarily match 1876 (var-directory-p
1238 ;; the handler regexp. 1877 (function (lambda (var)
1239 (expand-file-name 1878 (file-directory-p
1240 (concat (if (file-name-absolute-p pathdir) 1879 (comint-directory (substitute-in-file-name (concat "$" var)))))))
1241 comint-filename-prefix) 1880 (completions (all-completions varname variables)))
1242 pathdir)) 1881 ;; Complete variable as if its value were a filename (which it might be).
1243 default-directory)))) 1882 (cond ((null completions)
1883 (message "No completions of %s" varname)
1884 (ding))
1885 ((= 1 (length completions)) ; Gotcha!
1886 (let ((completion (car completions)))
1887 (if (string-equal completion varname)
1888 (message "Sole completion")
1889 (insert (substring (directory-file-name completion)
1890 (length varname)))
1891 (message "Completed"))
1892 (insert protection)
1893 (if comint-completion-addsuffix
1894 (insert (if (funcall var-directory-p completion) "/" " ")))))
1895 (t ; There's no unique completion.
1896 (let ((completion (try-completion varname variables)))
1897 ;; Insert the longest substring.
1898 (insert (substring (directory-file-name completion)
1899 (length varname)))
1900 (cond ((and comint-completion-recexact comint-completion-addsuffix
1901 (string-equal varname completion)
1902 (member completion completions))
1903 ;; It's not unique, but user wants shortest match.
1904 (insert protection
1905 (if (funcall var-directory-p completion) "/" " "))
1906 (message "Completed shortest"))
1907 ((or comint-completion-autolist
1908 (string-equal varname completion))
1909 ;; It's not unique, list possible completions.
1910 (comint-dynamic-list-completions completions))
1911 (t
1912 (message "Partially completed"))))))))
1913
1914
1915(defun comint-dynamic-simple-complete (stub candidates)
1916 "Dynamically complete STUB from CANDIDATES list.
1917This function inserts completion characters at point by completing STUB from
1918the strings in CANDIDATES. A completions listing may be shown in a help buffer
1919if completion is ambiguous.
1920
1921See also `comint-dynamic-complete-filename'."
1922 (let* ((completion-ignore-case nil)
1923 (candidates (mapcar (function (lambda (x) (list x))) candidates))
1924 (completions (all-completions stub candidates)))
1244 (cond ((null completions) 1925 (cond ((null completions)
1245 (message "No completions of %s" pathname) 1926 (message "No completions of %s" stub)
1246 (ding)) 1927 (ding))
1247 (t 1928 ((= 1 (length completions)) ; Gotcha!
1248 (let ((conf (current-window-configuration))) 1929 (let ((completion (car completions)))
1249 (with-output-to-temp-buffer "*Help*" 1930 (if (string-equal completion stub)
1250 (display-completion-list completions)) 1931 (message "Sole completion")
1251 (sit-for 0) 1932 (insert (substring completion (length stub)))
1252 (message "Hit space to flush") 1933 (message "Completed"))
1253 (let ((ch (read-event))) 1934 (if comint-completion-addsuffix (insert " "))))
1254 (if (eq ch ?\ ) 1935 (t ; There's no unique completion.
1255 (set-window-configuration conf) 1936 (let ((completion (try-completion stub candidates)))
1256 (setq unread-command-events (list ch))))))))) 1937 ;; Insert the longest substring.
1938 (insert (substring completion (length stub)))
1939 (cond ((and comint-completion-recexact comint-completion-addsuffix
1940 (string-equal stub completion)
1941 (member completion completions))
1942 ;; It's not unique, but user wants shortest match.
1943 (insert " ")
1944 (message "Completed shortest"))
1945 ((or comint-completion-autolist
1946 (string-equal stub completion))
1947 ;; It's not unique, list possible completions.
1948 (comint-dynamic-list-completions completions))
1949 (t
1950 (message "Partially completed"))))))))
1951
1952
1953(defun comint-dynamic-list-filename-completions ()
1954 "List in help buffer possible completions of the filename at point."
1955 (interactive)
1956 (let* ((completion-ignore-case nil)
1957 (filename (comint-match-partial-filename))
1958 (pathdir (file-name-directory filename))
1959 (pathnondir (file-name-nondirectory filename))
1960 (directory (if pathdir (comint-directory pathdir) default-directory))
1961 (completions (file-name-all-completions pathnondir directory)))
1962 (if completions
1963 (comint-dynamic-list-completions completions)
1964 (message "No completions of %s" filename)
1965 (ding))))
1966
1967
1968(defun comint-dynamic-list-completions (completions)
1969 "List in help buffer sorted COMPLETIONS.
1970Typing SPC flushes the help buffer."
1971 (let ((conf (current-window-configuration)))
1972 (with-output-to-temp-buffer " *Completions*"
1973 (display-completion-list (sort completions 'string-lessp)))
1974 (sit-for 0)
1975 (message "Hit space to flush")
1976 (let ((ch (read-event)))
1977 (if (eq ch ?\ )
1978 (set-window-configuration conf)
1979 (setq unread-command-events (list ch))))))
1257 1980
1258;;; Converting process modes to use comint mode 1981;;; Converting process modes to use comint mode
1259;;; =========================================================================== 1982;;; ===========================================================================
@@ -1318,7 +2041,7 @@ it just adds completion characters to the end of the filename."
1318;;; (setq shell-mode-map (full-copy-sparse-keymap comint-mode-map)) 2041;;; (setq shell-mode-map (full-copy-sparse-keymap comint-mode-map))
1319;;; (define-key shell-mode-map "\M-\t" 'comint-dynamic-complete) 2042;;; (define-key shell-mode-map "\M-\t" 'comint-dynamic-complete)
1320;;; (define-key shell-mode-map "\M-?" 2043;;; (define-key shell-mode-map "\M-?"
1321;;; 'comint-dynamic-list-completions))) 2044;;; 'comint-dynamic-list-filename-completions)))
1322;;; (use-local-map shell-mode-map) 2045;;; (use-local-map shell-mode-map)
1323;;; (make-local-variable 'shell-directory-stack) 2046;;; (make-local-variable 'shell-directory-stack)
1324;;; (setq shell-directory-stack nil) 2047;;; (setq shell-directory-stack nil)
@@ -1332,133 +2055,25 @@ it just adds completion characters to the end of the filename."
1332;;; $ESHELL, $SHELL, or /bin/sh. If you give make-comint a program argument 2055;;; $ESHELL, $SHELL, or /bin/sh. If you give make-comint a program argument
1333;;; of NIL, it barfs. Adjust your code accordingly... 2056;;; of NIL, it barfs. Adjust your code accordingly...
1334;;; 2057;;;
2058;;; Completion for comint-mode users
2059;;;
2060;;; For modes that use comint-mode, comint-after-partial-filename-command
2061;;; should be set to a function that returns t if the stub before point is to
2062;;; be treated as a filename. By default, if the stub contains a `/', or does
2063;;; not follow the prompt, comint-dynamic-complete-filename-command is called.
2064;;; Otherwise, comint-dynamic-complete-command-command is called. This should
2065;;; also be set to a function that completes whatever the mode calls commands.
2066;;; You could use comint-dynamic-simple-complete to do the bulk of the
2067;;; completion job.
1335 2068
1336;;; Do the user's customisation... 2069;;; Do the user's customisation...
1337
1338(defvar comint-load-hook nil
1339 "This hook is run when comint is loaded in.
1340This is a good place to put keybindings.")
1341
1342(run-hooks 'comint-load-hook)
1343
1344;;; Change log:
1345;;; 9/12/89
1346;;; - Souped up the filename expansion procedures.
1347;;; Doc strings are much clearer and more detailed.
1348;;; Fixed a bug where doing a filename completion when the point
1349;;; was in the middle of the filename instead of at the end would lose.
1350;;;
1351;;; 2/17/90
1352;;; - Souped up the command history stuff so that text inserted
1353;;; by comint-previous-input-matching is removed by following
1354;;; command history recalls. comint-next/previous-input-matching
1355;;; is now much more smoothly integrated w/the command history stuff.
1356;;; - Added comint-eol-on-send flag and comint-input-sender hook.
1357;;; Comint-input-sender based on code contributed by Jeff Peck
1358;;; (peck@sun.com).
1359;;;
1360;;; 3/13/90 ccm@cmu.cs.edu
1361;;; - Added comint-previous-similar-input for looking up similar inputs.
1362;;; - Added comint-send-and-get-output to allow snarfing input from
1363;;; buffer.
1364;;; - Added the ability to pick up a source file by positioning over
1365;;; a string in comint-get-source.
1366;;; - Added add-hook to make it a little easier for the user to use
1367;;; multiple hooks.
1368;;;
1369;;; 5/22/90 shivers
1370;;; - Moved Chris' multiplexed ipc stuff to comint-ipc.el.
1371;;; - Altered Chris' comint-get-source string feature. The string
1372;;; is only offered as a default if it names an existing file.
1373;;; - Changed comint-exec to directly crank up the process, instead
1374;;; of calling the env program. This made background.el happy.
1375;;; - Added new buffer-local var comint-ptyp. The problem is that
1376;;; the signalling functions don't work as advertised. If you are
1377;;; communicating via pipes, the CURRENT-GROUP arg is supposed to
1378;;; be ignored, but, unfortunately it seems to be the case that you
1379;;; must pass a NIL for this arg in the pipe case. COMINT-PTYP
1380;;; is a flag that tells whether the process is communicating
1381;;; via pipes or a pty. The comint signalling functions use it
1382;;; to determine the necessary CURRENT-GROUP arg value. The bug
1383;;; has been reported to the Gnu folks.
1384;;; - comint-dynamic-complete flushes the help window if you hit space
1385;;; after you execute it.
1386;;; - Added functions comint-send-string, comint-send-region and var
1387;;; comint-input-chunk-size. comint-send-string tries to prevent processes
1388;;; from hanging when you send them long strings by breaking them into
1389;;; chunks and allowing process output between chunks. I got the idea from
1390;;; Eero Simoncelli's Common Lisp package. Note that using
1391;;; comint-send-string means that the process buffer's contents can change
1392;;; during a call! If you depend on process output only happening between
1393;;; toplevel commands, this could be a problem. In such a case, use
1394;;; process-send-string instead. If this is a problem for people, I'd like
1395;;; to hear about it.
1396;;; - Added comint-proc-query as a simple mechanism for commands that
1397;;; want to query an inferior process and display its response. For a
1398;;; typical use, see lisp-show-arglist in cmulisp.el.
1399;;; - Added constant comint-version, which is now "2.01".
1400;;;
1401;;; 6/14/90 shivers
1402;;; - Had comint-update-env defined twice. Removed extra copy. Also
1403;;; renamed mem to be comint-mem, for modularity. The duplication
1404;;; was reported by Michael Meissner.
1405;;; 6/16/90 shivers
1406;;; - Emacs has two different mechanisms for maintaining the process
1407;;; environment, determined at compile time by the MAINTAIN-ENVIRONMENT
1408;;; #define. One uses the process-environment global variable, and
1409;;; one uses a getenv/setenv interface. comint-exec assumed the
1410;;; process-environment interface; it has been generalised (with
1411;;; comint-exec-1) to handle both cases. Pretty bogus. We could,
1412;;; of course, skip all this and just use the etc/env program to
1413;;; handle the environment tweaking, but that obscures process
1414;;; queries that other modules (like background.el) depend on. etc/env
1415;;; is also fairly bogus. This bug, and some of the fix code was
1416;;; reported by Dan Pierson.
1417;;;
1418;;; 9/5/90 shivers
1419;;; - Changed make-variable-buffer-local's to make-local-variable's.
1420;;; This leaves non-comint-mode buffers alone. Stephane Payrard
1421;;; reported the sloppy usage.
1422;;; - You can now go from comint-previous-similar-input to
1423;;; comint-previous-input with no problem.
1424;;;
1425;;; 12/21/90 shivers
1426;;; - Added a condition-case to comint-get-source. Bogus strings
1427;;; beginning with ~ were making the file-exists-p barf.
1428;;; - Added "=" to the set of chars recognised by file completion
1429;;; as constituting a filename.
1430;;;
1431;;; 1/90 shivers
1432;;; These changes comprise release 2.02:
1433;;; - Removed the kill-all-local-variables in comint-mode. This
1434;;; made it impossible for client modes to set things before calling
1435;;; comint-mode. (In particular, it messed up ilisp.el) In general,
1436;;; the client mode should be responsible for a k-a-l-v's.
1437;;; - Fixed comint-match-partial-pathname so that it works in
1438;;; more cases: if the filename begins at the start-of-buffer;
1439;;; if point is on the first char of the filename. Just a question
1440;;; of getting the tricky bits right.
1441;;; - Added a hook, comint-exec-hook that is run each time a process
1442;;; is cranked up. Useful for things like process-kill-without-query.
1443;;;
1444;;; These two were pointed out by tale:
1445;;; - Improved the doc string in comint-send-input a little bit.
1446;;; - Tweaked make-comint to check process status with comint-check-proc
1447;;; instead of equivalent inline code.
1448;;;
1449;;; - Prompt-search history commands have been commented out. I never
1450;;; liked them; I don't think anyone used them.
1451;;; - Made comint-exec-hook a local var, as it should have been.
1452;;; (This way, for instance, you can have shell procs kill-w/o-query,
1453;;; but let Scheme procs be default.)
1454;;; 2070;;;
1455;;; 7/91 Shivers 2071;;; Isn't this what eval-after-load is for?
1456;;; - Souped up comint-read-noecho with an optional argument, STARS. 2072;;;(defvar comint-load-hook nil
1457;;; Suggested by mjlx@EAGLE.CNSF.CORNELL.EDU. 2073;;; "This hook is run when comint is loaded in.
1458;;; - Moved comint-previous-input-matching from C-c r to C-M-r. 2074;;;This is a good place to put keybindings.")
1459;;; C-c <letter> bindings are reserved for the user. 2075;;;
1460;;; These bindings were done by Jim Blandy. 2076;;;(run-hooks 'comint-load-hook)
1461;;; These changes comprise version 2.03.
1462 2077
1463(provide 'comint) 2078(provide 'comint)
1464 2079