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