From 2755e6bba0f9dbb4030f51ea3bc258ee23bb41c5 Mon Sep 17 00:00:00 2001 From: Tassilo Horn Date: Tue, 8 Feb 2022 21:54:56 +0100 Subject: [PATCH] Allow showing show-paren context in an overlay * lisp/paren.el (show-paren-context-when-offscreen): Add new possibility `overlay'. (show-paren--context-overlay): New defvar. (show-paren--delete-context-overlay): New function. (show-paren--show-context-in-overlay): New function. (show-paren-function): Handle the new `overlay' case. * lisp/emacs-lisp/eldoc.el (eldoc-display-message-no-interference-p): There's no interference if `show-paren-context-when-offscreen' is overlay or child-frame. --- lisp/emacs-lisp/eldoc.el | 4 +++ lisp/paren.el | 53 ++++++++++++++++++++++++++++++++-------- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el index 74a20b8a8b7..73713a3dec9 100644 --- a/lisp/emacs-lisp/eldoc.el +++ b/lisp/emacs-lisp/eldoc.el @@ -387,6 +387,10 @@ Also store it in `eldoc-last-message' and return that value." ;; conflicts with eldoc. (and (boundp 'show-paren-context-when-offscreen) show-paren-context-when-offscreen + ;; There's no conflict with the child-frame and + ;; overlay versions. + (not (memq show-paren-context-when-offscreen + '(child-frame overlay))) (not (pos-visible-in-window-p (overlay-end show-paren--overlay))))))) diff --git a/lisp/paren.el b/lisp/paren.el index 221cad3f05a..8d45987e90c 100644 --- a/lisp/paren.el +++ b/lisp/paren.el @@ -96,14 +96,18 @@ context includes the previous nonblank line. By default, the context is shown in the echo area. +If set to the symbol `overlay', the context is shown in an +overlay at the top-left of the window. + If set to the symbol `child-frame', the context is shown in a -child frame at the top left of the window. You might want to +child frame at the top-left of the window. You might want to customize the `child-frame-border' face (especially the background color) to give the child frame a distinguished border. On non-graphical frames, the context is shown in the echo area." :type '(choice (const :tag "Off" nil) (const :tag "In echo area" t) - (const :tag "Child frame" child-frame)) + (const :tag "In overlay" overlay) + (const :tag "In child-frame" child-frame)) :version "29.1") (defvar show-paren--idle-timer nil) @@ -368,6 +372,32 @@ It is the default value of `show-paren-data-function'." (add-hook 'post-command-hook #'show-paren--delete-context-child-frame)))) +(defvar-local show-paren--context-overlay nil) + +(defun show-paren--delete-context-overlay () + (when show-paren--context-overlay + (delete-overlay show-paren--context-overlay) + (setq show-paren--context-overlay nil)) + (remove-hook 'post-command-hook #'show-paren--delete-overlays + 'local)) + +(defun show-paren--show-context-in-overlay (text) + "Show TEXT in an overlay at the top-left of the current window." + (setq text (replace-regexp-in-string "\n" " " text)) + (show-paren--delete-context-overlay) + (let* ((beg (window-start)) + (end (save-excursion + (goto-char beg) + (line-end-position)))) + (setq show-paren--context-overlay (make-overlay beg end))) + (overlay-put show-paren--context-overlay 'display text) + (overlay-put show-paren--context-overlay + 'face `(:box + ( :line-width (1 . -1) + :color ,(face-attribute 'shadow :foreground)))) + (add-hook 'post-command-hook #'show-paren--delete-context-overlay + nil 'local)) + (defun show-paren-function () "Highlight the parentheses until the next input arrives." (let ((data (and show-paren-mode (funcall show-paren-data-function)))) @@ -435,15 +465,18 @@ It is the default value of `show-paren-data-function'." (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)) + (let ((context (blink-paren-open-paren-line-string + openparen)) (message-log-max nil)) - (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))))) + (cond + ((and + (eq show-paren-context-when-offscreen 'child-frame) + (display-graphic-p)) + (show-paren--show-context-in-child-frame context)) + ((eq show-paren-context-when-offscreen 'overlay) + (show-paren--show-context-in-overlay context)) + (show-paren-context-when-offscreen + (minibuffer-message "Matches %s" context)))))) ;; 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.39.5