summaryrefslogtreecommitdiff
path: root/lisp/comint.el
diff options
context:
space:
mode:
authorRichard M. Stallman <rms@gnu.org>1994-03-03 23:30:57 +0000
committerRichard M. Stallman <rms@gnu.org>1994-03-03 23:30:57 +0000
commit2aa344a0bf554e81c74e73cb8fb3059ef4fd04cf (patch)
treeca93e74736bd71ed1f4371f6ba59efed1b3b0925 /lisp/comint.el
parent08abcd638bf72771421ccc247b24cf1c3dcab542 (diff)
downloademacs-2aa344a0bf554e81c74e73cb8fb3059ef4fd04cf.tar.gz
(comint-after-partial-filename-command,
comint-dynamic-complete-filename-command, comint-dynamic-complete-command-command, comint-get-current-command): Deleted. (comint-input-sentinel-functions): Replaces comint-input-sentinel. (comint-input-sentinel): Deleted. (comint-send-input): Run hooks on comint-input-sentinel-functions. (comint-output-sentinel-functions): Rename from comint-output-filter-functions. (comint-dynamic-complete-functions): New variable. (comint-mode-map): Removed menu-bar for command and variable completion. (comint-exec-1): Add to environment by hand; avoids using setenv. (comint-replace-by-expanded-history-before-point): Renamed from comint-replace-by-expanded-history. (comint-replace-by-expanded-history): New wrapper definition. (comint-word): New function. (comint-match-partial-filename): Use it. (comint-after-partial-filename, comint-match-partial-variable, comint-dynamic-complete-variable): Deleted. (comint-dynamic-complete): Run hooks on comint-dynamic-complete-functions. (comint-dynamic-complete-as-filename): Renamed from function comint-dynamic-complete-filename. (comint-dynamic-complete-filename): New wrapper definition. (comint-dynamic-simple-complete): Return a symbol representing completion.
Diffstat (limited to 'lisp/comint.el')
-rw-r--r--lisp/comint.el382
1 files changed, 146 insertions, 236 deletions
diff --git a/lisp/comint.el b/lisp/comint.el
index 1e4b9479dbe..b6c5fdbd19a 100644
--- a/lisp/comint.el
+++ b/lisp/comint.el
@@ -115,23 +115,22 @@
;;; comint-input-autoexpand - symbol ...
;;; comint-input-ignoredups - boolean ...
;;; comint-last-input-match - string ...
+;;; comint-dynamic-complete-functions - hook For the completion mechanism
;;; comint-get-old-input - function Hooks for specific
-;;; comint-get-current-command - function process-in-a-buffer
-;;; comint-dynamic-complete-command-command - function modes.
-;;; comint-after-partial-filename-command -
-;;; comint-input-sentinel - function ...
+;;; comint-input-sentinel-functions - hook process-in-a-buffer
+;;; comint-output-sentinel-functions - hook function modes.
;;; comint-input-filter - function ...
;;; comint-input-send - function ...
;;; comint-eol-on-send - boolean ...
;;; comint-process-echoes - boolean ...
;;; comint-scroll-to-bottom-on-input - symbol For scroll behavior
-;;; comint-scroll-to-bottom-on-output - symbol ...
-;;; comint-scroll-show-maximum-output - boolean ...
+;;; comint-scroll-to-bottom-on-output - symbol ...
+;;; comint-scroll-show-maximum-output - boolean...
;;;
;;; Comint mode non-buffer local variables:
-;;; comint-completion-addsuffix - boolean For file name completion
-;;; comint-completion-autolist - boolean behavior
-;;; comint-completion-recexact - boolean ...
+;;; comint-completion-addsuffix - boolean For file name completion
+;;; comint-completion-autolist - boolean behavior
+;;; comint-completion-recexact - boolean ...
(defvar comint-prompt-regexp "^"
"Regexp to recognise prompts in the inferior process.
@@ -226,44 +225,27 @@ It returns the text to be submitted as process input. The default is
`comint-get-old-input-default', which grabs the current line, and strips off
leading text matching `comint-prompt-regexp'.")
-(defvar comint-after-partial-filename-command 'comint-after-partial-filename
- "Function that returns non-nil if point is after a file name.
-By default this is `comint-after-partial-filename'.
+(defvar comint-dynamic-complete-functions
+ '(comint-replace-by-expanded-history comint-dynamic-complete-filename)
+ "List of functions called to perform completion.
+Functions should return non-nil if completion was performed.
+See also `comint-dynamic-complete'.
This is a good thing to set in mode hooks.")
-(defvar comint-dynamic-complete-filename-command
- 'comint-dynamic-complete-filename
- "Function that dynamically completes the file name at point.
-By default this is `comint-dynamic-complete-filename', though an alternative is
-`comint-replace-by-expanded-filename'.
-
-This is a good thing to set in mode hooks.")
-
-(defvar comint-dynamic-complete-command-command
- 'comint-dynamic-complete-filename
- "Function that dynamically completes the command at point.
-By default this is `comint-dynamic-complete-filename'.
-
-This is a good thing to set in mode hooks.")
-
-(defvar comint-get-current-command 'comint-get-old-input-default
- "Function that returns the current command including arguments.
-By default this is `comint-get-old-input-default', meaning the whole line.
-
-This is a good thing to set in mode hooks.")
-
-(defvar comint-input-sentinel (function ignore)
- "Called on each input submitted to comint mode process by `comint-send-input'.
-Thus it can, for instance, track cd/pushd/popd commands issued to a shell.")
-
(defvar comint-input-filter
(function (lambda (str) (not (string-match "\\`\\s *\\'" str))))
"Predicate for filtering additions to input history.
Takes one argument, the input. If non-nil, the input may be saved on the input
history list. Default is to save anything that isn't all whitespace.")
-(defvar comint-output-filter-functions '(comint-postoutput-scroll-to-bottom)
+(defvar comint-input-sentinel-functions '()
+ "Functions to call before input is sent to the process.
+These functions get one argument, a string containing the text to send.
+
+This variable is buffer-local.")
+
+(defvar comint-output-sentinel-functions '(comint-postoutput-scroll-to-bottom)
"Functions to call after output is inserted into the buffer.
One possible function is `comint-postoutput-scroll-to-bottom'.
These functions get one argument, a string containing the text just inserted.
@@ -309,7 +291,8 @@ This is to work around a bug in Emacs process signalling.")
(put 'comint-input-ring 'permanent-local t)
(put 'comint-input-ring-index 'permanent-local t)
(put 'comint-input-autoexpand 'permanent-local t)
-(put 'comint-output-filter-functions 'permanent-local t)
+(put 'comint-input-sentinel-functions 'permanent-local t)
+(put 'comint-output-sentinel-functions 'permanent-local t)
(put 'comint-scroll-to-bottom-on-input 'permanent-local t)
(put 'comint-scroll-to-bottom-on-output 'permanent-local t)
(put 'comint-scroll-show-maximum-output 'permanent-local t)
@@ -325,7 +308,7 @@ before submitting new input.
This mode is customised to create major modes such as Inferior Lisp
mode, Shell mode, etc. This can be done by setting the hooks
-`comint-input-sentinel', `comint-input-filter', `comint-input-sender'
+`comint-input-sentinel-functions', `comint-input-filter', `comint-input-sender'
and `comint-get-old-input' to appropriate functions, and the variable
`comint-prompt-regexp' to the appropriate regular expression.
@@ -341,7 +324,7 @@ Commands with no default key bindings include `send-invisible',
`comint-magic-space'.
Input to, and output from, the subprocess can cause the window to scroll to
-the end of the buffer. See variables `comint-output-filter-functions',
+the end of the buffer. See variables `comint-output-sentinel-functions',
`comint-scroll-to-bottom-on-input', and `comint-scroll-to-bottom-on-output'.
If you accidentally suspend your process, use \\[comint-continue-subjob]
@@ -376,12 +359,9 @@ Entry to this mode runs the hooks on `comint-mode-hook'."
(make-local-variable 'comint-input-autoexpand)
(make-local-variable 'comint-input-ignoredups)
(make-local-variable 'comint-delimiter-argument-list)
- (make-local-variable 'comint-after-partial-filename-command)
- (make-local-variable 'comint-dynamic-complete-filename-command)
- (make-local-variable 'comint-dynamic-complete-command-command)
- (make-local-variable 'comint-get-current-command)
+ (make-local-variable 'comint-dynamic-complete-functions)
(make-local-variable 'comint-get-old-input)
- (make-local-variable 'comint-input-sentinel)
+ (make-local-variable 'comint-input-sentinel-functions)
(make-local-variable 'comint-input-filter)
(make-local-variable 'comint-input-sender)
(make-local-variable 'comint-eol-on-send)
@@ -390,7 +370,7 @@ Entry to this mode runs the hooks on `comint-mode-hook'."
(make-local-variable 'comint-scroll-show-maximum-output)
(make-local-variable 'pre-command-hook)
(add-hook 'pre-command-hook 'comint-preinput-scroll-to-bottom)
- (make-local-variable 'comint-output-filter-functions)
+ (make-local-variable 'comint-output-sentinel-functions)
(make-local-variable 'comint-ptyp)
(make-local-variable 'comint-exec-hook)
(make-local-variable 'comint-process-echoes)
@@ -415,7 +395,6 @@ Entry to this mode runs the hooks on `comint-mode-hook'."
(define-key comint-mode-map "\C-c\C-c" 'comint-interrupt-subjob)
(define-key comint-mode-map "\C-c\C-z" 'comint-stop-subjob)
(define-key comint-mode-map "\C-c\C-\\" 'comint-quit-subjob)
- ;; " ; Stops emacs-19.19's hilit getting confused.
(define-key comint-mode-map "\C-c\C-m" 'comint-copy-old-input)
(define-key comint-mode-map "\C-c\C-o" 'comint-kill-output)
(define-key comint-mode-map "\C-c\C-r" 'comint-show-output)
@@ -432,12 +411,6 @@ Entry to this mode runs the hooks on `comint-mode-hook'."
'("Expand File Name" . comint-replace-by-expanded-filename))
(define-key comint-mode-map [menu-bar completion complete-listing]
'("File Completion Listing" . comint-dynamic-list-filename-completions))
- (define-key comint-mode-map [menu-bar completion complete-variable]
- '("Complete Variable Name" . comint-dynamic-complete-variable))
- (define-key comint-mode-map [menu-bar completion complete-command]
- '("Complete Command Name" . (lambda () (interactive)
- (funcall
- comint-dynamic-complete-command-command))))
(define-key comint-mode-map [menu-bar completion complete-file]
'("Complete File Name" . comint-dynamic-complete-filename))
(define-key comint-mode-map [menu-bar completion complete]
@@ -562,10 +535,10 @@ buffer. The hook `comint-exec-hook' is run after each exec."
;;; the appropriate environment.
(defun comint-exec-1 (name buffer command switches)
- (let ((process-environment (copy-sequence process-environment)))
- (setenv "TERMCAP" (format "emacs:co#%d:tc=unknown" (frame-width)))
- (setenv "TERM" "emacs")
- (setenv "EMACS" "t")
+ (let ((process-environment
+ (nconc (list "EMACS=t" "TERM=emacs"
+ (format "TERMCAP=emacs:co#%d:tc=unknown" (frame-width)))
+ process-environment)))
(apply 'start-process name buffer command switches)))
;;; Input history processing in a buffer
@@ -586,9 +559,10 @@ buffer. The hook `comint-exec-hook' is run after each exec."
;;; replace with expanded history.
;;; comint-magic-space Expand history and insert space.
;;;
-;;; Two functions:
+;;; Three functions:
;;; comint-read-input-ring Read into comint-input-ring...
;;; comint-write-input-ring Write to comint-input-ring-file-name.
+;;; comint-replace-by-expanded-history-before-point Workhorse function.
(defun comint-read-input-ring (&optional silent)
"Sets the buffer's `comint-input-ring' from a history file.
@@ -842,6 +816,8 @@ If N is negative, search backwards for the -Nth previous match."
(defun comint-replace-by-expanded-history (&optional silent)
"Expand input command history references before point.
+Expansion is dependent on the value of `comint-input-autoexpand'.
+
This function depends on the buffer's idea of the input history, which may not
match the command interpreter's idea, assuming it has one.
@@ -852,8 +828,22 @@ it cannot expand absolute input line number references.
If the optional argument SILENT is non-nil, never complain
even if history reference seems erroneous.
-See also `comint-magic-space'."
+See `comint-magic-space' and `comint-replace-by-expanded-history-before-point'.
+
+Returns t if successful."
(interactive)
+ (if (and comint-input-autoexpand
+ (string-match "[!^]" (funcall comint-get-old-input)))
+ ;; 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)
+ (/= previous-modified-tick (buffer-modified-tick)))))
+
+
+(defun comint-replace-by-expanded-history-before-point ()
+ "Expand directory stack reference before point.
+See `comint-replace-by-expanded-history'. Returns t if successful."
(save-excursion
(let ((toend (- (save-excursion (end-of-line nil) (point)) (point)))
(start (progn (comint-bol nil) (point))))
@@ -897,7 +887,8 @@ See also `comint-magic-space'."
;; Just a number of args from the previous input line.
(replace-match
(comint-args (comint-previous-input-string 0)
- (match-beginning 1) (match-end 1)) t t))
+ (match-beginning 1) (match-end 1)) t t)
+ (message "History item: previous"))
((looking-at
"!\\??\\({\\(.+\\)}\\|\\(\\sw+\\)\\)\\(:?[0-9^$*-]+\\)?")
;; Most recent input starting with or containing (possibly
@@ -915,11 +906,10 @@ See also `comint-magic-space'."
(goto-char (match-end 0))
(ding)))
(setq comint-input-ring-index pos)
- (message "History item: %d" (1+ pos))
(replace-match
(comint-args (ring-ref comint-input-ring pos)
- (match-beginning 4) (match-end 4))
- t t))))
+ (match-beginning 4) (match-end 4)) t t)
+ (message "History item: %d" (1+ pos)))))
((looking-at "\\^\\([^^]+\\)\\^?\\([^^]*\\)\\^?")
;; Quick substitution on the previous input line.
(let ((old (buffer-substring (match-beginning 1) (match-end 1)))
@@ -928,12 +918,11 @@ See also `comint-magic-space'."
(replace-match (comint-previous-input-string 0) t t)
(setq pos (point))
(goto-char (match-beginning 0))
- (if (search-forward old pos t)
- (replace-match new t t)
- (or silent
- (progn
- (message "Not found")
- (ding))))))
+ (if (not (search-forward old pos t))
+ (or silent
+ (error "Not found"))
+ (replace-match new t t)
+ (message "History item: substituted"))))
(t
(goto-char (match-end 0))))))))
@@ -1040,27 +1029,29 @@ a terminal newline is also inserted into the buffer and sent to the process
since it is assumed the remote process will re-echo it).
Any history reference may be expanded depending on the value of the variable
-`comint-input-autoexpand'. The value of variable `comint-input-sentinel' is
-called on the input before sending it. The input is entered into the input
-history ring, if the value of variable `comint-input-filter' returns non-nil
-when called on the input.
+`comint-input-autoexpand'. The list of function names contained in the value
+of `comint-input-sentinel-functions' is called on the input before sending it.
+The input is entered into the input history ring, if the value of variable
+`comint-input-filter' returns non-nil when called on the input.
If variable `comint-eol-on-send' is non-nil, then point is moved to the
end of line before sending the input.
-`comint-get-old-input', `comint-input-sentinel', and `comint-input-filter'
-are chosen according to the command interpreter running in the buffer. E.g.,
+The values of `comint-get-old-input', `comint-input-sentinel-functions', and
+`comint-input-filter' are chosen according to the command interpreter running
+in the buffer. E.g.,
+
If the interpreter is the csh,
comint-get-old-input is the default: take the current line, discard any
initial string matching regexp comint-prompt-regexp.
- comint-input-sentinel monitors input for \"cd\", \"pushd\", and \"popd\"
- commands. When it sees one, it cd's the buffer.
+ comint-input-sentinel-functions monitors input for \"cd\", \"pushd\", and
+ \"popd\" commands. When it sees one, it cd's the buffer.
comint-input-filter is the default: returns t if the input isn't all white
space.
If the comint is Lucid Common Lisp,
comint-get-old-input snarfs the sexp ending at point.
- comint-input-sentinel does nothing.
+ comint-input-sentinel-functions does nothing.
comint-input-filter returns nil if the input matches input-filter-regexp,
which matches (1) all whitespace (2) :a, :c, etc.
@@ -1103,7 +1094,10 @@ Similarly for Soar, Scheme, etc."
(not (string-equal (ring-ref comint-input-ring 0)
history))))
(ring-insert comint-input-ring history))
- (funcall comint-input-sentinel input)
+ (let ((functions comint-input-sentinel-functions))
+ (while functions
+ (funcall (car functions) (concat input "\n"))
+ (setq functions (cdr functions))))
(funcall comint-input-sender proc input)
(setq comint-input-ring-index nil)
(set-marker comint-last-input-start pmark)
@@ -1112,7 +1106,7 @@ Similarly for Soar, Scheme, etc."
;; A kludge to prevent the delay between insert and process output
;; affecting the display. A case for a comint-send-input-hook?
(if (eq (process-filter proc) 'comint-output-filter)
- (let ((functions comint-output-filter-functions))
+ (let ((functions comint-output-sentinel-functions))
(while functions
(funcall (car functions) (concat input "\n"))
(setq functions (cdr functions)))))))))
@@ -1157,7 +1151,7 @@ Similarly for Soar, Scheme, etc."
(narrow-to-region obeg oend)
(goto-char opoint)
- (let ((functions comint-output-filter-functions))
+ (let ((functions comint-output-sentinel-functions))
(while functions
(funcall (car functions) string)
(setq functions (cdr functions))))
@@ -1197,7 +1191,7 @@ Does not scroll if the current line is the last line in the buffer.
Depends on the value of `comint-scroll-to-bottom-on-output' and
`comint-scroll-show-maximum-output'.
-This function should be in the list `comint-output-filter-functions'."
+This function should be in the list `comint-output-sentinel-functions'."
(let* ((selected (selected-window))
(current (current-buffer))
(process (get-buffer-process current))
@@ -1697,22 +1691,15 @@ See `comint-prompt-regexp'."
;;; ===========================================================================
;;; Useful completion functions, courtesy of the Ergo group.
-;;; Six functions:
+;;; Six commands:
;;; comint-dynamic-complete Complete or expand command, filename,
;;; history at point.
;;; comint-dynamic-complete-filename Complete filename at point.
-;;; comint-dynamic-complete-variable Complete variable at point.
;;; comint-dynamic-list-filename-completions List completions in help buffer.
;;; comint-replace-by-expanded-filename Expand and complete filename at point;
;;; replace with expanded/completed name.
;;; comint-dynamic-simple-complete Complete stub given candidates.
-;;; Four hooks (defined above):
-;;; comint-dynamic-complete-filename-command Complete file name at point.
-;;; comint-dynamic-complete-command-command Complete command at point.
-;;; comint-get-current-command Return command at point.
-;;; comint-after-partial-filename-command Return non-nil if after file.
-
;;; These are not installed in the comint-mode keymap. But they are
;;; available for people who want them. Shell-mode installs them:
;;; (define-key shell-mode-map "\t" 'comint-dynamic-complete)
@@ -1749,71 +1736,45 @@ directory tracking functions.")
directory)))
-(defun comint-match-partial-filename ()
- "Return the filename at point, or signal an error.
-Environment variables are substituted."
- (save-excursion
- (if (re-search-backward "[^~/A-Za-z0-9+@:_.$#,={}-]" nil 'move)
- (forward-char 1))
- ;; Anchor the search forwards.
- (if (not (looking-at "[~/A-Za-z0-9+@:_.$#,={}-]")) (error ""))
- (re-search-forward "[~/A-Za-z0-9+@:_.$#,={}-]+")
- (substitute-in-file-name
- (buffer-substring (match-beginning 0) (match-end 0)))))
-
-
-(defun comint-match-partial-variable ()
- "Return the variable at point, or signal an error."
+(defun comint-word (word-chars)
+ "Return the word of WORD-CHARS at point, or nil if non is found.
+Word constituents are considered to be those in WORD-CHARS, which is like the
+inside of a \"[...]\" (see `skip-chars-forward')."
(save-excursion
- (if (re-search-backward "[^A-Za-z0-9_${}]" nil 'move)
- (forward-char 1))
- ;; Anchor the search forwards.
- (if (not (looking-at "\\$")) (error ""))
- (re-search-forward "\\${?[A-Za-z0-9_]+}?")
- (buffer-substring (match-beginning 0) (match-end 0))))
-
+ (let ((limit (point))
+ (word (concat "[" word-chars "]"))
+ (non-word (concat "[^" word-chars "]")))
+ (if (re-search-backward non-word nil 'move)
+ (forward-char 1))
+ ;; Anchor the search forwards.
+ (if (or (eolp) (looking-at non-word))
+ nil
+ (re-search-forward (concat word "+") limit)
+ (buffer-substring (match-beginning 0) (match-end 0))))))
-(defun comint-after-partial-filename ()
- "Returns t if point is after a file name.
-File names are assumed to contain `/'s or not be the first item in the input.
-See also `comint-bol'."
- (let ((filename (comint-match-partial-filename)))
- (or (save-match-data (string-match "/" filename))
- (not (eq (match-beginning 0)
- (save-excursion (comint-bol nil) (point)))))))
+(defun comint-match-partial-filename ()
+ "Return the filename at point, or nil if non is found.
+Environment variables are substituted. See `comint-word'."
+ (let ((filename (comint-word "~/A-Za-z0-9+@:_.$#,={}-")))
+ (and filename (substitute-in-file-name filename))))
(defun comint-dynamic-complete ()
- "Dynamically complete/expand the command/filename/history at point.
-If the text contains (a non-absolute line reference) `!' or `^' and
-`comint-input-autoexpand' is non-nil, then an attempt is made to complete the
-history. The value of the variable `comint-after-partial-filename-command' is
-used to match file names. Otherwise, an attempt is made to complete the
-command.
-
-See also the variables `comint-after-partial-filename-command',
-`comint-dynamic-complete-filename-command', and
-`comint-dynamic-complete-command-command', and functions
-`comint-replace-by-expanded-history' and `comint-magic-space'."
+ "Dynamically perform completion at point.
+Calls the functions in `comint-dynamic-complete-functions' to perform
+completion until a function returns non-nil, at which point completion is
+assumed to have occurred."
(interactive)
- (let ((previous-modified-tick (buffer-modified-tick)))
- (if (and comint-input-autoexpand
- (string-match "[!^]" (funcall comint-get-current-command)))
- ;; Looks like there might be history references in the command.
- (comint-replace-by-expanded-history))
- (if (= previous-modified-tick (buffer-modified-tick))
- ;; No references were expanded, so maybe they were none after all.
- (cond ((funcall comint-after-partial-filename-command)
- ;; It's a file name.
- (funcall comint-dynamic-complete-filename-command))
- (t
- ;; Assume it's a command.
- (funcall comint-dynamic-complete-command-command))))))
+ (let ((functions comint-dynamic-complete-functions))
+ (while (and functions (null (funcall (car functions))))
+ (setq functions (cdr functions)))))
(defun comint-dynamic-complete-filename ()
"Dynamically complete the filename at point.
+Completes if after a filename. See `comint-match-partial-filename' and
+`comint-dynamic-complete-as-filename'.
This function is similar to `comint-replace-by-expanded-filename', except that
it won't change parts of the filename already entered in the buffer; it just
adds completion characters to the end of the filename. A completions listing
@@ -1821,19 +1782,30 @@ may be shown in a help buffer if completion is ambiguous.
Completion is dependent on the value of `comint-completion-addsuffix' and
`comint-completion-recexact', and the timing of completions listing is
-dependent on the value of `comint-completion-autolist'."
+dependent on the value of `comint-completion-autolist'.
+
+Returns t if successful."
(interactive)
+ (if (comint-match-partial-filename)
+ (prog2 (message "Completing file name...")
+ (comint-dynamic-complete-as-filename))))
+
+
+(defun comint-dynamic-complete-as-filename ()
+ "Dynamically complete at point as a filename.
+See `comint-dynamic-complete-filename'. Returns t if successful."
(let* ((completion-ignore-case nil)
+ (success t)
;; For shell completion, treat all files as equally interesting.
(completion-ignored-extensions nil)
- (filename (comint-match-partial-filename))
+ (filename (or (comint-match-partial-filename) ""))
(pathdir (file-name-directory filename))
(pathnondir (file-name-nondirectory filename))
(directory (if pathdir (comint-directory pathdir) default-directory))
(completion (file-name-completion pathnondir directory)))
(cond ((null completion)
(message "No completions of %s" filename)
- (ding))
+ (setq success nil))
((eq completion t) ; Means already completed "file".
(if comint-completion-addsuffix (insert " "))
(message "Sole completion"))
@@ -1860,7 +1832,8 @@ dependent on the value of `comint-completion-autolist'."
;; It's not unique, list possible completions.
(comint-dynamic-list-filename-completions))
(t
- (message "Partially completed"))))))))
+ (message "Partially completed"))))))
+ success))
(defun comint-replace-by-expanded-filename ()
@@ -1876,86 +1849,33 @@ see `expand-file-name' and `substitute-in-file-name'. For completion see
(comint-dynamic-complete-filename))
-(defun comint-dynamic-complete-variable ()
- "Dynamically complete the environment variable at point.
-This function is similar to `comint-dynamic-complete-filename', except that it
-searches `process-environment' for completion candidates. Note that this may
-not be the same as the interpreter's idea of variable names. The main
-problem with this type of completion is that `process-environment' is the
-environment which Emacs started with. Emacs does not track changes to the
-environment made by the interpreter. Perhaps it would be more accurate if this
-function was called `comint-dynamic-complete-process-environment-variable'.
-
-See also `comint-dynamic-complete-filename'."
- (interactive)
- (let* ((completion-ignore-case nil)
- (variable (comint-match-partial-variable))
- (varname (substring variable (string-match "[^$({]" variable)))
- (protection (cond ((string-match "{" variable) "}")
- ((string-match "(" variable) ")")
- (t "")))
- (variables (mapcar (function (lambda (x)
- (list (substring x 0 (string-match "=" x)))))
- process-environment))
- (var-directory-p
- (function (lambda (var)
- (file-directory-p
- (comint-directory (substitute-in-file-name (concat "$" var)))))))
- (completions (all-completions varname variables)))
- ;; Complete variable as if its value were a filename (which it might be).
- (cond ((null completions)
- (message "No completions of %s" varname)
- (ding))
- ((= 1 (length completions)) ; Gotcha!
- (let ((completion (car completions)))
- (if (string-equal completion varname)
- (message "Sole completion")
- (insert (substring (directory-file-name completion)
- (length varname)))
- (message "Completed"))
- (insert protection)
- (if comint-completion-addsuffix
- (insert (if (funcall var-directory-p completion) "/" " ")))))
- (t ; There's no unique completion.
- (let ((completion (try-completion varname variables)))
- ;; Insert the longest substring.
- (insert (substring (directory-file-name completion)
- (length varname)))
- (cond ((and comint-completion-recexact comint-completion-addsuffix
- (string-equal varname completion)
- (member completion completions))
- ;; It's not unique, but user wants shortest match.
- (insert protection
- (if (funcall var-directory-p completion) "/" " "))
- (message "Completed shortest"))
- ((or comint-completion-autolist
- (string-equal varname completion))
- ;; It's not unique, list possible completions.
- (comint-dynamic-list-completions completions))
- (t
- (message "Partially completed"))))))))
-
-
(defun comint-dynamic-simple-complete (stub candidates)
"Dynamically complete STUB from CANDIDATES list.
This function inserts completion characters at point by completing STUB from
the strings in CANDIDATES. A completions listing may be shown in a help buffer
if completion is ambiguous.
+Returns nil if no completion was inserted.
+Returns `sole' if completed with the only completion match.
+Returns `shortest' if completed with the shortest of the completion matches.
+Returns `partial' if completed as far as possible with the completion matches.
+Returns `listed' if a completion listing was shown.
+
See also `comint-dynamic-complete-filename'."
(let* ((completion-ignore-case nil)
(candidates (mapcar (function (lambda (x) (list x))) candidates))
(completions (all-completions stub candidates)))
(cond ((null completions)
(message "No completions of %s" stub)
- (ding))
+ nil)
((= 1 (length completions)) ; Gotcha!
(let ((completion (car completions)))
(if (string-equal completion stub)
(message "Sole completion")
(insert (substring completion (length stub)))
(message "Completed"))
- (if comint-completion-addsuffix (insert " "))))
+ (if comint-completion-addsuffix (insert " "))
+ 'sole))
(t ; There's no unique completion.
(let ((completion (try-completion stub candidates)))
;; Insert the longest substring.
@@ -1965,13 +1885,16 @@ See also `comint-dynamic-complete-filename'."
(member completion completions))
;; It's not unique, but user wants shortest match.
(insert " ")
- (message "Completed shortest"))
+ (message "Completed shortest")
+ 'shortest)
((or comint-completion-autolist
(string-equal stub completion))
;; It's not unique, list possible completions.
- (comint-dynamic-list-completions completions))
+ (comint-dynamic-list-completions completions)
+ 'listed)
(t
- (message "Partially completed"))))))))
+ (message "Partially completed")
+ 'partial)))))))
(defun comint-dynamic-list-filename-completions ()
@@ -1980,15 +1903,14 @@ See also `comint-dynamic-complete-filename'."
(let* ((completion-ignore-case nil)
;; For shell completion, treat all files as equally interesting.
(completion-ignored-extensions nil)
- (filename (comint-match-partial-filename))
+ (filename (or (comint-match-partial-filename) ""))
(pathdir (file-name-directory filename))
(pathnondir (file-name-nondirectory filename))
(directory (if pathdir (comint-directory pathdir) default-directory))
(completions (file-name-all-completions pathnondir directory)))
(if completions
(comint-dynamic-list-completions completions)
- (message "No completions of %s" filename)
- (ding))))
+ (message "No completions of %s" filename))))
(defun comint-dynamic-list-completions (completions)
@@ -2046,7 +1968,7 @@ Typing SPC flushes the help buffer."
;;; copy-last-shell-input Use comint-previous-input/comint-next-input
;;;
;;; SHELL-SET-DIRECTORY is gone, its functionality taken over by
-;;; SHELL-DIRECTORY-TRACKER, the shell mode's comint-input-sentinel.
+;;; SHELL-DIRECTORY-TRACKER, the shell mode's comint-input-sentinel-functions.
;;; Comint mode does not provide functionality equivalent to
;;; shell-set-directory-error-hook; it is gone.
;;;
@@ -2063,8 +1985,8 @@ Typing SPC flushes the help buffer."
;;; necessary comint-specific local variables. Then create the
;;; foo-mode-specific local variables in foo-mode. Set the buffer's keymap to
;;; be foo-mode-map, and its mode to be foo-mode. Set the comint-mode hooks
-;;; (comint-prompt-regexp, comint-input-filter, comint-input-sentinel,
-;;; comint-get-old-input) that need to be different from the defaults. Call
+;;; (comint-{prompt-regexp, input-filter, input-sentinel-functions,
+;;; get-old-input) that need to be different from the defaults. Call
;;; foo-mode-hook, and you're done. Don't run the comint-mode hook yourself;
;;; comint-mode will take care of it. The following example, from shell.el,
;;; is typical:
@@ -2087,7 +2009,7 @@ Typing SPC flushes the help buffer."
;;; (use-local-map shell-mode-map)
;;; (make-local-variable 'shell-directory-stack)
;;; (setq shell-directory-stack nil)
-;;; (setq comint-input-sentinel 'shell-directory-tracker)
+;;; (add-hook 'comint-input-sentinel-functions 'shell-directory-tracker)
;;; (run-hooks 'shell-mode-hook))
;;;
;;;
@@ -2099,24 +2021,12 @@ Typing SPC flushes the help buffer."
;;;
;;; Completion for comint-mode users
;;;
-;;; For modes that use comint-mode, comint-after-partial-filename-command
-;;; should be set to a function that returns t if the stub before point is to
-;;; be treated as a filename. By default, if the stub contains a `/', or does
-;;; not follow the prompt, comint-dynamic-complete-filename-command is called.
-;;; Otherwise, comint-dynamic-complete-command-command is called. This should
-;;; also be set to a function that completes whatever the mode calls commands.
+;;; For modes that use comint-mode, comint-dynamic-complete-functions is the
+;;; hook to add completion functions to. Functions on this list should return
+;;; non-nil if completion occurs (i.e., further completion should not occur).
;;; You could use comint-dynamic-simple-complete to do the bulk of the
;;; completion job.
-;;; Do the user's customisation...
-;;;
-;;; Isn't this what eval-after-load is for?
-;;;(defvar comint-load-hook nil
-;;; "This hook is run when comint is loaded in.
-;;;This is a good place to put keybindings.")
-;;;
-;;;(run-hooks 'comint-load-hook)
-
(provide 'comint)
;;; comint.el ends here