emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Proposed extension of show-paren-mode: Highlight parens when point is i


From: Alan Mackenzie
Subject: Proposed extension of show-paren-mode: Highlight parens when point is in L or R margin.
Date: Sat, 11 Oct 2014 13:43:12 +0000
User-agent: Mutt/1.5.21 (2010-09-15)

Hi, Emacs.

This is an idea which struck me when I was reading CC Mode code.  I find
myself frequently scrolling through it, and frequently wanting to know
where the matching paren for one at beginning of indentation is.  That
involved me typing M-m an awful lot, and I've got tired of doing that.

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.  Then again, why not do the same if point is in a line
comment?

Here is a patch to .../lisp/paren.el which implements this.  To turn on
the new feature, set the new customizable variable
show-paren-when-point-in-margin to t.

Comments on this proposed new feature?




=== modified file 'lisp/paren.el'
*** lisp/paren.el       2014-02-10 01:34:22 +0000
--- lisp/paren.el       2014-10-11 13:34:19 +0000
***************
*** 72,77 ****
--- 72,85 ----
    :group 'paren-showing
    :version "20.3")
  
+ (defcustom show-paren-when-point-in-margin nil
+   "If non-nil, try to show parens when point is in LH or RH margin.
+ LH margin is before the first non-space/tab character on the line.
+ The RH margin is in a comment or whitespace towards 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
***************
*** 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
--- 128,187 ----
  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 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 LH margin.
!      ((and show-paren-when-point-in-margin
!          (< (point) ind-pos))
!       (cond
!        ((eq (syntax-class (syntax-after ind-pos)) 4)
!       (setq dir 1
!             oldpos ind-pos))
!        ((eq (syntax-class (syntax-after ind-pos)) 5)
!       (setq dir -1
!             oldpos (1+ ind-pos)))
!        ((eq (syntax-class (syntax-after (1- eol-pos))) 4)
!       (setq dir 1
!             oldpos (1- eol-pos)))
!        ((eq (syntax-class (syntax-after (1- eol-pos))) 5)
!       (setq dir -1
!             oldpos eol-pos))))
!      ;; Point is in a comment or whitespace to the right of the line.
!      ((and show-paren-when-point-in-margin
!          (>= (point) eol-pos))
!       (cond
!        ((eq (syntax-class (syntax-after (1- eol-pos))) 4)
!       (setq dir 1
!             oldpos (1- eol-pos)))
!        ((eq (syntax-class (syntax-after (1- eol-pos))) 5)
!       (setq dir -1
!             oldpos eol-pos)))))
!     (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.
--- 195,201 ----
            ;; 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
--- 203,209 ----
            ;; 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
--- 261,267 ----
          ;; Otherwise, turn off any such highlighting.
          (if (or (not here-beg)
                  (and (not show-paren-highlight-openparen)
!                    (= here-end (1+ (point)))
                       (integerp there-beg)))
              (delete-overlay show-paren--overlay-1)
            (move-overlay show-paren--overlay-1



-- 
Alan Mackenzie (Nuremberg, Germany).



reply via email to

[Prev in Thread] Current Thread [Next in Thread]