Skip to content

select.lua: add edit-config-file and edit-input-conf #16129

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

guidocella
Copy link
Contributor

Add a script with script bindings to edit mpv.conf and input.conf, and add them to the menu. These are useful as shortcuts, but the main motivation is that new users often ask why they can't find mpv.conf and input.conf, so this creates them if they don't exist, also including links to the documentation.

Other future script bindings that don't fit anywhere else can also be added to utils.lua.

Copy link

github-actions bot commented Mar 26, 2025

@guidocella guidocella force-pushed the utils branch 3 times, most recently from b465f69 to 3629e3c Compare March 28, 2025 06:46
@@ -556,6 +556,7 @@ static const m_option_t mp_opts[] = {
{"load-select", OPT_BOOL(lua_load_select), .flags = UPDATE_BUILTIN_SCRIPTS},
{"load-positioning", OPT_BOOL(lua_load_positioning), .flags = UPDATE_BUILTIN_SCRIPTS},
{"load-commands", OPT_BOOL(lua_load_commands), .flags = UPDATE_BUILTIN_SCRIPTS},
{"load-utils", OPT_BOOL(lua_load_utils), .flags = UPDATE_BUILTIN_SCRIPTS},
Copy link
Member

Choose a reason for hiding this comment

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

Could we convert this to load option to string list? Not related to this PR, just an idea I got rn.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't have a strong preference either way

return
end

file_handle:write(initial_contents .. "\n")
Copy link
Member

Choose a reason for hiding this comment

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

do you need \n here, initial content seems to already have new line.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah it's not needed after I added newlines in the initial contents

@kasper93
Copy link
Member

misc.lua, instead of utils.lua? It's more like miscellaneous functions than utils to be used by other scripts.

@hooke007
Copy link
Contributor

This might be a name to be easily misunderstood. I thought it was related to the mp.utils functions before checking.

@@ -990,6 +991,7 @@ static const struct MPOpts mp_default_opts = {
.lua_load_select = true,
.lua_load_positioning = true,
.lua_load_commands = true,
.loa_load_misc = true,
Copy link
Member

Choose a reason for hiding this comment

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

typo

Comment on lines 52 to 73
local platform = mp.get_property("platform")
local args
if platform == "windows" then
args = {"rundll32", "url.dll,FileProtocolHandler", path}
elseif platform == "darwin" then
args = {"open", path}
else
args = {"xdg-open", path}
end

local result = mp.command_native({
name = "subprocess",
playback_only = false,
args = args,
})

if result.status < 0 then
show_error("Subprocess error: " .. result.error_string)
elseif result.status > 0 then
show_error(utils.to_string(args) .. " failed with code " ..
result.status)
end
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the script is pretty much pointless except this part which can be extracted as a mp.utils function to "open url with preferred app". The rest can be implemented in select.lua.

I don't think third party scripts have much use for the two script bindings here so this script would create a thread and use resources while doing nothing.

Copy link
Contributor

Choose a reason for hiding this comment

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

The rest can be implemented in select.lua.

Something like this

Select a config file to edit:
/path/to/mpv.conf
/path/to/input.conf

script config files in ~~/script-opts directory can also be added to the list.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Edit config file and Edit input.conf are going to be added to the context menu (which I implemented months ago and is blocked by this PR), and the idea is to use this for any future miscellaneous functions, e.g. I implemented "seek to timestamp" for the context menu, and we can set prefetch-playlist to true here when the next file is an image like you suggested.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well I guess it's not too much of a stretch to add Edit config file, input.conf and Seek to timestamp to select.lua (the context menu is still populated by select.lua) and a C option to set prefetch-playlist to avoid adding another script if preferred?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, I think these helper functions can live in the script that uses it unless it's being used by multiple scripts, then it can live in places like defaults.lua which are included instead of using a separate script thread.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure I will update the PR. But for the record while I was also worried about many threads before avih challenged me to measure the difference and if you try running mpv with 100 copies of an empty script the CPU usage and performance are exactly the same and there's just an increase of 20MB of memory so it doesn't cause problems in practice.

Copy link
Member

Choose a reason for hiding this comment

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

I didn't look at this closely, but please don't forget that JS and JSON-IPC clients exists too in mpv, and functionality which is available to lua should also be available to any other client too. select.lua covers this by using JSON-based RPC-like thing which is accessible for any client.

@guidocella guidocella changed the title misc.lua: add this script select.lua: add edit-config-file and edit-input-conf Jul 24, 2025
@guidocella guidocella force-pushed the utils branch 3 times, most recently from e384203 to d39b909 Compare July 24, 2025 13:01
@avih
Copy link
Member

avih commented Jul 24, 2025

system_open doesn't belong in mp.utils IMO, at the very least because JSON IPC clients don't have access to it, but also because, if we decide it's important to have, then this really should be an mpv thing - to open some path via the preferred application.

Preferably this is implemented in one place, either the C code (as normal mpv command), or in some scripting language which makes it accessible to all clients.

Such scripting interfaces already exist: either message-based fire-and-forget (like osc-visibility), or, if the client needs to wait for completion (and do test that it works if this is the intent), then some RPC system like (or even the actual) select.lua.

Also, running a process synchronously is generally highly discouraged, as it completely blocks the event queue of the script.

And IMO none of those is worth cluttering defaults.lua/js, which should be kept minimal as the scripting interface of lua and js.

@guidocella
Copy link
Contributor Author

guidocella commented Jul 24, 2025

I removed the mp.utils helper at avih's request because it is unavailable to JSON IPC and other clients. It's inlined in select.lua for now but a system-open command could be implemented in C later.

Edit: we posted at the same time

Edit 2: switched to use run so it's asynchronous and still logs an error on failure

@avih
Copy link
Member

avih commented Jul 24, 2025

I think it's OK now at select.lua. And indeed run is nicer if you don't need to wait for completion.

Few notes:

  • Make sure you know what happens when using this with --no-config, and if it can be unexpected or non-obvious to the user, note it at the docs.
  • what happens if mpv was launched from a terminal, and the app which ends up running is using the terminal, like vim or nano? (linux/windows/macos). what happens with vim/nano/etc when mpv was not launched from the terminal? what happens when a desktop env is not available? (e.g. playing an audio file at the linux console and triggering this binding).
  • An alternative to launching the default system handler might be to configure an editor in mpv or select.lua script-opts, with some reasonable defaults on unix/windows/macos (e.g. $EDITOR, vi, notepad, whatever).
  • Another alternative might be to (create the file and) show this file in some file browser, and let the user open it with an editor. This should be easy on win/macos, but more tricky on unix in general, though maybe xdg-open path/to/directory/ (without file name) would do that. Or maybe allow specifying the name of this file browser (script opts etc)?
  • I don't know whether there are security implications here, because this ends up running something which the caller (select.lua) did not explicitly specify. Also, I don't know that .conf files are exclusively associated with an editor everywhere.
  • If it's concluded that it's reasonably safe, then I think that opening a file using the default system handler is a useful feature, and it can be trivially exposed to other clients via a normal script message, especially because it's fire-and-forget. So it could be nice if select.lua supported this too, so other clients could open a URL with this, etc.

@guidocella
Copy link
Contributor Author

  • Make sure you know what happens when using this with --no-config, and if it can be unexpected or non-obvious to the user, note it at the docs.

It creates mpv.conf and input.conf in the current working directory. This may be expected since --no-config is documented to make ~~/ an empty string. I don't think it's worth documenting such a niche case.

  • what happens if mpv was launched from a terminal, and the app which ends up running is using the terminal, like vim or nano? (linux/windows/macos). what happens with vim/nano/etc when mpv was not launched from the terminal? what happens when a desktop env is not available? (e.g. playing an audio file at the linux console and triggering this binding).

So as discussed on IRC apparently xdg-open honors Terminal=true in .desktop files only when it delegates to a smarter backend like gio open or gvfs-open, else it just execs the editor directly (https://unix.stackexchange.com/questions/777693/can-i-force-xdg-open-to-use-a-new-terminal-when-opening-a-terminal-app https://www.reddit.com/r/archlinux/comments/4opbt0/is_there_a_way_to_tell_xdgopen_to_use_the_current/). So using edit-config-file with a terminal editor configured and mpv running will make the terminal unusable.

I considered doing something like

elseif os.getenv("XDG_CURRENT_DESKTOP") then
    args = {"xdg-open", path}
else
    -- If the default text editor is a terminal one, xdg-open without a
    -- smart backend like gio open or gvfs-open will open the editor in the
    -- terminal making it unusable if mpv is running. Open the parent
    -- directory to be safe.
    args = {"xdg-open", (select(1, utils.split_path(path)))}

but this will no longer open the file directly for all window manager users who do have a graphical editor configured, and if you don't all graphical applications opening text files with xdg-open won't work anyway.

  • An alternative to launching the default system handler might be to configure an editor in mpv or select.lua script-opts, with some reasonable defaults on unix/windows/macos (e.g. $EDITOR, vi, notepad, whatever).

I'm not sure that is worth it when the main advantage of this feature is for now users who don't have to create the config files and have no idea what select.lua script-opts are. And it is more convenient if the editor you configured system wise is opened by default.

  • Another alternative might be to (create the file and) show this file in some file browser, and let the user open it with an editor. This should be easy on win/macos, but more tricky on unix in general, though maybe xdg-open path/to/directory/ (without file name) would do that. Or maybe allow specifying the name of this file browser (script opts etc)?

There's no standard way to specify which file to focus on startup with Linux file managers, and it is slower than opening the files directly.

  • I don't know whether there are security implications here, because this ends up running something which the caller (select.lua) did not explicitly specify. Also, I don't know that .conf files are exclusively associated with an editor everywhere.

If calling xdg-open was unsafe every application using it would be unsafe.

  • If it's concluded that it's reasonably safe, then I think that opening a file using the default system handler is a useful feature, and it can be trivially exposed to other clients via a normal script message, especially because it's fire-and-forget. So it could be nice if select.lua supported this too, so other clients could open a URL with this, etc.

It's reasonable to convert it to a command but I'm not willing to figure out how to make it work properly on Windows and macOS, but it seems out of place as a select.lua script message and it's just a few lines that you can copy paste and only useful if you need cross-platform support anyway, else you can run xdg-open foo directly.

@avih
Copy link
Member

avih commented Jul 24, 2025

It creates mpv.conf and input.conf in the current working directory. This may be expected since --no-config is documented to make ~~/ an empty string. I don't think it's worth documenting such a niche case.

The user doesn't know it uses ~~/ internally, they don't know it expands to an empty string with no-config, and I'm quite sure they don't expect it to create a config file in the current working directory. It's worth adding a note at the docs.

So using edit-config-file with a terminal editor configured and mpv running will make the terminal unusable.

Right. Not great.

  • An alternative to launching the default system handler might be to configure an editor in mpv or select.lua script-opts, with some reasonable defaults on unix/windows/macos (e.g. $EDITOR, vi, notepad, whatever).

I'm not sure that is worth it when the main advantage of this feature is for now users who don't have to create the config files and have no idea what select.lua script-opts are

And, accorgint to you on IRC:

avih: and what main problem does it solve?
guido: I see users asking it all the time
guido: why they can't find the config file

The main problem for these users is that they don't know where the config file is, together with the fact that it's not created automatically.

And the solution to this problem, other than directing them to the docs, is to create the file and show them where it is.

This can be done trivially in a menu items, by creating the file and printing its path to the OSD.

Opening an editor is an extra, which I agree is convenient, but only if it can be safe, because it IS extra, after we're solved the main problem of creating it and showing where it is.

  • I don't know whether there are security implications here, because this ends up running something which the caller (select.lua) did not explicitly specify. Also, I don't know that .conf files are exclusively associated with an editor everywhere.

If calling xdg-open was unsafe every application using it would be unsafe.

How do you even know that .conf is configured to open an editor? on unix/windows/macos? did you test it's the default with all these OSs? what if the user configured something else to open .conf files? I dunno, run a web server with this as its configuration.

Don't underestimates how systems of clueless users are configured.

This simply has too many boobytraps for an extra beyond the main problem which it solves, even if many users will not encounter them, and I don't think it's worth the hacks which might try to avoid them, and I don't think we can make it part of mpv while we know these boobytraps exist.

Solve the main problem, and leave extras to https://github.com/mpv-player/mpv/wiki/User-Scripts .

Unrelated, I'm pretty sure it doesn't create ~~/ itself if it doesn't exist, which I'm guessing for those clueless users it indeed doesn't exist, so in effect it will not create the config files either.

@guidocella
Copy link
Contributor Author

The user doesn't know it uses ~~/ internally, they don't know it expands to an empty string with no-config, and I'm quite sure they don't expect it to create a config file in the current working directory. It's worth adding a note at the docs.

Just made it return early with --no-config since editing mpv.conf in the working directory is not useful.

So using edit-config-file with a terminal editor configured and mpv running will make the terminal unusable.

Right. Not great.

Opening an editor is an extra, which I agree is convenient, but only if it can be safe

This simply has too many boobytraps

As I explained many times on IRC, configuring xdg-mime this way will break every graphical application opening files with xdg-open including chromium. It is not mpv's responsibility if you configure your system incorrectly. You need to either configure something like alacritty -e nvim as your text handler or use a desktop environment which does it automatically.

By the way, with "can't find" more than the path I'm referring to the fact that even after they find the mpv config directory they don't understand why the config files don't already exist. I see new users asking it often.

How do you even know that .conf is configured to open an editor? on unix/windows/macos? did you test it's the default with all these OSs? what if the user configured something else to open .conf files? I dunno, run a web server with this as its configuration.

xdg-open uses MIME types, not extensions. I indeed don't use Windows and macOS so confirmations from who does are welcome.

Solve the main problem, and leave extras to https://github.com/mpv-player/mpv/wiki/User-Scripts .

There is no point to a user script when the the feature is meant to be discoverable to new users by adding it to mpv's menu.

Unrelated, I'm pretty sure it doesn't create ~~/ itself if it doesn't exist, which I'm guessing for those clueless users it indeed doesn't exist, so in effect it will not create the config files either.

mpv creates it automatically on startup.

@avih
Copy link
Member

avih commented Jul 24, 2025

By the way, with "can't find" more than the path I'm referring to the fact that even after they find the mpv config directory they don't understand why the config files don't already exist. I see new users asking it often.

Yes. And the solution is to create it and show where it is. I said so explicitly. I'm not against these.

There is no point to a user script when the the feature is meant to be discoverable to new users by adding it to mpv's menu.

I'm not against the menu either, as I mentioned explicitly. By all means make a menu item which creates the file and shows where it is.

I only dislike the opening of an unknown external application to edit it, with its associated potential issues. This is the extra which IMO belongs in user-scripts.

@avih
Copy link
Member

avih commented Jul 24, 2025

By all means make a menu item which creates the file and shows where it is.

And if you want to be even more useful, copy its path to the clipboard too.

@na-na-hi
Copy link
Contributor

system_open doesn't belong in mp.utils IMO, at the very least because JSON IPC clients don't have access to it, but also because, if we decide it's important to have, then this really should be an mpv thing - to open some path via the preferred application.
Preferably this is implemented in one place, either the C code (as normal mpv command), or in some scripting language which makes it accessible to all clients.

system_open belongs exactly in mp.utils and not in C code because it has nothing to do with playback:

mp.utils functions
This built-in module provides generic helper functions for Lua, and have strictly speaking nothing to do with mpv or video/audio playback. They are provided for convenience. Most compensate for Lua's scarce standard library.

Not being available to JSON IPC clients is not a good reason to exclude it. They already do not have access to utils.readdir and utils.file_info in any way. And this is OK because these clients are written in other languages and can use their own libraries to achieve the same functionality instead of relying on mpv. The same applies to something like system_open.

Such scripting interfaces already exist: either message-based fire-and-forget (like osc-visibility), or, if the client needs to wait for completion (and do test that it works if this is the intent), then some RPC system like (or even the actual) select.lua.

osc-visibility cannot be implemented in any other way because it has to access the internals of osc.lua. This is not a good reason to justify that system_open should be done in the same way.

And IMO none of those is worth cluttering defaults.lua/js, which should be kept minimal as the scripting interface of lua and js.

I do not consider it something that is really needed in defaults.lua/js so I am OK with it being inside select.lua. I was just saying that it is better than a script-message based interface.

@avih
Copy link
Member

avih commented Jul 25, 2025

Not being available to JSON IPC clients is not a good reason to exclude it. They already do not have access to utils.readdir and utils.file_info in any way.

The trend over the years, possibly pushed and implemented to some degree by me, but not only, has been to remove special things which were only available to scripts, and make them generally available to all clients. From what I recall, this includes at least adding the mouse-pos property and make mp.mouse_pos (iirc) a thin wrapper over it, same for utils.get_pid, expand property-string and path, and more.

While it's true that any client can reimplement it, it's also true for any lua/js mpv scripts, but if we're making it available to scripts, then I think it would be nice of mpv to not limit it to scripts.

I do not consider it something that is really needed in defaults.lua/js so I am OK with it being inside select.lua. I was just saying that it is better than a script-message based interface.

I think duplicating any non trivial logic is not great, and if a trivial message based interface is enough to implement it only in one place, then I don't think it's too bad, even if not ideal. As for where to implement it, you could also say that copy to clipboard is not a core part of player functionality, so the lines can be blurry, though I agree mpv itself is also not ideal for it.

But as it stands, it appears that we don't strictly need this functionality to solve the core user problem here (which is mainly creating a config file and showing where it is), and also that it can have some issues specific to this scenario of launching an editor from mpv, so currently I don't see being vital, at least not here.

@@ -25,6 +25,15 @@ local options = {

require "mp.options".read_options(options, nil, function () end)

local default_config_file = [[# https://mpv.io/manual/master/#configuration-files
# https://mpv.io/manual/master/#options
Copy link
Member

Choose a reason for hiding this comment

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

This should refer to current version of installed mpv, not the master which ma be vastly different

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Switched to stable but we don't seem to have web pages for old versions of the manual.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually linking the current version's docs would be bad because the comments stay in the config files forever without getting updated along with mpv.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think there is no reason for these lines to exist. mpv can already build offiline docs which are accurate no matter what version or git revision is used. There can be another menu entry to open the doc in a browser instead.

@guidocella
Copy link
Contributor Author

Replaced xdg-open with gio open as per linkmauve's suggestion due to xdg-open using tools that are legacy and not XDG compliant depending on the DE.

Add script bindings to edit mpv.conf and input.conf, and add them to the
menu. These are useful as shortcuts, but the main motivation is that new
users often ask why they can't find mpv.conf and input.conf, so this
creates them if they don't exist.
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.

7 participants