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

Add a plugin.zsh file to be ZSH-framework friendly #15

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

unixorn
Copy link

@unixorn unixorn commented Jun 4, 2023

*.plugin.zsh files will be automatically detected and loaded by ZSH frameworks.

Add one that adds the utilities folder to the user's $PATH.

@unixorn
Copy link
Author

unixorn commented Jun 5, 2023

Added sourcing the helper functions

@gnachman
Copy link
Owner

Sorry for the delay in getting back to you on this.

I am not a zsh user so I'll need instructions on how to test this, how users are expected to use it, and what dependencies it has (i.e., does this require oh-my-zsh or something else to work?). Also, is this meant to supplant the built-in mechanism of modifying .zshrc?

@unixorn
Copy link
Author

unixorn commented Jun 21, 2023

Basically, this is a supplement to manually modifying .zshrc.

If a user is using any of the ZSH frameworks (not just oh-my-zsh), having a plugin file makes it easy to have the framework handle loading the integration. Many of the frameworks will even handle automatically running git clone to initially load the tool, and will periodically run git pull to keep the user's environment up to date.

Basically if someone's using a framework, a plugin file will make it easier to use the integration, and if they aren't, it won't harm anything.

I didn't see install instructions in the top level README or I would have added framework usage instructions there.

@gnachman
Copy link
Owner

Sorry for the delay in getting back to you.

I really need detailed instructions on how to test this.

@unixorn
Copy link
Author

unixorn commented Aug 20, 2023

ZSH frameworks can load plugins that follow the ZSH plugin standard during startup - for example, if the end user uses zgenom, they'd add zgenom load gnachman/iTerm2-shell-integration to their .zshrc and zgenom would automatically clone the repo from github, and during session startup, look for a file named something.plugin.zsh (there are some other extensions in the standard too, but .plugin.zsh is what I used in the PR) and source it.

The plugin file I added adds the repo's utilities directory to the user's $PATH and sources the functions in shell_integration/zsh, it doesn't alter the integration, just makes it easier for framework users to load it automatically.

@nunico
Copy link

nunico commented Aug 24, 2023

@unixorn the plugin.zsh file-name doesn't exactly match with the repository name and therefore could cause issues with plugin-managers. The T in the repo-name is uppercase and e.g. zimfw (plugin manager) looks for a .plugin.zsh file containing exactly that name.

Don't know if only zimfw is case-sensitive or the container env (as it's Linux) was the culprit here.

@gnachman you can run it in a container to try it out. Here's a Dockerfile that you can use:

FROM zshusers/zsh:5.9
RUN useradd -ms /usr/bin/zsh zshuser
RUN install_packages curl ca-certificates git
RUN echo 'source "$HOME"/.zshrc' >> /etc/profile.d/zsh
USER zshuser
WORKDIR /home/zshuser
ENV HOME=/home/zshuser
ENV ZDOTDIR=/home/zshuser
ENV ZIM_HOME=/home/zshuser/zimfw
RUN curl -fsSL --create-dirs -o ${ZIM_HOME}/zimfw.zsh \
  https://github.com/zimfw/zimfw/releases/latest/download/zimfw.zsh

RUN echo '[[ ! ${ZIM_HOME}/init.zsh -nt ${ZDOTDIR:-${HOME}}/.zimrc ]] \ 
  && source ${ZIM_HOME}/zimfw.zsh init -q; \
  source ${ZIM_HOME}/init.zsh' >> .zshrc
RUN echo 'zmodule unixorn/iTerm2-shell-integration --branch add-plugin-file' >> .zimrc

ENTRYPOINT [ "/usr/bin/zsh", "-l" ]

Comment on lines 3 to 8
# Add utilities to our path
PLUGIN_BIN="$(dirname $0)/utilities"
export PATH=${PATH}:${PLUGIN_BIN}

# And source the helper functions, too.
source "${0:h}/shell_integration/zsh"
Copy link

Choose a reason for hiding this comment

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

Since you're using the base-dir expansion ${0:h} for sourcing, it'd be more consistent to use that as well when assigning PATH. Also could potentially be a tiny bit slower to call dirname as it's a sub-shell call. But I could be wrong here.

Here's my suggestion:

path+=("${0:h}/utilities")

You don't need to export, and this way you append to the tied array version of $PATH

Copy link

Choose a reason for hiding this comment

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

Just because I've too much time at hand, I wanted to check how many millis one could scrape off with the parameter expansion over the dirname call. Turns out quite a few, though negligable in it's direct effect:

$ hyperfine --runs 500 'echo $(dirname $PWD)' 'echo "${PWD:h}"'                                                                          

