diff --git a/doc/pages/commands.asciidoc b/doc/pages/commands.asciidoc index 6b5a48e57c..9fca0fa2d4 100644 --- a/doc/pages/commands.asciidoc +++ b/doc/pages/commands.asciidoc @@ -275,9 +275,12 @@ of the file onto the filesystem embedded quotes. - *shell*:::: - also wrap each arguments in single quotes and escape + also wrap each argument in single quotes and escape embedded quotes in a shell compatible way. + - *json*:::: + convert each argument to a json string and join on newline. + *set-face* :: *alias* face + define a face in *scope* diff --git a/src/commands.cc b/src/commands.cc index d22c06479d..b43cfd98ae 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -28,6 +28,7 @@ #include "remote.hh" #include "shell_manager.hh" #include "string.hh" +#include "string_utils.hh" #include "user_interface.hh" #include "window.hh" @@ -1523,7 +1524,7 @@ const CommandDesc echo_cmd = { "echo ...: display given parameters in the status line", ParameterDesc{ { { "markup", { {}, "parse markup" } }, - { "quoting", { {arg_completer(Array{"raw", "kakoune", "shell"})}, "quote each argument separately using the given style (raw|kakoune|shell)" } }, + { "quoting", { {arg_completer(Array{"raw", "kakoune", "shell", "json"})}, "quote each argument separately using the given style (raw|kakoune|shell|json)" } }, { "end-of-line", { {}, "add trailing end-of-line" } }, { "to-file", { {filename_arg_completer}, "echo contents to given filename" } }, { "to-shell-script", { ArgCompleter{}, "pipe contents to given shell script" } }, @@ -1537,8 +1538,11 @@ const CommandDesc echo_cmd = { { String message; if (auto quoting = parser.get_switch("quoting")) - message = join(parser | transform(quoter(option_from_string(Meta::Type{}, *quoting))), - ' ', false); + { + auto quote_type = option_from_string(Meta::Type{}, *quoting); + message = join(parser | transform(quoter(quote_type)), + (quote_type == Quoting::Json ? '\n' : ' '), false); + } else message = join(parser, ' ', false); diff --git a/src/string_utils.hh b/src/string_utils.hh index 3034dfd5c9..4e1f8bbf6b 100644 --- a/src/string_utils.hh +++ b/src/string_utils.hh @@ -7,6 +7,7 @@ #include "ranges.hh" #include "optional.hh" #include "utils.hh" +#include "json.hh" namespace Kakoune { @@ -188,11 +189,17 @@ inline String shell_quote(StringView s) return format("'{}'", replace(s, "'", R"('\'')")); } +inline String json_quote(StringView s) +{ + return format("{}", to_json(s)); +} + enum class Quoting { Raw, Kakoune, - Shell + Shell, + Json }; constexpr auto enum_desc(Meta::Type) @@ -200,7 +207,8 @@ constexpr auto enum_desc(Meta::Type) return make_array>({ { Quoting::Raw, "raw" }, { Quoting::Kakoune, "kakoune" }, - { Quoting::Shell, "shell" } + { Quoting::Shell, "shell" }, + { Quoting::Json, "json" } }); } @@ -210,6 +218,7 @@ inline auto quoter(Quoting quoting) { case Quoting::Kakoune: return "e; case Quoting::Shell: return &shell_quote; + case Quoting::Json: return &json_quote; case Quoting::Raw: default: return +[](StringView s) { return s.str(); };