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

[新功能] 支持 Fish Shell 运行环境 #3419

Closed
Dragon1573 opened this issue Feb 24, 2023 · 23 comments
Closed

[新功能] 支持 Fish Shell 运行环境 #3419

Dragon1573 opened this issue Feb 24, 2023 · 23 comments

Comments

@Dragon1573
Copy link

你在什么场景下需要该功能?

我目前在 Windows 11 的 WSL2 (Ubuntu) 上使用 XMake ,配置的 Shell 环境为 Fish 。当前 XMake 提供的 curlwget 安装方式均为 Bash ,安装后提供的 ~/.xmake/profile 文件也只能在 Bash 环境下进行 source 操作。以上 source 命令在 Fish Shell 环境下执行会提示脚本语法错误。

同时,当前最新版本的 XMake 发行版本为 v2.7.7 ,而 Ubuntu PPA 可用的最新发行版仅为 v2.7.4 ,安装后在 Fish Shell 中使用无相关命令补全,也没有对应的 Manual Page 供 fish_update_completions 命令解析以自动生成参数补全配置文件。

描述可能的解决方案

  1. 按照 Fish Shell 语法复刻一份 shget.text ,以支持 Fish Shell 用户可以 fish < (wget ...) 进行安装而不需要切换到 Bash 环境
  2. 按照 Fish Shell 语法仿制复刻一份 ~/.xmake/profile.fish ,以支持 Fish Shell 用户激活启用 XMake 环境而不必切换到 Bash
  3. 提供类似 xmake.tar.gz 文件置于系统默认的文档文件目录下,以支持 fish_update_completions 命令读取解析 XMake 文档并自动生成参数补全
  4. 提供生成 ~/.config/fish/completions/xmake.fish 参数补全配置文件的方法,以支持 Fish Shell 自动加载为 XMake 提供参数补全
  5. 尽快同步升级 PPA 软件源中的 XMake 版本

描述你认为的候选方案

(暂时未想到其他解决方案)

其他信息

  • Windows 宿主系统:Windows 11 Professional 22H2 (22621)
  • Linux 子系统:Ubuntu 22.10 Kinetic(已启用官方 systemd 模式,支持 snap 命令)
  • PPA 软件源:deb https://ppa.launchpadcontent.net/xmake-io/xmake/ubuntu/ kinetic main
  • Fish Shell 版本:v3.5.1
@waruqi
Copy link
Member

waruqi commented Feb 24, 2023

对 fish 不熟,你可以直接来个 pr

@waruqi
Copy link
Member

waruqi commented Feb 24, 2023

尽快同步升级 PPA 软件源中的 XMake 版本

ci 上的自动提交莫名失效了,等之后有空了 才能看下原因。建议直接走 xmake update 更新

或者走源码编译安装,文档里说明

@Dragon1573
Copy link
Author

对 Fish 不熟,可以直接来个 PR

我对于 Fish 也只是基础使用,没有太多编写 Fish Shell 脚本的经验。我在 ~/.config/fish/completions/ 目录下暂时只有关于 Poetry (官方提供了自动生成,但生成结果存在问题,还要手动修一下)和 BFG Repo Cleaner (自己写的,很简陋,内容如下折叠),对于 XMake 这种涉及子命令和下属参数分类的程序还没有写过相关的 Fish 脚本配置。

~/.config/fish/completions/bfg.fish
# BFG Repo Cleaner 补全列表

complete -c 'bfg' -d "BFG Repo Cleaner"

