Complete ! shell escapes like a shell
A line starting with '!' was not in the completer tree at all, so Tab did nothing there -- just where the paths are longest. It now completes the way a shell does: the command word against the executables on PATH, the arguments against the filesystem, resolved relative to the active project because that is where forwardShell runs the line. Directories complete with their trailing slash, `~/` and absolute paths work, and dot entries stay hidden until the prefix asks for one. readline's completer is a tree of fixed words, which cannot express "a prefix that is not a word", so this is a small AutoCompleter that dispatches on the '!' and hands everything else to the existing tree. Its contract is easy to get subtly wrong -- candidates are the suffixes still missing, and the length is counted in runes, not bytes -- so the conversion has its own test, as does completing only the basename inside a directory, which is what keeps the candidate list readable. Only the basename is offered inside a directory, PATH is scanned once per session, and a bare '!' offers nothing rather than every executable on the machine. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -53,8 +53,9 @@ project, its git branch and a `*` dirty marker:
|
||||
|
||||
Features: command history (`~/.mgsh_history`), Tab completion (commands, local
|
||||
projects for `cd`/`open`, server repos for `clone`/`show`, branches/tags for
|
||||
`checkout`/`tag`, mirror targets for `pushremote`, filesystem paths for `dist`),
|
||||
and colored `list`/`log`/error output.
|
||||
`checkout`/`tag`, mirror targets for `pushremote`/`release`, filesystem paths for
|
||||
`dist`, and shell-style completion after `!`), and colored `list`/`log`/error
|
||||
output.
|
||||
|
||||
The server repository list is fetched once per session on the first Tab that
|
||||
needs it; `rescan` refreshes it (and reloads the configuration).
|
||||
@@ -70,6 +71,22 @@ prefix it with `!`:
|
||||
< src/myproject > !ls -la
|
||||
```
|
||||
|
||||
It runs in the active project's directory. Tab completion works there the way it
|
||||
does in a shell: the word after the `!` completes against the executables on
|
||||
`PATH`, everything after it against the filesystem — relative to the project,
|
||||
with `~/` and absolute paths understood, and directories completing with their
|
||||
trailing slash so the next Tab walks into them. Dot entries stay out of the way
|
||||
until the prefix asks for one.
|
||||
|
||||
```
|
||||
< src/myproject > !vi ma<Tab> -> !vi main
|
||||
< src/myproject > !vi <Tab> -> Makefile main.go main_test.go src/
|
||||
< src/myproject > !gre<Tab> -> grep gresource
|
||||
```
|
||||
|
||||
Word splitting for completion is by whitespace only; quotes and backslash
|
||||
escapes are left to the shell that runs the line.
|
||||
|
||||
### Commands
|
||||
|
||||
Run `help` for the full list. Highlights:
|
||||
|
||||
Reference in New Issue
Block a user