fish (the friendly interactive shell) advertises autosuggestions, syntax highlighting and completions as out-of-the-box features. In fish, what is the difference between an autosuggestion and a tab completion, and where does each one get its candidates from?
answer
- grey text ahead of the cursor
- one guess versus a candidate list
- history first, completions second
- right arrow accepts, Tab lists
- man pages become completion files
basics
~20 sIn fish, an autosuggestion is one greyed-out continuation of the line you are typing, taken mainly from your history and accepted with the right arrow key. Tab completion instead offers the set of candidates for the current token.
solid answer
~50 sThey are two separate mechanisms that happen to appear in the same place on screen. An **autosuggestion** is a single guess: once you have typed a character or two, fish paints the rest of the most recent matching history entry in grey after the cursor. It is not in your buffer, so pressing Enter runs only what you actually typed; Right arrow or `Ctrl-F` accepts the whole suggestion and `Alt-Right` accepts just the next word. If history has no match, fish falls back to a completion, such as a filename. **Completion** is the Tab key: fish computes the candidate set for the token you are on — branch names after `git checkout`, flags for the command you named — and shows them in a pager when there is more than one. Its candidates come from fish's shipped completion scripts, from files in `~/.config/fish/completions`, and from completions generated out of installed man pages by `fish_update_completions`.
go deeper
Be able to say plainly that the grey text after the cursor is one guess from your history, accepted with the right arrow, while Tab shows the list of candidates for the word you are on.
Explain the sources behind each mechanism: history first and completions as a fallback for suggestions, and shipped scripts, the completions directory and man-page generation via fish_update_completions for Tab.
Be ready to say what these defaults cost and where they mislead — highlighting is a lexical check, not a success prediction, and generated completions are only as good as the installed man pages.
Frame it as a defaults argument: fish bets that discoverability belongs in the shell rather than in each engineer's plugin stack. Be able to weigh that against every other shell being configurable to the same place.
## fish's premise fish — the "friendly interactive shell" — ships with the interactive features that other shells expect you to assemble yourself: suggestions as you type, coloured syntax, and completions for hundreds of commands, with no plugin manager and no configuration file to write. Two of those features look similar on screen and are constantly conflated, so this is a common opening question for anyone who lists fish on a CV. ## The autosuggestion is one guess As soon as you have typed a character or two, fish searches your command history for the most recent line that starts with what you have typed and paints the remainder in grey to the right of the cursor. ```fish # history contains: git commit -m "fix parser" # you type: git co # fish shows: git co mmit -m "fix parser" (the tail is grey, not typed) ``` Three things follow from that. First, the grey text is **not** part of your command buffer: pressing Enter runs only the characters you actually typed, which is why a suggestion can never surprise you into running the wrong thing. Second, there is exactly **one** suggestion at a time — it is a guess, not a menu. Third, you accept it explicitly: Right arrow or `Ctrl-F` takes the whole suggestion, `Alt-Right` (or `Alt-F`) takes only the next word, which is the move you want when the old command is nearly right but the last argument is wrong. History is the primary source. When no history entry matches, fish falls back to a completion candidate — typically a file or directory name — so autosuggestion and completion do share machinery, but the user-facing behaviour is different. ## The completion is the candidate set Tab is the completion key. fish completes the token under the cursor; if a unique candidate exists it is inserted, and if several match, fish opens a pager listing them, with descriptions, that you can page through and select. Completions are context-aware rather than merely file-based: after `git checkout ` you get branch names, after `ssh ` you get hosts fish can see, after a command name you get that command's options with a short description of each. ## Where completions come from Three sources, and knowing the third is the fish-specific part of the answer. 1. **Shipped completion scripts** for a large set of common commands, installed with fish itself. 2. **Your own or a package's scripts**, autoloaded from a `completions` directory — `~/.config/fish/completions/<command>.fish` for a user. 3. **Generated from man pages.** Running `fish_update_completions` parses the man pages installed on the machine and writes completion files from the options it finds. This is how fish knows the flags of tools nobody ever wrote a completion script for. The obvious limitation is that the result is only as good as the man page: badly formatted or missing man pages produce poor or no completions, and it captures option names, not the semantics of their arguments. ## Syntax highlighting, the third default As you type, fish colours the line: a name that resolves to a command or builtin gets the "valid command" colour, a name that does not resolves red, quoted strings are coloured distinctly, and a path that exists is underlined. An unterminated quote is visible immediately instead of at the moment you press Enter. It is important to describe this as a *lexical* check — "this name resolves to something runnable, this path exists" — not as a prediction that the command will succeed. The colours themselves are ordinary fish variables (the `fish_color_*` family) and can be changed interactively with `fish_config`. ## What to actually say in an interview Name the distinction (one inline guess versus a candidate set), name the accept keys, and name the man-page generation, because that is the detail that separates someone who has used fish from someone who has read a blog post about it. Then land the design point: none of this is unique in principle — bash and zsh can approximate all three with third-party plugins and configuration — fish's position is that these should be on for everyone, on first launch, with no dotfile at all. That default-on stance is the whole reason the shell exists, and it is also the reason it accepts the costs discussed whenever someone proposes it as a login shell.
- If the grey autosuggestion is not part of the command buffer, what happens when you press Enter with a suggestion showing?Only what you typed runs. The suggestion is display-only until you accept it with Right arrow or `Ctrl-F`, so a stale history entry can never be executed by accident. That is a deliberate safety property: fish is willing to guess loudly precisely because the guess cannot fire on its own.
- What are the practical limits of generating completions from man pages with fish_update_completions?It extracts option names and their descriptions from the page's formatting, so it only works for commands that ship a reasonable man page, and it cannot know what values an option's argument accepts. You get flag completion, not semantic completion — no branch names, no valid enum values — and a command documented only via `--help` gets nothing.
- fish underlines a path and colours an unknown command red. Does that mean the line will run successfully?No. The highlighting is lexical: fish checks that a command name resolves to something runnable and that a path currently exists. It says nothing about permissions, arguments, exit status or side effects, so a fully-coloured line can still fail immediately.
saying these in an interview costs you the question
- Says autosuggestion and tab completion are the same feature
- Thinks the grey text is already in the buffer and will execute
- Claims fish needs a plugin to enable autosuggestions
- Believes fish learns flags by running every command with --help
- Says syntax highlighting proves the command will succeed