GNU bug report logs - #27932
26.0.50; Feature request: prevent scroll commands from changing the buffer location of point

Previous Next

Package: emacs;

Reported by: Dani Moncayo <dmoncayo <at> gmail.com>

Date: Thu, 3 Aug 2017 13:35:02 UTC

Severity: wishlist

Found in version 26.0.50

To reply to this bug, email your comments to 27932 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#27932; Package emacs. (Thu, 03 Aug 2017 13:35:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Dani Moncayo <dmoncayo <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Thu, 03 Aug 2017 13:35:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Dani Moncayo <dmoncayo <at> gmail.com>
To: bug-gnu-emacs <bug-gnu-emacs <at> gnu.org>
Subject: 26.0.50; Feature request: prevent scroll commands from changing the
 buffer location of point
Date: Thu, 3 Aug 2017 15:34:38 +0200
Severity: wishlist

Hi,

I'd like to ask for a feature which I'm used to in other text editors
like notepad and notepad++ on MS-Windows (I think many other editors
may have it too).

I'd like to be able to configure Emacs so that scroll commands _never_
move point (cursor) from its _buffer_ location.

That could lead to situations where the point/cursor is not visible
(it is out of the visible portion of text).  In that situations, any
command which moves the cursor/point (e.g. C-f) or changes buffer text
should trigger an auto-scroll to get the point/cursor back to the
visible area (window), preserving its _buffer_ location.

