Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

autocomplete requires too many tabs #1725

Open
vogler opened this issue Jul 22, 2019 · 2 comments
Open

autocomplete requires too many tabs #1725

vogler opened this issue Jul 22, 2019 · 2 comments

Comments

@vogler
Copy link

vogler commented Jul 22, 2019

Description

For files foo.{a,b} (but also foo_{a,b} etc.)

v fo<TAB>

completes to

v foo.

but shows no file menu to make clear that the completion is not done.
Sometimes hitting <TAB><CR> is enough to edit a file and sometimes <TAB><TAB><TAB><CR> is needed, depending on the context (e.g. is there a .h file for a .c file).
An alternative would be to complete the most frequently/recently used suffix instead.
But at least it should already show the completion menu to indicate that there is a choice to be made - currently this requires another <TAB>.
To get from fo to foo.a you even have to do fo<TAB><TAB><TAB> since the first result is not selected.

I don't know if this can be done inside prezto or if it's a zsh issue.

Expected behavior

fo<TAB> completes to foo. and opens the completion results. Another <TAB> selects the first result.

Alternative:
fo<TAB> completes to foo.a and opens the completion results.
This means we can't complete to the longest common prefix anymore.
Maybe hitting <BS> could be used to shorten the completion to that longest common prefix.

Versions

  • Prezto commit: e94b6b2
  • ZSH version: zsh 5.7.1 (x86_64-apple-darwin18.2.0)
  • OS information: macOS 10.14.5 (18F132)
@vogler
Copy link
Author

vogler commented Jul 22, 2019

After reading http://zsh.sourceforge.net/Doc/Release/Completion-System.html I arrived at the following:

Alternative 1:

setopt menu_complete

v fo<TAB> -> v foo.a with open menu with foo.a selected (<TAB> cycles), <CR> accepts completion, <CR> executes command.
^O accepts completion and executes command.

Alternative 2:

zstyle ':completion:*:default' menu 'yes' 'search'

v fo<TAB> -> v foo.a with interactive search prompt (typing b will select foo.b, <TAB> cycles through results), <CR> ends isearch, <CR> accepts completion, <CR> executes command.
^O accepts completion and executes command.

Optional:

#  sort file completions by last access time (most recent first)
zstyle ':completion:*' file-sort access
# highlight the first ambiguous character in completion lists
zstyle ':completion:*' show-ambiguity 'true'
# make ctrl-j also accept completion and execute command, enter or space can still be used to accept w/o execution
bindkey -M menuselect '^J' .accept-line

I don't know if that's a better default (for me it certainly is). Sadly I didn't find an option to just show the menu w/o completing.
I'll leave this open for now in case someone has better ideas. Feel free to close.

@vogler
Copy link
Author

vogler commented Jul 22, 2019

