Mercurial > hg > xemacs-beta
comparison lisp/hyperbole/hmoccur.el @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | 4103f0995bd7 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:376386a54a3c |
---|---|
1 ;;!emacs | |
2 ;; | |
3 ;; FILE: hmoccur.el | |
4 ;; SUMMARY: Multi-buffer or multi-file regexp occurrence location. | |
5 ;; USAGE: GNU Emacs Lisp Library | |
6 ;; KEYWORDS: hypermedia, matching | |
7 ;; | |
8 ;; AUTHOR: Markus Freericks <mfx@cs.tu-berlin.de> / Bob Weiner | |
9 ;; ORG: Technical University of Berlin / Brown U. | |
10 ;; | |
11 ;; ORIG-DATE: 1-Aug-91 | |
12 ;; LAST-MOD: 14-Apr-95 at 16:04:43 by Bob Weiner | |
13 ;; | |
14 ;; This file is part of Hyperbole. | |
15 ;; Available for use and distribution under the same terms as GNU Emacs. | |
16 ;; | |
17 ;; Copyright (C) 1991, Markus Freericks | |
18 ;; Copyright (C) 1991-1995, Free Software Foundation, Inc. | |
19 ;; Developed with support from Motorola Inc. | |
20 ;; | |
21 ;; DESCRIPTION: | |
22 ;; | |
23 ;; Modified by Bob Weiner to allow selection of a set of files within a | |
24 ;; single directory to search. By default, {M-x moccur RTN} searches | |
25 ;; current buffers with files attached. | |
26 ;; | |
27 ;; Date: 1 Aug 91 15:47:27 GMT | |
28 ;; From: mfx@cs.tu-berlin.de (Markus Freericks) | |
29 ;; Subject: moccur - multibuffer occurences | |
30 ;; | |
31 ;; While editing some dozen or so files, i had the dire need for | |
32 ;; something like 'occur' that can cope with multiple buffers. This has | |
33 ;; probably been done before; but still, here is my try at it. It seems | |
34 ;; to be very useful. | |
35 ;; | |
36 ;; How to use it: simple say | |
37 ;; M-x moccur <regexp> | |
38 ;; moccur then searches through *all buffers* currently existing that are | |
39 ;; bound to files and displays the occurences in a buffer that runs in | |
40 ;; Moccur-mode. Change to that buffer, scroll around, and say C-c C-c | |
41 ;; to jump to the occurrence. Quite simple. | |
42 ;; | |
43 ;; Incompatibilites to Occur mode: | |
44 ;; a) it browses through *all* buffers that have a file name | |
45 ;; associated with them; those may or may not include the current | |
46 ;; buffer. Especially, while standard occur works | |
47 ;; on 'all lines following point', Moccur does not. | |
48 ;; b) there is no support for the 'NLINE' argument. | |
49 ;; | |
50 ;; Usage: | |
51 ;; moccur <regexp> shows all occurences of <regexp> in all buffers | |
52 ;; currently existing that refer to files. | |
53 ;; the occurences are displayed in a buffer running in Moccur mode; | |
54 ;; C-c C-c gets you to the occurence | |
55 ;; | |
56 ;; DESCRIP-END. | |
57 | |
58 ;;; ************************************************************************ | |
59 ;;; Public variables | |
60 ;;; ************************************************************************ | |
61 | |
62 (defconst moccur-source-prefix "@loc> " | |
63 "Prefix for lines indicating source of matches.") | |
64 | |
65 ;;; ************************************************************************ | |
66 ;;; Public functions | |
67 ;;; ************************************************************************ | |
68 | |
69 (defun moccur (regexp &optional file-regexp no-fold-search) | |
70 "Show all lines of all buffers containing a match for REGEXP. | |
71 With optional FILE-REGEXP, a pattern matching to files in a single | |
72 directory, search matching files rather than current buffers. | |
73 The lines are shown in a buffer named *Moccur* which serves as a menu to | |
74 find any of the occurrences in this buffer. | |
75 \\[describe-mode] in that buffer explains how." | |
76 (interactive "sRegexp to find occurrences of: \nsFiles to search (default current file buffers): ") | |
77 (if (equal file-regexp "") (setq file-regexp nil)) | |
78 (let* ((buffers (if file-regexp (directory-files | |
79 (expand-file-name | |
80 (or (file-name-directory | |
81 file-regexp) ".")) | |
82 'full (file-name-nondirectory file-regexp)) | |
83 (buffer-list))) | |
84 (occbuf (get-buffer-create "*Moccur*")) | |
85 (matches 0) | |
86 (firstmatch t)) | |
87 (set-buffer occbuf) | |
88 (setq buffer-read-only nil) | |
89 (widen) | |
90 (erase-buffer) | |
91 (insert "Lines matching '" regexp "':\n\n") | |
92 (let ((currbuf) (currfile) (kill-buf)) | |
93 (while buffers | |
94 (setq currbuf (car buffers) | |
95 currfile (if (stringp currbuf) currbuf) | |
96 kill-buf (and currfile (not (get-file-buffer currfile))) | |
97 buffers (cdr buffers)) | |
98 (if currfile | |
99 (setq currbuf (find-file-noselect currfile)) | |
100 (setq currfile (buffer-file-name currbuf))) | |
101 (if (or (not currfile) (not currbuf)) | |
102 nil | |
103 (set-buffer currbuf) | |
104 (let ((case-fold-search (not no-fold-search))) | |
105 (save-excursion | |
106 (goto-char (point-min)) | |
107 (setq firstmatch t) | |
108 (while (re-search-forward regexp nil t) | |
109 (setq matches (+ matches 1)) | |
110 (let* ((linenum (count-lines (point-min)(point))) | |
111 (tag (format "\n%4d:" linenum))) | |
112 (set-buffer occbuf) | |
113 (if firstmatch | |
114 (progn | |
115 (insert moccur-source-prefix currfile "\n") | |
116 (setq firstmatch nil))) | |
117 (insert tag) | |
118 (set-buffer currbuf) | |
119 (forward-word -1) ;; needed if match goes to eoline | |
120 (beginning-of-line) | |
121 (let ((beg (point))) | |
122 (end-of-line) | |
123 (append-to-buffer occbuf beg (point))) | |
124 (forward-line 1))))) | |
125 (save-excursion | |
126 (set-buffer occbuf) | |
127 (if (not firstmatch) (insert "\n\n")) | |
128 (if kill-buf (kill-buffer currbuf)))))) | |
129 (if (> matches 0) | |
130 (progn | |
131 (set-buffer occbuf) | |
132 (moccur-mode) | |
133 (if (fboundp 'outline-minor-mode) | |
134 (and (progn (goto-char 1) | |
135 (search-forward "\C-m" nil t)) | |
136 (outline-minor-mode 1))) | |
137 (goto-char (point-min)) | |
138 (pop-to-buffer occbuf) | |
139 (message "%d matches." matches) | |
140 t) | |
141 (message "No matches.") | |
142 nil))) | |
143 | |
144 (defun moccur-to () | |
145 "Go to the line where this occurrence was found." | |
146 (interactive) | |
147 (if (not (eq major-mode 'moccur-mode)) | |
148 (error "'moccur-to' must be called within a moccur buffer.") | |
149 (let ((beg nil) | |
150 (line nil) | |
151 (lineno nil) | |
152 (dstbuf nil)) | |
153 (save-excursion | |
154 (beginning-of-line) | |
155 (setq beg (point)) | |
156 (end-of-line) | |
157 (setq line (buffer-substring beg (point))) | |
158 (if (string-match "^[ ]*[0-9]+:" line) | |
159 (progn | |
160 (setq lineno (string-to-int (substring | |
161 line 0 (match-end 0)))) | |
162 (if (re-search-backward | |
163 (concat "^" moccur-source-prefix | |
164 "\"?\\([^\" \n]+\\)\"?") nil t) | |
165 (progn | |
166 (setq line (buffer-substring | |
167 (match-beginning 1) (match-end 1)) | |
168 dstbuf (find-file-noselect line)) | |
169 (if (not dstbuf) | |
170 (message | |
171 "moccur-to: file '%s' is not readable" line))) | |
172 (error "No moccur header line for file."))) | |
173 (error "Not an moccur occurrence line."))) | |
174 (if (and lineno dstbuf) | |
175 (progn | |
176 (message "Selection <%s> line %d." line lineno) | |
177 (pop-to-buffer dstbuf) | |
178 (goto-line lineno)))))) | |
179 | |
180 (fset 'moccur-mode-goto-occurrence 'moccur-to) | |
181 | |
182 | |
183 ;;; ************************************************************************ | |
184 ;;; Private functions | |
185 ;;; ************************************************************************ | |
186 | |
187 (defun moccur-mode () | |
188 "Major mode for output from \\[moccur]. | |
189 Move point to one of the occurrences in this buffer, | |
190 then use \\[moccur-to] to go to the same occurrence | |
191 in the buffer that the occurrenc was found in. | |
192 \\{occur-mode-map}" | |
193 (kill-all-local-variables) | |
194 (use-local-map moccur-mode-map) | |
195 (setq major-mode 'moccur-mode) | |
196 (setq mode-name "Moccur")) | |
197 | |
198 ;;; ************************************************************************ | |
199 ;;; Private variables | |
200 ;;; ************************************************************************ | |
201 | |
202 (defvar moccur-mode-map ()) | |
203 (if moccur-mode-map | |
204 () | |
205 (setq moccur-mode-map (make-sparse-keymap)) | |
206 (define-key moccur-mode-map "\C-c\C-c" 'moccur-to) | |
207 (define-key moccur-mode-map " " 'moccur-to) | |
208 (define-key moccur-mode-map "\C-m" 'moccur-to) | |
209 ) | |
210 | |
211 (provide 'hmoccur) |