complete -c 'bfg' -x -s 'b' -l 'strip-blobs-bigger-than' -d "strip blobs bigger than X (eg '128K', '1M', etc)"
complete -c 'bfg' -x -s 'B' -l 'strip-biggest-blobs' -d 'strip the top NUM biggest blobs'
complete -c 'bfg' -x -o 'bi' -l 'strip-blobs-with-ids' -d 'strip blobs with the specified Git object ids'
complete -c 'bfg' -x -s 'D' -l 'delete-files' -d "delete files with the specified names (eg '*.class', '*.{txt,log}' - matches on file name, not path within repo)"
complete -c 'bfg' -x -l 'delete-folders' -d "delete folders with the specified names (eg '.svn', '*-tmp' - matches on folder name, not path within repo)"
complete -c 'bfg' -x -l 'convert-to-git-lfs' -d "extract files with the specified names (eg '*.zip' or '*.mp4') into Git LFS"
complete -c 'bfg' -x -o 'rt' -l 'replace-text' -d 'filter content of files, replacing matched text'
complete -c 'bfg' -x -o 'fi' -l 'filter-content-including' -d "do file-content filtering on files that match the specified expression (eg '*.{txt,properties}')"
complete -c 'bfg' -x -o 'fe' -l 'filter-content-excluding' -d "don't do file-content filtering on files that match the specified expression (eg '*.{xml,pdf}')"
complete -c 'bfg' -x -o 'fs' -l 'filter-content-size-threshold' -d "only do file-content filtering on files smaller than <size> (default is 1048576 bytes)"
complete -c 'bfg' -x -s 'p' -l 'protect-blobs-from' -d "protect blobs that appear in the most recent versions of the specified refs (default is 'HEAD')"
complete -c 'bfg' -x -l 'no-blob-protection' -d "allow the BFG to modify even your *latest* commit. Not recommended: you should have already ensured your latest commit is clean"
complete -c 'bfg' -x -l 'private' -d "treat this repo-rewrite as removing private data (for example: omit old commit ids from commit messages)"
complete -c 'bfg' -x -l 'massive-non-file-objects-sized-up-to' -d "increase memory usage to handle over-size Commits, Tags, and Trees that are up to X in size (eg '10M')"

可能需要也需要很长时间才能写出这个补全文件。

建议直接走 xmake update 更新,或者走源码编译安装。

此方法会从 Gitee 仓库 获取 v2.7.7 更新,并将更新安装至 ~/.local/bin/ 目录。

此升级过程对于使用 apt install 方法从 PPA 源或 GitHub Releases *.deb 软件包安装的 XMake 无效,其安装位置位于 /usr/local/bin/xmake/usr/local/bin/xrepo

当前已使用 v2.7.6*.deb 包完成升级。

@waruqi
Copy link
Member

waruqi commented Feb 24, 2023

此方法会从 Gitee 仓库 获取 v2.7.7 更新,并将更新安装至 ~/.local/bin/ 目录。

这是推荐的安装方式,可以支持后续的快速 xmake update 更新,以及指定 dev 分支的快速更新,且无权限问题。。

走 ppa 原本就不推荐,更新也不及时,功能也受限制 (不支持 tab 不全 和 xmake update)

@Dragon1573
Copy link
Author

如上 Pull Requests ,按照 --help 提供的文档手搓了一份 自用 的补全配置文件。

技术不佳,暂时没有能力去实现优雅的配置生成方式,估计只能求助于其他大佬了😭

可能相对优雅的方式:

  1. 模仿 Poetry 执行 xmake completion --fish > ~/.config/fish/completions/xmake.fish 完成配置文件生成
  2. 提供 Manual 文档文件(或归档包),由 fish_update_completions 自动解析生成

⚠️注意

自用 的含义是这个配置文件本意是给我个人使用的,尽管里面不包含个人限定设置,但我无法保证其他 Fish Shell 用户下载安装此配置文件后也能获得相同的补全体验。如果有更好的解决方案,也请直接贡献给 XMake ❤️

@Dragon1573
Copy link
Author

安装后在 Fish Shell 中使用无相关命令补全,也没有对应的 Manual Page 供 fish_update_completions 命令解析以自动生成参数补全配置文件。

@waruqi 我看到本项目在 scripts/man/ 目录下提供了 xmake.1xrepo.1 文件作为文档页。

使用 wget 将其下载到本地,用 gzip 压缩后存储到 /usr/share/man/ 相关目录下,执行 fish_update_completions 可以让 Fish Shell 在 ~/.local/share/fish/generated_completions/ 目录中生成如下内容:

