diff options
| author | Luc Teirlinck | 2004-06-06 02:29:18 +0000 |
|---|---|---|
| committer | Luc Teirlinck | 2004-06-06 02:29:18 +0000 |
| commit | 271a87e8cf1e44e9235018b9f2a5a2b5a18af58d (patch) | |
| tree | 4c38d3c55603a6917143e32ed369ee4de77b8869 | |
| parent | f2260f48b09bc32ae620f26e797b85165152baf8 (diff) | |
| download | emacs-271a87e8cf1e44e9235018b9f2a5a2b5a18af58d.tar.gz emacs-271a87e8cf1e44e9235018b9f2a5a2b5a18af58d.zip | |
Merge the two `Commentary' sections.
(locate-ls-subdir-switches): New user option.
(locate): Update for other changes.
(locate-mode-map): Restore Dired binding for mouse-2.
Bind `locate-mouse-view-file' to M-mouse-2.
Bind `l' to `locate-do-redisplay'.
(locate-main-listing-line-p, locate-do-redisplay): New functions.
(locate-mouse-view-file, locate-tags, locate-find-directory):
Print message if used outside main listing.
(locate-mode): Update docstring. Make `*Locate*' buffer read-only.
Various changes to support inserted subdirectories.
(locate-insert-header): Change header of *Locate* buffer.
| -rw-r--r-- | lisp/locate.el | 180 |
1 files changed, 117 insertions, 63 deletions
diff --git a/lisp/locate.el b/lisp/locate.el index e61ec87d4e4..f337bd09bad 100644 --- a/lisp/locate.el +++ b/lisp/locate.el | |||
| @@ -24,42 +24,7 @@ | |||
| 24 | 24 | ||
| 25 | ;;; Commentary: | 25 | ;;; Commentary: |
| 26 | 26 | ||
| 27 | ;; Search a database of files and use dired commands on | 27 | ;; Search a database of files and use dired commands on the result. |
| 28 | ;; the result. | ||
| 29 | ;; | ||
| 30 | |||
| 31 | ;;;;; Building a database of files ;;;;;;;;; | ||
| 32 | ;; | ||
| 33 | ;; You can create a simple files database with a port of the Unix find command | ||
| 34 | ;; and one of the various Windows NT various scheduling utilities, | ||
| 35 | ;; for example the AT command from the NT Resource Kit, WinCron which is | ||
| 36 | ;; included with Microsoft FrontPage, or the shareware NTCron program. | ||
| 37 | ;; | ||
| 38 | ;; To set up a function which searches the files database, do something | ||
| 39 | ;; like this: | ||
| 40 | ;; | ||
| 41 | ;; (defvar locate-fcodes-file "c:/users/peter/fcodes") | ||
| 42 | ;; (defvar locate-make-command-line 'nt-locate-make-command-line) | ||
| 43 | ;; | ||
| 44 | ;; (defun nt-locate-make-command-line (arg) | ||
| 45 | ;; (list "grep" "-i" arg locate-fcodes-file)) | ||
| 46 | ;; | ||
| 47 | ;;;;;;;; ADVICE For dired-make-relative: ;;;;;;;;; | ||
| 48 | ;; | ||
| 49 | ;; For certain dired commands to work right, you should also include the | ||
| 50 | ;; following in your _emacs/.emacs: | ||
| 51 | ;; | ||
| 52 | ;; (defadvice dired-make-relative (before set-no-error activate) | ||
| 53 | ;; "For locate mode and Windows, don't return errors" | ||
| 54 | ;; (if (and (eq major-mode 'locate-mode) | ||
| 55 | ;; (memq system-type (list 'windows-nt 'ms-dos))) | ||
| 56 | ;; (ad-set-arg 2 t) | ||
| 57 | ;; )) | ||
| 58 | ;; | ||
| 59 | ;; Otherwise, `dired-make-relative' will give error messages like | ||
| 60 | ;; "FILENAME: not in directory tree growing at /" | ||
| 61 | |||
| 62 | ;;; Commentary: | ||
| 63 | ;; | 28 | ;; |
| 64 | ;; Locate.el provides an interface to a program which searches a | 29 | ;; Locate.el provides an interface to a program which searches a |
| 65 | ;; database of file names. By default, this program is the GNU locate | 30 | ;; database of file names. By default, this program is the GNU locate |
| @@ -109,6 +74,38 @@ | |||
| 109 | ;; regular expression; this is often useful to constrain a big search. | 74 | ;; regular expression; this is often useful to constrain a big search. |
| 110 | ;; | 75 | ;; |
| 111 | 76 | ||
| 77 | ;;;;; Building a database of files ;;;;;;;;; | ||
| 78 | ;; | ||
| 79 | ;; You can create a simple files database with a port of the Unix find command | ||
| 80 | ;; and one of the various Windows NT various scheduling utilities, | ||
| 81 | ;; for example the AT command from the NT Resource Kit, WinCron which is | ||
| 82 | ;; included with Microsoft FrontPage, or the shareware NTCron program. | ||
| 83 | ;; | ||
| 84 | ;; To set up a function which searches the files database, do something | ||
| 85 | ;; like this: | ||
| 86 | ;; | ||
| 87 | ;; (defvar locate-fcodes-file "c:/users/peter/fcodes") | ||
| 88 | ;; (defvar locate-make-command-line 'nt-locate-make-command-line) | ||
| 89 | ;; | ||
| 90 | ;; (defun nt-locate-make-command-line (arg) | ||
| 91 | ;; (list "grep" "-i" arg locate-fcodes-file)) | ||
| 92 | ;; | ||
| 93 | ;;;;;;;; ADVICE For dired-make-relative: ;;;;;;;;; | ||
| 94 | ;; | ||
| 95 | ;; For certain dired commands to work right, you should also include the | ||
| 96 | ;; following in your _emacs/.emacs: | ||
| 97 | ;; | ||
| 98 | ;; (defadvice dired-make-relative (before set-no-error activate) | ||
| 99 | ;; "For locate mode and Windows, don't return errors" | ||
| 100 | ;; (if (and (eq major-mode 'locate-mode) | ||
| 101 | ;; (memq system-type (list 'windows-nt 'ms-dos))) | ||
| 102 | ;; (ad-set-arg 2 t) | ||
| 103 | ;; )) | ||
| 104 | ;; | ||
| 105 | ;; Otherwise, `dired-make-relative' will give error messages like | ||
| 106 | ;; "FILENAME: not in directory tree growing at /" | ||
| 107 | |||
| 108 | |||
| 112 | ;;; Code: | 109 | ;;; Code: |
| 113 | 110 | ||
| 114 | (eval-when-compile | 111 | (eval-when-compile |
| @@ -154,6 +151,16 @@ | |||
| 154 | :type 'face | 151 | :type 'face |
| 155 | :group 'locate) | 152 | :group 'locate) |
| 156 | 153 | ||
| 154 | ;;;###autoload | ||
| 155 | (defcustom locate-ls-subdir-switches "-al" | ||
| 156 | "`ls' switches for inserting subdirectories in `*Locate*' buffers. | ||
| 157 | This should contain the \"-l\" switch. | ||
| 158 | Use the \"-F\" or \"-b\" switches if and only if you also use | ||
| 159 | them for `find-ls-option'." | ||
| 160 | :type 'string | ||
| 161 | :group 'locate | ||
| 162 | :version "21.4") | ||
| 163 | |||
| 157 | (defcustom locate-update-command "updatedb" | 164 | (defcustom locate-update-command "updatedb" |
| 158 | "The command used to update the locate database." | 165 | "The command used to update the locate database." |
| 159 | :type 'string | 166 | :type 'string |
| @@ -223,24 +230,25 @@ With prefix arg, prompt for the locate command to run." | |||
| 223 | (save-window-excursion | 230 | (save-window-excursion |
| 224 | (set-buffer (get-buffer-create locate-buffer-name)) | 231 | (set-buffer (get-buffer-create locate-buffer-name)) |
| 225 | (locate-mode) | 232 | (locate-mode) |
| 226 | (erase-buffer) | 233 | (let ((inhibit-read-only t)) |
| 234 | (erase-buffer) | ||
| 227 | 235 | ||
| 228 | (setq locate-current-filter filter) | 236 | (setq locate-current-filter filter) |
| 229 | 237 | ||
| 230 | (if run-locate-command | 238 | (if run-locate-command |
| 231 | (shell-command search-string locate-buffer-name) | 239 | (shell-command search-string locate-buffer-name) |
| 232 | (apply 'call-process locate-cmd nil t nil locate-cmd-args)) | 240 | (apply 'call-process locate-cmd nil t nil locate-cmd-args)) |
| 233 | 241 | ||
| 234 | (and filter | 242 | (and filter |
| 235 | (locate-filter-output filter)) | 243 | (locate-filter-output filter)) |
| 236 | 244 | ||
| 237 | (locate-do-setup search-string) | 245 | (locate-do-setup search-string) |
| 238 | ) | 246 | )) |
| 239 | (and (not (string-equal (buffer-name) locate-buffer-name)) | 247 | (and (not (string-equal (buffer-name) locate-buffer-name)) |
| 240 | (switch-to-buffer-other-window locate-buffer-name)) | 248 | (switch-to-buffer-other-window locate-buffer-name)) |
| 241 | 249 | ||
| 242 | (run-hooks 'dired-mode-hook) | 250 | (run-hooks 'dired-mode-hook) |
| 243 | (dired-next-line 2) ;move to first matching file. | 251 | (dired-next-line 3) ;move to first matching file. |
| 244 | (run-hooks 'locate-post-command-hook) | 252 | (run-hooks 'locate-post-command-hook) |
| 245 | ) | 253 | ) |
| 246 | ) | 254 | ) |
| @@ -281,9 +289,10 @@ shown; this is often useful to constrain a big search." | |||
| 281 | (define-key locate-mode-map [menu-bar mark directories] 'undefined) | 289 | (define-key locate-mode-map [menu-bar mark directories] 'undefined) |
| 282 | (define-key locate-mode-map [menu-bar mark symlinks] 'undefined) | 290 | (define-key locate-mode-map [menu-bar mark symlinks] 'undefined) |
| 283 | 291 | ||
| 284 | (define-key locate-mode-map [mouse-2] 'locate-mouse-view-file) | 292 | (define-key locate-mode-map [M-mouse-2] 'locate-mouse-view-file) |
| 285 | (define-key locate-mode-map "\C-c\C-t" 'locate-tags) | 293 | (define-key locate-mode-map "\C-c\C-t" 'locate-tags) |
| 286 | 294 | ||
| 295 | (define-key locate-mode-map "l" 'locate-do-redisplay) | ||
| 287 | (define-key locate-mode-map "U" 'dired-unmark-all-files) | 296 | (define-key locate-mode-map "U" 'dired-unmark-all-files) |
| 288 | (define-key locate-mode-map "V" 'locate-find-directory) | 297 | (define-key locate-mode-map "V" 'locate-find-directory) |
| 289 | ) | 298 | ) |
| @@ -318,45 +327,74 @@ shown; this is often useful to constrain a big search." | |||
| 318 | (not (eq lineno 2)) | 327 | (not (eq lineno 2)) |
| 319 | (buffer-substring (elt pos 0) (elt pos 1))))) | 328 | (buffer-substring (elt pos 0) (elt pos 1))))) |
| 320 | 329 | ||
| 330 | (defun locate-main-listing-line-p () | ||
| 331 | "Return t if current line contains a file name listed by locate. | ||
| 332 | This function returns nil if the current line either contains no | ||
| 333 | file 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 | |||
| 321 | (defun locate-mouse-view-file (event) | 340 | (defun locate-mouse-view-file (event) |
| 322 | "In Locate mode, view a file, using the mouse." | 341 | "In Locate mode, view a file, using the mouse." |
| 323 | (interactive "@e") | 342 | (interactive "@e") |
| 324 | (save-excursion | 343 | (save-excursion |
| 325 | (goto-char (posn-point (event-start event))) | 344 | (goto-char (posn-point (event-start event))) |
| 326 | (view-file (locate-get-filename)))) | 345 | (if (locate-main-listing-line-p) |
| 346 | (view-file (locate-get-filename)) | ||
| 347 | (message "This command only works inside main listing.")))) | ||
| 327 | 348 | ||
| 328 | ;; Define a mode for locate | 349 | ;; Define a mode for locate |
| 329 | ;; Default directory is set to "/" so that dired commands, which | 350 | ;; Default directory is set to "/" so that dired commands, which |
| 330 | ;; expect to be in a tree, will work properly | 351 | ;; expect to be in a tree, will work properly |
| 331 | (defun locate-mode () | 352 | (defun locate-mode () |
| 332 | "Major mode for the `*Locate*' buffer made by \\[locate]. | 353 | "Major mode for the `*Locate*' buffer made by \\[locate]. |
| 354 | \\<locate-mode-map>\ | ||
| 333 | In that buffer, you can use almost all the usual dired bindings. | 355 | In that buffer, you can use almost all the usual dired bindings. |
| 334 | \\[locate-find-directory] visits the directory of the file on the current line. | 356 | \\[locate-find-directory] visits the directory of the file on the current line. |
| 335 | 357 | ||
| 358 | Operating on listed files works, but does not always | ||
| 359 | automatically update the buffer as in ordinary Dired. | ||
| 360 | This is true both for the main listing and for subdirectories. | ||
| 361 | Reverting the buffer using \\[revert-buffer] deletes all subdirectories. | ||
| 362 | Specific `locate-mode' commands, such as \\[locate-find-directory], | ||
| 363 | do not work in subdirectories. | ||
| 364 | |||
| 336 | \\{locate-mode-map}" | 365 | \\{locate-mode-map}" |
| 366 | ;; Not to be called interactively. | ||
| 337 | (kill-all-local-variables) | 367 | (kill-all-local-variables) |
| 338 | ;; Avoid clobbering this variables | 368 | ;; Avoid clobbering this variable |
| 339 | (make-local-variable 'dired-subdir-alist) | 369 | (make-local-variable 'dired-subdir-alist) |
| 340 | (use-local-map locate-mode-map) | 370 | (use-local-map locate-mode-map) |
| 341 | (setq major-mode 'locate-mode | 371 | (setq major-mode 'locate-mode |
| 342 | mode-name "Locate" | 372 | mode-name "Locate" |
| 343 | default-directory "/") | 373 | default-directory "/" |
| 374 | buffer-read-only t | ||
| 375 | selective-display t) | ||
| 344 | (dired-alist-add-1 default-directory (point-min-marker)) | 376 | (dired-alist-add-1 default-directory (point-min-marker)) |
| 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) | ||
| 345 | (make-local-variable 'dired-move-to-filename-regexp) | 380 | (make-local-variable 'dired-move-to-filename-regexp) |
| 346 | ;; This should support both Unix and Windoze style names | 381 | ;; This should support both Unix and Windoze style names |
| 347 | (setq dired-move-to-filename-regexp | 382 | (setq dired-move-to-filename-regexp |
| 348 | (concat "." | 383 | (concat "^." |
| 349 | (make-string (1- locate-filename-indentation) ?\ ) | 384 | (make-string (1- locate-filename-indentation) ?\ ) |
| 350 | "\\(/\\|[A-Za-z]:\\)")) | 385 | "\\(/\\|[A-Za-z]:\\)\\|" |
| 386 | (default-value 'dired-move-to-filename-regexp))) | ||
| 351 | (make-local-variable 'dired-actual-switches) | 387 | (make-local-variable 'dired-actual-switches) |
| 352 | (setq dired-actual-switches "") | 388 | (setq dired-actual-switches "") |
| 353 | (make-local-variable 'dired-permission-flags-regexp) | 389 | (make-local-variable 'dired-permission-flags-regexp) |
| 354 | (setq dired-permission-flags-regexp | 390 | (setq dired-permission-flags-regexp |
| 355 | (concat "^.\\(" | 391 | (concat "^.\\(" |
| 356 | (make-string (1- locate-filename-indentation) ?\ ) | 392 | (make-string (1- locate-filename-indentation) ?\ ) |
| 357 | "\\)")) | 393 | "\\)\\|" |
| 394 | (default-value 'dired-permission-flags-regexp))) | ||
| 358 | (make-local-variable 'revert-buffer-function) | 395 | (make-local-variable 'revert-buffer-function) |
| 359 | (setq revert-buffer-function 'locate-update) | 396 | (setq revert-buffer-function 'locate-update) |
| 397 | (set (make-local-variable 'page-delimiter) "\n\n") | ||
| 360 | (run-hooks 'locate-mode-hook)) | 398 | (run-hooks 'locate-mode-hook)) |
| 361 | 399 | ||
| 362 | (defun locate-do-setup (search-string) | 400 | (defun locate-do-setup (search-string) |
| @@ -386,7 +424,10 @@ In that buffer, you can use almost all the usual dired bindings. | |||
| 386 | (dired-insert-set-properties (elt pos 0) (elt pos 1))))) | 424 | (dired-insert-set-properties (elt pos 0) (elt pos 1))))) |
| 387 | 425 | ||
| 388 | (defun locate-insert-header (search-string) | 426 | (defun locate-insert-header (search-string) |
| 389 | (let ((locate-format-string "Matches for %s") | 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") | ||
| 390 | (locate-regexp-match | 431 | (locate-regexp-match |
| 391 | (concat " *Matches for \\(" (regexp-quote search-string) "\\)")) | 432 | (concat " *Matches for \\(" (regexp-quote search-string) "\\)")) |
| 392 | (locate-format-args (list search-string)) | 433 | (locate-format-args (list search-string)) |
| @@ -424,6 +465,7 @@ In that buffer, you can use almost all the usual dired bindings. | |||
| 424 | 465 | ||
| 425 | (save-excursion | 466 | (save-excursion |
| 426 | (goto-char (point-min)) | 467 | (goto-char (point-min)) |
| 468 | (forward-line 1) | ||
| 427 | (if (not (looking-at locate-regexp-match)) | 469 | (if (not (looking-at locate-regexp-match)) |
| 428 | nil | 470 | nil |
| 429 | (add-text-properties (match-beginning 1) (match-end 1) | 471 | (add-text-properties (match-beginning 1) (match-end 1) |
| @@ -439,9 +481,11 @@ In that buffer, you can use almost all the usual dired bindings. | |||
| 439 | (defun locate-tags () | 481 | (defun locate-tags () |
| 440 | "Visit a tags table in `*Locate*' mode." | 482 | "Visit a tags table in `*Locate*' mode." |
| 441 | (interactive) | 483 | (interactive) |
| 442 | (let ((tags-table (locate-get-filename))) | 484 | (if (locate-main-listing-line-p) |
| 443 | (and (y-or-n-p (format "Visit tags table %s? " tags-table)) | 485 | (let ((tags-table (locate-get-filename))) |
| 444 | (visit-tags-table tags-table)))) | 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."))) | ||
| 445 | 489 | ||
| 446 | ;; From Stephen Eglen <stephen@cns.ed.ac.uk> | 490 | ;; From Stephen Eglen <stephen@cns.ed.ac.uk> |
| 447 | (defun locate-update (ignore1 ignore2) | 491 | (defun locate-update (ignore1 ignore2) |
| @@ -460,12 +504,14 @@ Database is updated using the shell command in `locate-update-command'." | |||
| 460 | (defun locate-find-directory () | 504 | (defun locate-find-directory () |
| 461 | "Visit the directory of the file mentioned on this line." | 505 | "Visit the directory of the file mentioned on this line." |
| 462 | (interactive) | 506 | (interactive) |
| 463 | (let ((directory-name (locate-get-dirname))) | 507 | (if (locate-main-listing-line-p) |
| 464 | (if (file-directory-p directory-name) | 508 | (let ((directory-name (locate-get-dirname))) |
| 465 | (find-file directory-name) | 509 | (if (file-directory-p directory-name) |
| 466 | (if (file-symlink-p directory-name) | 510 | (find-file directory-name) |
| 467 | (error "Directory is a symlink to a nonexistent target") | 511 | (if (file-symlink-p directory-name) |
| 468 | (error "Directory no longer exists; run `updatedb' to update database"))))) | 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."))) | ||
| 469 | 515 | ||
| 470 | (defun locate-find-directory-other-window () | 516 | (defun locate-find-directory-other-window () |
| 471 | "Visit the directory of the file named on this line in other window." | 517 | "Visit the directory of the file named on this line in other window." |
| @@ -518,6 +564,14 @@ Database is updated using the shell command in `locate-update-command'." | |||
| 518 | string)))))) | 564 | string)))))) |
| 519 | (locate search-string))) | 565 | (locate search-string))) |
| 520 | 566 | ||
| 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 | |||
| 521 | (provide 'locate) | 575 | (provide 'locate) |
| 522 | 576 | ||
| 523 | ;;; arch-tag: 60c4d098-b5d5-4b3c-a3e0-51a2e9f43898 | 577 | ;;; arch-tag: 60c4d098-b5d5-4b3c-a3e0-51a2e9f43898 |