*** empty log message ***
[bpt/emacs.git] / lisp / locate.el
CommitLineData
092af6d8 1;;; locate.el --- interface to the locate command
6aea3b07 2
0d30b337 3;; Copyright (C) 1996, 1998, 2001, 2002, 2003, 2004,
aaef169d 4;; 2005, 2006 Free Software Foundation, Inc.
6aea3b07 5
dc268724 6;; Author: Peter Breton <pbreton@cs.umb.edu>
f947a7fa 7;; Keywords: unix files
6aea3b07
RS
8
9;; This file is part of GNU Emacs.
10
11;; GNU Emacs is free software; you can redistribute it and/or modify
12;; it under the terms of the GNU General Public License as published by
13;; the Free Software Foundation; either version 2, or (at your option)
14;; any later version.
15
16;; GNU Emacs is distributed in the hope that it will be useful,
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
22;; along with GNU Emacs; see the file COPYING. If not, write to the
086add15
LK
23;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24;; Boston, MA 02110-1301, USA.
6aea3b07
RS
25
26;;; Commentary:
27
271a87e8 28;; Search a database of files and use dired commands on the result.
6aea3b07
RS
29;;
30;; Locate.el provides an interface to a program which searches a
31;; database of file names. By default, this program is the GNU locate
32;; command, but it could also be the BSD-style find command, or even a
33;; user specified command.
34;;
35;; To use the BSD-style "fast find", or any other shell command of the
83346ee8 36;; form
6aea3b07
RS
37;;
38;; SHELLPROGRAM Name-to-find
39;;
be8bf2d0 40;; set the variable `locate-command' in your .emacs file.
6aea3b07 41;;
83346ee8 42;; To use a more complicated expression, create a function which
be8bf2d0
RS
43;; takes a string (the name to find) as input and returns a list.
44;; The first element should be the command to be executed, the remaining
45;; elements should be the arguments (including the name to find). Then put
6aea3b07 46;;
83346ee8 47;; (setq locate-make-command-line 'my-locate-command-line)
6aea3b07
RS
48;;
49;; in your .emacs, using the name of your function in place of
be8bf2d0 50;; my-locate-command-line.
6aea3b07
RS
51;;
52;; You should make sure that whichever command you use works correctly
53;; from a shell prompt. GNU locate and BSD find expect the file databases
54;; to either be in standard places or located via environment variables.
55;; If the latter, make sure these environment variables are set in
be8bf2d0 56;; your emacs process.
6aea3b07
RS
57;;
58;; Locate-mode assumes that each line output from the locate-command
59;; consists exactly of a file name, possibly preceded or trailed by
60;; whitespace. If your file database has other information on the line (for
83346ee8 61;; example, the file size), you will need to redefine the function
be8bf2d0 62;; `locate-get-file-positions' to return a list consisting of the first
6aea3b07
RS
63;; character in the file name and the last character in the file name.
64;;
65;; To use locate-mode, simply type M-x locate and then the string
66;; you wish to find. You can use almost all of the dired commands in
67;; the resulting *Locate* buffer. It is worth noting that your commands
68;; do not, of course, affect the file database. For example, if you
69;; compress a file in the locate buffer, the actual file will be
70;; compressed, but the entry in the file database will not be
71;; affected. Consequently, the database and the filesystem will be out
be8bf2d0 72;; of sync until the next time the database is updated.
6aea3b07 73;;
be8bf2d0 74;; The command `locate-with-filter' keeps only lines matching a
6aea3b07
RS
75;; regular expression; this is often useful to constrain a big search.
76;;
77\f
271a87e8
LT
78;;;;; Building a database of files ;;;;;;;;;
79;;
80;; You can create a simple files database with a port of the Unix find command
81;; and one of the various Windows NT various scheduling utilities,
82;; for example the AT command from the NT Resource Kit, WinCron which is
83;; included with Microsoft FrontPage, or the shareware NTCron program.
84;;
85;; To set up a function which searches the files database, do something
86;; like this:
87;;
88;; (defvar locate-fcodes-file "c:/users/peter/fcodes")
89;; (defvar locate-make-command-line 'nt-locate-make-command-line)
90;;
91;; (defun nt-locate-make-command-line (arg)
92;; (list "grep" "-i" arg locate-fcodes-file))
93;;
94;;;;;;;; ADVICE For dired-make-relative: ;;;;;;;;;
95;;
96;; For certain dired commands to work right, you should also include the
97;; following in your _emacs/.emacs:
98;;
99;; (defadvice dired-make-relative (before set-no-error activate)
100;; "For locate mode and Windows, don't return errors"
101;; (if (and (eq major-mode 'locate-mode)
102;; (memq system-type (list 'windows-nt 'ms-dos)))
103;; (ad-set-arg 2 t)
104;; ))
105;;
106;; Otherwise, `dired-make-relative' will give error messages like
107;; "FILENAME: not in directory tree growing at /"
108
109\f
6aea3b07
RS
110;;; Code:
111
112(eval-when-compile
113 (require 'dired))
114
115;; Variables
6aea3b07 116
be8bf2d0
RS
117(defvar locate-current-filter nil)
118
d979dc2b
SE
119(defgroup locate nil
120 "Interface to the locate command."
121 :prefix "locate-"
122 :group 'external)
6aea3b07 123
d979dc2b
SE
124(defcustom locate-command "locate"
125 "*The executable program used to search a database of files."
126 :type 'string
127 :group 'locate)
6aea3b07 128
d979dc2b
SE
129(defvar locate-history-list nil
130 "The history list used by the \\[locate] command.")
6aea3b07 131
83346ee8
PB
132(defvar locate-grep-history-list nil
133 "The history list used by the \\[locate-with-filter] command.")
134
d979dc2b
SE
135(defcustom locate-make-command-line 'locate-default-make-command-line
136 "*Function used to create the locate command line."
137 :type 'function
138 :group 'locate)
139
140(defcustom locate-buffer-name "*Locate*"
141 "*Name of the buffer to show results from the \\[locate] command."
142 :type 'string
143 :group 'locate)
144
145(defcustom locate-fcodes-file nil
be8bf2d0 146 "*File name for the database of file names."
e0063bf6 147 :type '(choice (const :tag "None" nil) file)
d979dc2b
SE
148 :group 'locate)
149
83346ee8 150(defcustom locate-header-face nil
d979dc2b 151 "*Face used to highlight the locate header."
e0063bf6 152 :type '(choice (const :tag "None" nil) face)
d979dc2b 153 :group 'locate)
6aea3b07 154
271a87e8
LT
155;;;###autoload
156(defcustom locate-ls-subdir-switches "-al"
157 "`ls' switches for inserting subdirectories in `*Locate*' buffers.
34bb9b0a 158This should contain the \"-l\" switch, but not the \"-F\" or \"-b\" switches."
271a87e8
LT
159 :type 'string
160 :group 'locate
bf247b6e 161 :version "22.1")
271a87e8 162
be8bf2d0
RS
163(defcustom locate-update-command "updatedb"
164 "The command used to update the locate database."
165 :type 'string
166 :group 'locate)
6aea3b07 167
83346ee8 168(defcustom locate-prompt-for-command nil
442c8150 169 "If non-nil, the locate command prompts for a command to run.
83346ee8
PB
170Otherwise, that behavior is invoked via a prefix argument."
171 :group 'locate
172 :type 'boolean
173 )
174
6aea3b07
RS
175;; Functions
176
177(defun locate-default-make-command-line (search-string)
be8bf2d0 178 (list locate-command search-string))
6aea3b07 179
96c1776c
PB
180(defun locate-word-at-point ()
181 (let ((pt (point)))
182 (buffer-substring-no-properties
183 (save-excursion
184 (skip-chars-backward "-a-zA-Z0-9.")
185 (point))
186 (save-excursion
187 (skip-chars-forward "-a-zA-Z0-9.")
188 (skip-chars-backward "." pt)
189 (point)))))
190
1d96c2ff 191;;;###autoload
8348e1f9 192(defun locate (search-string &optional filter)
83346ee8
PB
193 "Run the program `locate', putting results in `*Locate*' buffer.
194With prefix arg, prompt for the locate command to run."
6aea3b07 195 (interactive
83346ee8 196 (list
8348e1f9
PB
197 (if (or (and current-prefix-arg
198 (not locate-prompt-for-command))
83346ee8 199 (and (not current-prefix-arg) locate-prompt-for-command))
8348e1f9
PB
200 (let ((locate-cmd (funcall locate-make-command-line "")))
201 (read-from-minibuffer
202 "Run locate (like this): "
203 (cons
204 (concat (car locate-cmd) " "
205 (mapconcat 'identity (cdr locate-cmd) " "))
206 (+ 2 (length (car locate-cmd))))
207 nil nil 'locate-history-list))
fe8c7212 208 (let* ((default (locate-word-at-point))
f1180544 209 (input
fe8c7212
RS
210 (read-from-minibuffer
211 (if (> (length default) 0)
5b76833f 212 (format "Locate (default %s): " default)
fe8c7212
RS
213 (format "Locate: "))
214 nil nil nil 'locate-history-list default t)))
215 (and (equal input "") default
216 (setq input default))
217 input))))
218 (if (equal search-string "")
c19813f3 219 (error "Please specify a filename to search for"))
be8bf2d0 220 (let* ((locate-cmd-list (funcall locate-make-command-line search-string))
6aea3b07
RS
221 (locate-cmd (car locate-cmd-list))
222 (locate-cmd-args (cdr locate-cmd-list))
83346ee8 223 (run-locate-command
8348e1f9
PB
224 (or (and current-prefix-arg (not locate-prompt-for-command))
225 (and (not current-prefix-arg) locate-prompt-for-command)))
be8bf2d0 226 )
83346ee8 227
6aea3b07 228 ;; Find the Locate buffer
be8bf2d0
RS
229 (save-window-excursion
230 (set-buffer (get-buffer-create locate-buffer-name))
231 (locate-mode)
e242b6c4
JL
232 (let ((inhibit-read-only t)
233 (buffer-undo-list t))
271a87e8 234 (erase-buffer)
83346ee8 235
271a87e8 236 (setq locate-current-filter filter)
83346ee8 237
271a87e8
LT
238 (if run-locate-command
239 (shell-command search-string locate-buffer-name)
240 (apply 'call-process locate-cmd nil t nil locate-cmd-args))
83346ee8 241
271a87e8
LT
242 (and filter
243 (locate-filter-output filter))
6aea3b07 244
271a87e8
LT
245 (locate-do-setup search-string)
246 ))
be8bf2d0
RS
247 (and (not (string-equal (buffer-name) locate-buffer-name))
248 (switch-to-buffer-other-window locate-buffer-name))
83346ee8 249
96c1776c 250 (run-hooks 'dired-mode-hook)
271a87e8 251 (dired-next-line 3) ;move to first matching file.
83346ee8 252 (run-hooks 'locate-post-command-hook)
be8bf2d0
RS
253 )
254 )
6aea3b07 255
1d96c2ff 256;;;###autoload
6aea3b07 257(defun locate-with-filter (search-string filter)
9be8f657
GM
258 "Run the locate command with a filter.
259
260The filter is a regular expression. Only results matching the filter are
261shown; this is often useful to constrain a big search."
6aea3b07 262 (interactive
be8bf2d0
RS
263 (list (read-from-minibuffer "Locate: " nil nil
264 nil 'locate-history-list)
265 (read-from-minibuffer "Filter: " nil nil
83346ee8 266 nil 'locate-grep-history-list)))
8348e1f9 267 (locate search-string filter))
6aea3b07
RS
268
269(defun locate-filter-output (filter)
270 "Filter output from the locate command."
271 (goto-char (point-min))
83346ee8 272 (delete-non-matching-lines filter))
6aea3b07
RS
273
274(defvar locate-mode-map nil
275 "Local keymap for Locate mode buffers.")
276(if locate-mode-map
277 nil
278
279 (require 'dired)
280
281 (setq locate-mode-map (copy-keymap dired-mode-map))
282
283 ;; Undefine Useless Dired Menu bars
284 (define-key locate-mode-map [menu-bar Dired] 'undefined)
285 (define-key locate-mode-map [menu-bar subdir] 'undefined)
286
287 (define-key locate-mode-map [menu-bar mark executables] 'undefined)
288 (define-key locate-mode-map [menu-bar mark directory] 'undefined)
289 (define-key locate-mode-map [menu-bar mark directories] 'undefined)
290 (define-key locate-mode-map [menu-bar mark symlinks] 'undefined)
291
271a87e8 292 (define-key locate-mode-map [M-mouse-2] 'locate-mouse-view-file)
83346ee8 293 (define-key locate-mode-map "\C-c\C-t" 'locate-tags)
6aea3b07 294
271a87e8 295 (define-key locate-mode-map "l" 'locate-do-redisplay)
83346ee8
PB
296 (define-key locate-mode-map "U" 'dired-unmark-all-files)
297 (define-key locate-mode-map "V" 'locate-find-directory)
6aea3b07
RS
298)
299
300;; This variable is used to indent the lines and then to search for
301;; the file name
302(defconst locate-filename-indentation 4
be8bf2d0 303 "The amount of indentation for each file.")
6aea3b07 304
6aea3b07
RS
305(defun locate-get-file-positions ()
306 (save-excursion
be8bf2d0
RS
307 (end-of-line)
308 (let ((eol (point)))
309 (beginning-of-line)
83346ee8 310
be8bf2d0
RS
311 ;; Assumes names end at the end of the line
312 (forward-char locate-filename-indentation)
313 (list (point) eol))))
6aea3b07
RS
314
315;; From SQL-mode
be8bf2d0 316(defun locate-current-line-number ()
6aea3b07 317 "Return the current line number, as an integer."
6aea3b07
RS
318 (+ (count-lines (point-min) (point))
319 (if (eq (current-column) 0)
320 1
321 0)))
322
323(defun locate-get-filename ()
324 (let ((pos (locate-get-file-positions))
be8bf2d0 325 (lineno (locate-current-line-number)))
83346ee8
PB
326 (and (not (eq lineno 1))
327 (not (eq lineno 2))
6aea3b07
RS
328 (buffer-substring (elt pos 0) (elt pos 1)))))
329
271a87e8
LT
330(defun locate-main-listing-line-p ()
331 "Return t if current line contains a file name listed by locate.
332This function returns nil if the current line either contains no
333file name or is inside a subdirectory."
334 (save-excursion
335 (forward-line 0)
336 (looking-at (concat "."
337 (make-string (1- locate-filename-indentation) ?\ )
338 "\\(/\\|[A-Za-z]:\\)"))))
339
83346ee8 340(defun locate-mouse-view-file (event)
6aea3b07 341 "In Locate mode, view a file, using the mouse."
83346ee8 342 (interactive "@e")
6aea3b07
RS
343 (save-excursion
344 (goto-char (posn-point (event-start event)))
271a87e8
LT
345 (if (locate-main-listing-line-p)
346 (view-file (locate-get-filename))
347 (message "This command only works inside main listing."))))
6aea3b07
RS
348
349;; Define a mode for locate
350;; Default directory is set to "/" so that dired commands, which
351;; expect to be in a tree, will work properly
352(defun locate-mode ()
442c8150 353 "Major mode for the `*Locate*' buffer made by \\[locate].
271a87e8 354\\<locate-mode-map>\
442c8150
LT
355In that buffer, you can use almost all the usual dired bindings.
356\\[locate-find-directory] visits the directory of the file on the current line.
357
271a87e8
LT
358Operating on listed files works, but does not always
359automatically update the buffer as in ordinary Dired.
360This is true both for the main listing and for subdirectories.
361Reverting the buffer using \\[revert-buffer] deletes all subdirectories.
362Specific `locate-mode' commands, such as \\[locate-find-directory],
363do not work in subdirectories.
364
442c8150 365\\{locate-mode-map}"
271a87e8 366 ;; Not to be called interactively.
6aea3b07 367 (kill-all-local-variables)
271a87e8 368 ;; Avoid clobbering this variable
83346ee8 369 (make-local-variable 'dired-subdir-alist)
6aea3b07
RS
370 (use-local-map locate-mode-map)
371 (setq major-mode 'locate-mode
372 mode-name "Locate"
271a87e8
LT
373 default-directory "/"
374 buffer-read-only t
375 selective-display t)
83346ee8 376 (dired-alist-add-1 default-directory (point-min-marker))
271a87e8
LT
377 (set (make-local-variable 'dired-directory) "/")
378 (set (make-local-variable 'dired-subdir-switches) locate-ls-subdir-switches)
379 (setq dired-switches-alist nil)
9bc260cf 380 (make-local-variable 'directory-listing-before-filename-regexp)
83346ee8 381 ;; This should support both Unix and Windoze style names
9bc260cf 382 (setq directory-listing-before-filename-regexp
271a87e8 383 (concat "^."
83346ee8 384 (make-string (1- locate-filename-indentation) ?\ )
271a87e8 385 "\\(/\\|[A-Za-z]:\\)\\|"
9bc260cf 386 (default-value 'directory-listing-before-filename-regexp)))
5c6a8dfe
RS
387 (make-local-variable 'dired-actual-switches)
388 (setq dired-actual-switches "")
389 (make-local-variable 'dired-permission-flags-regexp)
83346ee8
PB
390 (setq dired-permission-flags-regexp
391 (concat "^.\\("
392 (make-string (1- locate-filename-indentation) ?\ )
271a87e8
LT
393 "\\)\\|"
394 (default-value 'dired-permission-flags-regexp)))
be8bf2d0 395 (make-local-variable 'revert-buffer-function)
83346ee8 396 (setq revert-buffer-function 'locate-update)
271a87e8 397 (set (make-local-variable 'page-delimiter) "\n\n")
9b5e13c4 398 (run-mode-hooks 'locate-mode-hook))
6aea3b07 399
8348e1f9
PB
400(defun locate-do-setup (search-string)
401 (goto-char (point-min))
402 (save-excursion
83346ee8 403
8348e1f9
PB
404 ;; Nothing returned from locate command?
405 (and (eobp)
406 (progn
407 (kill-buffer locate-buffer-name)
408 (if locate-current-filter
409 (error "Locate: no match for %s in database using filter %s"
410 search-string locate-current-filter)
411 (error "Locate: no match for %s in database" search-string))))
83346ee8 412
8348e1f9 413 (locate-insert-header search-string)
83346ee8 414
8348e1f9
PB
415 (while (not (eobp))
416 (insert-char ?\ locate-filename-indentation t)
417 (locate-set-properties)
418 (forward-line 1)))
419 (goto-char (point-min)))
6aea3b07
RS
420
421(defun locate-set-properties ()
422 (save-excursion
423 (let ((pos (locate-get-file-positions)))
83346ee8 424 (dired-insert-set-properties (elt pos 0) (elt pos 1)))))
6aea3b07
RS
425
426(defun locate-insert-header (search-string)
271a87e8
LT
427 ;; There needs to be a space before `Matches, because otherwise,
428 ;; `*!" would erase the `M'. We can not use two spaces, or the line
429 ;; would mistakenly fit `dired-subdir-regexp'.
430 (let ((locate-format-string " /:\n Matches for %s")
6aea3b07
RS
431 (locate-regexp-match
432 (concat " *Matches for \\(" (regexp-quote search-string) "\\)"))
433 (locate-format-args (list search-string))
434 )
83346ee8 435
be8bf2d0 436 (and locate-fcodes-file
6aea3b07
RS
437 (setq locate-format-string
438 (concat locate-format-string " in %s")
439 locate-regexp-match
440 (concat locate-regexp-match
441 " in \\("
442 (regexp-quote locate-fcodes-file)
443 "\\)")
444 locate-format-args
445 (append (list locate-fcodes-file) locate-format-args)))
446
be8bf2d0 447 (and locate-current-filter
6aea3b07
RS
448 (setq locate-format-string
449 (concat locate-format-string " using filter %s")
450 locate-regexp-match
451 (concat locate-regexp-match
452 " using filter "
453 "\\("
454 (regexp-quote locate-current-filter)
455 "\\)")
456 locate-format-args
457 (append (list locate-current-filter) locate-format-args)))
83346ee8 458
6aea3b07 459 (setq locate-format-string
5421b899 460 (concat locate-format-string ":\n\n")
6aea3b07 461 locate-regexp-match
5421b899 462 (concat locate-regexp-match ":\n"))
83346ee8 463
5c6a8dfe 464 (insert (apply 'format locate-format-string (reverse locate-format-args)))
83346ee8 465
6aea3b07
RS
466 (save-excursion
467 (goto-char (point-min))
271a87e8 468 (forward-line 1)
6aea3b07
RS
469 (if (not (looking-at locate-regexp-match))
470 nil
471 (add-text-properties (match-beginning 1) (match-end 1)
472 (list 'face locate-header-face))
473 (and (match-beginning 2)
474 (add-text-properties (match-beginning 2) (match-end 2)
475 (list 'face locate-header-face)))
476 (and (match-beginning 3)
477 (add-text-properties (match-beginning 3) (match-end 3)
478 (list 'face locate-header-face)))
479 ))))
480
481(defun locate-tags ()
482 "Visit a tags table in `*Locate*' mode."
483 (interactive)
271a87e8
LT
484 (if (locate-main-listing-line-p)
485 (let ((tags-table (locate-get-filename)))
486 (and (y-or-n-p (format "Visit tags table %s? " tags-table))
487 (visit-tags-table tags-table)))
488 (message "This command only works inside main listing.")))
be8bf2d0
RS
489
490;; From Stephen Eglen <stephen@cns.ed.ac.uk>
491(defun locate-update (ignore1 ignore2)
492 "Update the locate database.
493Database is updated using the shell command in `locate-update-command'."
494 (let ((str (car locate-history-list)))
495 (cond ((yes-or-no-p "Update locate database (may take a few seconds)? ")
496 (shell-command locate-update-command)
8348e1f9 497 (locate str)))))
83346ee8
PB
498
499;;; Modified three functions from `dired.el':
500;;; dired-find-directory,
501;;; dired-find-directory-other-window
502;;; dired-get-filename
503
504(defun locate-find-directory ()
505 "Visit the directory of the file mentioned on this line."
506 (interactive)
271a87e8
LT
507 (if (locate-main-listing-line-p)
508 (let ((directory-name (locate-get-dirname)))
509 (if (file-directory-p directory-name)
510 (find-file directory-name)
511 (if (file-symlink-p directory-name)
512 (error "Directory is a symlink to a nonexistent target")
513 (error "Directory no longer exists; run `updatedb' to update database"))))
514 (message "This command only works inside main listing.")))
83346ee8
PB
515
516(defun locate-find-directory-other-window ()
517 "Visit the directory of the file named on this line in other window."
518 (interactive)
519 (find-file-other-window (locate-get-dirname)))
520
521(defun locate-get-dirname ()
522 "Return the directory name of the file mentioned on this line."
523 (let (file (filepos (locate-get-file-positions)))
524 (if (setq file (buffer-substring (nth 0 filepos) (nth 1 filepos)))
525 (progn
526 ;; Get rid of the mouse-face property that file names have.
527 (set-text-properties 0 (length file) nil file)
528 (setq file (file-name-directory file))
529 ;; Unquote names quoted by ls or by dired-insert-directory.
530 ;; Using read to unquote is much faster than substituting
531 ;; \007 (4 chars) -> ^G (1 char) etc. in a lisp loop.
532 (setq file
533 (read
534 (concat "\""
535 ;; some ls -b don't escape quotes, argh!
536 ;; This is not needed for GNU ls, though.
537 (or (dired-string-replace-match
538 "\\([^\\]\\|\\`\\)\"" file "\\1\\\\\"" nil t)
539 file)
540 "\"")))))
541 (and file buffer-file-coding-system
542 (not file-name-coding-system)
543 (setq file (encode-coding-string file buffer-file-coding-system)))
544 file))
545
546;; Only for GNU locate
547(defun locate-in-alternate-database (search-string database)
548 "Run the GNU locate command, using an alternate database."
549 (interactive
550 (list
551 (progn
552 ;; (require 'locate)
553 (read-from-minibuffer "Locate: " nil nil
554 nil 'locate-history-list))
555 (read-file-name "Locate using Database: " )
556 ))
557 (or (file-exists-p database)
558 (error "Database file %s does not exist" database))
559 (let ((locate-make-command-line
560 (function (lambda (string)
561 (cons locate-command
562 (list (concat "--database="
563 (expand-file-name database))
564 string))))))
8348e1f9 565 (locate search-string)))
6aea3b07 566
271a87e8
LT
567(defun locate-do-redisplay (&optional arg test-for-subdir)
568 "Like `dired-do-redisplay', but adapted for `*Locate*' buffers."
569 (interactive "P\np")
570 (if (string= (dired-current-directory) "/")
571 (message "This command only works in subdirectories.")
572 (let ((dired-actual-switches locate-ls-subdir-switches))
573 (dired-do-redisplay arg test-for-subdir))))
574
6aea3b07
RS
575(provide 'locate)
576
ab5796a9 577;;; arch-tag: 60c4d098-b5d5-4b3c-a3e0-51a2e9f43898
6aea3b07 578;;; locate.el ends here