xmake.fish
# xmake
# Autogenerated from man page /usr/share/man/man1/xmake.1.gz
complete -c xmake -s q -l quiet -d 'Quiet operation'
complete -c xmake -s y -l yes -d 'Input yes by default if need user confirm'
complete -c xmake -l confirm -d 'Input the given result if need user confirm.    - yes   - no   - def'
complete -c xmake -s v -l verbose -d 'Print lots of verbose information for users'
complete -c xmake -l root -d 'Allow to run xmake as root'
complete -c xmake -s D -l diagnosis -d 'Print lots of diagnosis information (backtrace, check info '
complete -c xmake -l version -d 'Print the version number and exit'
complete -c xmake -s h -l help -d 'Print this help message and exit'
complete -c xmake -s F -l file -d 'Read a given  xmake. lua file'
complete -c xmake -s P -l project -d 'Change to the given project directory.  Search priority:   1'
complete -c xmake -s b -l build -d 'Build target.  This is default building mode and optional'
complete -c xmake -s r -l rebuild -d 'Rebuild the target'
complete -c xmake -s a -l all -d 'Build all targets'
complete -c xmake -l dry-run -d 'Dry run to build target'
complete -c xmake -s j -l jobs -d 'Specifies the number of jobs to build simultaneously.  (default: 6)'
complete -c xmake -s w -l warning -d 'Enable the warnings output'
complete -c xmake -l files -d 'Build the given source files'
xrepo.fish
# xrepo
# Autogenerated from man page /usr/share/man/man1/xrepo.1.gz
complete -c xrepo -s q -l quiet -d 'Quiet operation'
complete -c xrepo -s y -l yes -d 'Input yes by default if need user confirm'
complete -c xrepo -l root -d 'Allow to run xrepo as root'
complete -c xrepo -s v -l verbose -d 'Print lots of verbose information for users'
complete -c xrepo -s D -l diagnosis -d 'Print lots of diagnosis information'
complete -c xrepo -l version -d 'Print the version number and exit'
complete -c xrepo -s h -l help -d 'Print this help message and exit.  AUTHOR xrepo is written by'

请问团队成员是否会考虑更新此文档,同时方便 fish_update_completions 生成自动补全嘛?

@waruqi
Copy link
Member

waruqi commented Feb 28, 2023

@waruqi 我看到本项目在 scripts/man/ 目录下提供了 xmake.1 和 xrepo.1 文件作为文档页。

这个也是之前人家贡献进来的,暂时没时间更新,你有兴趣的话,也可以来个 pr 过来。

@waruqi
Copy link
Member

waruqi commented Mar 1, 2023

另外,bash/zsh/ps 都是自动转发到 xmake 去动态执行补全,不需要预生成所有子命令。我想 fish 应该也可以,可以研究下

参考

completions="$(XMAKE_SKIP_HISTORY=1 XMAKE_ROOT=y xmake lua private.utils.complete "${COMP_POINT}" "nospace-nokey" "${COMP_LINE}")"

@Dragon1573
Copy link
Author

根据 register-completions.sh 文件展示的内容,看上去 XMake 以 Lua 脚本的形式提供了内置的补全功能。同时, Bash/Zsh/Powershell 均支持向相应的补全机制注册「钩子函数」,将相关的补全实现交由 XMake 自身处理。

但是在查看了 Fish Shell 的 complete 方法之后,并没有发现这么一个「补全钩子」的机制,所有的补全都是这样人为指定的,包括 pipxpoetry 全是以内置脚本的形式对外导出复杂的补全配置文件。

后续我可能会考虑把自己用的这个配置文件完善一下 PR 到这里,但愿它能够通用。

@waruqi
Copy link
Member

waruqi commented Mar 1, 2023

但是在查看了 Fish Shell 的 complete 方法之后,并没有发现这么一个「补全钩子」的机制,所有的补全都是这样人为指定的,包括 pipx 和 poetry 全是以内置脚本的形式对外导出复杂的补全配置文件。

如果是这种方式的话,很难适配 xmake 不同版本的升级迭代,每次更新版本,都得去重新生成去适配。。

而且很多内部参数值的列表补全,还有用户工程中的 targets 补全,这些都只能是动态完成的。。不太可能预生成,因为每个用户的工程配置都是不同的,随时可变。。。比如补全 xmake build xx 某个项目的 target name 等。

