summaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2000-08-29 00:47:45 +0000
committerJohn Wiegley <johnw@newartisans.com>2000-08-29 00:47:45 +0000
commitca7aae916bab6783c5133d8432b61d97b8ffa923 (patch)
tree1b36d8d391a6a0c166fd27a01acbc92a92020530 /lisp
parentb4bd214e74d885552fe38051253dbc2b362bfe67 (diff)
downloademacs-ca7aae916bab6783c5133d8432b61d97b8ffa923.tar.gz
See ChangeLog
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog4
-rw-r--r--lisp/align.el6
-rw-r--r--lisp/eshell/em-cmpl.el9
-rw-r--r--lisp/eshell/em-dirs.el6
-rw-r--r--lisp/eshell/em-hist.el14
-rw-r--r--lisp/eshell/em-ls.el2
-rw-r--r--lisp/eshell/em-rebind.el2
-rw-r--r--lisp/eshell/em-smart.el23
-rw-r--r--lisp/eshell/em-unix.el94
-rw-r--r--lisp/eshell/em-xtra.el2
-rw-r--r--lisp/eshell/esh-cmd.el162
-rw-r--r--lisp/eshell/esh-ext.el6
-rw-r--r--lisp/eshell/esh-io.el27
-rw-r--r--lisp/eshell/esh-mode.el1
-rw-r--r--lisp/eshell/esh-proc.el137
-rw-r--r--lisp/eshell/esh-util.el2
-rw-r--r--lisp/eshell/esh-var.el12
-rw-r--r--lisp/pcmpl-gnu.el7
-rw-r--r--lisp/pcomplete.el10
19 files changed, 348 insertions, 178 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index b0353360325..3399619f343 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,9 @@
2000-08-28 John Wiegley <johnw@gnu.org>
+ * eshell/esh-util.el (eshell-flatten-list): It's not too wise to
+ have a defsubst call itself. Made `eshell-flatten-list' back into
+ a function again.
+
* eshell/em-smart.el (eshell-smart-redisplay): Added a safety
catch, in case re-centering point at bottom messes up the display.
This happens frequently in Emacs 21, due I believe to variable
diff --git a/lisp/align.el b/lisp/align.el
index 0c7184678d7..4a3b098ec2b 100644
--- a/lisp/align.el
+++ b/lisp/align.el
@@ -873,7 +873,8 @@ on the format of these lists."
(interactive "r")
(let ((separator
(or separate
- (if (symbolp align-region-separate)
+ (if (and (symbolp align-region-separate)
+ (boundp align-region-separate))
(symbol-value align-region-separate)
align-region-separate)
'entire)))
@@ -1038,7 +1039,8 @@ to be colored."
(defun align-newline-and-indent ()
"A replacement function for `newline-and-indent', aligning as it goes."
(interactive)
- (let ((separate (or (if (symbolp align-region-separate)
+ (let ((separate (or (if (and (symbolp align-region-separate)
+ (boundp align-region-separate))
(symbol-value align-region-separate)
align-region-separate)
'entire))
diff --git a/lisp/eshell/em-cmpl.el b/lisp/eshell/em-cmpl.el
index a0668f7d57a..19a0f595e6f 100644
--- a/lisp/eshell/em-cmpl.el
+++ b/lisp/eshell/em-cmpl.el
@@ -225,7 +225,12 @@ to writing a completion function."
(documentation-property 'pcomplete-default-completion-function
'variable-documentation)
:type (get 'pcomplete-default-completion-function 'custom-type)
- :group 'pcomplete)
+ :group 'eshell-cmpl)
+
+(defcustom eshell-cmpl-use-paring t
+ (documentation-property 'pcomplete-use-paring 'variable-documentation)
+ :type (get 'pcomplete-use-paring 'custom-type)
+ :group 'eshell-cmpl)
;;; Functions:
@@ -265,6 +270,8 @@ to writing a completion function."
eshell-cmpl-cycle-cutoff-length)
(set (make-local-variable 'pcomplete-restore-window-delay)
eshell-cmpl-restore-window-delay)
+ (set (make-local-variable 'pcomplete-use-paring)
+ eshell-cmpl-use-paring)
;; `pcomplete-arg-quote-list' should only be set after all the
;; load-hooks for any other extension modules have been run, which
;; is true at the time `eshell-mode-hook' is run
diff --git a/lisp/eshell/em-dirs.el b/lisp/eshell/em-dirs.el
index 13565d87521..c59bd042575 100644
--- a/lisp/eshell/em-dirs.el
+++ b/lisp/eshell/em-dirs.el
@@ -382,11 +382,13 @@ in the minibuffer:
(index 0))
(if (= len 0)
(error "Directory ring empty"))
+ (eshell-init-print-buffer)
(while (< index len)
- (eshell-printn
+ (eshell-buffered-print
(concat (number-to-string index) ": "
- (ring-ref eshell-last-dir-ring index)))
+ (ring-ref eshell-last-dir-ring index) "\n"))
(setq index (1+ index)))
+ (eshell-flush)
(setq handled t)))))
(path
(setq path (eshell-expand-multiple-dots path))))
diff --git a/lisp/eshell/em-hist.el b/lisp/eshell/em-hist.el
index 896178a7958..1213dfcc291 100644
--- a/lisp/eshell/em-hist.el
+++ b/lisp/eshell/em-hist.el
@@ -350,17 +350,13 @@ unless a different file is specified on the command line.")
(defun eshell-put-history (input &optional ring at-beginning)
"Put a new input line into the history ring."
(unless ring (setq ring eshell-history-ring))
- (subst-char-in-string ?\n ?\177 input t)
(if at-beginning
(ring-insert-at-beginning ring input)
(ring-insert ring input)))
(defun eshell-get-history (index &optional ring)
"Get an input line from the history ring."
- (unless ring (setq ring eshell-history-ring))
- (let ((input (concat (ring-ref ring index))))
- (subst-char-in-string ?\177 ?\n input t)
- input))
+ (ring-ref (or ring eshell-history-ring) index))
(defun eshell-add-to-history ()
"Add INPUT to the history ring.
@@ -419,7 +415,8 @@ line, with the most recent command last. See also
(if (or (null ignore-dups)
(ring-empty-p ring)
(not (string-equal (ring-ref ring 0) history)))
- (ring-insert-at-beginning ring history)))
+ (ring-insert-at-beginning
+ ring (subst-char-in-string ?\177 ?\n history))))
(setq count (1+ count))))
(setq eshell-history-ring ring
eshell-history-index nil))))))
@@ -451,7 +448,9 @@ See also `eshell-read-history'."
(with-temp-buffer
(while (> index 0)
(setq index (1- index))
- (insert (ring-ref ring index) ?\n))
+ (let ((start (point)))
+ (insert (ring-ref ring index) ?\n)
+ (subst-char-in-region start (1- (point)) ?\n ?\177)))
(eshell-with-private-file-modes
(write-region (point-min) (point-max) file append
'no-message))))))))
@@ -891,7 +890,6 @@ If N is negative, search backwards for the -Nth previous match."
(goto-char eshell-last-output-end)
(delete-region (point) (point-max))
(when (and text (> (length text) 0))
- (subst-char-in-string ?\177 ?\n text t)
(insert text)
(put-text-property (1- (point)) (point)
'last-search-pos before)
diff --git a/lisp/eshell/em-ls.el b/lisp/eshell/em-ls.el
index e9e46c2f1a6..cd16f049815 100644
--- a/lisp/eshell/em-ls.el
+++ b/lisp/eshell/em-ls.el
@@ -820,7 +820,7 @@ Use TRUENAME for predicate tests, if passed."
((not (eshell-ls-filetype-p (cdr file) ?-))
'eshell-ls-special-face)
- ((and (not (= (user-uid) 0)) ; root can execute anything
+ ((and (/= (user-uid) 0) ; root can execute anything
(eshell-ls-applicable (cdr file) 3
'file-executable-p (car file)))
'eshell-ls-executable-face)
diff --git a/lisp/eshell/em-rebind.el b/lisp/eshell/em-rebind.el
index bd5ee5f5292..0463a78ffb4 100644
--- a/lisp/eshell/em-rebind.el
+++ b/lisp/eshell/em-rebind.el
@@ -235,7 +235,7 @@ input."
(let ((proc (get-buffer-process (current-buffer))))
(if (eobp)
(cond
- ((not (= (point) eshell-last-output-end))
+ ((/= (point) eshell-last-output-end)
(beep))
(proc
(process-send-eof))
diff --git a/lisp/eshell/em-smart.el b/lisp/eshell/em-smart.el
index 0d5a2732dd5..d7db23a0f9b 100644
--- a/lisp/eshell/em-smart.el
+++ b/lisp/eshell/em-smart.el
@@ -258,15 +258,20 @@ and the end of the buffer are still visible."
"Display as much output as possible, smartly."
(if (eobp)
(recenter -1)
- (and (memq 'eshell-smart-display-move pre-command-hook)
- (>= (point) eshell-last-input-start)
- (< (point) eshell-last-input-end)
- (set-window-start (selected-window)
- (line-beginning-position) t))
- (if (pos-visible-in-window-p (point-max))
- (save-excursion
- (goto-char (point-max))
- (recenter -1)))))
+ (let ((top-point (point)))
+ (and (memq 'eshell-smart-display-move pre-command-hook)
+ (>= (point) eshell-last-input-start)
+ (< (point) eshell-last-input-end)
+ (set-window-start (selected-window)
+ (line-beginning-position) t))
+ (if (pos-visible-in-window-p (point-max))
+ (save-excursion
+ (goto-char (point-max))
+ (recenter -1)
+ (unless (pos-visible-in-window-p top-point)
+ (goto-char top-point)
+ (set-window-start (selected-window)
+ (line-beginning-position) t)))))))
(defun eshell-smart-goto-end ()
"Like `end-of-buffer', but do not push a mark."
diff --git a/lisp/eshell/em-unix.el b/lisp/eshell/em-unix.el
index 33a99cb06a3..17e110f65ed 100644
--- a/lisp/eshell/em-unix.el
+++ b/lisp/eshell/em-unix.el
@@ -117,7 +117,7 @@ Otherwise, `rmdir' is required."
:type 'boolean
:group 'eshell-unix)
-(defcustom eshell-ln-overwrite-files t
+(defcustom eshell-ln-overwrite-files nil
"*If non-nil, `ln' will overwrite files without warning."
:type 'boolean
:group 'eshell-unix)
@@ -224,7 +224,7 @@ Remove (unlink) the FILE(s).")
(not (y-or-n-p (format "rm: delete buffer `%s'? "
entry)))))
(eshell-funcalln 'kill-buffer entry)))
- ((processp entry)
+ ((eshell-processp entry)
(if verbose
(eshell-printn (format "rm: killing process `%s'" entry)))
(unless (or preview
@@ -353,13 +353,14 @@ Remove the DIRECTORY(ies), if they are empty.")
command target)))
(unless preview
(eshell-funcalln 'make-directory target)))
- (eshell-shuffle-files command action
- (mapcar
- (function
- (lambda (file)
- (concat source "/" file)))
- (directory-files source))
- target func t args)
+ (apply 'eshell-shuffle-files
+ command action
+ (mapcar
+ (function
+ (lambda (file)
+ (concat source "/" file)))
+ (directory-files source))
+ target func t args)
(when (eq func 'rename-file)
(if verbose
(eshell-printn
@@ -527,7 +528,7 @@ with '--symbolic'. When creating hard links, each TARGET must exist.")
"Implementation of cat in Lisp."
(if eshell-in-pipeline-p
(throw 'eshell-replace-command
- (eshell-parse-command "*cat" args))
+ (eshell-parse-command "*cat" (eshell-flatten-list args)))
(eshell-init-print-buffer)
(eshell-eval-using-options
"cat" args
@@ -568,7 +569,7 @@ Concatenate FILE(s), or standard input, to standard output.")
(list 'quote (eshell-copy-environment))))))
(compile (concat "make " (eshell-flatten-and-stringify args))))
(throw 'eshell-replace-command
- (eshell-parse-command "*make" args))))
+ (eshell-parse-command "*make" (eshell-flatten-list args)))))
(defun eshell-occur-mode-goto-occurrence ()
"Go to the occurrence the current line describes."
@@ -644,7 +645,8 @@ external command."
(not eshell-in-pipeline-p)
(not eshell-in-subcommand-p))))
(throw 'eshell-replace-command
- (eshell-parse-command (concat "*" command) args))
+ (eshell-parse-command (concat "*" command)
+ (eshell-flatten-list args)))
(let* ((compilation-process-setup-function
(list 'lambda nil
(list 'setq 'process-environment
@@ -745,8 +747,8 @@ external command."
(cadr (car entries)))))
(unless (or (and symlink (not dereference-links))
(and only-one-filesystem
- (not (= only-one-filesystem
- (nth 12 (car entries))))))
+ (/= only-one-filesystem
+ (nth 12 (car entries)))))
(if symlink
(setq entry symlink))
(setq size
@@ -769,10 +771,10 @@ external command."
size))
(defun eshell/du (&rest args)
- "Implementation of \"du\" in Lisp, passing RAGS."
+ "Implementation of \"du\" in Lisp, passing ARGS."
(if (eshell-search-path "du")
(throw 'eshell-replace-command
- (eshell-parse-command "*du" args))
+ (eshell-parse-command "*du" (eshell-flatten-list args)))
(eshell-eval-using-options
"du" args
'((?a "all" nil show-all
@@ -875,32 +877,38 @@ Show wall-clock time elapsed during execution of COMMAND.")
(defun eshell/diff (&rest args)
"Alias \"diff\" to call Emacs `diff' function."
- (if (or eshell-plain-diff-behavior
- (not (and (eshell-interactive-output-p)
- (not eshell-in-pipeline-p)
- (not eshell-in-subcommand-p))))
- (throw 'eshell-replace-command
- (eshell-parse-command "*diff" args))
- (setq args (eshell-flatten-list args))
- (if (< (length args) 2)
- (error "diff: missing operand"))
- (let ((old (car (last args 2)))
- (new (car (last args)))
- (config (current-window-configuration)))
- (if (= (length args) 2)
- (setq args nil)
- (setcdr (last args 3) nil))
- (with-current-buffer
- (diff old new (eshell-flatten-and-stringify args))
- (when (fboundp 'diff-mode)
- (diff-mode)
- (set (make-local-variable 'eshell-diff-window-config) config)
- (local-set-key [?q] 'eshell-diff-quit)
- (if (fboundp 'turn-on-font-lock-if-enabled)
- (turn-on-font-lock-if-enabled))))
- (other-window 1)
- (goto-char (point-min))
- nil)))
+ (let ((orig-args (eshell-flatten-list args)))
+ (if (or eshell-plain-diff-behavior
+ (not (and (eshell-interactive-output-p)
+ (not eshell-in-pipeline-p)
+ (not eshell-in-subcommand-p))))
+ (throw 'eshell-replace-command
+ (eshell-parse-command "*diff" orig-args))
+ (setq args (eshell-copy-list orig-args))
+ (if (< (length args) 2)
+ (throw 'eshell-replace-command
+ (eshell-parse-command "*diff" orig-args)))
+ (let ((old (car (last args 2)))
+ (new (car (last args)))
+ (config (current-window-configuration)))
+ (if (= (length args) 2)
+ (setq args nil)
+ (setcdr (last args 3) nil))
+ (with-current-buffer
+ (condition-case err
+ (diff old new (eshell-flatten-and-stringify args))
+ (error
+ (throw 'eshell-replace-command
+ (eshell-parse-command "*diff" orig-args))))
+ (when (fboundp 'diff-mode)
+ (diff-mode)
+ (set (make-local-variable 'eshell-diff-window-config) config)
+ (local-set-key [?q] 'eshell-diff-quit)
+ (if (fboundp 'turn-on-font-lock-if-enabled)
+ (turn-on-font-lock-if-enabled))))
+ (other-window 1)
+ (goto-char (point-min))
+ nil))))
(defun eshell/locate (&rest args)
"Alias \"locate\" to call Emacs `locate' function."
@@ -911,7 +919,7 @@ Show wall-clock time elapsed during execution of COMMAND.")
(and (stringp (car args))
(string-match "^-" (car args))))
(throw 'eshell-replace-command
- (eshell-parse-command "*locate" args))
+ (eshell-parse-command "*locate" (eshell-flatten-list args)))
(save-selected-window
(let ((locate-history-list (list (car args))))
(locate-with-filter (car args) (cadr args))))))
diff --git a/lisp/eshell/em-xtra.el b/lisp/eshell/em-xtra.el
index ad5602d97a0..9b4e6ad058e 100644
--- a/lisp/eshell/em-xtra.el
+++ b/lisp/eshell/em-xtra.el
@@ -41,7 +41,7 @@ naturally accessible within Emacs."
"Implementation of expr, using the calc package."
(if (not (fboundp 'calc-eval))
(throw 'eshell-replace-command
- (eshell-parse-command "*expr" args))
+ (eshell-parse-command "*expr" (eshell-flatten-list args)))
;; to fool the byte-compiler...
(let ((func 'calc-eval))
(funcall func (eshell-flatten-and-stringify args)))))
diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el
index a3c7d58c066..fcdcfbb3fc3 100644
--- a/lisp/eshell/esh-cmd.el
+++ b/lisp/eshell/esh-cmd.el
@@ -516,8 +516,8 @@ implemented via rewriting, rather than as a function."
(list 'car
(list 'symbol-value
(list 'quote 'for-items)))))
- (list 'eshell-protect
- (eshell-invokify-arg body t)))
+ (list 'eshell-copy-handles
+ (eshell-invokify-arg body t)))
(list 'setcar 'for-items
(list 'cadr
(list 'symbol-value
@@ -581,7 +581,7 @@ must be implemented via rewriting, rather than as a function."
(eshell-structure-basic-command
'while '("while" "until") (car terms)
(eshell-invokify-arg (cadr terms) nil t)
- (list 'eshell-protect
+ (list 'eshell-copy-handles
(eshell-invokify-arg (car (last terms)) t)))))
(defun eshell-rewrite-if-command (terms)
@@ -770,6 +770,31 @@ this grossness will be made to disappear by using `call/cc'..."
(eshell-errorn (error-message-string err))
(eshell-close-handles 1)))))
+;; (defun eshell-copy-or-protect-handles ()
+;; (if (eshell-processp (car (aref eshell-current-handles
+;; eshell-output-handle)))
+;; (eshell-protect-handles eshell-current-handles)
+;; (eshell-create-handles
+;; (car (aref eshell-current-handles
+;; eshell-output-handle)) nil
+;; (car (aref eshell-current-handles
+;; eshell-error-handle)) nil)))
+
+;; (defmacro eshell-copy-handles (object)
+;; "Duplicate current I/O handles, so OBJECT works with its own copy."
+;; `(let ((eshell-current-handles (eshell-copy-or-protect-handles)))
+;; ,object))
+
+(defmacro eshell-copy-handles (object)
+ "Duplicate current I/O handles, so OBJECT works with its own copy."
+ `(let ((eshell-current-handles
+ (eshell-create-handles
+ (car (aref eshell-current-handles
+ eshell-output-handle)) nil
+ (car (aref eshell-current-handles
+ eshell-error-handle)) nil)))
+ ,object))
+
(defmacro eshell-protect (object)
"Protect I/O handles, so they aren't get closed after eval'ing OBJECT."
`(progn
@@ -779,32 +804,65 @@ this grossness will be made to disappear by using `call/cc'..."
(defmacro eshell-do-pipelines (pipeline)
"Execute the commands in PIPELINE, connecting each to one another."
(when (setq pipeline (cadr pipeline))
- `(let ((eshell-current-handles
- (eshell-create-handles
- (car (aref eshell-current-handles
- eshell-output-handle)) nil
- (car (aref eshell-current-handles
- eshell-error-handle)) nil)))
+ `(eshell-copy-handles
+ (progn
+ ,(when (cdr pipeline)
+ `(let (nextproc)
+ (progn
+ (set 'nextproc
+ (eshell-do-pipelines (quote ,(cdr pipeline))))
+ (eshell-set-output-handle ,eshell-output-handle
+ 'append nextproc)
+ (eshell-set-output-handle ,eshell-error-handle
+ 'append nextproc)
+ (set 'tailproc (or tailproc nextproc)))))
+ ,(let ((head (car pipeline)))
+ (if (memq (car head) '(let progn))
+ (setq head (car (last head))))
+ (when (memq (car head) eshell-deferrable-commands)
+ (ignore
+ (setcar head
+ (intern-soft
+ (concat (symbol-name (car head)) "*"))))))
+ ,(car pipeline)))))
+
+(defmacro eshell-do-pipelines-synchronously (pipeline)
+ "Execute the commands in PIPELINE in sequence synchronously.
+Output of each command is passed as input to the next one in the pipeline.
+This is used on systems where `start-process' is not supported."
+ (when (setq pipeline (cadr pipeline))
+ `(let (result)
(progn
,(when (cdr pipeline)
- `(let (nextproc)
+ `(let (output-marker)
(progn
- (set 'nextproc
- (eshell-do-pipelines (quote ,(cdr pipeline))))
+ (set 'output-marker ,(point-marker))
(eshell-set-output-handle ,eshell-output-handle
- 'append nextproc)
+ 'append output-marker)
(eshell-set-output-handle ,eshell-error-handle
- 'append nextproc)
- (set 'tailproc (or tailproc nextproc)))))
+ 'append output-marker))))
,(let ((head (car pipeline)))
(if (memq (car head) '(let progn))
(setq head (car (last head))))
+ ;;; FIXME: is deferrable significant here?
(when (memq (car head) eshell-deferrable-commands)
(ignore
(setcar head
(intern-soft
(concat (symbol-name (car head)) "*"))))))
- ,(car pipeline)))))
+ ;; The last process in the pipe should get its handles
+ ;; redirected as we found them before running the pipe.
+ ,(if (null (cdr pipeline))
+ `(progn
+ (set 'eshell-current-handles tail-handles)
+ (set 'eshell-in-pipeline-p nil)))
+ (set 'result ,(car pipeline))
+ ;; tailproc gets the result of the last successful process in
+ ;; the pipeline.
+ (set 'tailproc (or result tailproc))
+ ,(if (cdr pipeline)
+ `(eshell-do-pipelines-synchronously (quote ,(cdr pipeline))))
+ result))))
(defalias 'eshell-process-identity 'identity)
@@ -812,7 +870,14 @@ this grossness will be made to disappear by using `call/cc'..."
"Execute the commands in PIPELINE, connecting each to one another."
`(let ((eshell-in-pipeline-p t) tailproc)
(progn
- (eshell-do-pipelines ,pipeline)
+ ,(if (fboundp 'start-process)
+ `(eshell-do-pipelines ,pipeline)
+ `(let ((tail-handles (eshell-create-handles
+ (car (aref eshell-current-handles
+ ,eshell-output-handle)) nil
+ (car (aref eshell-current-handles
+ ,eshell-error-handle)) nil)))
+ (eshell-do-pipelines-synchronously ,pipeline)))
(eshell-process-identity tailproc))))
(defmacro eshell-as-subcommand (command)
@@ -919,12 +984,19 @@ at the moment are:
(erase-buffer)
(insert "command: \"" input "\"\n"))))
(setq eshell-current-command command)
- (eshell-resume-eval)))
+ (let ((delim (catch 'eshell-incomplete
+ (eshell-resume-eval))))
+ (if delim
+ (error "Unmatched delimiter: %c"
+ (if (listp delim)
+ (car delim)
+ delim))))))
(defun eshell-resume-command (proc status)
"Resume the current command when a process ends."
(when proc
- (unless (or (string= "stopped" status)
+ (unless (or (not (stringp status))
+ (string= "stopped" status)
(string-match eshell-reset-signals status))
(if (eq proc (eshell-interactive-process))
(eshell-resume-eval)))))
@@ -941,7 +1013,7 @@ at the moment are:
(setq retval
(eshell-do-eval
eshell-current-command))))))
- (if proc
+ (if (eshell-processp proc)
(ignore (setq eshell-last-async-proc proc))
(cadr retval)))))
(error
@@ -1019,38 +1091,31 @@ be finished later after the completion of an asynchronous subprocess."
(when (car eshell-command-body)
(assert (not synchronous-p))
(eshell-do-eval (car eshell-command-body))
- (setcar eshell-command-body nil))
+ (setcar eshell-command-body nil)
+ (setcar eshell-test-body nil))
(unless (car eshell-test-body)
(setcar eshell-test-body (eshell-copy-tree (car args))))
- (if (and (car eshell-test-body)
- (not (eq (car eshell-test-body) 0)))
- (while (cadr (eshell-do-eval (car eshell-test-body)))
- (setcar eshell-test-body 0)
- (setcar eshell-command-body (eshell-copy-tree (cadr args)))
- (eshell-do-eval (car eshell-command-body) synchronous-p)
- (setcar eshell-command-body nil)
- (setcar eshell-test-body (eshell-copy-tree (car args)))))
+ (while (cadr (eshell-do-eval (car eshell-test-body)))
+ (setcar eshell-command-body (eshell-copy-tree (cadr args)))
+ (eshell-do-eval (car eshell-command-body) synchronous-p)
+ (setcar eshell-command-body nil)
+ (setcar eshell-test-body (eshell-copy-tree (car args))))
(setcar eshell-command-body nil))
((eq (car form) 'if)
;; `eshell-copy-tree' is needed here so that the test argument
;; doesn't get modified and thus always yield the same result.
- (when (car eshell-command-body)
- (assert (not synchronous-p))
- (eshell-do-eval (car eshell-command-body))
- (setcar eshell-command-body nil))
- (unless (car eshell-test-body)
- (setcar eshell-test-body (eshell-copy-tree (car args))))
- (if (and (car eshell-test-body)
- (not (eq (car eshell-test-body) 0)))
- (if (cadr (eshell-do-eval (car eshell-test-body)))
- (progn
- (setcar eshell-test-body 0)
- (setcar eshell-command-body (eshell-copy-tree (cadr args)))
- (eshell-do-eval (car eshell-command-body) synchronous-p))
- (setcar eshell-test-body 0)
- (setcar eshell-command-body (eshell-copy-tree (car (cddr args))))
- (eshell-do-eval (car eshell-command-body) synchronous-p)))
- (setcar eshell-command-body nil))
+ (if (car eshell-command-body)
+ (progn
+ (assert (not synchronous-p))
+ (eshell-do-eval (car eshell-command-body)))
+ (unless (car eshell-test-body)
+ (setcar eshell-test-body (eshell-copy-tree (car args))))
+ (if (cadr (eshell-do-eval (car eshell-test-body)))
+ (setcar eshell-command-body (eshell-copy-tree (cadr args)))
+ (setcar eshell-command-body (eshell-copy-tree (car (cddr args)))))
+ (eshell-do-eval (car eshell-command-body) synchronous-p))
+ (setcar eshell-command-body nil)
+ (setcar eshell-test-body nil))
((eq (car form) 'setcar)
(setcar (cdr args) (eshell-do-eval (cadr args) synchronous-p))
(eval form))
@@ -1131,7 +1196,7 @@ be finished later after the completion of an asynchronous subprocess."
(if (and (memq (car form) eshell-deferrable-commands)
(not eshell-current-subjob-p)
result
- (processp result))
+ (eshell-processp result))
(if synchronous-p
(eshell/wait result)
(eshell-manipulate "inserting ignore form"
@@ -1172,7 +1237,8 @@ be finished later after the completion of an asynchronous subprocess."
(setq desc (substring desc 0
(1- (or (string-match "\n" desc)
(length desc)))))
- (kill-buffer "*Help*")
+ (if (buffer-live-p (get-buffer "*Help*"))
+ (kill-buffer "*Help*"))
(setq program (or desc name))))))
(if (not program)
(eshell-error (format "which: no %s in (%s)\n"
diff --git a/lisp/eshell/esh-ext.el b/lisp/eshell/esh-ext.el
index c4d031131a7..3aec7f22fd8 100644
--- a/lisp/eshell/esh-ext.el
+++ b/lisp/eshell/esh-ext.el
@@ -103,11 +103,9 @@ wholly ignored."
"Invoke a .BAT or .CMD file on DOS/Windows systems."
;; since CMD.EXE can't handle forward slashes in the initial
;; argument...
- (setcar args (subst-char-in-string directory-sep-char
- ?\\ (car args)))
+ (setcar args (subst-char-in-string directory-sep-char ?\\ (car args)))
(throw 'eshell-replace-command
- (eshell-parse-command eshell-windows-shell-file
- (cons "/c" args))))
+ (eshell-parse-command eshell-windows-shell-file (cons "/c" args))))
(defcustom eshell-interpreter-alist
(if (eshell-under-windows-p)
diff --git a/lisp/eshell/esh-io.el b/lisp/eshell/esh-io.el
index f59c1ef47b2..84dbbc18e07 100644
--- a/lisp/eshell/esh-io.el
+++ b/lisp/eshell/esh-io.el
@@ -132,8 +132,8 @@ the function is expected to return another function -- which is the
output function. Otherwise, the second element itself is the output
function.
-The output function is then called repeatedly with a single strings,
-with represents success pieces of the output of the command, until nil
+The output function is then called repeatedly with single strings,
+which represents successive pieces of the output of the command, until nil
is passed, meaning EOF.
NOTE: /dev/null is handled specially as a virtual target, and should
@@ -231,7 +231,9 @@ not be added to this variable."
(standard-output output-mode &optional standard-error error-mode)
"Create a new set of file handles for a command.
The default location for standard output and standard error will go to
-STANDARD-OUTPUT and STANDARD-ERROR, respectively."
+STANDARD-OUTPUT and STANDARD-ERROR, respectively.
+OUTPUT-MODE and ERROR-MODE are either `overwrite', `append' or `insert';
+a nil value of mode defaults to `insert'."
(let ((handles (make-vector eshell-number-of-handles nil))
(output-target (eshell-get-target standard-output output-mode))
(error-target (eshell-get-target standard-error error-mode)))
@@ -272,7 +274,7 @@ STATUS should be non-nil on successful termination of the output."
;; If we're redirecting to a process (via a pipe, or process
;; redirection), send it EOF so that it knows we're finished.
- ((processp target)
+ ((eshell-processp target)
(if (eq (process-status target) 'run)
(process-send-eof target)))
@@ -326,7 +328,8 @@ last execution result should not be changed."
(defun eshell-get-target (target &optional mode)
"Convert TARGET, which is a raw argument, into a valid output target.
-MODE is either `overwrite', `append' or `insert'."
+MODE is either `overwrite', `append' or `insert'; if it is omitted or nil,
+it defaults to `insert'."
(setq mode (or mode 'insert))
(cond
((stringp target)
@@ -367,7 +370,7 @@ MODE is either `overwrite', `append' or `insert'."
(if (eq mode 'overwrite)
(set target nil))
target)
- ((or (processp target)
+ ((or (eshell-processp target)
(markerp target))
target)
(t
@@ -394,7 +397,7 @@ MODE is either `overwrite', `append' or `insert'."
(if (and (listp current)
(not (member where current)))
(setq current (append current (list where)))
- (setq current (list where)))
+ (setq current where))
(if (not (aref eshell-current-handles index))
(aset eshell-current-handles index (cons nil 1)))
(setcar (aref eshell-current-handles index) current)))))
@@ -438,20 +441,20 @@ after all printing is over with no argument."
eshell-print-queue-count (1+ eshell-print-queue-count))))
(defsubst eshell-print (object)
- "Output OBJECT to the error handle."
+ "Output OBJECT to the standard output handle."
(eshell-output-object object eshell-output-handle))
(defsubst eshell-error (object)
- "Output OBJECT to the error handle."
+ "Output OBJECT to the standard error handle."
(eshell-output-object object eshell-error-handle))
(defsubst eshell-errorn (object)
- "Output OBJECT to the error handle."
+ "Output OBJECT followed by a newline to the standard error handle."
(eshell-error object)
(eshell-error "\n"))
(defsubst eshell-printn (object)
- "Output OBJECT to the error handle."
+ "Output OBJECT followed by a newline to the standard output handle."
(eshell-print object)
(eshell-print "\n"))
@@ -485,7 +488,7 @@ Returns what was actually sent, or nil if nothing was sent."
(if moving
(goto-char target))))))
- ((processp target)
+ ((eshell-processp target)
(when (eq (process-status target) 'run)
(setq object (eshell-stringify object))
(process-send-string target object)))
diff --git a/lisp/eshell/esh-mode.el b/lisp/eshell/esh-mode.el
index 0bb07734c14..2db4f2a10b6 100644
--- a/lisp/eshell/esh-mode.el
+++ b/lisp/eshell/esh-mode.el
@@ -474,6 +474,7 @@ sessions, such as when using `eshell-command'.")
(defun eshell-find-tag (&optional tagname next-p regexp-p)
"A special version of `find-tag' that ignores read-onlyness."
(interactive)
+ (require 'etags)
(let ((inhibit-read-only t)
(no-default (eobp)))
(setq tagname (find-tag-interactive "Find tag: " no-default))
diff --git a/lisp/eshell/esh-proc.el b/lisp/eshell/esh-proc.el
index ead49e1942f..ddb2c986a96 100644
--- a/lisp/eshell/esh-proc.el
+++ b/lisp/eshell/esh-proc.el
@@ -125,14 +125,15 @@ information, for example."
"Reset the command input location after a process terminates.
The signals which will cause this to happen are matched by
`eshell-reset-signals'."
- (if (string-match eshell-reset-signals status)
+ (if (and (stringp status)
+ (string-match eshell-reset-signals status))
(eshell-reset)))
(defun eshell-wait-for-process (&rest procs)
"Wait until PROC has successfully completed."
(while procs
(let ((proc (car procs)))
- (when (processp proc)
+ (when (eshell-processp proc)
;; NYI: If the process gets stopped here, that's bad.
(while (assq proc eshell-process-list)
(if (input-pending-p)
@@ -145,7 +146,8 @@ The signals which will cause this to happen are matched by
(defun eshell/jobs (&rest args)
"List processes, if there are any."
- (and (process-list)
+ (and (fboundp 'process-list)
+ (process-list)
(list-processes)))
(defun eshell/kill (&rest args)
@@ -153,7 +155,7 @@ The signals which will cause this to happen are matched by
(let ((ptr args)
(signum 'SIGINT))
(while ptr
- (if (or (processp (car ptr))
+ (if (or (eshell-processp (car ptr))
(and (stringp (car ptr))
(string-match "^[A-Za-z/][A-Za-z0-9<>/]+$"
(car ptr))))
@@ -162,7 +164,7 @@ The signals which will cause this to happen are matched by
(setcar ptr (get-process (car ptr))))
(setq ptr (cdr ptr)))
(while args
- (let ((id (if (processp (car args))
+ (let ((id (if (eshell-processp (car args))
(process-id (car args))
(car args))))
(when id
@@ -206,7 +208,7 @@ The prompt will be set to PROMPT."
(defsubst eshell-record-process-object (object)
"Record OBJECT as now running."
- (if (and (processp object)
+ (if (and (eshell-processp object)
eshell-current-subjob-p)
(eshell-interactive-print
(format "[%s] %d\n" (process-name object) (process-id object))))
@@ -217,7 +219,7 @@ The prompt will be set to PROMPT."
(defun eshell-remove-process-entry (entry)
"Record the process ENTRY as fully completed."
- (if (and (processp (car entry))
+ (if (and (eshell-processp (car entry))
(nth 2 entry)
eshell-done-messages-in-minibuffer)
(message (format "[%s]+ Done %s" (process-name (car entry))
@@ -225,6 +227,12 @@ The prompt will be set to PROMPT."
(setq eshell-process-list
(delq entry eshell-process-list)))
+(defvar eshell-scratch-buffer " *eshell-scratch*"
+ "Scratch buffer for holding Eshell's input/output.")
+(defvar eshell-last-sync-output-start nil
+ "A marker that tracks the beginning of output of the last subprocess.
+Used only on systems which do not support async subprocesses.")
+
(defun eshell-gather-process-output (command args)
"Gather the output from COMMAND + ARGS."
(unless (and (file-executable-p command)
@@ -235,39 +243,88 @@ The prompt will be set to PROMPT."
eshell-delete-exited-processes
delete-exited-processes))
(process-environment (eshell-environment-variables))
- (proc (apply 'start-process
- (file-name-nondirectory command) nil
- ;; `start-process' can't deal with relative
- ;; filenames
- (append (list (expand-file-name command)) args)))
- decoding encoding changed)
- (eshell-record-process-object proc)
- (set-process-buffer proc (current-buffer))
- (if (eshell-interactive-output-p)
- (set-process-filter proc 'eshell-output-filter)
- (set-process-filter proc 'eshell-insertion-filter))
- (set-process-sentinel proc 'eshell-sentinel)
- (run-hook-with-args 'eshell-exec-hook proc)
- (when (fboundp 'process-coding-system)
- (let ((coding-systems (process-coding-system proc)))
- (setq decoding (car coding-systems)
- encoding (cdr coding-systems)))
- ;; If start-process decided to use some coding system for
- ;; decoding data sent from the process and the coding system
- ;; doesn't specify EOL conversion, we had better convert CRLF
- ;; to LF.
- (if (vectorp (coding-system-eol-type decoding))
- (setq decoding (coding-system-change-eol-conversion decoding 'dos)
- changed t))
- ;; Even if start-process left the coding system for encoding
- ;; data sent from the process undecided, we had better use the
- ;; same one as what we use for decoding. But, we should
- ;; suppress EOL conversion.
- (if (and decoding (not encoding))
- (setq encoding (coding-system-change-eol-conversion decoding 'unix)
- changed t))
- (if changed
- (set-process-coding-system proc decoding encoding)))
+ proc decoding encoding changed)
+ (cond
+ ((fboundp 'start-process)
+ (setq proc
+ (apply 'start-process
+ (file-name-nondirectory command) nil
+ ;; `start-process' can't deal with relative
+ ;; filenames
+ (append (list (expand-file-name command)) args)))
+ (eshell-record-process-object proc)
+ (set-process-buffer proc (current-buffer))
+ (if (eshell-interactive-output-p)
+ (set-process-filter proc 'eshell-output-filter)
+ (set-process-filter proc 'eshell-insertion-filter))
+ (set-process-sentinel proc 'eshell-sentinel)
+ (run-hook-with-args 'eshell-exec-hook proc)
+ (when (fboundp 'process-coding-system)
+ (let ((coding-systems (process-coding-system proc)))
+ (setq decoding (car coding-systems)
+ encoding (cdr coding-systems)))
+ ;; If start-process decided to use some coding system for
+ ;; decoding data sent from the process and the coding system
+ ;; doesn't specify EOL conversion, we had better convert CRLF
+ ;; to LF.
+ (if (vectorp (coding-system-eol-type decoding))
+ (setq decoding (coding-system-change-eol-conversion decoding 'dos)
+ changed t))
+ ;; Even if start-process left the coding system for encoding
+ ;; data sent from the process undecided, we had better use the
+ ;; same one as what we use for decoding. But, we should
+ ;; suppress EOL conversion.
+ (if (and decoding (not encoding))
+ (setq encoding (coding-system-change-eol-conversion decoding 'unix)
+ changed t))
+ (if changed
+ (set-process-coding-system proc decoding encoding))))
+ (t
+ ;; No async subprocesses...
+ (let ((oldbuf (current-buffer))
+ (interact-p (eshell-interactive-output-p))
+ lbeg lend line proc-buf exit-status)
+ (and (not (markerp eshell-last-sync-output-start))
+ (setq eshell-last-sync-output-start (point-marker)))
+ (setq proc-buf
+ (set-buffer (get-buffer-create eshell-scratch-buffer)))
+ (erase-buffer)
+ (set-buffer oldbuf)
+ (run-hook-with-args 'eshell-exec-hook command)
+ (setq exit-status
+ (apply 'call-process-region
+ (append (list eshell-last-sync-output-start (point)
+ command t
+ eshell-scratch-buffer nil)
+ args)))
+ ;; When in a pipeline, record the place where the output of
+ ;; this process will begin.
+ (and eshell-in-pipeline-p
+ (set-marker eshell-last-sync-output-start (point)))
+ ;; Simulate the effect of the process filter.
+ (when (numberp exit-status)
+ (set-buffer proc-buf)
+ (goto-char (point-min))
+ (setq lbeg (point))
+ (while (eq 0 (forward-line 1))
+ (setq lend (point)
+ line (buffer-substring-no-properties lbeg lend))
+ (set-buffer oldbuf)
+ (if interact-p
+ (eshell-output-filter nil line)
+ (eshell-output-object line))
+ (setq lbeg lend)
+ (set-buffer proc-buf))
+ (set-buffer oldbuf))
+ (eshell-update-markers eshell-last-output-end)
+ ;; Simulate the effect of eshell-sentinel.
+ (eshell-close-handles (if (numberp exit-status) exit-status -1))
+ (run-hook-with-args 'eshell-kill-hook command exit-status)
+ (or eshell-in-pipeline-p
+ (setq eshell-last-sync-output-start nil))
+ (if (not (numberp exit-status))
+ (error "%s: external command failed: %s" command exit-status))
+ (setq proc t))))
proc))
(defun eshell-insertion-filter (proc string)
diff --git a/lisp/eshell/esh-util.el b/lisp/eshell/esh-util.el
index de19b636100..3d650928c62 100644
--- a/lisp/eshell/esh-util.el
+++ b/lisp/eshell/esh-util.el
@@ -262,7 +262,7 @@ If N or M is nil, it means the end of the list."
(put 'eshell-for 'lisp-indent-function 2)
-(defsubst eshell-flatten-list (args)
+(defun eshell-flatten-list (args)
"Flatten any lists within ARGS, so that there are no sublists."
(let ((new-list (list t)))
(eshell-for a args
diff --git a/lisp/eshell/esh-var.el b/lisp/eshell/esh-var.el
index 133239703b6..34994630251 100644
--- a/lisp/eshell/esh-var.el
+++ b/lisp/eshell/esh-var.el
@@ -264,7 +264,7 @@ function), and the arguments passed to this function would be the list
"Parse a variable interpolation.
This function is explicit for adding to `eshell-parse-argument-hook'."
(when (and (eq (char-after) ?$)
- (not (= (1+ (point)) (point-max))))
+ (/= (1+ (point)) (point-max)))
(forward-char)
(list 'eshell-escape-arg
(eshell-parse-variable))))
@@ -293,11 +293,19 @@ This function is explicit for adding to `eshell-parse-argument-hook'."
(defun eshell/export (&rest sets)
"This alias allows the 'export' command to act as bash users expect."
(while sets
- (if (string-match "^\\([^=]+\\)=\\(.*\\)" (car sets))
+ (if (and (stringp (car sets))
+ (string-match "^\\([^=]+\\)=\\(.*\\)" (car sets)))
(setenv (match-string 1 (car sets))
(match-string 2 (car sets))))
(setq sets (cdr sets))))
+(defun eshell/unset (&rest args)
+ "Unset an environment variable."
+ (while args
+ (if (stringp (car args))
+ (setenv (car args) nil t))
+ (setq args (cdr args))))
+
(defun pcomplete/eshell-mode/export ()
"Completion function for Eshell's `export'."
(while (pcomplete-here
diff --git a/lisp/pcmpl-gnu.el b/lisp/pcmpl-gnu.el
index f390f541e25..f7a681c803e 100644
--- a/lisp/pcmpl-gnu.el
+++ b/lisp/pcmpl-gnu.el
@@ -33,7 +33,7 @@
;; User Variables:
(defcustom pcmpl-gnu-makefile-regexps
- '("\\`Makefile\\." "\\.mak\\'")
+ '("\\`GNUmakefile" "\\`Makefile" "\\.mak\\'")
"*A list of regexps that will match Makefile names."
:type '(repeat regexp)
:group 'pcmpl-gnu)
@@ -111,7 +111,10 @@
(defun pcmpl-gnu-make-rule-names ()
"Return a list of possible make rule names in MAKEFILE."
(let* ((minus-f (member "-f" pcomplete-args))
- (makefile (or (cadr minus-f) "Makefile"))
+ (makefile (or (cadr minus-f)
+ (if (file-exists-p "GNUmakefile")
+ "GNUmakefile"
+ "Makefile")))
rules)
(if (not (file-readable-p makefile))
(unless minus-f (list "-f"))
diff --git a/lisp/pcomplete.el b/lisp/pcomplete.el
index 2b66b1d45b9..4f506212230 100644
--- a/lisp/pcomplete.el
+++ b/lisp/pcomplete.el
@@ -303,6 +303,14 @@ This function is used to generate completions for every argument."
:type 'function
:group 'pcomplete)
+(defcustom pcomplete-use-paring t
+ "*If t, pare alternatives that have already been used.
+If nil, you will always see the completion set of possible options, no
+matter which of those options have already been used in previous
+command arguments."
+ :type 'boolean
+ :group 'pcomplete)
+
;;; Internal Variables:
;; for cycling completion support
@@ -1017,7 +1025,7 @@ extra checking, and munging of the COMPLETIONS list."
(message "No completions of %s" stub)
(message "No completions")))
;; pare it down, if applicable
- (if pcomplete-seen
+ (if (and pcomplete-use-paring pcomplete-seen)
(let* ((arg (pcomplete-arg))
(prefix
(file-name-as-directory