From 2abf143f8185fced544c4f8d144ea710142d7a59 Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Fri, 24 Sep 2021 09:29:52 +0300 Subject: [PATCH] New thing-at-point target 'string' used in context-menu-region * lisp/mouse.el (context-menu-region): Use separate "List" and "String". * lisp/thingatpt.el (string): New target 'string'. (thing-at-point-bounds-of-string-at-point): New function. (thing-at-point-bounds-of-list-at-point): Revert previous commit by removing optional args 'escape-strings' and 'no-syntax-crossing'. (list-or-string): Remove recently added target 'list-or-string'. (thing-at-point-bounds-of-list-or-string-at-point): Remove function. https://lists.gnu.org/archive/html/emacs-devel/2021-09/msg01737.html --- etc/NEWS | 7 ++----- lisp/mouse.el | 17 +++++++++++------ lisp/thingatpt.el | 39 +++++++++++++++++++++++++-------------- 3 files changed, 38 insertions(+), 25 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index b0e2d2c060e..02cbaa51ed3 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2593,11 +2593,8 @@ This new command (bound to 'C-c C-l') regenerates the current hunk. This is like 'filename', but is a full path, and is nil if the file doesn't exist. -*** New 'thing-at-point' target: 'list-or-string'. -This is like 'list, but if point is inside a string that's enclosed in -the list, it returns the enclosed string and not the enclosing list. - -This is like 'list', but also prefers to find of any enclosing string. +*** New 'thing-at-point' target: 'string'. +If point is inside a string, it returns the enclosed string. +++ *** New variable 'thing-at-point-provider-alist'. diff --git a/lisp/mouse.el b/lisp/mouse.el index 8ad3f7664a2..9f1417f420d 100644 --- a/lisp/mouse.el +++ b/lisp/mouse.el @@ -482,12 +482,17 @@ Some context functions add menu items below the separator." `(menu-item "Defun" ,(lambda (e) (interactive "e") (mark-thing-at-mouse e 'defun)) :help "Mark the defun at click for a subsequent cut/copy")) - (define-key-after submenu [mark-list-or-string] - `(menu-item ,(if (nth 8 (save-excursion - (syntax-ppss (posn-point (event-end click))))) - "String" "List") - ,(lambda (e) (interactive "e") (mark-thing-at-mouse e 'list-or-string)) - :help "Mark list or string at click for a subsequent cut/copy")) + (define-key-after submenu [mark-list] + `(menu-item "List" + ,(lambda (e) (interactive "e") (mark-thing-at-mouse e 'list)) + :help "Mark the list at click for a subsequent cut/copy")) + (when (let ((pos (posn-point (event-end click)))) + (or (eq (char-syntax (char-after pos)) ?\") + (nth 3 (save-excursion (syntax-ppss pos))))) + (define-key-after submenu [mark-string] + `(menu-item "String" + ,(lambda (e) (interactive "e") (mark-thing-at-mouse e 'string)) + :help "Mark the string at click for a subsequent cut/copy"))) (define-key-after submenu [mark-line] `(menu-item "Line" ,(lambda (e) (interactive "e") (mark-thing-at-mouse e 'line)) diff --git a/lisp/thingatpt.el b/lisp/thingatpt.el index efe33982c3c..32e66184d70 100644 --- a/lisp/thingatpt.el +++ b/lisp/thingatpt.el @@ -231,7 +231,27 @@ The bounds of THING are determined by `bounds-of-thing-at-point'." (put 'line 'beginning-op (lambda () (if (bolp) (forward-line -1) (beginning-of-line)))) -;; Sexps +;; Strings + +(put 'string 'bounds-of-thing-at-point 'thing-at-point-bounds-of-string-at-point) + +(defun thing-at-point-bounds-of-string-at-point () + "Return the bounds of the string at point. +Prefer the enclosing string with fallback on sexp at point. +\[Internal function used by `bounds-of-thing-at-point'.]" + (save-excursion + (let ((ppss (syntax-ppss))) + (if (nth 3 ppss) + ;; Inside the string + (ignore-errors + (goto-char (nth 8 ppss)) + (cons (point) (progn (forward-sexp) (point)))) + ;; At the beginning of the string + (if (eq (char-syntax (char-after)) ?\") + (let ((bound (bounds-of-thing-at-point 'sexp))) + (and bound + (<= (car bound) (point)) (< (point) (cdr bound)) + bound))))))) (defun in-string-p () "Return non-nil if point is in a string." @@ -241,6 +261,8 @@ The bounds of THING are determined by `bounds-of-thing-at-point'." (beginning-of-defun) (nth 3 (parse-partial-sexp (point) orig))))) +;; Sexps + (defun thing-at-point--end-of-sexp () "Move point to the end of the current sexp." (let ((char-syntax (syntax-after (point)))) @@ -284,29 +306,18 @@ The bounds of THING are determined by `bounds-of-thing-at-point'." (put 'list 'bounds-of-thing-at-point 'thing-at-point-bounds-of-list-at-point) -(defun thing-at-point-bounds-of-list-at-point (&optional escape-strings no-syntax-crossing) +(defun thing-at-point-bounds-of-list-at-point () "Return the bounds of the list at point. Prefer the enclosing list with fallback on sexp at point. \[Internal function used by `bounds-of-thing-at-point'.]" (save-excursion - (if (ignore-errors (up-list -1 escape-strings no-syntax-crossing)) + (if (ignore-errors (up-list -1)) (ignore-errors (cons (point) (progn (forward-sexp) (point)))) (let ((bound (bounds-of-thing-at-point 'sexp))) (and bound (<= (car bound) (point)) (< (point) (cdr bound)) bound))))) -(put 'list-or-string 'bounds-of-thing-at-point - 'thing-at-point-bounds-of-list-or-string-at-point) - -(defun thing-at-point-bounds-of-list-or-string-at-point () - "Return the bounds of the list or string at point. -Like `thing-at-point-bounds-of-list-at-point', but if -point is inside a string that's enclosed in the list, this -function will return the enclosed string and not the -enclosing list." - (thing-at-point-bounds-of-list-at-point t t)) - ;; Defuns (put 'defun 'beginning-op 'beginning-of-defun) -- 2.39.2