From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Tassilo Horn Newsgroups: gmane.emacs.devel Subject: Re: Show show-paren context in a child frame Date: Sat, 05 Feb 2022 21:06:11 +0100 Message-ID: <874k5d2hwu.fsf@gnu.org> References: <87fsoxlc2p.fsf@gnu.org> <878rup2kg2.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="5261"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: mu4e 1.7.7; emacs 29.0.50 Cc: emacs-devel@gnu.org, Daniel =?utf-8?Q?Mart=C3=ADn?= Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sat Feb 05 21:12:35 2022 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nGRQA-0001Bb-HP for ged-emacs-devel@m.gmane-mx.org; Sat, 05 Feb 2022 21:12:34 +0100 Original-Received: from localhost ([::1]:57940 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nGRQ9-0007tE-6d for ged-emacs-devel@m.gmane-mx.org; Sat, 05 Feb 2022 15:12:33 -0500 Original-Received: from eggs.gnu.org ([209.51.188.92]:42340) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nGROf-0006gV-B0 for emacs-devel@gnu.org; Sat, 05 Feb 2022 15:11:01 -0500 Original-Received: from [2001:470:142:3::e] (port=41374 helo=fencepost.gnu.org) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nGROf-0001d3-12; Sat, 05 Feb 2022 15:11:01 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=MIME-Version:In-reply-to:Date:Subject:From:References: to; bh=No10e+kKaQ4o9eyW6LHXZtkLKHLDhzb9wKIWn/b9Lu8=; b=EtmP6INqKc+rodTBmOi6ul FjWBsPRIpjCf/JN1Z/N/3ekm7RzvoMmGGlGt6SZ4TWII1Z9dRqX7J6kvyZO3Sc/0XC59kGAeooarX sZlNs2HaKyXDXue5UEAtPkSUL+PCOCKmG6iEROmBIQZEpjuiDtExtaoD3Iyqzlae99VkXW1Jrd5a8 fP3elzCQBO2omHdJnre6LEaoxmiQJCXzWbCR7UGKTQBHRDVQaEQXf+eujZnG7CZIbfdGdVYm0uIzm pBBNus20LAponagVTNZBFEa/+bDhZtC6dCXD8wsjKNNMH88qUoUSo90BzVVa/9dvwo1+XLHC4LVsq UKNL72/PoYCw==; Original-Received: from auth1-smtp.messagingengine.com ([66.111.4.227]:47755) by fencepost.gnu.org with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1nGROe-0000ly-R8; Sat, 05 Feb 2022 15:11:00 -0500 Original-Received: from compute2.internal (compute2.nyi.internal [10.202.2.46]) by mailauth.nyi.internal (Postfix) with ESMTP id 2A37927C005A; Sat, 5 Feb 2022 15:11:00 -0500 (EST) Original-Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Sat, 05 Feb 2022 15:11:00 -0500 X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvvddrhedugddufedvucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne hmihhsshhinhhgucfvqfcufhhivghlugculdeftddmnecujfgurhepfhgfhffuffgjkfgg tgesmhdtreertdertdenucfhrhhomhepvfgrshhsihhlohcujfhorhhnuceothhsughhse hgnhhurdhorhhgqeenucggtffrrghtthgvrhhnpedvfeeufeetheehieelhefhtdejfeet vdfhtefhgfetjefgtdduhfeiudfgueeftdenucevlhhushhtvghrufhiiigvpedtnecurf grrhgrmhepmhgrihhlfhhrohhmpehthhhorhhnodhmvghsmhhtphgruhhthhhpvghrshho nhgrlhhithihqdekieejfeekjeekgedqieefhedvleekqdhtshguhheppehgnhhurdhorh hgsehfrghsthhmrghilhdrfhhm X-ME-Proxy: Original-Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat, 5 Feb 2022 15:10:59 -0500 (EST) In-reply-to: <878rup2kg2.fsf@gnu.org> X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:285914 Archived-At: --=-=-= Content-Type: text/plain Tassilo Horn writes: >> mouse-scroll-subr: Wrong type argument: window-live-p, # [30 >> times] >> >> Not sure if it's a bug in the child frame API or in the way you use >> it; I'm not familiar enough with the child frame API. > > Neither am I. I stole most of the child-frame code from vertico Gosh, I've written vertico over and over. Of course, it's *corfu*! But both are very good packages from the same author, so credits to Daniel Mendler. > which adds some more hacks to redirect accidental focus from the child > frame back to the parent. Seems like those are needed. New version attached which should make it impossible to somehow focus the child frame. Bye, Tassilo --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-Allow-showing-show-paren-context-in-child-frame.patch >From 5a5e6b78d0926791f2593c79c3d9c017315b8979 Mon Sep 17 00:00:00 2001 From: Tassilo Horn Date: Sat, 5 Feb 2022 13:22:55 +0100 Subject: [PATCH] Allow showing show-paren context in child frame --- lisp/paren.el | 124 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 117 insertions(+), 7 deletions(-) diff --git a/lisp/paren.el b/lisp/paren.el index 0065bba72e..d0c093a511 100644 --- a/lisp/paren.el +++ b/lisp/paren.el @@ -89,11 +89,19 @@ show-paren-highlight-openparen :type 'boolean) (defcustom show-paren-context-when-offscreen nil - "If non-nil, show context in the echo area when the openparen is offscreen. + "If non-nil, show context around the opening paren if it 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 +context includes the previous nonblank line. + +By default, the context is shown in the echo area. + +If set to the symbol `child-frame', the context is shown in a +child frame at the left top of the window. On non-graphical +frames, show the context in the echo area." + :type '(choice (const :tag "Off" nil) + (const :tag "In echo area" t) + (const :tag "Child frame" child-frame)) :version "29.1") (defvar show-paren--idle-timer nil) @@ -260,6 +268,103 @@ show-paren--default (if (= dir 1) pos (1+ pos)) mismatch))))))) +(defvar show-paren--context-child-frame nil) + +(defun show-paren--context-child-frame-redirect-focus () + "Redirect focus from child frame." + (redirect-frame-focus + show-paren--context-child-frame + (frame-parent corfu--frame))) + +(defun show-paren--context-child-frame-buffer (text) + (with-current-buffer + (get-buffer-create " *show-paren context*") + ;; Redirect focus to parent. + (add-hook 'pre-command-hook + #'show-paren--delete-context-child-frame + nil t) + ;; Use an empty keymap. + (use-local-map (make-keymap)) + (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))) + +(defvar show-paren--context-child-frame-parameters + `((visibility . nil) + (width . 0) (height . 0) + (min-width . t) (min-height . t) + (no-accept-focus . t) + (no-focus-on-map . 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))) + +(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--show-context-in-child-frame (text) + "Show TEXT in a child-frame at the top-left of the current window." + (let ((minibuffer (minibuffer-window (window-frame))) + (buffer (show-paren--context-child-frame-buffer text)) + (x (window-pixel-left)) + (y (window-pixel-top)) + (window-min-height 1) + (window-min-width 1) + after-make-frame-functions) + (show-paren--delete-context-child-frame) + (setq show-paren--context-child-frame + (make-frame + `((parent-frame . ,(window-frame)) + (minibuffer . ,minibuffer) + ,@show-paren--context-child-frame-parameters))) + (let ((win (frame-root-window show-paren--context-child-frame))) + (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-function () "Highlight the parentheses until the next input arrives." (let ((data (and show-paren-mode (funcall show-paren-data-function)))) @@ -299,8 +404,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 +420,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 +435,12 @@ 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 --=-=-=--