all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: "David De La Harpe Golden" <david.delaharpe.golden@gmail.com>
To: "Stefan Monnier" <monnier@iro.umontreal.ca>,
	 "Tassilo Horn" <tassilo@member.fsf.org>
Cc: David O'Toole <dto@gnu.org>,
	"Lennart Borgman \(gmail\)" <lennart.borgman@gmail.com>,
	emacs-devel@gnu.org
Subject: Re: Suggestion: A fringe indicator that shows the last/first line before scrolling
Date: Sat, 1 Mar 2008 03:28:46 +0000	[thread overview]
Message-ID: <8e24944a0802291928j4544932fqdcbf2f2b52cd4a08@mail.gmail.com> (raw)
In-Reply-To: <8e24944a0802291304m281c72efx9e00a8923ace862a@mail.gmail.com>

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

Version 3... "not perfect, but nice enough to use"

*** Changes:

Added explicit copyright+license comment in case that's an issue.

Separate overlay per window. Tracked in weak hash table as it seemed
as easy to do it that way.

Still just uses two global idle timers, so all the timings of changes
are linked .  Doesn't seem to matter much for just this
show-old-window-pos functionality though - the fringe marks are only
intended to be transiently displayed for a couple of seconds as a
visual aid anyway, and doesn't really matter much if they linger for
slightly off the stated time.

Note if you pause too long in the middle of a "scroll gesture" (i.e.
sequence of consecutive scrolling commands), then the fringe marks
will disappear and restart from where you paused. This is a good
reason why this is just not the way to do Martin's scroll-restore
point-tracking functionality, of course, but could even be considered
a feature rather than a bug in this context.

Added a customizable list of commands that warp the old position overlay,
the default means that the page-scrolling marks reappear each
individual page scroll, which is probably what people want for
page-by-page scrolling.  This actually warps all the old pos overlays,
not just the overlays in the window(s) associated with the command,
but again doesn't seem to matter much given transience of the effect.

*** still issue:

nongui terminals and gui terminals without fringes could use
alternate highlighting strategies I guess. Not sure what alternate
highlighting strategies are sensible, anything other than fringes
seems kinda ugly.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: show-old-window-pos.el --]
[-- Type: text/x-emacs-lisp; name=show-old-window-pos.el, Size: 5976 bytes --]

;;; show-old-window-pos.el --- Show old window position briefly after it changes.

;; Copyright (C) 2008 David De La Harpe Golden

;; Author: David De La Harpe Golden <david.delaharpe.golden@gmail.com>
;; Version: 3
;; Keywords: scrolling

;; show-old-window-pos.el is free software; you can redistribute it 
;; and/or modify it under the terms of the GNU General Public License 
;; as published by the Free Software Foundation; either version 3 of 
;; the License, or (at your option) any later version.

;; show-old-window-pos.el is distributed in the hope that it will be 
;; useful, but WITHOUT ANY WARRANTY; without even the implied warranty
;; of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:

;; This package provides fringe marks that show where in the buffer 
;; the window used to be showing for a couple of  seconds when the 
;; window position changes through scrolling etc.

;; This is done via timers, and is on a "best effort" basis only.

;;; Code:

