-;;; em-unix --- UNIX command aliases
+;;; 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>
;; 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:
-(eval-when-compile (require 'esh-maint))
+;; 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.
+
+;;; Code:
+
+(require 'eshell)
(defgroup eshell-unix nil
"This module defines many of the more common UNIX utilities as
: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
: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."
: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)
"Invoke man, flattening the arguments appropriately."
(funcall 'man (apply 'eshell-flatten-and-stringify args)))
+(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
(setq args (cdr args)))
nil))
+(put 'eshell/rm 'eshell-no-numeric-conversions t)
+
(defun eshell/mkdir (&rest args)
"Implementation of mkdir in Lisp."
(eshell-eval-using-options
(setq args (cdr args)))
nil))
+(put 'eshell/mkdir 'eshell-no-numeric-conversions t)
+
(defun eshell/rmdir (&rest args)
"Implementation of rmdir in Lisp."
(eshell-eval-using-options
(setq args (cdr args)))
nil))
+(put 'eshell/rmdir 'eshell-no-numeric-conversions t)
+
(eval-when-compile
(defvar no-dereference)
(defvar preview)
(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
(let (eshell-warn-dot-directories)
(if (and (not deep)
(eq func 'rename-file)
- (= (nth 11 (eshell-file-attributes
- (file-name-directory
- (expand-file-name source))))
- (nth 11 (eshell-file-attributes
- (file-name-directory
- (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
eshell-mv-interactive-query
eshell-mv-overwrite-files))))
+(put 'eshell/mv 'eshell-no-numeric-conversions t)
+
(defun eshell/cp (&rest args)
"Implementation of cp in Lisp."
(eshell-eval-using-options
eshell-cp-interactive-query
eshell-cp-overwrite-files preserve)))
+(put 'eshell/cp 'eshell-no-numeric-conversions t)
+
(defun eshell/ln (&rest args)
"Implementation of ln in Lisp."
(eshell-eval-using-options
eshell-ln-interactive-query
eshell-ln-overwrite-files))))
+(put 'eshell/ln 'eshell-no-numeric-conversions t)
+
(defun eshell/cat (&rest args)
"Implementation of cat in Lisp.
If in a pipeline, or the file is not a regular file, directory or
(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
;; if the file does not end in a newline, do not emit one
(setq eshell-ensure-newline-p nil))))
+(put 'eshell/cat 'eshell-no-numeric-conversions t)
+
;; special front-end functions for compilation-mode buffers
(defun eshell/make (&rest args)
(eshell-parse-command "*make" (eshell-stringify-list
(eshell-flatten-list args))))))
+(put 'eshell/make 'eshell-no-numeric-conversions t)
+
(defun eshell-occur-mode-goto-occurrence ()
"Go to the occurrence the current line describes."
(interactive)
(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))))
(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)
(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)))
(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)))))
(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))
(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)
(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))))
(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)))
(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))))
(pop-to-buffer (current-buffer))))))
nil)
+(put 'eshell/diff 'eshell-no-numeric-conversions t)
+
(defun eshell/locate (&rest args)
"Alias \"locate\" to call Emacs `locate' function."
(if (or eshell-plain-locate-behavior
(let ((locate-history-list (list (car args))))
(locate-with-filter (car args) (cadr args))))))
+(put 'eshell/locate 'eshell-no-numeric-conversions t)
+
(defun eshell/occur (&rest args)
"Alias \"occur\" to call Emacs `occur' function."
(let ((inhibit-read-only t))
(error "usage: occur: (REGEXP &optional NLINES)")
(apply 'occur args))))
-;;; Code:
+(put 'eshell/occur 'eshell-no-numeric-conversions t)
+
+(provide 'em-unix)
+;;; arch-tag: 2462edd2-a76a-4cf2-897d-92e9a82ac1c9
;;; em-unix.el ends here