-
Notifications
You must be signed in to change notification settings - Fork 179
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 for caching generated Zsh code from external commands #528
Comments
Hi @00dani. This is something I've been considering for a while. Thank you for the investigation you've done above. I see another scenario too, besides (1) source the output and (2) set environment variable value to output, which is (3) generate completion from output. But maybe all these cases under (3) can be generalized using (1). For example, this is what we do to initialize the completion for kubectl: https://github.com/zimfw/k/blob/b3567c755a56a34d7de44575f45dcbeedac2ebbd/init.zsh#L1-L8 |
I've just released version 1.13.0 with two new zmodule options that make it easier to do what is being proposed here: the
The difference of this function with the zeval-if-installed above is that it does the checks during startup, not during the module update: check if the command is installed, check if the generated file is outdated in comparison to the command timestamp, and zcompile the generated file. This is for example what is generated in the init.zsh file from the example above:
|
I've tried adding this eval function to my .zshrc but I get the error: |
Hi @dannysteenman. The code above defining, using and undefining zmodule-eval should be in your .zimrc instead. |
Thanks for the quick reply @ericbn, I forgot to mention that I've done that as well. However the completion I want to add (in this case for the package orbstack) doesn't activate. contents of .zimrc:
I've also tried adding the eval commands after the completion modules but unfortunately it didnt help. normally when I type it seems the orb completion has been installed:
contents of ~/.zim/modules/custom-orb:
|
Thank you for your great work @ericbn! I installed Starship using the method described in their page
Got it! What was missing is that when I was running The |
Is your feature request related to a problem? Please describe.
There are many programs that expect to be integrated into your shell by writing something like
eval "$(theprogram init)"
into your shell initialisation script. The program generates some shell code on the fly to hook itself into the appropriate parts of your shell. Direnv, Starship, Zoxide, and Carapace all recommend this installation method, for example, as do various "version manager" tools like rbenv and Pyenv.There are also programs like vivid which expect to be called during shell initialisation and have their output saved to a parameter (
LS_COLORS
in this case), rather than directly evaluated as shell script. Expecting this seems to be less common - even similar tools likedircolors
produce executable code that setsLS_COLORS
rather than simply a value that needs to be saved toLS_COLORS
- but it does happen, and I personally use vivid so I noticed.However this code-generation approach can be a source of slowdown, because it needs to fork and exec the external program every time your shell starts. Additionally, the Zsh code generated by the external program cannot be
zcompile
d, since it is always produced on the fly. Since the actual generated code produced by these commands changes relatively rarely, it makes a lot of sense to prebuild it,zcompile
it, and source that file on startup instead. Zim doesn't have a built-in way to do this, and I think it would be nice if it did.Describe the solution you'd like
Inspired by a similar feature in the Znap tool, Zim could provide an additional command inside the zimrc called something like
zeval
, which would be invoked like this:When such a definition is "installed", Zim would run the provided command once, save the result to a new
init.zsh
file, andzcompile
that file. Then on each launch, Zim would simply source that sameinit.zsh
along with everything else.Scenarios like
vivid
, where the command output needs to be saved to a parameter rather than simply evaluated, could be supported using a flag like this:zeval vivid -p LS_COLORS 'vivid generate molokai'
When this is provided, rather than just writing the command's output directly to
init.zsh
, Zim could generate something likeexport LS_COLORS="output of command"
and write that toinit.zsh
instead.Zim could detect when the command in zimrc has been changed (say, from
vivid generate molokai
tovivid generate gruvbox-dark
) and rerun it to produce a new cached result in that case, but otherwise keep using the cached output. Additionally azimfw
subcommand for invalidating cached evals would be useful.Describe alternatives you've considered
I've already come up with a hacky way to implement this idea with Zim's existing features. It looks like this, in my zimrc:
While this does absolutely work, this setup has a number of shortcomings: it's needlessly cloning an empty Git repository for every command I add, there's no simple way to invalidate the cached script when necessary, and the syntax I need to use for "save to a parameter" commands like
vivid
is honestly pretty gross!I could fix that last issue myself by teaching my
zeval
function about the-p
flag I suggested above, but the other problems really need support in Zim itself to be fixed properly.Outside of my personal hack, I've found there are also plugins like evalcache and zsh-smartcache which implement this idea as a standalone utility. However these approaches have their own shortcomings: they don't support caching of a parameter assignment (so they don't work with
vivid
) , they run totally independently of your plugin manager sozimfw
naturally can't manage them, and they both unconditionally shell out tomd5
ormd5sum
to hash your command so you're still not actually avoiding a fork/exec by using them. Strangely, they also do not attempt tozcompile
the cached output. Not sure why.Additional context
No response
The text was updated successfully, but these errors were encountered: