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
                       ^
7
  • 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
    Commented Aug 5, 2019 at 2:39
  • @Drew, thanks for the clarification! I shall do more Googling with this newly acquired information 💪 Commented Aug 5, 2019 at 4:52
  • 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 boxor hollow. Position actually means kind of "Insertion Position".
    – Tobias
    Commented Aug 5, 2019 at 13:11
  • 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
    Commented Aug 6, 2019 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
    Commented Aug 7, 2019 at 6:53

3 Answers 3

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)
1
  • thanks for the code and for pointing to the source! I'll study them and try the code out. Commented Aug 7, 2019 at 10:12
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.

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)
1
  • 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
    Commented Feb 19, 2021 at 0:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.