mirror of
https://github.com/mawww/kakoune.git
synced 2024-08-16 16:20:38 +03:00
Also check shell parameters for kak_* references
This makes it easier to pass shell fragments as arguments so that %sh{ eval "$@" } just works even if arguments refer to Kakoune's vars.
This commit is contained in:
parent
688e87d668
commit
1bdae3f9c4
@ -3,6 +3,10 @@
|
|||||||
This changelog contains major and/or breaking changes to Kakoune between
|
This changelog contains major and/or breaking changes to Kakoune between
|
||||||
released versions.
|
released versions.
|
||||||
|
|
||||||
|
== Development version
|
||||||
|
|
||||||
|
* Expose env vars that are mentionned in the arguments passed to shell expansions
|
||||||
|
|
||||||
== Kakoune 2024.05.18
|
== Kakoune 2024.05.18
|
||||||
|
|
||||||
* Fixed tests on Alpine Linux and *BSD
|
* Fixed tests on Alpine Linux and *BSD
|
||||||
|
@ -146,14 +146,16 @@ and unquote them, then execute the resulting `set` command, which sets
|
|||||||
the shell's argument variables to the items from `$kak_selections`. The
|
the shell's argument variables to the items from `$kak_selections`. The
|
||||||
`while` loop with `shift` iterates through the arguments one by one.
|
`while` loop with `shift` iterates through the arguments one by one.
|
||||||
|
|
||||||
Only variables actually mentioned in the body of the shell expansion will
|
Only variables actually mentioned in the body of the shell expansion or
|
||||||
be exported into the shell's environment. For example:
|
in passed arguments will be exported into the shell's environment.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
----
|
----
|
||||||
echo %sh{ env | grep ^kak_ }
|
echo %sh{ env | grep ^kak_ }
|
||||||
----
|
----
|
||||||
|
|
||||||
... will find none of Kakoune's special environment variables, but:
|
... will not find any of Kakoune's special environment variables, but:
|
||||||
|
|
||||||
----
|
----
|
||||||
echo %sh{ env | grep ^kak_ # kak_session }
|
echo %sh{ env | grep ^kak_ # kak_session }
|
||||||
@ -162,6 +164,15 @@ echo %sh{ env | grep ^kak_ # kak_session }
|
|||||||
... will find the `$kak_session` variable because it was mentioned by name
|
... will find the `$kak_session` variable because it was mentioned by name
|
||||||
in a comment, even though it wasn't directly used.
|
in a comment, even though it wasn't directly used.
|
||||||
|
|
||||||
|
----
|
||||||
|
define-command -params .. eval-shell %{ echo %sh{ eval "$@" } }
|
||||||
|
eval-shell 'echo $kak_session'
|
||||||
|
----
|
||||||
|
|
||||||
|
... will also find the `$kak_session` variable because it was mentioned by name
|
||||||
|
in the command arguments, which are automatically made available to shell blocks
|
||||||
|
as "$@"
|
||||||
|
|
||||||
TIP: These environment variables are also available in other contexts where
|
TIP: These environment variables are also available in other contexts where
|
||||||
Kakoune uses a shell command, such as the `|`, `!` or `$` normal mode commands
|
Kakoune uses a shell command, such as the `|`, `!` or `$` normal mode commands
|
||||||
(See <<keys#,`:doc keys`>>).
|
(See <<keys#,`:doc keys`>>).
|
||||||
|
@ -45,6 +45,9 @@ struct {
|
|||||||
unsigned int version;
|
unsigned int version;
|
||||||
StringView notes;
|
StringView notes;
|
||||||
} constexpr version_notes[] = { {
|
} constexpr version_notes[] = { {
|
||||||
|
0,
|
||||||
|
"» kak_* appearing in shell arguments will be added to the environment\n"
|
||||||
|
}, {
|
||||||
20240518,
|
20240518,
|
||||||
"» Fix tests failing on some platforms\n"
|
"» Fix tests failing on some platforms\n"
|
||||||
}, {
|
}, {
|
||||||
|
@ -141,30 +141,35 @@ Shell spawn_shell(const char* shell, StringView cmdline,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename GetValue>
|
template<typename GetValue>
|
||||||
Vector<String> generate_env(StringView cmdline, const Context& context, GetValue&& get_value)
|
Vector<String> generate_env(StringView cmdline, ConstArrayView<String> params, const Context& context, GetValue&& get_value)
|
||||||
{
|
{
|
||||||
static const Regex re(R"(\bkak_(quoted_)?(\w+)\b)");
|
static const Regex re(R"(\bkak_(quoted_)?(\w+)\b)");
|
||||||
|
|
||||||
Vector<String> env;
|
Vector<String> env;
|
||||||
for (auto&& match : RegexIterator{cmdline.begin(), cmdline.end(), re})
|
auto add_matches = [&](StringView s) {
|
||||||
{
|
for (auto&& match : RegexIterator{s.begin(), s.end(), re})
|
||||||
StringView name{match[2].first, match[2].second};
|
|
||||||
StringView shell_name{match[0].first, match[0].second};
|
|
||||||
|
|
||||||
auto match_name = [&](const String& s) {
|
|
||||||
return s.substr(0_byte, shell_name.length()) == shell_name and
|
|
||||||
s.substr(shell_name.length(), 1_byte) == "=";
|
|
||||||
};
|
|
||||||
if (any_of(env, match_name))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
StringView quoted{match[1].first, match[1].second};
|
StringView name{match[2].first, match[2].second};
|
||||||
Quoting quoting = match[1].matched ? Quoting::Shell : Quoting::Raw;
|
StringView shell_name{match[0].first, match[0].second};
|
||||||
env.push_back(format("kak_{}{}={}", quoted, name, get_value(name, quoting)));
|
|
||||||
} catch (runtime_error&) {}
|
auto match_name = [&](const String& s) {
|
||||||
}
|
return s.substr(0_byte, shell_name.length()) == shell_name and
|
||||||
|
s.substr(shell_name.length(), 1_byte) == "=";
|
||||||
|
};
|
||||||
|
if (any_of(env, match_name))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
StringView quoted{match[1].first, match[1].second};
|
||||||
|
Quoting quoting = match[1].matched ? Quoting::Shell : Quoting::Raw;
|
||||||
|
env.push_back(format("kak_{}{}={}", quoted, name, get_value(name, quoting)));
|
||||||
|
} catch (runtime_error&) {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
add_matches(cmdline);
|
||||||
|
for (auto&& param : params)
|
||||||
|
add_matches(param);
|
||||||
|
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
@ -265,13 +270,13 @@ std::pair<String, int> ShellManager::eval(
|
|||||||
const DebugFlags debug_flags = context.options()["debug"].get<DebugFlags>();
|
const DebugFlags debug_flags = context.options()["debug"].get<DebugFlags>();
|
||||||
const bool profile = debug_flags & DebugFlags::Profile;
|
const bool profile = debug_flags & DebugFlags::Profile;
|
||||||
if (debug_flags & DebugFlags::Shell)
|
if (debug_flags & DebugFlags::Shell)
|
||||||
write_to_debug_buffer(format("shell:\n{}\n----\n", cmdline));
|
write_to_debug_buffer(format("shell:\n{}\n----\nargs: {}\n----\n", cmdline, join(shell_context.params | transform(shell_quote), ' ')));
|
||||||
|
|
||||||
auto start_time = profile ? Clock::now() : Clock::time_point{};
|
auto start_time = profile ? Clock::now() : Clock::time_point{};
|
||||||
|
|
||||||
Optional<CommandFifos> command_fifos;
|
Optional<CommandFifos> command_fifos;
|
||||||
|
|
||||||
auto kak_env = generate_env(cmdline, context, [&](StringView name, Quoting quoting) {
|
auto kak_env = generate_env(cmdline, shell_context.params, context, [&](StringView name, Quoting quoting) {
|
||||||
if (name == "command_fifo" or name == "response_fifo")
|
if (name == "command_fifo" or name == "response_fifo")
|
||||||
{
|
{
|
||||||
if (not command_fifos)
|
if (not command_fifos)
|
||||||
@ -377,7 +382,7 @@ std::pair<String, int> ShellManager::eval(
|
|||||||
Shell ShellManager::spawn(StringView cmdline, const Context& context,
|
Shell ShellManager::spawn(StringView cmdline, const Context& context,
|
||||||
bool open_stdin, const ShellContext& shell_context)
|
bool open_stdin, const ShellContext& shell_context)
|
||||||
{
|
{
|
||||||
auto kak_env = generate_env(cmdline, context, [&](StringView name, Quoting quoting) {
|
auto kak_env = generate_env(cmdline, shell_context.params, context, [&](StringView name, Quoting quoting) {
|
||||||
if (auto it = shell_context.env_vars.find(name); it != shell_context.env_vars.end())
|
if (auto it = shell_context.env_vars.find(name); it != shell_context.env_vars.end())
|
||||||
return it->value;
|
return it->value;
|
||||||
return join(get_val(name, context) | transform(quoter(quoting)), ' ', false);
|
return join(get_val(name, context) | transform(quoter(quoting)), ' ', false);
|
||||||
|
Loading…
Reference in New Issue
Block a user