emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 9f505c4: New option show-paren-context-when-offscreen


From: Lars Ingebrigtsen
Subject: master 9f505c4: New option show-paren-context-when-offscreen
Date: Mon, 18 Oct 2021 03:28:29 -0400 (EDT)

branch: master
commit 9f505c476eb1a8e85ba26964abf218cab7db0e57
Author: Daniel Martín <mardani29@yahoo.es>
Commit: Lars Ingebrigtsen <larsi@gnus.org>

    New option show-paren-context-when-offscreen
    
    * 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  |  9 ++++++
 etc/NEWS                 |  8 ++++++
 lisp/emacs-lisp/eldoc.el |  9 +++++-
 lisp/paren.el            | 21 ++++++++++++++
 lisp/simple.el           | 71 +++++++++++++++++++++++++-----------------------
 test/lisp/paren-tests.el | 31 +++++++++++++++++++++
 6 files changed, 114 insertions(+), 35 deletions(-)

diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi
index 51a48df..0056906 100644
--- a/doc/emacs/programs.texi
+++ b/doc/emacs/programs.texi
@@ -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
diff --git a/etc/NEWS b/etc/NEWS
index d618891..f4b4625 100644
--- 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.
+
 
 * Changes in Specialized Modes and Packages in Emacs 29.1
 
diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el
index a1c3c32..b30d3fc 100644
--- a/lisp/emacs-lisp/eldoc.el
+++ b/lisp/emacs-lisp/eldoc.el
@@ -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)))))))
 
 
 (defvar eldoc-documentation-functions nil
diff --git a/lisp/paren.el b/lisp/paren.el
index ce6aa9a..7e7cf6c 100644
--- a/lisp/paren.el
+++ b/lisp/paren.el
@@ -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))))))
diff --git a/lisp/simple.el b/lisp/simple.el
index c7bb928..4f711d6 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -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.
diff --git a/test/lisp/paren-tests.el b/test/lisp/paren-tests.el
index c4bec5d..11249ee 100644
--- a/test/lisp/paren-tests.el
+++ b/test/lisp/paren-tests.el
@@ -117,5 +117,36 @@
                          (- (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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]