[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Proposed extension of show-paren-mode: Highlight parens when point i
From: |
Alan Mackenzie |
Subject: |
Re: Proposed extension of show-paren-mode: Highlight parens when point is in L or R margin. |
Date: |
Sun, 12 Oct 2014 10:04:16 +0000 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
Hi, Stefan.
On Sun, Oct 12, 2014 at 12:12:12AM -0400, Stefan Monnier wrote:
> > So: If point is in the LH margin of the code, highlight the first paren
> > on the line and its match, or failing that, the last paren on the line
> > with its match.
> Related ideas:
> - show matching paren when point is right after the open paren or right
> before the close paren. (see
>
> http://stackoverflow.com/questions/25648067/emacs-matching-parenthesis-when-cursor-is-on-closing-parenthesis
> for a 5-liner which does that).
> - show matching paren, when there's only whitespace between point and
> the open/close paren.
Maybe for later!
> This second idea is a superset of the one you suggest. I personally
> don't use show-paren-mode because I find it distracting, so maybe
> a superset would be too distracting.
> > Then again, why not do the same if point is in a line comment?
> Sorry, I don't know what "in a line comment" means.
In a comment which extends to EOL, e.g. "//..." in C++, or ";..." in
Lisp.
> As for your patch, I'd rather see the new code moved to a new function.
Done.
> See more detailed comments below.
> > + (defcustom show-paren-when-point-in-margin nil
> Please don't call it "margin".
OK. It's now called "periphery".
[ .... ]
> It's not at all clear to me why there has to be so many different cases
> (IOW we'd need a comment that explains why we need such complexity).
I've condensed these cases into a new function (see amended patch below).
[ .... ]
> This is a code duplication. Please move it to a separate helper function.
No it's not. It appears just once, after my patch is applied.
Here's the amended version, incorporating suggestions from you, Eli, and
David.
=== modified file 'lisp/paren.el'
*** lisp/paren.el 2014-02-10 01:34:22 +0000
--- lisp/paren.el 2014-10-12 09:46:33 +0000
***************
*** 72,77 ****
--- 72,85 ----
:group 'paren-showing
:version "20.3")
+ (defcustom show-paren-when-point-in-periphery nil
+ "If non-nil, show parens when point is in the line's periphery.
+ The periphery is either the whitespace at the beginning of a
+ line, or a comment \(or whitespace) at the end of a line."
+ :type 'boolean
+ :group 'paren-showing
+ :version "25.1")
+
(define-obsolete-face-alias 'show-paren-match-face 'show-paren-match "22.1")
(define-obsolete-face-alias 'show-paren-mismatch-face
***************
*** 112,117 ****
--- 120,138 ----
(delete-overlay show-paren--overlay)
(delete-overlay show-paren--overlay-1)))
+ (defun show-paren--categorize-paren (pos)
+ "Determine whether the character after POS has paren syntax,
+ and if so, return a cons (DIR . OUTSIDE). For an open paren, DIR
+ is 1 and OUTSIDE is the position before the paren. For a close
+ paren, DIR is -1 and OUTSIDE is the position after the paren. If
+ the character isn't a paren, return nil."
+ (cond
+ ((eq (syntax-class (syntax-after pos)) 4)
+ (cons 1 pos))
+ ((eq (syntax-class (syntax-after pos)) 5)
+ (cons -1 (1+ pos)))
+ (t nil)))
+
(defvar show-paren-data-function #'show-paren--default
"Function to find the opener/closer at point and its match.
The function is called with no argument and should return either nil
***************
*** 120,141 ****
Where HERE-BEG..HERE-END is expected to be around point.")
(defun show-paren--default ()
! (let* ((oldpos (point))
! (dir (cond ((eq (syntax-class (syntax-after (1- (point)))) 5) -1)
! ((eq (syntax-class (syntax-after (point))) 4) 1)))
! (unescaped
! (when dir
! ;; Verify an even number of quoting characters precede the paren.
! ;; Follow the same logic as in `blink-matching-open'.
! (= (if (= dir -1) 1 0)
! (logand 1 (- (point)
! (save-excursion
! (if (= dir -1) (forward-char -1))
! (skip-syntax-backward "/\\")
! (point)))))))
! (here-beg (if (eq dir 1) (point) (1- (point))))
! (here-end (if (eq dir 1) (1+ (point)) (point)))
! pos mismatch)
;;
;; Find the other end of the sexp.
(when unescaped
--- 141,190 ----
Where HERE-BEG..HERE-END is expected to be around point.")
(defun show-paren--default ()
! (let* ((ind-pos (save-excursion (back-to-indentation) (point)))
! (bol-pos (save-excursion (beginning-of-line) (point)))
! (eol-pos (save-excursion (end-of-line)
! (let ((s (syntax-ppss)))
! (if (nth 4 s)
! (goto-char (max (nth 8 s)
! (point-min))))
! (skip-chars-backward " \t"))
! (point)))
! (oldpos (point))
! dir paren-details unescaped pos mismatch here-beg here-end)
! (cond
! ;; Point is at a paren.
! ((eq (syntax-class (syntax-after (1- (point)))) 5)
! (setq dir -1))
! ((eq (syntax-class (syntax-after (point))) 4)
! (setq dir 1))
! ;; Point is in the WS before the code.
! ((and show-paren-when-point-in-periphery
! (< (point) ind-pos))
! (setq paren-details
! (or (show-paren--categorize-paren ind-pos)
! (show-paren--categorize-paren (1- eol-pos)))))
! ;; Point is in a comment or whitespace after the code.
! ((and show-paren-when-point-in-periphery
! (>= (point) eol-pos))
! (setq paren-details
! (or (show-paren--categorize-paren (1- eol-pos))
! (show-paren--categorize-paren ind-pos)))))
! (when paren-details
! (setq dir (car paren-details)
! oldpos (cdr paren-details)))
!
! (when dir
! (setq unescaped
! (= (if (= dir -1) 1 0)
! (logand 1 (- oldpos
! (save-excursion
! (goto-char oldpos)
! (if (= dir -1) (backward-char))
! (skip-syntax-backward "/\\")
! (point)))))))
! (setq here-beg (if (eq dir 1) oldpos (1- oldpos))
! here-end (if (eq dir 1) (1+ oldpos) oldpos))
;;
;; Find the other end of the sexp.
(when unescaped
***************
*** 149,155 ****
;; Scan across one sexp within that range.
;; Errors or nil mean there is a mismatch.
(condition-case ()
! (setq pos (scan-sexps (point) dir))
(error (setq pos t mismatch t)))
;; Move back the other way and verify we get back to the
;; starting point. If not, these two parens don't really match.
--- 198,204 ----
;; Scan across one sexp within that range.
;; Errors or nil mean there is a mismatch.
(condition-case ()
! (setq pos (scan-sexps oldpos dir))
(error (setq pos t mismatch t)))
;; Move back the other way and verify we get back to the
;; starting point. If not, these two parens don't really match.
***************
*** 157,163 ****
;; or one is inside a comment.
(when (integerp pos)
(unless (condition-case ()
! (eq (point) (scan-sexps pos (- dir)))
(error nil))
(setq pos nil)))
;; If found a "matching" paren, see if it is the right
--- 206,212 ----
;; or one is inside a comment.
(when (integerp pos)
(unless (condition-case ()
! (eq oldpos (scan-sexps pos (- dir)))
(error nil))
(setq pos nil)))
;; If found a "matching" paren, see if it is the right
***************
*** 215,221 ****
;; Otherwise, turn off any such highlighting.
(if (or (not here-beg)
(and (not show-paren-highlight-openparen)
! (> here-end (point))
(integerp there-beg)))
(delete-overlay show-paren--overlay-1)
(move-overlay show-paren--overlay-1
--- 264,270 ----
;; Otherwise, turn off any such highlighting.
(if (or (not here-beg)
(and (not show-paren-highlight-openparen)
! (= here-beg (point))
(integerp there-beg)))
(delete-overlay show-paren--overlay-1)
(move-overlay show-paren--overlay-1
> Stefan
--
Alan Mackenzie (Nuremberg, Germany).
Re: Proposed extension of show-paren-mode: Highlight parens when point is in L or R margin., Stefan Monnier, 2014/10/12
- Re: Proposed extension of show-paren-mode: Highlight parens when point is in L or R margin.,
Alan Mackenzie <=
- Re: Proposed extension of show-paren-mode: Highlight parens when point is in L or R margin., Stefan Monnier, 2014/10/14
- Re: Proposed extension of show-paren-mode: Highlight parens when point is in L or R margin., John Yates, 2014/10/14
- Re: Proposed extension of show-paren-mode: Highlight parens when point is in L or R margin., Alan Mackenzie, 2014/10/15
- Re: Proposed extension of show-paren-mode: Highlight parens when point is in L or R margin., Andy Moreton, 2014/10/15
- Re: Proposed extension of show-paren-mode: Highlight parens when point is in L or R margin., Stefan Monnier, 2014/10/15
- Re: Proposed extension of show-paren-mode: Highlight parens when point is in L or R margin., Alan Mackenzie, 2014/10/16
- Re: Proposed extension of show-paren-mode: Highlight parens when point is in L or R margin., Stefan Monnier, 2014/10/16
- Re: Proposed extension of show-paren-mode: Highlight parens when point is in L or R margin., Alan Mackenzie, 2014/10/16
- Re: Proposed extension of show-paren-mode: Highlight parens when point is in L or R margin., Stefan Monnier, 2014/10/16
- Re: Proposed extension of show-paren-mode: Highlight parens when point is in L or R margin., Alan Mackenzie, 2014/10/16