all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Show Paren mode: New prelude style
@ 2016-10-27 12:27 Alain Schneble
  2016-10-27 12:51 ` Alain Schneble
  2016-10-27 15:26 ` Eli Zaretskii
  0 siblings, 2 replies; 7+ messages in thread
From: Alain Schneble @ 2016-10-27 12:27 UTC (permalink / raw)
  To: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1150 bytes --]

Below you will find a patch to extend show-paren-mode with a new
`prelude' style.  It's an extension of `parenthesis' style.  If the
matching opening paren is not visible, it will show the line of text
containing it as an overlay on the window's start line.  I think it's
pretty useful, as it helps in keeping context when working e.g. in
defuns with many lines of code -- all without having to scroll up and
down.

If this extension sounds useful to be included for some of you as well,
I would be very happy to get some feedback.  There for sure are things
to improve.  (It actually works quite well with the use cases I tried.)

To try it out:

- emacs -Q
- In scratch buffer, enter some long lisp expressions that overlap the
  window.
- (setq show-paren-style 'prelude)
- (show-paren-mode)

Note 1: There may already be such functionality available that I'm not
aware of.  Please let me know if that is the case.

Note 2: When the fade-in line contains multiple opening parens, the
matching one is highlighted.

Note 3: I'm not too sure about the colors to choose for the new
`show-paren-prelude' face.

Any feedback is welcome.

Thanks,
Alain


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: New prelude style for Show Paren mode --]
[-- Type: text/x-patch, Size: 8217 bytes --]

From 5e5164ab6de8167004bf3ecac5937106984d64f9 Mon Sep 17 00:00:00 2001
From: Alain Schneble <a.s@realize.ch>
Date: Thu, 27 Oct 2016 13:47:18 +0200
Subject: [PATCH] New `prelude' style for show-paren-mode

* lisp/paren.el (show-paren-style): Add new prelude style to the list of
admissible styles.
* lisp/paren.el (show-paren--overlay-prelude): New overlay object.
* lisp/paren.el (show-paren-function): Implement new prelude style logic
to show line of text containing the matching opening paren on the
window's starting line, if it is not already visible.
* lisp/faces.el (show-paren-prelude): New defface to decorate new
show-paren--overlay-prelude overlay line.
* etc/NEWS (Show Paren mode): Add news entry for Show Paren mode, to
describe new style.
* doc/emacs/programs.texi (Matching): Update manual to include
description of new style.
---
 doc/emacs/programs.texi |  5 +++-
 etc/NEWS                |  8 +++++++
 lisp/faces.el           | 10 ++++++++
 lisp/paren.el           | 61 ++++++++++++++++++++++++++++++++++++++++++-------
 4 files changed, 75 insertions(+), 9 deletions(-)

diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi
index 0c79d9c..20f9e97 100644
--- a/doc/emacs/programs.texi
+++ b/doc/emacs/programs.texi
@@ -851,7 +851,10 @@ Matching
 @code{parenthesis} (show the matching paren), @code{expression}
 (highlight the entire expression enclosed by the parens), and
 @code{mixed} (highlight the matching paren if it is visible, the
-expression otherwise).
+expression otherwise).  Furthermore, there is @code{prelude}, an
+extension of @code{parenthesis}, that shows the line of text
+containing the matching opening paren as an overlay on the window's
+start line, if it is not already visible.
 
 @item
 @code{show-paren-when-point-inside-paren}, when non-@code{nil}, causes
diff --git a/etc/NEWS b/etc/NEWS
index d9973c0..e78fce7 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -479,6 +479,14 @@ contents of the buffer to determine whether it's a C or C++ source
 file.
 
 \f
+** Show Paren mode
+
+*** New style 'prelude' to fade-in invisible lines of text.
+If point is at a closing paren and the matching opening paren is not
+visible, show line of text containing the opening paren as an overlay
+on the window's start line.
+
+\f
 * New Modes and Packages in Emacs 26.1
 
 ** New Elisp data-structure library 'radix-tree'.
diff --git a/lisp/faces.el b/lisp/faces.el
index d6ec98b..20f1b02 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -2807,6 +2807,16 @@ show-paren-mismatch
   "Face used for a mismatching paren."
   :group 'paren-showing-faces)
 
