29876
|
1 ;;; em-basic --- basic shell builtin commands
|
|
2
|
|
3 ;; Copyright (C) 1999, 2000 Free Sofware Foundation
|
|
4
|
|
5 ;; This file is part of GNU Emacs.
|
|
6
|
|
7 ;; GNU Emacs is free software; you can redistribute it and/or modify
|
|
8 ;; it under the terms of the GNU General Public License as published by
|
|
9 ;; the Free Software Foundation; either version 2, or (at your option)
|
|
10 ;; any later version.
|
|
11
|
|
12 ;; GNU Emacs is distributed in the hope that it will be useful,
|
|
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15 ;; GNU General Public License for more details.
|
|
16
|
|
17 ;; You should have received a copy of the GNU General Public License
|
|
18 ;; along with GNU Emacs; see the file COPYING. If not, write to the
|
|
19 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
20 ;; Boston, MA 02111-1307, USA.
|
|
21
|
|
22 (provide 'em-basic)
|
|
23
|
|
24 (eval-when-compile (require 'esh-maint))
|
|
25
|
|
26 (defgroup eshell-basic nil
|
|
27 "The \"basic\" code provides a set of convenience functions which
|
|
28 are traditionally considered shell builtins. Since all of the
|
|
29 functionality provided by them is accessible through Lisp, they are
|
|
30 not really builtins at all, but offer a command-oriented way to do the
|
|
31 same thing."
|
|
32 :tag "Basic shell commands"
|
|
33 :group 'eshell-module)
|
|
34
|
|
35 ;;; Commentary:
|
|
36
|
|
37 ;; There are very few basic Eshell commands -- so-called builtins.
|
|
38 ;; They are: echo, umask, and version.
|
|
39 ;;
|
|
40 ;;;_* `echo'
|
|
41 ;;
|
|
42 ;; The `echo' command repeats its arguments to the screen. It is
|
|
43 ;; optional whether this is done in a Lisp-friendly fashion (so that
|
|
44 ;; the value of echo is useful to a Lisp command using the result of
|
|
45 ;; echo as an argument), or whether it should try to act like a normal
|
|
46 ;; shell echo, and always result in a flat string being returned.
|
|
47
|
|
48 (defcustom eshell-plain-echo-behavior nil
|
|
49 "*If non-nil, `echo' tries to behave like an ordinary shell echo.
|
|
50 This comes at some detriment to Lisp functionality. However, the Lisp
|
|
51 equivalent of `echo' can always be achieved by using `identity'."
|
|
52 :type 'boolean
|
|
53 :group 'eshell-basic)
|
|
54
|
|
55 ;;;
|
|
56 ;; An example of the difference is the following:
|
|
57 ;;
|
|
58 ;; echo Hello world
|
|
59 ;;
|
|
60 ;; If `eshell-plain-echo-behavior' is non-nil, this will yield the
|
|
61 ;; string "Hello world". If Lisp behavior is enabled, however, it
|
|
62 ;; will yield a list whose two elements are the strings "Hello" and
|
|
63 ;; "world". The way to write an equivalent expression for both would
|
|
64 ;; be:
|
|
65 ;;
|
|
66 ;; echo "Hello world"
|
|
67 ;;
|
|
68 ;; This always returns a single string.
|
|
69 ;;
|
|
70 ;;;_* `umask'
|
|
71 ;;
|
|
72 ;; The umask command changes the default file permissions for newly
|
|
73 ;; created files. It uses the same syntax as bash.
|
|
74 ;;
|
|
75 ;;;_* `version'
|
|
76 ;;
|
|
77 ;; This command reports the version number for Eshell and all its
|
|
78 ;; dependent module, including the date when those modules were last
|
|
79 ;; modified.
|
|
80
|
|
81 ;;; Code:
|
|
82
|
|
83 (require 'esh-opt)
|
|
84
|
|
85 ;;; Functions:
|
|
86
|
|
87 (defun eshell-echo (args &optional output-newline)
|
|
88 "Implementation code for a Lisp version of `echo'.
|
|
89 It returns a formatted value that should be passed to `eshell-print'
|
|
90 or `eshell-printn' for display."
|
|
91 (if eshell-plain-echo-behavior
|
|
92 (concat (apply 'eshell-flatten-and-stringify args) "\n")
|
|
93 (let ((value
|
|
94 (cond
|
|
95 ((= (length args) 0) "")
|
|
96 ((= (length args) 1)
|
|
97 (car args))
|
|
98 (t
|
|
99 (mapcar
|
|
100 (function
|
|
101 (lambda (arg)
|
|
102 (if (stringp arg)
|
|
103 (set-text-properties 0 (length arg) nil arg))
|
|
104 arg))
|
|
105 args)))))
|
|
106 (if output-newline
|
|
107 (cond
|
|
108 ((stringp value)
|
|
109 (concat value "\n"))
|
|
110 ((listp value)
|
|
111 (append value (list "\n")))
|
|
112 (t
|
|
113 (concat (eshell-stringify value) "\n")))
|
|
114 value))))
|
|
115
|
|
116 (defun eshell/echo (&rest args)
|
|
117 "Implementation of `echo'. See `eshell-plain-echo-behavior'."
|
|
118 (eshell-eval-using-options
|
|
119 "echo" args
|
|
120 '((?n nil nil output-newline "terminate with a newline")
|
|
121 (?h "help" nil nil "output this help screen")
|
|
122 :preserve-args
|
|
123 :usage "[-n] [object]")
|
|
124 (eshell-echo args output-newline)))
|
|
125
|
|
126 (defun eshell/printnl (&rest args)
|
|
127 "Print out each of the argument, separated by newlines."
|
|
128 (let ((elems (eshell-flatten-list args)))
|
|
129 (while elems
|
|
130 (eshell-printn (eshell-echo (list (car elems))))
|
|
131 (setq elems (cdr elems)))))
|
|
132
|
|
133 (defun eshell/listify (&rest args)
|
|
134 "Return the argument(s) as a single list."
|
|
135 (if (> (length args) 1)
|
|
136 args
|
|
137 (if (listp (car args))
|
|
138 (car args)
|
|
139 (list (car args)))))
|
|
140
|
|
141 (defun eshell/umask (&rest args)
|
|
142 "Shell-like implementation of `umask'."
|
|
143 (eshell-eval-using-options
|
|
144 "umask" args
|
|
145 '((?S "symbolic" nil symbolic-p "display umask symbolically")
|
|
146 (?h "help" nil nil "display this usage message")
|
|
147 :usage "[-S] [mode]")
|
|
148 (if (or (not args) symbolic-p)
|
|
149 (let ((modstr
|
|
150 (concat "000"
|
|
151 (format "%o"
|
|
152 (logand (lognot (default-file-modes))
|
|
153 511)))))
|
|
154 (setq modstr (substring modstr (- (length modstr) 3)))
|
|
155 (when symbolic-p
|
|
156 (let ((mode (default-file-modes)))
|
|
157 (setq modstr
|
|
158 (format
|
|
159 "u=%s,g=%s,o=%s"
|
|
160 (concat (and (= (logand mode 64) 64) "r")
|
|
161 (and (= (logand mode 128) 128) "w")
|
|
162 (and (= (logand mode 256) 256) "x"))
|
|
163 (concat (and (= (logand mode 8) 8) "r")
|
|
164 (and (= (logand mode 16) 16) "w")
|
|
165 (and (= (logand mode 32) 32) "x"))
|
|
166 (concat (and (= (logand mode 1) 1) "r")
|
|
167 (and (= (logand mode 2) 2) "w")
|
|
168 (and (= (logand mode 4) 4) "x"))))))
|
|
169 (eshell-printn modstr))
|
|
170 (setcar args (eshell-convert (car args)))
|
|
171 (if (numberp (car args))
|
|
172 (set-default-file-modes
|
|
173 (- 511 (car (read-from-string
|
|
174 (concat "?\\" (number-to-string (car args)))))))
|
|
175 (error "setting umask symbolically is not yet implemented"))
|
|
176 (eshell-print
|
|
177 "Warning: umask changed for all new files created by Emacs.\n"))
|
|
178 nil))
|
|
179
|
|
180 (eval-when-compile
|
|
181 (defvar print-func))
|
|
182
|
|
183 ;;; em-basic.el ends here
|