emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 64c8511: Add a new variable tab-first-completion


From: Lars Ingebrigtsen
Subject: master 64c8511: Add a new variable tab-first-completion
Date: Wed, 14 Oct 2020 01:27:18 -0400 (EDT)

branch: master
commit 64c8511664420498b9769b098a31300e2ab58c2d
Author: Alex Branham <alex.branham@gmail.com>
Commit: Lars Ingebrigtsen <larsi@gnus.org>

    Add a new variable tab-first-completion
    
    * doc/emacs/indent.texi (Indent Convenience): Mention it.
    
    * doc/lispref/text.texi (Mode-Specific Indent): Document it.
    
    * lisp/indent.el (tab-first-completion): New variable (bug#34787).
    (indent-for-tab-command): Use it.
---
 doc/emacs/indent.texi |  7 +++++++
 doc/lispref/text.texi | 24 ++++++++++++++++++++++++
 etc/NEWS              |  5 +++++
 lisp/indent.el        | 43 ++++++++++++++++++++++++++++++++++++++++---
 4 files changed, 76 insertions(+), 3 deletions(-)

diff --git a/doc/emacs/indent.texi b/doc/emacs/indent.texi
index d0360ac..d6395ef 100644
--- a/doc/emacs/indent.texi
+++ b/doc/emacs/indent.texi
@@ -250,6 +250,13 @@ Completion}).  If the value is @code{nil}, then @key{TAB} 
indents the
 current line only if point is at the left margin or in the line's
 indentation; otherwise, it inserts a tab character.
 
+@vindex tab-first-completion
+  If @code{tab-always-indent} is @code{complete}, whether to expand or
+indent can be further customized via the @code{tab-first-completion}
+variable.  For instance, if that variable is @code{eol}, only complete
+if point is at the end of a line.  @xref{Mode-Specific Indent,,,
+elisp, The Emacs Lisp Reference Manual} for further details.
+
 @cindex Electric Indent mode
 @cindex mode, Electric Indent
 @findex electric-indent-mode
diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi
index 722c044..559b2b1 100644
--- a/doc/lispref/text.texi
+++ b/doc/lispref/text.texi
@@ -2427,6 +2427,30 @@ already indented, it calls @code{completion-at-point} to 
complete the
 text at point (@pxref{Completion in Buffers}).
 @end defopt
 
+@defopt tab-first-completion
+If @code{tab-always-indent} is @code{complete}, whether to expand or
+indent can be further customized via the @code{tab-first-completion}
+variable.  The following values can be used:
+@table @code
+@item eol
+Only complete if point is at the end of a line.
+
+@item word
+Complete unless the next character has word syntax.
+
+@item word-or-paren
+Complete unless the next character has word syntax or is a
+parenthesis.
+
+@item word-or-paren-or-punct
+Complete unless the next character has word syntax, or is a
+parenthesis, or is punctuation.
+@end table
+
+In any case, typing @kbd{TAB} a second time always results in
+completion.
+@end defopt
+
 @cindex literate programming
 @cindex multi-mode indentation
   Some major modes need to support embedded regions of text whose
diff --git a/etc/NEWS b/etc/NEWS
index d8e19a9..334d782 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1134,6 +1134,11 @@ window after starting).  This variable defaults to nil.
 
 ** Miscellaneous
 
++++
+*** New user option 'tab-first-completion'.
+If 'tab-always-indent' is 'complete', this new option can be used to
+further tweak whether to complete or indent.
+
 ---
 *** 'zap-up-to-char' now uses 'read-char-from-minibuffer'.
 This allows navigating through the history of characters that have
diff --git a/lisp/indent.el b/lisp/indent.el
index 0a0dd99..e436d14 100644
--- a/lisp/indent.el
+++ b/lisp/indent.el
@@ -52,6 +52,8 @@ 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.
 
+Also see `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."
   :group 'indent
@@ -60,6 +62,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.
@@ -113,7 +136,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.
@@ -141,7 +164,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))
@@ -154,7 +178,20 @@ 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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]