Merge from emacs--rel--22
[bpt/emacs.git] / lisp / eshell / em-unix.el
index 6db127a..e970c87 100644 (file)
@@ -1,6 +1,7 @@
 ;;; em-unix.el --- UNIX command aliases
 
-;; Copyright (C) 1999, 2000, 2001 Free Software Foundation
+;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004,
+;;   2005, 2006, 2007 Free Software Foundation, Inc.
 
 ;; Author: John Wiegley <johnw@gnu.org>
 
@@ -8,7 +9,7 @@
 
 ;; 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 2, or (at your option)
+;; the Free Software Foundation; either version 3, or (at your option)
 ;; any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 
 ;; 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., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
 
-(provide 'em-unix)
+;;; Commentary:
+
+;; This file contains implementations of several UNIX command in Emacs
+;; Lisp, for several reasons:
+;;
+;;   1) it makes them available on all platforms where the Lisp
+;;      functions used are available
+;;
+;;   2) it makes their functionality accessible and modified by the
+;;      Lisp programmer.
+;;
+;;   3) it allows Eshell to refrain from having to invoke external
+;;      processes for common operations.
 
-(eval-when-compile (require 'esh-maint))
+;;; Code:
+
+(require 'eshell)
 
 (defgroup eshell-unix nil
   "This module defines many of the more common UNIX utilities as
@@ -38,20 +53,6 @@ by name)."
   :tag "UNIX commands in Lisp"
   :group 'eshell-module)
 
-;;; Commentary:
-
-;; This file contains implementations of several UNIX command in Emacs
-;; Lisp, for several reasons:
-;;
-;;   1) it makes them available on all platforms where the Lisp
-;;      functions used are available
-;;
-;;   2) it makes their functionality accessible and modified by the
-;;      Lisp programmer.
-;;
-;;   3) it allows Eshell to refrain from having to invoke external
-;;      processes for common operations.
-
 (defcustom eshell-unix-load-hook '(eshell-unix-initialize)
   "*A list of functions to run when `eshell-unix' is loaded."
   :type 'hook
@@ -76,7 +77,7 @@ receiving side of a command pipeline."
   :type 'boolean
   :group 'eshell-unix)
 
-(defcustom eshell-plain-locate-behavior nil
+(defcustom eshell-plain-locate-behavior (featurep 'xemacs)
   "*If non-nil, standalone \"locate\" commands will behave normally.
 Standalone in this context means not redirected, and not on the
 receiving side of a command pipeline."
@@ -135,15 +136,11 @@ Otherwise, Emacs will attempt to use rsh to invoke du on the remote machine."
   :type 'boolean
   :group 'eshell-unix)
 
-(require 'esh-opt)
-
 ;;; Functions:
 
 (defun eshell-unix-initialize ()
   "Initialize the UNIX support/emulation code."
-  (make-local-hook 'eshell-post-command-hook)
   (when (eshell-using-module 'eshell-cmpl)
-    (make-local-hook 'pcomplete-try-first-hook)
     (add-hook 'pcomplete-try-first-hook
              'eshell-complete-host-reference nil t))
   (make-local-variable 'eshell-complex-commands)
@@ -168,6 +165,35 @@ Otherwise, Emacs will attempt to use rsh to invoke du on the remote machine."
 
 (put 'eshell/man 'eshell-no-numeric-conversions t)
 
+(defun eshell/info (&rest args)
+  "Run the info command in-frame with the same behavior as command-line `info', ie:
+  'info'           => goes to top info window
+  'info arg1'      => IF arg1 is a file, then visits arg1
+  'info arg1'      => OTHERWISE goes to top info window and then menu item arg1
+  'info arg1 arg2' => does action for arg1 (either visit-file or menu-item) and then menu item arg2
+  etc."
+  (eval-and-compile (require 'info))
+  (let ((file (cond
+                ((not (stringp (car args)))
+                 nil)
+                ((file-exists-p (expand-file-name (car args)))
+                 (expand-file-name (car args)))
+                ((file-exists-p (concat (expand-file-name (car args)) ".info"))
+                 (concat (expand-file-name (car args)) ".info")))))
+
+    ;; If the first arg is a file, then go to that file's Top node
+    ;; Otherwise, go to the global directory
+    (if file
+      (progn
+        (setq args (cdr args))
+        (Info-find-node file "Top"))
+      (Info-directory))
+
+    ;; Treat all remaining args as menu references
+    (while args
+      (Info-menu (car args))
+      (setq args (cdr args)))))
+
 (defun eshell-remove-entries (path files &optional top-level)
   "From PATH, remove all of the given FILES, perhaps interactively."
   (while files
@@ -342,9 +368,11 @@ Remove the DIRECTORY(ies), if they are empty.")
                 (eq system-type 'ms-dos))
             (setq attr (eshell-file-attributes (car files)))
             (nth 10 attr-target) (nth 10 attr)
-            (= (nth 10 attr-target) (nth 10 attr))
+            ;; Use equal, not -, since the inode and the device could
+            ;; cons cells.
+            (equal (nth 10 attr-target) (nth 10 attr))
             (nth 11 attr-target) (nth 11 attr)
-            (= (nth 11 attr-target) (nth 11 attr)))
+            (equal (nth 11 attr-target) (nth 11 attr)))
        (eshell-error (format "%s: `%s' and `%s' are the same file\n"
                              command (car files) target)))
        (t
@@ -366,14 +394,16 @@ Remove the DIRECTORY(ies), if they are empty.")
                (let (eshell-warn-dot-directories)
                  (if (and (not deep)
                           (eq func 'rename-file)
-                          (= (nth 11 (eshell-file-attributes
-                                      (file-name-directory
-                                       (directory-file-name
-                                        (expand-file-name source)))))
-                             (nth 11 (eshell-file-attributes
-                                      (file-name-directory
-                                       (directory-file-name
-                                        (expand-file-name target)))))))
+                          ;; Use equal, since the device might be a
+                          ;; cons cell.
+                          (equal (nth 11 (eshell-file-attributes
+                                          (file-name-directory
+                                           (directory-file-name
+                                            (expand-file-name source)))))
+                                 (nth 11 (eshell-file-attributes
+                                          (file-name-directory
+                                           (directory-file-name
+                                            (expand-file-name target)))))))
                      (apply 'eshell-funcalln func source target args)
                  (unless (file-directory-p target)
                    (if verbose
@@ -568,9 +598,12 @@ symlink, then revert to the system's definition of cat."
   (if (or eshell-in-pipeline-p
          (catch 'special
            (eshell-for arg args
-             (unless (let ((attrs (eshell-file-attributes arg)))
-                       (and attrs (memq (aref (nth 8 attrs) 0)
-                                        '(?d ?l ?-))))
+             (unless (or (and (stringp arg)
+                              (> (length arg) 0)
+                              (eq (aref arg 0) ?-))
+                         (let ((attrs (eshell-file-attributes arg)))
+                           (and attrs (memq (aref (nth 8 attrs) 0)
+                                            '(?d ?l ?-)))))
                (throw 'special t)))))
       (let ((ext-cat (eshell-search-path "cat")))
        (if ext-cat
@@ -636,13 +669,12 @@ Concatenate FILE(s), or standard input, to standard output.")
 (defun eshell-occur-mode-mouse-goto (event)
   "In Occur mode, go to the occurrence whose line you click on."
   (interactive "e")
-  (let (buffer pos)
+  (let (pos)
     (save-excursion
       (set-buffer (window-buffer (posn-window (event-end event))))
       (save-excursion
        (goto-char (posn-point (event-end event)))
-       (setq pos (occur-mode-find-occurrence))
-       (setq buffer occur-buffer)))
+       (setq pos (occur-mode-find-occurrence))))
     (pop-to-buffer (marker-buffer pos))
     (goto-char (marker-position pos))))
 
@@ -678,7 +710,6 @@ available..."
                (if string (insert string))
                (setq string nil
                      files (cdr files)))))
-         (setq occur-buffer (current-buffer))
          (local-set-key [mouse-2] 'eshell-occur-mode-mouse-goto)
          (local-set-key [(control ?c) (control ?c)]
                         'eshell-occur-mode-goto-occurrence)
@@ -704,11 +735,7 @@ external command."
               (eshell-parse-command (concat "*" command)
                                     (eshell-stringify-list
                                      (eshell-flatten-list args))))
-      (let* ((compilation-process-setup-function
-             (list 'lambda nil
-                   (list 'setq 'process-environment
-                         (list 'quote (eshell-copy-environment)))))
-            (args (mapconcat 'identity
+      (let* ((args (mapconcat 'identity
                              (mapcar 'shell-quote-argument
                                      (eshell-stringify-list
                                       (eshell-flatten-list args)))
@@ -799,7 +826,7 @@ external command."
        (size 0.0))
     (while entries
       (unless (string-match "\\`\\.\\.?\\'" (caar entries))
-       (let* ((entry (concat path (char-to-string directory-sep-char)
+       (let* ((entry (concat path "/"
                              (caar entries)))
               (symlink (and (stringp (cadr (car entries)))
                             (cadr (car entries)))))
@@ -877,7 +904,7 @@ Summarize disk usage of each FILE, recursively for directories.")
        (unless by-bytes
         (setq block-size (or block-size 1024)))
        (if (and max-depth (stringp max-depth))
-          (setq max-depth (string-to-int max-depth)))
+          (setq max-depth (string-to-number max-depth)))
        ;; filesystem support means nothing under Windows
        (if (eshell-under-windows-p)
           (setq only-one-filesystem nil))
@@ -929,7 +956,10 @@ Show wall-clock time elapsed during execution of COMMAND.")
      (add-hook 'eshell-post-command-hook 'eshell-show-elapsed-time nil t)
      ;; after setting
      (throw 'eshell-replace-command
-           (eshell-parse-command (car time-args) (cdr time-args))))))
+           (eshell-parse-command (car time-args)
+;;; http://lists.gnu.org/archive/html/bug-gnu-emacs/2007-08/msg00205.html
+                                 (eshell-stringify-list
+                                  (eshell-flatten-list (cdr time-args))))))))
 
 (defalias 'eshell/whoami 'user-login-name)
 
@@ -941,6 +971,12 @@ Show wall-clock time elapsed during execution of COMMAND.")
   (if eshell-diff-window-config
       (set-window-configuration eshell-diff-window-config)))
 
+(defun nil-blank-string (string)
+  "Return STRING, or nil if STRING contains only non-blank characters."
+  (cond
+    ((string-match "[^[:blank:]]" string) string)
+    (nil)))
+
 (defun eshell/diff (&rest args)
   "Alias \"diff\" to call Emacs `diff' function."
   (let ((orig-args (eshell-stringify-list (eshell-flatten-list args))))
@@ -950,7 +986,7 @@ Show wall-clock time elapsed during execution of COMMAND.")
                      (not eshell-in-subcommand-p))))
        (throw 'eshell-replace-command
               (eshell-parse-command "*diff" orig-args))
-      (setq args (eshell-copy-list orig-args))
+      (setq args (copy-sequence orig-args))
       (if (< (length args) 2)
          (throw 'eshell-replace-command
                 (eshell-parse-command "*diff" orig-args)))
@@ -962,7 +998,8 @@ Show wall-clock time elapsed during execution of COMMAND.")
          (setcdr (last args 3) nil))
        (with-current-buffer
            (condition-case err
-               (diff old new (eshell-flatten-and-stringify args))
+               (diff old new
+                     (nil-blank-string (eshell-flatten-and-stringify args)))
              (error
               (throw 'eshell-replace-command
                      (eshell-parse-command "*diff" orig-args))))
@@ -1010,6 +1047,7 @@ Show wall-clock time elapsed during execution of COMMAND.")
 
 (put 'eshell/occur 'eshell-no-numeric-conversions t)
 
-;;; Code:
+(provide 'em-unix)
 
+;;; arch-tag: 2462edd2-a76a-4cf2-897d-92e9a82ac1c9
 ;;; em-unix.el ends here