Benchmark 1: echo $(dirname $PWD)
  Time (mean ± σ):       5.3 ms ±   2.0 ms    [User: 0.5 ms, System: 1.9 ms]
  Range (min … max):     1.2 ms …  26.0 ms    500 runs

  Warning: Command took less than 5 ms to complete. Note that the results might be inaccurate because hyperfine can not calibrate the shell startup time much more precise than this limit. You can try to use the `-N`/`--shell=none` option to disable the shell completely.
  Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.

Benchmark 2: echo "${PWD:h}"
  Time (mean ± σ):       0.6 ms ±   0.9 ms    [User: 0.0 ms, System: 0.1 ms]
  Range (min … max):     0.0 ms …   6.5 ms    500 runs

  Warning: Command took less than 5 ms to complete. Note that the results might be inaccurate because hyperfine can not calibrate the shell startup time much more precise than this limit. You can try to use the `-N`/`--shell=none` option to disable the shell completely.
  Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.

Summary
  echo "${PWD:h}" ran
    8.98 ± 14.07 times faster than echo $(dirname $PWD)

Copy link
Author

Choose a reason for hiding this comment

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

Your way is better, @nunico, I've switched to using it.

Copy link
Author

Choose a reason for hiding this comment

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

and renamed the plugin file

@gnachman
Copy link
Owner

Sorry for taking so long to get to this. I'd like to merge it but I don't understand how it's supposed to be used.

Where does this file go when installed?
What steps should a user take to use it?

I'm not a zsh user so please assume I don't know anything about their plugin ecosystem.

@unixorn
Copy link
Author

unixorn commented Oct 19, 2023

Basically, most ZSH frameworks can be configured to clone a repository. If there's a file named something.plugin.zsh at the top level of the repository, the framework will source that file during startup.

The iTerm2-shell-integration.plugin.zsh file I've added adds the repo's utilities directory to the user's $PATH, and sources shell_integration/zsh so that the user can use the functions and script in their ZSH environment without having to alter their .zshrc.

The better frameworks will even periodically do a git pull on the plugin repositories they use to ensure that the user has the latest versions without having to do manual git operations.

@unixorn
Copy link
Author

unixorn commented Oct 19, 2023

Basically, adding this file makes it a lot more convenient for ZSH framework users to use the integration and to keep the version they're using current.

@gnachman
Copy link
Owner

What do I do to try it out?

@unixorn
Copy link
Author

unixorn commented Oct 29, 2023

If you source the file, it should update your $PATH to include the repository's shell_integration/zsh and utilities directories.

At the end of the day, what ZSH frameworks do is make it easy to clone repositories, keep their copy up to date, and source their .plugin.zsh files during startup.

@bestlem
Copy link

bestlem commented Mar 16, 2024

@unixorn I think what is needed here in the instructions is actual executable code that the user has to use to get the plugin working not just describing in English what to do.

@unixorn
Copy link
Author

unixorn commented Mar 19, 2024

Added an install section to README.md

plugin.zsh files will be automatically detected and loaded by ZSH frameworks.

Add one that adds the utilities folder to the user's `$PATH`.

Signed-off-by: Joe Block <jpb@unixorn.net>
Signed-off-by: Joe Block <jpb@unixorn.net>
@nunico mentioned a better way to massage `$PATH`, use it instead.

Rename iterm2-shell-integration.plugin.zsh -> iTerm2-shell-integration.plugin.zsh
per @nunico's comments about issues with zimfw and potentially other plugin managers.

Signed-off-by: Joe Block <jpb@unixorn.net>
Add a section to README.md that details installing it with the three
most commonly used ZSH frameworks.

Signed-off-by: Joe Block <jpb@unixorn.net>
@unixorn
Copy link
Author

unixorn commented Aug 8, 2024

Anything else I need to do to get this merged?

@gnachman
Copy link
Owner

gnachman commented Aug 8, 2024

@unixorn Can you explain to me (a non-zsh user) how to test this?

@unixorn
Copy link
Author

unixorn commented Aug 9, 2024

Testing

  1. Run a zsh shell
  2. clone the repo (ZSH frameworks like zgenom/antigen/etc will do this automatically when the repo is added to their configuration)
  3. source iterm2-shell-integration.plugin.zsh (ZSH frameworks will handle this automatically for the end user)
  4. Check $PATH - it should now have repocheckout/utilities added to it

That's pretty much it. The reason to have a iterm2-shell-integration.plugin.zsh file is convenience - people using frameworks can let their frameworks handle cloning the repository, adding it to their $PATH and more importantly, keeping their local copy up to date without them having to remember to run git pull periodically.

Keeping that functionality in the .plugin.zsh file gives framework users ease of use without affecting non-zsh users.

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.

4 participants