1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-18 03:40:47 -08:00

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.
This commit is contained in:
Alex Branham 2020-10-14 07:26:58 +02:00 committed by Lars Ingebrigtsen
parent 5474603c4c
commit 64c8511664
4 changed files with 76 additions and 3 deletions

View file

@ -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 current line only if point is at the left margin or in the line's
indentation; otherwise, it inserts a tab character. 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 Electric Indent mode
@cindex mode, Electric Indent @cindex mode, Electric Indent
@findex electric-indent-mode @findex electric-indent-mode

View file

@ -2427,6 +2427,30 @@ already indented, it calls @code{completion-at-point} to complete the
text at point (@pxref{Completion in Buffers}). text at point (@pxref{Completion in Buffers}).
@end defopt @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 literate programming
@cindex multi-mode indentation @cindex multi-mode indentation
Some major modes need to support embedded regions of text whose Some major modes need to support embedded regions of text whose

View file

@ -1134,6 +1134,11 @@ window after starting). This variable defaults to nil.
** Miscellaneous ** 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'. *** 'zap-up-to-char' now uses 'read-char-from-minibuffer'.
This allows navigating through the history of characters that have This allows navigating through the history of characters that have

View file

@ -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 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. 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, Some programming language modes have their own variable to control this,
e.g., `c-tab-always-indent', and do not respect this variable." e.g., `c-tab-always-indent', and do not respect this variable."
:group 'indent :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 if inside indentation, else TAB" nil)
(const :tag "Indent, or if already indented complete" complete))) (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 () (defun indent-according-to-mode ()
"Indent line in proper way for current major 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 The function called to actually indent the line or insert a tab
is given by the variable `indent-line-function'. 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 current line or inserts a tab, it also rigidly indents the entire
balanced expression which starts at the beginning of the current balanced expression which starts at the beginning of the current
line, to reflect the current line's indentation. line, to reflect the current line's indentation.
@ -141,7 +164,8 @@ prefix argument is ignored."
(t (t
(let ((old-tick (buffer-chars-modified-tick)) (let ((old-tick (buffer-chars-modified-tick))
(old-point (point)) (old-point (point))
(old-indent (current-indentation))) (old-indent (current-indentation))
(syn `(,(syntax-after (point)))))
;; Indent the line. ;; Indent the line.
(or (not (eq (indent--funcall-widened indent-line-function) 'noindent)) (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. ;; If the text was already indented right, try completion.
((and (eq tab-always-indent 'complete) ((and (eq tab-always-indent 'complete)
(eq old-point (point)) (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)) (completion-at-point))
;; If a prefix argument was given, rigidly indent the following ;; If a prefix argument was given, rigidly indent the following