GNU bug report logs - #22873
25.1.50; Feature Request -- Multiple Cursors (built-in support)

Previous Next

Package: emacs;

Reported by: Keith David Bershatsky <esq <at> lawlist.com>

Date: Tue, 1 Mar 2016 18:46:01 UTC

Severity: wishlist

Found in version 25.1.50

To reply to this bug, email your comments to 22873 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#22873; Package emacs. (Tue, 01 Mar 2016 18:46:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Keith David Bershatsky <esq <at> lawlist.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Tue, 01 Mar 2016 18:46:02 GMT) Full text and rfc822 format available.

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

From: Keith David Bershatsky <esq <at> lawlist.com>
To: bug-gnu-emacs <at> gnu.org
Subject: 25.1.50; Feature Request -- Multiple Cursors (built-in support)
Date: Tue, 01 Mar 2016 10:44:58 -0800
[Message part 1 (text/plain, inline)]
As a feature request, it would be appreciated if the Emacs development team could please consider adding built-in support for multiple cursors similar to the Lisp library that Magnar Sveen has written:  https://github.com/magnars

[Out of the box, Emacs does not presently support a left vertical bar fake cursor overlay.]

The multiple cursors API should please be made available to the user so that fake cursors of any style can be drawn anywhere on the visible window.  [Available styles include those defined in the variable `cursor-type'.]

The API available to the user should support standard points for positions, instead of x/y/vpos/hpos.  In other words, the API should make it easy for the user to specifying a list of points -- e.g., '(5 6 7 8 9 10).  In that scenario, fake cursors would be drawn at positions 5, 6, 7, 8, 9 and 10.  Perhaps a cons cell with the `cursor-type' for each specified point would be appropriate -- that way a user would not be limited to the buffer-local or default cursor style for all fake cursors.

This feature request has the added benefit that the user can create a vertical line the entire length of the screen by using multiple fake bar cursors in addition to a stretch space glyph and an XPM image that is thin (e.g., one pixel wide) with a pixel height equal to the line height at any location where no character exists -- e.g., overlays using the 'after-string property.  An example would be the fill-column-indicator library written by Alp Aker:  https://github.com/alpaker/Fill-Column-Indicator  In the context of the fill-column-indicator example, a user can draw a vertical line that extends through the left side of each character to form a solid line the entire length of the window from top to bottom.

In my own personal setup, I would be drawing a solid vertical line that tracks the cursor position -- the line would run through the left side of any character along that resides on vertical column.

The following draft proof concept patch contains a variety of things including a sample of this particular feature request for multiple cursors.  The example has been tested on Emacs master branch for OSX and Windows operating systems.  On OSX the fake cursors draw immediately, but on Windows it is necessary to press any key after calling `multiple-cursors-test' for the fake cursors to appear.  The fake cursors are designed to disappear during the next command loop.  The internal function `move_it_to' provides for a conveniently quick method to convert PT to the necessary x/y/vpos/hpos.

NOTE:  `posn-at-point` is painfully slow to obtain x/y/vpos/hpos -- so we certainly want to avoid using that function when converting the list of PT for fake cursors each command loop.

The following test function called `multiple-cursors-test` works with the proof concept draft patch attached below, which admittedly needs a lot more work.  I tested using the bar `cursor-type'.

(defun multiple-cursors-test (&optional list)
"Draw fake cursors at all POS defined in the `multiple-cursor-list'.
The list contains integers representing the various positions.
The default list is for positions 5, 6, 7, 8, 9 and 10."
(interactive)
  (setq cursor-type 'bar)
  (setq multiple-cursors-list (if list list (list 5 6 7 8 9 10))))

(global-set-key [f1] 'multiple-cursors-test)

[multiple_cursors.diff (application/diff, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#22873; Package emacs. (Thu, 03 Mar 2016 06:31:02 GMT) Full text and rfc822 format available.

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

From: John Wiegley <jwiegley <at> gmail.com>
To: Keith David Bershatsky <esq <at> lawlist.com>
Cc: 22873 <at> debbugs.gnu.org, emacs-devel <at> gnu.org
Subject: Can we support multiple Cursors?
Date: Wed, 02 Mar 2016 22:30:38 -0800
>>>>> Keith David Bershatsky <esq <at> lawlist.com> writes:

> As a feature request, it would be appreciated if the Emacs development team
> could please consider adding built-in support for multiple cursors similar
> to the Lisp library that Magnar Sveen has written:
> https://github.com/magnars

I like this request, but my spidey sense tells me that implementing this at
the C level will introduce a huge number of ramifications that may not be
immediately apparent. For example, (point) conceptually goes from being one
position, to many. The implications of that are huge, which will mean
introducing special cases to avoid them, which then has its own implications,
etc.

I'd like to see discussion on this idea in emacs-devel, so I'm copying there.
This is something that deserves a larger audience than just those following
bug #22873. Is multiple-cursor editing a realistic possibility? And is it
worth the complexity?

-- 
John Wiegley                  GPG fingerprint = 4710 CF98 AF9B 327B B80F
http://newartisans.com                          60E1 46C4 BD1A 7AC1 4BA2




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#22873; Package emacs. (Thu, 03 Mar 2016 06:55:01 GMT) Full text and rfc822 format available.

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

From: Marcin Borkowski <mbork <at> mbork.pl>
To: John Wiegley <johnw <at> gnu.org>
Cc: Keith David Bershatsky <esq <at> lawlist.com>, 22873 <at> debbugs.gnu.org,
 emacs-devel <at> gnu.org
Subject: Re: Can we support multiple Cursors?
Date: Thu, 03 Mar 2016 07:54:17 +0100
On 2016-03-03, at 07:30, John Wiegley <jwiegley <at> gmail.com> wrote:

>>>>>> Keith David Bershatsky <esq <at> lawlist.com> writes:
>
>> As a feature request, it would be appreciated if the Emacs development team
>> could please consider adding built-in support for multiple cursors similar
>> to the Lisp library that Magnar Sveen has written:
>> https://github.com/magnars
>
> I like this request, but my spidey sense tells me that implementing this at
> the C level will introduce a huge number of ramifications that may not be
> immediately apparent. For example, (point) conceptually goes from being one
> position, to many. The implications of that are huge, which will mean
> introducing special cases to avoid them, which then has its own implications,
> etc.
>
> I'd like to see discussion on this idea in emacs-devel, so I'm copying there.
> This is something that deserves a larger audience than just those following
> bug #22873. Is multiple-cursor editing a realistic possibility? And is it
> worth the complexity?

What would be the added value of having that built-in vs. having it on
M?elpa?

Best,

-- 
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Faculty of Mathematics and Computer Science
Adam Mickiewicz University




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#22873; Package emacs. (Thu, 03 Mar 2016 11:22:02 GMT) Full text and rfc822 format available.

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

From: Richard Stallman <rms <at> gnu.org>
To: Marcin Borkowski <mbork <at> mbork.pl>
Cc: esq <at> lawlist.com, johnw <at> gnu.org, 22873 <at> debbugs.gnu.org, emacs-devel <at> gnu.org
Subject: Re: bug#22873: Can we support multiple Cursors?
Date: Thu, 03 Mar 2016 06:20:58 -0500
[[[ 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. ]]]

  > What would be the added value of having that built-in vs. having it on
  > M?elpa?

Melpa and ELPA are totally different.

ELPA is effectively an extension of Emacs, and we refer users there.

Melpa is someone else's repository, which we cannot treat as part of
Emacs.  We do not steer users there.

-- 
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#22873; Package emacs. (Thu, 03 Mar 2016 15:07:02 GMT) Full text and rfc822 format available.

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

From: Marcin Borkowski <mbork <at> mbork.pl>
To: rms <at> gnu.org
Cc: esq <at> lawlist.com, johnw <at> gnu.org, 22873 <at> debbugs.gnu.org, emacs-devel <at> gnu.org
Subject: Re: bug#22873: Can we support multiple Cursors?
Date: Thu, 03 Mar 2016 16:05:52 +0100
On 2016-03-03, at 12:20, Richard Stallman <rms <at> gnu.org> wrote:

> [[[ 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. ]]]
>
>   > What would be the added value of having that built-in vs. having it on
>   > M?elpa?
>
> Melpa and ELPA are totally different.
>
> ELPA is effectively an extension of Emacs, and we refer users there.
>
> Melpa is someone else's repository, which we cannot treat as part of
> Emacs.  We do not steer users there.

I understand all this.  (In fact, I wanted to write Elpa, only to
discover - to my surprise - that Magnar's multiple-cursors package is
actually on Melpa.  It is GPL'd, however.)

Still, I think that trying to implement that in core would be duplicated
effort, and the feature does not seem essential (it is roughly
equivalent to keyboard macros, though admittedly way cooler).  If
anything, I'd check whether it can be put on Elpa.

-- 
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Faculty of Mathematics and Computer Science
Adam Mickiewicz University




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#22873; Package emacs. (Fri, 04 Mar 2016 09:20:01 GMT) Full text and rfc822 format available.

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

From: Richard Stallman <rms <at> gnu.org>
To: Marcin Borkowski <mbork <at> mbork.pl>
Cc: esq <at> lawlist.com, johnw <at> gnu.org, 22873 <at> debbugs.gnu.org, emacs-devel <at> gnu.org
Subject: Re: bug#22873: Can we support multiple Cursors?
Date: Fri, 04 Mar 2016 04:19:29 -0500
[[[ 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. ]]]

  > I understand all this.  (In fact, I wanted to write Elpa, only to
  > discover - to my surprise - that Magnar's multiple-cursors package is
  > actually on Melpa.  It is GPL'd, however.)

Would he / can he contribute it so we can put it in ELPA?

-- 
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#22873; Package emacs. (Fri, 04 Mar 2016 23:18:01 GMT) Full text and rfc822 format available.

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

From: Keith David Bershatsky <esq <at> lawlist.com>
To: Marcin Borkowski <mbork <at> mbork.pl>
Cc: John Wiegley <jwiegley <at> gmail.com>, 22873 <at> debbugs.gnu.org,
 Richard Stallman <rms <at> gnu.org>
Subject: Re: bug#22873: Can we support multiple Cursors?
Date: Fri, 04 Mar 2016 15:16:56 -0800
I see this feature request as having two (2) distinct, yet related components.  The fake cursors being the first component that will operate similar to overlays, and are thus fairly innocuous as they won't have any real affect on where point is located after redisplay finishes.  The second component, however, is the functionality that can be found in Magnar Sveen's library and also is present in a popular commercial editor known as Sublime Text.

I enjoy using the multiple cursors library written by Magnar Sveen, but often find myself taking advantage of the wait times to pour myself a cup of coffee while making edits with a few hundred fake cursors in a large buffer.  E.g., I will type the word I want inserted or tap the arrow key a few times in a particular direction and then walk away from the computer or surf the web while Emacs does its thing.  I often have to use `M-x replace-string` when dealing with large numbers of edits instead of using my preferred choice of multiple cursors.  Admittedly, I am using a slightly older customized version of Mr. Sveen's library -- but I don't think the basic functionality has changed all that much since I first started using it.

I am not a programmer by trade, but I assume there could be some significant speed increases by having multiple cursor abilities baked into the C code base of the Emacs internals.

I don't think (based on my limited programming knowledge) that all of the cursor-types are presently available as overlays.  I need the left bar cursor so that I can draw my solid vertical line that tracks the cursor position, and so that is what motivated me to write a sample draft patch to the C internals.  My draft is progressing nicely, but it is slow to perfect because I am learning a few of the basics to the C language as I go.  I'll post to #22873 a revised draft of the first component (i.e., just fake cursors) in the next few days depending upon how many road blocks I encounter.  I've set up a simple cache of x/y/hpos/vpos so that recalculation is not necessary when the list of fake cursors doesn't change -- cursors are redrawn more than once per command loop depending upon what happens, e.g., with the mouse, etc.  And a user may not wish to change the positions of fake cursors every command loop, so the cache is helpful.

It may be a very long time, however, before I have enough basic skills to be able to implement some of the functionality of the second component.  I understand the implementation of feature 22873 is only a discussion at this point in time.  The beauty of Emacs, however, is that it's open source and I can make modifications to a custom build for my in-house use.  :)

Keith

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

At Thu, 03 Mar 2016 07:54:17 +0100,
Marcin Borkowski wrote:
> 
> 
> * * *
> 
> What would be the added value of having that built-in vs. having it on
> M?elpa?
> 
> Best,
> 
> -- 
> Marcin Borkowski




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#22873; Package emacs. (Sat, 05 Mar 2016 07:01:01 GMT) Full text and rfc822 format available.

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

From: Marcin Borkowski <mbork <at> mbork.pl>
To: Keith David Bershatsky <esq <at> lawlist.com>
Cc: John Wiegley <jwiegley <at> gmail.com>, 22873 <at> debbugs.gnu.org,
 Richard Stallman <rms <at> gnu.org>
Subject: Re: bug#22873: Can we support multiple Cursors?
Date: Sat, 05 Mar 2016 07:59:52 +0100
On 2016-03-05, at 00:16, Keith David Bershatsky <esq <at> lawlist.com> wrote:

> I enjoy using the multiple cursors library written by Magnar Sveen,
> but often find myself taking advantage of the wait times to pour
> myself a cup of coffee while making edits with a few hundred fake
> cursors in a large buffer.  E.g., I will type the word I want inserted
> or tap the arrow key a few times in a particular direction and then
> walk away from the computer or surf the web while Emacs does its
> thing.  I often have to use `M-x replace-string` when dealing with
> large numbers of edits instead of using my preferred choice of
> multiple cursors.  Admittedly, I am using a slightly older customized
> version of Mr. Sveen's library -- but I don't think the basic
> functionality has changed all that much since I first started using
> it.

Out of curiosity: did you try iedit?  How does it compare wrt speed in
such extreme cases?  (If it's applicable at all, that is - it's way
simpler than multiple-cursors, of course.)

> Keith

Best,

-- 
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Faculty of Mathematics and Computer Science
Adam Mickiewicz University




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#22873; Package emacs. (Wed, 09 Mar 2016 06:28:02 GMT) Full text and rfc822 format available.

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

From: Keith David Bershatsky <esq <at> lawlist.com>
To: Marcin Borkowski <mbork <at> mbork.pl>, John Wiegley <jwiegley <at> gmail.com>,
 Richard Stallman <rms <at> gnu.org>
Cc: 22873 <at> debbugs.gnu.org
Subject: Re: bug#22873: Can we support multiple Cursors?
Date: Tue, 08 Mar 2016 22:27:02 -0800
[Message part 1 (text/plain, inline)]
The second draft of the proposed feature for multiple fake cursors is attached.  For the record, I'm not a programmer -- just a hobbyist -- and the draft patch is not meant to be a proposed official patch -- it is just a working proof concept.  The patch contains a few extra things that I use for debugging and also for drawing my solid vertical line that tracks the cursor position.  It has been tested to some extent on Emacs built for OSX 10.6.8 and Windows XP (SP-3).  Different colors for each fake cursor have already been implemented on Emacs for OSX, but I haven't yet looked into how to accomplish that objective on Emacs for Windows.  The draft concept patch is for the master branch as of March 8, 2016 bearing commit "e0400b72a24d67b53f71c8b97915cae599e36c37".  After applying the patch, the new feature can be tested as follows:

(defun mc-test (&optional list)
"Draw fake cursors at all POS defined in the `mc-list'."
(interactive)
  (setq mc-list '(
    (3 "hbar" [1.0 0.0 0.0])
    (4 "bar" [0.0 1.0 0.0])
    (5 "box" [0.0 0.0 1.0])
    (6 "hollow" [1.0 1.0 1.0])
    (7 ("hbar" 3) [1.0 0.0 1.0])
    (8 ("bar" 3) [0.0 1.0 1.0]))))

(global-set-key [f1] 'mc-test)

To remove the cursors or change the cursors, just modify the buffer-local variable `mc-list' -- e.g., `(setq mc-list nil)` removes them all.  The colors on OSX are the standard RGB color vector.

Thank you, Marcin, for the referral to the ideit feature.  I will certainly try that feature out in the next few days, but have been buried in life's daily activities and also in acquiring the necessary skills to implement the fake cursors feature.

It sure would be great if a real programmer (instead of just a hobbyist like myself) could take this feature to the next level.  If the Windows setup is anything similar to OSX, implementing colors should not be that difficult to achieve (at least I hope that is the case).

I would like this feature to be similar to the original cursor such that a variable like `cursor-in-non-selected-windows' can be used to make the fake cursors displayed in only the selected window or in all windows where those points are visible.  At the present time, I've set it up so that only the selected window receives the fake cursors (as that is my personal preference).

Thank you for taking an interest in this potential new feature,

Keith

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

At Sat, 05 Mar 2016 07:59:52 +0100,
Marcin Borkowski wrote:
> 
> * * *
> 
> Out of curiosity: did you try iedit?  How does it compare wrt speed in
> such extreme cases?  (If it's applicable at all, that is - it's way
> simpler than multiple-cursors, of course.)

[multiple_cursors.diff (application/diff, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#22873; Package emacs. (Wed, 09 Mar 2016 16:04:01 GMT) Full text and rfc822 format available.

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: Keith David Bershatsky <esq <at> lawlist.com>
Cc: jwiegley <at> gmail.com, mbork <at> mbork.pl, rms <at> gnu.org, 22873 <at> debbugs.gnu.org
Subject: Re: bug#22873: Can we support multiple Cursors?
Date: Wed, 09 Mar 2016 18:03:25 +0200
> Date: Tue, 08 Mar 2016 22:27:02 -0800
> From: Keith David Bershatsky <esq <at> lawlist.com>
> Cc: 22873 <at> debbugs.gnu.org
> 
> The second draft of the proposed feature for multiple fake cursors is attached.  For the record, I'm not a programmer -- just a hobbyist -- and the draft patch is not meant to be a proposed official patch -- it is just a working proof concept.  The patch contains a few extra things that I use for debugging and also for drawing my solid vertical line that tracks the cursor position.  It has been tested to some extent on Emacs built for OSX 10.6.8 and Windows XP (SP-3).  Different colors for each fake cursor have already been implemented on Emacs for OSX, but I haven't yet looked into how to accomplish that objective on Emacs for Windows.  The draft concept patch is for the master branch as of March 8, 2016 bearing commit "e0400b72a24d67b53f71c8b97915cae599e36c37".  After applying the patch, the new feature can be tested as follows:

Looks like quite a few of the changes in the patch are not really
related to multiple cursors.  Did you produce diffs for all of your
other local changes?

> diff --git a/src/buffer.h b/src/buffer.h
> index 5783bfb..01c3755 100644
> --- a/src/buffer.h
> +++ b/src/buffer.h
> @@ -643,6 +643,15 @@ struct buffer
>       cache are enabled.  See search.c, indent.c and bidi.c for details.  */
>    Lisp_Object cache_long_scans_;
>  
> +  /* The name of the hook.  */
> +  Lisp_Object window_start_end_hook_;
> +
> +  /* The name of list.  */
> +  Lisp_Object posn_list_;
> +
> +  /* The name of list used by multiple cursors for next redisplay.  */
> +  Lisp_Object mc_list_;
> +
>    /* If the width run cache is enabled, this table contains the
>       character widths width_run_cache (see above) assumes.  When we
>       do a thorough redisplay, we compare this against the buffer's
> @@ -885,6 +894,21 @@ struct buffer
>     buffer.  (Some setters that are private to a single .c file are
>     defined as static in those files.)  */
>  INLINE void
> +bset_window_start_end_hook (struct buffer *b, Lisp_Object val)
> +{
> +  b->window_start_end_hook_ = val;
> +}

The above inline function and the corresponding member of struct
buffer seems unrelated.

> diff --git a/src/keyboard.c b/src/keyboard.c
> index 4e1ac15..329cba0 100644
> --- a/src/keyboard.c
> +++ b/src/keyboard.c
> @@ -1244,6 +1244,15 @@ static int read_key_sequence (Lisp_Object *, int, Lisp_Object,
>                                bool, bool, bool, bool);
>  static void adjust_point_for_property (ptrdiff_t, bool);
>  
> +static void
> +set_window_start_end_hook (void)
> +{
> +  Lisp_Object window = (selected_window);
> +  struct window *w = decode_live_window (window);
> +  w->window_start_end_hook_force = true;
> +  w->window_start_end_hook_pending = true;
> +}
> +
>  Lisp_Object
>  command_loop_1 (void)
>  {
> @@ -1269,6 +1278,8 @@ command_loop_1 (void)
>        if (!NILP (Vpost_command_hook) && !NILP (Vrun_hooks))
>  	safe_run_hooks (Qpost_command_hook);
>  
> +      set_window_start_end_hook ();
> +
>        /* If displaying a message, resize the echo area window to fit
>  	 that message's size exactly.  */
>        if (!NILP (echo_area_buffer[0]))
> @@ -1485,6 +1496,8 @@ command_loop_1 (void)
>  
>        safe_run_hooks (Qpost_command_hook);
>  
> +      set_window_start_end_hook ();
> +
>        /* If displaying a message, resize the echo area window to fit
>  	 that message's size exactly.  */
>        if (!NILP (echo_area_buffer[0]))

Likewise.

> diff --git a/src/xdisp.c b/src/xdisp.c
> index 5b96144..102ac23 100644
> --- a/src/xdisp.c
> +++ b/src/xdisp.c
> @@ -13414,6 +13414,93 @@ do { if (! polling_stopped_here) stop_polling ();	\
>  do { if (polling_stopped_here) start_polling ();	\
>         polling_stopped_here = false; } while (false)
>  
> +static void
> +run_window_start_end_hook (Lisp_Object window, struct text_pos startp, EMACS_INT posint, struct it it, char *string, bool force)
> +{

Likewise.

> +    case 'w':
> +      {
> +  ptrdiff_t window_start = marker_position (w->start);
> +  pint2str (decode_mode_spec_buf, width, window_start);
> +  return decode_mode_spec_buf;
> +      }
> +
> +    case 'W':
> +      {
> +  ptrdiff_t window_end = BUF_Z (b) - w->window_end_pos;
> +  pint2str (decode_mode_spec_buf, width, window_end);
> +  return decode_mode_spec_buf;
> +      }
> +

Likewise.

> +static const char *
> +internal_line_number_at_position (struct window *w, register int c, int field_width, Lisp_Object *string)
> +{

Likewise.

> +DEFUN ("line-number-at-position", Fline_number_at_position, Sline_number_at_position, 1, 2, 0,
> +       doc: /* Return line number at position.  */)
> +  (Lisp_Object window, Lisp_Object pos)
> +{

Likewise.

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#22873; Package emacs. (Wed, 09 Mar 2016 18:31:02 GMT) Full text and rfc822 format available.

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

From: Keith David Bershatsky <esq <at> lawlist.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: jwiegley <at> gmail.com, mbork <at> mbork.pl, rms <at> gnu.org, 22873 <at> debbugs.gnu.org
Subject: Re: bug#22873: Can we support multiple Cursors?
Date: Wed, 09 Mar 2016 10:30:48 -0800
Thank you, Eli, for taking a look at the second draft patch.  I agree that the unrelated features need to be removed so that we can focus specifically on feature 22873.

I would like some of my unrelated custom features to be available in-house while I am implementing fake cursors, but do not yet know how to easily separate them when creating a patch.  Absent that git knowledge, I will be manually cutting out those unrelated features in the various source code files and then creating a new diff that is 22873 specific.

The next phase will be for me to track down how to convert color vector RGB (three float numbers) to something that Emacs for Windows can recognize.  Different colors for each fake cursor is already working in Emacs for OSX 10.6.8.  When that next phase is implemented, I will ensure that the third draft patch is exclusively feature 22873 specific.

Keith

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

At Wed, 09 Mar 2016 18:03:25 +0200,
Eli Zaretskii wrote:
> 
> * * *
> 
> Looks like quite a few of the changes in the patch are not really
> related to multiple cursors.  Did you produce diffs for all of your
> other local changes?
> 
> * * *




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#22873; Package emacs. (Fri, 11 Mar 2016 07:19:02 GMT) Full text and rfc822 format available.

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

From: Keith David Bershatsky <esq <at> lawlist.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: jwiegley <at> gmail.com, mbork <at> mbork.pl, rms <at> gnu.org, 22873 <at> debbugs.gnu.org
Subject: Re: bug#22873: Can we support multiple Cursors?
Date: Thu, 10 Mar 2016 23:18:41 -0800
[Message part 1 (text/plain, inline)]
Attached is the third draft, multiple_cursors_003.diff, which applies to the master branch as of commit "ea626c72e590aa7a45fd26df42240854e4225cef" on March 10, 2015.

Different colors for each fake cursor are now supported on Emacs for Windows (XP SP-3) and OSX (10.6.8).

The next phase will be to separate the custom feature called `window-start-end-hook` from this new fake cursor feature 22873.  Currently, I am using the existence of a definitive window-start and window-end derived from the `window-start-end-hook` as a guide and condition precedent to placing the fake cursors.  Given that fake cursors are placed late in the stage of the redisplay process, I suspect that I can rely on other methods to extract the correct window-start and window-end.

The other unrelated features that were present in my first couple of drafts have been removed from this third draft.  The fake cursors feature works as follows -- to erase everything or change anything, just modify the `mc-list':

(defun mc-test (&optional list)
"Draw fake cursors at all POS defined in the `mc-list'.
Color vector is LSL (The Linden Scripting Language), rather than standard RGB.
`nsterm.m' uses `NSColor', which works well with LSL.  `w32term.c' uses
`PALETTERGB' or `RGB', and the conversion from LSL is done internally by
multiplying each element of the LSL color vector by 255."
(interactive)
  (setq mc-list '(
    (3 "hbar" [1.0 0.0 0.0])
    (4 "bar" [0.0 1.0 0.0])
    (5 "box" [0.0 0.0 1.0])
    (6 "hollow" [0.8 0.4 0.2])
    (7 ("hbar" 3) [1.0 0.0 1.0])
    (8 ("bar" 3) [0.0 1.0 1.0]))))

(global-set-key [f1] 'mc-test)

[multiple_cursors_003.diff (application/diff, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#22873; Package emacs. (Mon, 14 Mar 2016 18:36:02 GMT) Full text and rfc822 format available.

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

From: Keith David Bershatsky <esq <at> lawlist.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: John Wiegley <jwiegley <at> gmail.com>, Marcin Borkowski <mbork <at> mbork.pl>,
 22873 <at> debbugs.gnu.org, Richard Stallman <rms <at> gnu.org>
Subject: Re: bug#22873: Can we support multiple Cursors?
Date: Mon, 14 Mar 2016 11:35:18 -0700
Help, please:  :)

I reached a roadblock on Emacs for Windows and I haven't the slightest idea why my cached list of multiple cursors is being converted into a value `<optimized out>` sporadically when holding down the arrow key and moving the active cursor repetitively through plain text in a fundamental-mode buffer.  Emacs crashes in that circumstance.  The cache is a Lisp_Object pointer defined in `window.h` named mc_cache (aka `w->mc_cache`).  The value of `w->mc_cache` is:

  '((
    (3 hbar [1.0 0.0 0.0])
    (4 bar [0.0 1.0 0.0])
    (5 box [0.0 0.0 1.0])
    (6 hollow [0.8 0.4 0.2])
    (7 (hbar 3) [1.0 0.0 1.0])
    (8 (bar 3) [0.0 1.0 1.0]))
   (
    ((3 hbar [1.0 0.0 0.0]) (22 20 2 0))
    ((4 bar [0.0 1.0 0.0]) (33 20 3 0))
    ((5 box [0.0 0.0 1.0]) (44 20 4 0))
    ((6 hollow [0.8 0.4 0.2]) (55 20 5 0))
    ((7 (hbar 3) [1.0 0.0 1.0]) (66 20 6 0))
    ((8 (bar 3) [0.0 1.0 1.0]) (77 20 7 0))
    ))

The "for" loop looks like this and Emacs crashes when reading the line containing "cursor_spec_list = XCAR (XCAR (vlist))".  `cursor_spec_list` and `vlist` are both Lisp_Object:

   for (vlist = XCAR (XCDR (w->mc_cache));
        CONSP (vlist);
        vlist = XCDR (vlist))
     {
       cursor_spec_list = XCAR (XCAR (vlist));
       ***

Here is the gdb backtrace:

Administrator <at> lawlistf0aa /c/docume~1/administrator/desktop/emacs
$ gdb /c/docume~1/administrator/desktop/trunk/bin/emacs.exe
GNU gdb (GDB) 7.6.1
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from c:\docume~1\administrator\desktop\trunk\bin\emacs.exe...don
e.
(gdb) run
Starting program: c:/docume~1/administrator/desktop/trunk/bin/emacs.exe
[New Thread 1784.0x360]
[New Thread 1784.0x310]
[New Thread 1784.0x75c]
[New Thread 1784.0x1e8]
[New Thread 1784.0x3ec]

Program received signal SIGSEGV, Segmentation fault.
mc_calc (w=w <at> entry=0x55d24b8) at xdisp.c:29025
29025             cursor_spec_list = XCAR (XCAR (vlist));
(gdb) print vlist
$1 = -1006130013
(gdb) print cursor_spec_list
$2 = <optimized out>
(gdb) backtrace
#0  mc_calc (w=w <at> entry=0x55d24b8) at xdisp.c:29025
#1  0x010448db in display_and_set_cursor (w=w <at> entry=0x55d24b8,
    on=on <at> entry=true, hpos=57, vpos=17, x=627, y=345) at xdisp.c:29286
#2  0x011665e0 in x_update_window_end (w=0x55d24b8, cursor_on_p=true,
    mouse_face_overwritten_p=false) at w32term.c:686
#3  0x01005c13 in update_window (w=w <at> entry=0x55d24b8,
    force_p=<optimized out>, force_p <at> entry=true) at dispnew.c:3539
#4  0x01006e72 in update_window_tree (w=w <at> entry=0x55d24b8,
    force_p=force_p <at> entry=true) at dispnew.c:3217
#5  0x01009450 in update_frame (f=f <at> entry=0x55d2350, force_p=<optimized out>,
    force_p <at> entry=false, inhibit_hairy_id_p=inhibit_hairy_id_p <at> entry=false)
    at dispnew.c:3106
#6  0x0103ab20 in redisplay_internal () at xdisp.c:14142
#7  0x0103b9d8 in redisplay () at xdisp.c:13171
#8  0x010a3aed in read_char (commandflag=commandflag <at> entry=1,
    map=map <at> entry=136502483, prev_event=0,
    used_mouse_menu=used_mouse_menu <at> entry=0x82f8db,
    end_time=end_time <at> entry=0x0) at keyboard.c:2483
#9  0x010a6006 in read_key_sequence (keybuf=keybuf <at> entry=0x82f978,
    prompt=prompt <at> entry=0, dont_downcase_last=dont_downcase_last <at> entry=false,
    can_return_switch_frame=can_return_switch_frame <at> entry=true,
    fix_current_buffer=fix_current_buffer <at> entry=true,
    prevent_redisplay=prevent_redisplay <at> entry=false, bufsize=30)
    at keyboard.c:9066
#10 0x010a786f in command_loop_1 () at keyboard.c:1369
#11 0x010ff9e7 in internal_condition_case (
    bfun=bfun <at> entry=0x10a7697 <command_loop_1>,
    handlers=handlers <at> entry=12256, hfun=hfun <at> entry=0x109f644 <cmd_error>)
    at eval.c:1309
#12 0x0109b233 in command_loop_2 (ignore=0) at keyboard.c:1100
#13 0x010ff9ab in internal_catch (tag=tag <at> entry=32480,
    func=func <at> entry=0x109b214 <command_loop_2>, arg=arg <at> entry=0)
    at eval.c:1074
#14 0x0109b1f5 in command_loop () at keyboard.c:1079
#15 0x0109f2fc in recursive_edit_1 () at keyboard.c:685
#16 0x0109f58c in Frecursive_edit () at keyboard.c:756
#17 0x011b76fa in main (argc=<optimized out>, argv=0xa428b0) at emacs.c:1617
(gdb)

Thanks,

Keith




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#22873; Package emacs. (Mon, 14 Mar 2016 18:51:01 GMT) Full text and rfc822 format available.

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: Keith David Bershatsky <esq <at> lawlist.com>
Cc: jwiegley <at> gmail.com, mbork <at> mbork.pl, 22873 <at> debbugs.gnu.org, rms <at> gnu.org
Subject: Re: bug#22873: Can we support multiple Cursors?
Date: Mon, 14 Mar 2016 20:49:17 +0200
> Date:  Mon, 14 Mar 2016 11:35:18 -0700
> From:  Keith David Bershatsky <esq <at> lawlist.com>
> Cc:  22873 <at> debbugs.gnu.org,John Wiegley <jwiegley <at> gmail.com>,Marcin Borkowski <mbork <at> mbork.pl>,Richard Stallman <rms <at> gnu.org>
> 
> I reached a roadblock on Emacs for Windows and I haven't the slightest idea why my cached list of multiple cursors is being converted into a value `<optimized out>` sporadically when holding down the arrow key and moving the active cursor repetitively through plain text in a fundamental-mode buffer.  Emacs crashes in that circumstance.  The cache is a Lisp_Object pointer defined in `window.h` named mc_cache (aka `w->mc_cache`).  The value of `w->mc_cache` is:
> 
>   '((
>     (3 hbar [1.0 0.0 0.0])
>     (4 bar [0.0 1.0 0.0])
>     (5 box [0.0 0.0 1.0])
>     (6 hollow [0.8 0.4 0.2])
>     (7 (hbar 3) [1.0 0.0 1.0])
>     (8 (bar 3) [0.0 1.0 1.0]))
>    (
>     ((3 hbar [1.0 0.0 0.0]) (22 20 2 0))
>     ((4 bar [0.0 1.0 0.0]) (33 20 3 0))
>     ((5 box [0.0 0.0 1.0]) (44 20 4 0))
>     ((6 hollow [0.8 0.4 0.2]) (55 20 5 0))
>     ((7 (hbar 3) [1.0 0.0 1.0]) (66 20 6 0))
>     ((8 (bar 3) [0.0 1.0 1.0]) (77 20 7 0))
>     ))
> 
> The "for" loop looks like this and Emacs crashes when reading the line containing "cursor_spec_list = XCAR (XCAR (vlist))".  `cursor_spec_list` and `vlist` are both Lisp_Object:
> 
>    for (vlist = XCAR (XCDR (w->mc_cache));
>         CONSP (vlist);
>         vlist = XCDR (vlist))
>      {
>        cursor_spec_list = XCAR (XCAR (vlist));
>        ***

You maintain a Lisp object in a window object, but did you make sure
it's declared before the place in 'struct window' where we have this
comment:

    /* No Lisp data may follow below this point without changing
       mark_object in alloc.c.  The member current_matrix must be the
       first non-Lisp member.  */

If mc_cache is beyond this point, chances are it's being GC'ed behind
your back.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#22873; Package emacs. (Mon, 14 Mar 2016 22:40:02 GMT) Full text and rfc822 format available.

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

From: Keith David Bershatsky <esq <at> lawlist.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: John Wiegley <jwiegley <at> gmail.com>, Marcin Borkowski <mbork <at> mbork.pl>,
 22873 <at> debbugs.gnu.org, Richard Stallman <rms <at> gnu.org>
Subject: Re: bug#22873: Can we support multiple Cursors?
Date: Mon, 14 Mar 2016 15:38:55 -0700
[Message part 1 (text/plain, inline)]
Thank you, Eli, for resolving the issue with the `mc_cache` being GC'ed behind my back.  As per your suggestion, I moved the Lisp_Object definition of `mc_cache` in `window.h` to above the section beginning with the comment "No Lisp data may follow below this point . . . ."  I also moved the other mc-realted `int` and `bool_bf` definitions into the section beginning with "#ifdef HAVE_WINDOW_SYSTEM".

The enclosed `multiple_cursors_004.diff` applies to Emacs master branch from last night (March 13, 2016) bearing commit "181e92c4e060a7ce4740b561375f9ec9f473f144".

Multiple fake cursors now have preliminary support on all three (3) window systems -- i.e., X (--with-x --with-x-toolkit=no), Windows (XP SP-3) and OSX (10.6.8).

I will need to track down why (on Emacs for Windows) a fake cursor appearing as FILLED_BOX_CURSOR sometimes takes on the background color of the real active cursor.  This seems to depend upon whether I start with Emacs -Q versus a full configuration, so perhaps it won't be that difficult to track down.

I haven't done any calculations regarding the time needed to run `mc_x_y_hpos_vpos` on each position for fake cursors, so I don't really know how advantageous a cache is and whether more effort should be made to perfect a caching mechanism.

I'm assuming that just multiplying the LSL color vector elements by 255 for Windows and by 65535 for X is sufficient to obtain the exact color, but it certainly appears to look okay to my untrained eyes.

(defun mc-test (&optional list)
"Draw fake cursors at all POS defined in the `mc-list'.  Multiple fake cursors
are supported by GUI versions of Emacs built for X, Windows and OSX.
Color vector is LSL (The Linden Scripting Language), rather than standard RGB.
`nsterm.m' uses `NSColor', which works well with LSL.  `w32term.c' uses
`PALETTERGB' or `RGB', and the conversion from LSL is done internally by
multiplying each element of the LSL color vector by 255.  `xterm.c' uses
`x_make_truecolor_pixel', which uses 16-bit RGB -- the conversion from LSL
happens internally by multiplying each element of the LSL color vector by 65535."
(interactive)
  (setq mc-list (if list list '(
    (3 "hbar" [1.0 0.0 0.0])
    (4 "bar" [0.0 1.0 0.0])
    (5 "box" [0.0 0.0 1.0])
    (6 "hollow" [0.8 0.4 0.2])
    (7 ("hbar" 3) [1.0 0.0 1.0])
    (8 ("bar" 3) [0.0 1.0 1.0])))))

(global-set-key [f1] 'mc-test)

[multiple_cursors_004.diff (application/diff, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#22873; Package emacs. (Wed, 16 Mar 2016 08:01:01 GMT) Full text and rfc822 format available.

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

From: Keith David Bershatsky <esq <at> lawlist.com>
To: 22873 <at> debbugs.gnu.org
Cc: John Wiegley <jwiegley <at> gmail.com>, Eli Zaretskii <eliz <at> gnu.org>,
 Marcin Borkowski <mbork <at> mbork.pl>, Richard Stallman <rms <at> gnu.org>
Subject: Re: bug#22873: Can we support multiple Cursors?
Date: Wed, 16 Mar 2016 01:00:41 -0700
[Message part 1 (text/plain, inline)]
This fifth draft patch `multiple_cursors_005.diff` fixes the problem mentioned in my last email with the FILLED_BOX_CURSOR (a fake cursor) sometimes taking on the background color of the primary active cursor.  I see that the fake cursors do not always appear immediately in Emacs for Windows after pressing the F1 key to trigger the Lisp function `mc-test` -- i.e., there is a delay before the screen updates, so that will be one of my next projects to debug.  I didn't update the master branch tonight, so the patch applies as of the March 13, 2016 commit bearing "181e92c4e060a7ce4740b561375f9ec9f473f144".

(defun mc-test (&optional list)
"Draw fake cursors at all POS defined in the `mc-list'.  Multiple fake cursors
are supported by GUI versions of Emacs built for X, Windows and OSX.
Color vector is LSL (The Linden Scripting Language), rather than standard RGB.
`nsterm.m' uses `NSColor', which works well with LSL.  `w32term.c' uses
`PALETTERGB' or `RGB', and the conversion from LSL is done internally by
multiplying each element of the LSL color vector by 255.  `xterm.c' uses
`x_make_truecolor_pixel', which uses 16-bit RGB -- the conversion from LSL
happens internally by multiplying each element of the LSL color vector by 65535."
(interactive)
  (setq mc-list (if list list '(
    (3 "hbar" [1.0 0.0 0.0])
    (4 "bar" [0.0 1.0 0.0])
    (5 "box" [0.0 0.0 1.0])
    (6 "hollow" [0.8 0.4 0.2])
    (7 ("hbar" 3) [1.0 0.0 1.0])
    (8 ("bar" 3) [0.0 1.0 1.0])))))

(global-set-key [f1] 'mc-test)

[multiple_cursors_005.diff (application/diff, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#22873; Package emacs. (Fri, 18 Mar 2016 04:01:02 GMT) Full text and rfc822 format available.

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

From: Keith David Bershatsky <esq <at> lawlist.com>
To: 22873 <at> debbugs.gnu.org
Cc: John Wiegley <jwiegley <at> gmail.com>, Eli Zaretskii <eliz <at> gnu.org>,
 Marcin Borkowski <mbork <at> mbork.pl>, Richard Stallman <rms <at> gnu.org>
Subject: Re: bug#22873: Can we support multiple Cursors?
Date: Thu, 17 Mar 2016 21:00:32 -0700
[Message part 1 (text/plain, inline)]
Attached is the next draft patch -- multiple_cursors_006.diff -- that applies to Emacs master branch as of March 17, 2016, bearing commit "2fbdb1bb4c878f8ae17bd69d1b4ff51c47497e41".

This patch resolves the issue relating to a delay of the fake cursors appearing in Emacs for Windows.  The bug was caused because I had erroneously thought that the tail end of `redisplay_window' would be a sufficient location to calculate window-start/end for all circumstances, but it turned out that initializing fake cursors by merely setting the `mc-list` variable does not necessarily trigger the tail end of the former internal function.  Thus, there is now a second location at the beginning of `mc_calc' to determine window-start/end if it has not already been determined.  Other changes include setting up a struct prefix of `mc` in window.h for the pointers, except for the Lisp_Object `mc_cache' which apparently requires special treatment not lending itself to using a prefix.

That was the last of the known problems with fake cursors, so the next phase will be for me to try it out with a custom minor mode over the next few weeks to see what else may be needed.  The current draft patch has been lightly tested on Emacs for all three (3) window systems -- X11 (no toolkit), Windows (XP SP-3), and OSX (10.6.8).

(defun mc-test (&optional list)
"Draw fake cursors at all POS defined in the `mc-list'.  Multiple fake cursors
are supported by GUI versions of Emacs built for X, Windows and OSX.
Color vector is LSL (The Linden Scripting Language), rather than standard RGB.
`nsterm.m' uses `NSColor', which works well with LSL.  `w32term.c' uses
`PALETTERGB' or `RGB', and the conversion from LSL is done internally by
multiplying each element of the LSL color vector by 255.  `xterm.c' uses
`x_make_truecolor_pixel', which uses 16-bit RGB -- the conversion from LSL
happens internally by multiplying each element of the LSL color vector by 65535."
(interactive)
  (setq mc-list (if list list '(
    (3 "hbar" [1.0 0.0 0.0])
    (4 "bar" [0.0 1.0 0.0])
    (5 "box" [0.0 0.0 1.0])
    (6 "hollow" [0.8 0.4 0.2])
    (7 ("hbar" 3) [1.0 0.0 1.0])
    (8 ("bar" 3) [0.0 1.0 1.0])))))

(global-set-key [f1] 'mc-test)

[multiple_cursors_006.diff (application/diff, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#22873; Package emacs. (Sun, 27 Mar 2016 00:22:02 GMT) Full text and rfc822 format available.

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

From: John Wiegley <jwiegley <at> gmail.com>
To: Keith David Bershatsky <esq <at> lawlist.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, Marcin Borkowski <mbork <at> mbork.pl>,
 22873 <at> debbugs.gnu.org, Richard Stallman <rms <at> gnu.org>
Subject: Re: bug#22873: Can we support multiple Cursors?
Date: Sat, 26 Mar 2016 16:58:05 -0700
>>>>> Keith David Bershatsky <esq <at> lawlist.com> writes:

> That was the last of the known problems with fake cursors, so the next phase
> will be for me to try it out with a custom minor mode over the next few
> weeks to see what else may be needed. The current draft patch has been
> lightly tested on Emacs for all three (3) window systems -- X11 (no
> toolkit), Windows (XP SP-3), and OSX (10.6.8).

Thanks for carrying forward with this research, Keith!

-- 
John Wiegley                  GPG fingerprint = 4710 CF98 AF9B 327B B80F
http://newartisans.com                          60E1 46C4 BD1A 7AC1 4BA2




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#22873; Package emacs. (Tue, 29 Mar 2016 03:46:02 GMT) Full text and rfc822 format available.

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

From: Keith David Bershatsky <esq <at> lawlist.com>
To: 22873 <at> debbugs.gnu.org
Cc: John Wiegley <jwiegley <at> gmail.com>, Eli Zaretskii <eliz <at> gnu.org>,
 Marcin Borkowski <mbork <at> mbork.pl>, Richard Stallman <rms <at> gnu.org>
Subject: Re: bug#22873: Can we support multiple Cursors?
Date: Mon, 28 Mar 2016 20:45:07 -0700
[Message part 1 (text/plain, inline)]
The attached multiple_cursors_007.diff applies to the master branch as of today, March 28, 2016, bearing commit a30e7e12ed8465e2565dd318d921bc87f52ce18e.

mc_calc now runs from the applicable nsterm.m/w32term.c/xterm.c, instead of xdisp.c.  mc-calc has been broken down into 3 distinct sections, rather than if / if else / if else.  A bool argument has been added to mc_calc -- true for remove/cleanup, false for draw fake cursors.  The real cursor is redrawn if mc-list is set to Qnil (just in case it got erased during cleanup).  I do not believe mc_calc needs to run inside xdisp.c where draw_window_cursor is called at either location.

I've lightly tested this patch on Windows (XP SP-3), X11 (on an OSX box), and OSX (10.6.8).  I've switched over my own in-house setup to use this latest patch and I will be making notes of any problems as they arise -- e.g., I see there are a few rare instances where some of the fake cursors are not getting erased on OSX, and I see that Windows is a little slow drawing fake cursors when dealing with about 50 on the screen [I'm testing in a virtual machine called Parallels).  My primary usage of fake cursors is a vertical line that tracks the cursor position (compatible with word-wrap), and my secondary usage is with Magnar's library.

The usage of this patch is as follows:

    (defun mc-test (&optional list)
    "Draw fake cursors at all POS defined in the `mc-list'.  Multiple fake cursors
    are supported by GUI versions of Emacs built for X, Windows and OSX.
    Color vector is LSL (The Linden Scripting Language), rather than standard RGB.
    `nsterm.m' uses `NSColor', which works well with LSL.  `w32term.c' uses
    `PALETTERGB' or `RGB', and the conversion from LSL is done internally by
    multiplying each element of the LSL color vector by 255.  `xterm.c' uses
    `x_make_truecolor_pixel', which uses 16-bit RGB -- the conversion from LSL
    happens internally by multiplying each element of the LSL color vector by 65535."
    (interactive)
      (setq mc-list (if list list '(
        (3 "hbar" [1.0 0.0 0.0])
        (4 "bar" [0.0 1.0 0.0])
        (5 "box" [0.0 0.0 1.0])
        (6 "hollow" [0.8 0.4 0.2])
        (7 ("hbar" 3) [1.0 0.0 1.0])
        (8 ("bar" 3) [0.0 1.0 1.0])))))

    (global-set-key [f1] 'mc-test)


For anyone interested in trying out this latest patch with Magnar's library, the following are the only modifications that I am are of that would be needed (as of today, 03/28/2016) -- blue colored bar cursor for even numbered columns, red colored bar cursor for odd numbered columns.  One of the nifty things I see is that these fake cursors work well when placed at the very end of a line.

    (require 'multiple-cursors)

    (defun mc/clear-mc-list ()
      (setq mc-list nil))

    (add-hook 'multiple-cursors-mode-disabled-hook 'mc/clear-mc-list)

    (defun mc/create-fake-cursor-at-point (&optional id)
      "Add a fake cursor and possibly a fake active region overlay based on point and mark.
    Saves the current state in the overlay to be restored later."
      (unless mc--max-cursors-original
        (setq mc--max-cursors-original mc/max-cursors))
      (when mc/max-cursors
        (unless (< (mc/num-cursors) mc/max-cursors)
          (if (yes-or-no-p (format "%d active cursors. Continue? " (mc/num-cursors)))
              (setq mc/max-cursors (read-number "Enter a new, temporary maximum: "))
            (mc/remove-fake-cursors)
            (error "Aborted: too many cursors"))))
      (let ((overlay (make-overlay (point) (point))))
        (overlay-put overlay 'mc-id (or id (mc/create-cursor-id)))
        (overlay-put overlay 'type 'fake-cursor)
        (overlay-put overlay 'priority 100)
        (mc/store-current-state-in-overlay overlay)
        (when (use-region-p)
          (overlay-put overlay 'region-overlay
                       (mc/make-region-overlay-between-point-and-mark)))
        (let* (
            (overlays (mc/all-fake-cursors))
            (lst
              (mapcar
                (lambda (x)
                  (save-excursion
                    (let* (
                        current-column
                        (pos (overlay-start x)))
                      (goto-char pos)
                      (setq current-column (current-column))
                      (cond
                        ((oddp current-column)
                          (list pos "bar" [1.0 0.0 0.0])) ;; red
                        ((evenp current-column)
                          (list pos "bar" [0.0 0.0 1.0])))))) ;; blue
                overlays)) )
          (setq mc-list lst))
        overlay))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

[multiple_cursors_007.diff (application/diff, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#22873; Package emacs. (Tue, 29 Mar 2016 15:00:02 GMT) Full text and rfc822 format available.

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: Keith David Bershatsky <esq <at> lawlist.com>
Cc: jwiegley <at> gmail.com, mbork <at> mbork.pl, 22873 <at> debbugs.gnu.org, rms <at> gnu.org
Subject: Re: bug#22873: Can we support multiple Cursors?
Date: Tue, 29 Mar 2016 17:58:21 +0300
> Date:  Mon, 28 Mar 2016 20:45:07 -0700
> From:  Keith David Bershatsky <esq <at> lawlist.com>
> Cc:  John Wiegley <jwiegley <at> gmail.com>,Eli Zaretskii <eliz <at> gnu.org>,Marcin Borkowski <mbork <at> mbork.pl>,Richard Stallman <rms <at> gnu.org>
> 
> The attached multiple_cursors_007.diff applies to the master branch as of today, March 28, 2016, bearing commit a30e7e12ed8465e2565dd318d921bc87f52ce18e.
> 
> mc_calc now runs from the applicable nsterm.m/w32term.c/xterm.c, instead of xdisp.c.

Why is that a good idea?  You have 3 almost identical copies of the
same code, which goes against our long-time trend to have terminal
independent code only once, for easier maintenance.

>                         ((oddp current-column)
>                           (list pos "bar" [1.0 0.0 0.0])) ;; red
>                         ((evenp current-column)
>                           (list pos "bar" [0.0 0.0 1.0])))))) ;; blue

That's not how we specify colors in Emacs, not on the user level,
anyway.  I don't think I like this design.  Why not use the existing
mechanisms for specifying the cursor color?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#22873; Package emacs. (Tue, 29 Mar 2016 17:27:02 GMT) Full text and rfc822 format available.

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

From: Keith David Bershatsky <esq <at> lawlist.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: John Wiegley <jwiegley <at> gmail.com>, Marcin Borkowski <mbork <at> mbork.pl>,
 22873 <at> debbugs.gnu.org, Richard Stallman <rms <at> gnu.org>
Subject: Re: bug#22873: Can we support multiple Cursors?
Date: Tue, 29 Mar 2016 10:26:21 -0700
Thank you, Eli, for taking a look at the 7th working draft of mc.

Essentially, mc_calc is called at only one location depending on how Emacs was built:

* nsterm.m when built --with-ns.

* w32term.c when built for Windows.

* xterm.c when built --with-x.

All three of those files have similarities, and some of the functions in each file are either the same or similar.  I felt that tacking mc_calc onto the heels of a function from `xdisp.c` and putting in exceptions (to prevent it from always being called), is not as clean as putting it only where it was truly needed.  In a nutshell, I'm just following in the footsteps of my predecessors as to cursors for Emacs on Windows, OSX and X11.

I have made a note on my todo-list to add support for alternative methods for the end user to define colors:  [1.0 0.0 0.0]; "red"; "#FF0000"; (255, 0, 0); (65535, 0, 0) -- with some way to distinguish between the last two forms.  (1.0 is used by OSX; 255 is used by Windows; and 65535 is used by X11).

Keith

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

At Tue, 29 Mar 2016 17:58:21 +0300,
Eli Zaretskii wrote:
> 
> * * *
> > 
> > mc_calc now runs from the applicable nsterm.m/w32term.c/xterm.c, instead of xdisp.c.
> 
> Why is that a good idea?  You have 3 almost identical copies of the
> same code, which goes against our long-time trend to have terminal
> independent code only once, for easier maintenance.
> 
> >                         ((oddp current-column)
> >                           (list pos "bar" [1.0 0.0 0.0])) ;; red
> >                         ((evenp current-column)
> >                           (list pos "bar" [0.0 0.0 1.0])))))) ;; blue
> 
> That's not how we specify colors in Emacs, not on the user level,
> anyway.  I don't think I like this design.  Why not use the existing
> mechanisms for specifying the cursor color?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#22873; Package emacs. (Sun, 25 Jun 2017 22:10:02 GMT) Full text and rfc822 format available.

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

From: Keith David Bershatsky <esq <at> lawlist.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: John Wiegley <jwiegley <at> gmail.com>, Marcin Borkowski <mbork <at> mbork.pl>,
 22873 <at> debbugs.gnu.org, Richard Stallman <rms <at> gnu.org>
Subject: Re: bug#22873: Can we support multiple Cursors?
Date: Sun, 25 Jun 2017 15:09:16 -0700
[Message part 1 (text/plain, inline)]
WHAT'S NEW:

-  Fake cursors now only appear in the selected-window if the `mc-list' is defined -- i.e., the fake cursors are removed when the window loses focus, and they are added again when the window acquires focus.

-  `mc_color_vector_calculate` will take the familiar Emacs way of specifying colors (e.g., "red" and "#FF0000") and convert them internally to the LSL color vector.  The conversion process is transparent to the user.

-  `mc_remove_when_scrolled` will remove multiple cursors when scrolling.  This is important because `update_window_end` will not remove the cursors when scrolling.  [There was an emacs-devel thread (about 1.5 years ago) where I had sought help tracking the multiple cursors when scrolling.  It turned out that the method of tracking cursors was not the problem (since they don't move) -- it was simply that `update_window_end` was not being called in that circumstance.]

-  `mc_x_y_hpos_vpos' contains some extra `stuff` that is irrelevant to the functionality of this patch -- the extra `stuff` is used by me as a workaround to deal with the overlay after-string property that gets in the way of properly calculating coordinates.  [See the TODO section below.]

-  The patch applies to commit a30e7e12ed8465e2565dd318d921bc87f52ce18e from 03/28/2016.  [See apology for the inconvenience further down below.]


TODO:

-  Optimize drawing and removal of multiple fake cursors.

-  Fix any bugs (there will surely be many).

-  Implement a way to properly calculate x, y, hpos, vpos when overlays are present -- e.g., the overlay after-string property wreaks havoc on the current method of calculating coordinates.

-  Try and convince one or more real programmers to take over from here, since we now have a working proof concept.  [I am just a weekend hobbyist without any formal programming study.]


SUGGESTION:

I would respectfully suggest to the Emacs development team that multiple cursors be implemented in two stages:

-  The first stage would be the creation and removal of fake cursors to be used kind of like overlays.  I.e., specify the `point`, cursor-style, and color.  The suggestion by Eli Z. to support specifying colors with strings like "red" and "#FF0000" has now been implemented.

-  The second stage would be to implement built-in functionality similar to the multiple cursors library by Magnar Sveen.


[In an earlier section of this thread, I mentioned a substantial slow-down that I experienced when using the library written by Mr. Sveen.  I have since discovered that it was due to `line-number-at-pos', and I have already reached out to the author with an alternative suggestion to use (format-mode-line "%l").]


INSTALLATION (for anyone a little less familiar):

STEP #1 (clone master branch):  git clone -b master git://git.sv.gnu.org/emacs.git

STEP #2:  cd over to the root of the `emacs` source directory cloned in the first step above.

STEP #3 (hard reset):  git reset --hard a30e7e12ed8465e2565dd318d921bc87f52ce18e

You will see a message:  "HEAD is now at a30e7e1 Mention the `M-q' changes"

[We need to go back in time to 03/28/2016 as that is the master branch version that I am still using -- sorry for the inconvenience.  I will update to the latest version of Emacs at some point in the future as time permits.  Creating patches that apply to a "moving target" is challenging.]

STEP #4 (put the patch in place):  Copy the latest patch (multiple_cursors_008.diff) to the root of the emacs source directory cloned in the first step above.

STEP #5 (apply the patch):  git apply multiple_cursors_008.diff

STEP #6:  ./autogen.sh

STEP #7:  Configure the build for X, MS Windows, or OSX; e.g.,:  ./configure --with-ns

STEP #8:  make

STEP #9:  make install

STEP #10:  Launch the newly built Emacs, and copy the following function to the `*scratch*` buffer, and type `M-x mc-test`.

(defun mc-test ()
"Draw fake cursors at all POS defined in the `mc-list'.  Multiple fake cursors
are supported by GUI versions of Emacs built for X, Windows and OSX.
Popular forms of specifying colors such as \"red\" and \"#FF0000\" are now
supported, as well as LSL color vectors such as [1.0 0.0 0.0].  For those users
who choose the former familiar methods of specifying colors with strings,
`mc_color_vector_calculate' will convert those strings to LSL color vectors.
The color vectors are commonly referred to as LSL (The Linden Scripting Language).
`nsterm.m' uses `NSColor', which works well with LSL.  `w32term.c' uses
`PALETTERGB' or `RGB', and the conversion from LSL is done internally by
multiplying each element of the LSL color vector by 255.  `xterm.c' uses
`x_make_truecolor_pixel', which uses 16-bit RGB -- the conversion from LSL
happens internally by multiplying each element of the LSL color vector by 65535."
(interactive)
  (let ((buffer (get-buffer-create "*MC-TEST*")))
    (with-current-buffer buffer
      (erase-buffer)
      (insert "This is a test!")
      (setq mc-list '((1 "hbar" "red")
                      (2 "bar" "yellow")
                      (3 "box" "#00FF00")
                      (4 "hollow" "#0000FF")
                      (5 ("hbar" 3) [1.0 0.0 1.0])
                      (6 ("bar" 3) [0.0 1.0 1.0]))))
    (select-window (display-buffer buffer))
    ;;; The trigger in `keyboard.c` is not activated in this example, so we
    ;;; Force the multiple cursors to be drawn.
    (mc-draw-erase (selected-window))))


[multiple_cursors_008.diff (application/diff, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#22873; Package emacs. (Sun, 30 Jul 2017 17:40:01 GMT) Full text and rfc822 format available.

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

From: Keith David Bershatsky <esq <at> lawlist.com>
To: 22873 <at> debbugs.gnu.org
Cc: John Wiegley <jwiegley <at> gmail.com>, Eli Zaretskii <eliz <at> gnu.org>,
 Marcin Borkowski <mbork <at> mbork.pl>, Richard Stallman <rms <at> gnu.org>
Subject: bug#22873:  Can we support multiple Cursors?
Date: Sun, 30 Jul 2017 10:39:45 -0700
[Message part 1 (text/plain, inline)]
VERSION:  009

-  The patch applies to commit a30e7e12ed8465e2565dd318d921bc87f52ce18e from 03/28/2016.  [@lawlist is unable to use the current master branch for daily workflow due to certain unrelated bugs.  Until those unrelated bugs are resolved, @lawlist will continue using earlier versions of the master branch.  @lawlist is tentatively thinking of moving forwards in time to October 1, 2016 bearing commit bb2ef5c6f7058b149adc9230a3db7d1fbd423c51, but testing will be needed prior thereto.]


WHAT'S NEW:

-  `mc_store_previous_values':  Recording values of the current command loop (to be compared against the previous command loop) has been consolidated into one function, which makes the modification to `xdisp.c` cleaner.

-  Bug Fixes:  Enabling error checking when configuring the build revealed a few errors in the code that have now been corrected.  It turned out that `update_window_end` is called in about 99% of the locations where multiple cursors need to be removed.  A previous attempted optimization of `mc_calc` prevented cursor removal, and that bug has now been fixed.  Fixed two crashes; one was caused by an improper usage of `intern_c_string`, and another was caused by attempting to remove cursors directly from `xdisp.c` instead of letting `update_window_end` do its job.


TODO:

-  Track down the cause for the 1% of the time when multiple fake cursors are not being removed.  [It may have something to do with redisplay being interrupted due to keyboard activity, or perhaps when windows/frames are changing size?]

-  Optimize drawing and removal of multiple fake cursors.

-  Implement a way to properly calculate x, y, hpos, vpos when overlays are present.  The overlay after-string property wreaks havoc on the current method of calculating coordinates.

-  Try and motivate one or more real programmers to take over from here.


ROAD MAP:

-  The first stage is the creation/removal of fake cursors.

-  The second stage will be built-in functionality similar to the multiple cursors library by Magnar Sveen.


INSTALLATION:

-  STEP #1 (clone master branch):  git clone -b master git://git.sv.gnu.org/emacs.git

-  STEP #2:  cd over to the root of the `emacs` source directory cloned in the first step above.

-  STEP #3 (hard reset):  git reset --hard a30e7e12ed8465e2565dd318d921bc87f52ce18e

The following message is displayed in the terminal:  "HEAD is now at a30e7e1 Mention the `M-q' changes"

-  STEP #4 (put the patch in place):  Copy the latest patch (multiple_cursors_008.diff) to the root of the emacs source directory cloned in the first step above.

-  STEP #5 (apply the patch):  git apply multiple_cursors_009.diff

-  STEP #6:  ./autogen.sh

-  STEP #7:  Configure the build for X, MS Windows, or OSX; e.g.,:  ./configure --with-ns

-  STEP #8:  make

-  STEP #9:  make install

-  STEP #10:  Launch the newly built Emacs, and copy the following function to the `*scratch*` buffer, and type `M-x mc-test`.

(defun mc-test ()
"Draw fake cursors at all POS defined in the `mc-list'.  Multiple fake cursors
are supported by GUI versions of Emacs built for X, Windows and OSX.
Popular forms of specifying colors such as \"red\" and \"#FF0000\" are now
supported, as well as LSL color vectors such as [1.0 0.0 0.0].  For those users
who choose the former familiar methods of specifying colors with strings,
`mc_color_vector_calculate' will convert those strings to LSL color vectors.
The color vectors are commonly referred to as LSL (The Linden Scripting Language).
`nsterm.m' uses `NSColor', which works well with LSL.  `w32term.c' uses
`PALETTERGB' or `RGB', and the conversion from LSL is done internally by
multiplying each element of the LSL color vector by 255.  `xterm.c' uses
`x_make_truecolor_pixel', which uses 16-bit RGB -- the conversion from LSL
happens internally by multiplying each element of the LSL color vector by 65535."
(interactive)
  (let ((buffer (get-buffer-create "*MC-TEST*")))
    (with-current-buffer buffer
      (erase-buffer)
      (insert "This is a test!")
      (setq mc-list '((1 "hbar" "red")
                      (2 "bar" "yellow")
                      (3 "box" "#00FF00")
                      (4 "hollow" "#0000FF")
                      (5 ("hbar" 3) [1.0 0.0 1.0])
                      (6 ("bar" 3) [0.0 1.0 1.0]))))
    (select-window (display-buffer buffer))
    ;;; The trigger in `keyboard.c` is not activated in this example, so we
    ;;; Force the multiple cursors to be drawn.
    (mc-draw-erase (selected-window))))

[multiple_cursors_009.diff (application/diff, attachment)]

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

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

From: Keith David Bershatsky <esq <at> lawlist.com>
To: 22873 <at> debbugs.gnu.org
Cc: John Wiegley <jwiegley <at> gmail.com>, Eli Zaretskii <eliz <at> gnu.org>,
 Marcin Borkowski <mbork <at> mbork.pl>, Richard Stallman <rms <at> gnu.org>
Subject: bug#22873:  Can we support multiple cursors?
Date: Thu, 10 Aug 2017 17:00:33 -0700
[Message part 1 (text/plain, inline)]
PATCH VERSION:  010

-  This patch applies to commit a30e7e12ed8465e2565dd318d921bc87f52ce18e from 03/28/2016.  [@lawlist is presently unable to use the current master branch for daily workflow due to certain unrelated bugs.]


WHAT'S NEW:

-  `update_frame` runs too late in the redisplay cycle to reliably remove all fake cursors when cutting/pasting text in conjunction with the current command loop.  If we erase the fake cursors at the outset of `redisplay_window`, removal occurs too early in the redisplay cycle and the user sees the cursors being removed before the current command finishes.  The very end of `redisplay_window` is a little closer to being the "sweet spot" for initial fake cursor removal, which is where it now occurs.  Fake cursors are presently only being drawn whenever `update_frame` is called.  Removal of fake cursors is faster on OSX, and slower on Windows and X11.

-  Recordation of prior values at the end of `redisplay_window` has been simplified to just four (4) values (current/previous window-start/window-end).

-  `mc_erase` has been simplified to use the existing function `erase_phys_cursor`.

-  Miscellaneous bug fixes, including, but not limited to checks to ensure that coordinates (X, Y, HPOS, VPOS) are within bounds.

-  Improved comments and doc-strings.


TODO:

-  Set up a user option similar to `cursor-in-non-selected-windows'.

-  Explore the idea of whether we need additional code to handle removing/redrawing
   fake cursors when windows change sizes / layouts.

-  `w->phys_cursor.vpos` of the real cursor is accurate as to VPOS irrespective of
   whether the `header-line-format' exists.  `mc_x_y_hpos_vpos' may need to adopt
   a similar approach as to VPOS instead of checking the `header-line-format'
   and potentially adding a value of 1 immediately before calling `mc_erase' / `mc_draw'.

-  Fake cursors are being redrawn too often when mousing over text (underneath the
   real cursor) with mouse-face properties, and also when non-selected windows/frames
   have an ongoing process that require frequent redisplay updates.

-  Optimize drawing/erasing fake cursors.

-  Implement a way to properly calculate X, Y, HPOS, VPOS when overlays are present.
   The overlay after-string wreaks havoc when calculating coordinates.

-  Fix any bugs (there will surely be many).

-  Try and convince one or more real programmers to take over from here.


ROAD MAP:

-  The first stage of development is the creation and removal of fake cursors,
   which are specified with:  buffer point, cursor-style, and cursor color.

-  The second stage of development is the built-in C implementation of functionality
   similar to the multiple cursors library by Magnar Sveen.


INSTALLATION:

-  STEP #1 (clone master branch):  git clone -b master git://git.sv.gnu.org/emacs.git

-  STEP #2:  cd over to the root of the `emacs` source directory cloned in the first step above.

-  STEP #3 (hard reset):  git reset --hard a30e7e12ed8465e2565dd318d921bc87f52ce18e

   The following message is displayed in the terminal:  "HEAD is now at a30e7e1 Mention the `M-q' changes"

-  STEP #4 (put the patch in place):  Copy the latest patch to the root of the emacs source directory cloned in the first step above.

-  STEP #5 (apply the patch):  git apply [latest-patch.diff]

-  STEP #6:  ./autogen.sh

-  STEP #7:  Configure the build for X, MS Windows, or OSX; e.g.,:  ./configure --with-ns

-  STEP #8:  make

-  STEP #9:  make install

-  STEP #10:  Launch the newly built Emacs, and copy the following function to the `*scratch*` buffer, and type `M-x mc-test`.

(defun mc-test ()
"Draw fake cursors at all POS defined in the `mc-list'.  Multiple fake cursors
are supported by GUI versions of Emacs built for X, Windows and OSX.
Popular forms of specifying colors such as \"red\" and \"#FF0000\" are now
supported, as well as LSL color vectors such as [1.0 0.0 0.0].  For those users
who choose the former familiar methods of specifying colors with strings,
`mc_color_vector_calculate' will convert those strings to LSL color vectors.
The color vectors are commonly referred to as LSL (The Linden Scripting Language).
`nsterm.m' uses `NSColor', which works well with LSL.  `w32term.c' uses
`PALETTERGB' or `RGB', and the conversion from LSL is done internally by
multiplying each element of the LSL color vector by 255.  `xterm.c' uses
`x_make_truecolor_pixel', which uses 16-bit RGB -- the conversion from LSL
happens internally by multiplying each element of the LSL color vector by 65535."
(interactive)
  (let ((buffer (get-buffer-create "*MC-TEST*")))
    (with-current-buffer buffer
      (erase-buffer)
      (insert "This is a test!")
      (setq mc-list '((1 "hbar" "red")
                      (2 "bar" "yellow")
                      (3 "box" "#00FF00")
                      (4 "hollow" "#0000FF")
                      (5 ("hbar" 3) [1.0 0.0 1.0])
                      (6 ("bar" 3) [0.0 1.0 1.0]))))
    (select-window (display-buffer buffer))
    ;;; The trigger in `keyboard.c` is not activated in this example, so we
    ;;; Force the multiple cursors to be drawn.
    (mc-draw-erase (selected-window))))


[multiple_cursors_010.diff (application/diff, attachment)]

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

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

From: Keith David Bershatsky <esq <at> lawlist.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: John Wiegley <jwiegley <at> gmail.com>, Marcin Borkowski <mbork <at> mbork.pl>,
 22873 <at> debbugs.gnu.org, Richard Stallman <rms <at> gnu.org>
Subject: bug#22873:  Can we support multiple cursors?
Date: Sun, 13 Aug 2017 11:19:30 -0700
Dear Eli:

I could use some help/guidance, please.

I have encountered a situation where the Y and VPOS coordinates returned by `move_it_to` are sometimes out of bounds, and MATRIX_ROW crashes Emacs when drawing fake cursors that are out of bounds.  The solution appears to be a test for whether Y and VPOS are out of bounds.  I would like to use `window_box_height` to give me essentially the same value as `window-body-height` with a non-nil PIXELWISE argument.  In my case, I have 998 pixels for the window body height as depicted in the diagram of the Emacs manual:  https://www.gnu.org/software/emacs/manual/html_node/elisp/Window-Sizes.html  The last Y that I am interested in is at 1000 pixels because my `frame-char-height` -- aka `FRAME_LINE_HEIGHT (XFRAME (w->frame))` -- is 20.  Two pixels are hidden by the mode-line, so the line of text is partially visible.  `count-screen-lines` is not a viable option because using `vertical-motion` is too slow.  The last VPOS that I am interested in is 50 -- again, same thing, partially visible wit
 h two pixels hidden underneath the mode-line.

Testing and limiting the drawing of fake cursors with `y <= window_box_height (w)` gives me mixed results; i.e., sometimes fake cursors are drawn/erased only up to line 49, but sometimes it works up to line 50 (partially visible).  I think I want to test for whether Y is less than or equal to 1000 and if VPOS is less than or equal to 50 -- if the test is true, then go ahead and draw fake cursors up to and including that location.

However, I can foresee situations where there might be mixed line heights on the visible window, and relying upon the frame character height and window body height will not be reliable.  In a simple case, we can take 1000 divided by 20 and know that the VPOS is 50.

Is there a more reliable test for the last partially visible Y and VPOS within the window body height?  Should I be using pos_visible_p in some capacity here?

Thanks,

Keith




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

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: Keith David Bershatsky <esq <at> lawlist.com>
Cc: jwiegley <at> gmail.com, mbork <at> mbork.pl, 22873 <at> debbugs.gnu.org, rms <at> gnu.org
Subject: Re: bug#22873:  Can we support multiple cursors?
Date: Sun, 13 Aug 2017 21:36:22 +0300
> Date:  Sun, 13 Aug 2017 11:19:30 -0700
> From:  Keith David Bershatsky <esq <at> lawlist.com>
> Cc:  22873 <at> debbugs.gnu.org,John Wiegley <jwiegley <at> gmail.com>,Marcin Borkowski <mbork <at> mbork.pl>,Richard Stallman <rms <at> gnu.org>
> 
> I have encountered a situation where the Y and VPOS coordinates returned by `move_it_to` are sometimes out of bounds, and MATRIX_ROW crashes Emacs when drawing fake cursors that are out of bounds.  The solution appears to be a test for whether Y and VPOS are out of bounds.

Actually, the usual solution is to limit move_it_to to
last_visible_y.  Are you saying that you already do that, and the
values of Y and VPOS are still out of bounds?  That would be strange,
because the display engine does that in many places.

> I would like to use `window_box_height` to give me essentially the same value as `window-body-height` with a non-nil PIXELWISE argument.

And that's not what you get?  Can you show a simple example?

`count-screen-lines` is not a viable option because using `vertical-motion` is too slow.

It's strange that you say so because vertical-motion uses the same
move_it_to subroutines that you'd like to use directly.

> Testing and limiting the drawing of fake cursors with `y <= window_box_height (w)` gives me mixed results; i.e., sometimes fake cursors are drawn/erased only up to line 49, but sometimes it works up to line 50 (partially visible).  I think I want to test for whether Y is less than or equal to 1000 and if VPOS is less than or equal to 50 -- if the test is true, then go ahead and draw fake cursors up to and including that location.

Are you sure you account for the height of the cursor and the line on
which it is shown?  The Y coordinate is where the line begins; it ends
several pixels lower, i.e. at a greater value of Y.

> However, I can foresee situations where there might be mixed line heights on the visible window, and relying upon the frame character height and window body height will not be reliable.  In a simple case, we can take 1000 divided by 20 and know that the VPOS is 50.

For reliable calculations, you must do everything in pixels.

> Is there a more reliable test for the last partially visible Y and VPOS within the window body height?  Should I be using pos_visible_p in some capacity here?

You could use pos_visible_p, although it, again, uses move_it_to.  But
I don't think I have a clear understanding of your problem, so maybe
it's immaterial.




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

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

From: Keith David Bershatsky <esq <at> lawlist.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: John Wiegley <jwiegley <at> gmail.com>, Marcin Borkowski <mbork <at> mbork.pl>,
 22873 <at> debbugs.gnu.org, Richard Stallman <rms <at> gnu.org>
Subject: Re: bug#22873:  Can we support multiple cursors?
Date: Sun, 13 Aug 2017 20:20:10 -0700
I read through the comments in xdisp.c that immediately precede move_it_to and I also looked at all of it uses within xdisp.c, but I am still unclear how to limit move_it_to the it.last_visible_y.  I got the impression that if I put it.last_visible_y as an argument of move_it_to, that `it` would move to that location instead of POS if POS cannot be found.  I'd like the function mc_x_y_hpos_vpos to return valid coordinates if POSINT is on the visible window, or -1 for all four coordinates if it is not visible.  I'm calling mc_x_y_hpos_vpos late in the redisplay cycle and the START/END arguments "should be" correct.  I am unclear as why the Y and VPOS were sometimes out of bounds in a few corner cases (e.g., when I compiled a tex document that had errors in the LaTeX code) -- my best guess is that START/END may have been wrong because another window was opened displaying the tex compile messages.

I was pretty sure that I could substitute window_box_height for window-body-height (with a non-nil PIXELWISE argument), and that is why I phrased that previous comment with a degree of uncertainty.  Based on your comment, I now feel better about using window_box_height.  I was unaware that my usage of move_it_to may have been incorrect, so that is why I was trying to come up with new ways to workaround coordinates that were out of bounds.  If we can fix mc_x_y_hpos_vpos, then there would be no need to perform additional subsequent checks to see whether the values were correct.

Drawing and erasing fake cursors is done by temporarily hijacking w->phys_cursor and then calling either erase_phys_cursor or draw_window_cursor.

Today, I added "if (it.current_y >= it.last_visible_y) ... goto done"

Lisp_Object
mc_x_y_hpos_vpos (struct window *w, EMACS_INT posint, EMACS_INT start, EMACS_INT end)
{
  struct it it;
  void *itdata = bidi_shelve_cache ();
  struct text_pos pt;
  int x, y, hpos, vpos;
  if (posint >= start
      && posint <= end)
    {
      SET_TEXT_POS_FROM_MARKER (pt, w->start);
      start_display (&it, w, pt);
      move_it_to (&it, posint, -1, -1, -1, MOVE_TO_POS);
      if (it.current_y >= it.last_visible_y)
        {
          bidi_unshelve_cache (itdata, false);
          goto done;
        }
      x = it.current_x;
      y = it.current_y;
      hpos = it.hpos;
      vpos = it.vpos;
      bidi_unshelve_cache (itdata, false);
    }
    else
      {
        done:
        x = -1;
        y = -1;
        hpos = -1;
        vpos = -1;
      }
  return
    listn (CONSTYPE_HEAP, 4, make_number (x), make_number (y), make_number (hpos), make_number (vpos));
}




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

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: Keith David Bershatsky <esq <at> lawlist.com>
Cc: jwiegley <at> gmail.com, mbork <at> mbork.pl, 22873 <at> debbugs.gnu.org, rms <at> gnu.org
Subject: Re: bug#22873:  Can we support multiple cursors?
Date: Mon, 14 Aug 2017 18:01:07 +0300
> Date:  Sun, 13 Aug 2017 20:20:10 -0700
> From:  Keith David Bershatsky <esq <at> lawlist.com>
> Cc:  22873 <at> debbugs.gnu.org,John Wiegley <jwiegley <at> gmail.com>,Marcin Borkowski <mbork <at> mbork.pl>,Richard Stallman <rms <at> gnu.org>
> 
> I read through the comments in xdisp.c that immediately precede move_it_to and I also looked at all of it uses within xdisp.c, but I am still unclear how to limit move_it_to the it.last_visible_y.

Like this:

 move_it_to (&it, POS, -1, it.last_visible_y - 1, -1, MOVE_TO_POS | MOVE_TO_Y);

where POS is the buffer position.  You can find many examples of this
in xdisp.c.

> I got the impression that if I put it.last_visible_y as an argument of move_it_to, that `it` would move to that location instead of POS if POS cannot be found.

It stops when the first condition is satisfied.  If it reaches POS
before the window end, it stops there; otherwise it stops at the
window end.  It is then a simple matter of testing IT_CHARPOS(&it)
against POS to see which of these conditions caused it to stop.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#22873; Package emacs. (Mon, 14 Aug 2017 20:36:01 GMT) Full text and rfc822 format available.

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

From: Keith David Bershatsky <esq <at> lawlist.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: John Wiegley <jwiegley <at> gmail.com>, Marcin Borkowski <mbork <at> mbork.pl>,
 22873 <at> debbugs.gnu.org, Richard Stallman <rms <at> gnu.org>
Subject: bug#22873:  Can we support multiple cursors?
Date: Mon, 14 Aug 2017 13:35:17 -0700
Thank you, Eli, for teaching me how to better use move_it_to.

In the tests that I ran today using:

move_it_to (&it, POS, -1, it.last_visible_y - 1, -1, MOVE_TO_POS | MOVE_TO_Y);

I observed that IT will stop at *the beginning of the last partially visible line* when POS is on the last partially visible line and POS's X coordinate is greater than 0.  IT does *not* stop at the window-end.

The following seems to work better when POS is on the last partially visible line and POS's x coordinate is greater than 0.

move_it_to (&it, POS, it.last_visible_x, it.last_visible_y - 1, -1, MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);

I built a new working draft of Emacs based on the latter example and will be trying using it throughout the day.

Keith




This bug report was last modified 83 days ago.

Previous Next


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