1 ;;; thing.el --- find language-specific contiguous pieces of text
3 ;; Copyright (C) 1997 Free Software Foundation, Inc.
4 ;; Copyright (C) International Computer Science Institute, 1991
6 ;; Author: David Hughes <d.hughes@videonetworks.com>
7 ;; Maintainer: XEmacs Development Team
8 ;; Keywords: extensions, languages
10 ;; This file is part of XEmacs.
12 ;; XEmacs is free software; you can redistribute it and/or modify it
13 ;; under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 2, or (at your option)
17 ;; XEmacs is distributed in the hope that it will be useful, but
18 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 ;; General Public License for more details.
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with XEmacs; see the file COPYING. If not, write to the Free
24 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 ;;; Synched up with: Not in FSF.
31 ;; #### FSF has thingatpt.el, which does the same thing. Should merge
34 ;; I wish. The howls of pain every time I try are too overwhelming. -slb
36 ;; Authors: David Hughes <djh@cis.prime.com>
37 ;; adapted from Martin Boyer's thing.el for imouse
38 ;; Martin Boyer, IREQ <mboyer@ireq-robot.hydro.qc.ca>
39 ;; adapted from Heinz Schmidt's thing.el for sky-mouse
40 ;; Heinz Schmidt, ICSI (hws@ICSI.Berkeley.EDU)
41 ;; adapted from Dan L. Pierson's epoch-thing.el
42 ;; Dan L. Pierson <pierson@encore.com>, 2/5/90
43 ;; adapted from Joshua Guttman's Thing.el
44 ;; Joshua Guttman, MITRE (guttman@mitre.org)
45 ;; adapted from sun-fns.el by Joshua Guttman, MITRE.
49 ;;*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
50 ;;* FUNCTION: Things are language objects contiguous pieces of text
51 ;;* whose boundaries can be defined by syntax or context.
53 ;;* RELATED PACKAGES: various packages built on this.
56 ;;* Last edited: David Hughes 21st December 1992
57 ;;* jul 21 21:00 1993 (tlp00): added a kludgy thing-filename
58 ;;* Feb 22 21:00 1993 (tlp00): better merge with lucid and imouse
59 ;;* Dec 21 11:11 1992 (djh): added thing-report-char-p
60 ;;* Nov 23 18:00 1992 (djh): merged in Guido Bosch's ideas
61 ;;* Sep 10 15:35 1992 (djh): adapted for Lucid emacs19-mouse.el
62 ;;* Nov 28 17:40 1991 (mb): Cleaned up, and added thing-bigger-alist.
63 ;;* May 24 00:33 1991 (hws): overworked and added syntax.
64 ;;* Created: 2/5/90 Dan L. Pierson
65 ;;*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
71 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
72 ;;;;;;;;;;;; Customization and Entry Point ;;;;;;;;;;;;;;;;;;;;;;;;;
73 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
75 (defvar thing-boundary-alist
78 (?\( thing-sexp-start)
79 (?\$ thing-sexp-start)
81 (?\" thing-sexp-start)
86 "*List of pairs of the form (SYNTAX-CHAR FUNCTION) used by
87 the function `thing-boundaries'.")
89 (defvar thing-report-char-p t
90 "*Non nil means return single char boundaries if all else fails")
92 (defvar thing-report-whitespace t
93 "*Non nil means that whitespaces are considered as things, otherwise not.")
96 "The last thing found by thing-boundaries. Used for chaining commands.")
98 ;; The variable and function `thing-region' are to avoid the continual
99 ;; construction of cons cells as result af the thing scanner functions.
100 ;; This avoids unnecessary garbage collection. Guido Bosch <bosch@loria.fr>
102 (defvar thing-region (cons 'nil 'nil)
103 "Cons cell that contains a region (<beginning> . <end>)
104 The function `thing-region' updates and returns it.")
106 (defun thing-region (beginning end)
107 "Make BEGINNING the car and END the cdr of the cons cell in the
108 variable `thing-region'. Return the updated cons cell"
109 (cond ((/= beginning end)
110 (setcar thing-region beginning)
111 (setcdr thing-region end)
114 (defvar thing-bigger-alist
115 '((word-symbol thing-symbol)
117 (word-sexp thing-sexp)
119 (sexp-up thing-up-sexp)
120 (line thing-paragraph)
121 (paragraph thing-page)
123 (word-sentence thing-sentence)
124 (sentence thing-paragraph))
125 "List of pairs to go from one thing to a bigger thing.
126 See mouse-select-bigger-thing and mouse-delete-bigger-thing.")
128 (defvar thing-word-next nil
129 "*The next bigger thing after a word. A symbol.
130 Supported values are: word-symbol, word-sexp, and word-sentence.
131 Default value is word-sentence.
132 Automatically becomes local when set in any fashion.")
133 (make-variable-buffer-local 'thing-word-next)
135 (defun thing-boundaries (here)
136 "Return start and end of text object at HERE using syntax table and
137 thing-boundary-alist. Thing-boundary-alist is a list of pairs of the
138 form (SYNTAX-CHAR FUNCTION) where FUNCTION takes a single position
139 argument and returns a cons of places (start end) representing
140 boundaries of the thing at that position.
143 Left or right Paren syntax indicates an s-expression.
144 The end of a line marks the line including a trailing newline.
145 Word syntax indicates current word.
146 Symbol syntax indicates symbol.
147 If it doesn't recognize one of these it selects just the character HERE.
149 If an error occurs during syntax scanning, the function just prints a
150 message and returns `nil'."
152 (setq *last-thing* nil)
153 (if (save-excursion (goto-char here) (eolp))
154 (thing-get-line here)
155 (let* ((syntax (char-syntax (char-after here)))
156 (pair (assq syntax thing-boundary-alist)))
158 (or thing-report-whitespace
159 (not (eq (car (cdr pair)) 'thing-whitespace))))
160 (funcall (car (cdr pair)) here))
162 (setq *last-thing* 'char)
163 (thing-region here (1+ here)))
170 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
171 ;;;;;;;;;;;;;;;;; Code Delimiters ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
172 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
174 (defun thing-symbol (here)
175 "Return start and end of symbol at HERE."
176 (cond ((or (memq (char-syntax (char-after here)) '(?_ ?w))
178 (memq (char-syntax (char-before here)) '(?_ ?w))
179 ;; point is at the end of a symbol; look from inside the symbol
180 (setq here (1- here))))
181 (setq *last-thing* 'symbol)
182 (let ((end (scan-sexps here 1)))
184 (thing-region (min here (scan-sexps end -1)) end))))))
186 (defun thing-filename (here)
187 "Return start and end of filename at HERE."
188 (cond ((and (memq (char-syntax (char-after here)) '(?w ?_ ?.))
189 (< here (point-max)))
193 (and (re-search-forward "\\s \\|:\\s\"\\|$" nil t)
194 (goto-char (setq end (match-beginning 0)))
197 (re-search-backward "[^_a-zA-Z0-9---#$.~/@]+" nil t)
198 (setq start (+ (match-beginning 0)
202 (setq start (point-min)))
203 (thing-region (min start here) (max here end))))))))
205 (defun thing-sexp-start (here)
206 "Return start and end of sexp starting HERE."
207 (setq *last-thing* 'sexp-start)
208 (thing-region here (scan-sexps here 1)))
210 (defun thing-sexp-end (here)
211 "Return start and end of sexp ending HERE."
212 (setq *last-thing* 'sexp-end)
213 (thing-region (scan-sexps (1+ here) -1) (1+ here)))
215 (defun thing-sexp (here)
216 "Return start and end of the sexp at HERE."
217 (setq *last-thing* 'sexp)
220 (thing-region (progn (backward-up-list 1) (point))
221 (progn (forward-list 1) (point)))))
223 (defun thing-up-sexp (here)
224 "Return start and end of the sexp enclosing the selected area."
225 (setq *last-thing* 'sexp-up)
226 ;; Keep going up and backward in sexps. This means that thing-up-sexp
227 ;; can only be called after thing-sexp or after itself.
232 (backward-up-list 1) (error nil))
236 (forward-list 1) (error nil))
239 ;;; Allow punctuation marks not followed by white-space to include
240 ;;; the subsequent sexp. Useful in foo.bar(x).baz and such.
241 (defun thing-next-sexp (here)
242 "Return from HERE to the end of the sexp at HERE,
243 if the character at HERE is part of a sexp."
244 (setq *last-thing* 'sexp-next)
245 (if (= (char-syntax (char-after (1+ here))) ? )
246 (thing-region here (1+ here))
248 (save-excursion (goto-char here) (forward-sexp) (point)))))
250 ;;; Allow click to comment-char to extend to end of line
251 (defun thing-comment (here)
252 "Return rest of line from HERE to newline."
253 (setq *last-thing* 'comment)
254 (save-excursion (goto-char here)
255 (while (= (char-syntax (preceding-char)) ?<)
257 (thing-region (point) (progn (end-of-line) (point)))))
260 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
261 ;;;;;;;;;;;;;;;;; Text Delimiters ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
262 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
264 (defun thing-word (here)
265 "Return start and end of word at HERE."
269 (setq thing-word-next
271 ((memq major-mode '(emacs-lisp-mode c-mode c++-mode
272 fortran-mode latex-mode lisp-mode
275 (t 'word-sentence)))))
281 (thing-region (point) end))))
283 (defun thing-sentence (here)
284 "Return start and end of the sentence at HERE."
285 (setq *last-thing* 'sentence)
288 (thing-region (progn (backward-sentence) (point))
289 (progn (forward-sentence) (point)))))
291 (defun thing-whitespace (here)
292 "Return start to end of all of whitespace HERE."
293 (setq *last-thing* 'whitespace)
296 (let ((start (progn (skip-chars-backward " \t") (1+ (point))))
297 (end (progn (skip-chars-forward " \t") (point))))
299 (thing-region (1- start) end)
300 (thing-region start end)))))
303 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
304 ;;;;;;;;;;;;;;; Physical Delimiters ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
305 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
307 (defun thing-get-line (here)
308 "Return whole of line HERE is in, with newline unless at eob."
309 (setq *last-thing* 'line)
312 (let* ((start (progn (beginning-of-line 1) (point))))
313 (thing-region start (point)))))
315 (defun thing-paragraph (here)
316 "Return start and end of the paragraph at HERE."
317 (setq *last-thing* 'paragraph)
320 (thing-region (progn (backward-paragraph) (point))
321 (progn (forward-paragraph) (point)))))
323 (defun thing-page (here)
324 "Return start and end of the page at HERE."
325 (setq *last-thing* 'page)
328 (thing-region (progn (backward-page) (point))
329 (progn (forward-page) (point)))))
332 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
333 ;;;;;;;;;;;;;;;; Support functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
334 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
336 (defun kill-thing-at-point (here)
337 "Kill text object using syntax table.
338 See thing-boundaries for definition of text objects"
340 (let ((bounds (thing-boundaries here)))
341 (kill-region (car bounds) (cdr bounds))))
343 (defun copy-thing-at-point (here)
344 "Copy text object using syntax table.
345 See thing-boundaries for definition of text objects"
347 (let ((bounds (thing-boundaries here)))
348 (copy-region-as-kill (car bounds) (cdr bounds))))
350 ;;; thing.el ends here