Skip to content

Conversation

jgreitemann
Copy link
Contributor

Fixes #6861

Checklist

If applicable:

  • I have updated CHANGELOG.md
  • I have updated the documentation (README.md, docs/, demos/)
  • I have updated the config schema (cli/src/config-schema.json)
  • I have added/updated tests to cover my changes

Fixes #6861.

`current` might not be a prefix of the (normal) completion candidate
`path` if `current` itself is non-normal. In case `current` is longer
than the candidate `path`, the code previously panicked. The tests have
been extended to trigger this panic.

The panic is avoided by using `strip_prefix()` instead of direct
slicing. However, in case `current` does not prefix `path`, the path
may be truncated too early. Additionally, fish discards any completion
candidates that do not start with `current`, even if the completion
script writes them to stdout.

Thus, this commit is the minimal change to avoid the panic, but it does
not yet handle completion of non-normal paths correctly.
@jgreitemann jgreitemann requested a review from a team as a code owner October 19, 2025 13:22
Rewrites how the file-path completion is determined from a potentially
non-normal `current_prefix`. The basic idea is to normalize the
`current_prefix` first to obtain an actual prefix of the (normal)
`path`. The remainder can then be spliced onto the original
`current_prefix` to form a non-normalized completion path that is
prefixed by `current_prefix`, allowing the shell to accept it.

This requires a different API for the helper than what `dir_prefix_from`
provided. The latter assumed that when `None` was returned, `path` could
be completed as-is; a `Some` value indicated a partial completion of
`path` to the next directory. This is no longer sufficient as we need to
potentially return a different, non-normal path in either case.

Since we want to ignore the `mode` for directory completions, the
helper must also return the type of completion (partial/directory
or full/file). To avoid propagating this information, I instead
pass the `mode` into the helper and have it return finished
`CompletionCandidate`s. This also yields cleaner code on the caller
side.
path.split_at(path.len() - remainder.len() + next.len() + 1)
.0
})
fn is_path_separator(c: char) -> bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be better to use std::path::is_separator instead of manually defining this function

@yuja
Copy link
Contributor

yuja commented Oct 20, 2025

Maybe it's easier to normalize input to RepoPath and strip prefix from repo-relative path output (i.e. path instead of path.display() in template)? That will also fix Windows Bash issue. #7024

@jgreitemann
Copy link
Contributor Author

Easier in the sense that RepoPath uses / on either platform? Yes, unless we ever want to support completion on Powershell at some point. Idk, maybe slashes would be permissible there too, I've never understood when / works on Windows and when you need to use \... I also don't have a Windows machine to test that with.

If it's just Git Bash (and other POSIX shells in MinGW et al. environments), I'd lean towards sticking with the native path separator in general and fix the Git Bash issue separately by using slash_path on the result if COMPLETE=bash is used on cfg!(windows).

@yuja
Copy link
Contributor

yuja commented Oct 20, 2025

Easier in the sense that RepoPath uses / on either platform?

Easier because the command output is also normalized (to repo-relative paths.) Post-processing would be simple if both inputs and outputs are in the canonical form. We can convert them back to backslash paths if needed.

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

Successfully merging this pull request may close these issues.

Completion of non-normalized file path does not produce candidates and may panic

3 participants