Skip to content

autocomplete: Escape spaces and quotes in filename completions - #4224

Open
anandghegde wants to merge 1 commit into
micro-editor:masterfrom
anandghegde:filecomplete-escape-spaces
Open

autocomplete: Escape spaces and quotes in filename completions#4224
anandghegde wants to merge 1 commit into
micro-editor:masterfrom
anandghegde:filecomplete-escape-spaces

Conversation

@anandghegde

Copy link
Copy Markdown

Fixes #3970

Filename completion puts names with spaces into the prompt as-is, but open, tab, vsplit, cd, save and the save-as prompt all split their input with shellquote. So Ctrl-omyTab gives open my folder/, and pressing Enter opens an empty buffer named my. Completing further inside that folder also fails, because GetArg treats folder/... as a new argument.

This change:

  • escapes spaces, tabs and quotes with a backslash in the text that FileComplete inserts (the suggestion list still shows plain names)
  • makes FileComplete treat those backslash escapes as part of the current argument and strip them before looking up the directory, so completion keeps working inside my\ folder/

Only a backslash in front of one of those characters counts as an escape, so other backslashes, like Windows path separators, are handled the same as before. GetArg and the other completers are unchanged.

Before (master), with a my folder/it's a file.txt file:

> open my folder/        # after "my" + Tab
> open my folder/it      # "it" + Tab completes nothing
Enter -> empty buffer named "my"

After:

> open my\ folder/it\'s\ a\ file.txt
Enter -> opens "my folder/it's a file.txt"

Testing:

  • Added TestFileCompleteEscapesSpecialChars in internal/buffer/autocomplete_test.go. It fails on master and passes with the fix.
  • make test (go test ./internal/... ./cmd/... plus the gofmt check) passes on macOS with Go 1.27.
  • Checked the steps above by hand in a real terminal, with both the master build and this branch.

Note: #4178 (Windows path separators) also edits the start of FileComplete and adds autocomplete_test.go. The two changes are separate, but whichever merges second will need a small rebase. I'm happy to do that.

I used Claude Code to write this change. I reviewed and tested it myself.

🤖 Generated with Claude Code

https://claude.ai/code/session_01MA8JGs7pCoXFL2W6jEJ8sD

Commands and the save-as prompt split their input with shellquote, so a
completed name like "my folder/" was split into two arguments and the
following completion started from "folder/". Escape spaces and quotes
in the inserted completion and treat such escapes as part of the
argument when completing.

Fixes micro-editor#3970

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MA8JGs7pCoXFL2W6jEJ8sD

@Andriamanitra Andriamanitra left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Making this specific to FileComplete doesn't make sense to me. All other commands can also accept arguments with backslash escaped spaces. Is there a reason to introduce a new function getFileArg instead of simply fixing GetArg?

@Andriamanitra

Copy link
Copy Markdown
Collaborator

Is there a reason to introduce a new function getFileArg instead of simply fixing GetArg?

To answer my own question: The same GetArg is also used for autocompletion in regular BufPanes in which the situation is different. And custom completers implemented in plugins are quite rare (and they don't necessarily use GetArg anyway 1) so maybe it's fine...

Footnotes

  1. for example in µlsp we parse the contents of the buffer ourselves: https://github.com/Andriamanitra/mlsp/blob/91261a0926c9e95d059cf5854a0c2e8d4e7d4051/main.lua#L82-L112

@anandghegde

Copy link
Copy Markdown
Author

Right, that was the reason. GetArg is a public Buffer method (callable from Lua on any buffer), and on normal buffer text a backslash isn't a shell escape, so I didn't want to change what it returns there.

Also, making GetArg escape-aware alone wouldn't do much for the other built-in completers:

  • The things they complete (command names, option names/values, help topics, plugin names) don't contain spaces, so there's nothing to escape.
  • OptionValueComplete and PluginComplete (and InfoPane.CommandComplete, when it picks the command) split the line on ' ' themselves anyway, so they'd need their own changes.

Filenames are the only case where the bug shows up, so I kept the fix in FileComplete. If you'd rather have it in GetArg so plugin completers get it too, I'm happy to move it there and update those split sites to match. Just say which you prefer.

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.

Opening files via Ctrl-o only works if there are no spaces in path (Linux Mint)

2 participants