unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
From: Platon Pronko <platon7pronko@gmail.com>
To: Yuri Khan <yuri.v.khan@gmail.com>
Cc: Eli Zaretskii <eliz@gnu.org>, help-gnu-emacs@gnu.org
Subject: Re: Moving point around empty overlays with 'after-text
Date: Tue, 11 Apr 2023 16:49:10 +0800	[thread overview]
Message-ID: <dc397234-064a-0f2e-19d7-a75da3f97376@gmail.com> (raw)
In-Reply-To: <CAP_d_8X+Kg7KEhW5bB6jCVtVatiAyzZQKEJ6+-rpt=Ezr71=5w@mail.gmail.com>

On 2023-04-10 17:56, Yuri Khan wrote:
> You’re talking about typing “41, ” as if it were an atomic action. In
> some cases (e.g. pasting from clipboard) it could be, but normally
> you’ll be inserting characters one by one, and it might be instructive
> to look at the buffer contents and expected inlay behavior through the
> intermediate stages.
> 
> 0. Base state:
> 
>      def test(a1: Int = 1, a2: Int = 2, a3: Int = 3) {}
>      test({a1=}42)
> 
> 1. You type “4”. Depending on how the editor interprets the insertion
> around the inlay:
> 
> 1a. The editor inserts the digit 4 at the position where the inlay is.
> The text is now “test(442)”. Syntactically, you just changed the
> argument value, so the inlay should stay before the newly inserted
> character.
> 
>      def test(a1: Int = 1, a2: Int = 2, a3: Int = 3) {}
>      test({a1=}42)
> 
> 1b. The editor lets you insert the digit 4 before the inlay and
> somehow knows it is separate from the “42” that used to be the first
> argument. The text is now “test(4█42)” where the block represents some
> kind of separator. Likely, this text is invalid syntax, so the inlay
> is now technically incorrect.
> 
>      def test(a1: Int = 1, a2: Int = 2, a3: Int = 3) {}
>      test(4█a1=█42)
> 
> 2. You type “1”. Same thing as “4” before, only in case 2a the
> insertion is no longer adjacent to the inlay so the issue does not
> even arise. In case 2b, you now have “test(41█42)” in the buffer and
> “test(41█a1=█42)” in the view.
> 
> 3. You type “,”.
> 
> 3a. The text is now “test(41,42)” and syntactically it’s a call with
> two arguments. The inlay for the first argument stays right after the
> opening paren; a new inlay appears after the comma and before the 42.
> 
> 3b. The text is now syntactically well-formed, so the IDE can update the inlays.
> 
>      def test(a1: Int = 1, a2: Int = 2, a3: Int = 3) {}
>      test({a1=}41,{a2=}42)
> 
> 4. You type a space.
> 
> For typographical reasons, a well-designed grammar will infer the
> space to belong to the separator, not the argument expression. The
> inlay will shift after the space.
> 
>      def test(a1: Int = 1, a2: Int = 2, a3: Int = 3) {}
>      test({a1=}41, {a2=}42)
> 
> 
> Basically, after working out the above, my question is: Why is it
> important to let the user choose whether to insert newly typed
> characters before or after the inlay, if the inlay is going to be
> updated and repositioned based on the resulting buffer text?
> Alternatively, why is it important to let the user bring the buffer
> into an invalid state that may even be unrepresentable in text?

You are discussing the technical part, and there you are correct on all points. Of course, from the buffer standpoint all my examples are equivalent and it makes absolutely no difference on what side of the overlay the cursor is. And after the user types something the well-implemented mode will remove the overlay and everything will be fine.

I'm talking more about the user intention, before he actually types anything, and consequently the confusion he will temporarily experience when he will try to execute this intention. We here in Emacs mailing list understand the internals quite well and thus can understand that the overlay is zero-width and cursor position is actually the same on both sides. Less-enlightened user won't - for him the inlay is something tangible, present in the buffer the same way as the characters are present in the buffer.


And in the discussed example the user can have two different intentions:

