1
1
mirror of https://github.com/mawww/kakoune.git synced 2024-08-17 00:30:26 +03:00
This commit is contained in:
Devin J. Pohly 2024-06-27 14:57:47 +01:00 committed by GitHub
commit c875b1ce44
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 43 additions and 4 deletions

View File

@ -843,7 +843,9 @@ The following keys are recognized by this mode to help with editing
These keys are used to cancel long-running operations, either inside
Kakoune or outside it. Because they are intended as a safety mechanism
when something goes wrong, these keys are handled very early on in
Kakoune's input processing, and therefore cannot be remapped in any mode.
Kakoune's input processing, so they can only be remapped by changing
the `interrupt_key` and `cancel_key` options (see
<<options#builtin-options,`:doc options builtin-options`>>).
*<c-c>*::
Stop any external processes. If you ever see Kakoune display a message

View File

@ -79,6 +79,10 @@ are exclusively available to built-in options.
as a string but the set commands will complain if the entered text
is not a valid regex
*key*::
a single keypress using the same syntax as `map` (see
<<mapping#mappable-keys,`:doc mapping mappable-keys`>>)
*coord*::
a line, column pair (separated by a comma)
Cannot be used with `declare-option`
@ -312,6 +316,15 @@ are exclusively available to built-in options.
*debug* `flags(hooks|shell|profile|keys|commands)`::
dump various debug information in the '\*debug*' buffer
*interrupt_key* `key`::
_default_ <c-c> +
key used to interrupt any running external processes
*cancel_key* `key`::
_default_ <c-g> +
key used to cancel long-running Kakoune operations and clear the input
buffer
*idle_timeout* `int`::
_default_ 50 +
timeout, in milliseconds, with no user input that will trigger the

View File

@ -47,13 +47,14 @@ Client::Client(std::unique_ptr<UserInterface>&& ui,
m_ui->set_ui_options(m_window->options()["ui_options"].get<UserInterface::Options>());
m_ui->set_on_key([this](Key key) {
kak_assert(key != Key::Invalid);
if (key == ctrl('c'))
auto& opts = context().options();
if (key == opts["interrupt_key"].get<Key>())
{
auto prev_handler = set_signal_handler(SIGINT, SIG_IGN);
killpg(getpgrp(), SIGINT);
set_signal_handler(SIGINT, prev_handler);
}
else if (key == ctrl('g'))
else if (key == opts["cancel_key"].get<Key>())
{
m_pending_keys.clear();
print_status({"operation cancelled", context().faces()["Error"]});

View File

@ -1869,6 +1869,7 @@ const CommandDesc declare_option_cmd = {
" bool: boolean (true/false or yes/no)\n"
" str: character string\n"
" regex: regular expression\n"
" key: keystroke specifier\n"
" int-list: list of integers\n"
" str-list: list of character strings\n"
" completions: list of completion candidates\n"
@ -1885,7 +1886,7 @@ const CommandDesc declare_option_cmd = {
make_completer(
[](const Context& context, CompletionFlags flags,
StringView prefix, ByteCount cursor_pos) -> Completions {
auto c = {"int", "bool", "str", "regex", "int-list", "str-list", "completions", "line-specs", "range-specs", "str-to-str-map"};
auto c = {"int", "bool", "str", "regex", "key", "int-list", "str-list", "completions", "line-specs", "range-specs", "str-to-str-map"};
return { 0_byte, cursor_pos, complete(prefix, cursor_pos, c), Completions::Flags::Menu };
}),
[](const ParametersParser& parser, Context& context, const ShellContext&)
@ -1908,6 +1909,8 @@ const CommandDesc declare_option_cmd = {
opt = &reg.declare_option<String>(parser[1], docstring, "", flags);
else if (parser[0] == "regex")
opt = &reg.declare_option<Regex>(parser[1], docstring, Regex{}, flags);
else if (parser[0] == "key")
opt = &reg.declare_option<Key>(parser[1], docstring, Key(Key::Invalid), flags);
else if (parser[0] == "int-list")
opt = &reg.declare_option<Vector<int, MemoryDomain::Options>>(parser[1], docstring, {}, flags);
else if (parser[0] == "str-list")

View File

@ -223,6 +223,20 @@ String to_string(Key key)
return res;
}
String option_to_string(const Key& key)
{
return to_string(key);
}
Key option_from_string(Meta::Type<Key>, StringView str)
{
auto keys = parse_keys(str);
if (keys.size() != 1)
throw runtime_error(format("'{}' is not a single key", str));
return keys.front();
}
UnitTest test_keys{[]()
{
KeyList keys{

View File

@ -94,6 +94,8 @@ struct Key
static Modifiers to_modifier(MouseButton button) { return Key::Modifiers{((int)button << 6) & (int)Modifiers::MouseButtonMask}; }
Optional<Codepoint> codepoint() const;
static constexpr const char* option_type_name = "key";
};
constexpr bool with_bit_ops(Meta::Type<Key::Modifiers>) { return true; }
@ -107,6 +109,8 @@ KeyList parse_keys(StringView str);
String to_string(Key key);
StringView to_string(Key::MouseButton button);
Key::MouseButton str_to_button(StringView str);
String option_to_string(const Key& key);
Key option_from_string(Meta::Type<Key>, StringView str);
constexpr Key shift(Key key)
{

View File

@ -616,6 +616,8 @@ void register_options()
"set of pair of characters to be considered as matching pairs",
{ '(', ')', '{', '}', '[', ']', '<', '>' });
reg.declare_option<int>("startup_info_version", "version up to which startup info changes should be hidden", 0);
reg.declare_option("cancel_key", "key used to cancel long-running operations", ctrl('g'));
reg.declare_option("interrupt_key", "key used to stop external processes", ctrl('c'));
}
static Client* local_client = nullptr;