Subject: Re: bug#54488: 29.0.50; move-to-column/overlay-related regression in latest master, perhaps 28?

From: João Távora <[email-masked]>
Date: Mon, 21 Mar 2022 21:59:40 +0000

Eli Zaretskii <[email-masked]> writes:

>> From: João Távora <[email-masked]>
>> Date: Mon, 21 Mar 2022 16:37:18 +0000
>> Cc: [email-masked], Dmitry Gutov <[email-masked]>
>> 
>> If you are aware of the behaviour change , then I don't see the point 
>> with coming up with a simpler repro: I'd just be showing what you 
>> confirmed: that move-to-column now is affected by overlays such
>> as company's whereas before (emacs 27.2/28) it didn't.
> The questions is: does current-column, move-to-column, etc. on master
> indeed report the column number and move to the place whose column
> number _on_display_ is as you ask them?  If they do, then this is the
> correct behavior, and features that expect something else should
> adapt.

I agree, though bug-compatibility is a thing sometimes :-)

Anyway, since you seem to know what changed in Emacs, can you show a
snippet which worked in some (presumably wrong) way in 27.1 and now
works correctly in master? Maybe that holds some valuable clue..

> But if move-to-column moves to a column that is visually incorrect,
> I'd still like a simple reproducer.

Hmmm.  I tried, but couldn't

(with-current-buffer (generate-new-buffer "**test**")
  (insert "foofoofoo\nbarbarbar\nbazbazbaz")
  (forward-line -1)
  (goto-char (line-beginning-position))
  (prog1
      (let ((o (make-overlay (+ 3 (point)) (+ 6 (point)))))
        (overlay-put o 'invisible t)
        (overlay-put o 'display (propertize "BAR" 'face 'highlight))
        (goto-char (line-beginning-position))
        (let ((p (point)))
          (move-to-column 3)
          (buffer-substring-no-properties p (point))))
    (pop-to-buffer (current-buffer))))

This constructs an overlay that hides/replaces some text and eventually
returns "barbar".  If the overlay weren't there it would return "bar",
obviously.  I don't now if "barbar" is correct.  It doesn't look
especially correct, but I wouldn't know what to return here either,
since the text below is invisible and has probably been skipped over.
At any rate, it's exactly the same that 27.1 does, so it's not the
problem we're after, I think.

So maybe Dmitry has some valuable insight as to how exactly company
constructs its overlay or overlays.

> Even if one must use company-mode and eglot, can you post a recipe
> that doesn't involve their installation via package.el?  Suppose I
> download the relevant *.el files to my system and manually load them
> as needed, can you show a recipe that loads whatever is needed and
> then reproduces the issue?

Yes, I can do that.  But note you still need the clangd executable
somewhere in your system to provide the completions.  In my system
it was just:

  sudo pacman -S clang

but packages exist for most (all?) GNU/Linux distributions and OSs.

Then, assuming:

  ~/Source/Emacs/emacs is a checkout of master Emacs
  ~/Source/Emacs/company-mode is a checkout of [email-masked]:company-mode/company-mode.git
  ~/Source/Emacs/eglot is a checkout of [email-masked]:joaotavora/eglot.git

IMPORTANT: You need Eglot to be checked out at d5c7c40b, before the
Eglot "defensive" fix.

Then finally, this should set you up and should show you the differences
beween 27.2 and master Emacs, where the former works and the latter
errors.  Obviously in the master version you don't need these 5 loads.

$ some-version-of-emacs -Q                                         \
  -l ~/Source/Emacs/emacs/lisp/emacs-lisp/eldoc.el                 \
  -l ~/Source/Emacs/emacs/lisp/progmodes/xref.el                   \
  -l ~/Source/Emacs/emacs/lisp/progmodes/flymake.el                \
  -l ~/Source/Emacs/emacs/lisp/progmodes/project.el                \
  -l ~/Source/Emacs/emacs/lisp/jsonrpc.el                          \
  -L ~/Source/Emacs/company-mode -l company -f global-company-mode \
  -L ~/Source/Emacs/eglot -l eglot.el                              \
  ~/tmp/issue-860/args_out_of_range.c                              \
  -f eglot                                                         \
  -f display-line-numbers-mode                                     \
  -f toggle-debug-on-error                                         

The args_out_of_range.c file's contents are

------BEGIN
// args_out_of_range.c
struct Book {
  int id;
  char title[50]
} book = { 1024, "C" };

int main(int argc, char *argv[])
{

  // Master errors when typing "book." i.e.
  // typing the dot after book
  book
  return 0;
}
------END

Hope this helps, 
João