;;; comint.el --- general command interpreter in a window stuff
-;; Copyright (C) 1988, 90, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc.
+;; Copyright (C) 1988, 90, 92, 93, 94, 95, 96, 97, 98 Free Software Foundation, Inc.
;; Author: Olin Shivers <shivers@cs.cmu.edu> then
;; Simon Marshall <simon@gnu.ai.mit.edu>
(default-directory
(if (file-accessible-directory-p default-directory)
default-directory
- "/")))
+ (char-to-string directory-sep-char))))
(apply 'start-process name buffer command switches)))
\f
;; Input history processing in a buffer
(comint-previous-matching-input-from-input (- arg)))
-(defun comint-replace-by-expanded-history (&optional silent)
+(defun comint-replace-by-expanded-history (&optional silent start)
"Expand input command history references before point.
Expansion is dependent on the value of `comint-input-autoexpand'.
If the optional argument SILENT is non-nil, never complain
even if history reference seems erroneous.
+If the optional argument START is non-nil, that specifies the
+start of the text to scan for history references, rather
+than the logical beginning of line.
+
See `comint-magic-space' and `comint-replace-by-expanded-history-before-point'.
Returns t if successful."
(looking-at comint-prompt-regexp)))
;; Looks like there might be history references in the command.
(let ((previous-modified-tick (buffer-modified-tick)))
- (message "Expanding history references...")
- (comint-replace-by-expanded-history-before-point silent)
+ (comint-replace-by-expanded-history-before-point silent start)
(/= previous-modified-tick (buffer-modified-tick)))))
-(defun comint-replace-by-expanded-history-before-point (silent)
+(defun comint-replace-by-expanded-history-before-point (silent &optional start)
"Expand directory stack reference before point.
-See `comint-replace-by-expanded-history'. Returns t if successful."
+See `comint-replace-by-expanded-history'. Returns t if successful.
+
+If the optional argument START is non-nil, that specifies the
+start of the text to scan for history references, rather
+than the logical beginning of line."
(save-excursion
(let ((toend (- (save-excursion (end-of-line nil) (point)) (point)))
- (start (progn (comint-bol nil) (point))))
+ (start (or start (progn (comint-bol nil) (point)))))
(while (progn
(skip-chars-forward "^!^"
(save-excursion
(replace-match new t t)
(message "History item: substituted"))))
(t
- (goto-char (match-end 0))))))))
+ (forward-char 1)))))))
(defun comint-magic-space (arg)
Also, a run of one or more of a single character
in `comint-delimiter-argument-list' is a separate argument.
Argument 0 is the command name."
- (let ((argpart "[^ \n\t\"'`]+\\|\\(\"[^\"]*\"\\|'[^']*'\\|`[^`]*`\\)")
+ ;; The first line handles ordinary characters and backslash-sequences.
+ ;; The second matches "-quoted strings.
+ ;; The third matches '-quoted strings.
+ ;; The fourth matches `-quoted strings.
+ ;; This seems to fit the syntax of BASH 2.0.
+ (let ((argpart "[^ \n\t\"'`\\]+\\|\\\\[\"'`\\]+\\|\
+\\(\"\\([^\"\\]\\|\\\\.\\)*\"\\|\
+'[^']*'\\|\
+`[^`]*`\\)")
(args ()) (pos 0)
(count 0)
beg str value quotes)
;; Just whatever's already there
intxt
;; Expand and leave it visible in buffer
- (comint-replace-by-expanded-history t)
+ (comint-replace-by-expanded-history t pmark)
(buffer-substring pmark (point))))
(history (if (not (eq comint-input-autoexpand 'history))
input
;; This is messy 'cos ultimately the original
;; functions used do insertion, rather than return
;; strings. We have to expand, then insert back.
- (comint-replace-by-expanded-history t)
+ (comint-replace-by-expanded-history t pmark)
(let ((copy (buffer-substring pmark (point)))
(start (point)))
(insert input)
(run-hook-with-args 'comint-output-filter-functions "")))))
(defvar comint-preoutput-filter-functions nil
- "Functions to call after output is inserted into the buffer.
+ "Functions to call before output is inserted into the buffer.
These functions get one argument, a string containing the text to be
inserted. They return the string as it should be inserted.
(comint-skip-prompt)))
(defun comint-interrupt-subjob ()
- "Interrupt the current subjob."
+ "Interrupt the current subjob.
+This command also kills the pending input
+between the process-mark and point."
(interactive)
+ (comint-kill-input)
(interrupt-process nil comint-ptyp))
(defun comint-kill-subjob ()
- "Send kill signal to the current subjob."
+ "Send kill signal to the current subjob.
+This command also kills the pending input
+between the process-mark and point."
(interactive)
+ (comint-kill-input)
(kill-process nil comint-ptyp))
(defun comint-quit-subjob ()
- "Send quit signal to the current subjob."
+ "Send quit signal to the current subjob.
+This command also kills the pending input
+between the process-mark and point."
(interactive)
+ (comint-kill-input)
(quit-process nil comint-ptyp))
(defun comint-stop-subjob ()
"Stop the current subjob.
+This command also kills the pending input
+between the process-mark and point.
+
WARNING: if there is no current subjob, you can end up suspending
the top-level process running in the buffer. If you accidentally do
this, use \\[comint-continue-subjob] to resume the process. (This
is not a problem with most shells, since they ignore this signal.)"
(interactive)
+ (comint-kill-input)
(stop-process nil comint-ptyp))
(defun comint-continue-subjob ()
;; Try to position the proc window so you can see the answer.
;; This is bogus code. If you delete the (sit-for 0), it breaks.
;; I don't know why. Wizards invited to improve it.
- (if (not (pos-visible-in-window-p proc-pt proc-win))
- (let ((opoint (window-point proc-win)))
- (set-window-point proc-win proc-mark)
- (sit-for 0)
- (if (not (pos-visible-in-window-p opoint proc-win))
- (push-mark opoint)
- (set-window-point proc-win opoint)))))))
+ (unless (pos-visible-in-window-p proc-pt proc-win)
+ (let ((opoint (window-point proc-win)))
+ (set-window-point proc-win proc-mark)
+ (sit-for 0)
+ (if (not (pos-visible-in-window-p opoint proc-win))
+ (push-mark opoint)
+ (set-window-point proc-win opoint)))))))
\f
;; Filename/command/history completion in a buffer
directory tracking functions.")
(defvar comint-file-name-chars
- (cond
- ((eq system-type 'ms-dos)
- "~/A-Za-z0-9_^$!#%&{}@`'.()-")
- ((eq system-type 'windows-nt)
- "~/A-Za-z0-9_^$!#%&{}@`'.,:()-")
- (t
- "~/A-Za-z0-9+@:_.$#%,={}-"))
+ (if (memq system-type '(ms-dos windows-nt))
+ "~/A-Za-z0-9_^$!#%&{}@`'.,:()-"
+ "~/A-Za-z0-9+@:_.$#%,={}-")
"String of characters valid in a file name.
Note that all non-ASCII characters are considered valid in a file name
regardless of what this variable says.
(eq (preceding-char) ?\\)))
(backward-char 1))
;; Don't go forward over a word-char (this can happen if we're at bob).
- (if (or (not (bobp)) (looking-at non-word-chars))
- (forward-char 1))
+ (when (or (not (bobp)) (looking-at non-word-chars))
+ (forward-char 1))
;; Set match-data to match the entire string.
- (if (< (point) here)
- (progn (store-match-data (list (point) here))
- (match-string 0))))))
+ (when (< (point) here)
+ (set-match-data (list (point) here))
+ (match-string 0)))))
(defun comint-substitute-in-file-name (filename)
"Return FILENAME with environment variables substituted.
Returns t if successful."
(interactive)
- (if (comint-match-partial-filename)
- (let ((directory-sep-char (if (memq system-type '(ms-dos windows-nt))
- ?\\
- ?/)))
- (prog2 (or (window-minibuffer-p (selected-window))
- (message "Completing file name..."))
- (comint-dynamic-complete-as-filename)))))
+ (when (comint-match-partial-filename)
+ (unless (window-minibuffer-p (selected-window))
+ (message "Completing file name..."))
+ (comint-dynamic-complete-as-filename)))
(defun comint-dynamic-complete-as-filename ()
"Dynamically complete at point as a filename.
;;(file-name-handler-alist nil)
(minibuffer-p (window-minibuffer-p (selected-window)))
(success t)
- (dirsuffix (cond ((not comint-completion-addsuffix) "")
- ((not (consp comint-completion-addsuffix)) "/")
- (t (car comint-completion-addsuffix))))
- (filesuffix (cond ((not comint-completion-addsuffix) "")
- ((not (consp comint-completion-addsuffix)) " ")
- (t (cdr comint-completion-addsuffix))))
+ (dirsuffix (cond ((not comint-completion-addsuffix)
+ "")
+ ((not (consp comint-completion-addsuffix))
+ (char-to-string directory-sep-char))
+ (t
+ (car comint-completion-addsuffix))))
+ (filesuffix (cond ((not comint-completion-addsuffix)
+ "")
+ ((not (consp comint-completion-addsuffix))
+ " ")
+ (t
+ (cdr comint-completion-addsuffix))))
(filename (or (comint-match-partial-filename) ""))
(pathdir (file-name-directory filename))
(pathnondir (file-name-nondirectory filename))
(setq success nil))
((eq completion t) ; Means already completed "file".
(insert filesuffix)
- (or minibuffer-p (message "Sole completion")))
+ (unless minibuffer-p
+ (message "Sole completion")))
((string-equal completion "") ; Means completion on "directory/".
(comint-dynamic-list-filename-completions))
(t ; Completion string returned.
(cond ((symbolp (file-name-completion completion directory))
;; We inserted a unique completion.
(insert (if (file-directory-p file) dirsuffix filesuffix))
- (or minibuffer-p (message "Completed")))
+ (unless minibuffer-p
+ (message "Completed")))
((and comint-completion-recexact comint-completion-addsuffix
(string-equal pathnondir completion)
(file-exists-p file))
;; It's not unique, but user wants shortest match.
(insert (if (file-directory-p file) dirsuffix filesuffix))
- (or minibuffer-p (message "Completed shortest")))
+ (unless minibuffer-p
+ (message "Completed shortest")))
((or comint-completion-autolist
(string-equal pathnondir completion))
;; It's not unique, list possible completions.
(comint-dynamic-list-filename-completions))
(t
- (or minibuffer-p (message "Partially completed")))))))
+ (unless minibuffer-p
+ (message "Partially completed")))))))
success))