From 9a5cf2fc9f9d4afff586109239a1a3640c821727 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Tue, 20 Oct 2020 21:45:29 +1100 Subject: [PATCH] Support explicit register for :, |, ! and $ commands Giving an explicit register uses its content for the default value to use if the user does not enter anything. This enables: `set-register a %{commands}; execute-keys '"a:'` `set-register a %{shell script}; execute-keys '"a|'` ... This provides a nice way to avoid the need to escape keys to use those normal mode commands. Fixes #3825 --- src/normal.cc | 55 +++++++++++-------- test/normal/keep-cmd-reg/cmd | 1 + test/normal/keep-cmd-reg/in | 3 + .../normal/keep-cmd-reg/kak_quoted_selections | 1 + test/normal/keep-cmd-reg/rc | 1 + test/normal/pipe-reg/cmd | 1 + test/normal/pipe-reg/in | 1 + test/normal/pipe-reg/out | 1 + test/normal/pipe-reg/rc | 1 + test/normal/pipe-to-reg/cmd | 1 + test/normal/pipe-to-reg/in | 1 + test/normal/pipe-to-reg/out | 1 + test/normal/pipe-to-reg/rc | 1 + 13 files changed, 45 insertions(+), 24 deletions(-) create mode 100644 test/normal/keep-cmd-reg/cmd create mode 100644 test/normal/keep-cmd-reg/in create mode 100644 test/normal/keep-cmd-reg/kak_quoted_selections create mode 100644 test/normal/keep-cmd-reg/rc create mode 100644 test/normal/pipe-reg/cmd create mode 100644 test/normal/pipe-reg/in create mode 100644 test/normal/pipe-reg/out create mode 100644 test/normal/pipe-reg/rc create mode 100644 test/normal/pipe-to-reg/cmd create mode 100644 test/normal/pipe-to-reg/in create mode 100644 test/normal/pipe-to-reg/out create mode 100644 test/normal/pipe-to-reg/rc diff --git a/src/normal.cc b/src/normal.cc index beb880f9..bd520cb6 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -452,22 +452,24 @@ void for_each_codepoint(Context& context, NormalParams) selections.insert(strings, InsertMode::Replace); } -void command(const Context& context, EnvVarMap env_vars) +void command(const Context& context, EnvVarMap env_vars, char reg = 0) { if (not CommandManager::has_instance()) throw runtime_error{"commands are not supported"}; CommandManager::instance().clear_last_complete_command(); + String default_command = context.main_sel_register_value(reg ? reg : ':').str(); + context.input_handler().prompt( - ":", {}, context.main_sel_register_value(':').str(), + ":", {}, default_command, context.faces()["Prompt"], PromptFlags::DropHistoryEntriesWithBlankPrefix, ':', [](const Context& context, CompletionFlags flags, StringView cmd_line, ByteCount pos) { return CommandManager::instance().complete(context, flags, cmd_line, pos); }, - [env_vars = std::move(env_vars)](StringView cmdline, PromptEvent event, Context& context) { + [env_vars = std::move(env_vars), default_command](StringView cmdline, PromptEvent event, Context& context) { if (context.has_client()) { context.client().info_hide(); @@ -491,12 +493,9 @@ void command(const Context& context, EnvVarMap env_vars) if (event == PromptEvent::Validate) { if (cmdline.empty()) - cmdline = context.main_sel_register_value(':'); - else if (not is_blank(cmdline[0])) - RegisterManager::instance()[':'].set(context, cmdline.str()); + cmdline = default_command; - CommandManager::instance().execute( - cmdline, context, { {}, env_vars }); + CommandManager::instance().execute(cmdline, context, { {}, env_vars }); } }); } @@ -507,7 +506,7 @@ void command(Context& context, NormalParams params) { "count", to_string(params.count) }, { "register", String{¶ms.reg, 1} } }; - command(context, std::move(env_vars)); + command(context, std::move(env_vars), params.reg); } BufferCoord apply_diff(Buffer& buffer, BufferCoord pos, StringView before, StringView after) @@ -545,22 +544,22 @@ BufferCoord apply_diff(Buffer& buffer, BufferCoord pos, StringView before, Strin } template -void pipe(Context& context, NormalParams) +void pipe(Context& context, NormalParams params) { const char* prompt = replace ? "pipe:" : "pipe-to:"; + String default_command = context.main_sel_register_value(params.reg ? params.reg : '|').str(); + context.input_handler().prompt( - prompt, {}, context.main_sel_register_value("|").str(), context.faces()["Prompt"], + prompt, {}, default_command, context.faces()["Prompt"], PromptFlags::DropHistoryEntriesWithBlankPrefix, '|', shell_complete, - [](StringView cmdline, PromptEvent event, Context& context) + [default_command](StringView cmdline, PromptEvent event, Context& context) { if (event != PromptEvent::Validate) return; if (cmdline.empty()) - cmdline = context.main_sel_register_value("|"); - else - RegisterManager::instance()['|'].set(context, cmdline.str()); + cmdline = default_command; if (cmdline.empty()) return; @@ -626,22 +625,22 @@ void pipe(Context& context, NormalParams) } template -void insert_output(Context& context, NormalParams) +void insert_output(Context& context, NormalParams params) { const char* prompt = mode == InsertMode::Insert ? "insert-output:" : "append-output:"; + String default_command = context.main_sel_register_value(params.reg ? params.reg : '|').str(); + context.input_handler().prompt( - prompt, {}, context.main_sel_register_value("|").str(), context.faces()["Prompt"], + prompt, {}, default_command, context.faces()["Prompt"], PromptFlags::DropHistoryEntriesWithBlankPrefix, '|', shell_complete, - [](StringView cmdline, PromptEvent event, Context& context) + [default_command](StringView cmdline, PromptEvent event, Context& context) { if (event != PromptEvent::Validate) return; if (cmdline.empty()) - cmdline = context.main_sel_register_value("|"); - else - RegisterManager::instance()['|'].set(context, cmdline.str()); + cmdline = default_command; if (cmdline.empty()) return; @@ -1133,14 +1132,22 @@ void keep(Context& context, NormalParams params) }); } -void keep_pipe(Context& context, NormalParams) +void keep_pipe(Context& context, NormalParams params) { + String default_command = context.main_sel_register_value(params.reg ? params.reg : '|').str(); context.input_handler().prompt( - "keep pipe:", {}, {}, context.faces()["Prompt"], + "keep pipe:", {}, default_command, context.faces()["Prompt"], PromptFlags::DropHistoryEntriesWithBlankPrefix, '|', shell_complete, - [](StringView cmdline, PromptEvent event, Context& context) { + [default_command](StringView cmdline, PromptEvent event, Context& context) { if (event != PromptEvent::Validate) return; + + if (cmdline.empty()) + cmdline = default_command; + + if (cmdline.empty()) + return; + const Buffer& buffer = context.buffer(); auto& shell_manager = ShellManager::instance(); Vector keep; diff --git a/test/normal/keep-cmd-reg/cmd b/test/normal/keep-cmd-reg/cmd new file mode 100644 index 00000000..83989018 --- /dev/null +++ b/test/normal/keep-cmd-reg/cmd @@ -0,0 +1 @@ +%H"a$ diff --git a/test/normal/keep-cmd-reg/in b/test/normal/keep-cmd-reg/in new file mode 100644 index 00000000..928fc5df --- /dev/null +++ b/test/normal/keep-cmd-reg/in @@ -0,0 +1,3 @@ +foo +rha +bar diff --git a/test/normal/keep-cmd-reg/kak_quoted_selections b/test/normal/keep-cmd-reg/kak_quoted_selections new file mode 100644 index 00000000..57f09b9e --- /dev/null +++ b/test/normal/keep-cmd-reg/kak_quoted_selections @@ -0,0 +1 @@ +'foo' 'bar' diff --git a/test/normal/keep-cmd-reg/rc b/test/normal/keep-cmd-reg/rc new file mode 100644 index 00000000..bb917bfe --- /dev/null +++ b/test/normal/keep-cmd-reg/rc @@ -0,0 +1 @@ +set-register a %{grep 'foo\|bar'} diff --git a/test/normal/pipe-reg/cmd b/test/normal/pipe-reg/cmd new file mode 100644 index 00000000..8c8c8bb9 --- /dev/null +++ b/test/normal/pipe-reg/cmd @@ -0,0 +1 @@ +"a| diff --git a/test/normal/pipe-reg/in b/test/normal/pipe-reg/in new file mode 100644 index 00000000..c2267c2e --- /dev/null +++ b/test/normal/pipe-reg/in @@ -0,0 +1 @@ +%(foo) diff --git a/test/normal/pipe-reg/out b/test/normal/pipe-reg/out new file mode 100644 index 00000000..5716ca59 --- /dev/null +++ b/test/normal/pipe-reg/out @@ -0,0 +1 @@ +bar diff --git a/test/normal/pipe-reg/rc b/test/normal/pipe-reg/rc new file mode 100644 index 00000000..8f2e0357 --- /dev/null +++ b/test/normal/pipe-reg/rc @@ -0,0 +1 @@ +set-register a 'sed s/foo/bar/' diff --git a/test/normal/pipe-to-reg/cmd b/test/normal/pipe-to-reg/cmd new file mode 100644 index 00000000..11789850 --- /dev/null +++ b/test/normal/pipe-to-reg/cmd @@ -0,0 +1 @@ +"a:e! out diff --git a/test/normal/pipe-to-reg/in b/test/normal/pipe-to-reg/in new file mode 100644 index 00000000..d29170cc --- /dev/null +++ b/test/normal/pipe-to-reg/in @@ -0,0 +1 @@ +%(foobar) diff --git a/test/normal/pipe-to-reg/out b/test/normal/pipe-to-reg/out new file mode 100644 index 00000000..189899d2 --- /dev/null +++ b/test/normal/pipe-to-reg/out @@ -0,0 +1 @@ +barbar diff --git a/test/normal/pipe-to-reg/rc b/test/normal/pipe-to-reg/rc new file mode 100644 index 00000000..41a550da --- /dev/null +++ b/test/normal/pipe-to-reg/rc @@ -0,0 +1 @@ +set-register a %{sed -n "s/foo/bar/; P" > out}