-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Generalised to multiple runtime directories with priorities #5411
Conversation
e9d08ea
to
e1deb31
Compare
Priority should be (highest to lowest):
The docs recommend setting This means that for grammar fetch & build we probably want to write into the first dir? Except on CI \cc @the-mikedavis |
helix-term/src/health.rs
Outdated
writeln!(stdout, "Number of Runtime directories: {}", rt_dirs.len())?; | ||
for (i, rt_dir) in rt_dirs.iter().enumerate() { | ||
writeln!(stdout, "Runtime directory {}: {}", i + 1, rt_dir.display())?; | ||
if let Ok(path) = std::fs::read_link(&rt_dir) { | ||
let msg = format!("Runtime directory is symlinked to {}", path.display()); | ||
writeln!(stdout, "{}", msg.yellow())?; | ||
} | ||
if !rt_dir.exists() { | ||
writeln!(stdout, "{}", "Runtime directory does not exist.".red())?; | ||
} | ||
if rt_dir.read_dir().ok().map(|it| it.count()) == Some(0) { | ||
writeln!(stdout, "{}", "Runtime directory is empty.".red())?; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd just output this similar to PATH
or GOPATH
: a bunch of directories separated by ;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In addition to the runtime paths, the original behaviour conditionally reports for each runtime directory:
- the destination if a runtime directory is symlinked
- a red warning if the runtime directory doesn't exist
- a red warning if the runtime directory is empty
I assume you still want this info displayed? How should we clearly display this using a ;
-separated list? For 2 and 3, we can just filter on the non-existent / empty directories and join them on ;
. Should we just do the same thing for 1, and leave it up to the user to work out which runtime directory is the symlink?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've change the implementation so that a ;
-separated list of runtime directories is presented. For the warnings / errors, changed them all to warnings (yellow) because now it might be more common for a runtime directory to be missing or empty and it not be a problem. I didn't join these paths on ;
in the warnings, instead I just report a warning per case.
One thing is that windows / linux use ;
/ :
for this separator in PATH
and GOPATH
. I'm not sure we want to go to the effort to make this OS aware, so I just went with your suggestion for the semicolon. This seems like it would cause the least confusion given windows using :
after drive letter in path C:\\
etc.
Let me know what you think.
In that case how about:
Compared to the original behaviour this is just swapping 2 and 3. I assume my 1 here is what the CI uses. In addition it seems like I think it is best if this kind of packaging behaviour remains. It would be a pain if on updating a packager started putting (and overriding) the grammars under |
Oh I agree, I forgot to list it above :) Just wanted to clarify the intended use of |
Should we also make use of XDG_RUNTIME_DIR? I'm personally not of fan of placing runtime files the .config folder. |
It's orthogonal to this PR. #2135 implements that but it should be rebased after this is merged |
768adf5
to
36b98c0
Compare
I've now moved In terms of fetch and build, the behaviour is now that a cargo build will always put grammars in the runtime directory within the helix repo being built. When a user calls None of this is hard-coded, it is just the way it works with the new priority ordering and how the implementation of fetch and build always grab the highest priority runtime directory. I've modified the build from source instructions in the book to reflect some of this but not in that much detail. Let me know if you would like to further tweak this. |
This is an implementation for helix-editor#3346. Previously, one of the following runtime directories were used: 1. `$HELIX_RUNTIME` 2. sibling directory to `$CARGO_MANIFEST_DIR` 3. subdirectory of user config directory 4. subdirectory of path to helix executable The first directory provided / found to exist in this order was used as a root for all runtime file searches (grammars, themes, queries). This change lowers the priority of `$HELIX_RUNTIME` so that the user config runtime has higher priority. More significantly, all of these directories are now searched for runtime files, enabling a user to override default or system-level runtime files. If the same file name appears in multiple runtime directories, the following priority is now used: 1. sibling directory to `$CARGO_MANIFEST_DIR` 2. subdirectory of user config directory 3. `$HELIX_RUNTIME` 4. subdirectory of path to helix executable One exception to this rule is that a user can have a `themes` directory directly in the user config directory that has higher piority to `themes` directories in runtime directories. That behaviour has been preserved. As part of implementing this feature `theme::Loader` was simplified and the cycle detection logic of the theme inheritance was improved to cover more cases and to be more explicit.
36b98c0
to
5a0a1db
Compare
Reduced comment some verbosity, the method signatures should speak for themselves. runtime_file -> get_runtime_file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great! Just some minor nits
book/src/install.md
Outdated
config directory (for example `~/.config/helix/runtime` on Linux/macOS). An alternative runtime directory can | ||
be used by setting the `HELIX_RUNTIME` environment variable. Both runtime directories can be used at the same | ||
time, with the files residing under the config runtime directory given priority. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this can be expanded a bit, ideally we would have bullet points here that exactly lists what directories are searched in what order (and where grammars are installed by the cli)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. I've also moved it down slightly in the document to try and make the flow make a bit more sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a conflict with master. I've now merged in latest master and resolved the conflict.
BTW, what is the preferred process to keep these PRs up to date / conflict free with master? Should we be periodically rebasing and force pushing to our PR branch, or doing a regular merge? I was doing the former to try and keep things cleaner but then I see archseer at some point decided to do a regular merge.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rebase is preferred but if it's a small PR that we'll squash then it'll result in a single commit anyway
helix-term/src/health.rs
Outdated
if let Ok(path) = std::fs::read_link(&rt_dir) { | ||
let msg = format!("Runtime directory is symlinked to: {}", path.display()); | ||
writeln!(stdout, "{}", msg.yellow())?; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: this should show what runtime directory is symlinked, this may not always be obvious when multiple runtime dirs are symlinked.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have added both paths to output.
helix-view/src/theme.rs
Outdated
let mut names = Vec::new(); | ||
for dir in &self.theme_dirs { | ||
names.extend(Self::read_names(dir)); | ||
} | ||
names |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need to use a set here or sort and deadup, otherwise we could endup with duplicate theme names
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method is actually no longer used anywhere . I'm not sure if this is due to change in master being merged or if I made the change. Anyway I've removed the method.
helix-view/src/theme.rs
Outdated
if path.exists() && !visited_paths.contains(&path) { | ||
visited_paths.insert(path.clone()); | ||
Some(path) | ||
} else { | ||
None | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should track whether there is a cycle here (simply set a bool to true if we return None
because visited_paths
already contains path
) so we can create a separate error message for that case. Having the same error message for both cases seems confusing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep I'm doing that now. This method now returns a Result which distinguishes between the two cases.
The health display of runtime symlinks now prints both ends of the link. Separate errors are given when theme file is not found and when the only theme file found would form an inheritence cycle.
&helix_loader::config_dir().join("themes"), | ||
)); | ||
let mut names = theme::Loader::read_names(&helix_loader::config_dir().join("themes")); | ||
for rt_dir in helix_loader::runtime_dirs() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the function I commented in earlier has been inlined here (maybe by the merge from master?). This function has the same issue where we might ensup with the same theme name multiple times. I think an (unstable) sort and deadup would be a good solution
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Look down a couple of lines to 289 and 290 and it looks like this being done already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah you are right, sorry about that 😅
Also gave markdown headings to subsections. Fixed a error with table indentation not building table that also appears present on master.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM now
Thanks! This was a much needed improvement 🎉 |
…itor#5411) * Generalised to multiple runtime directories with priorities This is an implementation for helix-editor#3346. Previously, one of the following runtime directories were used: 1. `$HELIX_RUNTIME` 2. sibling directory to `$CARGO_MANIFEST_DIR` 3. subdirectory of user config directory 4. subdirectory of path to helix executable The first directory provided / found to exist in this order was used as a root for all runtime file searches (grammars, themes, queries). This change lowers the priority of `$HELIX_RUNTIME` so that the user config runtime has higher priority. More significantly, all of these directories are now searched for runtime files, enabling a user to override default or system-level runtime files. If the same file name appears in multiple runtime directories, the following priority is now used: 1. sibling directory to `$CARGO_MANIFEST_DIR` 2. subdirectory of user config directory 3. `$HELIX_RUNTIME` 4. subdirectory of path to helix executable One exception to this rule is that a user can have a `themes` directory directly in the user config directory that has higher piority to `themes` directories in runtime directories. That behaviour has been preserved. As part of implementing this feature `theme::Loader` was simplified and the cycle detection logic of the theme inheritance was improved to cover more cases and to be more explicit. * Removed AsRef usage to avoid binary growth * Health displaying ;-separated runtime dirs * Changed HELIX_RUNTIME build from src instructions * Updated doc for more detail on runtime directories * Improved health symlink printing and theme cycle errors The health display of runtime symlinks now prints both ends of the link. Separate errors are given when theme file is not found and when the only theme file found would form an inheritence cycle. * Satisfied clippy on passing Path * Clarified highest priority runtime directory purpose * Further clarified multiple runtime details in book Also gave markdown headings to subsections. Fixed a error with table indentation not building table that also appears present on master. --------- Co-authored-by: Paul Scott <paul.scott@anu.edu.au> Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
|
||
1. `runtime/` sibling directory to `$CARGO_MANIFEST_DIR` directory (this is intended for | ||
developing and testing helix only). | ||
2. `runtime/` subdirectory of OS-dependent helix user config directory. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, shouldn't this be ~/.local/state/helix/runtime (XDG_STATE_HOME
)?
This is clearly not config, but state, and we don't want backup programs to back up compiled tree-sitter .so grammars…
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's #584
This PR kept it to ~/.config
for backwards compatibility
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#5636 🤷
…itor#5411) * Generalised to multiple runtime directories with priorities This is an implementation for helix-editor#3346. Previously, one of the following runtime directories were used: 1. `$HELIX_RUNTIME` 2. sibling directory to `$CARGO_MANIFEST_DIR` 3. subdirectory of user config directory 4. subdirectory of path to helix executable The first directory provided / found to exist in this order was used as a root for all runtime file searches (grammars, themes, queries). This change lowers the priority of `$HELIX_RUNTIME` so that the user config runtime has higher priority. More significantly, all of these directories are now searched for runtime files, enabling a user to override default or system-level runtime files. If the same file name appears in multiple runtime directories, the following priority is now used: 1. sibling directory to `$CARGO_MANIFEST_DIR` 2. subdirectory of user config directory 3. `$HELIX_RUNTIME` 4. subdirectory of path to helix executable One exception to this rule is that a user can have a `themes` directory directly in the user config directory that has higher piority to `themes` directories in runtime directories. That behaviour has been preserved. As part of implementing this feature `theme::Loader` was simplified and the cycle detection logic of the theme inheritance was improved to cover more cases and to be more explicit. * Removed AsRef usage to avoid binary growth * Health displaying ;-separated runtime dirs * Changed HELIX_RUNTIME build from src instructions * Updated doc for more detail on runtime directories * Improved health symlink printing and theme cycle errors The health display of runtime symlinks now prints both ends of the link. Separate errors are given when theme file is not found and when the only theme file found would form an inheritence cycle. * Satisfied clippy on passing Path * Clarified highest priority runtime directory purpose * Further clarified multiple runtime details in book Also gave markdown headings to subsections. Fixed a error with table indentation not building table that also appears present on master. --------- Co-authored-by: Paul Scott <paul.scott@anu.edu.au> Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
This is an implementation for #3346
See commit message for an overview.
Here are some thing to consider when reviewing.
Depending on how helix is packaged, it still might not be possible for some users to conveniently override runtime files. E.g. on AUR helix-git,
/usr/bin/hx
is a shell script that setsHELIX_RUNTIME
to/usr/lib/helix/runtime
before calling/usr/lib/helix/hx
. Setting this env var is not necessary because helix already automatically checks for a runtime directory in the same directory as the executable. Setting it prevents~/.config/helix/runtime
from getting priority from the default runtime installation.The docs suggest that the
HELIX_RUNTIME
is intended as an option to override a~/.config/helix/runtime
, which I agree could be useful and why I've initially kept this behaviour. However, if it looks like packager's and build-from-source installers want to use this env var for their default runtime install, then we might want to rethink the priority order as outlined in the commit message.For consistencies sake you might want to consider if
~/.config/helix/themes
should be deprecated since this commit makes it so that~/.config/helix/runtime/themes
can be used to the same effect. Before and after this commit the former always has the higher priority.It just remembered that I haven't touched the user doc / book. I'll have to have a look and see where the new behaviour can be easily explained.
Closes #3346