+(defface show-paren-prelude
+  '((((class color) (background light))
+     :background "lightblue")
+    (((class color) (background dark))
+     :background "darkblue")
+    (t
+     :inherit underline))
+  "Face used to fade-in invisible lines of text."
+  :group 'paren-showing-faces)
+
 \f
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Manipulating font names.
diff --git a/lisp/paren.el b/lisp/paren.el
index e37cace..af5908c 100644
--- a/lisp/paren.el
+++ b/lisp/paren.el
@@ -40,10 +40,12 @@ paren-showing
 (defcustom show-paren-style 'parenthesis
   "Style used when showing a matching paren.
 Valid styles are `parenthesis' (meaning show the matching paren),
-`expression' (meaning show the entire expression enclosed by the paren) and
+`expression' (meaning show the entire expression enclosed by the paren),
 `mixed' (meaning show the matching paren if it is visible, and the expression
-otherwise)."
-  :type '(choice (const parenthesis) (const expression) (const mixed)))
+otherwise) and `prelude' (meaning show the matching paren if it is
+visible, or the line of text containing the matching opening paren
+as an overlay in the window's start line)."
+  :type '(choice (const parenthesis) (const expression) (const mixed) (const prelude)))
 
 (defcustom show-paren-delay 0.125
   "Time in seconds to delay before showing a matching paren.
@@ -95,6 +97,9 @@ show-paren--overlay
 (defvar show-paren--overlay-1
   (let ((ol (make-overlay (point) (point) nil t))) (delete-overlay ol) ol)
   "Overlay used to highlight the paren at point.")
+(defvar show-paren--overlay-prelude
+  (let ((ol (make-overlay (point) (point) nil t))) (delete-overlay ol) ol)
+  "Overlay used to show the line of text containing the opening paren.")
 
 
 ;;;###autoload
@@ -118,7 +123,8 @@ show-paren-mode
                                 #'show-paren-function))
   (unless show-paren-mode
     (delete-overlay show-paren--overlay)
-    (delete-overlay show-paren--overlay-1)))
+    (delete-overlay show-paren--overlay-1)
+    (delete-overlay show-paren--overlay-prelude)))
 
 (defun show-paren--unescaped-p (pos)
   "Determine whether the paren after POS is unescaped."
@@ -234,10 +240,12 @@ show-paren-function
   (let ((data (and show-paren-mode (funcall show-paren-data-function))))
     (if (not data)
         (progn
-          ;; If show-paren-mode is nil in this buffer or if not at a paren that
-          ;; has a match, turn off any previous paren highlighting.
+          ;; If show-paren-mode is nil in this buffer or if not at a
+          ;; paren that has a match, turn off any previous paren
+          ;; highlighting and/or prelude overlay.
           (delete-overlay show-paren--overlay)
-          (delete-overlay show-paren--overlay-1))
+          (delete-overlay show-paren--overlay-1)
+          (delete-overlay show-paren--overlay-prelude))
 
       ;; Found something to highlight.
       (let* ((here-beg (nth 0 data))
@@ -287,7 +295,44 @@ show-paren-function
                           there-beg there-end (current-buffer)))
           ;; Always set the overlay face, since it varies.
           (overlay-put show-paren--overlay 'priority show-paren-priority)
-          (overlay-put show-paren--overlay 'face face))))))
+          (overlay-put show-paren--overlay 'face face))
+        ;;
+        ;; If point is at a closing paren and the matching opening
+        ;; paren is not visible, show line of text containing the
+        ;; opening paren as an overlay on the window's start line.
+        (if (and (eq show-paren-style 'prelude)
+                 there-beg              ; Matching paren found?
+                 (> here-beg there-beg) ; Point placed after closing paren?
+                 ;; Point not on topmost line?
+                 (> (line-number-at-pos here-end) (line-number-at-pos (window-start)))
+                 ;; Opening paren not visible?
+                 (not (pos-visible-in-window-p there-beg)))
+            (let* ((prelude-overlay-beg (window-start))
+                   (prelude-overlay-end
+                    ;; Include trailing newline to enable overlays to
+                    ;; work properly on empty lines.
+                    (1+ (line-end-position (- (- (count-lines prelude-overlay-beg here-end) 2)))))
+                   (prelude-line-dist (- (- (count-lines there-beg here-end) 2)))
+                   (prelude-text
+                    (buffer-substring
+                     (line-beginning-position prelude-line-dist)
+                     ;; Again, include newline.
+                     (1+ (line-end-position prelude-line-dist))))
+                   ;; Translate opening paren pos to relative pos in
+                   ;; overlay text.
+                   (prelude-text-paren-beg
+                    (- there-beg (line-beginning-position prelude-line-dist))))
+              ;; Highlight opening paren in overlay text.
+              (put-text-property
+               prelude-text-paren-beg (+ prelude-text-paren-beg (- there-end there-beg))
+               'face 'show-paren-match prelude-text)
+              ;; Refresh overlay.
+              (move-overlay show-paren--overlay-prelude
+                            prelude-overlay-beg prelude-overlay-end (current-buffer))
+              (overlay-put show-paren--overlay-prelude 'display prelude-text)
+              (overlay-put show-paren--overlay-prelude 'priority show-paren-priority)
+              (overlay-put show-paren--overlay-prelude 'face 'show-paren-prelude))
+          (delete-overlay show-paren--overlay-prelude))))))
 
 (provide 'paren)
 
-- 
2.9.1


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

* Re: Show Paren mode: New prelude style
  2016-10-27 12:27 Show Paren mode: New prelude style Alain Schneble
@ 2016-10-27 12:51 ` Alain Schneble
  2016-10-31 19:30   ` Richard Copley
  2016-10-27 15:26 ` Eli Zaretskii
  1 sibling, 1 reply; 7+ messages in thread
