;;; ls-lisp.el --- emulate insert-directory completely in Emacs Lisp
;; Copyright (C) 1992, 1994, 2000, 2001, 2002, 2003, 2004,
-;; 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+;; 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
;; Author: Sebastian Kremer <sk@thp.uni-koeln.de>
;; Modified by: Francis J. Wright <F.J.Wright@maths.qmw.ac.uk>
;; Maintainer: FSF
;; Keywords: unix, dired
+;; Package: emacs
;; This file is part of GNU Emacs.
:group 'dired)
(defcustom ls-lisp-emulation
- (cond ((eq system-type 'macos) 'MacOS)
- ;; ((eq system-type 'windows-nt) 'MS-Windows)
+ (cond ;; ((eq system-type 'windows-nt) 'MS-Windows)
((memq system-type
- '(hpux usg-unix-v unisoft-unix irix berkeley-unix))
+ '(hpux usg-unix-v irix berkeley-unix))
'UNIX)) ; very similar to GNU
;; Anything else defaults to nil, meaning GNU.
"Platform to emulate: GNU (default), MacOS, MS-Windows, UNIX.
:group 'ls-lisp)
(defcustom ls-lisp-use-insert-directory-program
- (not (memq system-type '(macos ms-dos windows-nt)))
+ (not (memq system-type '(ms-dos windows-nt)))
"Non-nil causes ls-lisp to revert back to using `insert-directory-program'.
This is useful on platforms where ls-lisp is dumped into Emacs, such as
Microsoft Windows, but you would still like to use a program to list
(if (string-match "--dired " switches)
(setq switches (replace-match "" nil nil switches)))
;; Convert SWITCHES to a list of characters.
- (setq switches (delete ?- (append switches nil)))
+ (setq switches (delete ?\ (delete ?- (append switches nil))))
;; Sometimes we get ".../foo*/" as FILE. While the shell and
;; `ls' don't mind, we certainly do, because it makes us think
;; there is no wildcard, only a directory name.
(setq elt (car file-alist)
file-alist (cdr file-alist))
(when (and (eq (cadr elt) t) ; directory
- (not (string-match "\\`\\.\\.?\\'" (car elt))))
+ ;; Under -F, we have already decorated all
+ ;; directories, including "." and "..", with
+ ;; a /, so allow for that as well.
+ (not (string-match "\\`\\.\\.?/?\\'" (car elt))))
(setq elt (expand-file-name (car elt) dir))
(insert "\n" elt ":\n")
(ls-lisp-insert-directory
;; If not full-directory-p, FILE *must not* end in /, as
;; file-attributes will not recognize a symlink to a directory,
;; so must make it a relative filename as ls does:
+ (if (file-name-absolute-p file) (setq file (expand-file-name file)))
(if (eq (aref file (1- (length file))) ?/)
(setq file (substring file 0 -1)))
(let ((fattr (file-attributes file 'string)))
(if fattr
- (insert (ls-lisp-format file fattr (nth 7 fattr)
+ (insert (ls-lisp-format
+ (if (memq ?F switches)
+ (ls-lisp-classify-file file fattr)
+ file)
+ fattr (nth 7 fattr)
switches time-index (current-time)))
(message "%s: doesn't exist or is inaccessible" file)
(ding) (sit-for 2))))) ; to show user the message!
(nreverse file-alist)
file-alist))
+(defun ls-lisp-classify-file (filename fattr)
+ "Append a character to FILENAME indicating the file type.
+
+FATTR is the file attributes returned by `file-attributes' for the file.
+The file type indicators are `/' for directories, `@' for symbolic
+links, `|' for FIFOs, `=' for sockets, `*' for regular files that
+are executable, and nothing for other types of files."
+ (let* ((type (car fattr))
+ (modestr (nth 8 fattr))
+ (typestr (substring modestr 0 1)))
+ (cond
+ (type
+ (concat filename (if (eq type t) "/" "@")))
+ ((string-match "x" modestr)
+ (concat filename "*"))
+ ((string= "p" typestr)
+ (concat filename "|"))
+ ((string= "s" typestr)
+ (concat filename "="))
+ (t filename))))
+
(defun ls-lisp-classify (filedata)
- "Append a character to each file name indicating the file type.
-Also, for regular files that are executable, append `*'.
+ "Append a character to file name in FILEDATA indicating the file type.
+
+FILEDATA has the form (FILENAME . ATTRIBUTES), where ATTRIBUTES is the
+structure returned by `file-attributes' for that file.
+
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 recognized.]
-FILEDATA has the form (filename . `file-attributes'). Its `cadr' is t
-for directory, string (name linked to) for symbolic link, or nil."
+links, `|' for FIFOs, `=' for sockets, `*' for regular files that
+are executable, and nothing for other types of files."
(let ((file-name (car filedata))
- (type (cadr filedata)))
- (cond (type
- (cons
- (concat file-name (if (eq type t) "/" "@"))
- (cdr filedata)))
- ((string-match "x" (nth 9 filedata))
- (cons
- (concat file-name "*")
- (cdr filedata)))
- (t filedata))))
+ (fattr (cdr filedata)))
+ (setq file-name (propertize file-name 'dired-filename t))
+ (cons (ls-lisp-classify-file file-name fattr) fattr)))
(defun ls-lisp-extension (filename)
"Return extension of FILENAME (ignoring any version extension)
" "
(ls-lisp-format-time file-attr time-index now)
" "
- (propertize file-name 'dired-filename t)
+ (if (not (memq ?F switches)) ; ls-lisp-classify already did that
+ (propertize file-name 'dired-filename t)
+ file-name)
(if (stringp file-type) ; is a symbolic link
(concat " -> " file-type))
"\n"