;;; esh-cmd.el --- command invocation
-;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004,
-;; 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+;; 2008, 2009, 2010 Free Software Foundation, Inc.
;; Author: John Wiegley <johnw@gnu.org>
;; This file is part of GNU Emacs.
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
(require 'esh-ext)
(eval-when-compile
+ (require 'cl)
(require 'pcomplete))
(defvar eshell-current-command nil)
(defvar eshell-command-name nil)
(defvar eshell-command-arguments nil)
-(defvar eshell-in-pipeline-p nil)
+(defvar eshell-in-pipeline-p nil
+ "Internal Eshell variable, non-nil inside a pipeline.
+Has the value 'first, 'last for the first/last commands in the pipeline,
+otherwise t.")
(defvar eshell-in-subcommand-p nil)
(defvar eshell-last-arguments nil)
(defvar eshell-last-command-name nil)
"Output a debugging message to '*eshell last cmd*'."
(let ((buf (get-buffer-create "*eshell last cmd*"))
(text (eshell-stringify eshell-current-command)))
- (save-excursion
- (set-buffer buf)
+ (with-current-buffer buf
(if (not tag)
(erase-buffer)
(insert "\n\C-l\n" tag "\n\n" text
"Execute named command"
(eshell-command-result-p "+ 1 2" "3\n"))
-(eval-when-compile
- (defvar eshell-command-body)
- (defvar eshell-test-body))
+(defvar eshell-command-body)
+(defvar eshell-test-body)
(defsubst eshell-invokify-arg (arg &optional share-output silent)
"Change ARG so it can be invoked from a structured command.
(eshell-protect-handles eshell-current-handles)
,object))
-(defmacro eshell-do-pipelines (pipeline)
- "Execute the commands in PIPELINE, connecting each to one another."
+(defmacro eshell-do-pipelines (pipeline &optional notfirst)
+ "Execute the commands in PIPELINE, connecting each to one another.
+This macro calls itself recursively, with NOTFIRST non-nil."
(when (setq pipeline (cadr pipeline))
`(eshell-copy-handles
(progn
`(let (nextproc)
(progn
(set 'nextproc
- (eshell-do-pipelines (quote ,(cdr pipeline))))
+ (eshell-do-pipelines (quote ,(cdr pipeline)) t))
(eshell-set-output-handle ,eshell-output-handle
'append nextproc)
(eshell-set-output-handle ,eshell-error-handle
(setcar head
(intern-soft
(concat (symbol-name (car head)) "*"))))))
- ,(car pipeline)))))
+ ;; First and last elements in a pipeline may need special treatment.
+ ;; (Currently only eshell-ls-files uses 'last.)
+ ;; Affects process-connection-type in eshell-gather-process-output.
+ (let ((eshell-in-pipeline-p
+ ,(cond ((not notfirst) (quote 'first))
+ ((cdr pipeline) t)
+ (t (quote 'last)))))
+ ,(car pipeline))))))
(defmacro eshell-do-pipelines-synchronously (pipeline)
"Execute the commands in PIPELINE in sequence synchronously.
(list 'eshell-do-eval
(list 'quote command)))))
(and eshell-debug-command
- (save-excursion
- (let ((buf (get-buffer-create "*eshell last cmd*")))
- (set-buffer buf)
- (erase-buffer)
- (insert "command: \"" input "\"\n"))))
+ (with-current-buffer (get-buffer-create "*eshell last cmd*")
+ (erase-buffer)
+ (insert "command: \"" input "\"\n")))
(setq eshell-current-command command)
(let ((delim (catch 'eshell-incomplete
(eshell-resume-eval))))
(defmacro eshell-manipulate (tag &rest commands)
"Manipulate a COMMAND form, with TAG as a debug identifier."
- (if (not eshell-debug-command)
+ ;; Check `bound'ness since at compile time the code until here has not
+ ;; executed yet.
+ (if (not (and (boundp 'eshell-debug-command) eshell-debug-command))
`(progn ,@commands)
`(progn
(eshell-debug-command ,(eval tag) form)
(prog1
(describe-function sym)
(message nil))))))
- (setq desc (substring desc 0
- (1- (or (string-match "\n" desc)
- (length desc)))))
+ (setq desc (if desc (substring desc 0
+ (1- (or (string-match "\n" desc)
+ (length desc))))
+ ;; This should not happen.
+ (format "%s is defined, \
+but no documentation was found" name)))
(if (buffer-live-p (get-buffer "*Help*"))
(kill-buffer "*Help*"))
(setq program (or desc name))))))
(provide 'esh-cmd)
-;;; arch-tag: 8e4f3867-a0c5-441f-96ba-ddd142d94366
+;; arch-tag: 8e4f3867-a0c5-441f-96ba-ddd142d94366
;;; esh-cmd.el ends here