2019-12-01 16:00:47 -05:00
zmodule() {
2022-10-23 20:34:14 -04:00
local -r ztarget=${ZIM_CONFIG_FILE:-<%= home %>/.zimrc}
2023-09-16 14:16:19 -04:00
local -r zusage=$'Usage: <%= bold %>'${0}$'<%= normal %> <url> [<%= bold %>-n<%= normal %>|<%= bold %>--name<%= normal %> <module_name>] [<%= bold %>-r<%= normal %>|<%= bold %>--root<%= normal %> <path>] [options]
2019-12-01 16:00:47 -05:00
2023-09-16 14:16:19 -04:00
Add <%= bold %>zmodule<%= normal %> calls to your <%= bold %>'${ztarget}$'<%= normal %> file to define the modules to be initialized.
The initialization will be done in the same order it\'s defined.
2020-05-02 19:47:38 -04:00
2020-10-11 13:24:01 -04:00
<url> Module absolute path or repository URL. The following URL formats
2023-09-16 14:16:19 -04:00
are equivalent: <%= bold %>foo<%= normal %>, <%= bold %>zimfw/foo<%= normal %>, <%= bold %>https://github.com/zimfw/foo.git<%= normal %>.
2022-09-26 21:33:49 -04:00
If an absolute path is given, the module is considered externally
2024-02-16 20:41:29 -05:00
installed and won\'t be installed or updated by zimfw.
2023-09-16 14:16:19 -04:00
<%= bold %>-n<%= normal %>|<%= bold %>--name<%= normal %> <module_name> Set a custom module name. Default: the last component in <url>.
2022-10-06 20:52:57 -04:00
Slashes can be used inside the name to organize the module into
subdirectories. The module will be installed at
2023-09-16 14:16:19 -04:00
<%= bold %>'${ZIM_HOME}$'/<%= normal %><module_name>.
<%= bold %>-r<%= normal %>|<%= bold %>--root<%= normal %> <path> Relative path to the module root.
2020-05-02 19:47:38 -04:00
2022-09-26 21:33:49 -04:00
Per-module options:
2023-09-16 14:16:19 -04:00
<%= bold %>-b<%= normal %>|<%= bold %>--branch<%= normal %> <branch_name> Use specified branch when installing and updating the module.
2021-11-08 20:05:32 -05:00
Overrides the tag option. Default: the repository default branch.
2023-09-16 14:16:19 -04:00
<%= bold %>-t<%= normal %>|<%= bold %>--tag<%= normal %> <tag_name> Use specified tag when installing and updating the module. Over-
2021-11-08 20:05:32 -05:00
rides the branch option.
2024-02-16 20:41:29 -05:00
<%= bold %>-u<%= normal %>|<%= bold %>--use<%= normal %> <tool_name> Install and update the module using the defined tool. Default is
either defined by <%= bold %>zstyle \':zim:zmodule\' use \'<%= normal %><tool_name><%= bold %>\'<%= normal %>, or <%= bold %>git<%= normal %>
if none is provided. The tools available are:
<%= bold %>git<%= normal %> uses the git command. Local changes are preserved on updates.
<%= bold %>degit<%= normal %> uses curl or wget, and currently only works with GitHub
2021-11-08 20:05:32 -05:00
URLs. Modules install faster and take less disk space. Local
changes are lost on updates. Git submodules are not supported.
2024-02-16 20:41:29 -05:00
<%= bold %>mkdir<%= normal %> creates an empty directory. The <url> is only used to set
the module name. Use the <%= bold %>-c<%= normal %>|<%= bold %>--cmd<%= normal %> or <%= bold %>--on-pull<%= normal %> options to execute
the desired command to generate the module files.
2023-09-16 14:16:19 -04:00
<%= bold %>--no-submodules<%= normal %> Don\'t install or update git submodules.
<%= bold %>-z<%= normal %>|<%= bold %>--frozen<%= normal %> Don\'t install or update the module.
2022-09-26 21:33:49 -04:00
The per-module options above are carried over multiple zmodule calls for the same module.
Modules are uniquely identified by their name.
Per-module-root options:
2023-09-16 14:16:19 -04:00
<%= bold %>--if<%= normal %> <test> Will only initialize module root if specified test returns a zero
2022-12-18 15:58:30 -05:00
exit status. The test is evaluated at every new terminal startup.
2024-02-16 20:41:29 -05:00
<%= bold %>--if-command<%= normal %> <cmd_name> Will only initialize module root if specified external command is
2024-01-22 21:36:17 -05:00
available. This is evaluated at every new terminal startup.
2024-02-16 20:41:29 -05:00
Equivalent to <%= bold %>--if \'(( \${+commands[<%= normal %><cmd_name><%= bold %>]} ))\'<%= normal %>.
2023-09-16 14:16:19 -04:00
<%= bold %>--on-pull<%= normal %> <command> Execute command after installing or updating the module. The com-
2022-05-07 17:31:08 -04:00
mand is executed in the module root directory.
2023-09-16 14:16:19 -04:00
<%= bold %>-d<%= normal %>|<%= bold %>--disabled<%= normal %> Don\'t initialize the module root or uninstall the module.
2022-09-26 21:33:49 -04:00
The per-module-root options above are carried over multiple zmodule calls for the same mod-
ule root.
Per-call initialization options:
2023-09-16 14:16:19 -04:00
<%= bold %>-f<%= normal %>|<%= bold %>--fpath<%= normal %> <path> Will add specified path to fpath. The path is relative to the
module root directory. Default: <%= bold %>functions<%= normal %>, if the subdirectory
2022-09-26 21:33:49 -04:00
exists and is non-empty.
2023-09-16 14:16:19 -04:00
<%= bold %>-a<%= normal %>|<%= bold %>--autoload<%= normal %> <func_name> Will autoload specified function. Default: all valid names inside
the <%= bold %>functions<%= normal %> subdirectory, if any.
<%= bold %>-s<%= normal %>|<%= bold %>--source<%= normal %> <file_path> Will source specified file. The path is relative to the module
root directory. Default: <%= bold %>init.zsh<%= normal %>, if a non-empty <%= bold %>functions<%= normal %> sub-
2022-09-26 21:33:49 -04:00
directory exists, else the largest of the files matching the glob
2023-09-16 14:16:19 -04:00
<%= bold %>(init.zsh|<%= normal %><name><%= bold %>.(zsh|plugin.zsh|zsh-theme|sh))<%= normal %>, if any.
2022-10-06 20:52:57 -04:00
<name> in the glob is resolved to the last component of the mod-
ule name, or the last component of the path to the module root.
2023-09-16 14:16:19 -04:00
<%= bold %>-c<%= normal %>|<%= bold %>--cmd<%= normal %> <command> Will execute specified command. Occurrences of the <%= bold %>{}<%= normal %> placeholder
2022-09-26 21:33:49 -04:00
in the command are substituted by the module root directory path.
2023-09-16 14:16:19 -04:00
I.e., <%= bold %>-s \'foo.zsh\'<%= normal %> and <%= bold %>-c \'source {}/foo.zsh\'<%= normal %> are equivalent.
2021-09-26 20:47:44 -04:00
2022-09-26 21:33:49 -04:00
Setting any per-call initialization option above will disable the default values from the
other per-call initialization options, so only your provided values will be used. I.e. these
values are either all automatic, or all manual in each zmodule call. To use default values
2023-09-16 14:16:19 -04:00
and also provided values, use separate zmodule calls.'
2022-10-23 20:34:14 -04:00
if [[ ${${funcfiletrace[1]%:*}:A} != ${ztarget:A} ]]; then
2023-09-16 14:16:19 -04:00
print -u2 -lR $'<%= red %>'${0}$': Must be called from <%= bold %>'${ztarget}$'<%= normal %>' '' ${zusage}
2021-03-19 18:13:21 -04:00
return 2
2019-12-01 16:00:47 -05:00
fi
if (( ! # )); then
2023-09-16 14:16:19 -04:00
print -u2 -lR $'<%= red %><%= error %>'${funcfiletrace[1]}$': Missing zmodule url<%= normal %>' '' ${zusage}
2019-12-01 16:00:47 -05:00
_zfailed=1
2021-03-19 18:13:21 -04:00
return 2
2019-12-01 16:00:47 -05:00
fi
2022-09-26 21:33:49 -04:00
local zurl=${1} zname=${1:t} zroot zarg
2022-05-17 19:43:59 -04:00
local -a zfpaths zfunctions zcmds
2019-12-01 16:00:47 -05:00
if [[ ${zurl} =~ ^[^:/]+: ]]; then
2022-05-17 19:43:59 -04:00
zname=${zname%.git}
2019-12-01 16:00:47 -05:00
elif [[ ${zurl} != /* ]]; then
# Count number of slashes
case ${#zurl//[^\/]/} in
2021-09-23 15:29:40 -04:00
0) zurl=https://github.com/zimfw/${zurl}.git ;;
1) zurl=https://github.com/${zurl}.git ;;
2019-12-01 16:00:47 -05:00
esac
fi
shift
2022-09-26 21:33:49 -04:00
while [[ ${1} == (-n|--name|-r|--root) ]]; do
2019-12-01 16:00:47 -05:00
if (( # < 2 )); then
2023-09-16 14:16:19 -04:00
print -u2 -lR $'<%= red %><%= error %>'${funcfiletrace[1]}$':<%= bold %>'${zname}$':<%= normalred %> Missing argument for zmodule option <%= bold %>'${1}$'<%= normal %>' '' ${zusage}
2019-12-01 16:00:47 -05:00
_zfailed=1
2021-03-19 18:13:21 -04:00
return 2
2019-12-01 16:00:47 -05:00
fi
2022-09-26 21:33:49 -04:00
case ${1} in
-n|--name)
shift
zname=${${1%%/##}##/##}
;;
-r|--root)
shift
zroot=${${1%%/##}##/##}
;;
esac
2019-12-01 16:00:47 -05:00
shift
2022-05-17 19:43:59 -04:00
done
2020-06-05 23:09:23 -04:00
if [[ ${zurl} == /* ]]; then
2022-05-17 19:43:59 -04:00
_zdirs[${zname}]=${zurl%%/##}
2021-09-23 15:29:40 -04:00
zurl=
2020-06-05 23:09:23 -04:00
else
2022-05-17 19:43:59 -04:00
_zdirs[${zname}]=${ZIM_HOME}/modules/${zname}
fi
2022-09-26 21:33:49 -04:00
if [[ ${+_zurls[${zname}]} -ne 0 && ${_zurls[${zname}]} != ${zurl} ]]; then
2023-09-16 14:16:19 -04:00
print -u2 -lR $'<%= red %><%= error %>'${funcfiletrace[1]}$':<%= bold %>'${zname}$':<%= normalred %> Module already defined with a different URL. Expected <%= bold %>'${_zurls[${zname}]}$'<%= normal %>' '' ${zusage}
2022-09-26 21:33:49 -04:00
_zfailed=1
return 2
fi
2022-05-17 19:43:59 -04:00
_zurls[${zname}]=${zurl}
2022-09-26 21:33:49 -04:00
local -r zroot_dir=${_zdirs[${zname}]}${zroot:+/${zroot}}
_zroot_dirs+=(${zroot_dir})
2022-05-17 19:43:59 -04:00
# Set default values
if (( ! ${+_ztools[${zname}]} )); then
zstyle -s ':zim:zmodule' use "_ztools[${zname}]" || _ztools[${zname}]=git
2020-06-05 23:09:23 -04:00
fi
2022-05-17 19:43:59 -04:00
if (( ! ${+_ztypes[${zname}]} )) _ztypes[${zname}]=branch
if (( ! ${+_zsubmodules[${zname}]} )) _zsubmodules[${zname}]=1
# Set values from options
2019-12-01 16:00:47 -05:00
while (( # > 0 )); do
case ${1} in
2024-01-22 21:36:17 -05:00
-b|--branch|-t|--tag|-u|--use|--on-pull|--if|--if-command|-f|--fpath|-a|--autoload|-s|--source|-c|--cmd)
2019-12-01 16:00:47 -05:00
if (( # < 2 )); then
2023-09-16 14:16:19 -04:00
print -u2 -lR $'<%= red %><%= error %>'${funcfiletrace[1]}$':<%= bold %>'${zname}$':<%= normalred %> Missing argument for zmodule option <%= bold %>'${1}$'<%= normal %>' '' ${zusage}
2019-12-01 16:00:47 -05:00
_zfailed=1
2021-03-19 18:13:21 -04:00
return 2
2019-12-01 16:00:47 -05:00
fi
;;
esac
2021-09-19 14:37:13 -04:00
case ${1} in
2022-01-25 09:32:50 -05:00
-b|--branch|-t|--tag|-u|--use|--no-submodules)
2023-09-16 14:16:19 -04:00
if [[ -z ${zurl} ]] _zimfw_print -u2 -R $'<%= yellow %><%= warn %>'${funcfiletrace[1]}$':<%= bold %>'${zname}$':<%= normalyellow %> The zmodule option <%= bold %>'${1}$'<%= normalyellow %> has no effect for external modules<%= normal %>'
2021-09-19 14:37:13 -04:00
;;
esac
2019-12-01 16:00:47 -05:00
case ${1} in
-b|--branch)
shift
2022-05-17 19:43:59 -04:00
_ztypes[${zname}]=branch
_zrevs[${zname}]=${1}
2019-12-01 16:00:47 -05:00
;;
-t|--tag)
shift
2022-05-17 19:43:59 -04:00
_ztypes[${zname}]=tag
_zrevs[${zname}]=${1}
2019-12-01 16:00:47 -05:00
;;
2021-04-03 10:35:28 -04:00
-u|--use)
shift
2022-05-17 19:43:59 -04:00
_ztools[${zname}]=${1}
2021-04-03 10:35:28 -04:00
;;
2022-05-17 19:43:59 -04:00
--no-submodules) _zsubmodules[${zname}]=0 ;;
-z|--frozen) _zfrozens[${zname}]=1 ;;
2022-05-07 17:31:08 -04:00
--on-pull)
shift
2022-09-26 21:33:49 -04:00
zarg=${1}
if [[ -n ${zroot} ]] zarg="(builtin cd -q ${zroot}; ${zarg})"
_zonpulls[${zname}]="${_zonpulls[${zname}]+${_zonpulls[${zname}]}; }${zarg}"
2022-05-07 17:31:08 -04:00
;;
2022-10-06 20:52:57 -04:00
--if)
shift
_zifs[${zroot_dir}]=${1}
;;
2024-01-22 21:36:17 -05:00
--if-command)
shift
_zifs[${zroot_dir}]="(( \${+commands[${1}]} ))"
;;
2019-12-01 16:00:47 -05:00
-f|--fpath)
shift
zarg=${1}
2022-09-26 21:33:49 -04:00
if [[ ${zarg} != /* ]] zarg=${zroot_dir}/${zarg}
2019-12-01 16:00:47 -05:00
zfpaths+=(${zarg})
;;
-a|--autoload)
shift
zfunctions+=(${1})
;;
-s|--source)
shift
zarg=${1}
2022-09-26 21:33:49 -04:00
if [[ ${zarg} != /* ]] zarg=${zroot_dir}/${zarg}
2023-03-30 09:38:12 -04:00
zcmds+=("source ${(q-)zarg:a}")
2020-07-02 18:16:44 -04:00
;;
-c|--cmd)
shift
2023-03-30 09:38:12 -04:00
zcmds+=(${1//{}/${(q-)zroot_dir:a}})
2019-12-01 16:00:47 -05:00
;;
2022-09-26 21:33:49 -04:00
-d|--disabled) _zdisabled_root_dirs+=(${zroot_dir}) ;;
2019-12-01 16:00:47 -05:00
*)
2023-09-16 14:16:19 -04:00
print -u2 -lR $'<%= red %><%= error %>'${funcfiletrace[1]}$':<%= bold %>'${zname}$':<%= normalred %> Unknown zmodule option <%= bold %>'${1}$'<%= normal %>' '' ${zusage}
2019-12-01 16:00:47 -05:00
_zfailed=1
2021-03-19 18:13:21 -04:00
return 2
2019-12-01 16:00:47 -05:00
;;
esac
shift
done
2021-09-19 14:37:13 -04:00
if (( _zflags & 1 )); then
2022-05-17 19:43:59 -04:00
_znames+=(${zname})
2021-09-19 14:37:13 -04:00
fi
if (( _zflags & 2 )); then
2022-09-26 21:33:49 -04:00
if [[ ! -e ${zroot_dir} ]]; then
2023-09-16 14:16:19 -04:00
print -u2 -R $'<%= red %><%= error %>'${funcfiletrace[1]}$':<%= bold %>'${zname}': '${zroot_dir}$'<%= normalred %> not found<%= normal %>'
2022-09-26 21:33:49 -04:00
_zfailed=1
return 1
fi
if (( ! ${#zfpaths} && ! ${#zfunctions} && ! ${#zcmds} )); then
zfpaths=(${zroot_dir}/functions(NF))
# _* functions are autoloaded by compinit
# prompt_*_setup functions are autoloaded by promptinit
zfunctions=(${^zfpaths}/^(*~|*.zwc(|.old)|_*|prompt_*_setup)(N-.:t))
local -ra prezto_scripts=(${zroot_dir}/init.zsh(N))
if (( ${#zfpaths} && ${#prezto_scripts} )); then
# this follows the prezto module format, no need to check for other scripts
2023-03-30 09:38:12 -04:00
zcmds=('source '${(q-)^prezto_scripts:a})
2022-09-26 21:33:49 -04:00
else
# get script with largest size (descending `O`rder by `L`ength, and return only `[1]` first)
2022-10-06 20:52:57 -04:00
local -ra zscripts=(${zroot_dir}/(init.zsh|(${zname:t}|${zroot_dir:t}).(zsh|plugin.zsh|zsh-theme|sh))(NOL[1]))
2023-03-30 09:38:12 -04:00
zcmds=('source '${(q-)^zscripts:a})
2020-05-25 15:01:00 -04:00
fi
2019-12-01 16:00:47 -05:00
fi
2022-09-26 21:33:49 -04:00
if (( ! ${#zfpaths} && ! ${#zfunctions} && ! ${#zcmds} )); then
2023-09-16 14:16:19 -04:00
_zimfw_print -u2 -lR $'<%= yellow %><%= warn %>'${funcfiletrace[1]}$':<%= bold %>'${zname}$':<%= normalyellow %> Nothing found to be initialized. Customize the module name, root or initialization with <%= bold %>zmodule<%= normalyellow %> options.<%= normal %>' '' ${zusage}
2022-09-26 21:33:49 -04:00
fi
# Prefix is added to all _zfpaths, _zfunctions and _zcmds to distinguish the originating root dir
local -r zpre=${zroot_dir}$'\0'
_zfpaths+=(${zpre}${^zfpaths})
_zfunctions+=(${zpre}${^zfunctions})
_zcmds+=(${zpre}${^zcmds})
2019-12-01 16:00:47 -05:00
fi
}