From 5d96fad27863497a427c80550070e435a4c9e0d9 Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Thu, 23 Sep 2021 19:32:36 +0300 Subject: [PATCH] New thing-at-point target 'list-or-string' used in context-menu-region * lisp/mouse.el (context-menu-region): Rearrange the order to All>Defun>List>Line>Symbol. Show title either "List" or "String" depending on syntax-ppss, then use thing 'list-or-string' (bug#9054). * lisp/thingatpt.el (thing-at-point-bounds-of-list-at-point): Add optional args 'escape-strings' and 'no-syntax-crossing' like in 'up-list'. (list-or-string): New target 'list-or-string'. (thing-at-point-bounds-of-list-or-string-at-point): New function. --- etc/NEWS | 3 +++ lisp/mouse.el | 24 +++++++++++++----------- lisp/thingatpt.el | 13 +++++++++++-- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 175bae09e8e..e9b60e95945 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2586,6 +2586,9 @@ 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 also prefers to find of any enclosing string. + +++ *** New variable 'thing-at-point-provider-alist'. This allows mode-specific alterations to how 'thing-at-point' works. diff --git a/lisp/mouse.el b/lisp/mouse.el index 41333eb7f71..382c101159b 100644 --- a/lisp/mouse.el +++ b/lisp/mouse.el @@ -455,10 +455,11 @@ Some context functions add menu items below the separator." `(menu-item "Paste" mouse-yank-at-click :help "Paste (yank) text most recently cut/copied"))) (when (and (cdr yank-menu) (not buffer-read-only)) - (let ((submenu (make-sparse-keymap (propertize "Paste from Kill Menu")))) - (dolist (item yank-menu) + (let ((submenu (make-sparse-keymap (propertize "Paste from Kill Menu"))) + (i 0)) + (dolist (item (reverse yank-menu)) (when (consp item) - (define-key-after submenu (vector (car item)) + (define-key submenu (vector (setq i (1+ i))) `(menu-item ,(cadr item) ,(lambda () (interactive) (mouse-yank-from-menu click (car item))))))) @@ -477,18 +478,19 @@ Some context functions add menu items below the separator." `(menu-item "All" ,(lambda (e) (interactive "e") (mark-thing-at-mouse e 'buffer)) :help "Mark the whole buffer for a subsequent cut/copy")) - (define-key-after submenu [mark-line] - `(menu-item "Line" - ,(lambda (e) (interactive "e") (mark-thing-at-mouse e 'line)) - :help "Mark the line at click for a subsequent cut/copy")) (define-key-after submenu [mark-defun] `(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] - `(menu-item "List" - ,(lambda (e) (interactive "e") (mark-thing-at-mouse e 'list)) - :help "Mark the list at click for a subsequent cut/copy")) + (define-key-after submenu [mark-list-or-string] + `(menu-item ,(if (nth 8 (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-line] + `(menu-item "Line" + ,(lambda (e) (interactive "e") (mark-thing-at-mouse e 'line)) + :help "Mark the line at click for a subsequent cut/copy")) (define-key-after submenu [mark-symbol] `(menu-item "Symbol" ,(lambda (e) (interactive "e") (mark-thing-at-mouse e 'symbol)) diff --git a/lisp/thingatpt.el b/lisp/thingatpt.el index 58ef2cfd917..09a86d22438 100644 --- a/lisp/thingatpt.el +++ b/lisp/thingatpt.el @@ -284,18 +284,27 @@ 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 () +(defun thing-at-point-bounds-of-list-at-point (&optional escape-strings no-syntax-crossing) "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)) + (if (ignore-errors (up-list -1 escape-strings no-syntax-crossing)) (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 also +prefer to find of any enclosing string." + (thing-at-point-bounds-of-list-at-point t t)) + ;; Defuns (put 'defun 'beginning-op 'beginning-of-defun) -- 2.39.2