That feature could be enabled by giving some special value (e.g.
'never) to the variable "scroll-preserve-screen-position".

I don't know how complex is that to implement, but I think some users
may like it.

--
Dani Moncayo

In GNU Emacs 26.0.50 (build 1, x86_64-unknown-cygwin)
 of 2017-07-24 built on ZVDES404
Repository revision: 6dc5d45c542a6f9cfbcf3e37d597c9e0efb3070d
Windowing system distributor 'Microsoft Corp.', version 6.3.9600

Configured using:
 'configure --with-mailutils --with-w32'

Configured features:
SOUND ACL GNUTLS ZLIB TOOLKIT_SCROLL_BARS

Important settings:
  value of $LANG: C.ISO-8859-1
  locale-coding-system: iso-latin-1-unix




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#27932; Package emacs. (Thu, 03 Aug 2017 16:44:02 GMT) Full text and rfc822 format available.

Message #8 received at 27932 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Dani Moncayo <dmoncayo <at> gmail.com>
Cc: 27932 <at> debbugs.gnu.org
Subject: Re: bug#27932: 26.0.50;
 Feature request: prevent scroll commands from changing the buffer
 location of point
Date: Thu, 03 Aug 2017 19:42:59 +0300
> From: Dani Moncayo <dmoncayo <at> gmail.com>
> Date: Thu, 3 Aug 2017 15:34:38 +0200
> 
> I don't know how complex is that to implement

It would require a complete rewrite of most of the display engine
code.  The Emacs display engine is based on the principle that point
should always be visible, so whenever it becomes invisible, Emacs
scrolls the window to make it visible again.  The display code checks
this in many places, and they all will need to be changed in some, yet
unspecified, way.

Emacs provides the mark and "C-x C-x" as a way to jump between two
locations without requiring the feature you describe.  If the purpose
of what you want is some other use case, I think it would be good to
have it described.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#27932; Package emacs. (Thu, 03 Aug 2017 17:57:02 GMT) Full text and rfc822 format available.

Message #11 received at 27932 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Dani Moncayo <dmoncayo <at> gmail.com>, 27932 <at> debbugs.gnu.org
Subject: Re: bug#27932: 26.0.50; Feature request: prevent scroll commands
 from changing the buffer location of point
Date: Thu, 03 Aug 2017 19:56:38 +0200
> I'd like to be able to configure Emacs so that scroll commands _never_
> move point (cursor) from its _buffer_ location.
>
> That could lead to situations where the point/cursor is not visible
> (it is out of the visible portion of text).  In that situations, any
> command which moves the cursor/point (e.g. C-f) or changes buffer text
> should trigger an auto-scroll to get the point/cursor back to the
> visible area (window), preserving its _buffer_ location.
>
> That feature could be enabled by giving some special value (e.g.
> 'never) to the variable "scroll-preserve-screen-position".
>
> I don't know how complex is that to implement, but I think some users
> may like it.

‘scroll-restore-mode’ in ELPA should "in principle" emulate that.  But
it has its quirks.

martin





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#27932; Package emacs. (Fri, 04 Aug 2017 00:08:01 GMT) Full text and rfc822 format available.

Message #14 received at 27932 <at> debbugs.gnu.org (full text, mbox):

From: Tak Kunihiro <homeros.misasa <at> gmail.com>
To: Dani Moncayo <dmoncayo <at> gmail.com>
Cc: 27932 <at> debbugs.gnu.org
Subject: Re: bug#27932: 26.0.50;
 Feature request: prevent scroll commands from changing the buffer
 location of point
Date: Fri, 04 Aug 2017 08:16:12 +0900
I have a similar wish.

Without revision of engine I think you can (1) restore point, (2)
preserve region, and (3) extend region.

Those can be implemented in following steps.
 (a) Call minor mode by mouse wheel,
 (b) Store point and region, then
 (c) Restore point when the minor mode is turned off.

One idea to preserve region is to use secondary.  I am waiting for a
patch to be processed.

 http://lists.gnu.org/archive/html/bug-gnu-emacs/2017-06/msg00938.html

-- 
Tak Kunihiro





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#27932; Package emacs. (Fri, 04 Aug 2017 06:16:02 GMT) Full text and rfc822 format available.

Message #17 received at 27932 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Tak Kunihiro <homeros.misasa <at> gmail.com>
Cc: 27932 <at> debbugs.gnu.org, dmoncayo <at> gmail.com
Subject: Re: bug#27932: 26.0.50;
 Feature request: prevent scroll commands from changing the buffer
 location of point
Date: Fri, 04 Aug 2017 09:15:22 +0300
> From: Tak Kunihiro <homeros.misasa <at> gmail.com>
> Date: Fri, 04 Aug 2017 08:16:12 +0900
> Cc: 27932 <at> debbugs.gnu.org
> 
> I have a similar wish.
> 
> Without revision of engine I think you can (1) restore point, (2)
> preserve region, and (3) extend region.

How is this different from mark-related features, starting with "C-x C-x"?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#27932; Package emacs. (Fri, 04 Aug 2017 06:35:02 GMT) Full text and rfc822 format available.

Message #20 received at 27932 <at> debbugs.gnu.org (full text, mbox):

From: Dani Moncayo <dmoncayo <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 27932 <at> debbugs.gnu.org
Subject: Re: bug#27932: 26.0.50; Feature request: prevent scroll commands from
 changing the buffer location of point
Date: Fri, 4 Aug 2017 08:34:11 +0200
On Fri, Aug 4, 2017 at 8:14 AM, Eli Zaretskii <eliz <at> gnu.org> wrote:
> [Did you really mean to make this a private email?]

Oh no.  Sorry.  I'm adding the ticket address back.

>> > It would require a complete rewrite of most of the display engine
>> > code.  The Emacs display engine is based on the principle that point
>> > should always be visible, so whenever it becomes invisible, Emacs
>> > scrolls the window to make it visible again.  The display code checks
>> > this in many places, and they all will need to be changed in some, yet
>> > unspecified, way.
>>
>> I was afraid of the above.  Well it's your call to judge if this is worth it.
>
> I don't have anything against coding such a feature, but I myself
> won't be doing that any time soon, if ever.  It's just a too large
> project for my resources, and my motivation for doing this is zero,
> since I'm always annoyed by this behavior I find in MS Word.

I see.   :-(   :-)

>> > Emacs provides the mark and "C-x C-x" as a way to jump between two
>> > locations without requiring the feature you describe.  If the purpose
>> > of what you want is some other use case, I think it would be good to
>> > have it described.
>>
>> I can see several benefits in the requested feature:
>> * To have a way to explore a buffer without seeing a distracting
>> cursor jumping around.
>
> "Distracting cursor"?  If it distracts you, you can make it a bar
> instead of a block.

I want the cursor to be a block, so I can spot it easily on the
screen.  But I don't want to see it when I'm doing a "exploring trip"
in the buffer.

>> * To have a behavior which is standard in may other editors (where the
>> position of the cursor wrt the text is not altered by scrolling
>> commands).
>
> That's not a reasoning for the feature, because it doesn't provide any
> rationale in terms of utility.

Well, the point is that the requested behavior is a standard one among
many other editors.  I think this is something relevant to consider.

>> * To have an intuitive, quick and convenient way to explore the
>> neighborhood of point (e.g. using C-v, M-v or the mouse-wheel) and
>> then "return" (move the viewport back) to the point.
>
> How is this different from "C-x C-x"?

Well, it is similar, but "C-x C-x" requires you to push the mark
before you leave.  And users with little experience in Emacs may be
used to this workflow from their experience in other editors.

-- 
Dani Moncayo




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#27932; Package emacs. (Fri, 04 Aug 2017 06:40:01 GMT) Full text and rfc822 format available.

Message #23 received at 27932 <at> debbugs.gnu.org (full text, mbox):

From: Tak Kunihiro <homeros.misasa <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: Tak Kunihiro <homeros.misasa <at> gmail.com>, 27932 <at> debbugs.gnu.org,
 dmoncayo <at> gmail.com
Subject: Re: bug#27932: 26.0.50;
 Feature request: prevent scroll commands from changing the buffer
 location of point
Date: Fri, 04 Aug 2017 15:39:07 +0900
>> I have a similar wish.
>>
>> Without revision of engine I think you can (1) restore point, (2)
>> preserve region, and (3) extend region.
>
> How is this different from mark-related features, starting with "C-x C-x"?

"C-x C-x" requires mark.  Also "C-x C-x" changes scope in buffer.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#27932; Package emacs. (Fri, 04 Aug 2017 08:02:01 GMT) Full text and rfc822 format available.

Message #26 received at 27932 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Tak Kunihiro <homeros.misasa <at> gmail.com>
Cc: homeros.misasa <at> gmail.com, 27932 <at> debbugs.gnu.org, dmoncayo <at> gmail.com
Subject: Re: bug#27932: 26.0.50;
 Feature request: prevent scroll commands from changing the buffer
 location of point
Date: Fri, 04 Aug 2017 11:01:10 +0300
> From: Tak Kunihiro <homeros.misasa <at> gmail.com>
> Cc: Tak Kunihiro <homeros.misasa <at> gmail.com>,  dmoncayo <at> gmail.com,  27932 <at> debbugs.gnu.org
> Date: Fri, 04 Aug 2017 15:39:07 +0900
> 
> >> I have a similar wish.
> >>
> >> Without revision of engine I think you can (1) restore point, (2)
> >> preserve region, and (3) extend region.
> >
> > How is this different from mark-related features, starting with "C-x C-x"?
> 
> "C-x C-x" requires mark.

Most commands that go far away do leave mark where they were invoked.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#27932; Package emacs. (Fri, 04 Aug 2017 10:35:01 GMT) Full text and rfc822 format available.

Message #29 received at 27932 <at> debbugs.gnu.org (full text, mbox):

From: Tak Kunihiro <homeros.misasa <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: Tak Kunihiro <homeros.misasa <at> gmail.com>, 27932 <at> debbugs.gnu.org,
 dmoncayo <at> gmail.com
Subject: Re: bug#27932: 26.0.50;
 Feature request: prevent scroll commands from changing the buffer
 location of point
Date: Fri, 04 Aug 2017 19:33:59 +0900
>> >> I have a similar wish.
>> >>
>> >> Without revision of engine I think you can (1) restore point, (2)
>> >> preserve region, and (3) extend region.
>> >
>> > How is this different from mark-related features, starting with "C-x C-x"?
>> 
>> "C-x C-x" requires mark.
>
> Most commands that go far away do leave mark where they were invoked.

I agree.  Command in my mind that does not leave mark was mwheel-scroll.
Also C-v and M-v do not leave mark.  I think they should not.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#27932; Package emacs. (Fri, 04 Aug 2017 21:37:01 GMT) Full text and rfc822 format available.

Message #32 received at 27932 <at> debbugs.gnu.org (full text, mbox):

From: Richard Stallman <rms <at> gnu.org>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 27932 <at> debbugs.gnu.org, dmoncayo <at> gmail.com
Subject: Re: bug#27932: 26.0.50;
 Feature request: prevent scroll commands from changing the buffer
 location of point
Date: Fri, 04 Aug 2017 17:36:07 -0400
[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  > It would require a complete rewrite of most of the display engine
  > code.  The Emacs display engine is based on the principle that point
  > should always be visible, so whenever it becomes invisible, Emacs
  > scrolls the window to make it visible again.

I don't think the change would be terribly hard.  One would have to
find the places that insist on putting point on the screen, but I
think the changes required in each of those places would not be big.

If someone wants to try it, I encourage per to try it.

-- 
Dr Richard Stallman
President, Free Software Foundation (gnu.org, fsf.org)
Internet Hall-of-Famer (internethalloffame.org)
Skype: No way! See stallman.org/skype.html.





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#27932; Package emacs. (Sat, 05 Aug 2017 06:46:01 GMT) Full text and rfc822 format available.

Message #35 received at 27932 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: rms <at> gnu.org
Cc: 27932 <at> debbugs.gnu.org, dmoncayo <at> gmail.com
Subject: Re: bug#27932: 26.0.50;
 Feature request: prevent scroll commands from changing the buffer
 location of point
Date: Sat, 05 Aug 2017 09:44:57 +0300
> From: Richard Stallman <rms <at> gnu.org>
> CC: dmoncayo <at> gmail.com, 27932 <at> debbugs.gnu.org
> Date: Fri, 04 Aug 2017 17:36:07 -0400
> 
>   > It would require a complete rewrite of most of the display engine
>   > code.  The Emacs display engine is based on the principle that point
>   > should always be visible, so whenever it becomes invisible, Emacs
>   > scrolls the window to make it visible again.
> 
> I don't think the change would be terribly hard.  One would have to
> find the places that insist on putting point on the screen, but I
> think the changes required in each of those places would not be big.

The number of such places got a lot larger than it was when you were
more actively hacking Emacs, because over the years some users (Dani
included) requested more and more accuracy in that direction.

As for whether the changes in those places are hard, depends on how
well the person who'll do that understands what the code they are
looking at is doing, and why.  The answer might not always be obvious.

And then there are higher-level issues, like what does this mode mean
when scroll-conservatively is in effect.

> If someone wants to try it, I encourage per to try it.

Me too.  In fact, I'd encourage even smaller changes related to the
display code, so that we have more people who can make changes there
than we do now.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#27932; Package emacs. (Sat, 05 Aug 2017 20:21:02 GMT) Full text and rfc822 format available.

Message #38 received at 27932 <at> debbugs.gnu.org (full text, mbox):

From: Richard Stallman <rms <at> gnu.org>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 27932 <at> debbugs.gnu.org, dmoncayo <at> gmail.com
Subject: Re: bug#27932: 26.0.50;
 Feature request: prevent scroll commands from changing the buffer
 location of point
Date: Sat, 05 Aug 2017 16:19:52 -0400
[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  > And then there are higher-level issues, like what does this mode mean
  > when scroll-conservatively is in effect.

Person could try it whichever way is easiest and see if person likes it.

-- 
Dr Richard Stallman
President, Free Software Foundation (gnu.org, fsf.org)
Internet Hall-of-Famer (internethalloffame.org)
Skype: No way! See stallman.org/skype.html.





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#27932; Package emacs. (Sun, 06 Aug 2017 17:20:02 GMT) Full text and rfc822 format available.

Message #41 received at 27932 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: rms <at> gnu.org
Cc: 27932 <at> debbugs.gnu.org, dmoncayo <at> gmail.com
Subject: Re: bug#27932: 26.0.50;
 Feature request: prevent scroll commands from changing the buffer
 location of point
Date: Sun, 06 Aug 2017 20:18:43 +0300
> From: Richard Stallman <rms <at> gnu.org>
> CC: dmoncayo <at> gmail.com, 27932 <at> debbugs.gnu.org
> Date: Sat, 05 Aug 2017 16:19:52 -0400
> 
>   > And then there are higher-level issues, like what does this mode mean
>   > when scroll-conservatively is in effect.
> 
> Person could try it whichever way is easiest and see if person likes it.

I was thinking about the person who will need to decide how to code
that.

In several places we behave under scroll-conservatively with the
explicit goal of keeping point visible in the very first/last
sufficiently-visible screen line: this might need to be changed if
keeping point visible is no longer a requirement.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#27932; Package emacs. (Sun, 06 Aug 2017 21:01:01 GMT) Full text and rfc822 format available.

Message #44 received at 27932 <at> debbugs.gnu.org (full text, mbox):

From: Dani Moncayo <dmoncayo <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 27932 <at> debbugs.gnu.org, "Richard M. Stallman" <rms <at> gnu.org>
Subject: Re: bug#27932: 26.0.50; Feature request: prevent scroll commands from
 changing the buffer location of point
Date: Sun, 6 Aug 2017 23:00:38 +0200
> In several places we behave under scroll-conservatively with the
> explicit goal of keeping point visible in the very first/last
> sufficiently-visible screen line: this might need to be changed if
> keeping point visible is no longer a requirement.

Maybe I'm missing something, but I don't think that the
meaning/interpretation of 'scroll-conservatively' should be changed at
all, because AFAIK, that variable controls the auto-scroll triggered
by a point movement, and such auto-scroll would be equally necessary
with the proposed feature enabled (and should work equally).

-- 
Dani Moncayo




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#27932; Package emacs. (Mon, 07 Aug 2017 02:30:02 GMT) Full text and rfc822 format available.

Message #47 received at 27932 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Dani Moncayo <dmoncayo <at> gmail.com>
Cc: 27932 <at> debbugs.gnu.org, rms <at> gnu.org
Subject: Re: bug#27932: 26.0.50; Feature request: prevent scroll commands from
 changing the buffer location of point
Date: Mon, 07 Aug 2017 05:28:55 +0300
> From: Dani Moncayo <dmoncayo <at> gmail.com>
> Date: Sun, 6 Aug 2017 23:00:38 +0200
> Cc: "Richard M. Stallman" <rms <at> gnu.org>, 27932 <at> debbugs.gnu.org
> 
> Maybe I'm missing something, but I don't think that the
> meaning/interpretation of 'scroll-conservatively' should be changed at
> all, because AFAIK, that variable controls the auto-scroll triggered
> by a point movement, and such auto-scroll would be equally necessary
> with the proposed feature enabled (and should work equally).

??? The proposed feature is that point could go off the view without
requiring any scrolling.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#27932; Package emacs. (Mon, 07 Aug 2017 05:55:02 GMT) Full text and rfc822 format available.

Message #50 received at 27932 <at> debbugs.gnu.org (full text, mbox):

From: Dani Moncayo <dmoncayo <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 27932 <at> debbugs.gnu.org, "Richard M. Stallman" <rms <at> gnu.org>
Subject: Re: bug#27932: 26.0.50; Feature request: prevent scroll commands from
 changing the buffer location of point
Date: Mon, 7 Aug 2017 07:54:21 +0200
>> Maybe I'm missing something, but I don't think that the
>> meaning/interpretation of 'scroll-conservatively' should be changed at
>> all, because AFAIK, that variable controls the auto-scroll triggered
>> by a point movement, and such auto-scroll would be equally necessary
>> with the proposed feature enabled (and should work equally).
>
> ??? The proposed feature is that point could go off the view without
> requiring any scrolling.

The proposed feature is that any _scrolling_command_ (e.g. C-v, M-v,
mouse-wheel, ...) should perform its scrolling without altering the
location of point (wrt its buffer).  But any command which changes
either the location of point (wrt its buffer) (e.g. "C-u 200 C-n" or
the buffer text should check whether the point is currently visible,
and if it isn't visible, it should trigger an auto-scroll to make
point visible (exactly as happens now).

In short: point movement should trigger auto-scrolling (as now), but
scrolling should not move point.

-- 
Dani Moncayo




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#27932; Package emacs. (Mon, 07 Aug 2017 12:33:02 GMT) Full text and rfc822 format available.

Message #53 received at 27932 <at> debbugs.gnu.org (full text, mbox):

From: Tak Kunihiro <homeros.misasa <at> gmail.com>
To: Dani Moncayo <dmoncayo <at> gmail.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 27932 <at> debbugs.gnu.org,
 "Richard M. Stallman" <rms <at> gnu.org>
Subject: Re: bug#27932: 26.0.50;
 Feature request: prevent scroll commands from changing the buffer
 location of point
Date: Mon, 07 Aug 2017 21:32:41 +0900
> The proposed feature is that any _scrolling_command_ (e.g. C-v, M-v,
> mouse-wheel, ...) should perform its scrolling without altering the
> location of point (wrt its buffer).

I propose targeting mouse-wheel and scroll-bar-toolkit-scroll only, and
having a pseudo point.

This is in a middle, but I think building blocks are there.


;;; touchpad.el --- Scroll two dimensionally by touchpad

;; Copyright (C) 2017 Tak Kunihiro

;; Author: Tak Kunihiro <tkk <at> misasa.okayama-u.ac.jp>
;; Package-Requires: ((emacs "26"))
;; Keywords: mouse
;; Version: 1.0

;; This program 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.

;; This program 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/>.

;; Usage:
;;
;; To interactively toggle the mode:
;;
;;   M-x touchpad-mode RET
;;
;; To make the mode permanent, put these in your init file:
;;
;;   (require 'touchpad)
;;   (touchpad-mode 1)

;;; Commentary:

;; Touchpad mode is a global minor mode which makes swiping touchpad
;; scroll smoothly.  This package disables `auto-hscroll-mode' during
;; scroll by the touchpad because of following two aspects.

;; (1) It should be off during vertical scroll.  Let’s consider a
;;     buffer with empty and long alternative lines and when point is
;;     at the end of a long line at the top of window.  After
;;     `scroll-up 1', point jumps to the beginning of the next empty
;;     line and you see scope shifts suddenly leftward.  This behavior
;;     is sometimes unexpected one.

;; (2) It should be off during horizontal scroll.  During horizontal
;;     scroll, you may scroll a little in vertical direction without
;;     intention.  The horizontal scroll should be tolerance against
;;     such perturbation.

;; After scroll by the touchpad, you want to set `auto-hscroll-mode'
;; back again otherwise too inconvenient for edition by the keyboard.
;;
;; Approach of this package is to turn on another minor-mode
;; `touchpad--view-mode' with `auto-hscroll-mode' nil, at the beginning
;; of `mwheel-scroll'.  The minor mode is turned off upon key input
;; from the keyboard that moves point.
;;
;; This package also converts point and region to
;; `mouse-secondary-start' and `mouse-secondary-overlay'.  When
;; `touchpad-restore-point-flag' is non-nil, point will be moved to
;; `mouse-secondary-start' when `touchpad--view-mode' is turned off.

;;; Code:

(require 'mwheel)

(defvar touchpad-restore-point-flag t
  "Restore point when `touchpad--view-mode' is turned off.")

(defvar touchpad--cursor-type cursor-type
  "Cursor used by user.
This variable is used internally to restore original `cursor-type'.")

(defvar touchpad--auto-hscroll-mode nil
  "Value of auto-hscroll-mode specified by user.
This variable is used internally to restore original `auto-hscroll-mode'.")

;;;###autoload
(define-minor-mode touchpad-mode
  "A minor mode to scroll text two dimensionally.
With a prefix argument ARG, enable Touchpad Mode if ARG is
positive, and disable it otherwise.  If called from Lisp, enable
Touchpad Mode if ARG is omitted or nil."
  :init-value nil
  :group 'scrolling
  :global t
  :version "26.1"
  :keymap (let ((map (make-sparse-keymap)))
            ;; Extend primary by shift click
            (define-key map [S-down-mouse-1] 'ignore)
            (define-key map [S-mouse-1] 'mouse-save-then-kill)
            (if (not (eq system-type 'ms-dos))
                (global-set-key [C-S-down-mouse-1] 'mouse-appearance-menu))
            ;; Change size of font ize by wheel up and down
            (define-key map (kbd "<C-wheel-up>") 'touchpad-text-scale-increase)
            (define-key map (kbd "<C-wheel-down>") 'touchpad-text-scale-decrease)
            map)

  (if touchpad-mode
      (progn
        (advice-add 'mwheel-scroll :before 'touchpad-enable--view-mode)
        ;; http://lists.gnu.org/archive/html/bug-gnu-emacs/2017-04/msg00700.html
        ;; (add-hook 'mwheel-pre-scroll-hook 'touchpad-enable--view-mode)
        (advice-add 'ns-handle-scroll-bar-event :before 'touchpad-enable--view-mode)
        (advice-add 'scroll-bar-toolkit-scroll :before 'touchpad-enable--view-mode)
        (setq mwheel-tilt-scroll-p t))
    (advice-remove 'mwheel-scroll #'touchpad-enable--view-mode)
    ;; (remove-hook 'mwheel-pre-scroll-hook 'touchpad-enable--view-mode)
    (advice-remove 'ns-handle-scroll-bar-event #'touchpad-enable--view-mode)
    (advice-remove 'scroll-bar-toolkit-scroll #'touchpad-enable--view-mode)
    (dolist (var '(mwheel-tilt-scroll-p))
      (custom-reevaluate-setting var))))


;;; To enable Enable minor mode by hook instead of advice, patch shown
;;; by following URL should be accepted.
;;; http://lists.gnu.org/archive/html/bug-gnu-emacs/2017-04/msg00700.html

;; (defun touchpad-enable--view-mode ()
;;   "Enable minor mode `touchpad--view-mode' to disable `auto-hscroll-mode'.
;; This is supposed to be called before actual scrolling."
;;   (let ((buffer (window-buffer (mwheel-event-window last-input-event))))
;;     (with-current-buffer buffer
;;       (touchpad--view-mode 1)))) ; Turn on minor-mode.


(defun touchpad-enable--view-mode (func &rest args)
  "Enable minor mode `touchpad--view-mode' to disable `auto-hscroll-mode'.
This is supposed to be adviced before `mwheel-scroll'."
  (let ((buffer (window-buffer (mwheel-event-window last-input-event)))
        (point (point)))
    (when auto-hscroll-mode
      (setq touchpad--auto-hscroll-mode auto-hscroll-mode)) ; 26.1
    (unless touchpad--view-mode ; Switch from off to on.
      (when (fboundp 'mouse-set-secondary-from-primary)
        (mouse-set-secondary-from-primary))
      (when touchpad-restore-point-flag
        (touchpad-set-point point))
      (with-current-buffer buffer
        (touchpad--view-mode 1)))))


(copy-face 'cursor 'touchpad-point-face) ; 'cursor, 'region, 'secondary-selection, 'mode-line
;; (set-face-foreground 'touchpad-point-face "white")


(defun touchpad-point-overlay ()
  "Return an overlay which records the current point in the visiting buffer."
  (let ((overlays (overlays-in (point-min) (point-max)))
        ol)
    (while overlays
      (let ((overlay (car overlays)))
        (if (eq (overlay-get overlay 'face) 'touchpad-point-face)
            (progn (setq ol overlay)
                   (setq overlays nil))
          (setq overlays (cdr overlays)))))
    (unless ol
      ;; create a new overlay.
      ;; (info "(elisp) Overlay Properties")
      (setq ol (make-overlay (point-min) (point-min) nil t t))
      (delete-overlay ol)
      ;; (overlay-put ol 'priority 100)
      (overlay-put ol 'face 'touchpad-point-face))
    ol))


(defun touchpad-set-point (pos)
  "Move `touchpad-point-overlay' to the current point."
  (if (eolp)
      (let ((string (propertize "|" 'face 'touchpad-point-face))) ; "|", " "
        (move-overlay (touchpad-point-overlay) pos pos) ; empty overlay cursor char
        (overlay-put (touchpad-point-overlay) 'after-string string))
    (when (overlay-get (touchpad-point-overlay) 'after-string)
      (overlay-put (touchpad-point-overlay) 'after-string nil)) ; remove cursor char
    (move-overlay (touchpad-point-overlay) pos (1+ pos))))


(defun touchpad-remove-point ()
  "Remove `touchpad-point-overlay' in the visiting buffer."
  (when (overlay-get (touchpad-point-overlay) 'after-string)
    (overlay-put (touchpad-point-overlay) 'after-string nil)) ; remove cursor char
  (delete-overlay (touchpad-point-overlay))) ; remove overlay


(defun touchpad-point ()
  "Return point from `touchpad-point-overlay'."
  (overlay-start (touchpad-point-overlay)))


;;; Following definition is necessary until the patch is accepted by
;;; bug-gnu-emacs.  The code should be located on `mouse.el'.
;;; http://lists.gnu.org/archive/html/bug-gnu-emacs/2017-06/msg00938.html
(unless (fboundp 'mouse-set-secondary-from-primary)
  (defun mouse-set-secondary-from-primary ()
    "Set the secondary selection to text in the region.
When region does not exists, set mouse-secondary-start to the point.
When point is in the secondary selection, do nothing."
    (interactive)
    (cond
     ((region-active-p) ; Create mouse-secondary-overlay from region.
      (delete-overlay mouse-secondary-overlay)
      (move-overlay mouse-secondary-overlay (region-beginning) (region-end)))
     ((member 'secondary-selection ; Do nothing.
              (mapcar (lambda (xxx) (overlay-get xxx 'face))
                      (overlays-at (point)))))
     (t (delete-overlay mouse-secondary-overlay) ; Create mouse-secondary-start from point.
        (push-mark (point))
        (setq mouse-secondary-start (make-marker))
        (move-marker mouse-secondary-start (point))))))


(defun touchpad-disable--view-mode ()
  "Disable minor mode `touchpad--view-mode' to enable `auto-hscroll-mode' back.
Then invoke command that is bound to the original key."
  (interactive)
  (touchpad--view-mode 0) ; Turn off minor-mode.
  (when touchpad-restore-point-flag
    (touchpad-remove-point))
  (call-interactively (key-binding (this-command-keys))))


(defun touchpad-disable--view-mode-1 ()
  "Restore point then call `touchpad-disable--view-mode'."
  (interactive)
  (when touchpad-restore-point-flag
    (goto-char (touchpad-point))
    (touchpad-remove-point))
  (touchpad-disable--view-mode))


(define-minor-mode touchpad--view-mode
  "A minor-mode with `auto-hscroll-mode' off.
This minor mode is used internally."
  :init-value nil
  :lighter " view"
  :keymap (let ((map (make-sparse-keymap)))
            ;; Extend secondary instead of primary by shift click.
            (define-key map [remap mouse-save-then-kill] 'mouse-secondary-save-then-kill)

            ;; Turn off touchpad--view-mode and do what is supposed to do.
            ;; * do not restore point
            (define-key map [remap mouse-set-region] 'touchpad-disable--view-mode)
            ;; (define-key map [remap mouse-drag-region] 'touchpad-disable--view-mode) ; Lisp nesting exceeds ‘max-lisp-eval-depth’
            (define-key map [remap keyboard-quit] 'touchpad-disable--view-mode)
            (define-key map [remap mouse-set-point] 'touchpad-disable--view-mode)
            (define-key map [remap mark-whole-buffer] 'touchpad-disable--view-mode)
            (define-key map [remap mark-page] 'touchpad-disable--view-mode)
            (define-key map [remap mark-paragraph] 'touchpad-disable--view-mode)
            (define-key map [remap mark-word] 'touchpad-disable--view-mode)
            (define-key map [remap goto-char] 'touchpad-disable--view-mode)
            (define-key map [remap goto-line] 'touchpad-disable--view-mode)
            (define-key map [remap move-to-column] 'touchpad-disable--view-mode)
            (define-key map [remap isearch-forward] 'touchpad-disable--view-mode)
            (define-key map [remap isearch-backward] 'touchpad-disable--view-mode)
            ;; (define-key map [remap scroll-up-command] 'touchpad-disable--view-mode)
            ;; (define-key map [remap scroll-down-command] 'touchpad-disable--view-mode)
            ;; (define-key map [remap beginning-of-buffer] 'touchpad-disable--view-mode)
            ;; (define-key map [remap end-of-buffer] 'touchpad-disable--view-mode)
            ;; * restore point
            (define-key map [remap recenter-top-bottom] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap right-char] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap forward-char] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap forward-word] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap forward-sentence] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap forward-paragraph] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap forward-page] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap left-char] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap backward-char] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap backward-word] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap backward-sentence] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap backward-paragraph] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap backward-page] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap move-beginning-of-line] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap beginning-of-visual-line] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap move-end-of-line] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap end-of-visual-line] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap next-line] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap next-error] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap previous-line] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap previous-error] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap beginning-of-defun] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap end-of-defun] 'touchpad-disable--view-mode-1) ; restore point
            ;; * restore point and revise buffer
            (define-key map [remap self-insert-command] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap delete-char] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap kill-word] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap kill-line] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap quoted-insert] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap transpose-chars] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap transpose-words] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap yank] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap toggle-input-method] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap delete-backward-char] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap just-one-space] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap dabbrev-expand] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap mark-sexp] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap delete-indentation] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap helm-command-prefix] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap paredit-backward-slurp-sexp] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap paredit-splice-sexp-killing-backward] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap mark-sexp] 'touchpad-disable--view-mode-1) ; restore point
            ;; * local setup
            (define-key map [remap mew-summary-previous-line] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap mew-summary-next-line] 'touchpad-disable--view-mode-1) ; restore point
            (define-key map [remap skk-insert] 'touchpad-disable--view-mode-1) ; restore point
            map)
  :group 'scrolling

  (if touchpad--view-mode
      (progn
        (setq-local auto-hscroll-mode nil)
        (setq-local cursor-type 'hollow))
    (setq-local auto-hscroll-mode touchpad--auto-hscroll-mode)
    (setq-local cursor-type touchpad--cursor-type)))

(defun touchpad-text-scale-increase (event)
  "Increase the height of the default face in the current buffer by 1 step."
  (interactive "e")
  (save-excursion
    (mouse-set-point event)
    (text-scale-increase 1)))

(defun touchpad-text-scale-decrease (event)
  "Decrease the height of the default face in the current buffer by 1 step."
  (interactive "e")
  (save-excursion
    (mouse-set-point event)
    (text-scale-decrease 1)))

;;;; ChangeLog:

;; 2017-08-07  Tak Kunihiro <tkk <at> misasa.okayama-u.ac.jp>
;;
;; 	touchpad-mode: version 1.0
;;
;; 	* touchpad.el: New package.

(provide 'touchpad)
;;; touchpad.el ends here




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#27932; Package emacs. (Mon, 07 Aug 2017 16:41:02 GMT) Full text and rfc822 format available.

Message #56 received at 27932 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Dani Moncayo <dmoncayo <at> gmail.com>
Cc: 27932 <at> debbugs.gnu.org, rms <at> gnu.org
Subject: Re: bug#27932: 26.0.50; Feature request: prevent scroll commands from
 changing the buffer location of point
Date: Mon, 07 Aug 2017 19:38:16 +0300
> From: Dani Moncayo <dmoncayo <at> gmail.com>
> Date: Mon, 7 Aug 2017 07:54:21 +0200
> Cc: "Richard M. Stallman" <rms <at> gnu.org>, 27932 <at> debbugs.gnu.org
> 
> In short: point movement should trigger auto-scrolling (as now), but
> scrolling should not move point.

I see a possible misunderstanding here: the way scrolling works in
Emacs, it moves point and then lets the display engine scroll the text
in the window to make point visible.  So the two use cases you try to
differentiate are actually indistinguishable as far as the display
engine is concerned.  For example, invoking goto-char invokes the same
display code as scrolling commands, which is why scroll-conservatively
is obeyed even by goto-char (as many users expect).




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#27932; Package emacs. (Mon, 07 Aug 2017 21:10:02 GMT) Full text and rfc822 format available.

Message #59 received at 27932 <at> debbugs.gnu.org (full text, mbox):

From: Dani Moncayo <dmoncayo <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 27932 <at> debbugs.gnu.org, "Richard M. Stallman" <rms <at> gnu.org>
Subject: Re: bug#27932: 26.0.50; Feature request: prevent scroll commands from
 changing the buffer location of point
Date: Mon, 7 Aug 2017 23:09:36 +0200
>> In short: point movement should trigger auto-scrolling (as now), but
>> scrolling should not move point.
>
> I see a possible misunderstanding here: the way scrolling works in
> Emacs, it moves point and then lets the display engine scroll the text
> in the window to make point visible.  So the two use cases you try to
> differentiate are actually indistinguishable as far as the display
> engine is concerned.  For example, invoking goto-char invokes the same
> display code as scrolling commands, which is why scroll-conservatively
> is obeyed even by goto-char (as many users expect).

Ok I think I understand.

Then, the proposed feature would require a rethink of that approach,
because user-requested scrolling (C-v, M-v, mouse-wheel) would _not_
be driven by point movement, obviously.

-- 
Dani Moncayo




This bug report was last modified 90 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.