[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: patch for thingatpt.el
From: |
Drew Adams |
Subject: |
RE: patch for thingatpt.el |
Date: |
Mon, 16 Jul 2007 09:55:12 -0700 |
> > Below is a patch for thingatpt.el that provides additional
> > functionality and new thing and form functions. In particular:
> > (1) it lets you supply a syntax-table argument to most functions,
> > to affect the definition of what a word etc. is, and (2) it
> > provides functions to return things near point, not
> > just precisely at point.
>
> I believe that point 1 is misguided. We have `with-syntax-table'
> for those cases and it is quite sufficient AFAIK.
Right, and it's a much better approach too. Sorry about that. My enhancement
predated `with-syntax-table', and I wasn't aware of it.
Here is an updated change log and patch, which also incorporates the `defun'
bug fix I sent after the previous patch.
---------8<------------------
2007-07-16 Drew Adams <address@hidden>
* thingatpt.el: Functions for things near point. Treat defuns.
(near-point-x-distance, near-point-y-distance): New options.
(bounds-of-form-at-point, bounds-of-form-nearest-point,
bounds-of-symbol-at-point, bounds-of-symbol-nearest-point,
bounds-of-thing-at-point-1, bounds-of-thing-nearest-point,
form-at-point-with-bounds, form-nearest-point,
form-nearest-point-with-bounds, forward-char-same-line,
list-nearest-point, non-nil-symbol-name-at-point,
non-nil-symbol-name-nearest-point,
non-nil-symbol-nearest-point, number-nearest-point,
sentence-nearest-point, sexp-nearest-point,
symbol-at-point-with-bounds, symbol-name-at-point,
symbol-name-nearest-point, symbol-nearest-point,
symbol-nearest-point-with-bounds, thing-at-point-with-bounds,
thing/form-nearest-point-with-bounds, thing-nearest-point,
thing-nearest-point-with-bounds, word-nearest-point):
New functions.
(symbol-at-point): New arg NON-NIL.
(beginning-of-thing, beginning-of-sexp, end-of-thing,
end-of-sexp, form-at-point, forward-same-syntax,
forward-symbol, forward-whitespace, in-string-p,
list-at-point, number-at-point, sentence-at-point,
sexp-at-point, symbol-at-point,
thing-at-point-bounds-of-url-at-point, word-at-point):
Added doc string.
Defined treatment of defuns (in doc strings, but undefined).
---------8<------------------
*** thingatpt-CVS-2007-07-14.el Sat Jul 14 08:40:06 2007
--- thingatpt-CVS-patched-2007-07-16.el Mon Jul 16 09:45:58 2007
***************
*** 49,66 ****
(provide 'thingatpt)
! ;; Basic movement
! ;;;###autoload
! (defun forward-thing (thing &optional n)
! "Move forward to the end of the Nth next THING."
! (let ((forward-op (or (get thing 'forward-op)
! (intern-soft (format "forward-%s" thing)))))
! (if (functionp forward-op)
! (funcall forward-op (or n 1))
! (error "Can't determine how to move over a %s" thing))))
! ;; General routines
;;;###autoload
(defun bounds-of-thing-at-point (thing)
--- 49,71 ----
(provide 'thingatpt)
! ;;; Options
! (defcustom near-point-x-distance 50
! "Maximum number of characters from point to search, left and right.
! Used by functions that provide default text for minibuffer input.
! Some functions might ignore or override this setting temporarily."
! :type 'integer :group 'minibuffer)
!
! (defcustom near-point-y-distance 5
! "Maximum number of lines from point to search, up and down.
! To constrain search to the same line as point, set this to zero.
! Used by functions that provide default text for minibuffer input.
! Some functions might ignore or override this setting temporarily."
! :type 'integer :group 'minibuffer)
!
! ;;; THINGS -----------------------------------------------
;;;###autoload
(defun bounds-of-thing-at-point (thing)
***************
*** 68,79 ****
THING is a symbol which specifies the kind of syntactic entity you want.
Possibilities include `symbol', `list', `sexp', `defun', `filename',
`url',
`email', `word', `sentence', `whitespace', `line', `page' and others.
! See the file `thingatpt.el' for documentation on how to define
! a symbol as a valid THING.
!
! The value is a cons cell (START . END) giving the start and end positions
! of the textual entity that was found."
(if (get thing 'bounds-of-thing-at-point)
(funcall (get thing 'bounds-of-thing-at-point))
(let ((orig (point)))
--- 73,85 ----
THING is a symbol which specifies the kind of syntactic entity you want.
Possibilities include `symbol', `list', `sexp', `defun', `filename',
`url',
`email', `word', `sentence', `whitespace', `line', `page' and others.
+ See file `thingatpt.el' for how to define a symbol as a valid THING.
+ The value returned is a cons cell (START . END) giving the start and
+ end positions of the textual entity that was found."
+ (bounds-of-thing-at-point-1 thing))
! (defun bounds-of-thing-at-point-1 (thing)
! "Helper function for `bounds-of-thing-at-point'."
(if (get thing 'bounds-of-thing-at-point)
(funcall (get thing 'bounds-of-thing-at-point))
(let ((orig (point)))
***************
*** 120,211 ****
(error nil)))))
;;;###autoload
(defun thing-at-point (thing)
! "Return the THING at point.
THING is a symbol which specifies the kind of syntactic entity you want.
Possibilities include `symbol', `list', `sexp', `defun', `filename',
`url',
`email', `word', `sentence', `whitespace', `line', `page' and others.
!
! See the file `thingatpt.el' for documentation on how to define
! a symbol as a valid THING."
(if (get thing 'thing-at-point)
(funcall (get thing 'thing-at-point))
(let ((bounds (bounds-of-thing-at-point thing)))
! (if bounds
! (buffer-substring (car bounds) (cdr bounds))))))
;; Go to beginning/end
(defun beginning-of-thing (thing)
(let ((bounds (bounds-of-thing-at-point thing)))
(or bounds (error "No %s here" thing))
(goto-char (car bounds))))
(defun end-of-thing (thing)
(let ((bounds (bounds-of-thing-at-point thing)))
(or bounds (error "No %s here" thing))
(goto-char (cdr bounds))))
;; Special cases
! ;; Lines
;; bolp will be false when you click on the last line in the buffer
;; and it has no final newline.
!
! (put 'line 'beginning-op
! (lambda () (if (bolp) (forward-line -1) (beginning-of-line))))
;; Sexps
-
(defun in-string-p ()
(let ((orig (point)))
(save-excursion
(beginning-of-defun)
(nth 3 (parse-partial-sexp (point) orig)))))
(defun end-of-sexp ()
(let ((char-syntax (char-syntax (char-after (point)))))
(if (or (eq char-syntax ?\))
(and (eq char-syntax ?\") (in-string-p)))
(forward-char 1)
(forward-sexp 1))))
-
(put 'sexp 'end-op 'end-of-sexp)
(defun beginning-of-sexp ()
(let ((char-syntax (char-syntax (char-before (point)))))
(if (or (eq char-syntax ?\()
(and (eq char-syntax ?\") (in-string-p)))
(forward-char -1)
(forward-sexp -1))))
-
(put 'sexp 'beginning-op 'beginning-of-sexp)
;; Lists
-
(put 'list 'end-op (lambda () (up-list 1)))
(put 'list 'beginning-op 'backward-sexp)
;; Filenames and URLs www.com/foo%32bar
-
(defvar thing-at-point-file-name-chars "-~/[:alnum:]_.${}#%,:"
"Characters allowable in filenames.")
!
! (put 'filename 'end-op
! (lambda ()
! (re-search-forward (concat "\\=[" thing-at-point-file-name-chars
"]*")
nil t)))
! (put 'filename 'beginning-op
! (lambda ()
! (if (re-search-backward (concat "[^" thing-at-point-file-name-chars
"]")
nil t)
(forward-char)
(goto-char (point-min)))))
(defvar thing-at-point-url-path-regexp
"[^]\t\n \"'()<>[^`{}]*[^]\t\n \"'()<>[^`{}.,;]+"
! "A regular expression probably matching the host and filename or e-mail
part of a URL.")
(defvar thing-at-point-short-url-regexp
(concat "[-A-Za-z0-9.]+" thing-at-point-url-path-regexp)
--- 126,325 ----
(error nil)))))
;;;###autoload
+ (defun thing-at-point-with-bounds (thing)
+ "Return (THING START . END) with START and END of THING.
+ Return nil if no THING is found.
+ THING is the `thing-at-point' (which see).
+ START and END are the car and cdr of the `bounds-of-thing-at-point'."
+ (let ((bounds (bounds-of-thing-at-point thing)))
+ (and bounds (cons (buffer-substring (car bounds) (cdr bounds))
bounds))))
+
+ ;;;###autoload
(defun thing-at-point (thing)
! "Return the THING at point, or nil if there is none.
THING is a symbol which specifies the kind of syntactic entity you want.
Possibilities include `symbol', `list', `sexp', `defun', `filename',
`url',
`email', `word', `sentence', `whitespace', `line', `page' and others.
! See file `thingatpt.el' for how to define a symbol as a valid THING."
(if (get thing 'thing-at-point)
(funcall (get thing 'thing-at-point))
(let ((bounds (bounds-of-thing-at-point thing)))
! (and bounds (buffer-substring (car bounds) (cdr bounds))))))
!
! ;;;###autoload
! (defun thing-nearest-point-with-bounds (thing)
! "Return (THING START . END) with START and END of THING.
! Return nil if no THING is found.
! THING is the `thing-nearest-point' (which see)."
! (thing/form-nearest-point-with-bounds #'thing-at-point-with-bounds
thing))
!
! (defun thing/form-nearest-point-with-bounds (fn thing &optional pred)
! "Thing or form nearest point, with bounds.
! FN is a function returning a thing or form at point, with bounds.
! If PRED is non-nil, then FN is called with THING and PRED as
! arguments. Otherwise, it is called with THING as argument.
! THING is the `thing-nearest-point' (which see).
! PRED is an optional predicate that THING must satisfy to qualify."
! (let ((f-or-t+bds (if pred (funcall fn thing pred) (funcall fn thing)))
! (ind1 0) (ind2 0) (bobp (bobp)) (updown 1)
! (eobp (eobp)) (bolp (bolp)) (eolp (eolp))
! (max-x (abs near-point-x-distance))
! (max-y (abs near-point-y-distance)))
! ;; IND2: Loop over lines (alternately up and down).
! (while (and (<= ind2 max-y) (not f-or-t+bds) (not (and bobp eobp)))
! (setq updown (- updown)) ; Switch directions up/down
(1/-1).
! (save-excursion
! (condition-case ()
! (previous-line (* updown ind2)) ; 0, 1, -1, 2, -2, ...
! (beginning-of-buffer (setq bobp t))
! (end-of-buffer (setq eobp t))
! (error nil))
! ;; Don't try to go beyond buffer limit.
! (unless (or (and bobp (natnump updown)) (and eobp (< updown 0)))
! (setq f-or-t+bds (if pred (funcall fn thing pred) (funcall fn
thing))
! bolp (bolp) eolp (eolp) ind1 0)
! (save-excursion
! ;; IND1: Loop over chars in same line (alternately left and
right),
! ;; until either found thing/form or both line limits reached.
! (while (and (not (and bolp eolp))
! (<= ind1 max-x)
! (not f-or-t+bds))
! (unless bolp (save-excursion ; Left.
! (setq bolp (forward-char-same-line (-
ind1))
! f-or-t+bds
! (if pred (funcall fn thing pred)
(funcall fn thing)))))
! (unless (or f-or-t+bds eolp) ; Right.
! (save-excursion
! (setq eolp (forward-char-same-line ind1)
! f-or-t+bds (if pred (funcall fn thing pred)
(funcall fn thing)))))
! (setq ind1 (1+ ind1)))
! (setq bobp (bobp) eobp (eobp)))))
! ;; Increase search line distance every second time (once up, once
down).
! (when (or (< updown 0) (zerop ind2)) (setq ind2 (1+ ind2)))) ;
0,1,1,2,2...
! f-or-t+bds))
!
! (defun forward-char-same-line (&optional arg)
! "Move forward a max of ARG chars on the same line, or backward if ARG <
0.
! Return the signed number of chars moved if /= ARG, else return nil."
! (interactive "p")
! (let* ((start (point))
! (fwd-p (natnump arg))
! (max (save-excursion
! (if fwd-p (end-of-line) (beginning-of-line))
! (- (point) start))))
! (forward-char (if fwd-p (min max arg) (max max arg)))
! (and (< (abs max) (abs arg)) max)))
!
! ;;;###autoload
! (defun bounds-of-thing-nearest-point (thing)
! "Return (START . END) with START and END of type THING.
! Return nil if no such THING is found. See `thing-nearest-point'."
! (let ((thing+bds (thing-nearest-point-with-bounds thing)))
! (and thing+bds (cdr thing+bds))))
!
! ;;;###autoload
! (defun thing-nearest-point (thing)
! "Return the THING nearest to the cursor, if any, else return nil.
! \"Nearest\" to point is determined as follows:
! The nearest THING on the same line is returned, if there is any.
! Between two THINGs equidistant from point on the same line, the
! leftmost is considered nearer.
! Otherwise, neighboring lines are tried in sequence:
! previous, next, 2nd previous, 2nd next, 3rd previous, 3rd next, etc.
! This means that between two THINGs equidistant from point in
! lines above and below it, the THING in the line above point
! (previous Nth) is considered nearer to it.
! Related function `thing-at-point' returns the THING under the cursor,
! or nil if none."
! (let ((thing+bds (thing-nearest-point-with-bounds thing)))
! (and thing+bds (car thing+bds))))
!
!
! ;;; FORWARD, BEGINNING, END OPERATIONS ------------------------------
!
! ;;;###autoload
! (defun forward-thing (thing &optional n)
! "Move forward to the end of the Nth next THING."
! (let ((forward-op (or (get thing 'forward-op)
! (intern-soft (format "forward-%s" thing)))))
! (if (functionp forward-op)
! (funcall forward-op (or n 1))
! (error "Can't determine how to move over a %s" thing))))
;; Go to beginning/end
(defun beginning-of-thing (thing)
+ "Go to the beginning of THING."
(let ((bounds (bounds-of-thing-at-point thing)))
(or bounds (error "No %s here" thing))
(goto-char (car bounds))))
(defun end-of-thing (thing)
+ "Go to the end of THING."
(let ((bounds (bounds-of-thing-at-point thing)))
(or bounds (error "No %s here" thing))
(goto-char (cdr bounds))))
;; Special cases
! ;; Defuns
! (put 'defun 'beginning-op 'beginning-of-defun)
! (put 'defun 'end-op 'end-of-defun)
! (put 'defun 'forward-op 'end-of-defun)
+ ;; Lines
;; bolp will be false when you click on the last line in the buffer
;; and it has no final newline.
! (put 'line 'beginning-op (lambda ()
! (if (bolp) (forward-line -1)
(beginning-of-line))))
;; Sexps
(defun in-string-p ()
+ "True if point is inside a string."
(let ((orig (point)))
(save-excursion
(beginning-of-defun)
(nth 3 (parse-partial-sexp (point) orig)))))
(defun end-of-sexp ()
+ "Go to the end of the sexp at point."
(let ((char-syntax (char-syntax (char-after (point)))))
(if (or (eq char-syntax ?\))
(and (eq char-syntax ?\") (in-string-p)))
(forward-char 1)
(forward-sexp 1))))
(put 'sexp 'end-op 'end-of-sexp)
(defun beginning-of-sexp ()
+ "Go to the beginning of the sexp at point."
(let ((char-syntax (char-syntax (char-before (point)))))
(if (or (eq char-syntax ?\()
(and (eq char-syntax ?\") (in-string-p)))
(forward-char -1)
(forward-sexp -1))))
(put 'sexp 'beginning-op 'beginning-of-sexp)
;; Lists
(put 'list 'end-op (lambda () (up-list 1)))
(put 'list 'beginning-op 'backward-sexp)
;; Filenames and URLs www.com/foo%32bar
(defvar thing-at-point-file-name-chars "-~/[:alnum:]_.${}#%,:"
"Characters allowable in filenames.")
! (put 'filename 'end-op (lambda ()
! (re-search-forward
! (concat "\\=[" thing-at-point-file-name-chars
"]*")
nil t)))
! (put 'filename 'beginning-op (lambda ()
! (if (re-search-backward
! (concat "[^"
thing-at-point-file-name-chars "]")
nil t)
(forward-char)
(goto-char (point-min)))))
(defvar thing-at-point-url-path-regexp
"[^]\t\n \"'()<>[^`{}]*[^]\t\n \"'()<>[^`{}.,;]+"
! "A regexp probably matching the host and filename or e-mail part of a
URL.")
(defvar thing-at-point-short-url-regexp
(concat "[-A-Za-z0-9.]+" thing-at-point-url-path-regexp)
***************
*** 238,245 ****
"A regular expression matching a URL marked up per RFC1738.
This may contain whitespace (including newlines) .")
- (put 'url 'bounds-of-thing-at-point
'thing-at-point-bounds-of-url-at-point)
(defun thing-at-point-bounds-of-url-at-point ()
(let ((strip (thing-at-point-looking-at
thing-at-point-markedup-url-regexp))) ;; (url "") short
(if (or strip
--- 352,359 ----
"A regular expression matching a URL marked up per RFC1738.
This may contain whitespace (including newlines) .")
(defun thing-at-point-bounds-of-url-at-point ()
+ "Return the bounds of the URL around or before point."
(let ((strip (thing-at-point-looking-at
thing-at-point-markedup-url-regexp))) ;; (url "") short
(if (or strip
***************
*** 254,269 ****
(setq beginning (+ beginning 5))
(setq end (- end 1)))
(cons beginning end)))))
- (put 'url 'thing-at-point 'thing-at-point-url-at-point)
(defun thing-at-point-url-at-point ()
"Return the URL around or before point.
-
Search backwards for the start of a URL ending at or after point. If
no URL found, return nil. The access scheme will be prepended if
absent: \"mailto:\" if the string contains \"@\", \"ftp://\" if it
starts with \"ftp\" and not \"ftp:/\", or \"http://\" by default."
-
(let ((url "") short strip)
(if (or (setq strip (thing-at-point-looking-at
thing-at-point-markedup-url-regexp))
--- 368,381 ----
(setq beginning (+ beginning 5))
(setq end (- end 1)))
(cons beginning end)))))
+ (put 'url 'bounds-of-thing-at-point
'thing-at-point-bounds-of-url-at-point)
(defun thing-at-point-url-at-point ()
"Return the URL around or before point.
Search backwards for the start of a URL ending at or after point. If
no URL found, return nil. The access scheme will be prepended if
absent: \"mailto:\" if the string contains \"@\", \"ftp://\" if it
starts with \"ftp\" and not \"ftp:/\", or \"http://\" by default."
(let ((url "") short strip)
(if (or (setq strip (thing-at-point-looking-at
thing-at-point-markedup-url-regexp))
***************
*** 291,296 ****
--- 403,409 ----
(if (string-equal "" url)
nil
url)))))
+ (put 'url 'thing-at-point 'thing-at-point-url-at-point)
;; The normal thingatpt mechanism doesn't work for complex regexps.
;; This should work for almost any regexp wherever we are in the
***************
*** 326,332 ****
(setq match (point))))
(goto-char match)
(looking-at regexp)))))
-
(put 'url 'end-op
(lambda ()
(let ((bounds (thing-at-point-bounds-of-url-at-point)))
--- 439,444 ----
***************
*** 351,357 ****
;; not sure they're actually needed, and URL seems to skip them too.
;; Note that (end-of-thing 'email) and (beginning-of-thing 'email)
;; work automagically, though.
-
(put 'email 'bounds-of-thing-at-point
(lambda ()
(let ((thing (thing-at-point-looking-at
thing-at-point-email-regexp)))
--- 463,468 ----
***************
*** 359,365 ****
(let ((beginning (match-beginning 0))
(end (match-end 0)))
(cons beginning end))))))
-
(put 'email 'thing-at-point
(lambda ()
(let ((boundary-pair (bounds-of-thing-at-point 'email)))
--- 470,475 ----
***************
*** 368,375 ****
(car boundary-pair) (cdr boundary-pair))))))
;; Whitespace
-
(defun forward-whitespace (arg)
(interactive "p")
(if (natnump arg)
(re-search-forward "[ \t]+\\|\n" nil 'move arg)
--- 478,486 ----
(car boundary-pair) (cdr boundary-pair))))))
;; Whitespace
(defun forward-whitespace (arg)
+ "Move forward over ARG groups of TAB or SPC characters or ARG lines.
+ Move backward if ARG is negative."
(interactive "p")
(if (natnump arg)
(re-search-forward "[ \t]+\\|\n" nil 'move arg)
***************
*** 379,417 ****
(skip-chars-backward " \t")))
(setq arg (1+ arg)))))
! ;; Buffer
!
(put 'buffer 'end-op (lambda () (goto-char (point-max))))
(put 'buffer 'beginning-op (lambda () (goto-char (point-min))))
;; Symbols
-
(defun forward-symbol (arg)
(interactive "p")
(if (natnump arg)
(re-search-forward "\\(\\sw\\|\\s_\\)+" nil 'move arg)
(while (< arg 0)
! (if (re-search-backward "\\(\\sw\\|\\s_\\)+" nil 'move)
(skip-syntax-backward "w_"))
(setq arg (1+ arg)))))
;; Syntax blocks
-
(defun forward-same-syntax (&optional arg)
(interactive "p")
(while (< arg 0)
! (skip-syntax-backward
! (char-to-string (char-syntax (char-after (1- (point))))))
(setq arg (1+ arg)))
(while (> arg 0)
(skip-syntax-forward (char-to-string (char-syntax (char-after
(point)))))
(setq arg (1- arg))))
- ;; Aliases
-
- (defun word-at-point () (thing-at-point 'word))
- (defun sentence-at-point () (thing-at-point 'sentence))
-
(defun read-from-whole-string (str)
"Read a Lisp expression from STR.
Signal an error if the entire string was not used."
--- 490,522 ----
(skip-chars-backward " \t")))
(setq arg (1+ arg)))))
! ;; Buffers
(put 'buffer 'end-op (lambda () (goto-char (point-max))))
(put 'buffer 'beginning-op (lambda () (goto-char (point-min))))
;; Symbols
(defun forward-symbol (arg)
+ "Move forward ARG symbols. Move backward if ARG is negative."
(interactive "p")
(if (natnump arg)
(re-search-forward "\\(\\sw\\|\\s_\\)+" nil 'move arg)
(while (< arg 0)
! (when (re-search-backward "\\(\\sw\\|\\s_\\)+" nil 'move)
(skip-syntax-backward "w_"))
(setq arg (1+ arg)))))
;; Syntax blocks
(defun forward-same-syntax (&optional arg)
+ "Move forward over ARG groups of characters with the same syntax.
+ Move backward if ARG is negative."
(interactive "p")
(while (< arg 0)
! (skip-syntax-backward (char-to-string (char-syntax (char-after (1-
(point))))))
(setq arg (1+ arg)))
(while (> arg 0)
(skip-syntax-forward (char-to-string (char-syntax (char-after
(point)))))
(setq arg (1- arg))))
(defun read-from-whole-string (str)
"Read a Lisp expression from STR.
Signal an error if the entire string was not used."
***************
*** 426,447 ****
(error "Can't read whole string")
(car read-data))))
(defun form-at-point (&optional thing pred)
(let ((sexp (condition-case nil
(read-from-whole-string (thing-at-point (or thing 'sexp)))
(error nil))))
(if (or (not pred) (funcall pred sexp)) sexp)))
;;;###autoload
! (defun sexp-at-point () (form-at-point 'sexp))
;;;###autoload
! (defun symbol-at-point ()
! (let ((thing (thing-at-point 'symbol)))
! (if thing (intern thing))))
;;;###autoload
! (defun number-at-point () (form-at-point 'sexp 'numberp))
;;;###autoload
! (defun list-at-point () (form-at-point 'list 'listp))
;; arch-tag: bb65a163-dae2-4055-aedc-fe11f497f698
;;; thingatpt.el ends here
--- 531,788 ----
(error "Can't read whole string")
(car read-data))))
+
+ ;;; FORMS ----------------------------------------------------------
+
+ ;;;###autoload
+ (defun form-at-point-with-bounds (&optional thing pred)
+ "Return (FORM START . END), START and END the char positions of FORM.
+ FORM is the `form-at-point'. Return nil if no form is found.
+ THING is the kind of form desired (default: `sexp').
+ PRED is a predicate that THING must satisfy to qualify."
+ (let* ((thing+bds (thing-at-point-with-bounds (or thing 'sexp)))
+ (sexp (and thing+bds
+ (condition-case nil
+ (read-from-whole-string (car thing+bds))
+ (error nil))))) ; E.g. tries to read `.'.
+ (and (or sexp (and thing+bds (string= "nil" (car thing+bds)))) ; Could
be `nil'.
+ (or (not pred) (funcall pred sexp))
+ (cons sexp (cdr thing+bds)))))
+
+ ;;;###autoload
+ (defun bounds-of-form-at-point (&optional thing pred)
+ "Return (START . END), with START and END of `form-at-point'.
+ THING is the kind of form desired (default: `sexp').
+ PRED is a predicate that THING must satisfy to qualify."
+ (let ((form+bds (form-at-point-with-bounds thing pred)))
+ (and form+bds (cdr form+bds))))
+
+ ;;;###autoload
(defun form-at-point (&optional thing pred)
+ "Return the form nearest to the cursor, if any, else return nil.
+ The form is a Lisp entity, not necessarily a string.
+ THING is the kind of form desired (default: `sexp').
+ PRED is a predicate that THING must satisfy to qualify."
(let ((sexp (condition-case nil
(read-from-whole-string (thing-at-point (or thing 'sexp)))
(error nil))))
(if (or (not pred) (funcall pred sexp)) sexp)))
;;;###autoload
! (defun form-nearest-point-with-bounds (&optional thing pred)
! "Return (FORM START . END), START and END the char positions of FORM.
! FORM is the `form-nearest-point'.
! Return nil if no such form is found.
! THING is the kind of form desired (default: `sexp').
! PRED is a predicate that THING must satisfy to qualify."
! (thing/form-nearest-point-with-bounds #'form-at-point-with-bounds thing
pred))
!
! ;;;###autoload
! (defun bounds-of-form-nearest-point (&optional thing pred)
! "Return (START . END) with START and END of `form-nearest-point'.
! Return nil if no such form is found.
! THING is the kind of form desired (default: `sexp').
! PRED is a predicate that THING must satisfy to qualify."
! (let ((form+bds (form-nearest-point-with-bounds thing pred)))
! (and form+bds (cdr form+bds))))
!
! ;;;###autoload
! (defun form-nearest-point (&optional thing pred)
! "Return the form nearest to the cursor, if any, else return nil.
! \"Nearest\" to point is determined as for `thing-nearest-point'.
! THING is the kind of form desired (default: `sexp').
! PRED is a predicate that THING must satisfy to qualify."
! (let ((form+bds (form-nearest-point-with-bounds thing pred)))
! (and form+bds (car form+bds))))
!
!
! ;;; SYMBOLS ----------------------------------------------------------
!
! ;;;###autoload
! (defun symbol-at-point-with-bounds (&optional non-nil)
! "Return (SYMBOL START . END) with START and END of SYMBOL.
! Return nil if no such Emacs Lisp symbol is found.
! SYMBOL is the `symbol-at-point' (which see).
! If optional arg NON-NIL is non-nil, then the nearest symbol other
! than `nil' is sought."
! (with-syntax-table emacs-lisp-mode-syntax-table
! (form-at-point-with-bounds
! 'symbol (if non-nil (lambda (sym) (and sym (symbolp sym)))
'symbolp))))
!
! ;;;###autoload
! (defun bounds-of-symbol-at-point (&optional non-nil)
! "Return (START . END) with START and END of `symbol-at-point'.
! If optional arg NON-NIL is non-nil, then the nearest symbol other
! than `nil' is sought."
! (let ((symb+bds (symbol-at-point-with-bounds non-nil)))
! (and symb+bds (cdr symb+bds))))
!
! ;;;###autoload
! (defun symbol-at-point (&optional non-nil)
! "Return the Emacs Lisp symbol under the cursor, or nil if none.
! If optional arg NON-NIL is non-nil, then the nearest symbol other
! than `nil' is sought.
!
! Some related functions:
! `symbol-nearest-point' returns the symbol nearest the cursor, or nil.
! `symbol-name-nearest-point' returns the name of
! `symbol-nearest-point' as a string, or \"\" if none.
! `symbol-name-before-point' returns the string naming the symbol at or
! before the cursor (even if it is on a previous line) or \"\" if none.
! `word-before-point' returns the word (a string) at or before cursor.
! Note that these last three functions return strings, not symbols."
! (with-syntax-table emacs-lisp-mode-syntax-table
! (form-at-point
! 'symbol (if non-nil (lambda (sym) (and sym (symbolp sym)))
'symbolp))))
!
! ;;;###autoload
! (defun symbol-nearest-point-with-bounds (&optional non-nil)
! "Return (SYMBOL START . END) with START and END of SYMBOL.
! SYMBOL is the `symbol-nearest-point' (which see).
! If optional arg NON-NIL is non-nil, then the nearest symbol other
! than `nil' is sought.
! Return nil if no such Emacs Lisp symbol is found."
! (with-syntax-table emacs-lisp-mode-syntax-table
! (form-nearest-point-with-bounds
! 'symbol (if non-nil (lambda (sym) (and sym (symbolp sym)))
'symbolp))))
!
! ;;;###autoload
! (defun bounds-of-symbol-nearest-point (&optional non-nil)
! "Return (START . END) with START and END of `symbol-nearest-point'.
! If optional arg NON-NIL is non-nil, then the nearest symbol other
! than `nil' is sought."
! (let ((symb+bds (symbol-nearest-point-with-bounds non-nil)))
! (and symb+bds (cdr symb+bds))))
!
! ;;;###autoload
! (defun symbol-nearest-point (&optional non-nil)
! "Return the Emacs Lisp symbol nearest the cursor, or nil if none.
! \"Nearest\" to point is determined as for `thing-nearest-point'.
! If optional arg NON-NIL is non-nil, then the nearest symbol other
! than `nil' is sought.
!
! Some related functions:
! `symbol-at-point' returns the symbol under the cursor, or nil if none.
! `symbol-name-nearest-point' returns the name of `symbol-nearest-point'
! as a string, or \"\" if none.
! `symbol-name-before-point' returns the string naming the symbol at or
! before the cursor (even if it is on a previous line) or \"\" if none.
! `word-at-point' returns the word at point, or nil if none.
! `word-nearest-point' returns the word nearest point, or \"\" if none.
! `word-before-point' returns the word at or before the cursor as a
string.
! Note that these last three functions return strings, not symbols."
! (let ((symb+bds (symbol-nearest-point-with-bounds non-nil)))
! (and symb+bds (car symb+bds))))
!
! ;;;###autoload
! (defun non-nil-symbol-nearest-point ()
! "Return the Emacs Lisp symbol other than `nil' nearest the cursor.
! Return nil if none is found.
! \"Nearest\" to point is determined as for `thing-nearest-point'.
!
! Some related functions:
! `symbol-at-point' returns the symbol under the cursor, or nil if none.
! `symbol-name-nearest-point' returns the name of `symbol-nearest-point'
! as a string, or \"\" if none.
! `symbol-name-before-point' returns the string naming the symbol at or
! before the cursor (even if it is on a previous line) or \"\" if none.
! `word-at-point' returns the word at point, or nil if none.
! `word-nearest-point' returns the word nearest point, or \"\" if none.
! `word-before-point' returns the word at or before the cursor as a
string.
! Note that these last three functions return strings, not symbols."
! (let ((symb+bds (symbol-nearest-point-with-bounds t)))
! (and symb+bds (car symb+bds))))
!
!
! ;;; SYMBOL NAMES, WORDS, SENTENCES, SEXPS, NUMBERS, LISTS, etc. ----------
!
! ;;;###autoload
! (defun symbol-name-at-point ()
! "String naming the Emacs Lisp symbol at point, or \"\" if none."
! ;; We do it this way to be able to pick symbol `nil' (name "nil").
! (let ((symb+bds (symbol-at-point-with-bounds)))
! (if symb+bds (symbol-name (car symb+bds)) "")))
!
;;;###autoload
! (defun non-nil-symbol-name-at-point ()
! "String naming the Emacs Lisp symbol nearest point, or \"\" if none.
! Returns the name of the nearest symbol other than `nil'.
! \"Nearest\" to point is determined as for `thing-nearest-point'."
! (let ((symb+bds (symbol-at-point-with-bounds t)))
! (if symb+bds (symbol-name (car symb+bds)) "")))
!
;;;###autoload
! (defun symbol-name-nearest-point ()
! "String naming the Emacs Lisp symbol nearest point, or \"\" if none.
! \"Nearest\" to point is determined as for `thing-nearest-point'."
! ;; We do it this way to be able to pick symbol `nil' (name "nil").
! (let ((symb+bds (symbol-nearest-point-with-bounds)))
! (if symb+bds (symbol-name (car symb+bds)) "")))
!
! ;;;###autoload
! (defun non-nil-symbol-name-nearest-point ()
! "String naming the Emacs Lisp symbol nearest point, or \"\" if none.
! Returns the name of the nearest symbol other than `nil'.
! \"Nearest\" to point is determined as for `thing-nearest-point'."
! (let ((symb+bds (symbol-nearest-point-with-bounds t)))
! (if symb+bds (symbol-name (car symb+bds)) "")))
!
! ;;;###autoload
! (defun word-at-point ()
! "Return the word (a string) nearest to point, if any, else \"\"."
! (thing-at-point 'word))
!
! ;;;###autoload
! (defun word-nearest-point ()
! "Return the word (a string) nearest to point, if any, else \"\".
! \"Nearest\" to point is determined as for `thing-nearest-point'."
! (thing-nearest-point 'word))
!
! ;;;###autoload
! (defun sentence-at-point ()
! "Return the sentence (a string) nearest to point, if any, else \"\"."
! (thing-at-point 'sentence))
!
! ;;;###autoload
! (defun sentence-nearest-point ()
! "Return the sentence (a string) nearest to point, if any, else \"\".
! \"Nearest\" to point is determined as for `thing-nearest-point'."
! (thing-nearest-point 'sentence))
!
! ;;;###autoload
! (defun sexp-at-point ()
! "Return the sexp (a string) nearest to point, if any, else \"\"."
! (form-at-point 'sexp))
!
! ;;;###autoload
! (defun sexp-nearest-point ()
! "Return the sexp (a string) nearest to point, if any, else \"\".
! \"Nearest\" to point is determined as for `thing-nearest-point'."
! (form-nearest-point 'sexp))
!
! ;;;###autoload
! (defun number-at-point ()
! "Return the number at point, if any, else nil."
! (form-at-point 'sexp 'numberp))
!
! ;;;###autoload
! (defun number-nearest-point ()
! "Return the number nearest to point, if any, else nil.
! \"Nearest\" to point is determined as for `thing-nearest-point'."
! (form-nearest-point 'sexp 'numberp))
!
! ;;;###autoload
! (defun list-at-point ()
! "Return the list nearest to point, if any, else nil."
! (form-at-point 'list 'listp))
!
;;;###autoload
! (defun list-nearest-point ()
! "Return the list nearest to point, if any, else nil.
! This does not distinguish between finding no list and finding
! the empty list. \"Nearest\" to point is determined as for
! `thing-nearest-point'."
! (form-nearest-point 'list 'listp))
;; arch-tag: bb65a163-dae2-4055-aedc-fe11f497f698
;;; thingatpt.el ends here