unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* 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

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