jorgebucaran / fisher

A plugin manager for Fish

Home Page:https://git.io/fisher

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

First-class support for `$fisher_path`

jorgebucaran opened this issue · comments

We can customize the installation path using $fisher_path, but Fisher doesn't help you with the boilerplate code necessary to load it during startup. It would be great if Fisher did all this work when you're using a custom $fisher_path.

Something like this via $__fish_config/conf.d/fisher.fish would do it:

set --query fisher_path || exit

set fish_function_path $fish_function_path[1] $fisher_path/functions $fish_function_path[2..-1]
set fish_complete_path $fish_complete_path[1] $fisher_path/completions $fish_complete_path[2..-1]

for file in $fisher_path/conf.d/*.fish
    source $file
end

I was able to make this work with the following snippet. I couldn't use the return since the code isn't running in a function, and had to switch to using cat since the the redirection didn't work when there were multiple files in the conf.d directory.

if set --query fisher_path

    set fish_function_path $fish_function_path[1] $fisher_path/functions $fish_function_path[2..-1]
    set fish_complete_path $fish_complete_path[1] $fisher_path/completions $fish_complete_path[2..-1]

    set --local files $fisher_path/conf.d/*.fish && set --query files[1] && cat $files | source
end

I should've used exit and just a for loop instead, thanks! @vamega

commented

👋 I write a simple plugin to make $fisher_path work in one-line:

curl -sSL https://git.io/fisher_path.fish --create-dirs -o $__fish_config_dir/conf.d/fisher_path.fish

@jorgebucaran is there any plans on adding a "out of the box" support for $fisher_path?

It would be really nice to have this without the need of extra boilerplate code or third party plugins

Sorry, not at this time. I get that out-of-the-box support would be nice to have for some, but using a plugin like @kidonng's works just as well, allowing me to keep Fisher simple, which is also in the interest of all of us.

I see your point, but wouldn't it be counter-intuitive to have a variable that only instructs the plugin manager where to install the plugins, when you need to manually write extra configuration to actually be able to make use of those installed plugins?

Shouldn't it be part of fisher project scope?

You are right, which is why using $fisher_path was essentially a "hack" until we decided to document it.

I am not completely made up my mind about this yet, which is why the issue is still open.

commented

@henriquehbr Just want to say that while it is possible to use it as a Fisher plugin, the recommend way to use it is to put it in ~/. config/fish/conf.d or copy the snippet to your config.fish.

@kidonng What would be the possible pitfalls of using it as a fisher plugin?

At the moment, i'm using it in my config.fish and it's working fine, but i also considered the option of using it as a plugin for keeping config.fish clean

commented

You will still need some boilerplate code like source $fisher_path/conf.d/fisher_path.fish in order for it to work. Also I don't think it will be updated often (if it even needs update, that is), you can just put it in your ~/. config/fish/conf.d and relax.

Why do you need that boilerplate? @kidonng.

commented

I was replying to @henriquehbr's question that what's the downside of using it as a fisher plugin, where your still have to source the plugin in order for it to do its job.

Thanks for the advice @kidonng, i think i'll go with this solution, even though it requires an extra source, it also unclutters config.fish, which for me is pretty nice

I know you were. I'm just confused, why the extra boilerplate with the plugin?

Hey @jorgebucaran, according to this heads-up on the docs:

Fisher expands plugins into your Fish configuration directory by default, overwriting existing files. If you wish to change this behavior, set $fisher_path to your preferred location and put it in your function path

By default, if you run fisher update, your plugins are overwritten, but if you have $fisher_path set, this doesn't happen, and fisher update fails with the following message:

fisher: Cannot install "...": please remove or move conflicting files first:

Is that correct? if yes, is there some way to keep the custom $fisher_path and still "force" a update overwriting conflicting files with some kind of a --force flag? probably, this doesn't exists yet, would you consider such feature as a valid addition?

That message is also shown whenever you try to install a plugin that's already installed. Are you saying that setting $fisher_path may be causing fisher update to fail to update? Then that may be a bug. I expect fisher update to always update my plugins.

I have fisher pre-installed on my dotfiles repo (to avoid having to install it manually), but whenever i try to update my plugins, this message appears, and fisher is automatically removed from the fish_plugins file, i'm not sure if it's necessarily $fisher_path fault

Isn't it a good idea to overwrite installed plugins on update by default?

Isn't it a good idea to overwrite installed plugins on update by default?

That's exactly what Fisher does.

I'll need you to share your dotfiles with us. Maybe it's not a Fisher issue at all.

You have a few things like . instead of source, also I'm not sure if this command should be interactive or not. If it isn't, guard it behind status is-interactive.

I'd start commenting out stuff to see if I can narrow down the issue a bit. If you can't figure it out, I'd suggest creating a Docker image with a repro. Have a look at Fisher's ci.yml for tips.

Spotted the issue! since i migrated from zsh to fish, i've been having trouble dealing with the fish_variables file, from what i've observed, renaming fisher.fish plugin file (including the completions) to _fisher.fish and re-running fisher update got it working properly

Seems like deleting fish_variables undo a bunch of important changes, including the universal variable _fisher_plugins, which made fisher stop working when the variables file was regenerated

The reason for deleting fish_variables is because i wanted to make atomic commits to my dotfiles repo of only a specific set of changes, instead of everything at once

@jorgebucaran do you know a better way of dealing with this specific situation, or it's just something that i have to get used to?

Deal with what exactly? If you clobber Fisher's state you are going to break it.

The solution consists of adding a conf.d snippet to check if $fisher_path is set and doing something like #640 (comment). I'm not really eager to add a conf.d snippet at this time, but I'm still intrigued by the idea. I may revisit this in the future. For now, this (slightly modified) code from @kidonng does it:

! set --query fisher_path[1] || test "$fisher_path" = $__fish_config_dir && exit

set fish_complete_path $fish_complete_path[1] $fisher_path/completions $fish_complete_path[2..]
set fish_function_path $fish_function_path[1] $fisher_path/functions $fish_function_path[2..]

for file in $fisher_path/conf.d/*.fish
    source $file
end

I know this is closed, but I am struggling to understand how to properly export the $fisher_path variable.

In config.fish I have tried set -gx fisher_path ~/.config/fish/fisher and set -x fisher_path ~/.config/fish/fisher (just export, still unsure what the difference is).
But the only thing that seems to work is set -Ux fisher_path ~/.config/fish/fisher. How do I keep track of this env variable in git?

If you are looking to change the default path where Fisher installs plugins, you only need to set $fisher_path to your desired location in config.fish. No need to "export" anything. For the git part, commit config.fish to your dotfiles repo. You'll probably want to support configuration snippets as described above, but that's really up to you.

This is my config.fish:

# function fish_vi_cursor; end
fish_vi_key_bindings

function fish_user_key_bindings
  for mode in insert default visual
    bind -M $mode \cf forward-word
    bind -M $mode \ce forward-char
    bind -M $mode \co forward-char
  end
  # bind -M default \e\e 'thefuck-command-line'  # Bind EscEsc to thefuck
end

# set -x GOPATH (go env GOPATH)
set --global --export MSSQL_TEST_PASS CrowdCrowd2
set --global --export EDITOR nvim
set --global --export NNN_PLUG z:autojump
set --global --export PYENV_ROOT /Users/ms/.pyenv
set --global --export LS_COLORS gxfxbEaEBxxEhEhBaDaCaD
set --global --export XDG_CONFIG_HOME $HOME/.config
set --global --export ANDROID_SDK_ROOT /Users/ms/Library/Android/sdk
# set --global --export FZF_CTRL_T_COMMAND fd --type file --follow --hidden --exclude .git
# set --global --export FZF_DEFAULT_COMMAND fd --type file --follow --hidden --exclude .git

set --global --export JAVA_HOME /Users/ms/Library/Java/JavaVirtualMachines/corretto-16.0.2/Contents/Home

set --universal --export fisher_path ~/.config/fish/fisher

# Don't show no message when logging in
set --global fish_greeting

if not type -q fisher
  echo "`fisher` is not installed, install with `curl -sL https://git.io/fisher | source && fisher install jorgebucaran/fisher` or check https://github.com/jorgebucaran/fisher"
end

starship init fish | source

So I can do set fisher_path ~/.config/fish/fisher and that's it?
If I only do that I can't run fisher in any new terminals.

~/.config/fish/fisher is a directory, right? Forgot to mention that you need to add that location to Fish's $fish_function_path and $fish_complete_path as described here.

Yes, indeed ~/.config/fish/fisher is a dir 👍
However I have installed #640 (comment) @kidonng 's fisher_path.fish into ~/.config/fish/conf.d. But I still need to set $fisher_path as a universal var and export it.

@jorgebucaran are you using a custom $fisher_path in your setup, if so what does your config.fish look like?

You don't need to set $fisher_path to universal (you don't need to export it either), otherwise I would've mentioned that in the docs. The instructions provided in #640 (comment) should be enough. What isn't working?

...are you using a custom $fisher_path in your setup

Not currently using a custom $fisher_path.

If I change my config.fish from

set -Ux fisher_path ~/.config/fish/fisher

to

set fisher_path ~/.config/fish/fisher

I can no longer use fisher when opening a new terminal.

Did you also add fisher_path to fish_function_path? If you don't, you won't be able to use Fisher in a new terminal.

Did you also add fisher_path to fish_function_path? If you don't, you won't be able to use Fisher in a new terminal.

Indeed I did. At least I think that's what @kidonng's plugin does. #640 (comment)
And the plugin

My suggestion: uninstall all your plugins (you can reinstall them once we've resolved this). Also make sure you are not using Oh My Fish.

Follow the instructions in this issue to customize your $fisher_path and let me know if you get stuck. Something in your environment breaks Fisher and it isn't Fisher.

I feel like there is a step I am missing. This is what I did:

  1. Delete $__fish_config_dir/fisher
  2. Copy #640 (comment) into $__fish_config_dir/conf.d/fisher_path.fish
  3. Edit config.fish: put set fisher_path $__fish_config_dir/fisher close to the top of the file
  4. Install fisher as per instructions: curl -sL https://raw.githubusercontent.com/jorgebucaran/fisher/main/functions/fisher.fish | source && fisher install jorgebucaran/fisher
  5. See some error message about not finding fzf_configure_bindings (makes sense since the fisher plugin is not installed)
  6. Each time I open a new terminal and run fisher I get fish: Unknown command: fisher

Can you see what I am doing wrong? @jorgebucaran

Do you have to delete $__fish_config_dir/fisher? Isn't that where you want to point your fisher_path to?

Do you have to delete $__fish_config_dir/fisher? Isn't that where you want to point your fisher_path to?

I followed your steps of removing all plugins first. Deleting everything inside $__fish_config_dir/fisher/* is what I did. I made sure the folder existed before opening a new terminal.

Did you clear out or commented everything in your config.fish?

Did you clear out or commented everything in your config.fish?

Nope! That's a very good point... 😬 will try.

@martisj Because I happened to run into this issue and just read the documantation on fish configuration files, I suspect that the issue is the order of execution of configuration files in fish. Seems scripts in conf.d are executed before the main config.fish. This means that when your conf.d script runs fisher_path is unset, then you get to config.fish and set it. When you instead use set -U the variable persists, so the conf.d script sees the value set by the previous shell.