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

feat(layout): Support environment variables in cwd (#2288) #2291

Merged
merged 6 commits into from
Apr 28, 2023

Conversation

shahamran
Copy link
Contributor

Fixes #2288.

  • Add shellexpand as dependency. I hope it's fine, it only has dirs as a dependency.
  • Expand environment variable in kdl parser's parse_cwd().
    • On failure, fall back to previous behavior.

It's my first time creating a PR here. Tell me if I missed anything! 😃

* add `shellexpand` as dependency
* expand environment variable in kdl parser's `parse_cwd()`
@shahamran shahamran temporarily deployed to cachix March 15, 2023 15:45 — with GitHub Actions Inactive
Copy link
Member

@imsnif imsnif left a comment

Choose a reason for hiding this comment

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

Hey, I'm happy to see this! On the whole this looks good. I left one minor comment in the code, but there are some behaviours that I think we need to look more deeply into.

  1. shellexpand mentions that they can also handle tildes (~) at the beginning of paths. So that we can do something like ~/my/folder that will be expanded to /home/aram/my/folder. Could we also support those while we're here?
  2. We need to make sure this also works and does the right thing with cwd composition in its various permutations (also to be sure that we do the right thing after addressing point 1... maybe only invoke shellexpand for the whole string?)
  3. Be sure we support cwd for bare panes (eg. pane cwd="my/folder"), command panes (eg. pane command="ls" cwd="my/folder") and edit pans (eg. pane edit="my_file.rs" cwd="my/folder"). All of these should behave properly with env variables and tildes

Thanks again for this! Looking forward to seeing this merged soon.

zellij-utils/src/kdl/kdl_layout_parser.rs Outdated Show resolved Hide resolved
@shahamran
Copy link
Contributor Author

Hi. Thanks for the quick reply!
I actually thought about adding tilde expansion, but thought it's a big feature which will less likely be approved.
I'll add it (replace shellexpand::env() with full()) and more tests. My plan is to replace this explicit, fragile test with snapshot + manual observation. What do you think?

* Return a proper `ConfigError` on failures.
* Replace raw cwd parsing with `parse_cwd()`.
* Add tests that verify correct expansions.
@shahamran shahamran requested a review from imsnif March 16, 2023 16:57
@shahamran
Copy link
Contributor Author

Hi @imsnif,
Do you want me to make additional changes?

@shahamran shahamran temporarily deployed to cachix March 28, 2023 10:09 — with GitHub Actions Inactive
@imsnif
Copy link
Member

imsnif commented Mar 28, 2023

Hey @shahamran - sorry for taking so long to get to this!

Good progress! I did some manual tests and found that there are some places in which we're still not picking this up. I think this needs to work in the layouts wherever we have a path, otherwise it might be confusing. I didn't test everything, but just a few examples:

layout {
    pane cwd="~/code" // works!
    pane edit="~/backup/foo.txt" // does not work for me
    pane command="~/backup/executable" // does not work for me
    pane command="ls" { // works!
        cwd "~/backup"
    }
}

Would you like to take a look at these and maybe do another sweep of the layout file to find out if there might be other places we'll need to add this functionality to?

@shahamran
Copy link
Contributor Author

I see. In this case, I think the 2 most reasonable options are:

  1. Modify kdl_get_string_property_or_child_value_with_error to perform shellexpand internally.
  2. Have a general parse_path() method in KdlLayoutParser and use it when parsing cwd, edit, command (and risk missing places where it's also applicable).

Regarding 1, why is this a macro? couldn't it be a regular function that takes a &KdlNode and &str?
I searched for usages and didn't encounter anything that justifies a macro. What am I missing?

@imsnif
Copy link
Member

imsnif commented Mar 28, 2023

Regarding 1, why is this a macro? couldn't it be a regular function that takes a &KdlNode and &str? I searched for usages and didn't encounter anything that justifies a macro. What am I missing?

I dunno, it works :)

Do whatever you think is best, let me know when you'd like another review. I'll try to get to it ASAP but thank you for your patience!

@shahamran
Copy link
Contributor Author

Hi, sorry for the long delay.
I added handling and tests for the command and edit contexts.
I think the more robust solution will be to do it in the kdl-parser module, but I didn't manage to make a small change there, I ended up changing the entire file, which was too much IMO.
Hope this smaller commit catches all use cases.
Let me know what you think!

@shahamran shahamran temporarily deployed to cachix April 18, 2023 13:29 — with GitHub Actions Inactive
Copy link
Member

@imsnif imsnif left a comment

Choose a reason for hiding this comment

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

Hey, great work! Thanks for making all the changes. This looks to be in great shape - I left some minor comments in the code - I think once they are addressed we can merge. Looking forward to seeing this in main.

#[track_caller]
fn env_test_helper(layout_str: &str, env_vars: Vec<(&str, &str)>, expected_output: Vec<&str>) {
for (key, value) in &env_vars {
std::env::set_var(key, value);
Copy link
Member

Choose a reason for hiding this comment

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

I think this will set the environment variable globally for all the tests, no? I'm a little wary of such things. Ideally we can find a solution that does this locally only for one test, and if not maybe we can unset these after the assert?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

that's true, and this is why I used weird names for the vars I set (besides $HOME).

current version handles restoring the previous env after parsing.


#[test]
fn env_valid_global_cwd() {
env_test_helper(
Copy link
Member

Choose a reason for hiding this comment

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

This is great, but I personally find it a little hard to understand at a glance. Which I think is important when we're considering tests. How about we change it to something like (pseudocode, if you have a better idea then by all means!)

LayoutTesterWithEnvironment::new()
    .set_env_variables(/* ... */)
    .parse_layout(stringified_layout)
    .assert(/* .. */)
    .assert(/* .. */)

);
}
for s in expected_output {
assert!(layout.contains(s), "expected string `{s}` was not found");
Copy link
Member

Choose a reason for hiding this comment

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

What do you think about asserting the cwd in the parsed structures (iirc they are a TildPaneLayout in this case) directly instead of parsing and stringifying? I think it'll be more accurate and clear, but maybe it's too much work?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think the snapshot test I added handles this request indirectly 😃

@shahamran
Copy link
Contributor Author

Hi, thanks for the feedback :)

I agree the test helper thing was ugly and fragile. I merged the tests to a single snapshot test, and went over the generated file.

I also handled adding / removing env vars in a more correct way.

Let me know if this looks good to you, and feel free to request as many changes as needed!
I appreciate the feedback.

@shahamran shahamran temporarily deployed to cachix April 22, 2023 20:00 — with GitHub Actions Inactive
@shahamran shahamran temporarily deployed to cachix April 23, 2023 11:04 — with GitHub Actions Inactive
@shahamran shahamran requested a review from imsnif April 23, 2023 14:04
@shahamran
Copy link
Contributor Author

@imsnif ping :)

@imsnif
Copy link
Member

imsnif commented Apr 28, 2023

Hey @shahamran - thank you for your patience. It's not always easy for me to get to everything that needs attention in the project in a timely manner, so I appreciate your understanding.

Great work on the changes, I'm happy to go ahead and merge this. Thanks for your diligent work and perseverance!

@imsnif imsnif merged commit b640270 into zellij-org:main Apr 28, 2023
@shahamran
Copy link
Contributor Author

Thanks a lot @imsnif, for the guidance and feedback.

While working on this, I noticed a place that I think can be improved, and I'm not sure opening an issue is the right place for it, so I'm asking here:
Will you be open for a PR that refactors / changes the kdl parsing module from macro-based to function-based? I think it'll help with readability, allow code-completion in these functions and improve compile times.

@imsnif
Copy link
Member

imsnif commented May 2, 2023

Hey @shahamran - while I very much appreciate the offer, I think if we consider refactoring this area of the code it would be best to re-write it in the new KQL (I believe it is called) - the KDL query language.

But I'm afraid even that is not in my focus right now. This project is still pre 1.0, which means most of the changes that happen are on a larger scope (eg. adding a web client). There will be lots of time for refactoring and improving the developer experience once things stabilize a bit. More info about what we're focusing on here.

If you're interested in helping out in those areas, you can hop by discord and ask for specific guidance on issues in our development channel.

Thanks again for your contribution!

renovate bot added a commit to scottames/dots that referenced this pull request Jun 19, 2023
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [aquaproj/aqua-registry](https://github.com/aquaproj/aqua-registry)
| minor | `v4.19.0` -> `v4.20.0` |
| [zellij-org/zellij](https://github.com/zellij-org/zellij) | minor |
`v0.36.0` -> `v0.37.0` |

---

### Release Notes

<details>
<summary>aquaproj/aqua-registry</summary>

###
[`v4.20.0`](https://github.com/aquaproj/aqua-registry/releases/tag/v4.20.0)

[Compare
Source](https://github.com/aquaproj/aqua-registry/compare/v4.19.0...v4.20.0)


[Issues](https://github.com/aquaproj/aqua-registry/issues?q=is%3Aissue+milestone%3Av4.20.0)
| [Pull
Requests](https://github.com/aquaproj/aqua-registry/pulls?q=is%3Apr+milestone%3Av4.20.0)
| aquaproj/aqua-registry@v4.19.0...v4.20.0

#### 🎉 New Packages


[#&#8203;13132](https://github.com/aquaproj/aqua-registry/issues/13132)
[segmentio/golines](https://github.com/segmentio/golines): A golang
formatter that fixes long lines
[@&#8203;iwata](https://github.com/iwata)

#### Fixes


[#&#8203;13143](https://github.com/aquaproj/aqua-registry/issues/13143)
[terraform-linters/tflint](https://github.com/terraform-linters/tflint):
Support old versions

</details>

<details>
<summary>zellij-org/zellij</summary>

###
[`v0.37.0`](https://github.com/zellij-org/zellij/releases/tag/v0.37.0)

[Compare
Source](https://github.com/zellij-org/zellij/compare/v0.36.0...v0.37.0)

In this release we've done a lot of work on our WebAssembly / WASI
plugin system and are very excited to invite adventurous Rust developers
to come pioneer our plugin system with us. To read more, please see the
official [Plugin
Documentation](https://zellij.dev/documentation/plugins.html).

Please also drop by our Discord or Matrix and show us the plugins you're
working on!

#### Other Highlights

- Some basic themes are now included with the release, give it a try by
starting Zellij with `zellij options --theme catppuccin-mocha`
-   Layouts now support environment variables and tilde expansions
-   We can now provide a `--cwd` option when starting Zellij

#### All changes

- fix(plugin): respect hide session option on compact-bar by
[@&#8203;pedromfedricci](https://github.com/pedromfedricci) in
[zellij-org/zellij#2368
- feat: Add layout configuration to exclude panes from tab sync by
[@&#8203;on3iro](https://github.com/on3iro) in
[zellij-org/zellij#2314
- Fix 2205 - Support cwd by
[@&#8203;Kangaxx-0](https://github.com/Kangaxx-0) in
[zellij-org/zellij#2290
- feat(plugins): reload plugin at runtime by
[@&#8203;imsnif](https://github.com/imsnif) in
[zellij-org/zellij#2372
- Update architecture doc by
[@&#8203;Kangaxx-0](https://github.com/Kangaxx-0) in
[zellij-org/zellij#2371
- feat(themes): add nightfox themes by
[@&#8203;EdenEast](https://github.com/EdenEast) in
[zellij-org/zellij#2384
- feat: provide default themes by
[@&#8203;jaeheonji](https://github.com/jaeheonji) in
[zellij-org/zellij#2307
- feat(plugins): update and render plugins asynchronously by
[@&#8203;imsnif](https://github.com/imsnif) in
[zellij-org/zellij#2410
- feat(layout): Support environment variables in cwd
([#&#8203;2288](https://github.com/zellij-org/zellij/issues/2288)) by
[@&#8203;shahamran](https://github.com/shahamran) in
[zellij-org/zellij#2291
- Add file path context to all IO errors in ConfigError by
[@&#8203;Imberflur](https://github.com/Imberflur) in
[zellij-org/zellij#2412
- fix(e2e): fix flaky locked mode test by
[@&#8203;imsnif](https://github.com/imsnif) in
[zellij-org/zellij#2413
- Fix error loading non-existant themes directory and use default themes
as the base when merging by
[@&#8203;Imberflur](https://github.com/Imberflur) in
[zellij-org/zellij#2411
- improve build/ci times by
[@&#8203;tlinford](https://github.com/tlinford) in
[zellij-org/zellij#2396
- Do not unwrap() the sticky bit setting! by
[@&#8203;valpackett](https://github.com/valpackett) in
[zellij-org/zellij#2424
- Use rust 1.67 by [@&#8203;har7an](https://github.com/har7an) in
[zellij-org/zellij#2375
- Fix issue 2421 - Update config file output by
[@&#8203;Kangaxx-0](https://github.com/Kangaxx-0) in
[zellij-org/zellij#2443
- feat(plugins): Plugin workers and strider by
[@&#8203;imsnif](https://github.com/imsnif) in
[zellij-org/zellij#2449
- fix: cwd of newtab action by
[@&#8203;onichandame](https://github.com/onichandame) in
[zellij-org/zellij#2455
- feat(wasm-plugin-system): major overhaul and some goodies by
[@&#8203;imsnif](https://github.com/imsnif) in
[zellij-org/zellij#2510
- feat(plugins): extensive plugin api by
[@&#8203;imsnif](https://github.com/imsnif) in
[zellij-org/zellij#2516
- fix: runtime panic because of local cache by
[@&#8203;jaeheonji](https://github.com/jaeheonji) in
[zellij-org/zellij#2522
- fix(output): do not hide cursor on a render that does not include
visual assets by [@&#8203;imsnif](https://github.com/imsnif) in
[zellij-org/zellij#2528
- fix(screen): focus tab as well as pane when launching existing plugin
by [@&#8203;imsnif](https://github.com/imsnif) in
[zellij-org/zellij#2530
- fix(strider): clear search term on ESC by
[@&#8203;imsnif](https://github.com/imsnif) in
[zellij-org/zellij#2531
- fix(plugins): only listen to hd if a plugin is subscribed to hd events
by [@&#8203;imsnif](https://github.com/imsnif) in
[zellij-org/zellij#2529
- fix(logs): suppress debug logs when not debugging by
[@&#8203;imsnif](https://github.com/imsnif) in
[zellij-org/zellij#2532
- fix(plugins): allow loading relative urls by
[@&#8203;imsnif](https://github.com/imsnif) in
[zellij-org/zellij#2539
- feat(plugins): plugin pane state events by
[@&#8203;imsnif](https://github.com/imsnif) in
[zellij-org/zellij#2545
- performance(plugins): use a debounced fs watcher by
[@&#8203;imsnif](https://github.com/imsnif) in
[zellij-org/zellij#2546
- feat(plugins): more plugin api methods by
[@&#8203;imsnif](https://github.com/imsnif) in
[zellij-org/zellij#2550
- refactor(plugins): improve api by
[@&#8203;imsnif](https://github.com/imsnif) in
[zellij-org/zellij#2552
- feat(plugins): strider improvements by
[@&#8203;imsnif](https://github.com/imsnif) in
[zellij-org/zellij#2551
- docs(plugins): document the zellij-tile events and commands api by
[@&#8203;imsnif](https://github.com/imsnif) in
[zellij-org/zellij#2554
- docs(plugins): better zellij-tile-docs by
[@&#8203;imsnif](https://github.com/imsnif) in
[zellij-org/zellij#2560

#### New Contributors

- [@&#8203;on3iro](https://github.com/on3iro) made their first
contribution in
[zellij-org/zellij#2314
- [@&#8203;Kangaxx-0](https://github.com/Kangaxx-0) made their first
contribution in
[zellij-org/zellij#2290
- [@&#8203;EdenEast](https://github.com/EdenEast) made their first
contribution in
[zellij-org/zellij#2384
- [@&#8203;shahamran](https://github.com/shahamran) made their first
contribution in
[zellij-org/zellij#2291
- [@&#8203;Imberflur](https://github.com/Imberflur) made their first
contribution in
[zellij-org/zellij#2412
- [@&#8203;valpackett](https://github.com/valpackett) made their first
contribution in
[zellij-org/zellij#2424
- [@&#8203;onichandame](https://github.com/onichandame) made their
first contribution in
[zellij-org/zellij#2455

**Full Changelog**:
zellij-org/zellij@v0.36.0...v0.37.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config help](https://github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://app.renovatebot.com/dashboard#github/scottames/dots).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNS4xMjYuMCIsInVwZGF0ZWRJblZlciI6IjM1LjEyNi4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiJ9-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
@MurtadhaInit
Copy link

Thanks for the great work!

I just wanted to ask whether this was also supposed to fix the issue of env variables not accepted as values for options within the config file or not.

The reason I'm asking is that something like scrollback_editor doesn't accept a value of $EDITOR, or default_shell not accepting $SHELL (which actually contradicts the docs).

Sorry if that's unrelated or if this is not the right place to raise this.

@shahamran shahamran deleted the fix-2288-env-var-in-cwd branch June 20, 2023 06:36
@shahamran
Copy link
Contributor Author

Hi @MurtadhaInit. Can you open an issue, and I'll try to look into it?

Please include steps to reproduce the problem. Thanks!

@MurtadhaInit
Copy link

@shahamran Hi, I've opened an issue 2574
Let me know if there are any further details I can provide.

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.

Environment variables inside cwd
3 participants