From: Alain Schneble @ 2016-10-27 12:51 UTC (permalink / raw)
  To: emacs-devel

Alain Schneble <a.s@realize.ch> writes:

> Below you will find a patch to extend show-paren-mode with a new
> `prelude' style.  It's an extension of `parenthesis' style.  If the
> matching opening paren is not visible, it will show the line of text
> containing it as an overlay on the window's start line.  I think it's
> pretty useful, as it helps in keeping context when working e.g. in
> defuns with many lines of code -- all without having to scroll up and
> down.

It just came to my mind that I might better had introduced a new
separate customizable option to enable or disable prelude instead of
mixing it with the already existing style.  After all, it could be
useful in *addition* to the existing ones.  What do you think?

Alain




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

* Re: Show Paren mode: New prelude style
  2016-10-27 12:27 Show Paren mode: New prelude style Alain Schneble
  2016-10-27 12:51 ` Alain Schneble
@ 2016-10-27 15:26 ` Eli Zaretskii
  2016-10-27 17:15   ` Alain Schneble
  1 sibling, 1 reply; 7+ messages in thread
From: Eli Zaretskii @ 2016-10-27 15:26 UTC (permalink / raw)
  To: Alain Schneble; +Cc: emacs-devel

> From: Alain Schneble <a.s@realize.ch>
> Date: Thu, 27 Oct 2016 14:27:59 +0200
> 
> Below you will find a patch to extend show-paren-mode with a new
> `prelude' style.  It's an extension of `parenthesis' style.  If the
> matching opening paren is not visible, it will show the line of text
> containing it as an overlay on the window's start line.

Any reasons for lack of symmetry with the closing paren?



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

* Re: Show Paren mode: New prelude style
  2016-10-27 15:26 ` Eli Zaretskii
@ 2016-10-27 17:15   ` Alain Schneble
  2016-10-27 17:31     ` Eli Zaretskii
  0 siblings, 1 reply; 7+ messages in thread
From: Alain Schneble @ 2016-10-27 17:15 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

Eli Zaretskii <eliz@gnu.org> writes:

>> From: Alain Schneble <a.s@realize.ch>
>> Date: Thu, 27 Oct 2016 14:27:59 +0200
>> 
>> Below you will find a patch to extend show-paren-mode with a new
>> `prelude' style.  It's an extension of `parenthesis' style.  If the
>> matching opening paren is not visible, it will show the line of text
>> containing it as an overlay on the window's start line.
>
> Any reasons for lack of symmetry with the closing paren?

It's just because I thought the opposite is much less useful, as there
is probably less entropy in the lines containing the closing parens.  I
might be wrong though.

Symmetry for sure is a valid point and I will extend it if you think
it's worth it.

Alain




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

* Re: Show Paren mode: New prelude style
  2016-10-27 17:15   ` Alain Schneble
@ 2016-10-27 17:31     ` Eli Zaretskii
  0 siblings, 0 replies; 7+ messages in thread
From: Eli Zaretskii @ 2016-10-27 17:31 UTC (permalink / raw)
  To: Alain Schneble; +Cc: emacs-devel

