]> git.eshelyaron.com Git - emacs.git/commitdiff
New option show-paren-context-when-offscreen
authorDaniel Martín <mardani29@yahoo.es>
Sat, 16 Oct 2021 18:24:19 +0000 (20:24 +0200)
committerLars Ingebrigtsen <larsi@gnus.org>
Mon, 18 Oct 2021 07:26:44 +0000 (09:26 +0200)
* lisp/simple.el (blink-paren-open-paren-line-string): Extract
functionality that shows the open paren line in the echo area into its
own function, to reuse it from paren.el.
(blink-matching-open): Use blink-paren-open-paren-line-string.
* lisp/paren.el (show-paren-context-when-offscreen): New option
show-paren-context-when-offscreen.
(show-paren-function): Implement it using
blink-paren-open-paren-line-string.
* lisp/emacs-lisp/eldoc.el (eldoc-display-message-no-interference-p):
Make sure the feature works well with eldoc.
* test/lisp/paren-tests.el (paren-tests-open-paren-line): Test
blink-paren-open-paren-line-string.
* doc/emacs/programs.texi (Matching): Update the documentation.
* etc/NEWS: And announce the new feature.

doc/emacs/programs.texi
etc/NEWS
lisp/emacs-lisp/eldoc.el
lisp/paren.el
lisp/simple.el
test/lisp/paren-tests.el

index 51a48df2e270425f5707929620238f67286d4bbc..0056906e1f715e57a44cae5fe4be65e9645a0b21 100644 (file)
@@ -868,6 +868,15 @@ highlighting also when point is in whitespace at the beginning of a
 line and there is a paren at the first or last non-whitespace position
 on the line, or when point is at the end of a line and there is a
 paren at the last non-whitespace position on the line.
+
+@item
+@vindex show-paren-context-when-offscreen
+@code{show-paren-context-when-offscreen}, when non-@code{nil}, shows
+some context in the echo area when point is in a closing delimiter and
+the opening delimiter is offscreen.  The context is usually the line
+that contains the opening delimiter, except if the opening delimiter
+is on its own line, in which case the context includes the previous
+nonblank line.
 @end itemize
 
 @cindex Electric Pair mode
index d6188919155fb69963779e79f0c988bf4fd05a8b..f4b462516faf491e18c5d503d50bf787b22e0304 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -86,6 +86,14 @@ effectively dragged.
 Customize this option to limit the amount of entries in the menu
 "Edit->Paste from Kill Menu".  The default is 60.
 
+** show-paren-mode
+
++++
+*** New user option 'show-paren-context-when-offscreen'.
+When non-nil, if the point is in a closing delimiter and the opening
+delimiter is offscreen, shows some context around the opening
+delimiter in the echo area.
+
 \f
 * Changes in Specialized Modes and Packages in Emacs 29.1
 
index a1c3c3268f2c4547f49dd5539beaf8d39f82864f..b30d3fc30f45c9a0c0db7e2e5ac650eb9d0f19c2 100644 (file)
@@ -380,7 +380,14 @@ Also store it in `eldoc-last-message' and return that value."
 ;; it undesirable to print eldoc messages right this instant.
 (defun eldoc-display-message-no-interference-p ()
   "Return nil if displaying a message would cause interference."
-  (not (or executing-kbd-macro (bound-and-true-p edebug-active))))
+  (not (or executing-kbd-macro
+           (bound-and-true-p edebug-active)
+           ;; The following configuration shows "Matches..." in the
+           ;; echo area when point is after a closing bracket, which
+           ;; conflicts with eldoc.
+           (and show-paren-context-when-offscreen
+                (not (pos-visible-in-window-p
+                      (overlay-end show-paren--overlay)))))))
 
 \f
 (defvar eldoc-documentation-functions nil
index ce6aa9ae13bef471a8f9c669f9eca375ed1d715b..7e7cf6c262a80c699b7cfe7ad83a1004ac457cc6 100644 (file)
@@ -88,6 +88,14 @@ is not highlighted, the cursor being regarded as adequate to mark
 its position."
   :type 'boolean)
 
+(defcustom show-paren-context-when-offscreen nil
+  "If non-nil, show context in the echo area when the openparen is offscreen.
+The context is usually the line that contains the openparen,
+except if the openparen is on its own line, in which case the
+context includes the previous nonblank line."
+  :type 'boolean
+  :version "29.1")
+
 (defvar show-paren--idle-timer nil)
 (defvar show-paren--overlay
   (let ((ol (make-overlay (point) (point) nil t))) (delete-overlay ol) ol)
@@ -312,6 +320,19 @@ It is the default value of `show-paren-data-function'."
                             (current-buffer))
             (move-overlay show-paren--overlay
                           there-beg there-end (current-buffer)))
