;;; ls-lisp.el --- emulate insert-directory completely in Emacs Lisp
-;; Copyright (C) 1992, 1994, 2000 Free Software Foundation, Inc.
+;; Copyright (C) 1992, 1994, 2000, 2002, 2003, 2004,
+;; 2005, 2006 Free Software Foundation, Inc.
;; Author: Sebastian Kremer <sk@thp.uni-koeln.de>
;; Modified by: Francis J. Wright <F.J.Wright@maths.qmw.ac.uk>
;; 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.
;;; Commentary:
;; * A few obscure ls switches are still ignored: see the docstring of
;; `insert-directory'.
-;; * Generally only numeric uid/gid.
-
;; TO DO =============================================================
;; Complete handling of F switch (if/when possible).
;; Revised by Andrew Innes and Geoff Volker (and maybe others).
;; Modified by Francis J. Wright <F.J.Wright@maths.qmw.ac.uk>, mainly
-;; to support many more ls options, "platform emulation", hooks for
-;; external symbolic link support and more robust sorting.
+;; to support many more ls options, "platform emulation" and more
+;; robust sorting.
;;; Code:
(or (featurep 'ls-lisp) ; FJW: unless this file is being reloaded!
(setq original-insert-directory (symbol-function 'insert-directory)))
-;; This stub is to allow ls-lisp to parse symbolic links via another
-;; library such as w32-symlinks.el from
-;; http://centaur.maths.qmw.ac.uk/Emacs/:
-(defun ls-lisp-parse-symlink (file-name)
- "This stub may be redefined to parse FILE-NAME as a symlink.
-It should return nil or the link target as a string."
- nil)
-
\f
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(let* ((dir (file-name-as-directory file))
(default-directory dir) ; so that file-attributes works
(file-alist
- (directory-files-and-attributes dir nil wildcard-regexp t))
+ (directory-files-and-attributes dir nil wildcard-regexp t 'string))
(now (current-time))
(sum 0)
;; do all bindings here for speed
;; so must make it a relative filename as ls does:
(if (eq (aref file (1- (length file))) ?/)
(setq file (substring file 0 -1)))
- (let ((fattr (file-attributes file)))
+ (let ((fattr (file-attributes file 'string)))
(if fattr
(insert (ls-lisp-format file fattr (nth 7 fattr)
switches time-index (current-time)))
;; symbolic link, or nil.
(let (el dirs files)
(while file-alist
- (if (eq (cadr (setq el (car file-alist))) t) ; directory
+ (if (or (eq (cadr (setq el (car file-alist))) t) ; directory
+ (and (stringp (cadr el))
+ (file-directory-p (cadr el)))) ; symlink to a directory
(setq dirs (cons el dirs))
(setq files (cons el files)))
(setq file-alist (cdr file-alist)))
Also, for regular files that are executable, append `*'.
The file type indicators are `/' for directories, `@' for symbolic
links, `|' for FIFOs, `=' for sockets, and nothing for regular files.
-\[But FIFOs and sockets are not recognised.]
+\[But FIFOs and sockets are not recognized.]
FILEDATA has the form (filename . `file-attributes'). Its `cadr' is t
for directory, string (name linked to) for symbolic link, or nil."
- (let ((dir (cadr filedata)) (file-name (car filedata)))
- (cond ((or dir
- ;; Parsing .lnk files here is perhaps overkill!
- (setq dir (ls-lisp-parse-symlink file-name)))
+ (let ((file-name (car filedata))
+ (type (cadr filedata)))
+ (cond (type
(cons
- (concat file-name (if (eq dir t) "/" "@"))
+ (concat file-name (if (eq type t) "/" "@"))
(cdr filedata)))
((string-match "x" (nth 9 filedata))
(cons
;; t for directory, string (name linked to)
;; for symbolic link, or nil.
(drwxrwxrwx (nth 8 file-attr))) ; attribute string ("drwxrwxrwx")
- (and (null file-type)
- ;; Maybe no kernel support for symlinks, so...
- (setq file-type (ls-lisp-parse-symlink file-name))
- (aset drwxrwxrwx 0 ?l)) ; symbolic link - update attribute string
(concat (if (memq ?i switches) ; inode number
(format " %6d" (nth 10 file-attr)))
;; nil is treated like "" in concat
;; They tend to be bogus on non-UNIX platforms anyway so
;; optionally hide them.
(if (memq 'uid ls-lisp-verbosity)
- ;; (user-login-name uid) works on Windows NT but not
- ;; on 9x and maybe not on some other platforms, so...
+ ;; uid can be a sting or an integer
(let ((uid (nth 2 file-attr)))
- (if (= uid (user-uid))
- (format " %-8s" (user-login-name))
- (format " %-8d" uid))))
+ (format (if (stringp uid) " %-8s" " %-8d") uid)))
(if (not (memq ?G switches)) ; GNU ls -- shows group by default
(if (or (memq ?g switches) ; UNIX ls -- no group by default
(memq 'gid ls-lisp-verbosity))
- (if (memq system-type '(macos windows-nt ms-dos))
- ;; No useful concept of group...
- " root"
- (let* ((gid (nth 3 file-attr))
- (group (user-login-name gid)))
- (if group
- (format " %-8s" group)
- (format " %-8d" gid))))))
+ (let ((gid (nth 3 file-attr)))
+ (format (if (stringp gid) " %-8s" " %-8d") gid))))
(ls-lisp-format-file-size file-size (memq ?h switches))
" "
(ls-lisp-format-time file-attr time-index now)
" "
- file-name
+ (propertize file-name 'dired-filename t)
(if (stringp file-type) ; is a symbolic link
(concat " -> " file-type))
"\n"
(defun ls-lisp-format-file-size (file-size human-readable)
(if (or (not human-readable)
(< file-size 1024))
- (format (if (floatp file-size) " %8.0f" " %8d") file-size)
+ (format (if (floatp file-size) " %9.0f" " %9d") file-size)
(do ((file-size (/ file-size 1024.0) (/ file-size 1024.0))
;; kilo, mega, giga, tera, peta, exa
(post-fixes (list "k" "M" "G" "T" "P" "E") (cdr post-fixes)))
- ((< file-size 1024) (format " %7.0f%s" file-size (car post-fixes))))))
+ ((< file-size 1024) (format " %8.0f%s" file-size (car post-fixes))))))
(provide 'ls-lisp)