> From: Alain Schneble <a.s@realize.ch>
> CC: <emacs-devel@gnu.org>
> Date: Thu, 27 Oct 2016 19:15:35 +0200
> 
> > Any reasons for lack of symmetry with the closing paren?
> 
> It's just because I thought the opposite is much less useful, as there
> is probably less entropy in the lines containing the closing parens.  I
> might be wrong though.

In Lisp sources, closing parentheses tend to come in large groups, so
it isn't always easy to understand which one closes the expression on
whose opening parenthesis you see the cursor.

> Symmetry for sure is a valid point and I will extend it if you think
> it's worth it.

I think it should be considered, but maybe you should wait for others
to chime in.

Thanks.



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

* Re: Show Paren mode: New prelude style
  2016-10-27 12:51 ` Alain Schneble
@ 2016-10-31 19:30   ` Richard Copley
  2016-10-31 19:57     ` Evgeny Roubinchtein
  0 siblings, 1 reply; 7+ messages in thread
From: Richard Copley @ 2016-10-31 19:30 UTC (permalink / raw)
  To: Alain Schneble; +Cc: Emacs Development

On 27 October 2016 at 13:51, Alain Schneble <a.s@realize.ch> wrote:
> Alain Schneble <a.s@realize.ch> writes:
>
>> Below you will find a patch to extend show-paren-mode with a new
>> `prelude' style.  It's an extension of `parenthesis' style.  If the
>> matching opening paren is not visible, it will show the line of text
>> containing it as an overlay on the window's start line.  I think it's
>> pretty useful, as it helps in keeping context when working e.g. in
>> defuns with many lines of code -- all without having to scroll up and
>> down.
>
> It just came to my mind that I might better had introduced a new
> separate customizable option to enable or disable prelude instead of
> mixing it with the already existing style.  After all, it could be
> useful in *addition* to the existing ones.  What do you think?

Alain,
I agree, it seems to be orthogonal to show-paren mode. It sounds
more like a good old-fashioned minor-mode than a custom option.

Did you rule out using header-line-format? My feeling is that
as a user I want to see the line at window-start and I'd prefer
it not to be obscured by an overlay.



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

* Re: Show Paren mode: New prelude style
  2016-10-31 19:30   ` Richard Copley
@ 2016-10-31 19:57     ` Evgeny Roubinchtein
  0 siblings, 0 replies; 7+ messages in thread
From: Evgeny Roubinchtein @ 2016-10-31 19:57 UTC (permalink / raw)
  To: Richard Copley; +Cc: Alain Schneble, Emacs Development

[-- Attachment #1: Type: text/plain, Size: 1362 bytes --]

FWIW, the following two minor modes are already part of  Emacs:

* which-function-mode
* semantic-stickyfunc-mode

On Mon, Oct 31, 2016 at 3:30 PM, Richard Copley <rcopley@gmail.com> wrote:

> On 27 October 2016 at 13:51, Alain Schneble <a.s@realize.ch> wrote:
> > Alain Schneble <a.s@realize.ch> writes:
> >
> >> Below you will find a patch to extend show-paren-mode with a new
> >> `prelude' style.  It's an extension of `parenthesis' style.  If the
> >> matching opening paren is not visible, it will show the line of text
> >> containing it as an overlay on the window's start line.  I think it's
> >> pretty useful, as it helps in keeping context when working e.g. in
> >> defuns with many lines of code -- all without having to scroll up and
> >> down.
> >
> > It just came to my mind that I might better had introduced a new
> > separate customizable option to enable or disable prelude instead of
> > mixing it with the already existing style.  After all, it could be
> > useful in *addition* to the existing ones.  What do you think?
>
> Alain,
> I agree, it seems to be orthogonal to show-paren mode. It sounds
> more like a good old-fashioned minor-mode than a custom option.
>
> Did you rule out using header-line-format? My feeling is that
> as a user I want to see the line at window-start and I'd prefer
> it not to be obscured by an overlay.
>
>

[-- Attachment #2: Type: text/html, Size: 1938 bytes --]

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

end of thread, other threads:[~2016-10-31 19:57 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-10-27 12:27 Show Paren mode: New prelude style Alain Schneble
2016-10-27 12:51 ` Alain Schneble
2016-10-31 19:30   ` Richard Copley
2016-10-31 19:57     ` Evgeny Roubinchtein
2016-10-27 15:26 ` Eli Zaretskii
2016-10-27 17:15   ` Alain Schneble
2016-10-27 17:31     ` Eli Zaretskii

Code repositories for project(s) associated with this external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.