+          ;; If `show-paren-open-line-when-offscreen' is t and point
+          ;; is at a close paren, show the line that contains the
+          ;; openparen in the echo area.
+          (let ((openparen (min here-beg there-beg)))
+            (if (and show-paren-context-when-offscreen
+                     (< there-beg here-beg)
+                     (not (pos-visible-in-window-p openparen)))
+                (let ((open-paren-line-string
+                       (blink-paren-open-paren-line-string openparen))
+                      (message-log-max nil))
+                  (minibuffer-message
+                   "Matches %s"
+                   (substring-no-properties open-paren-line-string)))))
           ;; Always set the overlay face, since it varies.
           (overlay-put show-paren--overlay 'priority show-paren-priority)
           (overlay-put show-paren--overlay 'face face))))))
index c7bb928cd733bcbbb0a16d971d6d5f0ca255d930..4f711d60ea2104bc0d2887551701561b5503c270 100644 (file)
@@ -8577,40 +8577,43 @@ The function should return non-nil if the two tokens do not match.")
                                    (current-buffer))
                      (sit-for blink-matching-delay))
                  (delete-overlay blink-matching--overlay)))))
-       (t
-        (let ((open-paren-line-string
-               (save-excursion
-                 (goto-char blinkpos)
-                 ;; Show what precedes the open in its line, if anything.
-                 (cond
-                  ((save-excursion (skip-chars-backward " \t") (not (bolp)))
-                   (buffer-substring (line-beginning-position)
-                                     (1+ blinkpos)))
-                  ;; Show what follows the open in its line, if anything.
-                  ((save-excursion
-                     (forward-char 1)
-                     (skip-chars-forward " \t")
-                     (not (eolp)))
-                   (buffer-substring blinkpos
-                                     (line-end-position)))
-                  ;; Otherwise show the previous nonblank line,
-                  ;; if there is one.
-                  ((save-excursion (skip-chars-backward "\n \t") (not (bobp)))
-                   (concat
-                    (buffer-substring (progn
-                                        (skip-chars-backward "\n \t")
-                                        (line-beginning-position))
-                                      (progn (end-of-line)
-                                             (skip-chars-backward " \t")
-                                             (point)))
-                    ;; Replace the newline and other whitespace with `...'.
-                    "..."
-                    (buffer-substring blinkpos (1+ blinkpos))))
-                  ;; There is nothing to show except the char itself.
-                  (t (buffer-substring blinkpos (1+ blinkpos)))))))
-          (minibuffer-message
-           "Matches %s"
-           (substring-no-properties open-paren-line-string))))))))
+       ((not show-paren-context-when-offscreen)
+        (minibuffer-message
+         "Matches %s"
+         (substring-no-properties
+          (blink-paren-open-paren-line-string blinkpos))))))))
+
+(defun blink-paren-open-paren-line-string (pos)
+  "Return the line string that contains the openparen at POS."
+  (save-excursion
+    (goto-char pos)
+    ;; Show what precedes the open in its line, if anything.
+    (cond
+     ((save-excursion (skip-chars-backward " \t") (not (bolp)))
+      (buffer-substring (line-beginning-position)
+                        (1+ pos)))
+     ;; Show what follows the open in its line, if anything.
+     ((save-excursion
+        (forward-char 1)
+        (skip-chars-forward " \t")
+        (not (eolp)))
+      (buffer-substring pos
+                        (line-end-position)))
+     ;; Otherwise show the previous nonblank line,
+     ;; if there is one.
+     ((save-excursion (skip-chars-backward "\n \t") (not (bobp)))
+      (concat
+       (buffer-substring (progn
+                           (skip-chars-backward "\n \t")
+                           (line-beginning-position))
+                         (progn (end-of-line)
+                                (skip-chars-backward " \t")
+                                (point)))
+       ;; Replace the newline and other whitespace with `...'.
+       "..."
+       (buffer-substring pos (1+ pos))))
+     ;; There is nothing to show except the char itself.
+     (t (buffer-substring pos (1+ pos))))))
 
 (defvar blink-paren-function 'blink-matching-open
   "Function called, if non-nil, whenever a close parenthesis is inserted.
index c4bec5d86de9fad65191545c1ee49c079493cccc..11249ee9bc17f862710d5489d9cd32e1ba711d6c 100644 (file)
                          (- (point-max) 1) (point-max)
                          nil)))))
 
+(ert-deftest paren-tests-open-paren-line ()
+  (cl-flet ((open-paren-line ()
+                             (let* ((data (show-paren--default))
+                                    (here-beg (nth 0 data))
+                                    (there-beg (nth 2 data)))
+                               (blink-paren-open-paren-line-string
+                                (min here-beg there-beg)))))
+    ;; Lisp-like
+    (with-temp-buffer
+      (insert "(defun foo ()
+                  (dummy))")
+      (goto-char (point-max))
+      (should (string= "(defun foo ()" (open-paren-line))))
+
+    ;; C-like
+    (with-temp-buffer
+      (insert "int foo() {
+                 int blah;
+             }")
+      (goto-char (point-max))
+      (should (string= "int foo() {" (open-paren-line))))
+
+    ;; C-like with hanging {
+    (with-temp-buffer
+      (insert "int foo()
+               {
+                 int blah;
+               }")
+      (goto-char (point-max))
+      (should (string= "int foo()...{" (open-paren-line))))))
+
 (provide 'paren-tests)
 ;;; paren-tests.el ends here