Mercurial > emacs
comparison lisp/ls-lisp.el @ 1334:92791ed2d1eb
Most functions renamed to start with ls-lisp.
(insert-directory): Renamed from dired-ls.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Mon, 05 Oct 1992 04:54:07 +0000 |
parents | 5054c696885d |
children | ecf43116a845 |
comparison
equal
deleted
inserted
replaced
1333:5054c696885d | 1334:92791ed2d1eb |
---|---|
1 ;;;; dired-lisp.el - emulate Tree Dired's ls completely in Emacs Lisp | 1 ;;;; directory.el - emulate insert-directory completely in Emacs Lisp |
2 | |
3 ;;;; READ THE WARNING BELOW BEFORE USING THIS PROGRAM! | |
4 | |
5 (defconst dired-lisp-version (substring "$Revision: 1.8 $" 11 -2) | |
6 "$Id: dired-lisp.el,v 1.8 1992/05/01 17:50:56 sk Exp sk $") | |
7 | 2 |
8 ;; Copyright (C) 1992 by Sebastian Kremer <sk@thp.uni-koeln.de> | 3 ;; Copyright (C) 1992 by Sebastian Kremer <sk@thp.uni-koeln.de> |
9 | 4 |
10 ;; This program is free software; you can redistribute it and/or modify | 5 ;; This program is free software; you can redistribute it and/or modify |
11 ;; it under the terms of the GNU General Public License as published by | 6 ;; it under the terms of the GNU General Public License as published by |
19 ;; | 14 ;; |
20 ;; You should have received a copy of the GNU General Public License | 15 ;; You should have received a copy of the GNU General Public License |
21 ;; along with this program; if not, write to the Free Software | 16 ;; along with this program; if not, write to the Free Software |
22 ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 17 ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
23 | 18 |
24 ;; LISPDIR ENTRY for the Elisp Archive =============================== | |
25 ;; LCD Archive Entry: | |
26 ;; dired-lisp|Sebastian Kremer|sk@thp.uni-koeln.de | |
27 ;; |emulate Tree Dired's ls completely in Emacs Lisp | |
28 ;; |$Date: 1992/05/01 17:50:56 $|$Revision: 1.8 $| | |
29 | |
30 ;; INSTALLATION ======================================================= | 19 ;; INSTALLATION ======================================================= |
31 ;; | 20 ;; |
32 ;; Put this file into your load-path. Loading it will result in | 21 ;; Put this file into your load-path. To use it, load it |
33 ;; redefining function dired-ls to not call ls. | 22 ;; with (load "directory"). |
34 | |
35 ;; You need tree dired from ftp.cs.buffalo.edu:pub/Emacs/diredall.tar.Z, | |
36 ;; classic (e.g. 18.57) dired.el will not work. | |
37 | 23 |
38 ;; OVERVIEW =========================================================== | 24 ;; OVERVIEW =========================================================== |
39 | 25 |
40 ;; This file overloads tree dired so that all fileinfo is retrieved | 26 ;; This file overloads the function insert-directory to implement it |
41 ;; directly from Emacs lisp, without using an ls subprocess. | 27 ;; directly from Emacs lisp, without running `ls' in a subprocess. |
42 | 28 |
43 ;; Useful if you cannot afford to fork Emacs on a real memory UNIX, | 29 ;; It is useful if you cannot afford to fork Emacs on a real memory UNIX, |
44 ;; under VMS, or if you don't have the ls program, or if you want | 30 ;; under VMS, or if you don't have the ls program, or if you want |
45 ;; different format from what ls offers. | 31 ;; different format from what ls offers. |
46 | 32 |
47 ;; Beware that if you change the output format of dired-ls, you'll | 33 ;; This function uses regexps instead of shell |
48 ;; have to change dired-move-to-filename and | 34 ;; wildcards. If you enter regexps remember to double each $ sign. |
49 ;; dired-move-to-end-of-filename as well. | 35 ;; For example, to include files *.el, enter `.*\.el$$', |
50 | |
51 ;; With this package is loaded, dired uses regexps instead of shell | |
52 ;; wildcards. If you enter regexps remember to double each $ sign. | |
53 ;; For example, to dired all elisp (*.el) files, enter `.*\.el$$', | |
54 ;; resulting in the regexp `.*\.el$'. | 36 ;; resulting in the regexp `.*\.el$'. |
55 | 37 |
56 ;; WARNING =========================================================== | |
57 | |
58 ;; With earlier version of this program I sometimes got an internal | |
59 ;; Emacs error: | |
60 | |
61 ;; Signalling: (wrong-type-argument natnump #<EMACS BUG: ILLEGAL | |
62 ;; DATATYPE (#o37777777727) Save your buffers immediately and please | |
63 ;; report this bug>) | |
64 | |
65 ;; The datatype differs (I also got #o67 once). | |
66 | |
67 ;; Sometimes emacs just crashed with a fatal error. | |
68 | |
69 ;; After I've avoided using directory-files and file-attributes | |
70 ;; together inside a mapcar, the bug didn't surface any longer. | |
71 | |
72 ;; RESTRICTIONS ===================================================== | 38 ;; RESTRICTIONS ===================================================== |
73 | 39 |
74 ;; * many ls switches are ignored, see docstring of `dired-ls'. | 40 ;; * many ls switches are ignored, see docstring of `insert-directory'. |
75 | |
76 ;; * In Emacs 18: cannot display date of file, displays a fake date | |
77 ;; "Jan 00 00:00" instead (dates do work in Emacs 19) | |
78 | 41 |
79 ;; * Only numeric uid/gid | 42 ;; * Only numeric uid/gid |
80 | |
81 ;; * if you load dired-lisp after ange-ftp, remote listings look | |
82 ;; really strange: | |
83 ;; | |
84 ;; total 1 | |
85 ;; d????????? -1 -1 -1 -1 Jan 1 1970 . | |
86 ;; d????????? -1 -1 -1 -1 Jan 1 1970 .. | |
87 ;; | |
88 ;; This is because ange-ftp's file-attributes does not return much | |
89 ;; useful information. | |
90 ;; | |
91 ;; If you load dired-lisp first, there seem to be no problems. | |
92 | 43 |
93 ;; TODO ============================================================== | 44 ;; TODO ============================================================== |
94 | 45 |
95 ;; Recognize some more ls switches: R F | 46 ;; Recognize some more ls switches: R F |
96 | 47 |
97 | 48 (defun insert-directory (file &optional switches wildcard full-directory-p) |
98 (require 'dired) ; we will redefine dired-ls: | 49 "Insert directory listing for of FILE, formatted according to SWITCHES. |
99 (or (fboundp 'dired-lisp-unix-ls) | 50 Leaves point after the inserted text. |
100 (fset 'dired-lisp-unix-ls (symbol-function 'dired-ls))) | 51 Optional third arg WILDCARD means treat FILE as shell wildcard. |
101 | |
102 (fset 'dired-ls 'dired-lisp-ls) | |
103 | |
104 (defun dired-lisp-ls (file &optional switches wildcard full-directory-p) | |
105 "dired-lisp.el's version of dired-ls. | |
106 Known switches: A a S r i s t | |
107 In Emacs 19, additional known switches are: c u | |
108 Others are ignored. | |
109 | |
110 Insert ls output of FILE, optionally formatted with SWITCHES. | |
111 Optional third arg WILDCARD means treat non-directory part of FILE as | |
112 emacs regexp (_not_ a shell wildcard). If you enter regexps remember | |
113 to double each $ sign. | |
114 | |
115 Optional fourth arg FULL-DIRECTORY-P means file is a directory and | 52 Optional fourth arg FULL-DIRECTORY-P means file is a directory and |
116 switches do not contain `d'. | 53 switches do not contain `d', so that a full listing is expected. |
117 | 54 |
118 SWITCHES default to dired-listing-switches." | 55 This version of the function comes from `directory.el'. |
119 (or switches (setq switches dired-listing-switches)) | 56 It does not support ordinary shell wildcards; instead, it allows |
120 (or (consp switches) ; convert to list of chars | 57 regular expressions to match file names. |
121 (setq switches (mapcar 'identity switches))) | 58 |
122 (if wildcard | 59 The switches that work are: A a c i r S s t u" |
123 (setq wildcard (file-name-nondirectory file) ; actually emacs regexp | 60 (let (handler (handlers file-name-handler-alist)) |
124 ;; perhaps convert it from shell to emacs syntax? | 61 (save-match-data |
125 file (file-name-directory file))) | 62 (while (and (consp handlers) (null handler)) |
126 (if (or wildcard | 63 (if (and (consp (car handlers)) |
127 full-directory-p) | 64 (stringp (car (car handlers))) |
128 (let* ((dir (file-name-as-directory file)) | 65 (string-match (car (car handlers)) file)) |
129 (default-directory dir);; so that file-attributes works | 66 (setq handler (cdr (car handlers)))) |
130 (sum 0) | 67 (setq handlers (cdr handlers)))) |
131 elt | 68 (if handler |
132 short | 69 (funcall handler 'insert-directory file switches |
133 (file-list (directory-files dir nil wildcard)) | 70 wildcard full-directory-p) |
134 file-alist | 71 (if wildcard |
135 ;; do all bindings here for speed | 72 (setq wildcard (file-name-nondirectory file) ; actually emacs regexp |
136 fil attr) | 73 ;; perhaps convert it from shell to emacs syntax? |
137 (cond ((memq ?A switches) | 74 file (file-name-directory file))) |
138 (setq file-list | 75 (if (or wildcard |
139 (dired-lisp-delete-matching "^\\.\\.?$" file-list))) | 76 full-directory-p) |
140 ((not (memq ?a switches)) | 77 (let* ((dir (file-name-as-directory file)) |
141 ;; if neither -A nor -a, flush . files | 78 (default-directory dir);; so that file-attributes works |
142 (setq file-list | 79 (sum 0) |
143 (dired-lisp-delete-matching "^\\." file-list)))) | 80 elt |
144 (setq file-alist | 81 short |
145 (mapcar | 82 (file-list (directory-files dir nil wildcard)) |
146 (function | 83 file-alist |
147 (lambda (x) | 84 ;; do all bindings here for speed |
148 ;; file-attributes("~bogus") bombs | 85 fil attr) |
149 (cons x (file-attributes (expand-file-name x))))) | 86 (cond ((memq ?A switches) |
150 ;; inserting the call to directory-files right here | 87 (setq file-list |
151 ;; seems to stimulate an Emacs bug | 88 (ls-lisp-delete-matching "^\\.\\.?$" file-list))) |
152 ;; ILLEGAL DATATYPE (#o37777777727) or #o67 | 89 ((not (memq ?a switches)) |
153 file-list)) | 90 ;; if neither -A nor -a, flush . files |
154 (insert "total \007\n") ; filled in afterwards | 91 (setq file-list |
155 (setq file-alist | 92 (ls-lisp-delete-matching "^\\." file-list)))) |
156 (dired-lisp-handle-switches file-alist switches)) | 93 (setq file-alist |
157 (while file-alist | 94 (mapcar |
158 (setq elt (car file-alist) | 95 (function |
159 short (car elt) | 96 (lambda (x) |
160 attr (cdr elt) | 97 ;; file-attributes("~bogus") bombs |
161 file-alist (cdr file-alist) | 98 (cons x (file-attributes (expand-file-name x))))) |
162 fil (concat dir short) | 99 ;; inserting the call to directory-files right here |
163 sum (+ sum (nth 7 attr))) | 100 ;; seems to stimulate an Emacs bug |
164 (insert (dired-lisp-format short attr switches))) | 101 ;; ILLEGAL DATATYPE (#o37777777727) or #o67 |
165 ;; Fill in total size of all files: | 102 file-list)) |
166 (save-excursion | 103 (insert "total \007\n") ; filled in afterwards |
167 (search-backward "total \007") | 104 (setq file-alist |
168 (goto-char (match-end 0)) | 105 (ls-lisp-handle-switches file-alist switches)) |
169 (delete-char -1) | 106 (while file-alist |
170 (insert (format "%d" (1+ (/ sum 1024)))))) | 107 (setq elt (car file-alist) |
171 ;; if not full-directory-p, FILE *must not* end in /, as | 108 short (car elt) |
172 ;; file-attributes will not recognize a symlink to a directory | 109 attr (cdr elt) |
173 ;; must make it a relative filename as ls does: | 110 file-alist (cdr file-alist) |
174 (setq file (file-name-nondirectory file)) | 111 fil (concat dir short) |
175 (insert (dired-lisp-format file (file-attributes file) switches)))) | 112 sum (+ sum (nth 7 attr))) |
176 | 113 (insert (ls-lisp-format short attr switches))) |
177 (defun dired-lisp-delete-matching (regexp list) | 114 ;; Fill in total size of all files: |
115 (save-excursion | |
116 (search-backward "total \007") | |
117 (goto-char (match-end 0)) | |
118 (delete-char -1) | |
119 (insert (format "%d" (1+ (/ sum 1024)))))) | |
120 ;; if not full-directory-p, FILE *must not* end in /, as | |
121 ;; file-attributes will not recognize a symlink to a directory | |
122 ;; must make it a relative filename as ls does: | |
123 (setq file (file-name-nondirectory file)) | |
124 (insert (ls-lisp-format file (file-attributes file) switches)))))) | |
125 | |
126 (defun ls-lisp-delete-matching (regexp list) | |
178 ;; Delete all elements matching REGEXP from LIST, return new list. | 127 ;; Delete all elements matching REGEXP from LIST, return new list. |
179 ;; Should perhaps use setcdr for efficiency. | 128 ;; Should perhaps use setcdr for efficiency. |
180 (let (result) | 129 (let (result) |
181 (while list | 130 (while list |
182 (or (string-match regexp (car list)) | 131 (or (string-match regexp (car list)) |
183 (setq result (cons (car list) result))) | 132 (setq result (cons (car list) result))) |
184 (setq list (cdr list))) | 133 (setq list (cdr list))) |
185 result)) | 134 result)) |
186 | 135 |
187 (defun dired-lisp-handle-switches (file-alist switches) | 136 (defun ls-lisp-handle-switches (file-alist switches) |
188 ;; FILE-ALIST's elements are (FILE . FILE-ATTRIBUTES). | 137 ;; FILE-ALIST's elements are (FILE . FILE-ATTRIBUTES). |
189 ;; Return new alist sorted according to SWITCHES which is a list of | 138 ;; Return new alist sorted according to SWITCHES which is a list of |
190 ;; characters. Default sorting is alphabetically. | 139 ;; characters. Default sorting is alphabetically. |
191 (let (index) | 140 (let (index) |
192 (setq file-alist | 141 (setq file-alist |
197 ;; 7th file attribute is file size | 146 ;; 7th file attribute is file size |
198 ;; Make largest file come first | 147 ;; Make largest file come first |
199 (< (nth 7 (cdr y)) | 148 (< (nth 7 (cdr y)) |
200 (nth 7 (cdr x)))))) | 149 (nth 7 (cdr x)))))) |
201 ((memq ?t switches) ; sorted on time | 150 ((memq ?t switches) ; sorted on time |
202 (setq index (dired-lisp-time-index switches)) | 151 (setq index (ls-lisp-time-index switches)) |
203 (function | 152 (function |
204 (lambda (x y) | 153 (lambda (x y) |
205 (time-lessp (nth index (cdr y)) | 154 (ls-lisp-time-lessp (nth index (cdr y)) |
206 (nth index (cdr x)))))) | 155 (nth index (cdr x)))))) |
207 (t ; sorted alphabetically | 156 (t ; sorted alphabetically |
208 (function | 157 (function |
209 (lambda (x y) | 158 (lambda (x y) |
210 (string-lessp (car x) | 159 (string-lessp (car x) |
211 (car y))))))))) | 160 (car y))))))))) |
212 (if (memq ?r switches) ; reverse sort order | 161 (if (memq ?r switches) ; reverse sort order |
213 (setq file-alist (nreverse file-alist))) | 162 (setq file-alist (nreverse file-alist))) |
214 file-alist) | 163 file-alist) |
215 | 164 |
216 ;; From Roland McGrath. Can use this to sort on time. | 165 ;; From Roland McGrath. Can use this to sort on time. |
217 (defun time-lessp (time0 time1) | 166 (defun ls-lisp-time-lessp (time0 time1) |
218 (let ((hi0 (car time0)) | 167 (let ((hi0 (car time0)) |
219 (hi1 (car time1)) | 168 (hi1 (car time1)) |
220 (lo0 (car (cdr time0))) | 169 (lo0 (car (cdr time0))) |
221 (lo1 (car (cdr time1)))) | 170 (lo1 (car (cdr time1)))) |
222 (or (< hi0 hi1) | 171 (or (< hi0 hi1) |
223 (and (= hi0 hi1) | 172 (and (= hi0 hi1) |
224 (< lo0 lo1))))) | 173 (< lo0 lo1))))) |
225 | 174 |
226 | 175 |
227 (defun dired-lisp-format (file-name file-attr &optional switches) | 176 (defun ls-lisp-format (file-name file-attr &optional switches) |
228 (let ((file-type (nth 0 file-attr))) | 177 (let ((file-type (nth 0 file-attr))) |
229 (concat (if (memq ?i switches) ; inode number | 178 (concat (if (memq ?i switches) ; inode number |
230 (format "%6d " (nth 10 file-attr))) | 179 (format "%6d " (nth 10 file-attr))) |
231 ;; nil is treated like "" in concat | 180 ;; nil is treated like "" in concat |
232 (if (memq ?s switches) ; size in K | 181 (if (memq ?s switches) ; size in K |
240 (nth 1 file-attr) ; no. of links | 189 (nth 1 file-attr) ; no. of links |
241 (nth 2 file-attr) ; uid | 190 (nth 2 file-attr) ; uid |
242 (nth 3 file-attr) ; gid | 191 (nth 3 file-attr) ; gid |
243 (nth 7 file-attr) ; size in bytes | 192 (nth 7 file-attr) ; size in bytes |
244 ) | 193 ) |
245 (dired-lisp-format-time file-attr switches) | 194 (ls-lisp-format-time file-attr switches) |
246 " " | 195 " " |
247 file-name | 196 file-name |
248 (if (stringp file-type) ; is a symbolic link | 197 (if (stringp file-type) ; is a symbolic link |
249 (concat " -> " file-type) | 198 (concat " -> " file-type) |
250 "") | 199 "") |
251 "\n" | 200 "\n" |
252 ))) | 201 ))) |
253 | 202 |
254 (defun dired-lisp-time-index (switches) | 203 (defun ls-lisp-time-index (switches) |
255 ;; Return index into file-attributes according to ls SWITCHES. | 204 ;; Return index into file-attributes according to ls SWITCHES. |
256 (cond | 205 (cond |
257 ((memq ?c switches) 6) ; last mode change | 206 ((memq ?c switches) 6) ; last mode change |
258 ((memq ?u switches) 4) ; last access | 207 ((memq ?u switches) 4) ; last access |
259 ;; default is last modtime | 208 ;; default is last modtime |
260 (t 5))) | 209 (t 5))) |
261 | 210 |
262 (defun dired-lisp-format-time (file-attr switches) | 211 (defun ls-lisp-format-time (file-attr switches) |
263 ;; Format time string for file with attributes FILE-ATTR according | 212 ;; Format time string for file with attributes FILE-ATTR according |
264 ;; to SWITCHES (a list of ls option letters of which c and u are recognized). | 213 ;; to SWITCHES (a list of ls option letters of which c and u are recognized). |
265 ;; file-attributes's time is in a braindead format | 214 ;; file-attributes's time is in a braindead format |
266 ;; Emacs 19 can format it using a new optional argument to | 215 ;; Emacs 19 can format it using a new optional argument to |
267 ;; current-time-string, for Emacs 18 we just return the faked fixed | 216 ;; current-time-string, for Emacs 18 we just return the faked fixed |
268 ;; date "Jan 00 00:00 ". | 217 ;; date "Jan 00 00:00 ". |
269 (condition-case error-data | 218 (condition-case error-data |
270 (let* ((time (current-time-string | 219 (let* ((time (current-time-string |
271 (nth (dired-lisp-time-index switches) file-attr))) | 220 (nth (ls-lisp-time-index switches) file-attr))) |
272 (date (substring time 4 11)) ; "Apr 30 " | 221 (date (substring time 4 11)) ; "Apr 30 " |
273 (clock (substring time 11 16)) ; "11:27" | 222 (clock (substring time 11 16)) ; "11:27" |
274 (year (substring time 19 24)) ; " 1992" | 223 (year (substring time 19 24)) ; " 1992" |
275 (same-year (equal year (substring (current-time-string) 19 24)))) | 224 (same-year (equal year (substring (current-time-string) 19 24)))) |
276 (concat date ; has trailing SPC | 225 (concat date ; has trailing SPC |
281 clock | 230 clock |
282 year))) | 231 year))) |
283 (error | 232 (error |
284 "Jan 00 00:00"))) | 233 "Jan 00 00:00"))) |
285 | 234 |
286 (provide 'dired-lisp) | 235 (provide 'ls-lisp) |
287 | 236 |
288 ; eof | 237 ; eof |