像此类的动态补全,还有很多地方都是,所以预生成的方式基本是完全没啥大的用处。。也不好维护。。不建议这么做。

@Dragon1573
Copy link
Author

那看来现阶段暂时是做不了它的 Fish Shell 补全配置文件了,至少我没找到什么很好的办法😞

此需求暂时搁置,希望后续有其他大佬能够以更优雅的方式实现❤️

@Dragon1573 Dragon1573 closed this as not planned Won't fix, can't repro, duplicate, stale Mar 1, 2023
@waruqi
Copy link
Member

waruqi commented Mar 1, 2023

我觉得这种应该是很平常的需求,其他shell 都支持,fish shell 不应该不行。。

而且我看 fish 里面也是通过 complete 命令来整的,跟 bash 类似,仅仅只是参数的差异。。

其实可以问问 chatgpt,将下面的 bash 方式转成 fish 方式:

  complete -o default -o nospace -F _xmake_bash_complete xmake

下面结果不一定对,但可以做个参考:

ChatGPT:

在 fish shell 中,使用 complete 命令来实现命令行补全功能。以下是将 complete -o default -o nospace -F _xmake_bash_complete xmake 转换为 fish shell 的代码:

complete -c xmake -n "__fish_use_subcommand" -f -a "(command xmake | _xmake_fish_complete)"
function _xmake_fish_complete
  set -l words (commandline -o)
  set -l completions (command xmake $words (commandline -cp) (commandline -ct))
  for completion in $completions
    echo $completion
  end
end
解释:

complete -c xmake:定义 xmake 命令的补全规则。
-n "__fish_use_subcommand":指定 fish shell 使用子命令补全。
-f:将补全的结果作为完整的单词输出。
-a "(command xmake | _xmake_fish_complete)":使用 _xmake_fish_complete 函数来获取补全的结果。
function _xmake_fish_complete:定义 _xmake_fish_complete 函数,用于获取补全的结果。
set -l words (commandline -o):获取当前命令行的单词。
set -l completions (command xmake $words (commandline -cp) (commandline -ct)):使用 command 命令执行 xmake 命令,并传入当前的命令行参数。
for completion in $completions:循环遍历补全结果。
echo $completion:输出每个补全结果。
这样就可以在 fish shell 中实现和原命令相同的命令行补全功能。

@Dragon1573
Copy link
Author

ChatGPT 生成的这一段 Fish Shell 代码片段好像存在问题,在触发补全的过程中会有大量报错。

目前参考了以上结果自己写了一个,效果和那些用 sample completions --shell fish > ~/.config/fish/completions/sample.fish 命令直接导出详尽 Fish Shell 补全配置的应用没法比,但基本的补全已经实现了。

@waruqi
Copy link
Member

waruqi commented Mar 2, 2023

ChatGPT 生成的这一段 Fish Shell 代码片段好像存在问题,在触发补全的过程中会有大量报错。

当然不可能直接用,仅供参考的。

@Dragon1573 Dragon1573 closed this as not planned Won't fix, can't repro, duplicate, stale Mar 2, 2023
@waruqi waruqi reopened this Mar 2, 2023
@waruqi
Copy link
Member

waruqi commented Mar 2, 2023

这里不用关,等我重构完,会支持上,先备着吧

@waruqi
Copy link
Member

waruqi commented Mar 2, 2023

我初步加上了 #3447

不过 get.sh/update 里面对 fish 的探测和 profile 注入还没做,fish下也还没测

@waruqi
Copy link
Member

waruqi commented Mar 3, 2023

怎么判断当前在 fish 下。。我看 $SHELL 显示的还是 bash 么

image

@waruqi
Copy link
Member

waruqi commented Mar 3, 2023

还有如果改成 curl -fsSL https://xmake.io/shget.text | bash 怎么传参指定安装特定分支和版本?

curl -fsSL https://xmake.io/shget.text | bash dev 好像不行

@waruqi
Copy link
Member

waruqi commented Mar 3, 2023

可以了,我重构了下,建议全量更新 dev 后测试,目前 get.sh 为了兼容现有老版本,因此只有 dev 分支编译,或者 local 本地编译安装,会启用新的注入逻辑