Intention 1: prepending something to argument value. In this case he will want to position the cursor after the overlay:

test(a1=<cursor>42)
test(a1=1<cursor>42)

(here and after - I'm intentionally omitting the braces around the {a1=} part, to illustrate my point better - usually the inlays look very close to syntactically correct code, so when the developer is working with the code he is likely to treat that "nonexistent" code very similarly to the real one, as if it was actually present)

It will not make sense for him to want to position the cursor before the overlay. Look how confusing his intuition would be if overlay was setup to show cursor before:

test(<cusor>a1=42)
// User is confused.
// He might want to move cursor to the right,
// but then it jumps into the middle of the next argument:
test(a1=4<cursor>)
// He returns back:
test(<cursor>a1=42)
// User types "1". Here's how his brain predicts the next state of the buffer:
test(1a1=42)

Of course once the inlay is hidden, everything is back to normal. But user is already slightly frustrated.

Intention 2: prepending another argument. In this case he will want to position the cursor before the overlay:

test(<cursor>a1=42)
// User tries to type "a0=1," (let's imagine there was such an argument)
test(a<cursor>a1=42)
// More typing
test(a0=1,<cursor>a1=42)

Here, if the overlay was set up such that the cursor is shown after, the user's intuition would be screwed again:

test(a1=<cursor>42)
// Why my cursor is between the argument name and argument value?
// Move left:
test<cursor>(a1=42)
// Something is broken, let's move back:
test(a1=<cursor>42)
// Let's try typing "a0=1". Here's the intuitively expected state of the buffer, completely garbled:
test(a1=a0=142)


In all these examples nothing horrible happened - after a short struggle the user will be able to fix the issue and continue on his way. But such issues contribute to the overall feeling of the editor, and I would be sad if Emacs was leaving people with the feeling of "ever so slightly broken". We can be better than that :)

(and in "we" I include myself - I'm not just idly discussing, I will be willing to go into the code and create a patch if we can agree on how it should be patched, if it should be)


Oh, and by the way, even if we disregard all of the above - we still don't have any well-defined way of positioning the cursor around the zero-width overlay. The way it works currently is it's either broken and cursor is shown on the wrong side, or the code relies on some side effect of overlay implementation (c.f. https://debbugs.gnu.org/cgi/bugreport.cgi?bug=62540).



  reply	other threads:[~2023-04-11  8:49 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-08  5:46 Moving point around empty overlays with 'after-text Ash
2023-04-08 10:06 ` Eli Zaretskii
2023-04-08 10:14   ` Platon Pronko
2023-04-08 10:10 ` Platon Pronko
2023-04-08 23:06   ` Ash
2023-04-09 12:15     ` Platon Pronko
2023-04-09 14:49       ` tomas
2023-04-10  1:52         ` Platon Pronko
2023-04-10  4:56           ` Eli Zaretskii
2023-04-10  5:22             ` Platon Pronko
2023-04-10  9:56               ` Yuri Khan
2023-04-11  8:49                 ` Platon Pronko [this message]
2023-04-11  9:41                   ` Yuri Khan
2023-04-10  5:35           ` tomas
2023-04-10  5:48             ` Platon Pronko
2023-04-09 20:44       ` Ash
2023-04-10  2:00         ` Platon Pronko
2023-04-10  3:21           ` Ash
2023-04-10  3:31             ` Platon Pronko
2023-04-11  0:22               ` Ash
2023-04-10  5:09             ` Eli Zaretskii
2023-04-10  5:37               ` Platon Pronko
2023-04-10  8:03                 ` Eli Zaretskii
2023-04-10  9:05                   ` Platon Pronko
2023-04-10  5:01           ` Eli Zaretskii
2023-04-10  5:26             ` Platon Pronko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

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

  git send-email \
    --in-reply-to=dc397234-064a-0f2e-19d7-a75da3f97376@gmail.com \
    --to=platon7pronko@gmail.com \
    --cc=eliz@gnu.org \
    --cc=help-gnu-emacs@gnu.org \
    --cc=yuri.v.khan@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).