* bug#34787: New defcustom to govern TAB completion
@ 2019-03-08 18:21 Alex Branham
2019-03-08 19:29 ` Alex Branham
2019-05-25 13:05 ` Alex Branham
0 siblings, 2 replies; 8+ messages in thread
From: Alex Branham @ 2019-03-08 18:21 UTC (permalink / raw)
To: 34787
[-- Attachment #1: Type: text/plain, Size: 5156 bytes --]
Hello -
In ESS, we have 'ess-first-tab-never-complete' which governs whether TAB
offers completion. The gist of it is that if you're in a buffer (with |
representing point):
(def|var foo)
and you hit TAB, you might not want completion offered. I've put
together a patch that incorporates this into Emacs by adding a new
defcustom `tab-first-completion'. The values are currently based on
ESS's implementation, though we can certainly change that if we want.
Perhaps it should be a function that receives one argument (position)
and if it returns non-nil, then we complete?
Is this something people would be interested in adding?
Thanks,
Alex
From eb4c1a9c8bcd2f5018150b0502e8ed945c181e74 Mon Sep 17 00:00:00 2001
From: Alex Branham <alex.branham@gmail.com>
Date: Fri, 8 Mar 2019 12:09:04 -0600
Subject: [PATCH] New defcustom tab-first-completion
* lisp/indent.el (tab-always-indent): Mention 'tab-first-completion'.
(tab-first-completion): New defcustom.
(indent-for-tab-command): Use 'tab-first-completion'.
Bug#<TBD>
---
lisp/indent.el | 40 +++++++++++++++++++++++++++++++++++++---
1 file changed, 37 insertions(+), 3 deletions(-)
diff --git a/lisp/indent.el b/lisp/indent.el
index 34757a43d7..08087effa6 100644
--- a/lisp/indent.el
+++ b/lisp/indent.el
@@ -51,6 +51,7 @@ If nil, hitting TAB indents the current line if point is at the left margin
or in the line's indentation, otherwise it inserts a \"real\" TAB character.
If `complete', TAB first tries to indent the current line, and if the line
was already indented, then try to complete the thing at point.
+See also `tab-first-completion'.
Some programming language modes have their own variable to control this,
e.g., `c-tab-always-indent', and do not respect this variable."
@@ -60,6 +61,27 @@ e.g., `c-tab-always-indent', and do not respect this variable."
(const :tag "Indent if inside indentation, else TAB" nil)
(const :tag "Indent, or if already indented complete" complete)))
+(defcustom tab-first-completion nil
+ "Governs the behavior of TAB completion on the first press of the key.
+When nil, complete. When `eol', only complete if point is at the
+end of a line. When `word', complete unless the next character
+has word syntax (according to `syntax-after'). When
+`word-or-paren', complete unless the next character is part of a
+word or a parenthesis. When `word-or-paren-or-punct', complete
+unless the next character is part of a word, parenthesis, or
+punctuation. Typing TAB a second time always results in
+completion.
+
+This variable has no effect unless `tab-always-indent' is `complete'."
+ :group 'indent
+ :type '(choice
+ (const :tag "Always complete" nil)
+ (const :tag "Unless at the end of a line" 'eol)
+ (const :tag "Unless looking at a word" 'word)
+ (const :tag "Unless at a word or parenthesis" 'word-or-paren)
+ (const :tag "Unless at a word, parenthesis, or punctuation." 'word-or-paren-or-punct))
+ :version "27.1")
+
(defun indent-according-to-mode ()
"Indent line in proper way for current major mode.
@@ -111,7 +133,7 @@ or performs symbol completion, depending on `tab-always-indent'.
The function called to actually indent the line or insert a tab
is given by the variable `indent-line-function'.
-If a prefix argument is given, after this function indents the
+If a prefix argument is given (ARG), after this function indents the
current line or inserts a tab, it also rigidly indents the entire
balanced expression which starts at the beginning of the current
line, to reflect the current line's indentation.
@@ -139,7 +161,8 @@ prefix argument is ignored."
(t
(let ((old-tick (buffer-chars-modified-tick))
(old-point (point))
- (old-indent (current-indentation)))
+ (old-indent (current-indentation))
+ (syn (syntax-after (point))))
;; Indent the line.
(or (not (eq (indent--funcall-widened indent-line-function) 'noindent))
@@ -152,7 +175,18 @@ prefix argument is ignored."
;; If the text was already indented right, try completion.
((and (eq tab-always-indent 'complete)
(eq old-point (point))
- (eq old-tick (buffer-chars-modified-tick)))
+ (eq old-tick (buffer-chars-modified-tick))
+ (or (null tab-first-completion)
+ (eq last-command this-command)
+ (and (equal tab-first-completion 'eol)
+ (eolp))
+ (and (member tab-first-completion '(word word-or-paren word-or-paren-or-punct))
+ (not (member 2 syn)))
+ (and (member tab-first-completion '(word-or-paren word-or-paren-or-punct))
+ (not (or (member 4 syn)
+ (member 5 syn))))
+ (and (equal tab-first-completion 'word-or-paren-or-punct)
+ (not (member 1 syn)))))
(completion-at-point))
;; If a prefix argument was given, rigidly indent the following
--
2.19.2
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 487 bytes --]
^ permalink raw reply related [flat|nested] 8+ messages in thread
* bug#34787: New defcustom to govern TAB completion
2019-03-08 18:21 bug#34787: New defcustom to govern TAB completion Alex Branham
@ 2019-03-08 19:29 ` Alex Branham
2020-10-14 5:29 ` Lars Ingebrigtsen
2019-05-25 13:05 ` Alex Branham
1 sibling, 1 reply; 8+ messages in thread
From: Alex Branham @ 2019-03-08 19:29 UTC (permalink / raw)
To: 34787
On Fri 08 Mar 2019 at 12:21, Alex Branham <alex.branham@gmail.com> wrote:
> @@ -139,7 +161,8 @@ prefix argument is ignored."
> (t
> (let ((old-tick (buffer-chars-modified-tick))
> (old-point (point))
> - (old-indent (current-indentation)))
> + (old-indent (current-indentation))
> + (syn (syntax-after (point))))
^^^^^ should be (syn `(,(syntax-after (point))))
I accidentally sent the wrong patch; this part needs to be quoted.
Alex
^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#34787: New defcustom to govern TAB completion
2019-03-08 18:21 bug#34787: New defcustom to govern TAB completion Alex Branham
2019-03-08 19:29 ` Alex Branham
@ 2019-05-25 13:05 ` Alex Branham
2019-05-25 13:37 ` Noam Postavsky
1 sibling, 1 reply; 8+ messages in thread
From: Alex Branham @ 2019-05-25 13:05 UTC (permalink / raw)
To: 34787
Hi -
Just following up on this since I didn't hear back. If people are
interested, great. If not, I can close this bug report.
As a quick reminder/TLDR - the proposal is to add a defcustom that
governs whether TAB offers completion when hit the first time. The
thinking is that if point is in the middle of a word, you may not want
completion.
Thanks,
Alex
On Fri 08 Mar 2019 at 12:21, Alex Branham <alex.branham@gmail.com> wrote:
> Hello -
>
> In ESS, we have 'ess-first-tab-never-complete' which governs whether TAB
> offers completion. The gist of it is that if you're in a buffer (with |
> representing point):
>
> (def|var foo)
>
> and you hit TAB, you might not want completion offered. I've put
> together a patch that incorporates this into Emacs by adding a new
> defcustom `tab-first-completion'. The values are currently based on
> ESS's implementation, though we can certainly change that if we want.
> Perhaps it should be a function that receives one argument (position)
> and if it returns non-nil, then we complete?
>
> Is this something people would be interested in adding?
>
> Thanks,
> Alex
>
>
> From eb4c1a9c8bcd2f5018150b0502e8ed945c181e74 Mon Sep 17 00:00:00 2001
> From: Alex Branham <alex.branham@gmail.com>
> Date: Fri, 8 Mar 2019 12:09:04 -0600
> Subject: [PATCH] New defcustom tab-first-completion
>
> * lisp/indent.el (tab-always-indent): Mention 'tab-first-completion'.
> (tab-first-completion): New defcustom.
> (indent-for-tab-command): Use 'tab-first-completion'.
>
> Bug#<TBD>
> ---
> lisp/indent.el | 40 +++++++++++++++++++++++++++++++++++++---
> 1 file changed, 37 insertions(+), 3 deletions(-)
>
> diff --git a/lisp/indent.el b/lisp/indent.el
> index 34757a43d7..08087effa6 100644
> --- a/lisp/indent.el
> +++ b/lisp/indent.el
> @@ -51,6 +51,7 @@ If nil, hitting TAB indents the current line if point is at the left margin
> or in the line's indentation, otherwise it inserts a \"real\" TAB character.
> If `complete', TAB first tries to indent the current line, and if the line
> was already indented, then try to complete the thing at point.
> +See also `tab-first-completion'.
>
> Some programming language modes have their own variable to control this,
> e.g., `c-tab-always-indent', and do not respect this variable."
> @@ -60,6 +61,27 @@ e.g., `c-tab-always-indent', and do not respect this variable."
> (const :tag "Indent if inside indentation, else TAB" nil)
> (const :tag "Indent, or if already indented complete" complete)))
>
> +(defcustom tab-first-completion nil
> + "Governs the behavior of TAB completion on the first press of the key.
> +When nil, complete. When `eol', only complete if point is at the
> +end of a line. When `word', complete unless the next character
> +has word syntax (according to `syntax-after'). When
> +`word-or-paren', complete unless the next character is part of a
> +word or a parenthesis. When `word-or-paren-or-punct', complete
> +unless the next character is part of a word, parenthesis, or
> +punctuation. Typing TAB a second time always results in
> +completion.
> +
> +This variable has no effect unless `tab-always-indent' is `complete'."
> + :group 'indent
> + :type '(choice
> + (const :tag "Always complete" nil)
> + (const :tag "Unless at the end of a line" 'eol)
> + (const :tag "Unless looking at a word" 'word)
> + (const :tag "Unless at a word or parenthesis" 'word-or-paren)
> + (const :tag "Unless at a word, parenthesis, or punctuation." 'word-or-paren-or-punct))
> + :version "27.1")
> +
>
> (defun indent-according-to-mode ()
> "Indent line in proper way for current major mode.
> @@ -111,7 +133,7 @@ or performs symbol completion, depending on `tab-always-indent'.
> The function called to actually indent the line or insert a tab
> is given by the variable `indent-line-function'.
>
> -If a prefix argument is given, after this function indents the
> +If a prefix argument is given (ARG), after this function indents the
> current line or inserts a tab, it also rigidly indents the entire
> balanced expression which starts at the beginning of the current
> line, to reflect the current line's indentation.
> @@ -139,7 +161,8 @@ prefix argument is ignored."
> (t
> (let ((old-tick (buffer-chars-modified-tick))
> (old-point (point))
> - (old-indent (current-indentation)))
> + (old-indent (current-indentation))
> + (syn (syntax-after (point))))
>
> ;; Indent the line.
> (or (not (eq (indent--funcall-widened indent-line-function) 'noindent))
> @@ -152,7 +175,18 @@ prefix argument is ignored."
> ;; If the text was already indented right, try completion.
> ((and (eq tab-always-indent 'complete)
> (eq old-point (point))
> - (eq old-tick (buffer-chars-modified-tick)))
> + (eq old-tick (buffer-chars-modified-tick))
> + (or (null tab-first-completion)
> + (eq last-command this-command)
> + (and (equal tab-first-completion 'eol)
> + (eolp))
> + (and (member tab-first-completion '(word word-or-paren word-or-paren-or-punct))
> + (not (member 2 syn)))
> + (and (member tab-first-completion '(word-or-paren word-or-paren-or-punct))
> + (not (or (member 4 syn)
> + (member 5 syn))))
> + (and (equal tab-first-completion 'word-or-paren-or-punct)
> + (not (member 1 syn)))))
> (completion-at-point))
>
> ;; If a prefix argument was given, rigidly indent the following
^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#34787: New defcustom to govern TAB completion
2019-05-25 13:05 ` Alex Branham
@ 2019-05-25 13:37 ` Noam Postavsky
2019-05-25 13:43 ` Alex Branham
0 siblings, 1 reply; 8+ messages in thread
From: Noam Postavsky @ 2019-05-25 13:37 UTC (permalink / raw)
To: Alex Branham; +Cc: 34787
Alex Branham <alex.branham@gmail.com> writes:
> As a quick reminder/TLDR - the proposal is to add a defcustom that
> governs whether TAB offers completion when hit the first time. The
> thinking is that if point is in the middle of a word, you may not want
> completion.
How would it interact with the existing tab-always-indent? Would it
make sense to combine them?
^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#34787: New defcustom to govern TAB completion
2019-05-25 13:37 ` Noam Postavsky
@ 2019-05-25 13:43 ` Alex Branham
2019-06-05 1:50 ` Noam Postavsky
0 siblings, 1 reply; 8+ messages in thread
From: Alex Branham @ 2019-05-25 13:43 UTC (permalink / raw)
To: Noam Postavsky; +Cc: 34787
[-- Attachment #1: Type: text/plain, Size: 746 bytes --]
On Sat 25 May 2019 at 08:37, Noam Postavsky <npostavs@gmail.com> wrote:
> Alex Branham <alex.branham@gmail.com> writes:
>
>> As a quick reminder/TLDR - the proposal is to add a defcustom that
>> governs whether TAB offers completion when hit the first time. The
>> thinking is that if point is in the middle of a word, you may not want
>> completion.
>
> How would it interact with the existing tab-always-indent? Would it
> make sense to combine them?
The way we have it in ESS currently is that they're two separate
variables. One (our version of tab-always-indent) governs whether TAB
offers completion and another (what I'm proposing adding to Emacs)
governs whether the first press of TAB should offer completion based on
context.
Alex
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 487 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#34787: New defcustom to govern TAB completion
2019-05-25 13:43 ` Alex Branham
@ 2019-06-05 1:50 ` Noam Postavsky
2020-08-24 19:22 ` Stefan Kangas
0 siblings, 1 reply; 8+ messages in thread
From: Noam Postavsky @ 2019-06-05 1:50 UTC (permalink / raw)
To: Alex Branham; +Cc: 34787
Alex Branham <alex.branham@gmail.com> writes:
> On Sat 25 May 2019 at 08:37, Noam Postavsky <npostavs@gmail.com> wrote:
>
>> Alex Branham <alex.branham@gmail.com> writes:
>>
>>> As a quick reminder/TLDR - the proposal is to add a defcustom that
>>> governs whether TAB offers completion when hit the first time. The
>>> thinking is that if point is in the middle of a word, you may not want
>>> completion.
>>
>> How would it interact with the existing tab-always-indent? Would it
>> make sense to combine them?
>
> The way we have it in ESS currently is that they're two separate
> variables. One (our version of tab-always-indent) governs whether TAB
> offers completion and another (what I'm proposing adding to Emacs)
> governs whether the first press of TAB should offer completion based on
> context.
Oh, I see, it only affects people who have already customized
tab-always-indent to a non-default value (specifically, `complete').
So I guess the idea is that (setq tab-always-indent 'complete) triggers
too many accidental completions to be a reasonable setting? I think it
would be nicer if the option's values could be `(word paren)', `(word
paren punct) instead of `word-or-paren', `word-or-paren-or-punct', etc.
^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#34787: New defcustom to govern TAB completion
2019-06-05 1:50 ` Noam Postavsky
@ 2020-08-24 19:22 ` Stefan Kangas
0 siblings, 0 replies; 8+ messages in thread
From: Stefan Kangas @ 2020-08-24 19:22 UTC (permalink / raw)
To: Noam Postavsky; +Cc: 34787, Alex Branham
Noam Postavsky <npostavs@gmail.com> writes:
> Alex Branham <alex.branham@gmail.com> writes:
>
>> On Sat 25 May 2019 at 08:37, Noam Postavsky <npostavs@gmail.com> wrote:
>>
>>> Alex Branham <alex.branham@gmail.com> writes:
>>>
>>>> As a quick reminder/TLDR - the proposal is to add a defcustom that
>>>> governs whether TAB offers completion when hit the first time. The
>>>> thinking is that if point is in the middle of a word, you may not want
>>>> completion.
>>>
>>> How would it interact with the existing tab-always-indent? Would it
>>> make sense to combine them?
>>
>> The way we have it in ESS currently is that they're two separate
>> variables. One (our version of tab-always-indent) governs whether TAB
>> offers completion and another (what I'm proposing adding to Emacs)
>> governs whether the first press of TAB should offer completion based on
>> context.
>
> Oh, I see, it only affects people who have already customized
> tab-always-indent to a non-default value (specifically, `complete').
>
> So I guess the idea is that (setq tab-always-indent 'complete) triggers
> too many accidental completions to be a reasonable setting? I think it
> would be nicer if the option's values could be `(word paren)', `(word
> paren punct) instead of `word-or-paren', `word-or-paren-or-punct', etc.
(That was one year ago.)
Are you still working on this?
Best regards,
Stefan Kangas
^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#34787: New defcustom to govern TAB completion
2019-03-08 19:29 ` Alex Branham
@ 2020-10-14 5:29 ` Lars Ingebrigtsen
0 siblings, 0 replies; 8+ messages in thread
From: Lars Ingebrigtsen @ 2020-10-14 5:29 UTC (permalink / raw)
To: Alex Branham; +Cc: 34787
Alex Branham <alex.branham@gmail.com> writes:
> On Fri 08 Mar 2019 at 12:21, Alex Branham <alex.branham@gmail.com> wrote:
>
>> @@ -139,7 +161,8 @@ prefix argument is ignored."
>> (t
>> (let ((old-tick (buffer-chars-modified-tick))
>> (old-point (point))
>> - (old-indent (current-indentation)))
>> + (old-indent (current-indentation))
>> + (syn (syntax-after (point))))
> ^^^^^ should be (syn `(,(syntax-after (point))))
>
> I accidentally sent the wrong patch; this part needs to be quoted.
I played around with this a bit, and it seems to work very well, and
quite naturally. So I've applied this to Emacs 28.
Noam made the suggestion of making this a list of values like (word
paren) instead of word-or-paren, and that does seem like a good idea,
but either works. I guess somebody might want (word punct) and not
word-and-paren-and-punct, for instance? So if somebody were to change
this to work that way instead, I wouldn't mind, but I think it's
probably fine as is.
--
(domestic pets only, the antidote for overdose, milk.)
bloggy blog: http://lars.ingebrigtsen.no
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2020-10-14 5:29 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-03-08 18:21 bug#34787: New defcustom to govern TAB completion Alex Branham
2019-03-08 19:29 ` Alex Branham
2020-10-14 5:29 ` Lars Ingebrigtsen
2019-05-25 13:05 ` Alex Branham
2019-05-25 13:37 ` Noam Postavsky
2019-05-25 13:43 ` Alex Branham
2019-06-05 1:50 ` Noam Postavsky
2020-08-24 19:22 ` Stefan Kangas
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).