summaryrefslogtreecommitdiff
path: root/lisp/eshell/em-basic.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/eshell/em-basic.el')
-rw-r--r--lisp/eshell/em-basic.el183
1 files changed, 183 insertions, 0 deletions
diff --git a/lisp/eshell/em-basic.el b/lisp/eshell/em-basic.el
new file mode 100644
index 00000000000..0a7e9a97573
--- /dev/null
+++ b/lisp/eshell/em-basic.el
@@ -0,0 +1,183 @@
+;;; em-basic --- basic shell builtin commands
+
+;; Copyright (C) 1999, 2000 Free Sofware Foundation
+
+;; This file is part of GNU Emacs.
+
+;; 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)
+;; 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
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; 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., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+(provide 'em-basic)
+
+(eval-when-compile (require 'esh-maint))
+
+(defgroup eshell-basic nil
+ "The \"basic\" code provides a set of convenience functions which
+are traditionally considered shell builtins. Since all of the
+functionality provided by them is accessible through Lisp, they are
+not really builtins at all, but offer a command-oriented way to do the
+same thing."
+ :tag "Basic shell commands"
+ :group 'eshell-module)
+
+;;; Commentary:
+
+;; There are very few basic Eshell commands -- so-called builtins.
+;; They are: echo, umask, and version.
+;;
+;;;_* `echo'
+;;
+;; The `echo' command repeats its arguments to the screen. It is
+;; optional whether this is done in a Lisp-friendly fashion (so that
+;; the value of echo is useful to a Lisp command using the result of
+;; echo as an argument), or whether it should try to act like a normal
+;; shell echo, and always result in a flat string being returned.
+
+(defcustom eshell-plain-echo-behavior nil
+ "*If non-nil, `echo' tries to behave like an ordinary shell echo.
+This comes at some detriment to Lisp functionality. However, the Lisp
+equivalent of `echo' can always be achieved by using `identity'."
+ :type 'boolean
+ :group 'eshell-basic)
+
+;;;
+;; An example of the difference is the following:
+;;
+;; echo Hello world
+;;
+;; If `eshell-plain-echo-behavior' is non-nil, this will yield the
+;; string "Hello world". If Lisp behavior is enabled, however, it
+;; will yield a list whose two elements are the strings "Hello" and
+;; "world". The way to write an equivalent expression for both would
+;; be:
+;;
+;; echo "Hello world"
+;;
+;; This always returns a single string.
+;;
+;;;_* `umask'
+;;
+;; The umask command changes the default file permissions for newly
+;; created files. It uses the same syntax as bash.
+;;
+;;;_* `version'
+;;
+;; This command reports the version number for Eshell and all its
+;; dependent module, including the date when those modules were last
+;; modified.
+
+;;; Code:
+
+(require 'esh-opt)
+
+;;; Functions:
+
+(defun eshell-echo (args &optional output-newline)
+ "Implementation code for a Lisp version of `echo'.
+It returns a formatted value that should be passed to `eshell-print'
+or `eshell-printn' for display."
+ (if eshell-plain-echo-behavior
+ (concat (apply 'eshell-flatten-and-stringify args) "\n")
+ (let ((value
+ (cond
+ ((= (length args) 0) "")
+ ((= (length args) 1)
+ (car args))
+ (t
+ (mapcar
+ (function
+ (lambda (arg)
+ (if (stringp arg)
+ (set-text-properties 0 (length arg) nil arg))
+ arg))
+ args)))))
+ (if output-newline
+ (cond
+ ((stringp value)
+ (concat value "\n"))
+ ((listp value)
+ (append value (list "\n")))
+ (t
+ (concat (eshell-stringify value) "\n")))
+ value))))
+
+(defun eshell/echo (&rest args)
+ "Implementation of `echo'. See `eshell-plain-echo-behavior'."
+ (eshell-eval-using-options
+ "echo" args
+ '((?n nil nil output-newline "terminate with a newline")
+ (?h "help" nil nil "output this help screen")
+ :preserve-args
+ :usage "[-n] [object]")
+ (eshell-echo args output-newline)))
+
+(defun eshell/printnl (&rest args)
+ "Print out each of the argument, separated by newlines."
+ (let ((elems (eshell-flatten-list args)))
+ (while elems
+ (eshell-printn (eshell-echo (list (car elems))))
+ (setq elems (cdr elems)))))
+
+(defun eshell/listify (&rest args)
+ "Return the argument(s) as a single list."
+ (if (> (length args) 1)
+ args
+ (if (listp (car args))
+ (car args)
+ (list (car args)))))
+
+(defun eshell/umask (&rest args)
+ "Shell-like implementation of `umask'."
+ (eshell-eval-using-options
+ "umask" args
+ '((?S "symbolic" nil symbolic-p "display umask symbolically")
+ (?h "help" nil nil "display this usage message")
+ :usage "[-S] [mode]")
+ (if (or (not args) symbolic-p)
+ (let ((modstr
+ (concat "000"
+ (format "%o"
+ (logand (lognot (default-file-modes))
+ 511)))))
+ (setq modstr (substring modstr (- (length modstr) 3)))
+ (when symbolic-p
+ (let ((mode (default-file-modes)))
+ (setq modstr
+ (format
+ "u=%s,g=%s,o=%s"
+ (concat (and (= (logand mode 64) 64) "r")
+ (and (= (logand mode 128) 128) "w")
+ (and (= (logand mode 256) 256) "x"))
+ (concat (and (= (logand mode 8) 8) "r")
+ (and (= (logand mode 16) 16) "w")
+ (and (= (logand mode 32) 32) "x"))
+ (concat (and (= (logand mode 1) 1) "r")
+ (and (= (logand mode 2) 2) "w")
+ (and (= (logand mode 4) 4) "x"))))))
+ (eshell-printn modstr))
+ (setcar args (eshell-convert (car args)))
+ (if (numberp (car args))
+ (set-default-file-modes
+ (- 511 (car (read-from-string
+ (concat "?\\" (number-to-string (car args)))))))
+ (error "setting umask symbolically is not yet implemented"))
+ (eshell-print
+ "Warning: umask changed for all new files created by Emacs.\n"))
+ nil))
+
+(eval-when-compile
+ (defvar print-func))
+
+;;; em-basic.el ends here