unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Proposed extension of show-paren-mode:  Highlight parens when point is in L or R margin.
@ 2014-10-11 13:43 Alan Mackenzie
  2014-10-11 14:21 ` Eli Zaretskii
                   ` (2 more replies)
  0 siblings, 3 replies; 23+ messages in thread
From: Alan Mackenzie @ 2014-10-11 13:43 UTC (permalink / raw)
  To: emacs-devel

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).



^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2014-10-17  0:14 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-10-11 13:43 Proposed extension of show-paren-mode: Highlight parens when point is in L or R margin Alan Mackenzie
2014-10-11 14:21 ` Eli Zaretskii
2014-10-12  8:39   ` Alan Mackenzie
2014-10-12  8:55     ` David Kastrup
2014-10-12  9:25       ` Alan Mackenzie
2014-10-12  9:01     ` Eli Zaretskii
2014-10-12 10:18       ` Alan Mackenzie
2014-10-12  4:12 ` Stefan Monnier
2014-10-12 10:04   ` Alan Mackenzie
2014-10-14 17:49     ` Stefan Monnier
2014-10-14 18:32       ` John Yates
2014-10-15  9:12       ` Alan Mackenzie
2014-10-15 22:38         ` Andy Moreton
2014-10-16  2:43         ` Stefan Monnier
2014-10-16  9:53           ` Alan Mackenzie
2014-10-16 12:59             ` Stefan Monnier
2014-10-16 13:31               ` Alan Mackenzie
2014-10-16 14:37                 ` Stefan Monnier
2014-10-16 15:46                   ` Alan Mackenzie
2014-10-16 17:40                     ` Stefan Monnier
2014-10-16 21:26                       ` Alan Mackenzie
2014-10-17  0:14                         ` Stefan Monnier
2014-10-14 21:50 ` João Távora

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).