(defgroup show-old-window-pos nil
  "Indicate (in the fringe) the old window position for a bit when scrolling."
  :version "23.1"
  :group 'windows)

(defface show-old-window-pos-fringe 
  '((t (:foreground "darkcyan")))
  "Face for old window position fringe mark."
  :group 'show-old-window-pos
  :version "23.1")

(defcustom show-old-window-pos-linger-time 2
  "How long the fringe marks showing old window position should be visible for."
  :type 'integer
  :group 'show-old-window-pos
  :version "23.1")


(defcustom show-old-window-pos-each-time-commands
  '(scroll-up scroll-down scroll-other-window scroll-other-window-down)
  "What commands should always show the immediately preceding old window position.
Typically, one would want only commands that cause large scrolls 
or other window changes listed here."
  :type '(repeat symbol)
  :group 'show-old-window-pos
  :version "23.1")

(defvar show-old-window-pos-overlays (make-hash-table :weakness 'key))

(defun show-old-window-pos-overlays-ensure-hash-table ()
  (unless (hash-table-p show-old-window-pos-overlays)
    (setq show-old-window-pos-overlays (make-hash-table :weakness 'key))))

(defun show-old-window-pos-add-overlay (window)
  (show-old-window-pos-overlays-ensure-hash-table)
  (let ((overlay (make-overlay 
		  (window-start window) 
		  (- (window-end window) 1) 
		  (window-buffer window))))
    (overlay-put overlay 'window window)
    (puthash window overlay show-old-window-pos-overlays)))

(defun show-old-window-pos-overlays-showhide ()
  (show-old-window-pos-overlays-ensure-hash-table)
  (mapcar (lambda (visible-frame)
	    (mapcar 
	     (lambda (window)
	       (let ((old-pos-overlay
		      (gethash window show-old-window-pos-overlays)))
		 (unless old-pos-overlay
		   (show-old-window-pos-add-overlay window))
		 (if (equal (window-start window) 
			    (overlay-start old-pos-overlay))
		     (overlay-put old-pos-overlay 'before-string nil)
		   (overlay-put 
		    old-pos-overlay 'before-string 
		    (concat
		     (propertize "[" 'display 
				 (list 'left-fringe 'top-left-angle 
				       'show-old-window-pos-fringe))
		     (propertize "[" 'display 
				 (list 'right-fringe 'top-right-angle 
				       'show-old-window-pos-fringe)))))
		 (if (equal (- (window-end window) 1) 
			    (overlay-end old-pos-overlay))
		     (overlay-put old-pos-overlay 'after-string nil)
		   (overlay-put 
		    old-pos-overlay 'after-string 
		    (concat
		     (propertize "]" 'display 
				 (list 'left-fringe 'bottom-left-angle 
				       'show-old-window-pos-fringe))
		     (propertize "]" 'display 
				 (list 'right-fringe 
				       'bottom-right-angle
				       'show-old-window-pos-fringe)))))))
	     (window-list visible-frame)))
	  (visible-frame-list)))

(defun show-old-window-pos-overlays-update-pos ()
  (show-old-window-pos-overlays-ensure-hash-table)
  (mapcar (lambda (visible-frame) 
	    (mapcar (lambda (window) 
		      (let ((old-pos-overlay 
			     (gethash window show-old-window-pos-overlays)))
			(if old-pos-overlay
			    (move-overlay old-pos-overlay
					  (window-start window)
					  (- (window-end window) 1)
					  (window-buffer window))
			  (show-old-window-pos-add-overlay window))))
		    (window-list visible-frame)))
	  (visible-frame-list))
  (show-old-window-pos-overlays-showhide)
  (redisplay))

	     
(defun show-old-window-pos-maybe-reset-old-pos ()
  "Pre-command-hook that resets the old window pos before certain commands."
  (when (memq this-command show-old-window-pos-each-time-commands)
    (show-old-window-pos-overlays-update-pos)))


(define-minor-mode show-old-window-pos-mode
  "Toggle show-old-window-pos-mode.

In show-old-window-pos-mode, if the fringes are present, fringe
marks will show the position the old window was showing in its
buffer for `show-old-window-pos-linger-time' seconds when the 
window changes position."

  :global t
  :group 'show-old-window-pos
  :init-value nil
  :link '(emacs-commentary-link "show-old-window-pos.el")
  (if show-old-window-pos-mode
      (progn
	(add-hook 'pre-command-hook 'show-old-window-pos-maybe-reset-old-pos)
	(run-with-idle-timer 0 t 'show-old-window-pos-overlays-showhide)
	(run-with-idle-timer show-old-window-pos-linger-time
			     t 'show-old-window-pos-overlays-update-pos))
    (cancel-function-timers 'show-old-window-pos-overlays-showhide)
    (cancel-function-timers 'show-old-window-pos-overlays-update-pos)
    (remove-hook 'pre-command-hook 'show-old-window-pos-maybe-reset-old-pos)
    ;; Explicitly delete overlays.
    (maphash (lambda (key val)
	       (if (overlayp val)
		   (delete-overlay val)))
	     show-old-window-pos-overlays)
    (setq show-old-window-pos-overlays nil)))

(provide 'show-old-window-pos)

;;; show-old-window-pos.el ends here

  parent reply	other threads:[~2008-03-01  3:28 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-02-28 11:48 Suggestion: A fringe indicator that shows the last/first line before scrolling Tassilo Horn
2008-02-28 13:55 ` David O'Toole
2008-02-28 15:46   ` Lennart Borgman (gmail)
2008-02-28 16:34     ` David De La Harpe Golden
2008-02-28 17:52       ` Lennart Borgman (gmail)
2008-02-28 18:01         ` David De La Harpe Golden
2008-02-28 18:12           ` Lennart Borgman (gmail)
2008-02-28 18:18             ` David De La Harpe Golden
2008-02-28 18:34               ` Lennart Borgman (gmail)
2008-02-28 23:18                 ` David De La Harpe Golden
2008-02-29  1:55                   ` Stefan Monnier
2008-02-29  2:50                     ` David De La Harpe Golden
2008-02-29  4:33                       ` Stefan Monnier
2008-02-29 17:57                         ` David De La Harpe Golden
2008-02-29 21:04                           ` David De La Harpe Golden
2008-02-29 21:12                             ` David De La Harpe Golden
2008-02-29 21:33                             ` Lennart Borgman (gmail)
2008-02-29 23:16                               ` David De La Harpe Golden
2008-02-29 23:29                                 ` Lennart Borgman (gmail)
2008-02-29 23:59                                   ` David De La Harpe Golden
2008-03-01  0:05                                     ` David De La Harpe Golden
2008-03-01  0:10                                     ` Lennart Borgman (gmail)
2008-03-01  3:28                             ` David De La Harpe Golden [this message]
2008-03-01  3:39                               ` Miles Bader
2008-03-01  3:59                                 ` David De La Harpe Golden
2008-03-02  3:00                                 ` David De La Harpe Golden
2008-03-01  3:44                               ` David De La Harpe Golden
2008-02-28 17:19   ` Stefan Monnier
2008-02-28 17:39     ` Tassilo Horn
2008-02-28 18:16       ` Stefan Monnier
2008-02-29  1:40 ` Richard Stallman
2008-02-29  8:02   ` Tassilo Horn
2008-02-29 19:54     ` Richard Stallman
2008-03-01  9:28       ` Tassilo Horn

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

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8e24944a0802291928j4544932fqdcbf2f2b52cd4a08@mail.gmail.com \
    --to=david.delaharpe.golden@gmail.com \
    --cc=dto@gnu.org \
    --cc=emacs-devel@gnu.org \
    --cc=lennart.borgman@gmail.com \
    --cc=monnier@iro.umontreal.ca \
    --cc=tassilo@member.fsf.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 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.