Skip to content

commands.lua: add quotes to file completion - #18336

Open
guidocella wants to merge 1 commit into
mpv-player:masterfrom
guidocella:quote-files
Open

commands.lua: add quotes to file completion#18336
guidocella wants to merge 1 commit into
mpv-player:masterfrom
guidocella:quote-files

Conversation

@guidocella

Copy link
Copy Markdown
Contributor

Automatically inserting quotes in file completion problematic, because when completing directories you want the cursor before the final quote rather than after in order to further complete the files within, and there is no system to set a cursor position before the end of the completion.

However we can add quotes automatically without this issue when:

  • completing files in the current directory
  • we can add only the first quote when completing directories in the current directory
  • we can add the final quote after files if the user typed a quote at the beginning of the path, since there's nothing remaining to complete after regular files

This adds single quotes because they are easier to type. Filenames containing both spaces and single quotes are not supported.

Automatically inserting quotes in file completion problematic, because
when completing directories you want the cursor before the final quote
rather than after in order to further complete the files within, and
there is no system to set a cursor position before the end of the
completion.

However we can add quotes automatically without this issue when:
- completing files in the current directory
- we can add only the first quote when completing directories in the
  current directory
- we can add the final quote after files if the user typed a quote at
  the beginning of the path, since there's nothing remaining to complete
  after regular files

This adds single quotes because they are easier to type. Filenames
containing both spaces and single quotes are not supported.
@na-na-hi

na-na-hi commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

The quote issue can be avoided entirely by auto escaping special characters instead. There won't be quote character at the end that interferes further completion this way.

@guidocella

Copy link
Copy Markdown
Contributor Author

How? mpv interprets foo\ bar as 2 arguments.

@na-na-hi

na-na-hi commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Console can preprocess the input and make that one argument. Similar to what shells do.

@verygoodlee

verygoodlee commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Console can preprocess the input and make that one argument. Similar to what shells do.

I don't think this is feasible. there may be additional arguments after the file path, which can cause ambiguity.

e.g. loadfile /path/to/foo bar append

  • the file path is /path/to/foo bar append
  • the file path is /path/to/foo bar and followed by an append flag

the linux shell style escaping /path/to/foo\ bar is obviously not suitable for Windows, because \ is file separator on Windows.

@verygoodlee

verygoodlee commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

The behavior of Windows PowerShell is to add quotes and place the input cursor before the closing quote.
20260803-113627
Windows CMD is a bit different, it places the input cursor after the closing quote.
20260803-122037

@CogentRedTester

Copy link
Copy Markdown
Contributor

I don't think this is feasible. there may be additional arguments after the file path, which can cause ambiguity.

I don't think this is too difficult, we should be able to detect when a space is not escaped and detect that a new argument will start afterwards. Something like this:

local function submit(text)
    -- Find each argument in the command string.
    -- Only end the argument with a space not preceded by a `\`.
    local escaped_command = string.gsub(text..' ', '([^%s].-[^\\])%s', function(arg)
        -- Do nothing if the argument is already quoted.
        if arg:find([[^".*"$]]) or arg:find([[^'.*'$]]) or arg:find([[^`(.).*%1`]]) then
            return nil
        end

        return '"' .. arg:gsub('\\ ', ' ') .. '"'
    end)

    mp.command(escaped_command)
end

The only problem is that the command syntax currently allows backslash literals (and, I think, pretty much every character outside of newlines?) outside quotes, meaning that someone can currently write script-message one\ two\ three\ and they would be treated as three separate arguments, whereas this escape character change would read this as one argument.

the linux shell style escaping /path/to/foo\ bar is obviously not suitable for Windows, because \ is file separator on Windows.

We could use another escape character I suppose, or we could return forward slashes for completions even on windows, though that may cause issues if people are copying and pasting paths. We could also probably code commands.lua to only do the escape handling when the path is not already quoted and avoid most accidental Windows incompatibilities.

@guidocella

Copy link
Copy Markdown
Contributor Author

Escaping is not so simple since you can also do loadfile foo;cmd2. I would rather extend the completion system than to preprocess the input command.

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.

4 participants