./configure
make -j4
./scripts/get.sh __local__ __install_only__

get.sh 会自动调用 xmake update --integrate 安装 profile 脚本,当然,你手动执行也行。。

它会先生成 ~/.xmake/profile ,这是一个固定路径,用于提供给用户,快速手动 source ~/.xmake/profile 更新环境。

内部已经兼容支持了 fish/bash/zsh

$ cat ~/.xmake/profile
export XMAKE_ROOTDIR="/Users/ruki/.local/bin"
export XMAKE_PROGRAM_DIR="/Users/ruki/.local/share/xmake"
export PATH="$XMAKE_ROOTDIR:$PATH"
test $FISH_VERSION && test -f "$XMAKE_PROGRAM_DIR/scripts/profile-unix.fish" && source "$XMAKE_PROGRAM_DIR/scripts/profile-unix.fish" && exit 0
test -f "$XMAKE_PROGRAM_DIR/scripts/profile-unix.sh" && source "$XMAKE_PROGRAM_DIR/scripts/profile-unix.sh"

同时,它还会注入到 ~/.bash_profile, ~/.profile 以及 fish 的全局 profile , ~/.config/fish/config.fish

# >>> xmake >>>
test -f "/Users/ruki/.xmake/profile" && source "/Users/ruki/.xmake/profile"
# <<< xmake <<<

所以,新开的 bash/fish 终端,也能自动生效,不需要再手动 source ~/.xmake/profile

相关 patch

#3447

@waruqi
Copy link
Member

waruqi commented Mar 3, 2023

@Dragon1573 @xq114 不过目前,windows 下 ps1 的 profile 还没重构,整合到 xmake update --integrate

以及 fish 的 xrepo env 环境还没在 profile 中提供,后续你们有时间的话,也可以帮忙提 pr 过来。

@waruqi waruqi added this to the v2.7.8 milestone Mar 3, 2023
@waruqi
Copy link
Member

waruqi commented Mar 3, 2023

这里应该差不多了,我先关了,如果有问题,可以再开或者直接 pr

@waruqi waruqi closed this as completed Mar 3, 2023
@Dragon1573
Copy link
Author

可以了,我重构了下,建议全量更新 dev 后测试,目前 get.sh 为了兼容现有老版本,因此只有 dev 分支编译,或者本地编译安装,会启用新的注入逻辑。

我使用 xmake update --uninstall 卸载现有的 Xmake 版本,随后使用 curl -fsSL https://xmake.io/shget.text | bash -s -- dev 在线安装 dev 分支版本,安装后 Xmake 本体功能正常。

get.sh 会自动调用 xmake update --integrate 安装 profile 脚本,当然,你手动执行也行。它会先生成 ~/.xmake/profile ,这是一个固定路径,用于提供给用户,快速手动 source ~/.xmake/profile 更新环境。内部已经兼容支持了 Fish/Bash/Zsh 。

确认此项生成功能正常,内容与你提供的片段相同。

同时,它还会注入到 ~/.bash_profile~/.profile 以及 Fish 的全局 Profile , ~/.config/fish/config.fish

经测:

  • 我本地没有创建 ~/.bash_profile ,未执行注入
  • ~/.profile 注入成功
  • ~/.config/fish/config.fish 注入失败

@waruqi
Copy link
Member

waruqi commented Mar 4, 2023

我本地没有创建 ~/.bash_profile ,未执行注入

目前只有,macos 下会注入这个,linux 下不会注入这个。。只要 ~/.profile 被注入了,.bash_profile 就没必要再去注入了。。

~/.config/fish/config.fish 注入失败

这个安装后,在 fish 下重新执行 xmake update --integrate 才会被注入。。

因为 $FISH_VERISON 这个只能在 shell 中判断识别 fish ,在首次安装 xmake update --integrate 子进程里是取不到 这个值的,因为它不是环境变量,所以首次安装是识别不到当前运行在 fish 下,只有下次下载,我强行设置了 XMAKE_SHELL=fish 才能识别到。。

除非有其他办法,fish 起的子进程里面能判断识别当前在 fish 下。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants