From: Tassilo Horn <tsdh@gnu.org>
To: emacs-devel@gnu.org
Subject: Show show-paren context in a child frame
Date: Sat, 05 Feb 2022 13:33:22 +0100 [thread overview]
Message-ID: <87fsoxlc2p.fsf@gnu.org> (raw)
[-- Attachment #1: Type: text/plain, Size: 782 bytes --]
Hi all,
today I've discovered `show-paren-context-when-offscreen' which displays
the context around the opening paren in the echo area. That's a very
nice feature, however it competes with eldoc, i.e., it'll show the
context in the echo area and a fraction of a second later, that's
repressed by eldoc's text (or the other way round depending on the
delays one uses).
Therefore, I've experimented with adding a special `child-frame' value
for `show-paren-context-when-offscreen' which displays the context in a
child frame. This works pretty well although setting up a child frame
with corresponding buffer for a kind of tooltip pane requires quite some
gymnastics in frame parameters and buffer-local variables which I've
copied from vertico. Comments welcome!
Bye,
Tassilo
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Allow-showing-show-paren-context-in-child-frame.patch --]
[-- Type: text/x-patch, Size: 5723 bytes --]
From f3300f0cffd5344c013e3be0690f2ff1b50a1703 Mon Sep 17 00:00:00 2001
From: Tassilo Horn <tsdh@gnu.org>
Date: Sat, 5 Feb 2022 13:22:55 +0100
Subject: [PATCH] Allow showing show-paren context in child frame
---
lisp/paren.el | 91 ++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 87 insertions(+), 4 deletions(-)
diff --git a/lisp/paren.el b/lisp/paren.el
index 0065bba72e..f8a56ddf24 100644
--- a/lisp/paren.el
+++ b/lisp/paren.el
@@ -260,6 +260,86 @@ show-paren--default
(if (= dir 1) pos (1+ pos))
mismatch)))))))
+(defvar show-paren--context-child-frame nil)
+
+(defun show-paren--context-child-frame-buffer (text)
+ (with-current-buffer
+ (get-buffer-create " *show-paren context*")
+ (dolist (var '((mode-line-format . nil)
+ (header-line-format . nil)
+ (tab-line-format . nil)
+ (tab-bar-format . nil) ;; Emacs 28 tab-bar-format
+ (frame-title-format . "")
+ (truncate-lines . t)
+ (cursor-in-non-selected-windows . nil)
+ (cursor-type . nil)
+ (show-trailing-whitespace . nil)
+ (display-line-numbers . nil)
+ (left-fringe-width . nil)
+ (right-fringe-width . nil)
+ (left-margin-width . 0)
+ (right-margin-width . 0)
+ (fringes-outside-margins . 0)
+ (buffer-read-only . t)))
+ (set (make-local-variable (car var)) (cdr var)))
+ (let ((inhibit-modification-hooks t)
+ (inhibit-read-only t))
+ (erase-buffer)
+ (insert text)
+ (goto-char (point-min)))
+ (current-buffer)))
+
+(defun show-paren--show-context-in-child-frame (text)
+ (let ((minibuffer (minibuffer-window (window-frame)))
+ (buffer (show-paren--context-child-frame-buffer text))
+ (x (window-pixel-left))
+ (y (window-pixel-top)))
+ (show-paren--delete-context-child-frame)
+ (setq show-paren--context-child-frame
+ (make-frame
+ `((parent-frame . ,(window-frame))
+ (minibuffer . ,minibuffer)
+ (visibility . nil)
+ (width . 0)
+ (height . 0)
+ (no-accept-focus . t)
+ (no-focus-on-map . t)
+ (min-width . t)
+ (min-height . t)
+ (border-width . 0)
+ (child-frame-border-width . 1)
+ (left-fringe . 0)
+ (right-fringe . 0)
+ (vertical-scroll-bars . nil)
+ (horizontal-scroll-bars . nil)
+ (menu-bar-lines . 0)
+ (tool-bar-lines . 0)
+ (tab-bar-lines . 0)
+ (no-other-frame . t)
+ (no-other-window . t)
+ (no-delete-other-windows . t)
+ (unsplittable . t)
+ (undecorated . t)
+ (cursor-type . nil)
+ (no-special-glyphs . t)
+ (desktop-dont-save . t))))
+ (let ((win (frame-root-window show-paren--context-child-frame))
+ (window-min-height 0)
+ (window-min-width 0))
+ (set-window-buffer win buffer)
+ (set-window-dedicated-p win t)
+ (set-frame-size show-paren--context-child-frame
+ (string-width text)
+ (length (string-lines text)))
+ (set-frame-position show-paren--context-child-frame x y)
+ (make-frame-visible show-paren--context-child-frame)
+ (add-hook 'post-command-hook #'show-paren--delete-context-child-frame))))
+
+(defun show-paren--delete-context-child-frame ()
+ (when show-paren--context-child-frame
+ (delete-frame show-paren--context-child-frame))
+ (remove-hook 'post-command-hook #'show-paren--delete-context-child-frame))
+
(defun show-paren-function ()
"Highlight the parentheses until the next input arrives."
(let ((data (and show-paren-mode (funcall show-paren-data-function))))
@@ -299,8 +379,8 @@ show-paren-function
;; Otherwise, turn off any such highlighting.
(if (or (not here-beg)
(and (not show-paren-highlight-openparen)
- (> here-end (point))
- (<= here-beg (point))
+ (> here-end (point))
+ (<= here-beg (point))
(integerp there-beg)))
(delete-overlay show-paren--overlay-1)
(move-overlay show-paren--overlay-1
@@ -315,7 +395,7 @@ show-paren-function
(delete-overlay show-paren--overlay)
(if highlight-expression
(move-overlay show-paren--overlay
- (if (< there-beg here-beg) here-end here-beg)
+ (if (< there-beg here-beg) here-end here-beg)
(if (< there-beg here-beg) there-beg there-end)
(current-buffer))
(move-overlay show-paren--overlay
@@ -330,7 +410,10 @@ show-paren-function
(let ((open-paren-line-string
(blink-paren-open-paren-line-string openparen))
(message-log-max nil))
- (minibuffer-message "Matches %s" open-paren-line-string))))
+ (if (and (eq show-paren-context-when-offscreen 'child-frame)
+ (display-graphic-p))
+ (show-paren--show-context-in-child-frame open-paren-line-string)
+ (minibuffer-message "Matches %s" 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))))))
--
2.35.1
next reply other threads:[~2022-02-05 12:33 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-05 12:33 Tassilo Horn [this message]
2022-02-05 18:00 ` Show show-paren context in a child frame Daniel Martín
2022-02-05 19:03 ` Tassilo Horn
2022-02-05 20:06 ` Tassilo Horn
2022-02-06 10:18 ` Tassilo Horn
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87fsoxlc2p.fsf@gnu.org \
--to=tsdh@gnu.org \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).