Mercurial > hg > xemacs-beta
comparison lisp/utils/thing.el @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | bcdc7deadc19 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:376386a54a3c |
---|---|
1 ;;; thing.el --- find language-specific contiguous pieces of text | |
2 | |
3 ;; Keywords: extensions, languages | |
4 | |
5 ;;; Authors: David Hughes <djh@cis.prime.com> | |
6 ;;; adapted from Martin Boyer's thing.el for imouse | |
7 ;;; Martin Boyer, IREQ <mboyer@ireq-robot.hydro.qc.ca> | |
8 ;;; adapted from Heinz Schmidt's thing.el for sky-mouse | |
9 ;;; Heinz Schmidt, ICSI (hws@ICSI.Berkeley.EDU) | |
10 ;;; adapted from Dan L. Pierson's epoch-thing.el | |
11 ;;; Dan L. Pierson <pierson@encore.com>, 2/5/90 | |
12 ;;; adapted from Joshua Guttman's Thing.el | |
13 ;;; Joshua Guttman, MITRE (guttman@mitre.org) | |
14 ;;; adapted from sun-fns.el by Joshua Guttman, MITRE. | |
15 ;;; | |
16 ;;; Copyright (C) International Computer Science Institute, 1991 | |
17 ;;; | |
18 | |
19 ;; This file is part of XEmacs. | |
20 | |
21 ;; XEmacs is free software; you can redistribute it and/or modify | |
22 ;; it under the terms of the GNU General Public License as published by | |
23 ;; the Free Software Foundation; either version 2, or (at your option) | |
24 ;; any later version. | |
25 | |
26 ;; XEmacs is distributed in the hope that it will be useful, | |
27 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
28 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
29 ;; GNU General Public License for more details. | |
30 | |
31 ;; You should have received a copy of the GNU General Public License | |
32 ;; along with XEmacs; see the file COPYING. If not, write to | |
33 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | |
34 | |
35 ;;; Synched up with: Not in FSF. | |
36 ;;; #### FSF has thingatpt.el, which does the same thing. Should merge | |
37 ;;; or toss this. | |
38 | |
39 ;;;*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
40 ;;;* FUNCTION: Things are language objects contiguous pieces of text | |
41 ;;;* whose boundaries can be defined by syntax or context. | |
42 ;;;* | |
43 ;;;* RELATED PACKAGES: various packages built on this. | |
44 ;;;* | |
45 ;;;* HISTORY: | |
46 ;;;* Last edited: David Hughes 21st December 1992 | |
47 ;;;* jul 21 21:00 1993 (tlp00): added a kludgy thing-filename | |
48 ;;;* Feb 22 21:00 1993 (tlp00): better merge with lucid and imouse | |
49 ;;;* Dec 21 11:11 1992 (djh): added thing-report-char-p | |
50 ;;;* Nov 23 18:00 1992 (djh): merged in Guido Bosch's ideas | |
51 ;;;* Sep 10 15:35 1992 (djh): adapted for Lucid emacs19-mouse.el | |
52 ;;;* Nov 28 17:40 1991 (mb): Cleaned up, and added thing-bigger-alist. | |
53 ;;;* May 24 00:33 1991 (hws): overworked and added syntax. | |
54 ;;;* Created: 2/5/90 Dan L. Pierson | |
55 ;;;*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
56 | |
57 (provide 'thing) | |
58 | |
59 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
60 ;;;;;;;;;;;; Customization and Entry Point ;;;;;;;;;;;;;;;;;;;;;;;;; | |
61 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
62 | |
63 (defvar thing-boundary-alist | |
64 '((?w thing-word) | |
65 (?_ thing-symbol) | |
66 (?\( thing-sexp-start) | |
67 (?\$ thing-sexp-start) | |
68 (?' thing-sexp-start) | |
69 (?\" thing-sexp-start) | |
70 (?\) thing-sexp-end) | |
71 (? thing-whitespace) | |
72 (?< thing-comment) | |
73 (?. thing-next-sexp)) | |
74 "*List of pairs of the form (SYNTAX-CHAR FUNCTION) used by | |
75 the function `thing-boundaries'.") | |
76 | |
77 (defvar thing-report-char-p t | |
78 "*Non nil means return single char boundaries if all else fails") | |
79 | |
80 (defvar thing-report-whitespace t | |
81 "*Non nil means that whitespaces are considered as things, otherwise not.") | |
82 | |
83 (defvar *last-thing* | |
84 "The last thing found by thing-boundaries. Used for chaining commands.") | |
85 | |
86 ;; The variable and function `thing-region' are to avoid the continual | |
87 ;; construction of cons cells as result af the thing scanner functions. | |
88 ;; This avoids unnecessary garbage collection. Guido Bosch <bosch@loria.fr> | |
89 | |
90 (defvar thing-region (cons 'nil 'nil) | |
91 "Cons cell that contains a region (<beginning> . <end>) | |
92 The function `thing-region' updates and returns it.") | |
93 | |
94 (defun thing-region (beginning end) | |
95 "Make BEGINNING the car and END the cdr of the cons cell in the | |
96 variable `thing-region'. Return the updated cons cell" | |
97 (cond ((/= beginning end) | |
98 (setcar thing-region beginning) | |
99 (setcdr thing-region end) | |
100 thing-region))) | |
101 | |
102 (defvar thing-bigger-alist | |
103 '((word-symbol thing-symbol) | |
104 (symbol thing-sexp) | |
105 (word-sexp thing-sexp) | |
106 (sexp thing-up-sexp) | |
107 (sexp-up thing-up-sexp) | |
108 (line thing-paragraph) | |
109 (paragraph thing-page) | |
110 (char thing-word) | |
111 (word-sentence thing-sentence) | |
112 (sentence thing-paragraph)) | |
113 "List of pairs to go from one thing to a bigger thing. | |
114 See mouse-select-bigger-thing and mouse-delete-bigger-thing.") | |
115 | |
116 (defvar thing-word-next nil | |
117 "*The next bigger thing after a word. A symbol. | |
118 Supported values are: word-symbol, word-sexp, and word-sentence. | |
119 Default value is word-sentence. | |
120 Automatically becomes local when set in any fashion.") | |
121 (make-variable-buffer-local 'thing-word-next) | |
122 | |
123 (defun thing-boundaries (here) | |
124 "Return start and end of text object at HERE using syntax table and | |
125 thing-boundary-alist. Thing-boundary-alist is a list of pairs of the | |
126 form (SYNTAX-CHAR FUNCTION) where FUNCTION takes a single position | |
127 argument and returns a cons of places (start end) representing | |
128 boundaries of the thing at that position. | |
129 | |
130 Typically: | |
131 Left or right Paren syntax indicates an s-expression. | |
132 The end of a line marks the line including a trailing newline. | |
133 Word syntax indicates current word. | |
134 Symbol syntax indicates symbol. | |
135 If it doesn't recognize one of these it selects just the character HERE. | |
136 | |
137 If an error occurs during syntax scanning, the function just prints a | |
138 message and returns `nil'." | |
139 (interactive "d") | |
140 (setq *last-thing* nil) | |
141 (if (save-excursion (goto-char here) (eolp)) | |
142 (thing-get-line here) | |
143 (let* ((syntax (char-syntax (char-after here))) | |
144 (pair (assq syntax thing-boundary-alist))) | |
145 (cond ((and pair | |
146 (or thing-report-whitespace | |
147 (not (eq (car (cdr pair)) 'thing-whitespace)))) | |
148 (funcall (car (cdr pair)) here)) | |
149 (thing-report-char-p | |
150 (setq *last-thing* 'char) | |
151 (thing-region here (1+ here))) | |
152 (t | |
153 nil))))) | |
154 | |
155 | |
156 | |
157 | |
158 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
159 ;;;;;;;;;;;;;;;;; Code Delimiters ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
160 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
161 | |
162 (defun thing-symbol (here) | |
163 "Return start and end of symbol at HERE." | |
164 (cond ((memq (char-syntax (char-after here)) '(?_ ?w)) | |
165 (setq *last-thing* 'symbol) | |
166 (let ((end (scan-sexps here 1))) | |
167 (thing-region (min here (scan-sexps end -1)) end))))) | |
168 | |
169 (defun thing-filename (here) | |
170 "Return start and end of filename at HERE." | |
171 (cond ((memq (char-syntax (char-after here)) '(?w ?_ ?.)) | |
172 (let (start end) | |
173 (save-excursion | |
174 (goto-char here) | |
175 (and (re-search-forward "\\s \\|:\\s\"\\|$" nil t) | |
176 (goto-char (setq end (match-beginning 0))) | |
177 (or | |
178 (and | |
179 (re-search-backward "[^_a-zA-Z0-9---#$.~/@]+" nil t) | |
180 (setq start (+ (match-beginning 0) | |
181 (if (bolp) | |
182 0 | |
183 1)))) | |
184 (setq start (point-min))) | |
185 (thing-region (min start here) (max here end)))))))) | |
186 ;~/ | |
187 (defun thing-sexp-start (here) | |
188 "Return start and end of sexp starting HERE." | |
189 (setq *last-thing* 'sexp-start) | |
190 (thing-region here (scan-sexps here 1))) | |
191 | |
192 (defun thing-sexp-end (here) | |
193 "Return start and end of sexp ending HERE." | |
194 (setq *last-thing* 'sexp-end) | |
195 (thing-region (scan-sexps (1+ here) -1) (1+ here))) | |
196 | |
197 (defun thing-sexp (here) | |
198 "Return start and end of the sexp at HERE." | |
199 (setq *last-thing* 'sexp) | |
200 (save-excursion | |
201 (goto-char here) | |
202 (thing-region (progn (backward-up-list 1) (point)) | |
203 (progn (forward-list 1) (point))))) | |
204 | |
205 (defun thing-up-sexp (here) | |
206 "Return start and end of the sexp enclosing the selected area." | |
207 (setq *last-thing* 'sexp-up) | |
208 ;; Keep going up and backward in sexps. This means that thing-up-sexp | |
209 ;; can only be called after thing-sexp or after itself. | |
210 (save-excursion | |
211 (goto-char here) | |
212 (thing-region (progn | |
213 (condition-case () | |
214 (backward-up-list 1) (error nil)) | |
215 (point)) | |
216 (progn | |
217 (condition-case () | |
218 (forward-list 1) (error nil)) | |
219 (point))))) | |
220 | |
221 ;;; Allow punctuation marks not followed by white-space to include | |
222 ;;; the subsequent sexp. Useful in foo.bar(x).baz and such. | |
223 (defun thing-next-sexp (here) | |
224 "Return from HERE to the end of the sexp at HERE, | |
225 if the character at HERE is part of a sexp." | |
226 (setq *last-thing* 'sexp-next) | |
227 (if (= (char-syntax (char-after (1+ here))) ? ) | |
228 (thing-region here (1+ here)) | |
229 (thing-region here | |
230 (save-excursion (goto-char here) (forward-sexp) (point))))) | |
231 | |
232 ;;; Allow click to comment-char to extend to end of line | |
233 (defun thing-comment (here) | |
234 "Return rest of line from HERE to newline." | |
235 (setq *last-thing* 'comment) | |
236 (save-excursion (goto-char here) | |
237 (while (= (char-syntax (preceding-char)) ?<) | |
238 (forward-char -1)) | |
239 (thing-region (point) (progn (end-of-line) (point))))) | |
240 | |
241 | |
242 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
243 ;;;;;;;;;;;;;;;;; Text Delimiters ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
244 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
245 | |
246 (defun thing-word (here) | |
247 "Return start and end of word at HERE." | |
248 (setq *last-thing* | |
249 (if thing-word-next | |
250 thing-word-next | |
251 (setq thing-word-next | |
252 (cond | |
253 ((memq major-mode '(emacs-lisp-mode c-mode c++-mode | |
254 fortran-mode latex-mode lisp-mode | |
255 perl-mode tex-mode)) | |
256 'word-symbol) | |
257 (t 'word-sentence))))) | |
258 (save-excursion | |
259 (goto-char here) | |
260 (forward-word 1) | |
261 (let ((end (point))) | |
262 (forward-word -1) | |
263 (thing-region (point) end)))) | |
264 | |
265 (defun thing-sentence (here) | |
266 "Return start and end of the sentence at HERE." | |
267 (setq *last-thing* 'sentence) | |
268 (save-excursion | |
269 (goto-char here) | |
270 (thing-region (progn (backward-sentence) (point)) | |
271 (progn (forward-sentence) (point))))) | |
272 | |
273 (defun thing-whitespace (here) | |
274 "Return start to end of all of whitespace HERE." | |
275 (setq *last-thing* 'whitespace) | |
276 (save-excursion | |
277 (goto-char here) | |
278 (let ((start (progn (skip-chars-backward " \t") (1+ (point)))) | |
279 (end (progn (skip-chars-forward " \t") (point)))) | |
280 (if (= start end) | |
281 (thing-region (1- start) end) | |
282 (thing-region start end))))) | |
283 | |
284 | |
285 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
286 ;;;;;;;;;;;;;;; Physical Delimiters ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
287 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
288 | |
289 (defun thing-get-line (here) | |
290 "Return whole of line HERE is in, with newline unless at eob." | |
291 (setq *last-thing* 'line) | |
292 (save-excursion | |
293 (goto-char here) | |
294 (let* ((start (progn (beginning-of-line 1) (point)))) | |
295 (thing-region start (point))))) | |
296 | |
297 (defun thing-paragraph (here) | |
298 "Return start and end of the paragraph at HERE." | |
299 (setq *last-thing* 'paragraph) | |
300 (save-excursion | |
301 (goto-char here) | |
302 (thing-region (progn (backward-paragraph) (point)) | |
303 (progn (forward-paragraph) (point))))) | |
304 | |
305 (defun thing-page (here) | |
306 "Return start and end of the page at HERE." | |
307 (setq *last-thing* 'page) | |
308 (save-excursion | |
309 (goto-char here) | |
310 (thing-region (progn (backward-page) (point)) | |
311 (progn (forward-page) (point))))) | |
312 | |
313 | |
314 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
315 ;;;;;;;;;;;;;;;; Support functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
316 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
317 | |
318 (defun kill-thing-at-point (here) | |
319 "Kill text object using syntax table. | |
320 See thing-boundaries for definition of text objects" | |
321 (interactive "d") | |
322 (let ((bounds (thing-boundaries here))) | |
323 (kill-region (car bounds) (cdr bounds)))) | |
324 | |
325 (defun copy-thing-at-point (here) | |
326 "Copy text object using syntax table. | |
327 See thing-boundaries for definition of text objects" | |
328 (interactive "d") | |
329 (let ((bounds (thing-boundaries here))) | |
330 (copy-region-as-kill (car bounds) (cdr bounds)))) |