mp.input: allow async completions

Previously, it was impossible to generate a list of completions for an
`input.get()` request asynchronously, as the values had to be returned
by the callback function.

This commit provides a way to send completions asynchronously by passing
a second argument to the complete callback; a function which can be
passed the return values to respond to the complete event.
This commit is contained in:
CogentRedTester authored and Kacper Michajłow committed 2026-02-24 20:19:24 +01:00
1 parent cf481faa72
commit c72f2add25
3 files changed
+46 -24

No files matched your search

+12 -5
View File
@@ -946,14 +946,21 @@ REPL.
``complete``
A callback invoked when the user edits the text or moves the cursor. The
first argument is the text before the cursor. The callback should return
a table of the string candidate completion values and the 1-based cursor
first argument is the text before the cursor, and the second argument is
a response function which can be called to present completion values to
the user.
The first argument to the response function is a table of the string
candidate completion values, and the second argument is the 1-based cursor
position from which the completion starts. console will show the
completions that fuzzily match the text between this position and the
cursor and allow selecting them.
cursor, which the user can select with ``TAB``. The completions will only
be shown to the user if the text before the cursor has not since changed.
The response function should be called with an empty table if there are no
completion values to display.
The third and optional return value is a string that will be appended to
the input line without displaying it in the completions.
The third and optional argument to the response function is a string that
will be appended to the input line without displaying it in the completions.
``autoselect_completion``
Whether to automatically select the first completion on submit if one
+18 -11
View File
@@ -662,26 +662,33 @@ function register_event_handler(t) {
latest_handler_id = handler_id;
mp.register_script_message(handler_id, function (type, args) {
if (latest_handler_id !== handler_id && type !== "closed")
if (type == "closed")
mp.unregister_script_message(handler_id);
if (!t[type] || (latest_handler_id !== handler_id && type !== "closed"))
return;
if (t[type]) {
args = args ? JSON.parse(args) : [];
var result = t[type].apply(null, args);
args = args ? JSON.parse(args) : [];
if (type == "complete") {
var complete = function(completions, completion_pos, completion_append) {
if (completions == undefined)
return;
if (type == "complete" && result) {
mp.commandv("script-message-to", "console", "complete", JSON.stringify({
client_name: mp.script_name,
handler_id: handler_id,
list: result[0],
start_pos: result[1],
append: result[2] || "",
list: completions,
start_pos: completion_pos,
append: completion_append || "",
}));
}
}
if (type == "closed")
mp.unregister_script_message(handler_id);
args[1] = complete;
complete.apply(null, t[type].apply(null, args));
} else {
t[type].apply(null, args)
}
})
return handler_id;
+16 -8
View File
@@ -40,16 +40,23 @@ local function register_event_handler(t)
latest_handler_id = handler_id
mp.register_script_message(handler_id, function (type, args)
if type == "closed" then
mp.unregister_script_message(handler_id)
end
-- do not process events (other than closed) for an input that has been overwritten
if latest_handler_id ~= handler_id and type ~= "closed" then
if not t[type] or (latest_handler_id ~= handler_id and type ~= "closed") then
return
end
if t[type] then
local completions, completion_pos, completion_append =
t[type](unpack(utils.parse_json(args or "") or {}))
args = utils.parse_json(args or "") or {}
if type == "complete" then
local function complete(completions, completion_pos, completion_append)
if not completions then
return
end
if type == "complete" and completions then
mp.commandv("script-message-to", "console", "complete", utils.format_json({
client_name = mp.get_script_name(),
handler_id = handler_id,
@@ -58,10 +65,11 @@ local function register_event_handler(t)
append = completion_append or "",
}))
end
end
if type == "closed" then
mp.unregister_script_message(handler_id)
args[2] = complete
complete(t[type](unpack(args)))
else
t[type](unpack(args))
end
end)