This posts will describe how I display lines matching off-screen parentheses at the top of the window:
blink-matching-paren can be used to configure the display of
matching parentheses. If you look at the source, you will see that
blink-paren-post-self-insert-function is added to
do the job.
There are two things I would like to change about the way it works:
When the matching paren goes off-screen, I usually look at the top of the window. Thus, this is the place where I would like to display the match information.
The matching information should be displayed after movement commands as well.
First let’s take care of
;; we will call `blink-matching-open` ourselves... (remove-hook 'post-self-insert-hook #'blink-paren-post-self-insert-function) ;; this still needs to be set for `blink-matching-open` to work (setq blink-matching-paren 'show)
As I already use
show-paren-mode to visualize matching parentheses it makes
sense to look for a way to hook into it. Because of that I decided to advice
(let ((ov nil)) ; keep track of the overlay (advice-add #'show-paren-function :after (defun show-paren--off-screen+ (&rest _args) "Display matching line for off-screen paren." (when (overlayp ov) (delete-overlay ov)) ;; check if it's appropriate to show match info, ;; see `blink-paren-post-self-insert-function' (when (and (overlay-buffer show-paren--overlay) (not (or cursor-in-echo-area executing-kbd-macro noninteractive (minibufferp) this-command)) (and (not (bobp)) (memq (char-syntax (char-before)) '(?\) ?\$))) (= 1 (logand 1 (- (point) (save-excursion (forward-char -1) (skip-syntax-backward "/\\") (point)))))) ;; rebind `minibuffer-message' called by ;; `blink-matching-open' to handle the overlay display (cl-letf (((symbol-function #'minibuffer-message) (lambda (msg &rest args) (let ((msg (apply #'format-message msg args))) (setq ov (display-line-overlay+ (window-start) msg )))))) (blink-matching-open))))))
To create the overlay I have written the following helper function:
(defun display-line-overlay+ (pos str &optional face) "Display line at POS as STR with FACE. FACE defaults to inheriting from default and highlight." (let ((ol (save-excursion (goto-char pos) (make-overlay (line-beginning-position) (line-end-position))))) (overlay-put ol 'display str) (overlay-put ol 'face (or face '(:inherit default :inherit highlight))) ol))
All that is left is to activate
show-paren-mode with the settings you like:
(setq show-paren-style 'paren show-paren-delay 0.03 show-paren-highlight-openparen t show-paren-when-point-inside-paren nil show-paren-when-point-in-periphery t) (show-paren-mode 1)
To use the code of this post make sure to evaluate the code with lexical-scope.