changelog shortlog tags changeset files revisions annotate raw

w32-find-dired.el

changeset 66: 5b737eefe5ea
author: kim.vanwyk
date: Wed Nov 10 15:19:03 2010 +0200 (18 months ago)
permissions: -rw-r--r--
description: Adding CSharp Mode and Google Weather
1;;; w32-find-dired.el --- light w32 replacement for `find-dired'
2
3;; Copyright (C) 2004 Free Software Foundation, Inc.
4
5;; Author: Mathias Dahl (brakjoller@gmail.com)
6;; Version: w32-find-dired 0.1.1
7
8;; This file is not part of GNU Emacs (yet)
9
10;; GNU Emacs is free software; you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
12;; the Free Software Foundation; either version 2, or (at your option)
13;; any later version.
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
21;; along with GNU Emacs; see the file COPYING. If not, write to the
22;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23;; Boston, MA 02111-1307, USA.
24
25;;; Commentary:
26
27;; This is a light variant of `find-dired' for those who run Emacs on
28;; w32.
29
30;; Instead of using find, cmd.exe's `dir' command is used. The output
31;; is then transformed to something dired can use, using
32;; `insert-directory' from ls-lisp.el.
33
34;; It does not support all things that `find-dired' can do, mostly
35;; because the dir-command command used is not as powerful. It is also
36;; "hard coded" into doing recursive directory listing.
37
38;; Most of the code is ripped from find-dired.el
39
40;;; History
41
42;; * Version 0.1.1, 2006-01-12, Mathias Dahl
43
44;; - Changed the way `dir' is called.
45
46;;; Code:
47
48(require 'dired)
49
50(defvar w32-find-dired-pattern nil
51 "Last arguments given to `for' by \\[w32-find-dired].")
52
53;; History of w32-find-dired-pattern values entered in the minibuffer.
54(defvar w32-find-dired-pattern-history nil)
55
56(defun w32-find-dired (dir pattern)
57 "Use cmd.exe's `dir' command to find files recursively, and go
58into Dired mode on a buffer of the output. The command run (after
59changing into DIR) is
60
61 dir /s /b DIR\\PATTERN
62"
63
64 (interactive (list (read-file-name "Run find in directory: " nil "" t)
65 (read-string "Search for: " w32-find-dired-pattern
66 '(w32-find-dired-pattern-history . 1))))
67 (let ((dired-buffers dired-buffers))
68 ;; Expand DIR ("" means default-directory)
69 (setq dir (abbreviate-file-name
70 (file-name-as-directory (expand-file-name dir))))
71 ;; Check that it's really a directory.
72 (or (file-directory-p dir)
73 (error "w32-find-dired needs a directory: %s" dir))
74
75 (switch-to-buffer (get-buffer-create "*w32-find-dired*"))
76
77 ;; See if there's still a process running, and offer to kill it
78 ;; first, if it is.
79 (let ((find (get-buffer-process (current-buffer))))
80 (when find
81 (if (or (not (eq (process-status find) 'run))
82 (yes-or-no-p "A `for' process is running; kill it? "))
83 (condition-case nil
84 (progn
85 (interrupt-process find)
86 (sit-for 1)
87 (delete-process find))
88 (error nil))
89 (error "Cannot have two processes in `%s' at once" (buffer-name)))))
90 (widen)
91 (kill-all-local-variables)
92 (setq buffer-read-only nil)
93 (erase-buffer)
94 (setq default-directory dir
95 w32-find-dired-pattern pattern) ; save for next interactive
96 ; call
97 ;; The next statement will bomb in classic dired (no optional arg
98 ;; allowed)
99 (dired-mode dir (cdr find-ls-option))
100 ;; This really should rerun the find command, but I don't
101 ;; have time for that.
102 (use-local-map (append (make-sparse-keymap) (current-local-map)))
103 (define-key (current-local-map) "g" 'undefined)
104 ;; Set subdir-alist so that Tree Dired will work:
105 (if (fboundp 'dired-simple-subdir-alist)
106 ;; will work even with nested dired format (dired-nstd.el,v
107 ;; 1.15 and later)
108 (dired-simple-subdir-alist)
109 ;; else we have an ancient tree dired (or classic dired, where
110 ;; this does no harm)
111 (set (make-local-variable 'dired-subdir-alist)
112 (list (cons default-directory (point-min-marker)))))
113 (setq buffer-read-only nil)
114 ;; Subdir headlerline must come first because the first marker in
115 ;; subdir-alist points there.
116 (insert " " dir ":\n")
117 ;; Make second line a ``dir'' line in analogy to the ``total'' or
118 ;; ``wildcard'' line.
119 (insert " " pattern "\n")
120 ;; Start the dir process.
121 (let ((proc (start-process
122 "dir"
123 (current-buffer)
124 "cmd"
125 "/c" "dir" "/b" "/s"
126 (concat (substitute ?\\ ?/ dir) pattern))))
127 (set-process-filter proc (function w32-find-dired-filter))
128 (set-process-sentinel proc (function w32-find-dired-sentinel))
129 ;; Initialize the process marker; it is used by the filter.
130 (move-marker (process-mark proc) 1 (current-buffer)))
131 (setq mode-line-process '(":%s"))))
132
133
134(defun w32-find-dired-filter (proc string)
135 ;; Filter for \\[w32-find-dired] processes.
136 (let ((buf (process-buffer proc)))
137 (if (buffer-name buf) ; not killed?
138 (save-excursion
139 (set-buffer buf)
140 (save-restriction
141 (widen)
142 (save-excursion
143 (let ((buffer-read-only nil)
144 (end (point-max)))
145 (goto-char end)
146 ;; Just insert the data, the sentinel will take care
147 ;; of the formatting.
148 (insert string)
149 ;; Find all the complete lines in the unprocessed
150 ;; output and process it to add text properties.
151 (goto-char end)
152 (if (search-backward "\n" (process-mark proc) t)
153 (progn
154 (dired-insert-set-properties (process-mark proc)
155 (1+ (point)))
156 (move-marker (process-mark proc) (1+ (point)))))
157 ))))
158 ;; The buffer has been killed.
159 (delete-process proc))))
160
161
162(defun w32-find-dired-sentinel (proc state)
163 ;; Sentinel for \\[w32-find-dired] processes.
164 (let ((buf (process-buffer proc)))
165 (if (buffer-name buf)
166 (save-excursion
167 (set-buffer buf)
168 (let ((buffer-read-only nil)
169 (saved-pos nil))
170 (save-excursion
171 (goto-char (point-max))
172 (insert "\n w32-find-dired " state)
173 (forward-char -1) ;Back up before \n at end of STATE.
174 (insert " at " (substring (current-time-string) 0 19))
175 (forward-char 1)
176 (setq mode-line-process
177 (concat ":"
178 (symbol-name (process-status proc))))
179 ;; Since the buffer and mode line will show that the
180 ;; process is dead, we can delete it now. Otherwise it
181 ;; will stay around until M-x list-processes.
182 (delete-process proc)
183
184 ;; Transform the output from dir into dired format
185
186 ;; Skip header
187 (goto-char (point-min))
188 (forward-line 2)
189 (beginning-of-line)
190
191 ;; Transform each line
192 (while (looking-at "^.")
193 (setq col0 (point))
194 (end-of-line)
195 (setq row (buffer-substring col0 (point)))
196 (setq row (substitute ?/ ?\\ row))
197 (beginning-of-line)
198 (kill-line)
199 (insert " ")
200 (insert-directory row "")
201 ;; insert-directory adds a newline that we want to
202 ;; remove
203 (delete-char -1)
204 (forward-line 1))
205
206 (force-mode-line-update)))
207 (message "w32-find-dired %s finished." (current-buffer))))))
208
209(provide 'w32-find-dired)
210
211;;; w32-find-dired.el ends here