{"id":13835499,"url":"https://github.com/CogentRedTester/mpv-user-input","last_synced_at":"2025-07-10T07:32:21.228Z","repository":{"id":37860043,"uuid":"330349125","full_name":"CogentRedTester/mpv-user-input","owner":"CogentRedTester","description":"API to allow mpv scripts to request user text input","archived":false,"fork":false,"pushed_at":"2023-12-27T13:06:01.000Z","size":104,"stargazers_count":53,"open_issues_count":0,"forks_count":6,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-03T20:11:15.189Z","etag":null,"topics":["mpv","mpv-script","text-input","user-input"],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CogentRedTester.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2021-01-17T08:46:56.000Z","updated_at":"2025-02-27T09:15:22.000Z","dependencies_parsed_at":"2023-12-27T14:25:38.082Z","dependency_job_id":null,"html_url":"https://github.com/CogentRedTester/mpv-user-input","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/CogentRedTester/mpv-user-input","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CogentRedTester%2Fmpv-user-input","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CogentRedTester%2Fmpv-user-input/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CogentRedTester%2Fmpv-user-input/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CogentRedTester%2Fmpv-user-input/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CogentRedTester","download_url":"https://codeload.github.com/CogentRedTester/mpv-user-input/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CogentRedTester%2Fmpv-user-input/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264545168,"owners_count":23625404,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["mpv","mpv-script","text-input","user-input"],"created_at":"2024-08-04T14:01:03.551Z","updated_at":"2025-07-10T07:32:21.010Z","avatar_url":"https://github.com/CogentRedTester.png","language":"Lua","funding_links":[],"categories":["Library","others"],"sub_categories":[],"readme":"# mpv-user-input\n\nThis script aims to create a common API that other scripts can use to request text input from the user via the OSD.\nThis script was built from [mpv's console.lua](https://github.com/mpv-player/mpv/blob/7ca14d646c7e405f3fb1e44600e2a67fc4607238/player/lua/console.lua).\nThe logging, commands, and tab completion have been removed, leaving just the text input and history code.\nAs a result this script's text input has almost identical behaviour to console.lua.\n\nAround the original code is a system to recieve input requests via script messages, and respond with the users input, and an error message if the request was somehow terminated.\nThe script utilises a queue system to handle multiple requests at once, and there are various option flags to control how to handle multiple requests from the same source.\n\nUsage of this API requires that standard interface functions be used to request and cancel input requests, these functions are packaged into [user-input-module.lua](/user-input-module.lua), which can be loaded as a module, or simply pasted into another script.\nIf a script does choose to load the module, then I recommend it be loaded from `~~/script-modules` rather than `~~/scripts`.\n\nThe aim of this script is that it be seamless enough that it could be added to mpv player officially.\n\nFor versions of mpv ≤ v0.36 see the [mpv-v0.36 branch](https://github.com/CogentRedTester/mpv-user-input/tree/mpv-v0.36).\n\n## Installation\n\n**If you've been directed here by another script that requires this API follow these instructions unless told otherwise.**\n\nPlace [user-input.lua](user-input.lua) inside the `~~/scripts/` directory, and place [user-input-module.lua](user-input-module.lua) inside the `~~/script-modules/` directory.\nCreate these directories if they do not exist. `~~/` represents the mpv config directory.\n\n### Advanced\n\nWhat is important is that `user-input.lua` is loaded as a script my mpv, which can be done from anywhere using the `--script` option.\nMeanwhile, `user-input-module.lua` needs to be in one of the lua package paths; scripts that use this API are recommended to use `~~/script-modules/`, but you can set any directory using the `LUA_PATH` environment variable.\n\n### Developers\n\nIf you use the recommended `~~/script-modules/` directory then load this addon with the following code:\n\n```lua\npackage.path = mp.command_native({\"expand-path\", \"~~/script-modules/?.lua;\"})..package.path\nlocal input = require \"user-input-module\"\n```\n\n## Interface Functions - v0.1.0\n\nNote: this API is still in its early stages, so these functions may change.\n\n### `get_user_input(fn [, options [, ...]])`\n\nRequests input from the user and returns a request table.\n\n```lua\ninput.get_user_input(print) -- prints the user input plus the error code\n```\n\n`fn` is called when user-input sends a response, the first argument will be the input string the user entered,\nthe second argument will be an error string if the input is `nil`.\nAny additional arguments sent after the options table will be sent to fn as additional arguments after the error string.\n\nThe following error codes currently exist:\n\n```properties\n    exited          the user closed the input instead of pressing Enter\n    already_queued  a request with the specified id was already in the queue\n    cancelled       the request was cancelled\n    replaced        request was replaced\n```\n\nIf the request throws an error for whatever reason then that Lua error message will be returned instead.\nThose error messages are undefined and could change at any time.\n\n#### options\n\nOptions is an optional table of values and flags which can be used to control the behaviour of user-input. The function will preset some options if they are left blank.\nThe following options are currently available:\n\n| name          | type    | default                   | description                                                                                                       |\n|---------------|---------|---------------------------|-------------------------------------------------------------------------------------------------------------------|\n| id            | string  | mp.get_script_name()..`/` | used for storing input history and detecting duplicate requests                                                   |\n| source        | string  | mp.get_script_name()      | used to show the source of the request in square brackets                                                         |\n| request_text  | string  | `requesting user input:`  | printed above the input box - use it to describe the input request                                                |\n| default_input | string  |                           | text to pre-enter into the input                                                                                  |\n| cursor_pos    | number  | 1                         | the numerical position to place the cursor - for use with the default_input field                                 |\n| queueable     | boolean | false                     | allows requests to be queued even if there is already one queued with the same id                                 |\n| replace       | boolean | false                     | replace the queued request with the same id with the new request                                                      |\n\nThe function prepends the script name to any id to avoid conflicts between\ndifferent scripts.\nDo not use both the `queuable` and `replace` flags for input requests with the same ID, the behaviour is undefined and may change at any time.\n\nHere is an example for printing only a sucessful input:\n\n```lua\ninput.get_user_input(function(line, err)\n        if line then print(line) end\n    end, { request_text = \"print text:\" })\n```\n\n#### request table\n\nThe request table returned by `get_user_input` can be used to modify the behaviour of an existing request.\nThe defined fields are:\n\n| name          | type    | description                                                                                                       |\n|---------------|---------|-------------------------------------------------------------------------------------------------------------------|\n| callback      | function| the callback function - same as `fn` passed to `get_user_input()` - can be set to a different function to modify the callback |\n| passthrough_args | table| an array of extra arguments to pass to the callback - cannot be `nil`                                             |\n| pending       | boolean | true if the request is still pending, false if the request is completed                                           |\n| cancel        | method  | cancels the request - unlike `cancel_user_input()` this does not cancel all requests with a matching id           |\n| update        | method  | takes an options table and updates the request - maintains the original request unlike the `replace` flag - not all options can be changed |\n\nA method is referring to a function that is called with Lua's method syntax:\n\n```lua\nlocal request = input.get_user_input(print)\nrequest:update{\n    request_text = \"hello world:\"\n}\nrequest:cancel()\n```\n\n### `cancel_user_input([id])`\n\nRemoves all input requests with a matching string id.\nIf no id is provided, then the default id for `get_user_input()` will be used.\n\nThe cancellation happens asynchronously.\n\n### `get_user_input_co([options [, co_resume]])`\n\nThis is a wrapper function around `get_user_input()` that uses [coroutines](https://www.lua.org/manual/5.1/manual.html#2.11)\nto make the input request behave synchronously. It returns `line, err`, as would\nnormally be passed to the callback function.\n\nThis function will yield the current coroutine and resume once the input\nresponse has been received. If the coroutine is forcibly resumed by the user then\nit will send a cancellation request to `user-input` and will return `nil, 'cancelled'`.\nThe request object is passed to the yield function.\n\n```lua\nlocal function main()\n    local line, err = input.get_user_input_co({ request_text = 'test input:' })\n    if line then print(line) end\nend\n\nlocal co = coroutine.create(main)\nlocal success, request = coroutine.resume(co)\n```\n\nIf a function is passed as `co_resume` then custom resume behaviour can be setup instead\nof the default `coroutine.resume`. This can be useful if you want to define what happens when an error is thrown.\nThis function is the equivalent of the usual callback function, except it's purpose is to resume\nthe yielded coroutine and that it has three agruments:\n`uid, line, err` where `uid` is a unique variable that needs to be\npassed to `coroutine.resume()`. The functions created by `coroutine.wrap()` can be passed into here.\nThe following examples show how this can be used to propogate errors using `coroutine.wrap()`,\nand how to safely catch and print errors using a custom error handler.\n\n```lua\n-- if an error is thrown the script will crash instead of the error being caught\nlocal driver\ndriver = coroutine.wrap(function()\n    local line, err = input.get_user_input_co({ request_text = 'test input:' }, driver)\n    if line then print(line) end\nend)\n\nlocal request = driver()\n```\n\n```lua\n-- if the coroutine throws an error it is caught and a stack trace is printed\n-- note that the error handler shown here is actually what is used by default when `co_resume` is nil\nfunction coroutine_resume_err(uid, line, err)\n    local co = coroutine.running()\n    local success, err = coroutine.resume(co, uid, line, err)\n    if not success then\n        msg.warn( debug.traceback(co) )\n        msg.error(err)\n    end\nend\n\nlocal function main()\n    local line, err = input.get_user_input_co({ request_text = 'test input:' }, coroutine_resume_err)\n    if line then print(line) end\nend\n\nlocal co = coroutine.create(main)\nlocal success, request = coroutine.resume(co)\n```\n\n## Examples\n\nThe [examples](/examples) folder contains some scripts that make user of the API.\n\nYou can find more examples in the [wiki page](https://github.com/CogentRedTester/mpv-user-input/wiki/Scripts-that-use-mpv%E2%80%90user%E2%80%90input).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FCogentRedTester%2Fmpv-user-input","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FCogentRedTester%2Fmpv-user-input","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FCogentRedTester%2Fmpv-user-input/lists"}