aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSpencer Baugh2025-08-28 14:13:24 -0400
committerStefan Monnier2025-09-09 18:02:24 -0400
commit0e9cee2bf5d97a23c47d99ffc47396dcd3bd50ee (patch)
tree66d451585272981ff2383580e4e5fbbf9dcf760a
parent82f6c1651435aac656de7116511bf290bb0ef3e4 (diff)
downloademacs-0e9cee2bf5d97a23c47d99ffc47396dcd3bd50ee.tar.gz
emacs-0e9cee2bf5d97a23c47d99ffc47396dcd3bd50ee.zip
Ignore keymaps at point for positions outside the buffer
Correct a few edge cases where we used the keymaps at point when looking up keymaps for an event position which is outside the current buffer. Namely: - Clicking on a part of the mode line which is after the end of mode-line-format produces an event with non-nil posn-area but nil posn-string. - Even if posn-string doesn't have a local keymap, we should still ignore the keymaps at point if posn-string is non-nil. * src/keymap.c (Fcurrent_active_maps): Ignore keymaps at point for more positions outside the buffer. (bug#76620)
-rw-r--r--src/keymap.c38
-rw-r--r--test/src/keymap-tests.el27
2 files changed, 43 insertions, 22 deletions
diff --git a/src/keymap.c b/src/keymap.c
index 2c250578b00..295b209f06b 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -1735,11 +1735,20 @@ means to return the active maps for that window's buffer. */)
1735 } 1735 }
1736 } 1736 }
1737 1737
1738 /* If on a mode line string with a local keymap, 1738 Lisp_Object pos_area = POSN_POSN (position);
1739 or for a click on a string, i.e. overlay string or a 1739 if (EQ (pos_area, Qmode_line) || EQ (pos_area, Qheader_line))
1740 string displayed via the `display' property, 1740 {
1741 consider `local-map' and `keymap' properties of 1741 /* For clicks on mode line or header line, ignore the maps
1742 that string. */ 1742 we found at POSITION, because properties at point are
1743 not relevant in that case. */
1744 local_map = Qnil;
1745 keymap = Qnil;
1746 }
1747
1748 /* If on a mode line string with a local keymap, or for a
1749 click on a string, i.e. overlay string or a string
1750 displayed via the `display' property, consider only the
1751 `local-map' and `keymap' properties of that string. */
1743 1752
1744 if (CONSP (string) && STRINGP (XCAR (string))) 1753 if (CONSP (string) && STRINGP (XCAR (string)))
1745 { 1754 {
@@ -1749,23 +1758,8 @@ means to return the active maps for that window's buffer. */)
1749 && XFIXNUM (pos) >= 0 1758 && XFIXNUM (pos) >= 0
1750 && XFIXNUM (pos) < SCHARS (string)) 1759 && XFIXNUM (pos) < SCHARS (string))
1751 { 1760 {
1752 Lisp_Object map = Fget_text_property (pos, Qlocal_map, 1761 local_map = Fget_text_property (pos, Qlocal_map, string);
1753 string); 1762 keymap = Fget_text_property (pos, Qkeymap, string);
1754 Lisp_Object pos_area = POSN_POSN (position);
1755 /* For clicks on mode line or header line, override
1756 the maps we found at POSITION unconditionally, even
1757 if the corresponding properties of the mode- or
1758 header-line string are nil, because propertries at
1759 point are not relevant in that case. */
1760 if (!NILP (map)
1761 || EQ (pos_area, Qmode_line)
1762 || EQ (pos_area, Qheader_line))
1763 local_map = map;
1764 map = Fget_text_property (pos, Qkeymap, string);
1765 if (!NILP (map)
1766 || EQ (pos_area, Qmode_line)
1767 || EQ (pos_area, Qheader_line))
1768 keymap = map;
1769 } 1763 }
1770 } 1764 }
1771 1765
diff --git a/test/src/keymap-tests.el b/test/src/keymap-tests.el
index c605c3eb09d..950c741a6dd 100644
--- a/test/src/keymap-tests.el
+++ b/test/src/keymap-tests.el
@@ -509,6 +509,33 @@ g .. h foo
509 ;; From the parent this time/ 509 ;; From the parent this time/
510 (should (equal (keymap-lookup map "u") #'undo)))) 510 (should (equal (keymap-lookup map "u") #'undo))))
511 511
512(defun keymap-test--maps-for-posn (area string)
513 (current-active-maps
514 nil
515 ;; FIXME: This test would be better if this was a real position
516 ;; created by a real click.
517 `(,(selected-window) ,area (1 . 1) 0 (,string . 0) nil (1 . 1) nil (1 . 1) (1 . 1))))
518
519(ert-deftest keymap-test-keymaps-for-non-buffer-positions ()
520 "`current-active-maps' with non-buffer positions. (bug#76620)"
521 (with-temp-buffer
522 (pop-to-buffer (current-buffer))
523 (let ((keymap (make-sparse-keymap "keymap-at-point")))
524 (insert (propertize "string" 'keymap keymap))
525 (goto-char (point-min))
526 (should (memq keymap (current-active-maps)))
527 (should-not (memq keymap (keymap-test--maps-for-posn 'mode-line nil)))
528 (should-not (memq keymap (keymap-test--maps-for-posn 'mode-line "s")))
529 (should-not (memq keymap (keymap-test--maps-for-posn nil "s")))
530 (should (memq keymap (keymap-test--maps-for-posn nil nil)))
531 (let* ((mode-line-keymap (make-sparse-keymap "keymap-in-mode-line"))
532 (s (propertize "string" 'keymap mode-line-keymap)))
533 ;; Respect `keymap' in the string clicked on.
534 (should-not (memq keymap (keymap-test--maps-for-posn nil s)))
535 (should-not (memq keymap (keymap-test--maps-for-posn 'mode-line s)))
536 (should (memq mode-line-keymap (keymap-test--maps-for-posn nil s)))
537 (should (memq mode-line-keymap (keymap-test--maps-for-posn 'mode-line s)))))))
538
512(provide 'keymap-tests) 539(provide 'keymap-tests)
513 540
514;;; keymap-tests.el ends here 541;;; keymap-tests.el ends here