unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Word completion in text modes
@ 2023-11-18 12:03 Eshel Yaron
  2023-11-18 12:39 ` Eli Zaretskii
  2023-11-18 18:33 ` Juri Linkov
  0 siblings, 2 replies; 20+ messages in thread
From: Eshel Yaron @ 2023-11-18 12:03 UTC (permalink / raw)
  To: emacs-devel

Hi Emacs,

I wonder how people here feel about updating `text-mode` to have it (and
its derivatives) use `completion-at-point` for word completion instead
of `ispell-complete-word`.  That'd be accompanied by a new
`ispell-completion-at-point` function that `text-mode` adds to
`completion-at-point-functions` so word completion still works OOTB,
just using a different interface.

I can see several advantages to making such a change:

1. Word completion would benefit from UI customizations and
   other enhancements that users have in place for `completion-at-point`.
2. `completion-preview-mode` and any other feature that leverages
   `completion-at-point-functions` would work for word completion as well.
3. Emacs would be slightly more consistent and simple all in all.

The main downside of this idea is that people who prefer the interface
that `ispell-complete-word` provides would need to rebind it to `C-M-i`
or some other key themselves.  Since this command has been around for a
very long time, I can imagine that some users may have grown fond of it.

So I have a WIP patch that adds `ispell-completion-at-point` (similar to
the one proposed in Bug#52743, but slightly enhanced) and updates
`text-mode` to use it.  If that sounds sensible and people are not that
attached to the `ispell-complete-word` interface for word completion,
I'll add some documentation updates and submit that patch for review.


Thanks,

Eshel



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Word completion in text modes
  2023-11-18 12:03 Word completion in text modes Eshel Yaron
@ 2023-11-18 12:39 ` Eli Zaretskii
  2023-11-18 13:21   ` Eshel Yaron
  2023-11-18 16:05   ` [External] : " Drew Adams
  2023-11-18 18:33 ` Juri Linkov
  1 sibling, 2 replies; 20+ messages in thread
From: Eli Zaretskii @ 2023-11-18 12:39 UTC (permalink / raw)
  To: Eshel Yaron; +Cc: emacs-devel

> From: Eshel Yaron <me@eshelyaron.com>
> Date: Sat, 18 Nov 2023 13:03:36 +0100
> 
> I wonder how people here feel about updating `text-mode` to have it (and
> its derivatives) use `completion-at-point` for word completion instead
> of `ispell-complete-word`.  That'd be accompanied by a new
> `ispell-completion-at-point` function that `text-mode` adds to
> `completion-at-point-functions` so word completion still works OOTB,
> just using a different interface.
> 
> I can see several advantages to making such a change:
> 
> 1. Word completion would benefit from UI customizations and
>    other enhancements that users have in place for `completion-at-point`.
> 2. `completion-preview-mode` and any other feature that leverages
>    `completion-at-point-functions` would work for word completion as well.
> 3. Emacs would be slightly more consistent and simple all in all.
> 
> The main downside of this idea is that people who prefer the interface
> that `ispell-complete-word` provides would need to rebind it to `C-M-i`
> or some other key themselves.  Since this command has been around for a
> very long time, I can imagine that some users may have grown fond of it.

I don't understand why users of ispell-complete-word would need to
rebind the command.  ispell-complete-word is by default not bound to
any key, so if we still provide ispell-complete-word, the old binding,
if there was one, should still work, and the only difference should be
the implementation details?  Or what did I miss?

In any case, would the text-mode completion-at-point support the
dictionaries used currently by ispell-complete-word?  If not, why not?

Btw, a really great addition to text-mode would be to have completion
that is based not only on dictionaries that suggest single words, but
also on dictionaries or other databases that suggest phrases based on
context.  IMNSHO, such a feature would be much more important and
useful than the minor changes of UI and reshuffling of the
implementation details of the sort that you propose.  Other
applications start offering this kind of features, so I think Emacs
should have it as well, as we are, after all, a text editor.  That is
not to say that what you suggest is unwelcome or something, just that
such internal cleanups are maybe not yet the most important and useful
change in developing and enhancing text-based modes, at least IMO.

> So I have a WIP patch that adds `ispell-completion-at-point` (similar to
> the one proposed in Bug#52743, but slightly enhanced) and updates
> `text-mode` to use it.  If that sounds sensible and people are not that
> attached to the `ispell-complete-word` interface for word completion,
> I'll add some documentation updates and submit that patch for review.

How would being "attached to the `ispell-complete-word` interface for
word completion" get in the way?  I'd like to understand this better
before we decide that this change should be installed, and how the
modified completion will work.

Thanks.



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Word completion in text modes
  2023-11-18 12:39 ` Eli Zaretskii
@ 2023-11-18 13:21   ` Eshel Yaron
  2023-11-18 13:50     ` Eli Zaretskii
  2023-11-18 16:05   ` [External] : " Drew Adams
  1 sibling, 1 reply; 20+ messages in thread
From: Eshel Yaron @ 2023-11-18 13:21 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

Eli Zaretskii <eliz@gnu.org> writes:

>> From: Eshel Yaron <me@eshelyaron.com>
>> Date: Sat, 18 Nov 2023 13:03:36 +0100
>> 
>> I wonder how people here feel about updating `text-mode` to have it (and
>> its derivatives) use `completion-at-point` for word completion instead
>> of `ispell-complete-word`.  That'd be accompanied by a new
>> `ispell-completion-at-point` function that `text-mode` adds to
>> `completion-at-point-functions` so word completion still works OOTB,
>> just using a different interface.
>> 
>> I can see several advantages to making such a change:
>> 
>> 1. Word completion would benefit from UI customizations and
>>    other enhancements that users have in place for `completion-at-point`.
>> 2. `completion-preview-mode` and any other feature that leverages
>>    `completion-at-point-functions` would work for word completion as well.
>> 3. Emacs would be slightly more consistent and simple all in all.
>> 
>> The main downside of this idea is that people who prefer the interface
>> that `ispell-complete-word` provides would need to rebind it to `C-M-i`
>> or some other key themselves.  Since this command has been around for a
>> very long time, I can imagine that some users may have grown fond of it.
>
> I don't understand why users of ispell-complete-word would need to
> rebind the command.  ispell-complete-word is by default not bound to
> any key, so if we still provide ispell-complete-word, the old binding,
> if there was one, should still work, and the only difference should be
> the implementation details?  Or what did I miss?

It _is_ bound to `C-M-i` in `text-mode`, that's actually even mentioned
in several places in the Emacs manual, e.g. in "(emacs) Text Mode":

    Text mode binds ‘M-<TAB>’ to ‘ispell-complete-word’.

> In any case, would the text-mode completion-at-point support the
> dictionaries used currently by ispell-complete-word?  If not, why not?

Yes, in my current implementation `ispell-completion-at-point` reuses
the same dictionaries as `ispell-complete-word`.

> Btw, a really great addition to text-mode would be to have completion
> that is based not only on dictionaries that suggest single words, but
> also on dictionaries or other databases that suggest phrases based on
> context.

I agree, that'd be great.

> IMNSHO, such a feature would be much more important and useful than
> the minor changes of UI and reshuffling of the implementation details
> of the sort that you propose.

My proposal would benefit this aim as well, I think, as we could simply
add another completion function to `completion-at-point-functions`, say
`phrase-completion-at-point`, and users would have their word completion
extended to include such phrase completion with no further setup.

> Other applications start offering this kind of features, so I think
> Emacs should have it as well, as we are, after all, a text editor.
> That is not to say that what you suggest is unwelcome or something,
> just that such internal cleanups are maybe not yet the most important
> and useful change in developing and enhancing text-based modes, at
> least IMO.
>
>> So I have a WIP patch that adds `ispell-completion-at-point` (similar to
>> the one proposed in Bug#52743, but slightly enhanced) and updates
>> `text-mode` to use it.  If that sounds sensible and people are not that
>> attached to the `ispell-complete-word` interface for word completion,
>> I'll add some documentation updates and submit that patch for review.
>
> How would being "attached to the `ispell-complete-word` interface for
> word completion" get in the way?

See above.  My concern here regards users that are used to pressing
`C-M-i` in `text-mode` and friends, and getting `ispell-complete-word`.
If we follow my suggestion of removing this binding, `C-M-i` would
invoke `completion-at-point`, providing similar functionality but with a
different interface (by default that would be the *Completions* buffer,
instead of the *Choices* buffer that `ispell-complete-word` provides).
Does that make sense?

> I'd like to understand this better before we decide that this change
> should be installed, and how the modified completion will work.
>
> Thanks.



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Word completion in text modes
  2023-11-18 13:21   ` Eshel Yaron
@ 2023-11-18 13:50     ` Eli Zaretskii
  2023-11-18 15:53       ` Eshel Yaron
  0 siblings, 1 reply; 20+ messages in thread
From: Eli Zaretskii @ 2023-11-18 13:50 UTC (permalink / raw)
  To: Eshel Yaron; +Cc: emacs-devel

> From: Eshel Yaron <me@eshelyaron.com>
> Cc: emacs-devel@gnu.org
> Date: Sat, 18 Nov 2023 14:21:30 +0100
> 
> Eli Zaretskii <eliz@gnu.org> writes:
> 
> > I don't understand why users of ispell-complete-word would need to
> > rebind the command.  ispell-complete-word is by default not bound to
> > any key, so if we still provide ispell-complete-word, the old binding,
> > if there was one, should still work, and the only difference should be
> > the implementation details?  Or what did I miss?
> 
> It _is_ bound to `C-M-i` in `text-mode`, that's actually even mentioned
> in several places in the Emacs manual, e.g. in "(emacs) Text Mode":
> 
>     Text mode binds ‘M-<TAB>’ to ‘ispell-complete-word’.

I tried that in mail-mode and didn't see it bound.  But that's because
mail-mode binds C-M-i to another command.  Which IMO is a sign of a
problem we need to fix: it makes no sense to have a completion command
bound in Text mode but not in _all_ of its descendants.  I guess the
developers of mail-mode didn't consider ispell-complete-word an
important enough feature, and the question then becomes: will the new
text-mode completion-at-point feature be significantly better?

In any case, back to the original issue: what you say about rebinding
ispell-complete-word can only be a problem if the new completion is
incompatible with ispell-complete-word.  So we should make sure it is
NOT incompatible.  Then the problem would not exist.

> > IMNSHO, such a feature would be much more important and useful than
> > the minor changes of UI and reshuffling of the implementation details
> > of the sort that you propose.
> 
> My proposal would benefit this aim as well, I think, as we could simply
> add another completion function to `completion-at-point-functions`, say
> `phrase-completion-at-point`, and users would have their word completion
> extended to include such phrase completion with no further setup.

I appreciate the enthusiasm, but very much doubt that minor internal
changes ("minor" from the POV of user-visible changes in behavior)
will eventually bring us important features such as powerful text-mode
completion.  Infrastructure that makes extensions easy is a Good
Thing, but it is not enough to actually make those extensions happen,
not by a long shot.  Which is why I prefer to make such internal
reshuffling only together with installing the corresponding
extensions, not as separate "cleanups".

> > How would being "attached to the `ispell-complete-word` interface for
> > word completion" get in the way?
> 
> See above.  My concern here regards users that are used to pressing
> `C-M-i` in `text-mode` and friends, and getting `ispell-complete-word`.
> If we follow my suggestion of removing this binding, `C-M-i` would
> invoke `completion-at-point`, providing similar functionality but with a
> different interface (by default that would be the *Completions* buffer,
> instead of the *Choices* buffer that `ispell-complete-word` provides).

If that is the danger, it follows that we should make the UI of
completion-at-point be able to support the UI of ispell-complete-word.

Btw, reusing the *Completions* buffer might cause problems on its own,
regardless of the ispell-complete-word issue: what if this completion
is invoked while typing at the prompt of a command that already popped
up the *Completions* buffer?  Something to think about, I guess, if we
are going to add more and more of these completion-at-point frameworks
and features.



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Word completion in text modes
  2023-11-18 13:50     ` Eli Zaretskii
@ 2023-11-18 15:53       ` Eshel Yaron
  2023-11-18 16:03         ` [External] : " Drew Adams
  2023-11-18 16:37         ` Eli Zaretskii
  0 siblings, 2 replies; 20+ messages in thread
From: Eshel Yaron @ 2023-11-18 15:53 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

Eli Zaretskii <eliz@gnu.org> writes:

>> It _is_ bound to `C-M-i` in `text-mode`, that's actually even mentioned
>> in several places in the Emacs manual, e.g. in "(emacs) Text Mode":
>>
>>     Text mode binds ‘M-<TAB>’ to ‘ispell-complete-word’.
>
> I tried that in mail-mode and didn't see it bound.  But that's because
> mail-mode binds C-M-i to another command.  Which IMO is a sign of a
> problem we need to fix: it makes no sense to have a completion command
> bound in Text mode but not in _all_ of its descendants.

Yes, `C-M-i` is bound to `completion-at-point` in `mail-mode-map`, which
is exactly the binding I'm proposing for the parent, `text-mode`, no?

> I guess the developers of mail-mode didn't consider
> ispell-complete-word an important enough feature, and the question
> then becomes: will the new text-mode completion-at-point feature be
> significantly better?
>
> In any case, back to the original issue: what you say about rebinding
> ispell-complete-word can only be a problem if the new completion is
> incompatible with ispell-complete-word.  So we should make sure it is
> NOT incompatible.  Then the problem would not exist.

The way I see it `ispell-complete-word` predates `completion-at-point`,
and in terms of functionality the latter subsumes the former.
`ispell-complete-word` reuses the spell correction UI of `ispell-word`
for word completion.  That's something that I wouldn't necessarily try
to port over to `completion-at-point` for compatibility sake, as we now
have various proper completion (not spell correction) interfaces that
were not available when `ispell-complete-word` came about.  Either way
it'd be compatible in the sense that you get the same completions, and
`ispell-complete-word` wouldn't go anywhere so users could rebind it if
they really want to.

>> > IMNSHO, such a feature would be much more important and useful than
>> > the minor changes of UI and reshuffling of the implementation details
>> > of the sort that you propose.
>>
>> My proposal would benefit this aim as well, I think, as we could simply
>> add another completion function to `completion-at-point-functions`, say
>> `phrase-completion-at-point`, and users would have their word completion
>> extended to include such phrase completion with no further setup.
>
> I appreciate the enthusiasm, but very much doubt that minor internal
> changes ("minor" from the POV of user-visible changes in behavior)
> will eventually bring us important features such as powerful text-mode
> completion.  Infrastructure that makes extensions easy is a Good
> Thing, but it is not enough to actually make those extensions happen,
> not by a long shot.

Absolutely, there's some more work to be done to accomplish what you
describe, no magic solutions here.  I propose to modernize completion in
text modes, opening a door for further developments.

> Which is why I prefer to make such internal reshuffling only together
> with installing the corresponding extensions, not as separate
> "cleanups".

Alright, although IMO this has concrete benefits beyond mere cleanup.
I'm fine with keeping this patch in a local branch for now, of course.

>> My concern here regards users that are used to pressing `C-M-i` in
>> `text-mode` and friends, and getting `ispell-complete-word`.  If we
>> follow my suggestion of removing this binding, `C-M-i` would invoke
>> `completion-at-point`, providing similar functionality but with a
>> different interface (by default that would be the *Completions*
>> buffer, instead of the *Choices* buffer that `ispell-complete-word`
>> provides).
>
> If that is the danger, it follows that we should make the UI of
> completion-at-point be able to support the UI of ispell-complete-word.

Sure, we could also add a `completion-in-region-function` that imitates
the current UI of `ispell-complete-word`, although IMO it's not really
an ideal interface for completions, so I'm not sure users would like
that for the rest of their `completion-at-point` calls.  That could be
made local in text mode buffers, perhaps.

> Btw, reusing the *Completions* buffer might cause problems on its own,
> regardless of the ispell-complete-word issue: what if this completion
> is invoked while typing at the prompt of a command that already popped
> up the *Completions* buffer?

That's interesting.  I guess Emacs could keep a stack of such nested
completion sessions and restore the first session when the other ends.
I'm not sure if there's something of that sorts in place.  Indeed,
that's a broader issue than the one at hand.

> Something to think about, I guess, if we are going to add more and
> more of these completion-at-point frameworks and features.


Thanks,

Eshel



^ permalink raw reply	[flat|nested] 20+ messages in thread

* RE: [External] : Re: Word completion in text modes
  2023-11-18 15:53       ` Eshel Yaron
@ 2023-11-18 16:03         ` Drew Adams
  2023-11-18 16:37         ` Eli Zaretskii
  1 sibling, 0 replies; 20+ messages in thread
From: Drew Adams @ 2023-11-18 16:03 UTC (permalink / raw)
  To: Eshel Yaron, Eli Zaretskii; +Cc: emacs-devel@gnu.org

> > Btw, reusing the *Completions* buffer might cause problems on its own,
> > regardless of the ispell-complete-word issue: what if this completion
> > is invoked while typing at the prompt of a command that already popped
> > up the *Completions* buffer?
> 
> That's interesting.  I guess Emacs could keep a stack of such nested
> completion sessions and restore the first session when the other ends.
> I'm not sure if there's something of that sorts in place.

There is something: recursive editing levels.

https://www.gnu.org/software/emacs/manual/html_node/emacs/Recursive-Edit.html

___

See also the little library `rec-edit.el'.
Among other things, it can help you deal
with the "Stuck Recursive" problem.

https://www.emacswiki.org/emacs/download/rec-edit.el

https://www.emacswiki.org/emacs/RecursiveEdit#rec-edit.el

https://www.gnu.org/software/emacs/manual/html_node/emacs/Stuck-Recursive.html


^ permalink raw reply	[flat|nested] 20+ messages in thread

* RE: [External] : Re: Word completion in text modes
  2023-11-18 12:39 ` Eli Zaretskii
  2023-11-18 13:21   ` Eshel Yaron
@ 2023-11-18 16:05   ` Drew Adams
  2023-11-18 16:55     ` Juergen Fenn
  1 sibling, 1 reply; 20+ messages in thread
From: Drew Adams @ 2023-11-18 16:05 UTC (permalink / raw)
  To: Eli Zaretskii, Eshel Yaron; +Cc: emacs-devel@gnu.org

> Btw, a really great addition to text-mode would be to have completion
> that is based not only on dictionaries that suggest single words, but
> also on dictionaries or other databases that suggest phrases based on
> context.

I don't even use in-buffer word etc. completion
much, but this sounds like a good idea to me!



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Word completion in text modes
  2023-11-18 15:53       ` Eshel Yaron
  2023-11-18 16:03         ` [External] : " Drew Adams
@ 2023-11-18 16:37         ` Eli Zaretskii
  2023-11-18 19:03           ` Eshel Yaron
  1 sibling, 1 reply; 20+ messages in thread
From: Eli Zaretskii @ 2023-11-18 16:37 UTC (permalink / raw)
  To: Eshel Yaron; +Cc: emacs-devel

> From: Eshel Yaron <me@eshelyaron.com>
> Cc: emacs-devel@gnu.org
> Date: Sat, 18 Nov 2023 16:53:28 +0100
> 
> Eli Zaretskii <eliz@gnu.org> writes:
> 
> >> It _is_ bound to `C-M-i` in `text-mode`, that's actually even mentioned
> >> in several places in the Emacs manual, e.g. in "(emacs) Text Mode":
> >>
> >>     Text mode binds ‘M-<TAB>’ to ‘ispell-complete-word’.
> >
> > I tried that in mail-mode and didn't see it bound.  But that's because
> > mail-mode binds C-M-i to another command.  Which IMO is a sign of a
> > problem we need to fix: it makes no sense to have a completion command
> > bound in Text mode but not in _all_ of its descendants.
> 
> Yes, `C-M-i` is bound to `completion-at-point` in `mail-mode-map`, which
> is exactly the binding I'm proposing for the parent, `text-mode`, no?

I was talking about ispell-complete-word, not about C-M-i.

And if you turn on Flyspell mode, as many users do in Mail buffers,
C-M-i gets rebound yet again.

> > In any case, back to the original issue: what you say about rebinding
> > ispell-complete-word can only be a problem if the new completion is
> > incompatible with ispell-complete-word.  So we should make sure it is
> > NOT incompatible.  Then the problem would not exist.
> 
> The way I see it `ispell-complete-word` predates `completion-at-point`,
> and in terms of functionality the latter subsumes the former.

Not according to your own description, below.

> `ispell-complete-word` reuses the spell correction UI of `ispell-word`
> for word completion.  That's something that I wouldn't necessarily try
> to port over to `completion-at-point` for compatibility sake, as we now
> have various proper completion (not spell correction) interfaces that
> were not available when `ispell-complete-word` came about.

If we don't preserve that UI, we will be making an incompatible
change, which from my POV is undesirable.  It doesn't matter whether
we like or dislike the ispell UI for this: compatibility means just
that.  We could make the old UI an opt-in behavior, but tossing it
altogether is not something I'd welcome.

> Either way it'd be compatible in the sense that you get the same
> completions, and `ispell-complete-word` wouldn't go anywhere so
> users could rebind it if they really want to.

That is not compatibility in my book, sorry.  We should actually offer
a very similar or identical UI.



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [External] : Re: Word completion in text modes
  2023-11-18 16:05   ` [External] : " Drew Adams
@ 2023-11-18 16:55     ` Juergen Fenn
  0 siblings, 0 replies; 20+ messages in thread
From: Juergen Fenn @ 2023-11-18 16:55 UTC (permalink / raw)
  To: emacs-devel



Am 18.11.23 um 17:05 Uhr schrieb Drew Adams:
>> Btw, a really great addition to text-mode would be to have completion
>> that is based not only on dictionaries that suggest single words, but
>> also on dictionaries or other databases that suggest phrases based on
>> context.
>
> I don't even use in-buffer word etc. completion
> much, but this sounds like a good idea to me!

It's easy to realise. I keep a notebook buffer in Org open where most of
the completion-at-point suggestions in my sessions come from. You could
say this is a kind of dictionary for the vocabulary I keep using.

Please also think of language environments. Most languages are much more
complex than English and need special attention for completion (case,
punctuation, etc.).

BTW, at the beginning of this month we had another discussion of
completion-at-point under the subject "Inline completion preview".

Regards,
Jürgen.



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Word completion in text modes
  2023-11-18 12:03 Word completion in text modes Eshel Yaron
  2023-11-18 12:39 ` Eli Zaretskii
@ 2023-11-18 18:33 ` Juri Linkov
  1 sibling, 0 replies; 20+ messages in thread
From: Juri Linkov @ 2023-11-18 18:33 UTC (permalink / raw)
  To: Eshel Yaron; +Cc: emacs-devel

> 1. Word completion would benefit from UI customizations and
>    other enhancements that users have in place for `completion-at-point`.
> 2. `completion-preview-mode` and any other feature that leverages
>    `completion-at-point-functions` would work for word completion as well.
> 3. Emacs would be slightly more consistent and simple all in all.

When I tested `completion-preview-mode`, I noticed it was quite unusable
in the comments of prog-mode.  But I'm unsure what would make more sense.
Maybe dabbrev-capf?



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Word completion in text modes
  2023-11-18 16:37         ` Eli Zaretskii
@ 2023-11-18 19:03           ` Eshel Yaron
  2023-11-18 19:18             ` Eli Zaretskii
  0 siblings, 1 reply; 20+ messages in thread
From: Eshel Yaron @ 2023-11-18 19:03 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

Eli Zaretskii <eliz@gnu.org> writes:

>> From: Eshel Yaron <me@eshelyaron.com>
>> Cc: emacs-devel@gnu.org
>> Date: Sat, 18 Nov 2023 16:53:28 +0100
>>
>> `ispell-complete-word` reuses the spell correction UI of `ispell-word`
>> for word completion.  That's something that I wouldn't necessarily try
>> to port over to `completion-at-point` for compatibility sake, as we now
>> have various proper completion (not spell correction) interfaces that
>> were not available when `ispell-complete-word` came about.
>
> If we don't preserve that UI, we will be making an incompatible
> change, which from my POV is undesirable.  It doesn't matter whether
> we like or dislike the ispell UI for this: compatibility means just
> that.  We could make the old UI an opt-in behavior, but tossing it
> altogether is not something I'd welcome.

I think we mostly agree then, because I didn't suggest tossing the old
UI anywhere.  To opt-in to the old behavior, you'd say:

  (keymap-set text-mode-map "C-M-i" #'ispell-complete-word)

That seems to me like a simple enough tip for users that we could appear
in a NEWS entry.  Does that sound reasonable?

>> Either way it'd be compatible in the sense that you get the same
>> completions, and `ispell-complete-word` wouldn't go anywhere so
>> users could rebind it if they really want to.
>
> That is not compatibility in my book, sorry.  We should actually offer
> a very similar or identical UI.

Yes, I wonder just wonder how should we offer that UI.  Doesn't keeping
the command around for users to make use of cover it?  Or do you mean
there should be some user option for selecting the word completion UI?



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Word completion in text modes
  2023-11-18 19:03           ` Eshel Yaron
@ 2023-11-18 19:18             ` Eli Zaretskii
  2023-11-21 13:45               ` Eshel Yaron
  0 siblings, 1 reply; 20+ messages in thread
From: Eli Zaretskii @ 2023-11-18 19:18 UTC (permalink / raw)
  To: Eshel Yaron; +Cc: emacs-devel

> From: Eshel Yaron <me@eshelyaron.com>
> Cc: emacs-devel@gnu.org
> Date: Sat, 18 Nov 2023 20:03:45 +0100
> 
> Eli Zaretskii <eliz@gnu.org> writes:
> 
> > If we don't preserve that UI, we will be making an incompatible
> > change, which from my POV is undesirable.  It doesn't matter whether
> > we like or dislike the ispell UI for this: compatibility means just
> > that.  We could make the old UI an opt-in behavior, but tossing it
> > altogether is not something I'd welcome.
> 
> I think we mostly agree then, because I didn't suggest tossing the old
> UI anywhere.  To opt-in to the old behavior, you'd say:
> 
>   (keymap-set text-mode-map "C-M-i" #'ispell-complete-word)
> 
> That seems to me like a simple enough tip for users that we could appear
> in a NEWS entry.  Does that sound reasonable?

I'd prefer a solution that didn't require key bindings.  Something
like a user option.

> >> Either way it'd be compatible in the sense that you get the same
> >> completions, and `ispell-complete-word` wouldn't go anywhere so
> >> users could rebind it if they really want to.
> >
> > That is not compatibility in my book, sorry.  We should actually offer
> > a very similar or identical UI.
> 
> Yes, I wonder just wonder how should we offer that UI.  Doesn't keeping
> the command around for users to make use of cover it?  Or do you mean
> there should be some user option for selecting the word completion UI?

I think an option will be better.



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Word completion in text modes
  2023-11-18 19:18             ` Eli Zaretskii
@ 2023-11-21 13:45               ` Eshel Yaron
  2023-11-25 10:40                 ` Eli Zaretskii
  0 siblings, 1 reply; 20+ messages in thread
From: Eshel Yaron @ 2023-11-21 13:45 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

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

Eli Zaretskii <eliz@gnu.org> writes:

>> From: Eshel Yaron <me@eshelyaron.com>
>> Cc: emacs-devel@gnu.org
>> Date: Sat, 18 Nov 2023 20:03:45 +0100
>>
>> Eli Zaretskii <eliz@gnu.org> writes:
>>
>> > ...We could make the old UI an opt-in behavior, but tossing it
>> > altogether is not something I'd welcome.
>>
>> I think we mostly agree then, because I didn't suggest tossing the old
>> UI anywhere.  To opt-in to the old behavior, you'd say:
>>
>>   (keymap-set text-mode-map "C-M-i" #'ispell-complete-word)
>>
>> That seems to me like a simple enough tip for users that we could appear
>> in a NEWS entry.  Does that sound reasonable?
>
> I'd prefer a solution that didn't require key bindings.  Something
> like a user option.

That'd indeed be more convenient for some users, I suppose.
I'm attaching below a patch that facilitates using `completion-at-point`
in Text mode instead of `ispell-complete-word` by default.  Other than
the somewhat awkward name of the user option that restores the binding,
I'm pretty happy with this patch as it brings about the three benefits I
outlined in my original message in this thread.  WDYT?



[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Unbind-C-M-i-in-Text-mode.patch --]
[-- Type: text/x-patch, Size: 9589 bytes --]

From 8d03bec5f8825704f4e85cd0e5b57877a29bf40f Mon Sep 17 00:00:00 2001
From: Eshel Yaron <me@eshelyaron.com>
Date: Tue, 21 Nov 2023 12:39:23 +0100
Subject: [PATCH] Unbind 'C-M-i' in Text mode

Remove the binding of 'C-M-i' to 'ispell-complete-word' in Text mode.
Define a new 'ispell-completion-at-point' function and add that to
'completion-at-point-functions' in Text mode, such that
'completion-at-point' provides the same word completions as
'ispell-complete-word' does OOTB.

* lisp/textmodes/ispell.el (ispell-completion-at-point): New function.
* lisp/textmodes/text-mode.el (text-mode): Add it to 'c-a-p-functions'.
(text-mode-map): Remove 'C-M-i' binding.
(text-mode-meta-tab-ispell-complete-word): New user option.
* etc/NEWS: Announce it.
* doc/emacs/fixit.texi (Spelling)
* doc/emacs/text.texi (Text Mode)
* doc/lispref/modes.texi (Basic Major Modes)
(Example Major Modes): Update.
* lisp/mail/sendmail.el (mail-abbrevs-loaded)
* lisp/nxml/nxml-mode.el (nxml-mode-map): Remove superfluous binding.
---
 doc/emacs/fixit.texi        | 16 ++++------------
 doc/emacs/text.texi         | 12 ++++++------
 doc/lispref/modes.texi      | 13 +------------
 etc/NEWS                    |  9 +++++++++
 lisp/mail/sendmail.el       |  1 -
 lisp/nxml/nxml-mode.el      |  1 -
 lisp/textmodes/ispell.el    | 22 ++++++++++++++++++++++
 lisp/textmodes/text-mode.el | 18 +++++++++++++++---
 8 files changed, 57 insertions(+), 35 deletions(-)

diff --git a/doc/emacs/fixit.texi b/doc/emacs/fixit.texi
index 78503d31a38..51814ab30e0 100644
--- a/doc/emacs/fixit.texi
+++ b/doc/emacs/fixit.texi
@@ -292,11 +292,6 @@ Spelling
 Restart the spell-checker process, using @var{dict} as the dictionary.
 @item M-x ispell-kill-ispell
 Kill the spell-checker subprocess.
-@item M-@key{TAB}
-@itemx @key{ESC} @key{TAB}
-@itemx C-M-i
-Complete the word before point based on the spelling dictionary
-(@code{ispell-complete-word}).
 @item M-x flyspell-mode
 Enable Flyspell mode, which highlights all misspelled words.
 @item M-x flyspell-prog-mode
@@ -398,14 +393,11 @@ Spelling
 Show the list of options.
 @end table
 
-@findex ispell-complete-word
-  In Text mode and related modes, @kbd{M-@key{TAB}}
-(@code{ispell-complete-word}) performs in-buffer completion based on
-spelling correction.  Insert the beginning of a word, and then type
-@kbd{M-@key{TAB}}; this shows a list of completions.  (If your
+  Use the command @kbd{M-@key{TAB}} (@code{completion-at-point}) to
+complete the word at point.  Insert the beginning of a word, and then
+type @kbd{M-@key{TAB}} to select from a list of completions.  (If your
 window manager intercepts @kbd{M-@key{TAB}}, type @w{@kbd{@key{ESC}
-@key{TAB}}} or @kbd{C-M-i}.)  Each completion is listed with a digit or
-character; type that digit or character to choose it.
+@key{TAB}}} or @kbd{C-M-i}.)
 
 @cindex @code{ispell} program
 @findex ispell-kill-ispell
diff --git a/doc/emacs/text.texi b/doc/emacs/text.texi
index 6f57bae8fef..b6a9dd6de53 100644
--- a/doc/emacs/text.texi
+++ b/doc/emacs/text.texi
@@ -943,12 +943,12 @@ Text Mode
 composition, for instance.
 
 @kindex M-TAB @r{(Text mode)}
-  Text mode binds @kbd{M-@key{TAB}} to @code{ispell-complete-word}.
-This command performs completion of the partial word in the buffer
-before point, using the spelling dictionary as the space of possible
-words.  @xref{Spelling}.  If your window manager defines
-@kbd{M-@key{TAB}} to switch windows, you can type @kbd{@key{ESC}
-@key{TAB}} or @kbd{C-M-i} instead.
+  The command @kbd{M-@key{TAB}} (@code{completion-at-point}) performs
+completion of the partial word in the buffer before point, using the
+spelling dictionary as the space of possible words by default.
+@xref{Spelling}.  If your window manager defines @kbd{M-@key{TAB}} to
+switch windows, you can type @kbd{@key{ESC} @key{TAB}} or @kbd{C-M-i}
+instead.
 
 @vindex text-mode-hook
   Entering Text mode runs the mode hook @code{text-mode-hook}
diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi
index 8670807cbdf..ffd7ad7f51d 100644
--- a/doc/lispref/modes.texi
+++ b/doc/lispref/modes.texi
@@ -981,9 +981,7 @@ Basic Major Modes
 @deffn Command text-mode
 Text mode is a major mode for editing human languages.  It defines the
 @samp{"} and @samp{\} characters as having punctuation syntax
-(@pxref{Syntax Class Table}), and binds @kbd{M-@key{TAB}} to
-@code{ispell-complete-word} (@pxref{Spelling,,, emacs, The GNU Emacs
-Manual}).
+(@pxref{Syntax Class Table}).
 
 An example of a major mode derived from Text mode is HTML mode.
 @xref{HTML Mode,,SGML and HTML Modes, emacs, The GNU Emacs Manual}.
@@ -1377,15 +1375,6 @@ Example Major Modes
     st)
   "Syntax table used while in `text-mode'.")
 @end group
-
-;; @r{Create the keymap for this mode.}
-@group
-(defvar-keymap text-mode-map
-  :doc "Keymap for `text-mode'.
-Many other modes, such as `mail-mode' and `outline-mode', inherit all
-the commands defined in this map."
-  "C-M-i" #'ispell-complete-word)
-@end group
 @end smallexample
 
   Here is how the actual mode command is defined now:
diff --git a/etc/NEWS b/etc/NEWS
index e14d15a7487..b0653a3ff20 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1116,6 +1116,15 @@ showcases all their customization options.
 \f
 * Incompatible Lisp Changes in Emacs 30.1
 
++++
+** 'M-TAB' now invokes 'completion-at-point' also in Text mode.
+Text mode no longer binds 'M-TAB' to 'ispell-complete-word', and
+instead this mode arranges for 'completion-at-point', globally bound
+to 'M-TAB', to perform word completion as well.  If you want 'M-TAB'
+to invoke 'ispell-complete-word', as it did in previous Emacs
+versions, customize the new option
+'text-mode-meta-tab-ispell-complete-word' to non-nil.
+
 ** 'pp' and 'pp-to-string' now always include a terminating newline.
 In the past they included a terminating newline in most cases but not all.
 
diff --git a/lisp/mail/sendmail.el b/lisp/mail/sendmail.el
index 8306bd3b30c..b5dd5322ec1 100644
--- a/lisp/mail/sendmail.el
+++ b/lisp/mail/sendmail.el
@@ -269,7 +269,6 @@ mail-citation-prefix-regexp
 (defvar mail-abbrevs-loaded nil)
 (defvar mail-mode-map
   (let ((map (make-sparse-keymap)))
-    (define-key map "\M-\t" 'completion-at-point)
     (define-key map "\C-c?" 'describe-mode)
     (define-key map "\C-c\C-f\C-t" 'mail-to)
     (define-key map "\C-c\C-f\C-b" 'mail-bcc)
diff --git a/lisp/nxml/nxml-mode.el b/lisp/nxml/nxml-mode.el
index 67d136b5a66..bc32598003e 100644
--- a/lisp/nxml/nxml-mode.el
+++ b/lisp/nxml/nxml-mode.el
@@ -390,7 +390,6 @@ nxml-mode-map
   "C-c C-u" #'nxml-insert-named-char
   "C-c C-o" nxml-outline-prefix-map
   "/"       #'nxml-electric-slash
-  "M-TAB"   #'completion-at-point
   "S-<mouse-2>" #'nxml-mouse-hide-direct-text-content)
 
 (defvar nxml-font-lock-keywords
diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el
index b71e85b0e37..8fdf9a764aa 100644
--- a/lisp/textmodes/ispell.el
+++ b/lisp/textmodes/ispell.el
@@ -3680,6 +3680,28 @@ ispell-horiz-scroll
 	  (if (>= column (- (window-width) 2))
 	      (scroll-left (max (- column (window-width) -3) 10)))))))
 
+;;;###autoload
+(defun ispell-completion-at-point ()
+  "Word completion function for use in `completion-at-point-functions'."
+  (pcase (bounds-of-thing-at-point 'word)
+    (`(,beg . ,end)
+     (when (and (< beg (point)) (<= (point) end))
+       (let* ((word (buffer-substring-no-properties beg end))
+              (len (length word))
+              (inhibit-message t)
+              (all (cons word (ispell-lookup-words word)))
+              (cur all))
+         (while cur
+           (unless (string-prefix-p word (car cur))
+             (setcar cur (concat word (substring (car cur) len))))
+           (while (when-let ((next (cadr cur)))
+                    (not (string-prefix-p word next t)))
+             (setcdr cur (cddr cur)))
+           (setq cur (cdr cur)))
+         (list beg end (cdr all)
+               :annotation-function (lambda (_) " Dictionary word")
+               :exclusive 'no))))))
+
 
 ;;; Interactive word completion.
 ;; Forces "previous-word" processing.  Do we want to make this selectable?
diff --git a/lisp/textmodes/text-mode.el b/lisp/textmodes/text-mode.el
index ccba1b063ab..607702da48f 100644
--- a/lisp/textmodes/text-mode.el
+++ b/lisp/textmodes/text-mode.el
@@ -73,8 +73,19 @@ text-mode-syntax-table
 (defvar-keymap text-mode-map
   :doc "Keymap for `text-mode'.
 Many other modes, such as `mail-mode' and `outline-mode', inherit
-all the commands defined in this map."
-  "C-M-i" #'ispell-complete-word)
+all the commands defined in this map.")
+
+(defcustom text-mode-meta-tab-ispell-complete-word nil
+  "Whether M-TAB invokes `ispell-complete-word' in Text mode.
+
+This user option only takes effect when you customize it in
+Custom or with `setopt', not with `setq'."
+  :group 'text
+  :type 'boolean
+  :set (lambda (sym val)
+         (if (set sym val)
+	     (keymap-set text-mode-map "C-M-i" #'ispell-complete-word)
+           (keymap-unset text-mode-map "C-M-i" t))))
 
 (easy-menu-define text-mode-menu text-mode-map
   "Menu for `text-mode'."
@@ -131,7 +142,8 @@ text-mode
 
   ;; Enable text conversion in this buffer.
   (setq-local text-conversion-style t)
-  (add-hook 'context-menu-functions 'text-mode-context-menu 10 t))
+  (add-hook 'context-menu-functions 'text-mode-context-menu 10 t)
+  (add-hook 'completion-at-point-functions #'ispell-completion-at-point 10 t))
 
 (define-derived-mode paragraph-indent-text-mode text-mode "Parindent"
   "Major mode for editing text, with leading spaces starting a paragraph.
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: Word completion in text modes
  2023-11-21 13:45               ` Eshel Yaron
@ 2023-11-25 10:40                 ` Eli Zaretskii
  2023-11-25 12:11                   ` Eshel Yaron
  0 siblings, 1 reply; 20+ messages in thread
From: Eli Zaretskii @ 2023-11-25 10:40 UTC (permalink / raw)
  To: Eshel Yaron; +Cc: emacs-devel

> From: Eshel Yaron <me@eshelyaron.com>
> Cc: emacs-devel@gnu.org
> Date: Tue, 21 Nov 2023 14:45:01 +0100
> 
> Eli Zaretskii <eliz@gnu.org> writes:
> 
> > I'd prefer a solution that didn't require key bindings.  Something
> > like a user option.
> 
> That'd indeed be more convenient for some users, I suppose.
> I'm attaching below a patch that facilitates using `completion-at-point`
> in Text mode instead of `ispell-complete-word` by default.  Other than
> the somewhat awkward name of the user option that restores the binding,
> I'm pretty happy with this patch as it brings about the three benefits I
> outlined in my original message in this thread.  WDYT?

See some comments below.

> diff --git a/doc/emacs/fixit.texi b/doc/emacs/fixit.texi
> index 78503d31a38..51814ab30e0 100644
> --- a/doc/emacs/fixit.texi
> +++ b/doc/emacs/fixit.texi
> @@ -292,11 +292,6 @@ Spelling
>  Restart the spell-checker process, using @var{dict} as the dictionary.
>  @item M-x ispell-kill-ispell
>  Kill the spell-checker subprocess.
> -@item M-@key{TAB}
> -@itemx @key{ESC} @key{TAB}
> -@itemx C-M-i
> -Complete the word before point based on the spelling dictionary
> -(@code{ispell-complete-word}).
>  @item M-x flyspell-mode
>  Enable Flyspell mode, which highlights all misspelled words.
>  @item M-x flyspell-prog-mode
> @@ -398,14 +393,11 @@ Spelling
>  Show the list of options.
>  @end table
>  
> -@findex ispell-complete-word
> -  In Text mode and related modes, @kbd{M-@key{TAB}}
> -(@code{ispell-complete-word}) performs in-buffer completion based on
> -spelling correction.  Insert the beginning of a word, and then type
> -@kbd{M-@key{TAB}}; this shows a list of completions.  (If your
> +  Use the command @kbd{M-@key{TAB}} (@code{completion-at-point}) to
> +complete the word at point.  Insert the beginning of a word, and then
> +type @kbd{M-@key{TAB}} to select from a list of completions.  (If your
>  window manager intercepts @kbd{M-@key{TAB}}, type @w{@kbd{@key{ESC}
> -@key{TAB}}} or @kbd{C-M-i}.)  Each completion is listed with a digit or
> -character; type that digit or character to choose it.
> +@key{TAB}}} or @kbd{C-M-i}.)

The removal of the command from the summary violates our conventions
in such sections: we first show a summary of the commands described by
the section, and then have their full description.  So please don't
remove the command from the summary; instead, change the description
and the command name to follow the code changes.

> diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi
> index 8670807cbdf..ffd7ad7f51d 100644
> --- a/doc/lispref/modes.texi
> +++ b/doc/lispref/modes.texi
> @@ -981,9 +981,7 @@ Basic Major Modes
>  @deffn Command text-mode
>  Text mode is a major mode for editing human languages.  It defines the
>  @samp{"} and @samp{\} characters as having punctuation syntax
> -(@pxref{Syntax Class Table}), and binds @kbd{M-@key{TAB}} to
> -@code{ispell-complete-word} (@pxref{Spelling,,, emacs, The GNU Emacs
> -Manual}).
> +(@pxref{Syntax Class Table}).

Why remove the reference to the command binding here?

> +(defcustom text-mode-meta-tab-ispell-complete-word nil
> +  "Whether M-TAB invokes `ispell-complete-word' in Text mode.
> +
> +This user option only takes effect when you customize it in
> +Custom or with `setopt', not with `setq'."
> +  :group 'text
> +  :type 'boolean
> +  :set (lambda (sym val)
> +         (if (set sym val)
> +	     (keymap-set text-mode-map "C-M-i" #'ispell-complete-word)
> +           (keymap-unset text-mode-map "C-M-i" t))))

The :version tag is missing.

Did you check what happens when Flyspell mode is turned on in a buffer
under Text mode or one of its descendants?

Thanks.



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Word completion in text modes
  2023-11-25 10:40                 ` Eli Zaretskii
@ 2023-11-25 12:11                   ` Eshel Yaron
  2023-11-25 12:33                     ` Eli Zaretskii
  0 siblings, 1 reply; 20+ messages in thread
From: Eshel Yaron @ 2023-11-25 12:11 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

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

Eli Zaretskii <eliz@gnu.org> writes:

>> From: Eshel Yaron <me@eshelyaron.com>
>>
>> I'm attaching below a patch that facilitates using `completion-at-point`
>> in Text mode instead of `ispell-complete-word` by default.  Other than
>> the somewhat awkward name of the user option that restores the binding,
>> I'm pretty happy with this patch as it brings about the three benefits I
>> outlined in my original message in this thread.  WDYT?
>
> See some comments below.
>
>> diff --git a/doc/emacs/fixit.texi b/doc/emacs/fixit.texi
>> index 78503d31a38..51814ab30e0 100644
>> --- a/doc/emacs/fixit.texi
>> +++ b/doc/emacs/fixit.texi
>> @@ -292,11 +292,6 @@ Spelling
>>  Restart the spell-checker process, using @var{dict} as the dictionary.
>>  @item M-x ispell-kill-ispell
>>  Kill the spell-checker subprocess.
>> -@item M-@key{TAB}
>> -@itemx @key{ESC} @key{TAB}
>> -@itemx C-M-i
>> -Complete the word before point based on the spelling dictionary
>> -(@code{ispell-complete-word}).
>>  @item M-x flyspell-mode
>>  Enable Flyspell mode, which highlights all misspelled words.
>>  @item M-x flyspell-prog-mode
>>
>>  ...

> The removal of the command from the summary violates our conventions
> in such sections: we first show a summary of the commands described by
> the section, and then have their full description.  So please don't
> remove the command from the summary; instead, change the description
> and the command name to follow the code changes.

I see, done in the updated patch I'm attaching below.

>> diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi
>> index 8670807cbdf..ffd7ad7f51d 100644
>> --- a/doc/lispref/modes.texi
>> +++ b/doc/lispref/modes.texi
>> @@ -981,9 +981,7 @@ Basic Major Modes
>>  @deffn Command text-mode
>>  Text mode is a major mode for editing human languages.  It defines the
>>  @samp{"} and @samp{\} characters as having punctuation syntax
>> -(@pxref{Syntax Class Table}), and binds @kbd{M-@key{TAB}} to
>> -@code{ispell-complete-word} (@pxref{Spelling,,, emacs, The GNU Emacs
>> -Manual}).
>> +(@pxref{Syntax Class Table}).
>
> Why remove the reference to the command binding here?

Text mode no longer binds `C-M-i` to anything, relying on the global
binding instead.  So there doesn't seem to be any reason to mention this
binding here anymore, just like it's not mentioned in the description of
`prog-mode` that follows this paragraph.  Does that make sense?

>> +(defcustom text-mode-meta-tab-ispell-complete-word nil
>> +  "Whether M-TAB invokes `ispell-complete-word' in Text mode.
>> +
>> +This user option only takes effect when you customize it in
>> +Custom or with `setopt', not with `setq'."
>> +  :group 'text
>> +  :type 'boolean
>> +  :set (lambda (sym val)
>> +         (if (set sym val)
>> +	     (keymap-set text-mode-map "C-M-i" #'ispell-complete-word)
>> +           (keymap-unset text-mode-map "C-M-i" t))))
>
> The :version tag is missing.

Thanks, I've added it in the updated patch.

> Did you check what happens when Flyspell mode is turned on in a buffer
> under Text mode or one of its descendants?

Yes.  Unless one sets `flyspell-use-meta-tab` to nil, Flyspell mode binds
`C-M-i` to a completely different command, `flyspell-auto-correct-word`.
That is something that people are hopefully aware of when they opt-in to
enabling of this minor mode, I suppose.  Personally, I don't really like that
behavior, so I unbind many of Flyspell's bindings.  I'd be happy to see
`flyspell-use-meta-tab` set to nil be default, but since Flyspell is opt-in,
I consider it a bit of a different story compared to the Text mode binding.


Patch v2 follows:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: v2-0001-Unbind-C-M-i-in-Text-mode.patch --]
[-- Type: text/x-patch, Size: 9597 bytes --]

From 6fb2bf3476bd0f2323ad921aef0c91cb60d2bf2c Mon Sep 17 00:00:00 2001
From: Eshel Yaron <me@eshelyaron.com>
Date: Tue, 21 Nov 2023 12:39:23 +0100
Subject: [PATCH v2] Unbind 'C-M-i' in Text mode

Remove the binding of 'C-M-i' to 'ispell-complete-word' in Text mode.
Define a new 'ispell-completion-at-point' function and add that to
'completion-at-point-functions' in Text mode, such that
'completion-at-point' provides the same word completions as
'ispell-complete-word' does OOTB.

* lisp/textmodes/ispell.el (ispell-completion-at-point): New function.
* lisp/textmodes/text-mode.el (text-mode): Add it to 'c-a-p-functions'.
(text-mode-map): Remove 'C-M-i' binding.
(text-mode-meta-tab-ispell-complete-word): New user option.
* etc/NEWS: Announce it.
* doc/emacs/fixit.texi (Spelling)
* doc/emacs/text.texi (Text Mode)
* doc/lispref/modes.texi (Basic Major Modes)
(Example Major Modes): Update.
* lisp/mail/sendmail.el (mail-abbrevs-loaded)
* lisp/nxml/nxml-mode.el (nxml-mode-map): Remove superfluous binding.
---
 doc/emacs/fixit.texi        | 15 ++++++---------
 doc/emacs/text.texi         | 12 ++++++------
 doc/lispref/modes.texi      | 13 +------------
 etc/NEWS                    |  9 +++++++++
 lisp/mail/sendmail.el       |  1 -
 lisp/nxml/nxml-mode.el      |  1 -
 lisp/textmodes/ispell.el    | 22 ++++++++++++++++++++++
 lisp/textmodes/text-mode.el | 19 ++++++++++++++++---
 8 files changed, 60 insertions(+), 32 deletions(-)

diff --git a/doc/emacs/fixit.texi b/doc/emacs/fixit.texi
index 78503d31a38..e31df4865fc 100644
--- a/doc/emacs/fixit.texi
+++ b/doc/emacs/fixit.texi
@@ -295,8 +295,8 @@ Spelling
 @item M-@key{TAB}
 @itemx @key{ESC} @key{TAB}
 @itemx C-M-i
-Complete the word before point based on the spelling dictionary
-(@code{ispell-complete-word}).
+Complete the word before point based on the spelling dictionary and
+other completion sources (@code{completion-at-point}).
 @item M-x flyspell-mode
 Enable Flyspell mode, which highlights all misspelled words.
 @item M-x flyspell-prog-mode
@@ -398,14 +398,11 @@ Spelling
 Show the list of options.
 @end table
 
-@findex ispell-complete-word
-  In Text mode and related modes, @kbd{M-@key{TAB}}
-(@code{ispell-complete-word}) performs in-buffer completion based on
-spelling correction.  Insert the beginning of a word, and then type
-@kbd{M-@key{TAB}}; this shows a list of completions.  (If your
+  Use the command @kbd{M-@key{TAB}} (@code{completion-at-point}) to
+complete the word at point.  Insert the beginning of a word, and then
+type @kbd{M-@key{TAB}} to select from a list of completions.  (If your
 window manager intercepts @kbd{M-@key{TAB}}, type @w{@kbd{@key{ESC}
-@key{TAB}}} or @kbd{C-M-i}.)  Each completion is listed with a digit or
-character; type that digit or character to choose it.
+@key{TAB}}} or @kbd{C-M-i}.)
 
 @cindex @code{ispell} program
 @findex ispell-kill-ispell
diff --git a/doc/emacs/text.texi b/doc/emacs/text.texi
index 6f57bae8fef..b6a9dd6de53 100644
--- a/doc/emacs/text.texi
+++ b/doc/emacs/text.texi
@@ -943,12 +943,12 @@ Text Mode
 composition, for instance.
 
 @kindex M-TAB @r{(Text mode)}
-  Text mode binds @kbd{M-@key{TAB}} to @code{ispell-complete-word}.
-This command performs completion of the partial word in the buffer
-before point, using the spelling dictionary as the space of possible
-words.  @xref{Spelling}.  If your window manager defines
-@kbd{M-@key{TAB}} to switch windows, you can type @kbd{@key{ESC}
-@key{TAB}} or @kbd{C-M-i} instead.
+  The command @kbd{M-@key{TAB}} (@code{completion-at-point}) performs
+completion of the partial word in the buffer before point, using the
+spelling dictionary as the space of possible words by default.
+@xref{Spelling}.  If your window manager defines @kbd{M-@key{TAB}} to
+switch windows, you can type @kbd{@key{ESC} @key{TAB}} or @kbd{C-M-i}
+instead.
 
 @vindex text-mode-hook
   Entering Text mode runs the mode hook @code{text-mode-hook}
diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi
index 13090a13d71..6cdedfa4592 100644
--- a/doc/lispref/modes.texi
+++ b/doc/lispref/modes.texi
@@ -986,9 +986,7 @@ Basic Major Modes
 @deffn Command text-mode
 Text mode is a major mode for editing human languages.  It defines the
 @samp{"} and @samp{\} characters as having punctuation syntax
-(@pxref{Syntax Class Table}), and binds @kbd{M-@key{TAB}} to
-@code{ispell-complete-word} (@pxref{Spelling,,, emacs, The GNU Emacs
-Manual}).
+(@pxref{Syntax Class Table}).
 
 An example of a major mode derived from Text mode is HTML mode.
 @xref{HTML Mode,,SGML and HTML Modes, emacs, The GNU Emacs Manual}.
@@ -1382,15 +1380,6 @@ Example Major Modes
     st)
   "Syntax table used while in `text-mode'.")
 @end group
-
-;; @r{Create the keymap for this mode.}
-@group
-(defvar-keymap text-mode-map
-  :doc "Keymap for `text-mode'.
-Many other modes, such as `mail-mode' and `outline-mode', inherit all
-the commands defined in this map."
-  "C-M-i" #'ispell-complete-word)
-@end group
 @end smallexample
 
   Here is how the actual mode command is defined now:
diff --git a/etc/NEWS b/etc/NEWS
index 458e9e513de..fd633fad6fb 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1132,6 +1132,15 @@ showcases all their customization options.
 \f
 * Incompatible Lisp Changes in Emacs 30.1
 
++++
+** 'M-TAB' now invokes 'completion-at-point' also in Text mode.
+Text mode no longer binds 'M-TAB' to 'ispell-complete-word', and
+instead this mode arranges for 'completion-at-point', globally bound
+to 'M-TAB', to perform word completion as well.  If you want 'M-TAB'
+to invoke 'ispell-complete-word', as it did in previous Emacs
+versions, customize the new option
+'text-mode-meta-tab-ispell-complete-word' to non-nil.
+
 ** 'pp' and 'pp-to-string' now always include a terminating newline.
 In the past they included a terminating newline in most cases but not all.
 
diff --git a/lisp/mail/sendmail.el b/lisp/mail/sendmail.el
index 8306bd3b30c..b5dd5322ec1 100644
--- a/lisp/mail/sendmail.el
+++ b/lisp/mail/sendmail.el
@@ -269,7 +269,6 @@ mail-citation-prefix-regexp
 (defvar mail-abbrevs-loaded nil)
 (defvar mail-mode-map
   (let ((map (make-sparse-keymap)))
-    (define-key map "\M-\t" 'completion-at-point)
     (define-key map "\C-c?" 'describe-mode)
     (define-key map "\C-c\C-f\C-t" 'mail-to)
     (define-key map "\C-c\C-f\C-b" 'mail-bcc)
diff --git a/lisp/nxml/nxml-mode.el b/lisp/nxml/nxml-mode.el
index 67d136b5a66..bc32598003e 100644
--- a/lisp/nxml/nxml-mode.el
+++ b/lisp/nxml/nxml-mode.el
@@ -390,7 +390,6 @@ nxml-mode-map
   "C-c C-u" #'nxml-insert-named-char
   "C-c C-o" nxml-outline-prefix-map
   "/"       #'nxml-electric-slash
-  "M-TAB"   #'completion-at-point
   "S-<mouse-2>" #'nxml-mouse-hide-direct-text-content)
 
 (defvar nxml-font-lock-keywords
diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el
index b71e85b0e37..8fdf9a764aa 100644
--- a/lisp/textmodes/ispell.el
+++ b/lisp/textmodes/ispell.el
@@ -3680,6 +3680,28 @@ ispell-horiz-scroll
 	  (if (>= column (- (window-width) 2))
 	      (scroll-left (max (- column (window-width) -3) 10)))))))
 
+;;;###autoload
+(defun ispell-completion-at-point ()
+  "Word completion function for use in `completion-at-point-functions'."
+  (pcase (bounds-of-thing-at-point 'word)
+    (`(,beg . ,end)
+     (when (and (< beg (point)) (<= (point) end))
+       (let* ((word (buffer-substring-no-properties beg end))
+              (len (length word))
+              (inhibit-message t)
+              (all (cons word (ispell-lookup-words word)))
+              (cur all))
+         (while cur
+           (unless (string-prefix-p word (car cur))
+             (setcar cur (concat word (substring (car cur) len))))
+           (while (when-let ((next (cadr cur)))
+                    (not (string-prefix-p word next t)))
+             (setcdr cur (cddr cur)))
+           (setq cur (cdr cur)))
+         (list beg end (cdr all)
+               :annotation-function (lambda (_) " Dictionary word")
+               :exclusive 'no))))))
+
 
 ;;; Interactive word completion.
 ;; Forces "previous-word" processing.  Do we want to make this selectable?
diff --git a/lisp/textmodes/text-mode.el b/lisp/textmodes/text-mode.el
index ccba1b063ab..7f38a1c463d 100644
--- a/lisp/textmodes/text-mode.el
+++ b/lisp/textmodes/text-mode.el
@@ -73,8 +73,20 @@ text-mode-syntax-table
 (defvar-keymap text-mode-map
   :doc "Keymap for `text-mode'.
 Many other modes, such as `mail-mode' and `outline-mode', inherit
-all the commands defined in this map."
-  "C-M-i" #'ispell-complete-word)
+all the commands defined in this map.")
+
+(defcustom text-mode-meta-tab-ispell-complete-word nil
+  "Whether M-TAB invokes `ispell-complete-word' in Text mode.
+
+This user option only takes effect when you customize it in
+Custom or with `setopt', not with `setq'."
+  :group 'text
+  :type 'boolean
+  :version "30.1"
+  :set (lambda (sym val)
+         (if (set sym val)
+	     (keymap-set text-mode-map "C-M-i" #'ispell-complete-word)
+           (keymap-unset text-mode-map "C-M-i" t))))
 
 (easy-menu-define text-mode-menu text-mode-map
   "Menu for `text-mode'."
@@ -131,7 +143,8 @@ text-mode
 
   ;; Enable text conversion in this buffer.
   (setq-local text-conversion-style t)
-  (add-hook 'context-menu-functions 'text-mode-context-menu 10 t))
+  (add-hook 'context-menu-functions 'text-mode-context-menu 10 t)
+  (add-hook 'completion-at-point-functions #'ispell-completion-at-point 10 t))
 
 (define-derived-mode paragraph-indent-text-mode text-mode "Parindent"
   "Major mode for editing text, with leading spaces starting a paragraph.
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: Word completion in text modes
  2023-11-25 12:11                   ` Eshel Yaron
@ 2023-11-25 12:33                     ` Eli Zaretskii
  2023-11-25 13:00                       ` Eshel Yaron
  0 siblings, 1 reply; 20+ messages in thread
From: Eli Zaretskii @ 2023-11-25 12:33 UTC (permalink / raw)
  To: Eshel Yaron; +Cc: emacs-devel

> From: Eshel Yaron <me@eshelyaron.com>
> Cc: emacs-devel@gnu.org
> Date: Sat, 25 Nov 2023 13:11:27 +0100
> 
> >> diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi
> >> index 8670807cbdf..ffd7ad7f51d 100644
> >> --- a/doc/lispref/modes.texi
> >> +++ b/doc/lispref/modes.texi
> >> @@ -981,9 +981,7 @@ Basic Major Modes
> >>  @deffn Command text-mode
> >>  Text mode is a major mode for editing human languages.  It defines the
> >>  @samp{"} and @samp{\} characters as having punctuation syntax
> >> -(@pxref{Syntax Class Table}), and binds @kbd{M-@key{TAB}} to
> >> -@code{ispell-complete-word} (@pxref{Spelling,,, emacs, The GNU Emacs
> >> -Manual}).
> >> +(@pxref{Syntax Class Table}).
> >
> > Why remove the reference to the command binding here?
> 
> Text mode no longer binds `C-M-i` to anything, relying on the global
> binding instead.  So there doesn't seem to be any reason to mention this
> binding here anymore, just like it's not mentioned in the description of
> `prog-mode` that follows this paragraph.  Does that make sense?

But the global bin ding has a text-mode-special effect in Text mode,
does it not?  Then we should change the text to mention that special
effect, instead of removing it completely.  That's assuming the
completion feature is still important enough to mention it in the
manual.

> > Did you check what happens when Flyspell mode is turned on in a buffer
> > under Text mode or one of its descendants?
> 
> Yes.  Unless one sets `flyspell-use-meta-tab` to nil, Flyspell mode binds
> `C-M-i` to a completely different command, `flyspell-auto-correct-word`.

And if flyspell-use-meta-tab is nil, what happens then under Flyspell
mode?



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Word completion in text modes
  2023-11-25 12:33                     ` Eli Zaretskii
@ 2023-11-25 13:00                       ` Eshel Yaron
  2023-11-26 10:31                         ` Eli Zaretskii
  0 siblings, 1 reply; 20+ messages in thread
From: Eshel Yaron @ 2023-11-25 13:00 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

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

Hi,

Eli Zaretskii <eliz@gnu.org> writes:

>> Text mode no longer binds `C-M-i` to anything, relying on the global
>> binding instead.  So there doesn't seem to be any reason to mention this
>> binding here anymore, just like it's not mentioned in the description of
>> `prog-mode` that follows this paragraph.  Does that make sense?
>
> But the global binding has a text-mode-special effect in Text mode,
> does it not?

Yes,

> Then we should change the text to mention that special effect, instead
> of removing it completely.  That's assuming the completion feature is
> still important enough to mention it in the manual.

Alright, I've added a few words about that in an updated, attached below.

>> > Did you check what happens when Flyspell mode is turned on in a buffer
>> > under Text mode or one of its descendants?
>>
>> Yes.  Unless one sets `flyspell-use-meta-tab` to nil, Flyspell mode binds
>> `C-M-i` to a completely different command, `flyspell-auto-correct-word`.
>
> And if flyspell-use-meta-tab is nil, what happens then under Flyspell
> mode?

Well, then Flyspell leaves `C-M-i` intact, and if you press those keys
you get whatever they are otherwise bound to.  Namely, with my patch, you
get `completion-at-point`, unless you've customized the new user option
to have Text mode bind `C-M-i` to `ispell-complete-word`, in which case
you get just that.



[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: v3-0001-Unbind-C-M-i-in-Text-mode.patch --]
[-- Type: text/x-patch, Size: 9729 bytes --]

From 4dab9d7d9ff2c5530d7c65a4695dd53b3e70f843 Mon Sep 17 00:00:00 2001
From: Eshel Yaron <me@eshelyaron.com>
Date: Tue, 21 Nov 2023 12:39:23 +0100
Subject: [PATCH v3] Unbind 'C-M-i' in Text mode

Remove the binding of 'C-M-i' to 'ispell-complete-word' in Text mode.
Define a new 'ispell-completion-at-point' function and add that to
'completion-at-point-functions' in Text mode, such that
'completion-at-point' provides the same word completions as
'ispell-complete-word' does OOTB.

* lisp/textmodes/ispell.el (ispell-completion-at-point): New function.
* lisp/textmodes/text-mode.el (text-mode): Add it to 'c-a-p-functions'.
(text-mode-map): Remove 'C-M-i' binding.
(text-mode-meta-tab-ispell-complete-word): New user option.
* etc/NEWS: Announce it.
* doc/emacs/fixit.texi (Spelling)
* doc/emacs/text.texi (Text Mode)
* doc/lispref/modes.texi (Basic Major Modes)
(Example Major Modes): Update.
* lisp/mail/sendmail.el (mail-abbrevs-loaded)
* lisp/nxml/nxml-mode.el (nxml-mode-map): Remove superfluous binding.
---
 doc/emacs/fixit.texi        | 15 ++++++---------
 doc/emacs/text.texi         | 12 ++++++------
 doc/lispref/modes.texi      | 15 +++------------
 etc/NEWS                    |  9 +++++++++
 lisp/mail/sendmail.el       |  1 -
 lisp/nxml/nxml-mode.el      |  1 -
 lisp/textmodes/ispell.el    | 22 ++++++++++++++++++++++
 lisp/textmodes/text-mode.el | 19 ++++++++++++++++---
 8 files changed, 62 insertions(+), 32 deletions(-)

diff --git a/doc/emacs/fixit.texi b/doc/emacs/fixit.texi
index 78503d31a38..e31df4865fc 100644
--- a/doc/emacs/fixit.texi
+++ b/doc/emacs/fixit.texi
@@ -295,8 +295,8 @@ Spelling
 @item M-@key{TAB}
 @itemx @key{ESC} @key{TAB}
 @itemx C-M-i
-Complete the word before point based on the spelling dictionary
-(@code{ispell-complete-word}).
+Complete the word before point based on the spelling dictionary and
+other completion sources (@code{completion-at-point}).
 @item M-x flyspell-mode
 Enable Flyspell mode, which highlights all misspelled words.
 @item M-x flyspell-prog-mode
@@ -398,14 +398,11 @@ Spelling
 Show the list of options.
 @end table
 
-@findex ispell-complete-word
-  In Text mode and related modes, @kbd{M-@key{TAB}}
-(@code{ispell-complete-word}) performs in-buffer completion based on
-spelling correction.  Insert the beginning of a word, and then type
-@kbd{M-@key{TAB}}; this shows a list of completions.  (If your
+  Use the command @kbd{M-@key{TAB}} (@code{completion-at-point}) to
+complete the word at point.  Insert the beginning of a word, and then
+type @kbd{M-@key{TAB}} to select from a list of completions.  (If your
 window manager intercepts @kbd{M-@key{TAB}}, type @w{@kbd{@key{ESC}
-@key{TAB}}} or @kbd{C-M-i}.)  Each completion is listed with a digit or
-character; type that digit or character to choose it.
+@key{TAB}}} or @kbd{C-M-i}.)
 
 @cindex @code{ispell} program
 @findex ispell-kill-ispell
diff --git a/doc/emacs/text.texi b/doc/emacs/text.texi
index 6f57bae8fef..b6a9dd6de53 100644
--- a/doc/emacs/text.texi
+++ b/doc/emacs/text.texi
@@ -943,12 +943,12 @@ Text Mode
 composition, for instance.
 
 @kindex M-TAB @r{(Text mode)}
-  Text mode binds @kbd{M-@key{TAB}} to @code{ispell-complete-word}.
-This command performs completion of the partial word in the buffer
-before point, using the spelling dictionary as the space of possible
-words.  @xref{Spelling}.  If your window manager defines
-@kbd{M-@key{TAB}} to switch windows, you can type @kbd{@key{ESC}
-@key{TAB}} or @kbd{C-M-i} instead.
+  The command @kbd{M-@key{TAB}} (@code{completion-at-point}) performs
+completion of the partial word in the buffer before point, using the
+spelling dictionary as the space of possible words by default.
+@xref{Spelling}.  If your window manager defines @kbd{M-@key{TAB}} to
+switch windows, you can type @kbd{@key{ESC} @key{TAB}} or @kbd{C-M-i}
+instead.
 
 @vindex text-mode-hook
   Entering Text mode runs the mode hook @code{text-mode-hook}
diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi
index 13090a13d71..70a4899b623 100644
--- a/doc/lispref/modes.texi
+++ b/doc/lispref/modes.texi
@@ -986,9 +986,9 @@ Basic Major Modes
 @deffn Command text-mode
 Text mode is a major mode for editing human languages.  It defines the
 @samp{"} and @samp{\} characters as having punctuation syntax
-(@pxref{Syntax Class Table}), and binds @kbd{M-@key{TAB}} to
-@code{ispell-complete-word} (@pxref{Spelling,,, emacs, The GNU Emacs
-Manual}).
+(@pxref{Syntax Class Table}), and arranges for
+@code{completion-at-point} to complete words based on the spelling
+dictionary (@pxref{Completion in Buffers}).
 
 An example of a major mode derived from Text mode is HTML mode.
 @xref{HTML Mode,,SGML and HTML Modes, emacs, The GNU Emacs Manual}.
@@ -1382,15 +1382,6 @@ Example Major Modes
     st)
   "Syntax table used while in `text-mode'.")
 @end group
-
-;; @r{Create the keymap for this mode.}
-@group
-(defvar-keymap text-mode-map
-  :doc "Keymap for `text-mode'.
-Many other modes, such as `mail-mode' and `outline-mode', inherit all
-the commands defined in this map."
-  "C-M-i" #'ispell-complete-word)
-@end group
 @end smallexample
 
   Here is how the actual mode command is defined now:
diff --git a/etc/NEWS b/etc/NEWS
index 458e9e513de..fd633fad6fb 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1132,6 +1132,15 @@ showcases all their customization options.
 \f
 * Incompatible Lisp Changes in Emacs 30.1
 
++++
+** 'M-TAB' now invokes 'completion-at-point' also in Text mode.
+Text mode no longer binds 'M-TAB' to 'ispell-complete-word', and
+instead this mode arranges for 'completion-at-point', globally bound
+to 'M-TAB', to perform word completion as well.  If you want 'M-TAB'
+to invoke 'ispell-complete-word', as it did in previous Emacs
+versions, customize the new option
+'text-mode-meta-tab-ispell-complete-word' to non-nil.
+
 ** 'pp' and 'pp-to-string' now always include a terminating newline.
 In the past they included a terminating newline in most cases but not all.
 
diff --git a/lisp/mail/sendmail.el b/lisp/mail/sendmail.el
index 8306bd3b30c..b5dd5322ec1 100644
--- a/lisp/mail/sendmail.el
+++ b/lisp/mail/sendmail.el
@@ -269,7 +269,6 @@ mail-citation-prefix-regexp
 (defvar mail-abbrevs-loaded nil)
 (defvar mail-mode-map
   (let ((map (make-sparse-keymap)))
-    (define-key map "\M-\t" 'completion-at-point)
     (define-key map "\C-c?" 'describe-mode)
     (define-key map "\C-c\C-f\C-t" 'mail-to)
     (define-key map "\C-c\C-f\C-b" 'mail-bcc)
diff --git a/lisp/nxml/nxml-mode.el b/lisp/nxml/nxml-mode.el
index 67d136b5a66..bc32598003e 100644
--- a/lisp/nxml/nxml-mode.el
+++ b/lisp/nxml/nxml-mode.el
@@ -390,7 +390,6 @@ nxml-mode-map
   "C-c C-u" #'nxml-insert-named-char
   "C-c C-o" nxml-outline-prefix-map
   "/"       #'nxml-electric-slash
-  "M-TAB"   #'completion-at-point
   "S-<mouse-2>" #'nxml-mouse-hide-direct-text-content)
 
 (defvar nxml-font-lock-keywords
diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el
index b71e85b0e37..8fdf9a764aa 100644
--- a/lisp/textmodes/ispell.el
+++ b/lisp/textmodes/ispell.el
@@ -3680,6 +3680,28 @@ ispell-horiz-scroll
 	  (if (>= column (- (window-width) 2))
 	      (scroll-left (max (- column (window-width) -3) 10)))))))
 
+;;;###autoload
+(defun ispell-completion-at-point ()
+  "Word completion function for use in `completion-at-point-functions'."
+  (pcase (bounds-of-thing-at-point 'word)
+    (`(,beg . ,end)
+     (when (and (< beg (point)) (<= (point) end))
+       (let* ((word (buffer-substring-no-properties beg end))
+              (len (length word))
+              (inhibit-message t)
+              (all (cons word (ispell-lookup-words word)))
+              (cur all))
+         (while cur
+           (unless (string-prefix-p word (car cur))
+             (setcar cur (concat word (substring (car cur) len))))
+           (while (when-let ((next (cadr cur)))
+                    (not (string-prefix-p word next t)))
+             (setcdr cur (cddr cur)))
+           (setq cur (cdr cur)))
+         (list beg end (cdr all)
+               :annotation-function (lambda (_) " Dictionary word")
+               :exclusive 'no))))))
+
 
 ;;; Interactive word completion.
 ;; Forces "previous-word" processing.  Do we want to make this selectable?
diff --git a/lisp/textmodes/text-mode.el b/lisp/textmodes/text-mode.el
index ccba1b063ab..7f38a1c463d 100644
--- a/lisp/textmodes/text-mode.el
+++ b/lisp/textmodes/text-mode.el
@@ -73,8 +73,20 @@ text-mode-syntax-table
 (defvar-keymap text-mode-map
   :doc "Keymap for `text-mode'.
 Many other modes, such as `mail-mode' and `outline-mode', inherit
-all the commands defined in this map."
-  "C-M-i" #'ispell-complete-word)
+all the commands defined in this map.")
+
+(defcustom text-mode-meta-tab-ispell-complete-word nil
+  "Whether M-TAB invokes `ispell-complete-word' in Text mode.
+
+This user option only takes effect when you customize it in
+Custom or with `setopt', not with `setq'."
+  :group 'text
+  :type 'boolean
+  :version "30.1"
+  :set (lambda (sym val)
+         (if (set sym val)
+	     (keymap-set text-mode-map "C-M-i" #'ispell-complete-word)
+           (keymap-unset text-mode-map "C-M-i" t))))
 
 (easy-menu-define text-mode-menu text-mode-map
   "Menu for `text-mode'."
@@ -131,7 +143,8 @@ text-mode
 
   ;; Enable text conversion in this buffer.
   (setq-local text-conversion-style t)
-  (add-hook 'context-menu-functions 'text-mode-context-menu 10 t))
+  (add-hook 'context-menu-functions 'text-mode-context-menu 10 t)
+  (add-hook 'completion-at-point-functions #'ispell-completion-at-point 10 t))
 
 (define-derived-mode paragraph-indent-text-mode text-mode "Parindent"
   "Major mode for editing text, with leading spaces starting a paragraph.
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: Word completion in text modes
  2023-11-25 13:00                       ` Eshel Yaron
@ 2023-11-26 10:31                         ` Eli Zaretskii
  2023-11-26 11:03                           ` Eshel Yaron
  0 siblings, 1 reply; 20+ messages in thread
From: Eli Zaretskii @ 2023-11-26 10:31 UTC (permalink / raw)
  To: Eshel Yaron; +Cc: emacs-devel

> From: Eshel Yaron <me@eshelyaron.com>
> Cc: emacs-devel@gnu.org
> Date: Sat, 25 Nov 2023 14:00:42 +0100
> 
> > Then we should change the text to mention that special effect, instead
> > of removing it completely.  That's assuming the completion feature is
> > still important enough to mention it in the manual.
> 
> Alright, I've added a few words about that in an updated, attached below.

Thanks, installed on master.



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Word completion in text modes
  2023-11-26 10:31                         ` Eli Zaretskii
@ 2023-11-26 11:03                           ` Eshel Yaron
  2023-11-26 11:23                             ` Eli Zaretskii
  0 siblings, 1 reply; 20+ messages in thread
From: Eshel Yaron @ 2023-11-26 11:03 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

Eli Zaretskii <eliz@gnu.org> writes:

>> From: Eshel Yaron <me@eshelyaron.com>
>> Cc: emacs-devel@gnu.org
>> Date: Sat, 25 Nov 2023 14:00:42 +0100
>>
>> > Then we should change the text to mention that special effect, instead
>> > of removing it completely.  That's assuming the completion feature is
>> > still important enough to mention it in the manual.
>>
>> Alright, I've added a few words about that in an updated, attached below.
>
> Thanks, installed on master.

Great.  Note that this also resolves Bug#52743 AFAICT, as well as this
FIXME in `ispell-complete-word` (that I forgot to remove in the patch):

diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el
index 8fdf9a764aa..4c3b22281bd 100644
--- a/lisp/textmodes/ispell.el
+++ b/lisp/textmodes/ispell.el
@@ -3718,7 +3718,6 @@ ispell-complete-word
 by `ispell-alternate-dictionary' or by `ispell-complete-word-dict';
 if none of those name an existing word-list file, this command
 signals an error."
-  ;; FIXME: completion-at-point-function.
   (interactive "P")
   (let ((case-fold-search-val case-fold-search)
        (word (ispell-get-word nil "\\*")) ; force "previous-word" processing.



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: Word completion in text modes
  2023-11-26 11:03                           ` Eshel Yaron
@ 2023-11-26 11:23                             ` Eli Zaretskii
  0 siblings, 0 replies; 20+ messages in thread
From: Eli Zaretskii @ 2023-11-26 11:23 UTC (permalink / raw)
  To: Eshel Yaron; +Cc: emacs-devel

> From: Eshel Yaron <me@eshelyaron.com>
> Cc: emacs-devel@gnu.org
> Date: Sun, 26 Nov 2023 12:03:21 +0100
> 
> Great.  Note that this also resolves Bug#52743 AFAICT, as well as this
> FIXME in `ispell-complete-word` (that I forgot to remove in the patch):

Fixed, thanks.



^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2023-11-26 11:23 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-18 12:03 Word completion in text modes Eshel Yaron
2023-11-18 12:39 ` Eli Zaretskii
2023-11-18 13:21   ` Eshel Yaron
2023-11-18 13:50     ` Eli Zaretskii
2023-11-18 15:53       ` Eshel Yaron
2023-11-18 16:03         ` [External] : " Drew Adams
2023-11-18 16:37         ` Eli Zaretskii
2023-11-18 19:03           ` Eshel Yaron
2023-11-18 19:18             ` Eli Zaretskii
2023-11-21 13:45               ` Eshel Yaron
2023-11-25 10:40                 ` Eli Zaretskii
2023-11-25 12:11                   ` Eshel Yaron
2023-11-25 12:33                     ` Eli Zaretskii
2023-11-25 13:00                       ` Eshel Yaron
2023-11-26 10:31                         ` Eli Zaretskii
2023-11-26 11:03                           ` Eshel Yaron
2023-11-26 11:23                             ` Eli Zaretskii
2023-11-18 16:05   ` [External] : " Drew Adams
2023-11-18 16:55     ` Juergen Fenn
2023-11-18 18:33 ` Juri Linkov

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

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).