Generate static init.zsh script \o/

to autoloads the functions and sources the scripts, instead of executing
zimfw during startup, and having it always figuring out what do to on
the fly.

This takes out the worry about zimfw interfering with the startup time,
and allows room to add more features to it. So, zstyle was replaced by a
custom zmodule function to define the modules, with the extra ability of
allowing users to set custom fpath paths, autoloaded functions and
sourced scripts per module.
This commit is contained in:
Eric Nielsen 2019-12-01 16:00:47 -05:00
parent 109279fc59
commit dfe35e1bfa
No known key found for this signature in database
GPG Key ID: 47D1DBFA0765A1FB
19 changed files with 626 additions and 480 deletions

View File

@ -3,7 +3,7 @@ Zsh IMproved FrameWork
<div align="center"> <div align="center">
<a href="https://github.com/zimfw/zimfw"> <a href="https://github.com/zimfw/zimfw">
<img width=650px src="https://i.eriner.me/zim_banner.png"> <img width=650px src="https://zimfw.github.io/images/zim_banner.png">
</a> </a>
</div> </div>
@ -53,50 +53,40 @@ read about the [available modules] and tweak your `.zshrc` file.
If you have a different shell framework installed (like oh-my-zsh or prezto), If you have a different shell framework installed (like oh-my-zsh or prezto),
*uninstall those first to prevent conflicts*. *uninstall those first to prevent conflicts*.
Settings Usage
-------- -----
### Enabled modules ### zmodule
Use the following zstyle to select the modules you would like enabled: Add `zmodule` calls to your `.zimrc` file to define the modules to be loaded.
The modules are loaded in the same order they are defined. Add:
zstyle ':zim' modules 'first-module' 'second-module' 'third-module' zmodule <url> [-n|--name <module_name>] [options]
You can provide as many module names as you want. Modules are sourced in the where &lt;url&gt; is the required repository URL or path. The following formats
order given. are equivalent: *name*, zimfw/*name*, https://<em></em>github.com/zimfw/<em>name</em>.git
By default, a module is installed from the Zim repository with the same name. By default, the module name is the last component in the &lt;url&gt;. Use the
For example, the `utility` module is installed from `-n`|`--name` &lt;module&lowbar;name&gt; option to set a custom module name.
https://<em></em>github.com/zimfw/utility.git if no additional module configuration is provided.
### Module customization #### Repository options
To configure a module, use the following format, where the style name is the * `-b`&vert;`--branch` &lt;branch&lowbar;name&gt;: Use specified branch when installing and updating the module. Overrides the tag option. Default: `master`
module name: * `-t`&vert;`--tag` &lt;tag&lowbar;name&gt;: Use specified tag when installing and updating the module. Overrides the branch option.
* `-z`&vert;`--frozen`: Don't install or update the module
zstyle ':zim:module' <module> ['frozen' yes] ['url' <url>] ['branch' <branch>|'tag' <tag>] #### Startup options
| Key | Description | Default value | * `-f`&vert;`--fpath` &lt;path&gt;: Add specified path to `fpath`. The path is relative to the module root directory. Default: `functions`, if the subdirectory exists
| --- | ----------- | ------------- | * `-a`&vert;`--autoload` &lt;function&lowbar;name&gt;: Autoload specified function. Default: all valid names inside all the module specified `fpath` paths
| frozen | If set to yes, then module will not be cleaned, installed or updated. It can still be freely enabled or disabled with the modules style. | no | * `-s`&vert;`--source` &lt;file&lowbar;path&gt;: Source specified file. The file path is relative to the module root directory. Default: the file with largest size matching `{init.zsh|module_name.{zsh|plugin.zsh|zsh-theme|sh}}`, if any exists
| url | Repository URL or path. The following formats are equivalent: *module*, zimfw/*module*, https://<em></em>github.com/zimfw/<em>module</em>.git | *module* | * `-d`&vert;`--disabled`: Don't use or clean the module
| branch | Repository branch. | master |
| tag | Repository tag. Overrides branch, if one was specified. | |
Choose the module name wisely. The first file found in the module root directory, ### zimfw
in the following order, will be sourced:
init.zsh, *module*.zsh, *module*.plugin.zsh, *module*.zsh.theme, *module*.sh
For example, [mafredi/zsh-async](https://github.com/mafredri/zsh-async) must be To install new defined modules, run:
configured as a module called `async`:
zstyle ':zim:module' async 'url' 'mafredri/zsh-async' zimfw install
because it has an async.zsh initialization file. Then to be enabled, `async` must
be added to the modules style.
Updating
--------
To update your modules, run: To update your modules, run:
@ -114,8 +104,8 @@ Uninstalling
The best way to remove Zim is to manually delete `~/.zim`, `~/.zimrc`, and The best way to remove Zim is to manually delete `~/.zim`, `~/.zimrc`, and
remove the initialization lines from your `~/.zshrc` and `~/.zlogin`. remove the initialization lines from your `~/.zshrc` and `~/.zlogin`.
[history-substring-search]: https://i.eriner.me/zim_history-substring-search.gif [history-substring-search]: https://zimfw.github.io/images/zim_history-substring-search.gif
[syntax-highlighting]: https://i.eriner.me/zim_syntax-highlighting.gif [syntax-highlighting]: https://zimfw.github.io/images/zim_syntax-highlighting.gif
[blazing speed]: https://github.com/zimfw/zimfw/wiki/Speed [blazing speed]: https://github.com/zimfw/zimfw/wiki/Speed
[available modules]: https://github.com/zimfw/zimfw/wiki/Modules [available modules]: https://github.com/zimfw/zimfw/wiki/Modules
[themes wiki page]: https://github.com/zimfw/zimfw/wiki/Themes [themes wiki page]: https://github.com/zimfw/zimfw/wiki/Themes

View File

@ -1,4 +1,4 @@
autoload -Uz is-at-least && if ! is-at-least <%= min_zsh_version %>; then autoload -Uz is-at-least && if ! is-at-least <%= min_zsh_version %>; then
print -u2 "init: error starting Zim: You're using Zsh version ${ZSH_VERSION} and versions < <%= min_zsh_version %> are not supported. Update your Zsh." print -u2 -R "${0}: Error starting Zim. You're using Zsh version ${ZSH_VERSION} and versions < <%= min_zsh_version %> are not supported. Update your Zsh."
return 1 return 1
fi fi

View File

@ -1,46 +1,2 @@
# Define Zim location # Define Zim location
: ${ZIM_HOME=${0:h}} : ${ZIM_HOME=${0:A:h}}
# Source user configuration
[[ -f <%= home %>/.zimrc ]] && source <%= home %>/.zimrc
# Set input mode before loading modules
if zstyle -t ':zim:input' mode 'vi'; then
bindkey -v
else
bindkey -e
fi
# Autoload enabled modules' functions
() {
local zfunction
local -a zmodules
zstyle -a ':zim' modules 'zmodules'
setopt LOCAL_OPTIONS EXTENDED_GLOB
fpath=(${ZIM_HOME}/modules/${^zmodules}/functions(/FN) ${fpath})
for zfunction in ${ZIM_HOME}/modules/${^zmodules}/functions/<%= functions_glob %>(-.N:t); do
autoload -Uz ${zfunction}
done
}
# Source enabled modules' init scripts
() {
local zmodule zdir zfile
local -a zmodules
zstyle -a ':zim' modules 'zmodules'
for zmodule in ${zmodules}; do
zdir=${ZIM_HOME}/modules/${zmodule}
if [[ ! -d ${zdir} ]]; then
print -u2 "init: module ${zmodule} not installed"
else
for zfile in ${zdir}/{init.zsh,${zmodule}.{zsh,plugin.zsh,zsh-theme,sh}}; do
if [[ -f ${zfile} ]]; then
source ${zfile}
break
fi
done
fi
done
}

View File

@ -1,13 +1,9 @@
_zimfw_compile() { _zimfw_compile() {
setopt LOCAL_OPTIONS EXTENDED_GLOB setopt LOCAL_OPTIONS EXTENDED_GLOB
autoload -U zrecompile autoload -U zrecompile
local zdumpfile zdir zfile
local zdir zfile
local -a zmodules
zstyle -a ':zim' modules 'zmodules'
# Compile the completion cache; significant speedup # Compile the completion cache; significant speedup
local zdumpfile
zstyle -s ':zim:completion' dumpfile 'zdumpfile' || zdumpfile="<%= home %>/.zcompdump" zstyle -s ':zim:completion' dumpfile 'zdumpfile' || zdumpfile="<%= home %>/.zcompdump"
if [[ -f ${zdumpfile} ]]; then if [[ -f ${zdumpfile} ]]; then
zrecompile -p ${1} ${zdumpfile} || return 1 zrecompile -p ${1} ${zdumpfile} || return 1
@ -16,19 +12,19 @@ _zimfw_compile() {
# Compile .zshrc # Compile .zshrc
zrecompile -p ${1} <%= home %>/.zshrc || return 1 zrecompile -p ${1} <%= home %>/.zshrc || return 1
# Compile enabled modules' autoloaded functions # Compile autoloaded functions
for zdir in ${ZIM_HOME}/modules/${^zmodules}/functions(/FN); do for zdir in ${fpath}; do
zrecompile -p ${1} ${zdir}.zwc ${zdir}/<%= functions_glob %>(-.N) || return 1 [[ ${zdir} == (.|..) || ${zdir} == (.|..)/* ]] && continue
if [[ -w ${zdir:h} ]]; then
zrecompile -p ${1} ${zdir}.zwc ${zdir}/^(*.*)(N-.) || return 1
fi
done done
# Compile enabled modules' scripts # Compile scripts
for zfile in ${ZIM_HOME}/modules/${^zmodules}/(^*test*/)#*.zsh{,-theme}(.NLk+1); do for zfile in ${ZIM_HOME}/(^*test*/)#*.zsh{,-theme}(N-.); do
zrecompile -p ${1} ${zfile} || return 1 zrecompile -p ${1} ${zfile} || return 1
done done
# Compile this script
zrecompile -p ${1} ${ZIM_HOME}/<%= script_filename %> || return 1
if [[ ${1} != -q ]]; then if [[ ${1} != -q ]]; then
print -P '%F{green}✓%f Done with compile.' print -P '%F{green}✓%f Done with compile.'
fi fi

