From: Alan Mackenzie <acm@muc.de>
To: emacs-devel@gnu.org
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 [thread overview]
Message-ID: <20141011134312.GA4148@acm.acm> (raw)
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).
next reply other threads:[~2014-10-11 13:43 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-10-11 13:43 Alan Mackenzie [this message]
2014-10-11 14:21 ` Proposed extension of show-paren-mode: Highlight parens when point is in L or R margin 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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20141011134312.GA4148@acm.acm \
--to=acm@muc.de \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).