Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to override environment variables in child processes #5063

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

krobelus
Copy link
Contributor

@krobelus krobelus commented Dec 16, 2023

Today I have to restart Kakoune in order to set environment variables
in shell expansions globally. For example KAK_LSP_FORCE_PROJECT_ROOT or RUST_BACKTRACE.


Another use case is when using rust-analyzer's test framework.
When a test fails, it tells me to run env UPDATE_EXPECT=1 cargo test to update test with the actual behavior.
The kakoune-cargo plugin does not provide a way to set environment variables.
The reason I want to run this from the editor is that this allows me to run only the test at cursor (using rust-analyzer code lenses).


When running ":git" commands, there is an ambiguity on whether to
use the $PWD or the buffer's worktree. We use $PWD but it should be
possible to override this behavior. An obvious way to do this is to
override Git environment variables:

set-option -add global env GIT_WORK_TREE=/path/to/my/repo GIT_DIR=/path/to/my/repo.git

(another in-flight patch adds the obvious default to GIT_DIR so we don't need to set that).


There are some minor issues left

  • If a user sets PATH, this will stomp the one we setenv()'d.
  • Today both key and value require escaping for = and . This is not
    intuitive. Since neither environment variables nor ui_options ever
    need a = in the key name, we can get rid of the escaping.

Alternative approach: The str-to-str-map can be somewhat clunky. We
could instead export any option named like env_FOO. Not yet sure
which approach is better.

Alternative: maybe a setenv or export command?

Closes #4482
That issues asks for a separate client-specific env as well but we
don't have a client scope so I'm not sure.

Today I have to restart Kakoune in order to set environment variables
in shell expansions globally. For example KAK_LSP_FORCE_PROJECT_ROOT.

When running ":git" commands, there is an ambiguity on whether to
use the $PWD or the buffer's worktree.  We use $PWD but it should be
possible to override this behavior.  An obvious way to do this is to
override Git environment variables:

	set-option -add global env GIT_WORK_TREE=/path/to/my/repo GIT_DIR=/path/to/my/repo.git

(another in-flight patch adds the obvious default to GIT_DIR so we don't need to set that).

---

There are some minor issues left
- If a user sets PATH, this will stomp the one we setenv()'d.
- Today both key and value require escaping for = and \. This is not
  intuitive. Since neither environment variables nor ui_options ever
  need a = in the key name, we can get rid of the escaping.

Alternative approach: The str-to-str-map can be somewhat clunky. We
could instead export any option named like env_FOO. Not yet sure
which approach is better.

Closes mawww#4482
That issues asks for a separate client-specific env as well but we
don't have a client scope so I'm not sure.
@krobelus krobelus marked this pull request as ready for review January 14, 2024 17:13
krobelus added a commit to kakoune-lsp/kakoune-lsp that referenced this pull request Feb 10, 2024
To use, either patch Kakoune using
mawww/kakoune#5063 and set preferred servers
for each buffer like

	set-option -add buffer env KAK_LSP_LANGUAGE_SERVER=pylsp_main # or pylsp_test

Alternatively, use (untested)

	unset-option buffer lsp_cmd
	set-option buffer lsp_cmd "KAK_LSP_LANGUAGE_SERVER=pylsp_main %opt{lsp_cmd}"
@@ -146,6 +146,8 @@ Vector<String> generate_env(StringView cmdline, const Context& context, GetValue
static const Regex re(R"(\bkak_(quoted_)?(\w+)\b)");

Vector<String> env;
for (const auto& [key, value] : context.options()["env"].get<HashMap<String, String, MemoryDomain::Options>>())
env.push_back(format("{}={}", key, value));
Copy link
Contributor Author

@krobelus krobelus Feb 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an ergonomic abstraction but it's incomplete in that it does not allow to unset environment variables, and neither does it allow to erase the entire environment (though I don't think there is a use case for that).
A more flexible (but probably not better) approach would be to allow overriding KAKOUNE_POSIX_SHELL dynamically, then we can set it to env ... "$@"..

@pjungkamp
Copy link
Contributor

I'd like to integrate kakoune with direnv. Since direnv relies on changing environment variables, I'd need to be able to propagate the changed environment to a running kakoune session...

Is there anything happening around here?

@krobelus
Copy link
Contributor Author

krobelus commented Aug 3, 2024

Nothing wrong with using this patch (I do use it occasionally).

One alternative approach is to simply add setenv and unsetenv commands, which is more obvious than the above str-to-str-map. I believe that would suffice for the direnv use case. Probably this should change places where we do getenv("XDG_RUNTIME_DIR") to instead cache the value at startup, to prevent weird states.

The advantage of the str-to-str-map is that it's easy to undo an override but for the use cases I had so far, unsetenv works too.

I'd like to integrate kakoune with direnv.

This means that the :cd command might apply a new envrc.
Sounds fine. I guess usually Kakoune doesn't accumulate much state, in that case restarting should work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Ability to change session and client environment variables
2 participants