Add support for -on-change and -on-abort to prompt

Fixes #1209
This commit is contained in:
Maxime Coste 2017-02-12 12:51:58 +00:00
parent 9ba1665e58
commit 2edb7d62ef
2 changed files with 24 additions and 9 deletions

View File

@ -160,6 +160,10 @@ commands:
*-password* switch hides the entered text and clears the register *-password* switch hides the entered text and clears the register
after command execution. after command execution.
The *-on-change* and *-on-abort* switches, followed by a command
will have this command executed whenever the prompt content changes
or the prompt is aborted, respectively.
*on-key* <command>:: *on-key* <command>::
wait for next key from user, then execute <command>, the key is wait for next key from user, then execute <command>, the key is
available through the `key` value, accessible through `$kak_key` available through the `key` value, accessible through `$kak_key`

View File

@ -1713,7 +1713,9 @@ const CommandDesc prompt_cmd = {
{ "file-completion", { false, "use file completion for prompt" } }, { "file-completion", { false, "use file completion for prompt" } },
{ "client-completion", { false, "use client completion for prompt" } }, { "client-completion", { false, "use client completion for prompt" } },
{ "buffer-completion", { false, "use buffer completion for prompt" } }, { "buffer-completion", { false, "use buffer completion for prompt" } },
{ "command-completion", { false, "use command completion for prompt" } } }, { "command-completion", { false, "use command completion for prompt" } },
{ "on-change", { true, "command to execute whenever the prompt changes" } },
{ "on-abort", { true, "command to execute whenever the prompt is canceled" } } },
ParameterDesc::Flags::None, 2, 2 ParameterDesc::Flags::None, 2, 2
}, },
CommandFlags::None, CommandFlags::None,
@ -1751,26 +1753,35 @@ const CommandDesc prompt_cmd = {
const auto flags = parser.get_switch("password") ? const auto flags = parser.get_switch("password") ?
PromptFlags::Password : PromptFlags::None; PromptFlags::Password : PromptFlags::None;
String on_change = parser.get_switch("on-change").value_or("").str();
String on_abort = parser.get_switch("on-abort").value_or("").str();
CapturedShellContext sc{shell_context}; CapturedShellContext sc{shell_context};
context.input_handler().prompt( context.input_handler().prompt(
parser[0], initstr.str(), get_face("Prompt"), parser[0], initstr.str(), get_face("Prompt"),
flags, std::move(completer), flags, std::move(completer),
[=](StringView str, PromptEvent event, Context& context) mutable [=](StringView str, PromptEvent event, Context& context) mutable
{ {
if (event != PromptEvent::Validate) if ((event == PromptEvent::Abort and on_abort.empty()) or
(event == PromptEvent::Change and on_change.empty()))
return; return;
sc.env_vars["text"] = str.str();
auto& text = sc.env_vars["text"] = str.str();
auto clear_password = on_scope_end([&] {
if (flags & PromptFlags::Password)
memset(text.data(), 0, (int)text.length());
});
ScopedSetBool disable_history{context.history_disabled()}; ScopedSetBool disable_history{context.history_disabled()};
CommandManager::instance().execute(command, context, sc); StringView cmd;
switch (event)
if (flags & PromptFlags::Password)
{ {
String& str = sc.env_vars["text"];; case PromptEvent::Validate: cmd = command; break;
memset(str.data(), 0, (int)str.length()); case PromptEvent::Change: cmd = on_change; break;
str = ""; case PromptEvent::Abort: cmd = on_abort; break;
} }
CommandManager::instance().execute(cmd, context, sc);
}); });
} }
}; };