I can't find a place to put bindkey -M menuselect '^J' .accept-line. Both in zshrc and zpreztorc I get no such keymap 'menuselect'.
If I leave off -M menuselect or try -M main it doesn't complain, but it also doesn't work (bindkey-all only lists .accept-line in a keymap .safe, but that's coming from somewhere else).

vogler added a commit to vogler/prezto that referenced this issue Jul 22, 2019
…w-ambiguity

sorin-ionescu#1725

Is it possible to configure some of this in zsh?
http://zsh.sourceforge.net/Doc/Release/Completion-System.html

Tried the following:

- expand ❓: If one of its values is the string ‘suffix’, matching names for components after the first ambiguous one will also be added. This means that the resulting string is the longest unambiguous string possible. However, menu completion can be used to cycle through all matches.

  ~~~
  $ zstyle ':completion:*' expand 'prefix' 'suffix'
  $ zstyle ':completion::complete:*' expand 'prefix' 'suffix'
  ~~~

  -> No effect.

- file-sort ✅: The standard filename completion function uses this style without a tag to determine in which order the names should be listed; menu completion will cycle through them in the same order. The possible values are: ‘size’ to sort by the size of the file; ‘links’ to sort by the number of links to the file; ‘modification’ (or ‘time’ or ‘date’) to sort by the last modification time; ‘access’ to sort by the last access time; and ‘inode’ (or ‘change’) to sort by the last inode change time. If the style is set to any other value, or is unset, files will be sorted alphabetically by name. If the value contains the string ‘reverse’, sorting is done in the opposite order. If the value contains the string ‘follow’, timestamps are associated with the targets of symbolic links; the default is to use the timestamps of the links themselves.

  ~~~
  $ zstyle ':completion:*' file-sort access
  ~~~

  -> Will use this to sort by most recently accessed (e.g. do `cat foo.b` to make it the first completion item).

- force-list ❓: This forces a list of completions to be shown at any point where listing is done, even in cases where the list would usually be suppressed. For example, normally the list is only shown if there are at least two different matches. By setting this style to ‘always’, the list will always be shown, even if there is only a single match that will immediately be accepted. The style may also be set to a number. In this case the list will be shown if there are at least that many matches, even if they would all insert the same string.
This style is tested for the default tag as well as for each tag valid for the current completion. Hence the listing can be forced only for certain types of match.

  ~~~
  $ zstyle ':completion:*' force-list 'always'
  $ zstyle ':completion:*:default' force-list 'always'
  ~~~

  -> No effect.

- menu ✅: If this is ‘true’ in the context of any of the tags defined for the current completion menu completion will be used. If the value contains the string ‘select’, menu selection will be started unconditionally. The word ‘interactive’ in the value causes interactive mode to be entered immediately when menu selection is started; see The zsh/complist Module for a description of interactive mode. Including the string ‘search’ does the same for incremental search mode.

  ~~~
  $ zstyle ':completion:*' menu 'true' 'select' 'interactive' 'search'
  ~~~

  Has no effect, but the following does (tried `interactive` but didn't like it because it didn't complete and cycle with `<TAB>`):

  ~~~
  $ zstyle ':completion:*:default' menu 'yes' 'search'
  ~~~

  Before: `v fo` `<TAB>` -> `v foo.`, `<TAB>` -> file menu, `<TAB>` -> select first entry: `v foo.a`, `<CR>` accepts completion, `<CR>` executes command.
  With this: `v fo` `<TAB>` -> `v foo.a` with interactive search prompt (typing `b` will select `foo.b`, `<TAB>` cycles through results), `<CR>` ends isearch, `<CR>` accepts completion, `<CR>` executes command.

  How to get rid of additional `<CR>`?
  `man zshmodules`:
    `accept-line` only leaves incremental search, going back to the normal menu selection mode. [...]
    For  example,  the  widget `.accept-line` has the effect of leaving menu selection and accepting the entire command line.
    `bindkey ^J .accept-line` (https://unix.stackexchange.com/questions/280368/how-can-i-use-a-key-other-than-enter-to-exit-zshs-completion-menu-widget) has no effect.

- `setopt menu_complete` ✅: https://unix.stackexchange.com/questions/12288/zsh-insert-completion-on-first-tab-even-if-ambiguous?rq=1
  Works, simplest solution: `v fo`, `<TAB>` -> `v foo.a` with open menu with `foo.a` selected (`<TAB>` cycles), `<CR>` accepts completion, `<CR>` executes command.
  `^O` accepts completion and executes command.
  `bindkey`: "^O" accept-line-and-down-history
  `bindkey -M menuselect '^J' .accept-line` also works (`^M` or `space` can then still be used to insert completion w/o executing).

Additional options:
~~~
$ zstyle ':completion:*' show-ambiguity 'true'
~~~
If the zsh/complist module is loaded, this style can be used to highlight the first ambiguous character in completion lists. The value is either a color indication such as those supported by the list-colors style or, with a value of ‘true’, a default of underlining is selected. The highlighting is only applied if the completion display strings correspond to the actual matches.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant