From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Alan Mackenzie Newsgroups: gmane.emacs.devel 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 Message-ID: <20141011134312.GA4148@acm.acm> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1413035362 22405 80.91.229.3 (11 Oct 2014 13:49:22 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 11 Oct 2014 13:49:22 +0000 (UTC) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sat Oct 11 15:49:15 2014 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Xcx2n-0008PS-6p for ged-emacs-devel@m.gmane.org; Sat, 11 Oct 2014 15:49:13 +0200 Original-Received: from localhost ([::1]:54219 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Xcx2m-0007W4-Tm for ged-emacs-devel@m.gmane.org; Sat, 11 Oct 2014 09:49:12 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:57805) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Xcx2d-0007Vt-5W for emacs-devel@gnu.org; Sat, 11 Oct 2014 09:49:10 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Xcx2V-0007uz-L4 for emacs-devel@gnu.org; Sat, 11 Oct 2014 09:49:03 -0400 Original-Received: from colin.muc.de ([193.149.48.1]:49275 helo=mail.muc.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Xcx2V-0007uv-6N for emacs-devel@gnu.org; Sat, 11 Oct 2014 09:48:55 -0400 Original-Received: (qmail 99134 invoked by uid 3782); 11 Oct 2014 13:48:52 -0000 Original-Received: from acm.muc.de (pD951B461.dip0.t-ipconnect.de [217.81.180.97]) by colin.muc.de (tmda-ofmipd) with ESMTP; Sat, 11 Oct 2014 15:48:52 +0200 Original-Received: (qmail 4244 invoked by uid 1000); 11 Oct 2014 13:43:13 -0000 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-Delivery-Agent: TMDA/1.1.12 (Macallan) X-Primary-Address: acm@muc.de X-detected-operating-system: by eggs.gnu.org: FreeBSD 8.x X-Received-From: 193.149.48.1 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:175260 Archived-At: 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).