4

Problem

I have show-paren-mode enabled, but the highlighting behavior unintuitive. In particular, the matching parentheses are only highlighted in two situations as shown below (the second of which is unintuitive):

  1. Cursor on the opening parenthesis (which is expected behavior):

    ( some characters here ) some more characters here
    ^
    cursor must be at the caret for highlighting to show
    
  2. Cursor on the character after the closing parenthesis (which is unintuitive):

    ( some characters here ) some more characters here
                            ^
                            cursor must be at the caret for highlighting to show
    

Question

Is there a way for the matching parentheses to be highlighted when the cursor is on the closing parenthesis?

Like this:

( some characters here ) some more characters here
                       ^
yongjieyongjie
  • 286
  • 1
  • 5
  • 2
    This does not answer your question, but the cursor is never actually "on" any character. It is before or after a character. A block cursor that is just before a character can look like it is on the character, but it's not. (So the behavior you want is for the highlighting to occur when the cursor is before the closing paren, not after it.) – Drew Aug 05 '19 at 02:39
  • @Drew, thanks for the clarification! I shall do more Googling with this newly acquired information – yongjieyongjie Aug 05 '19 at 04:52
  • @Drew If that level of abstraction is left, how can we say: "cursor is at position x" - isn't cursor than before or after x? – Andreas Röhler Aug 05 '19 at 07:13
  • 1
    @AndreasRöhler I assume that `x` is a number in your phrase "cursor is at position x". The cursor represents point and point represents positions between characters. That makes the difference between `(buffer-size)` and `(point-max)`. The first point position is that one before the first character the last one is that one behind the last character. So `(point-max)` is `(1+ (buffer-size))`. If you set `cursor-type` to `bar`. That actually represents the cursor position better than `box`or `hollow`. Position actually means kind of "Insertion Position". – Tobias Aug 05 '19 at 13:11
  • What @Tobias said. – Drew Aug 05 '19 at 15:21
  • 2
    You can partially achieve that effect when you set `show-paren-when-point-inside-paren` to t. Let `|` be the cursor. In `(|ignore)` highlight `()` of `ignore`. In `(ignore|)` highlight `()` of `ignore`. In `(progn (ignore)|)` highlight `()` of `ignore`. In `(progn (ignore))|` highlight `()` of `progn`. – Tobias Aug 06 '19 at 14:26
  • 1
    This is not an answer but maybe you are interested in another solution as well. I like to combine `show-paren-mode` with `highlight-parentheses-mode` and only highlight one level of surrounding parens using `(setq hl-paren-colors '("steel blue"))`, this way you always get the surrounding parens highlighted (which includes the situation where the point is right before the closing paren as in you example), too. – clemera Aug 07 '19 at 06:53

3 Answers3

2

The following mutilating shortening of show-paren--locate-near-paren does what you want.

Copy these lines into your init file and restart Emacs.

(defun show-paren--locate-near-paren-ad ()
  "Locate an unescaped paren \"near\" point to show.
If one is found, return the cons (DIR . OUTSIDE), where DIR is 1
for an open paren, -1 for a close paren, and OUTSIDE is the buffer
position of the outside of the paren.  Otherwise return nil."
  (let* ((before (show-paren--categorize-paren (point))))
    (when (or
       (eq (car before) 1)
       (eq (car before) -1))
      before)))

(advice-add 'show-paren--locate-near-paren :override #'show-paren--locate-near-paren-ad)
Tobias
  • 32,569
  • 1
  • 34
  • 75
0

The following advice does what you want. When the block cursor is "on" the opening parenthesis, the closing parenthesis is highlighted. When the block cursor is "on" the closing parenthesis, the opening parenthesis is highlighted.

(advice-add show-paren-data-function
            :around
            (lambda (orig-fun)
              (cond ((looking-at "\\s(")
                     (funcall orig-fun))
                    ((looking-at "\\s)")
                     (save-excursion (forward-char 1) (funcall orig-fun))))))

The first cond clause handles an opening delimiter character (e.g. when the cursor is "on" an opening parenthesis). Since the default Emacs behavior already does what you want, we do not need to change the behavior, so we just reuse the original function.

The second cond clause handles a closing delimiter character (e.g. when the cursor is "on" a closing parenthesis). The default Emacs behavior is not doing what you want. To solve the problem, we "trick" the original function into believing that the cursor is right after the closing parenthesis whenever the cursor is "on" the closing parenthesis.

Otherwise, we return nil.


You may also want to consider this variant:

(advice-add show-paren-data-function
            :around
            (lambda (orig-fun)
              (cond ((looking-at "\\s)")
                     (save-excursion (forward-char 1) (funcall orig-fun)))
                    (t (funcall orig-fun)))))

When the block cursor is "on" a closing parenthesis, it will highlight the opening parenthesis. When the block cursor is not "on" a closing parenthesis, but the previous character is a closing parenthesis, it will highlight the opening parenthesis.

I have tried these code snippets in GNU Emacs 26.3.

Flux
  • 583
  • 2
  • 16
0

I believe setting show-paren-when-point-inside-paren to t does what you want.

From the docs:

Documentation:
If non-nil, show parens when point is just inside one.
This will only be done when point isn’t also just outside a paren.

Can be set with:

(setq show-paren-when-point-inside-paren t)
kfoley
  • 529
  • 4
  • 13
  • No, this does not do what the OP wants. Suppose we have these parentheses: `((...))`. When the block cursor is "on" the outer closing parenthesis, the inner pair of parentheses is highlighted. This is not what the OP wants. The OP wants to highlight the outer pair of parentheses when the block cursor is on the outer closing parenthesis. – Flux Feb 19 '21 at 00:42