View File

@ -1,9 +1,4 @@
zimfw() { if [[ ${1} == (compile|login-init) && ${2} == (|-q) ]]; then
case ${1} in _zimfw_compile ${2}
compile|login-init) _zimfw_compile ${2} ;; return
*) fi
source ${ZIM_HOME}/<%= script_filename %> <%= second_stage_guard %>
zimfw "${@}"
;;
esac
}

View File

@ -0,0 +1,26 @@
_zimfw_build() {
() {
local -r ztarget=${ZIM_HOME}/init.zsh
if command cmp -s ${ztarget} ${1}; then
if (( ! _zquiet )); then
print -PR "%F{green}✓%f %B${ztarget}:%b Already up to date"
fi
else
if [[ -e ${ztarget} ]]; then
command mv -f ${ztarget}{,.old} || return 1
fi
command mv -f ${1} ${ztarget} && \
if (( ! _zquiet )); then
print -PR "%F{green}✓%f %B${ztarget}:%b Updated. Restart your terminal for changes to take effect."
fi
fi
if (( ! _zquiet )); then
print -P '%F{green}✓%f Done with build.'
fi
} =(
print -R "zimfw() { source ${ZIM_HOME}/<%= script_filename %> \"\${@}\" }"
(( ${#_zfpaths} )) && print -R 'fpath=('${_zfpaths:P}' ${fpath})'
(( ${#_zfunctions} )) && print -R 'autoload -Uz '${_zfunctions}
print -Rn ${(F):-source ${^_zscripts:P}}
)
}

View File

@ -1,27 +0,0 @@
_zimfw_modules() {
local zmodule zurl ztype zrev
local -a zmodules
local -A zoptions
zstyle -a ':zim' modules 'zmodules'
for zmodule in ${zmodules}; do
zstyle -a ':zim:module' ${zmodule} 'zoptions'
[[ ${zoptions[frozen]} == yes ]] && continue
zurl=${zoptions[url]:-${zmodule}}
if [[ ${zurl} != /* && ${zurl} != *@*:* ]]; then
# Count number of slashes
case ${#zurl//[^\/]/} in
0) zurl="https://github.com/zimfw/${zurl}.git" ;;
1) zurl="https://github.com/${zurl}.git" ;;
esac
fi
if [[ -n ${zoptions[tag]} ]]; then
ztype=tag
zrev=${zoptions[tag]}
else
ztype=branch
zrev=${zoptions[branch]:-master}
fi
# Cannot have an empty space at the EOL because this is read by xargs -L1
print "'${ZIM_HOME}/modules/${zmodule}' '${zurl}' '${ztype}' '${zrev}'${1:+ ${1}}"
done
}

View File

@ -0,0 +1,119 @@
zmodule() {
local -r zusage="
Usage: %B${0}%b <url> [%B-n%b|%B--name%b <module_name>] [options]
Repository options:
%B-b%b|%B--branch%b <branch_name> Use specified branch when installing and updating the module
%B-t%b|%B--tag%b <tag_name> Use specified tag when installing and updating the module
%B-z%b|%B--frozen%b Don't install or update the module
Startup options:
%B-f%b|%B--fpath%b <path> Add specified path to fpath
%B-a%b|%B--autoload%b <function_name> Autoload specified function
%B-s%b|%B--source%b <file_path> Source specified file
%B-d%b|%B--disabled%b Don't use or clean the module
"
if [[ ${${funcfiletrace[1]%:*}:t} != .zimrc ]]; then
print -u2 -PR "%F{red}${0}: Must be called from <%= home %>/.zimrc%f"$'\n'${zusage}
return 1
fi
if (( ! # )); then
print -u2 -PR "%F{red}✗ ${funcfiletrace[1]}: Missing zmodule url%f"
_zfailed=1
return 1
fi
setopt LOCAL_OPTIONS EXTENDED_GLOB
local zmodule=${1:t} zurl=${1}
local ztype=branch zrev=master
local -i zdisabled=0 zfrozen=0
local -a zfpaths zfunctions zscripts
local zarg
if [[ ${zurl} =~ ^[^:/]+: ]]; then
zmodule=${zmodule%.git}
elif [[ ${zurl} != /* ]]; then
# Count number of slashes
case ${#zurl//[^\/]/} in
0) zurl="https://github.com/zimfw/${zurl}.git" ;;
1) zurl="https://github.com/${zurl}.git" ;;
esac
fi
shift
if [[ ${1} == (-n|--name) ]]; then
if (( # < 2 )); then
print -u2 -PR "%F{red}✗ ${funcfiletrace[1]}:%B${zmodule}:%b Missing argument for zmodule option ${1}%f"
_zfailed=1
return 1
fi
shift
zmodule=${1}
shift
fi
local -r zdir=${ZIM_HOME}/modules/${zmodule}
while (( # > 0 )); do
case ${1} in
-b|--branch|-t|--tag|-f|--fpath|-a|--autoload|-s|--source)
if (( # < 2 )); then
print -u2 -PR "%F{red}✗ ${funcfiletrace[1]}:%B${zmodule}:%b Missing argument for zmodule option ${1}%f"
_zfailed=1
return 1
fi
;;
esac
case ${1} in
-b|--branch)
shift
ztype=branch
zrev=${1}
;;
-t|--tag)
shift
ztype=tag
zrev=${1}
;;
-z|--frozen) zfrozen=1 ;;
-f|--fpath)
shift
zarg=${1}
[[ ${zarg} != /* ]] && zarg=${zdir}/${zarg}
zfpaths+=(${zarg})
;;
-a|--autoload)
shift
zfunctions+=(${1})
;;
-s|--source)
shift
zarg=${1}
[[ ${zarg} != /* ]] && zarg=${zdir}/${zarg}
zscripts+=(${zarg})
;;
-d|--disabled) zdisabled=1 ;;
*)
print -u2 -PR "%F{red}✗ ${funcfiletrace[1]}:%B${zmodule}:%b Unknown zmodule option ${1}%f"
_zfailed=1
return 1
;;
esac
shift
done
if (( zdisabled )); then
_zdisableds+=(${zmodule})
else
(( ! ${#zfpaths} )) && zfpaths+=(${zdir}/functions(NF))
if (( ! ${#zfunctions} )); then
# _* functions are autoloaded by compinit
# prompt_*_setup functions are autoloaded by promptinit
zfunctions+=(${^zfpaths}/^(*.*|_*|prompt_*_setup)(N-.:t))
fi
if (( ! ${#zscripts} )); then
zscripts+=(${zdir}/(init.zsh|${zmodule:t}.(zsh|plugin.zsh|zsh-theme|sh))(NOL[1]))
fi
_zfpaths+=(${zfpaths})
_zfunctions+=(${zfunctions})
_zscripts+=(${zscripts})
_zmodules+=(${zmodule})
fi
if (( ! zfrozen )); then
_zmodules_xargs+=${zmodule}$'\0'${zdir}$'\0'${zurl}$'\0'${ztype}$'\0'${zrev}$'\0'${_zquiet}$'\0'
fi
}

View File

@ -0,0 +1,7 @@
_zimfw_source_zimrc() {
local -i _zfailed=0
if ! source <%= home %>/.zimrc || (( _zfailed )); then
print -u2 -PR "%F{red}✗ Failed to source <%= home %>/.zimrc%f"
return 1
fi
}

View File

@ -1,21 +1,14 @@
_zimfw_clean_modules() { _zimfw_clean_modules() {
local zdir zmodule local zopt zdir zmodule
local -a zmodules (( ! _zquiet )) && zopt='-v'
local -A zoptions for zdir in ${ZIM_HOME}/modules/*(N/); do
# Source .zimrc to refresh zmodules
[[ -f <%= home %>/.zimrc ]] && source <%= home %>/.zimrc
zstyle -a ':zim' modules 'zmodules'
for zdir in ${ZIM_HOME}/modules/*(/N); do
zmodule=${zdir:t} zmodule=${zdir:t}
# If zmodules does not contain the zmodule # If _zmodules and _zdisableds do not contain the zmodule
if (( ! ${zmodules[(I)${zmodule}]} )); then if (( ! ${_zmodules[(I)${zmodule}]} && ! ${_zdisableds[(I)${zmodule}]} )); then
zstyle -a ':zim:module' ${zmodule} 'zoptions' command rm -rf ${zopt} ${zdir} || return 1
[[ ${zoptions[frozen]} == yes ]] && continue
command rm -rf ${zdir} || return 1
[[ ${1} != -q ]] && print ${zdir}
fi fi
done done
if [[ ${1} != -q ]]; then if (( ! _zquiet )); then
print -P "%F{green}✓%f Done with clean-modules." print -P '%F{green}✓%f Done with clean-modules.'
fi fi
} }

View File

@ -1,13 +1,18 @@
_zimfw_clean_compiled() { _zimfw_clean_compiled() {
setopt LOCAL_OPTIONS PIPE_FAIL local zopt_find zopt_rm zdir
local find_opt rm_opt if (( ! _zquiet )); then
if [[ ${1} != -q ]]; then zopt_find='-print'
find_opt='-print' zopt_rm='-v'
rm_opt='-v'
fi fi
command find ${ZIM_HOME} \( -name '*.zwc' -o -name '*.zwc.old' \) -delete ${find_opt} || return 1 for zdir in ${fpath}; do
command rm -f ${rm_opt} <%= home %>/.zshrc.zwc{,.old} || return 1 [[ ${zdir} == (.|..) || ${zdir} == (.|..)/* ]] && continue
if [[ ${1} != -q ]]; then if [[ -w ${zdir:h} ]]; then
print -P "%F{green}✓%f Done with clean-compiled. Run %Bzimfw compile%b to re-compile." command rm -f ${zopt_rm} ${zdir}.zwc{,.old} || return 1
fi
done
command find ${ZIM_HOME} \( -name '*.zwc' -o -name '*.zwc.old' \) -delete ${zopt_find} || return 1
command rm -f ${zopt_rm} <%= home %>/.zshrc.zwc{,.old} || return 1
if (( ! _zquiet )); then
print -P '%F{green}✓%f Done with clean-compiled. Run %Bzimfw compile%b to re-compile.'
fi fi
} }

View File

@ -1,10 +1,9 @@
_zimfw_clean_dumpfile() { _zimfw_clean_dumpfile() {
setopt LOCAL_OPTIONS PIPE_FAIL local zdumpfile zopt
local zdumpfile zout zopt
zstyle -s ':zim:completion' dumpfile 'zdumpfile' || zdumpfile="<%= home %>/.zcompdump" zstyle -s ':zim:completion' dumpfile 'zdumpfile' || zdumpfile="<%= home %>/.zcompdump"
[[ ${1} != -q ]] && zopt='-v' (( ! _zquiet )) && zopt='-v'
command rm -f ${zopt} ${zdumpfile}{,.zwc{,.old}} || return 1 command rm -f ${zopt} ${zdumpfile}{,.zwc{,.old}} || return 1
if [[ ${1} != -q ]]; then if (( ! _zquiet )); then
print -P "%F{green}✓%f Done with clean-dumpfile. Restart your terminal to dump an updated configuration." print -P '%F{green}✓%f Done with clean-dumpfile. Restart your terminal to dump an updated configuration.'
fi fi
} }

View File

@ -1,5 +1,5 @@
_zimfw_info() { _zimfw_info() {
print 'Zim version: <%= version %> (previous commit is <%= `git rev-parse --short HEAD | tr -d '\r\n'` %>)' print 'Zim version: <%= version %> (previous commit is <%= `git rev-parse --short HEAD | tr -d '\r\n'` %>)'
print "Zsh version: ${ZSH_VERSION}" print -R "Zsh version: ${ZSH_VERSION}"
print "System info: $(command uname -a)" print -R "System info: $(command uname -a)"
} }

View File

@ -1,20 +1,26 @@
_zimfw_upgrade() { _zimfw_upgrade() {
local zscript=${ZIM_HOME}/<%= script_filename %> local -r zscript=${ZIM_HOME}/<%= script_filename %>
local zurl=https://raw.githubusercontent.com/zimfw/zimfw/develop/<%= script_filename %> local -r zurl=https://raw.githubusercontent.com/zimfw/zimfw/develop/<%= script_filename %>
if (( ${+commands[wget]} )); then {
command wget -nv ${1} -O ${zscript}.new ${zurl} || return 1 if (( ${+commands[wget]} )); then
else command wget -nv ${1} -O ${zscript}.new ${zurl} || return 1
command curl -fsSL -o ${zscript}.new ${zurl} || return 1 else
fi command curl -fsSL -o ${zscript}.new ${zurl} || return 1
if command cmp -s ${zscript}{,.new}; then fi
command rm ${zscript}.new && \ if command cmp -s ${zscript}{,.new}; then
if [[ ${1} != -q ]]; then if (( ! _zquiet )); then
print -P "%F{green}✓%f <%= script_filename %>: Already up to date." print -P '%F{green}✓%f %B<%= script_filename %>:%b Already up to date'
fi fi
else else
command mv ${zscript}{,.old} && command mv ${zscript}{.new,} && \ command mv -f ${zscript}{,.old} && command mv -f ${zscript}{.new,} && \
if [[ ${1} != -q ]]; then if (( ! _zquiet )); then
print -P "%F{green}✓%f <%= script_filename %>: upgraded. Restart your terminal for changes to take effect." print -P '%F{green}✓%f %B<%= script_filename %>:%b Upgraded. Restart your terminal for changes to take effect.'
fi fi
fi fi
if (( ! _zquiet )); then
print -P '%F{green}✓%f Done with upgrade.'
fi
} always {
command rm -f ${zscript}.new
}
} }

View File

@ -1,25 +1,38 @@
unfunction zimfw
zimfw() { zimfw() {
local zusage="usage: ${0} <action> [-q] local -r zusage="
actions: Usage: %B${0}%b <action> [%B-q%b]
clean Clean all (see below).
clean-modules Clean unused modules.
clean-compiled Clean Zsh compiled files.
clean-dumpfile Clean completion dump file.
compile Compile Zsh files.
info Print Zim and system info.
install Install new modules.
update Update current modules.
upgrade Upgrade Zim.
options:
-q Quiet, only outputs errors."
if [[ ${#} -ne 1 && ${2} != -q ]]; then Actions:
print -u2 ${zusage} %Bbuild%b Build init script
return 1 %Bclean%b Clean all (see below)
%Bclean-modules%b Clean unused modules
%Bclean-compiled%b Clean Zsh compiled files
%Bclean-dumpfile%b Clean completion dump file
%Bcompile%b Compile Zsh files
%Binfo%b Print Zim and system info
%Binstall%b Install new modules
%Bupdate%b Update current modules
%Bupgrade%b Upgrade Zim
Options:
%B-q%b Quiet, only outputs errors
"
local ztool _zmodules_xargs
local -a _zdisableds _zmodules _zfpaths _zfunctions _zscripts
local -i _zquiet=0
if (( # > 2 )); then
print -u2 -PR "%F{red}${0}: Too many options%f"$'\n'${zusage}
return 1
elif (( # > 1 )); then
case ${2} in
-q) _zquiet=1 ;;
*)
print -u2 -PR "%F{red}${0}: Unknown option ${2}%f"$'\n'${zusage}
return 1
;;
esac
fi fi
local ztool
case ${1} in case ${1} in
install) install)
ztool="<%= render_escaped("src/tools/install.zsh.erb") %>" ztool="<%= render_escaped("src/tools/install.zsh.erb") %>"
@ -30,27 +43,29 @@ options:
esac esac
case ${1} in case ${1} in
build) _zimfw_source_zimrc && _zimfw_build && _zimfw_compile ${2} ;;
clean) clean)
_zimfw_clean_modules ${2} && \ _zimfw_source_zimrc && \
_zimfw_clean_compiled ${2} && \ _zimfw_clean_modules && \
_zimfw_clean_dumpfile ${2} _zimfw_clean_compiled && \
_zimfw_clean_dumpfile
;; ;;
clean-modules) _zimfw_clean_modules ${2} ;; clean-modules) _zimfw_source_zimrc && _zimfw_clean_modules ;;
clean-compiled) _zimfw_clean_compiled ${2} ;; clean-compiled) _zimfw_clean_compiled ;;
clean-dumpfile) _zimfw_clean_dumpfile ${2} ;; clean-dumpfile) _zimfw_clean_dumpfile ;;
compile|login-init) _zimfw_compile ${2} ;; compile|login-init) _zimfw_source_zimrc && _zimfw_compile ${2} ;;
info) _zimfw_info ${2} ;; info) _zimfw_info ;;
install|update) install|update)
# Source .zimrc to refresh zmodules _zimfw_source_zimrc || return 1
[[ -f <%= home %>/.zimrc ]] && source <%= home %>/.zimrc print -Rn ${_zmodules_xargs} | xargs -0 -n6 -P10 zsh -c ${ztool} ${1} && \
_zimfw_modules ${2} | xargs -L1 -P10 zsh -c ${ztool} ${1} && \ if (( ! _zquiet )); then
if [[ ${2} != -q ]]; then print -PR "%F{green}✓%f Done with ${1}. Restart your terminal for any changes to take effect."
print -P "%F{green}✓%f Done with ${1}. Restart your terminal for any changes to take effect." fi && \
fi _zimfw_build && _zimfw_compile ${2}
;; ;;
upgrade) _zimfw_upgrade ${2} ;; upgrade) _zimfw_upgrade ;;
*) *)
print -u2 ${zusage} print -u2 -PR "%F{red}${0}: Unknown action ${1}%f"$'\n'${zusage}
return 1 return 1
;; ;;
esac esac

View File

@ -1,20 +1,20 @@
# This runs in a new shell # This runs in a new shell
DIR=${1} readonly MODULE=${1}
URL=${2} readonly DIR=${2}
REV=${4} readonly URL=${3}
OPT=${5} readonly REV=${5}
MODULE=${DIR:t} readonly -i QUIET=${6}
CLEAR_LINE="\033[2K\r" readonly CLEAR_LINE=$'\E[2K\r'
if [[ -e ${DIR} ]]; then if [[ -e ${DIR} ]]; then
# Already exists # Already exists
return 0 return 0
fi fi
[[ ${OPT} != -q ]] && print -n "${CLEAR_LINE}Installing ${MODULE} …" (( ! QUIET )) && print -Rn ${CLEAR_LINE}"Installing ${MODULE} …"
if ERR=$(command git clone -b ${REV} -q --recursive ${URL} ${DIR} 2>&1); then if ERR=$(command git clone -b ${REV} -q --recursive ${URL} ${DIR} 2>&1); then
if [[ ${OPT} != -q ]]; then if (( ! QUIET )); then
print -P "${CLEAR_LINE}%F{green}✓%f ${MODULE}: Installed" print -PR ${CLEAR_LINE}"%F{green}✓%f %B${MODULE}:%b Installed"
fi fi
else else
print -P "${CLEAR_LINE}%F{red}✗ ${MODULE}: Error%f\n${ERR}" print -u2 -PR ${CLEAR_LINE}"%F{red}✗ %B${MODULE}:%b Error during git clone%f"$'\n'${(F):- ${(f)^ERR}}
return 1 return 1
fi fi

View File

@ -1,14 +1,14 @@
# This runs in a new shell # This runs in a new shell
DIR=${1} readonly MODULE=${1}
URL=${2} readonly DIR=${2}
TYPE=${3} readonly URL=${3}
REV=${4} readonly TYPE=${4}
OPT=${5} readonly REV=${5}
MODULE=${DIR:t} readonly -i QUIET=${6}
CLEAR_LINE="\033[2K\r" readonly CLEAR_LINE=$'\E[2K\r'
[[ ${OPT} != -q ]] && print -n "${CLEAR_LINE}Updating ${MODULE} …" (( ! QUIET )) && print -Rn ${CLEAR_LINE}"Updating ${MODULE} …"
if ! cd ${DIR} 2>/dev/null; then if ! builtin cd ${DIR} 2>/dev/null; then
print -P "${CLEAR_LINE}%F{red}✗ ${MODULE}: Not installed%f" print -u2 -PR ${CLEAR_LINE}"%F{red}✗ %B${MODULE}:%b Not installed%f"
return 1 return 1
fi fi
if [[ ${PWD} != $(command git rev-parse --show-toplevel 2>/dev/null) ]]; then if [[ ${PWD} != $(command git rev-parse --show-toplevel 2>/dev/null) ]]; then
@ -16,32 +16,32 @@ if [[ ${PWD} != $(command git rev-parse --show-toplevel 2>/dev/null) ]]; then
return 0 return 0
fi fi
if [[ ${URL} != $(command git config --get remote.origin.url) ]]; then if [[ ${URL} != $(command git config --get remote.origin.url) ]]; then
print -P "${CLEAR_LINE}%F{red}✗ ${MODULE}: URL does not match. Expected ${URL}. Will not try to update.%f" print -u2 -PR ${CLEAR_LINE}"%F{red}✗ %B${MODULE}:%b URL does not match. Expected ${URL}. Will not try to update.%f"
return 1 return 1
fi fi
if [[ ${TYPE} == tag ]]; then if [[ ${TYPE} == tag ]]; then
if [[ ${REV} == $(command git describe --tags --exact-match 2>/dev/null) ]]; then if [[ ${REV} == $(command git describe --tags --exact-match 2>/dev/null) ]]; then
[[ ${OPT} != -q ]] && print -P "${CLEAR_LINE}%F{green}✓%f ${MODULE}: Already up to date" (( ! QUIET )) && print -PR ${CLEAR_LINE}"%F{green}✓%f %B${MODULE}:%b Already up to date"
return 0 return 0
fi fi
fi fi
if ! ERR=$(command git fetch -pq origin ${REV} 2>&1); then if ! ERR=$(command git fetch -pq origin ${REV} 2>&1); then
print -P "${CLEAR_LINE}%F{red}✗ ${MODULE}: Error (1)%f\n${ERR}" print -u2 -PR ${CLEAR_LINE}"%F{red}✗ %B${MODULE}:%b Error during git fetch%f"$'\n'${(F):- ${(f)^ERR}}
return 1 return 1
fi fi
if [[ ${TYPE} == branch ]]; then if [[ ${TYPE} == branch ]]; then
LOG_REV="${REV}@{u}" LOG_REV=${REV}@{u}
else else
LOG_REV=${REV} LOG_REV=${REV}
fi fi
LOG=$(command git log --graph --color --format='%C(yellow)%h%C(reset) %s %C(cyan)(%cr)%C(reset)' ..${LOG_REV} 2>/dev/null) LOG=$(command git log --graph --color --format='%C(yellow)%h%C(reset) %s %C(cyan)(%cr)%C(reset)' ..${LOG_REV} 2>/dev/null)
if ! ERR=$(command git checkout -q ${REV} -- 2>&1); then if ! ERR=$(command git checkout -q ${REV} -- 2>&1); then
print -P "${CLEAR_LINE}%F{red}✗ ${MODULE}: Error (2)%f\n${ERR}" print -u2 -PR ${CLEAR_LINE}"%F{red}✗ %B${MODULE}:%b Error during git checkout%f"$'\n'${(F):- ${(f)^ERR}}
return 1 return 1
fi fi
if [[ ${TYPE} == branch ]]; then if [[ ${TYPE} == branch ]]; then
if ! OUT=$(command git merge --ff-only --no-progress -n 2>&1); then if ! OUT=$(command git merge --ff-only --no-progress -n 2>&1); then
print -P "${CLEAR_LINE}%F{red}✗ ${MODULE}: Error (3)%f\n${OUT}" print -u2 -PR ${CLEAR_LINE}"%F{red}✗ %B${MODULE}:%b Error during git merge%f"$'\n'${(F):- ${(f)^OUT}}
return 1 return 1
fi fi
# keep just first line of OUT # keep just first line of OUT
@ -49,16 +49,12 @@ if [[ ${TYPE} == branch ]]; then
else else
OUT="Updating to ${TYPE} ${REV}" OUT="Updating to ${TYPE} ${REV}"
fi fi
if [[ -n ${LOG} ]]; then
LOG_LINES=(' '${(f)^LOG})
OUT="${OUT}
${(F)LOG_LINES}"
fi
if ERR=$(command git submodule update --init --recursive -q 2>&1); then if ERR=$(command git submodule update --init --recursive -q 2>&1); then
if [[ ${OPT} != -q ]]; then if (( ! QUIET )); then
print -R "$(print -P "${CLEAR_LINE}%F{green}✓%f") ${MODULE}: ${OUT}" [[ -n ${LOG} ]] && OUT=${OUT}$'\n'${(F):- ${(f)^LOG}}
print -PR ${CLEAR_LINE}"%F{green}✓%f %B${MODULE}:%b ${OUT}"
fi fi
else else
print -P "${CLEAR_LINE}%F{red}✗ ${MODULE}: Error (4)%f\n${ERR}" print -u2 -PR ${CLEAR_LINE}"%F{red}✗ %B${MODULE}:%b Error during git submodule update%f"$'\n'${(F):- ${(f)^ERR}}
return 1 return 1
fi fi

View File

@ -1,13 +1,11 @@
<%# coding: UTF-8 %><% <%# coding: UTF-8 %><%
class Zim class Zim
attr_reader :functions_glob, :home, :min_zsh_version, :script_filename, :second_stage_guard, :version attr_reader :home, :min_zsh_version, :script_filename, :second_stage_guard, :version
def initialize def initialize
@functions_glob = "^(_*|*.*|prompt_*_setup)"
@home = "${ZDOTDIR:-${HOME}}" @home = "${ZDOTDIR:-${HOME}}"
@min_zsh_version = "5.2" @min_zsh_version = "5.2"
@script_filename = "zimfw.zsh" @script_filename = "zimfw.zsh"
@second_stage_guard = 2
@version = "1.0.0-SNAPSHOT" @version = "1.0.0-SNAPSHOT"
end end
@ -20,21 +18,13 @@ class Zim
end end
def render_escaped(filename) def render_escaped(filename)
render(filename).gsub(/(\$[^']|")/, "\\\\\\1") render(filename).gsub(/(\$[^']|"|`)/, "\\\\\\1")
end end
end end
zim = Zim.new zim = Zim.new
%># AUTOMATICALLY GENERATED FILE. EDIT ONLY THE SOURCE FILES AND THEN COMPILE. %># AUTOMATICALLY GENERATED FILE. EDIT ONLY THE SOURCE FILES AND THEN COMPILE.
# DO NOT DIRECTLY EDIT THIS FILE! # DO NOT DIRECTLY EDIT THIS FILE!
if (( ! # )); then <%= zim.render_all("src/stage1/*.erb") %>
<%= zim.render_all("src/stage2/*.erb") %>
# Stage 1 of sourcing this script zimfw "${@}"
<%= zim.render_all("src/stage1/*.erb") %># Stage 1 done
elif [[ ${1} == <%= zim.second_stage_guard %> ]]; then
# Stage 2 of sourcing this script. Should only be done internally by zimfw.
<%= zim.render_all("src/stage2/*.erb") %># Stage 2 done
fi

516
zimfw.zsh
View File

@ -1,71 +1,20 @@
# AUTOMATICALLY GENERATED FILE. EDIT ONLY THE SOURCE FILES AND THEN COMPILE. # AUTOMATICALLY GENERATED FILE. EDIT ONLY THE SOURCE FILES AND THEN COMPILE.
# DO NOT DIRECTLY EDIT THIS FILE! # DO NOT DIRECTLY EDIT THIS FILE!
if (( ! # )); then
# Stage 1 of sourcing this script
autoload -Uz is-at-least && if ! is-at-least 5.2; then autoload -Uz is-at-least && if ! is-at-least 5.2; then
print -u2 "init: error starting Zim: You're using Zsh version ${ZSH_VERSION} and versions < 5.2 are not supported. Update your Zsh." print -u2 -R "${0}: Error starting Zim. You're using Zsh version ${ZSH_VERSION} and versions < 5.2 are not supported. Update your Zsh."
return 1 return 1
fi fi
# Define Zim location # Define Zim location
: ${ZIM_HOME=${0:h}} : ${ZIM_HOME=${0:A:h}}
# Source user configuration
[[ -f ${ZDOTDIR:-${HOME}}/.zimrc ]] && source ${ZDOTDIR:-${HOME}}/.zimrc
# Set input mode before loading modules
if zstyle -t ':zim:input' mode 'vi'; then
bindkey -v
else
bindkey -e
fi
# Autoload enabled modules' functions
() {
local zfunction
local -a zmodules
zstyle -a ':zim' modules 'zmodules'
setopt LOCAL_OPTIONS EXTENDED_GLOB
fpath=(${ZIM_HOME}/modules/${^zmodules}/functions(/FN) ${fpath})
for zfunction in ${ZIM_HOME}/modules/${^zmodules}/functions/^(_*|*.*|prompt_*_setup)(-.N:t); do
autoload -Uz ${zfunction}
done
}
# Source enabled modules' init scripts
() {
local zmodule zdir zfile
local -a zmodules
zstyle -a ':zim' modules 'zmodules'
for zmodule in ${zmodules}; do
zdir=${ZIM_HOME}/modules/${zmodule}
if [[ ! -d ${zdir} ]]; then
print -u2 "init: module ${zmodule} not installed"
else
for zfile in ${zdir}/{init.zsh,${zmodule}.{zsh,plugin.zsh,zsh-theme,sh}}; do
if [[ -f ${zfile} ]]; then
source ${zfile}
break
fi
done
fi
done
}
_zimfw_compile() { _zimfw_compile() {
setopt LOCAL_OPTIONS EXTENDED_GLOB setopt LOCAL_OPTIONS EXTENDED_GLOB
autoload -U zrecompile autoload -U zrecompile
local zdumpfile zdir zfile
local zdir zfile
local -a zmodules
zstyle -a ':zim' modules 'zmodules'
# Compile the completion cache; significant speedup # Compile the completion cache; significant speedup
local zdumpfile
zstyle -s ':zim:completion' dumpfile 'zdumpfile' || zdumpfile="${ZDOTDIR:-${HOME}}/.zcompdump" zstyle -s ':zim:completion' dumpfile 'zdumpfile' || zdumpfile="${ZDOTDIR:-${HOME}}/.zcompdump"
if [[ -f ${zdumpfile} ]]; then if [[ -f ${zdumpfile} ]]; then
zrecompile -p ${1} ${zdumpfile} || return 1 zrecompile -p ${1} ${zdumpfile} || return 1
@ -74,198 +23,332 @@ _zimfw_compile() {
# Compile .zshrc # Compile .zshrc
zrecompile -p ${1} ${ZDOTDIR:-${HOME}}/.zshrc || return 1 zrecompile -p ${1} ${ZDOTDIR:-${HOME}}/.zshrc || return 1
# Compile enabled modules' autoloaded functions # Compile autoloaded functions
for zdir in ${ZIM_HOME}/modules/${^zmodules}/functions(/FN); do for zdir in ${fpath}; do
zrecompile -p ${1} ${zdir}.zwc ${zdir}/^(_*|*.*|prompt_*_setup)(-.N) || return 1 [[ ${zdir} == (.|..) || ${zdir} == (.|..)/* ]] && continue
if [[ -w ${zdir:h} ]]; then
zrecompile -p ${1} ${zdir}.zwc ${zdir}/^(*.*)(N-.) || return 1
fi
done done
# Compile enabled modules' scripts # Compile scripts
for zfile in ${ZIM_HOME}/modules/${^zmodules}/(^*test*/)#*.zsh{,-theme}(.NLk+1); do for zfile in ${ZIM_HOME}/(^*test*/)#*.zsh{,-theme}(N-.); do
zrecompile -p ${1} ${zfile} || return 1 zrecompile -p ${1} ${zfile} || return 1
done done
# Compile this script
zrecompile -p ${1} ${ZIM_HOME}/zimfw.zsh || return 1
if [[ ${1} != -q ]]; then if [[ ${1} != -q ]]; then
print -P '%F{green}✓%f Done with compile.' print -P '%F{green}✓%f Done with compile.'
fi fi
} }
zimfw() { if [[ ${1} == (compile|login-init) && ${2} == (|-q) ]]; then
case ${1} in _zimfw_compile ${2}
compile|login-init) _zimfw_compile ${2} ;; return
*) fi
source ${ZIM_HOME}/zimfw.zsh 2
zimfw "${@}"
;;
esac
}
# Stage 1 done
elif [[ ${1} == 2 ]]; then _zimfw_build() {
() {
# Stage 2 of sourcing this script. Should only be done internally by zimfw. local -r ztarget=${ZIM_HOME}/init.zsh
_zimfw_modules() { if command cmp -s ${ztarget} ${1}; then
local zmodule zurl ztype zrev if (( ! _zquiet )); then
local -a zmodules print -PR "%F{green}✓%f %B${ztarget}:%b Already up to date"
local -A zoptions fi
zstyle -a ':zim' modules 'zmodules'
for zmodule in ${zmodules}; do
zstyle -a ':zim:module' ${zmodule} 'zoptions'
[[ ${zoptions[frozen]} == yes ]] && continue
zurl=${zoptions[url]:-${zmodule}}
if [[ ${zurl} != /* && ${zurl} != *@*:* ]]; then
# Count number of slashes
case ${#zurl//[^\/]/} in
0) zurl="https://github.com/zimfw/${zurl}.git" ;;
1) zurl="https://github.com/${zurl}.git" ;;
esac
fi
if [[ -n ${zoptions[tag]} ]]; then
ztype=tag
zrev=${zoptions[tag]}
else else
ztype=branch if [[ -e ${ztarget} ]]; then
zrev=${zoptions[branch]:-master} command mv -f ${ztarget}{,.old} || return 1
fi
command mv -f ${1} ${ztarget} && \
if (( ! _zquiet )); then
print -PR "%F{green}✓%f %B${ztarget}:%b Updated. Restart your terminal for changes to take effect."
fi
fi fi
# Cannot have an empty space at the EOL because this is read by xargs -L1 if (( ! _zquiet )); then
print "'${ZIM_HOME}/modules/${zmodule}' '${zurl}' '${ztype}' '${zrev}'${1:+ ${1}}" print -P '%F{green}✓%f Done with build.'
fi
} =(
print -R "zimfw() { source ${ZIM_HOME}/zimfw.zsh \"\${@}\" }"
(( ${#_zfpaths} )) && print -R 'fpath=('${_zfpaths:P}' ${fpath})'
(( ${#_zfunctions} )) && print -R 'autoload -Uz '${_zfunctions}
print -Rn ${(F):-source ${^_zscripts:P}}
)
}
zmodule() {
local -r zusage="
Usage: %B${0}%b <url> [%B-n%b|%B--name%b <module_name>] [options]
Repository options:
%B-b%b|%B--branch%b <branch_name> Use specified branch when installing and updating the module
%B-t%b|%B--tag%b <tag_name> Use specified tag when installing and updating the module
%B-z%b|%B--frozen%b Don't install or update the module
Startup options:
%B-f%b|%B--fpath%b <path> Add specified path to fpath
%B-a%b|%B--autoload%b <function_name> Autoload specified function
%B-s%b|%B--source%b <file_path> Source specified file
%B-d%b|%B--disabled%b Don't use or clean the module
"
if [[ ${${funcfiletrace[1]%:*}:t} != .zimrc ]]; then
print -u2 -PR "%F{red}${0}: Must be called from ${ZDOTDIR:-${HOME}}/.zimrc%f"$'\n'${zusage}
return 1
fi
if (( ! # )); then
print -u2 -PR "%F{red}✗ ${funcfiletrace[1]}: Missing zmodule url%f"
_zfailed=1
return 1
fi
setopt LOCAL_OPTIONS EXTENDED_GLOB
local zmodule=${1:t} zurl=${1}
local ztype=branch zrev=master
local -i zdisabled=0 zfrozen=0
local -a zfpaths zfunctions zscripts
local zarg
if [[ ${zurl} =~ ^[^:/]+: ]]; then
zmodule=${zmodule%.git}
elif [[ ${zurl} != /* ]]; then
# Count number of slashes
case ${#zurl//[^\/]/} in
0) zurl="https://github.com/zimfw/${zurl}.git" ;;
1) zurl="https://github.com/${zurl}.git" ;;
esac
fi
shift
if [[ ${1} == (-n|--name) ]]; then
if (( # < 2 )); then
print -u2 -PR "%F{red}✗ ${funcfiletrace[1]}:%B${zmodule}:%b Missing argument for zmodule option ${1}%f"
_zfailed=1
return 1
fi
shift
zmodule=${1}
shift
fi
local -r zdir=${ZIM_HOME}/modules/${zmodule}
while (( # > 0 )); do
case ${1} in
-b|--branch|-t|--tag|-f|--fpath|-a|--autoload|-s|--source)
if (( # < 2 )); then
print -u2 -PR "%F{red}✗ ${funcfiletrace[1]}:%B${zmodule}:%b Missing argument for zmodule option ${1}%f"
_zfailed=1
return 1
fi
;;
esac
case ${1} in
-b|--branch)
shift
ztype=branch
zrev=${1}
;;
-t|--tag)
shift
ztype=tag
zrev=${1}
;;
-z|--frozen) zfrozen=1 ;;
-f|--fpath)
shift
zarg=${1}
[[ ${zarg} != /* ]] && zarg=${zdir}/${zarg}
zfpaths+=(${zarg})
;;
-a|--autoload)
shift
zfunctions+=(${1})
;;
-s|--source)
shift
zarg=${1}
[[ ${zarg} != /* ]] && zarg=${zdir}/${zarg}
zscripts+=(${zarg})
;;
-d|--disabled) zdisabled=1 ;;
*)
print -u2 -PR "%F{red}✗ ${funcfiletrace[1]}:%B${zmodule}:%b Unknown zmodule option ${1}%f"
_zfailed=1
return 1
;;
esac
shift
done done
if (( zdisabled )); then
_zdisableds+=(${zmodule})
else
(( ! ${#zfpaths} )) && zfpaths+=(${zdir}/functions(NF))
if (( ! ${#zfunctions} )); then
# _* functions are autoloaded by compinit
# prompt_*_setup functions are autoloaded by promptinit
zfunctions+=(${^zfpaths}/^(*.*|_*|prompt_*_setup)(N-.:t))
fi
if (( ! ${#zscripts} )); then
zscripts+=(${zdir}/(init.zsh|${zmodule:t}.(zsh|plugin.zsh|zsh-theme|sh))(NOL[1]))
fi
_zfpaths+=(${zfpaths})
_zfunctions+=(${zfunctions})
_zscripts+=(${zscripts})
_zmodules+=(${zmodule})
fi
if (( ! zfrozen )); then
_zmodules_xargs+=${zmodule}$'\0'${zdir}$'\0'${zurl}$'\0'${ztype}$'\0'${zrev}$'\0'${_zquiet}$'\0'
fi
}
_zimfw_source_zimrc() {
local -i _zfailed=0
if ! source ${ZDOTDIR:-${HOME}}/.zimrc || (( _zfailed )); then
print -u2 -PR "%F{red}✗ Failed to source ${ZDOTDIR:-${HOME}}/.zimrc%f"
return 1
fi
} }
_zimfw_clean_modules() { _zimfw_clean_modules() {
local zdir zmodule local zopt zdir zmodule
local -a zmodules (( ! _zquiet )) && zopt='-v'
local -A zoptions for zdir in ${ZIM_HOME}/modules/*(N/); do
# Source .zimrc to refresh zmodules
[[ -f ${ZDOTDIR:-${HOME}}/.zimrc ]] && source ${ZDOTDIR:-${HOME}}/.zimrc
zstyle -a ':zim' modules 'zmodules'
for zdir in ${ZIM_HOME}/modules/*(/N); do
zmodule=${zdir:t} zmodule=${zdir:t}
# If zmodules does not contain the zmodule # If _zmodules and _zdisableds do not contain the zmodule
if (( ! ${zmodules[(I)${zmodule}]} )); then if (( ! ${_zmodules[(I)${zmodule}]} && ! ${_zdisableds[(I)${zmodule}]} )); then
zstyle -a ':zim:module' ${zmodule} 'zoptions' command rm -rf ${zopt} ${zdir} || return 1
[[ ${zoptions[frozen]} == yes ]] && continue
command rm -rf ${zdir} || return 1
[[ ${1} != -q ]] && print ${zdir}
fi fi
done done
if [[ ${1} != -q ]]; then if (( ! _zquiet )); then
print -P "%F{green}✓%f Done with clean-modules." print -P '%F{green}✓%f Done with clean-modules.'
fi fi
} }
_zimfw_clean_compiled() { _zimfw_clean_compiled() {
setopt LOCAL_OPTIONS PIPE_FAIL local zopt_find zopt_rm zdir
local find_opt rm_opt if (( ! _zquiet )); then
if [[ ${1} != -q ]]; then zopt_find='-print'
find_opt='-print' zopt_rm='-v'
rm_opt='-v'
fi fi
command find ${ZIM_HOME} \( -name '*.zwc' -o -name '*.zwc.old' \) -delete ${find_opt} || return 1 for zdir in ${fpath}; do
command rm -f ${rm_opt} ${ZDOTDIR:-${HOME}}/.zshrc.zwc{,.old} || return 1 [[ ${zdir} == (.|..) || ${zdir} == (.|..)/* ]] && continue
if [[ ${1} != -q ]]; then if [[ -w ${zdir:h} ]]; then
print -P "%F{green}✓%f Done with clean-compiled. Run %Bzimfw compile%b to re-compile." command rm -f ${zopt_rm} ${zdir}.zwc{,.old} || return 1
fi
done
command find ${ZIM_HOME} \( -name '*.zwc' -o -name '*.zwc.old' \) -delete ${zopt_find} || return 1
command rm -f ${zopt_rm} ${ZDOTDIR:-${HOME}}/.zshrc.zwc{,.old} || return 1
if (( ! _zquiet )); then
print -P '%F{green}✓%f Done with clean-compiled. Run %Bzimfw compile%b to re-compile.'
fi fi
} }
_zimfw_clean_dumpfile() { _zimfw_clean_dumpfile() {
setopt LOCAL_OPTIONS PIPE_FAIL local zdumpfile zopt
local zdumpfile zout zopt
zstyle -s ':zim:completion' dumpfile 'zdumpfile' || zdumpfile="${ZDOTDIR:-${HOME}}/.zcompdump" zstyle -s ':zim:completion' dumpfile 'zdumpfile' || zdumpfile="${ZDOTDIR:-${HOME}}/.zcompdump"
[[ ${1} != -q ]] && zopt='-v' (( ! _zquiet )) && zopt='-v'
command rm -f ${zopt} ${zdumpfile}{,.zwc{,.old}} || return 1 command rm -f ${zopt} ${zdumpfile}{,.zwc{,.old}} || return 1
if [[ ${1} != -q ]]; then if (( ! _zquiet )); then
print -P "%F{green}✓%f Done with clean-dumpfile. Restart your terminal to dump an updated configuration." print -P '%F{green}✓%f Done with clean-dumpfile. Restart your terminal to dump an updated configuration.'
fi fi
} }
_zimfw_info() { _zimfw_info() {
print 'Zim version: 1.0.0-SNAPSHOT (previous commit is 601941f)' print 'Zim version: 1.0.0-SNAPSHOT (previous commit is e81c1d1)'
print "Zsh version: ${ZSH_VERSION}" print -R "Zsh version: ${ZSH_VERSION}"
print "System info: $(command uname -a)" print -R "System info: $(command uname -a)"
} }
_zimfw_upgrade() { _zimfw_upgrade() {
local zscript=${ZIM_HOME}/zimfw.zsh local -r zscript=${ZIM_HOME}/zimfw.zsh
local zurl=https://raw.githubusercontent.com/zimfw/zimfw/develop/zimfw.zsh local -r zurl=https://raw.githubusercontent.com/zimfw/zimfw/develop/zimfw.zsh
if (( ${+commands[wget]} )); then {
command wget -nv ${1} -O ${zscript}.new ${zurl} || return 1 if (( ${+commands[wget]} )); then
else command wget -nv ${1} -O ${zscript}.new ${zurl} || return 1
command curl -fsSL -o ${zscript}.new ${zurl} || return 1 else
fi command curl -fsSL -o ${zscript}.new ${zurl} || return 1
if command cmp -s ${zscript}{,.new}; then fi
command rm ${zscript}.new && \ if command cmp -s ${zscript}{,.new}; then
if [[ ${1} != -q ]]; then if (( ! _zquiet )); then
print -P "%F{green}✓%f zimfw.zsh: Already up to date." print -P '%F{green}✓%f %Bzimfw.zsh:%b Already up to date'
fi fi
else else
command mv ${zscript}{,.old} && command mv ${zscript}{.new,} && \ command mv -f ${zscript}{,.old} && command mv -f ${zscript}{.new,} && \
if [[ ${1} != -q ]]; then if (( ! _zquiet )); then
print -P "%F{green}✓%f zimfw.zsh: upgraded. Restart your terminal for changes to take effect." print -P '%F{green}✓%f %Bzimfw.zsh:%b Upgraded. Restart your terminal for changes to take effect.'
fi fi
fi fi
if (( ! _zquiet )); then
print -P '%F{green}✓%f Done with upgrade.'
fi
} always {
command rm -f ${zscript}.new
}
} }
unfunction zimfw
zimfw() { zimfw() {
local zusage="usage: ${0} <action> [-q] local -r zusage="
actions: Usage: %B${0}%b <action> [%B-q%b]
clean Clean all (see below).
clean-modules Clean unused modules.
clean-compiled Clean Zsh compiled files.
clean-dumpfile Clean completion dump file.
compile Compile Zsh files.
info Print Zim and system info.
install Install new modules.
update Update current modules.
upgrade Upgrade Zim.
options:
-q Quiet, only outputs errors."
if [[ ${#} -ne 1 && ${2} != -q ]]; then Actions:
print -u2 ${zusage} %Bbuild%b Build init script
return 1 %Bclean%b Clean all (see below)
%Bclean-modules%b Clean unused modules
%Bclean-compiled%b Clean Zsh compiled files
%Bclean-dumpfile%b Clean completion dump file
%Bcompile%b Compile Zsh files
%Binfo%b Print Zim and system info
%Binstall%b Install new modules
%Bupdate%b Update current modules
%Bupgrade%b Upgrade Zim
Options:
%B-q%b Quiet, only outputs errors
"
local ztool _zmodules_xargs
local -a _zdisableds _zmodules _zfpaths _zfunctions _zscripts
local -i _zquiet=0
if (( # > 2 )); then
print -u2 -PR "%F{red}${0}: Too many options%f"$'\n'${zusage}
return 1
elif (( # > 1 )); then
case ${2} in
-q) _zquiet=1 ;;
*)
print -u2 -PR "%F{red}${0}: Unknown option ${2}%f"$'\n'${zusage}
return 1
;;
esac
fi fi
local ztool
case ${1} in case ${1} in
install) install)
ztool="# This runs in a new shell ztool="# This runs in a new shell
DIR=\${1} readonly MODULE=\${1}
URL=\${2} readonly DIR=\${2}
REV=\${4} readonly URL=\${3}
OPT=\${5} readonly REV=\${5}
MODULE=\${DIR:t} readonly -i QUIET=\${6}
CLEAR_LINE=\"\033[2K\r\" readonly CLEAR_LINE=$'\E[2K\r'
if [[ -e \${DIR} ]]; then if [[ -e \${DIR} ]]; then
# Already exists # Already exists
return 0 return 0
fi fi
[[ \${OPT} != -q ]] && print -n \"\${CLEAR_LINE}Installing \${MODULE}\" (( ! QUIET )) && print -Rn \${CLEAR_LINE}\"Installing \${MODULE}\"
if ERR=\$(command git clone -b \${REV} -q --recursive \${URL} \${DIR} 2>&1); then if ERR=\$(command git clone -b \${REV} -q --recursive \${URL} \${DIR} 2>&1); then
if [[ \${OPT} != -q ]]; then if (( ! QUIET )); then
print -P \"\${CLEAR_LINE}%F{green}✓%f \${MODULE}: Installed\" print -PR \${CLEAR_LINE}\"%F{green}✓%f %B\${MODULE}:%b Installed\"
fi fi
else else
print -P \"\${CLEAR_LINE}%F{red}\${MODULE}: Error%f\n\${ERR}\" print -u2 -PR \${CLEAR_LINE}\"%F{red}✗ %B\${MODULE}:%b Error during git clone%f\"$'\n'\${(F):- \${(f)^ERR}}
return 1 return 1
fi fi
" "
;; ;;
update) update)
ztool="# This runs in a new shell ztool="# This runs in a new shell
DIR=\${1} readonly MODULE=\${1}
URL=\${2} readonly DIR=\${2}
TYPE=\${3} readonly URL=\${3}
REV=\${4} readonly TYPE=\${4}
OPT=\${5} readonly REV=\${5}
MODULE=\${DIR:t} readonly -i QUIET=\${6}
CLEAR_LINE=\"\033[2K\r\" readonly CLEAR_LINE=$'\E[2K\r'
[[ \${OPT} != -q ]] && print -n \"\${CLEAR_LINE}Updating \${MODULE}\" (( ! QUIET )) && print -Rn \${CLEAR_LINE}\"Updating \${MODULE}\"
if ! cd \${DIR} 2>/dev/null; then if ! builtin cd \${DIR} 2>/dev/null; then
print -P \"\${CLEAR_LINE}%F{red}\${MODULE}: Not installed%f\" print -u2 -PR \${CLEAR_LINE}\"%F{red}%B\${MODULE}:%b Not installed%f\"
return 1 return 1
fi fi
if [[ \${PWD} != \$(command git rev-parse --show-toplevel 2>/dev/null) ]]; then if [[ \${PWD} != \$(command git rev-parse --show-toplevel 2>/dev/null) ]]; then
@ -273,32 +356,32 @@ if [[ \${PWD} != \$(command git rev-parse --show-toplevel 2>/dev/null) ]]; then
return 0 return 0
fi fi
if [[ \${URL} != \$(command git config --get remote.origin.url) ]]; then if [[ \${URL} != \$(command git config --get remote.origin.url) ]]; then
print -P \"\${CLEAR_LINE}%F{red}\${MODULE}: URL does not match. Expected \${URL}. Will not try to update.%f\" print -u2 -PR \${CLEAR_LINE}\"%F{red}%B\${MODULE}:%b URL does not match. Expected \${URL}. Will not try to update.%f\"
return 1 return 1
fi fi
if [[ \${TYPE} == tag ]]; then if [[ \${TYPE} == tag ]]; then
if [[ \${REV} == \$(command git describe --tags --exact-match 2>/dev/null) ]]; then if [[ \${REV} == \$(command git describe --tags --exact-match 2>/dev/null) ]]; then
[[ \${OPT} != -q ]] && print -P \"\${CLEAR_LINE}%F{green}✓%f \${MODULE}: Already up to date\" (( ! QUIET )) && print -PR \${CLEAR_LINE}\"%F{green}✓%f %B\${MODULE}:%b Already up to date\"
return 0 return 0
fi fi
fi fi
if ! ERR=\$(command git fetch -pq origin \${REV} 2>&1); then if ! ERR=\$(command git fetch -pq origin \${REV} 2>&1); then
print -P \"\${CLEAR_LINE}%F{red}\${MODULE}: Error (1)%f\n\${ERR}\" print -u2 -PR \${CLEAR_LINE}\"%F{red}✗ %B\${MODULE}:%b Error during git fetch%f\"$'\n'\${(F):- \${(f)^ERR}}
return 1 return 1
fi fi
if [[ \${TYPE} == branch ]]; then if [[ \${TYPE} == branch ]]; then
LOG_REV=\"\${REV}@{u}\" LOG_REV=\${REV}@{u}
else else
LOG_REV=\${REV} LOG_REV=\${REV}
fi fi
LOG=\$(command git log --graph --color --format='%C(yellow)%h%C(reset) %s %C(cyan)(%cr)%C(reset)' ..\${LOG_REV} 2>/dev/null) LOG=\$(command git log --graph --color --format='%C(yellow)%h%C(reset) %s %C(cyan)(%cr)%C(reset)' ..\${LOG_REV} 2>/dev/null)
if ! ERR=\$(command git checkout -q \${REV} -- 2>&1); then if ! ERR=\$(command git checkout -q \${REV} -- 2>&1); then
print -P \"\${CLEAR_LINE}%F{red}\${MODULE}: Error (2)%f\n\${ERR}\" print -u2 -PR \${CLEAR_LINE}\"%F{red}✗ %B\${MODULE}:%b Error during git checkout%f\"$'\n'\${(F):- \${(f)^ERR}}
return 1 return 1
fi fi
if [[ \${TYPE} == branch ]]; then if [[ \${TYPE} == branch ]]; then
if ! OUT=\$(command git merge --ff-only --no-progress -n 2>&1); then if ! OUT=\$(command git merge --ff-only --no-progress -n 2>&1); then
print -P \"\${CLEAR_LINE}%F{red}\${MODULE}: Error (3)%f\n\${OUT}\" print -u2 -PR \${CLEAR_LINE}\"%F{red}✗ %B\${MODULE}:%b Error during git merge%f\"$'\n'\${(F):- \${(f)^OUT}}
return 1 return 1
fi fi
# keep just first line of OUT # keep just first line of OUT
@ -306,17 +389,13 @@ if [[ \${TYPE} == branch ]]; then
else else
OUT=\"Updating to \${TYPE} \${REV}\" OUT=\"Updating to \${TYPE} \${REV}\"
fi fi
if [[ -n \${LOG} ]]; then
LOG_LINES=(' '\${(f)^LOG})
OUT=\"\${OUT}
\${(F)LOG_LINES}\"
fi
if ERR=\$(command git submodule update --init --recursive -q 2>&1); then if ERR=\$(command git submodule update --init --recursive -q 2>&1); then
if [[ \${OPT} != -q ]]; then if (( ! QUIET )); then
print -R \"\$(print -P \"\${CLEAR_LINE}%F{green}✓%f\") \${MODULE}: \${OUT}\" [[ -n \${LOG} ]] && OUT=\${OUT}$'\n'\${(F):- \${(f)^LOG}}
print -PR \${CLEAR_LINE}\"%F{green}✓%f %B\${MODULE}:%b \${OUT}\"
fi fi
else else
print -P \"\${CLEAR_LINE}%F{red}\${MODULE}: Error (4)%f\n\${ERR}\" print -u2 -PR \${CLEAR_LINE}\"%F{red}✗ %B\${MODULE}:%b Error during git submodule update%f\"$'\n'\${(F):- \${(f)^ERR}}
return 1 return 1
fi fi
" "
@ -324,31 +403,32 @@ fi
esac esac
case ${1} in case ${1} in
build) _zimfw_source_zimrc && _zimfw_build && _zimfw_compile ${2} ;;
clean) clean)
_zimfw_clean_modules ${2} && \ _zimfw_source_zimrc && \
_zimfw_clean_compiled ${2} && \ _zimfw_clean_modules && \
_zimfw_clean_dumpfile ${2} _zimfw_clean_compiled && \
_zimfw_clean_dumpfile
;; ;;
clean-modules) _zimfw_clean_modules ${2} ;; clean-modules) _zimfw_source_zimrc && _zimfw_clean_modules ;;
clean-compiled) _zimfw_clean_compiled ${2} ;; clean-compiled) _zimfw_clean_compiled ;;
clean-dumpfile) _zimfw_clean_dumpfile ${2} ;; clean-dumpfile) _zimfw_clean_dumpfile ;;
compile|login-init) _zimfw_compile ${2} ;; compile|login-init) _zimfw_source_zimrc && _zimfw_compile ${2} ;;
info) _zimfw_info ${2} ;; info) _zimfw_info ;;
install|update) install|update)
# Source .zimrc to refresh zmodules _zimfw_source_zimrc || return 1
[[ -f ${ZDOTDIR:-${HOME}}/.zimrc ]] && source ${ZDOTDIR:-${HOME}}/.zimrc print -Rn ${_zmodules_xargs} | xargs -0 -n6 -P10 zsh -c ${ztool} ${1} && \
_zimfw_modules ${2} | xargs -L1 -P10 zsh -c ${ztool} ${1} && \ if (( ! _zquiet )); then
if [[ ${2} != -q ]]; then print -PR "%F{green}✓%f Done with ${1}. Restart your terminal for any changes to take effect."
print -P "%F{green}✓%f Done with ${1}. Restart your terminal for any changes to take effect." fi && \
fi _zimfw_build && _zimfw_compile ${2}
;; ;;
upgrade) _zimfw_upgrade ${2} ;; upgrade) _zimfw_upgrade ;;
*) *)
print -u2 ${zusage} print -u2 -PR "%F{red}${0}: Unknown action ${1}%f"$'\n'${zusage}
return 1 return 1
;; ;;
esac esac
} }
# Stage 2 done
fi zimfw "${@}"