mirror of
https://github.com/oh-my-fish/oh-my-fish.git
synced 2024-11-22 12:43:23 +08:00
init: rewrite init process (#260)
* init: rewrite init process Now use pure globbing to generate 100% valid function and completion paths, effectively splitting the init process in two steps, one which paths are added, and other when initialization is done (sourcing init). This initialization code introduces a new interface for `init.fish` hook, which deprecates the previously used event model. The new interface injects three variables into `init.fish`: path, package and bundle. This variables can be used by the package to autoload paths, use bundled files, etc. Also supports key bindings by sourcing $OMF_CONFIG/key_bindings.fish and also key_bindings.fish in packages (plugins and themes) root directories. This is done when fish_user_key_bindings is called. * omf: migrate to new init hook * omf/templates: migrate to new init and uninstall hooks * docs: document new init and uninstall hooks interface * README: update new hook interface spec
This commit is contained in:
parent
17de8c4b6b
commit
a164ebdd5d
|
@ -62,7 +62,7 @@ Apply a theme. To list available themes, type `omf theme`. You can also [preview
|
|||
|
||||
Remove a theme or package.
|
||||
|
||||
> Packages subscribed to `uninstall_<pkg>` events are notified before the package is removed, so custom cleanup of resources can be done. See [Uninstall](/docs/en-US/Packages.md#uninstall) for more information.
|
||||
> Packages can use uninstall hooks, so custom cleanup of resources can be done when uninstalling it. See [Uninstall](/docs/en-US/Packages.md#uninstall) for more information.
|
||||
|
||||
#### `omf reload`
|
||||
|
||||
|
@ -125,7 +125,7 @@ Every time a package/theme is installed or removed, the `bundle` file is updated
|
|||
|
||||
## Creating Packages
|
||||
|
||||
Oh My Fish uses an advanced and well defined plugin architecture to ease plugin development, including init/uninstall events and function autoloading. [See the documentation](docs/en-US/Packages.md) for more details.
|
||||
Oh My Fish uses an advanced and well defined plugin architecture to ease plugin development, including init/uninstall hooks, function and completion autoloading. [See the packages documentation](docs/en-US/Packages.md) for more details.
|
||||
|
||||
[fishshell]: http://fishshell.com
|
||||
|
||||
|
|
|
@ -53,24 +53,27 @@ Packages were designed to take advantages of fish events. There are currently tw
|
|||
|
||||
## Initialization
|
||||
|
||||
If you want to be [notified](http://fishshell.com/docs/current/commands.html#emit) when your package loads, declare the following function in your `hello_world.fish`:
|
||||
If you want code to be executed when the package loads, you can add code to `init.fish` file at package's root directory:
|
||||
|
||||
```fish
|
||||
function init -a path --on-event init_hello_world
|
||||
echo "hello_world initialized"
|
||||
end
|
||||
echo "hello_world initialized"
|
||||
```
|
||||
|
||||
Use this event to modify the environment, load resources, autoload functions, etc. If your package does not export any functions, you can still use this event to add functionality to your package.
|
||||
Inside this hook runs you can access three package-related variables:
|
||||
|
||||
* `$package`: Package name
|
||||
* `$path`: Package installation path
|
||||
* `$dependencies` : Package dependencies
|
||||
|
||||
Use this hook to modify the environment, load resources, autoload functions, etc. If your package does not export any function, you can still use this event to add functionality to your package, or dynamically create functions.
|
||||
|
||||
## Uninstall
|
||||
|
||||
Oh My Fish emits `uninstall_<pkg>` events before a package is removed via `omf remove <pkg>`. Subscribers can use the event to clean up custom resources, etc.
|
||||
Oh My Fish also features `uninstall.fish` hook, which is called before a package is removed via `omf remove <pkg>`. Packages can use this hook to clean up custom resources, etc.
|
||||
|
||||
```fish
|
||||
function uninstall --on-event uninstall_hello_world
|
||||
end
|
||||
```
|
||||
Inside this hook you can access one package-related variable:
|
||||
|
||||
* `$path`: Package installation path
|
||||
|
||||
|
||||
# Make it public
|
||||
|
|
|
@ -54,24 +54,26 @@ end
|
|||
|
||||
## 初始化
|
||||
|
||||
如果你想在插件被加载时收到[通知](http://fishshell.com/docs/current/commands.html#emit),你可以在 `hello_world.fish` 添加下面的代码:
|
||||
如果要执行的代码包时加载,可以为`init.fish`文件在包的根目录下添加代码:
|
||||
|
||||
```fish
|
||||
function init -a path --on-event init_hello_world
|
||||
echo "hello_world initialized"
|
||||
end
|
||||
echo "hello_world initialized"
|
||||
```
|
||||
|
||||
该事件可以用于修改环境变量、加载资源和自动加载函数等。如果你的插件没有输出任何的函数,你仍然可以使用该事件加载其他的函数。
|
||||
这里面挂机运行,您可以访问包相关的变量:
|
||||
|
||||
* `$package`:包名称
|
||||
* `$path`:软件包的安装路径
|
||||
* `$dependencies`:软件包依赖
|
||||
|
||||
使用这个钩子来修改环境,资源负载,自动加载的功能,等等。如果你的包不出口任何功能,您仍可以使用此事件将功能添加到您的包,还是动态创建功能。
|
||||
|
||||
## 卸载
|
||||
|
||||
Oh My Fish 通过 `omf remove <pkg>` 移除已安装的插件前会发送 `uninstall_<pkg>` 事件。订阅者可以使用该事件清理自定义的资源等操作。
|
||||
哦,我的鱼还设有`uninstall.fish`挂钩,通过 `omf remove <pkg>`被删除软件包之前被调用。包可以使用这个钩子清理自定义的资源,等等。
|
||||
|
||||
```fish
|
||||
function uninstall --on-event uninstall_hello_world
|
||||
end
|
||||
```
|
||||
本书中,你可以访问一个包相关的变量:
|
||||
* `$path`:软件包的安装路径
|
||||
|
||||
|
||||
# 发布插件
|
||||
|
|
|
@ -56,8 +56,7 @@ Oh My Fish 自带的辅助命令工具 `omf` 可以帮助你快速获取安装
|
|||
|
||||
移除主题或插件。
|
||||
|
||||
> 插件如果注册(subscribed)过 `uninstall_<pkg>` 事件将会在插件移除前触发,因此你可以自定义自身清理和扫尾的工作以保证插件干净移除。
|
||||
详见[卸载部分](Packages.md#uninstall)获取更多信息。
|
||||
> 包可以使用卸载挂钩,所以资源的自定义清理可以做到卸载时。有关更多信息,请参见 [卸载](Packages.md#uninstall) 。
|
||||
|
||||
#### `omf new pkg | theme` _`<name>`_
|
||||
|
||||
|
|
84
init.fish
84
init.fish
|
@ -1,55 +1,43 @@
|
|||
# SYNOPSIS
|
||||
# Initialize Oh My Fish.
|
||||
#
|
||||
# OVERVIEW
|
||||
# + Source $OMF_CONFIG/before.init.fish
|
||||
#
|
||||
# + Autoload Oh My Fish packages, themes and config path
|
||||
# + For each <pkg> inside {$OMF_PATH,$OMF_CONFIG}
|
||||
# + Autoload <pkg> directory
|
||||
# + Source <pkg>.fish
|
||||
# + Emit init_<pkg> event
|
||||
#
|
||||
# + Autoload {$OMF_PATH,$OMF_CONFIG}/functions
|
||||
# + Source $OMF_CONFIG/init.fish
|
||||
#
|
||||
# ENV
|
||||
# OMF_PATH ~/.local/share/omf by default.
|
||||
# OMF_IGNORE List of packages to ignore.
|
||||
# OMF_CONFIG ~/.config/omf by default.
|
||||
# OMF_VERSION Oh My Fish! version
|
||||
|
||||
# Set OMF_CONFIG if not set.
|
||||
if not set -q OMF_CONFIG
|
||||
set -q XDG_CONFIG_HOME; or set -l XDG_CONFIG_HOME "$HOME/.config"
|
||||
set -gx OMF_CONFIG "$XDG_CONFIG_HOME/omf"
|
||||
end
|
||||
|
||||
# Source custom before.init.fish file
|
||||
source $OMF_CONFIG/before.init.fish ^/dev/null
|
||||
|
||||
# Save the head of function path and autoload core functions
|
||||
set -l user_function_path $fish_function_path[1]
|
||||
set fish_function_path[1] $OMF_PATH/lib
|
||||
|
||||
# Autoload util functions
|
||||
autoload $OMF_PATH/lib $OMF_PATH/lib/git
|
||||
|
||||
for path in {$OMF_PATH,$OMF_CONFIG}/pkg/*
|
||||
set -l name (basename $path)
|
||||
|
||||
contains -- $name $OMF_IGNORE; and continue
|
||||
require $name
|
||||
test -f $OMF_CONFIG/before.init.fish
|
||||
and source $OMF_CONFIG/before.init.fish ^/dev/null
|
||||
emit perf:timer:start "Oh My Fish initialisation"
|
||||
# Read current theme
|
||||
read -l theme < $OMF_CONFIG/theme
|
||||
# Prepare Oh My Fish paths
|
||||
set -l core_function_path $OMF_PATH/lib{,/git}
|
||||
set -l theme_function_path {$OMF_CONFIG,$OMF_PATH}/themes*/$theme{,/functions}
|
||||
# Autoload core library
|
||||
set fish_function_path $fish_function_path[1] \
|
||||
$core_function_path \
|
||||
$theme_function_path \
|
||||
$fish_function_path[2..-1]
|
||||
# Require all packages
|
||||
emit perf:timer:start "Oh My Fish init installed packages"
|
||||
require --path {$OMF_PATH,$OMF_CONFIG}/pkg/*
|
||||
emit perf:timer:finish "Oh My Fish init installed packages"
|
||||
# Backup key bindings
|
||||
functions -q fish_user_key_bindings
|
||||
and functions -c fish_user_key_bindings __original_fish_user_key_bindings
|
||||
# Override key bindings, calling original if existent
|
||||
function fish_user_key_bindings
|
||||
# Read packages key bindings
|
||||
for file in {$OMF_CONFIG,$OMF_PATH}/{,pkg,theme}/*/key_bindings.fish
|
||||
source $file
|
||||
end
|
||||
# Read custom key bindings file
|
||||
source $OMF_CONFIG/key_bindings.fish ^/dev/null
|
||||
# Call original key bindings if existent
|
||||
functions -q __original_fish_user_key_bindings
|
||||
and __original_fish_user_key_bindings
|
||||
end
|
||||
|
||||
# Autoload theme
|
||||
autoload {$OMF_PATH,$OMF_CONFIG}/themes/(cat $OMF_CONFIG/theme)
|
||||
|
||||
# Autoload custom functions
|
||||
autoload $OMF_CONFIG/functions
|
||||
autoload $user_function_path
|
||||
|
||||
# Source custom init.fish file
|
||||
source $OMF_CONFIG/init.fish ^/dev/null
|
||||
|
||||
set -g OMF_VERSION "2"
|
||||
emit perf:timer:start "Oh My Fish init user config path"
|
||||
require --no-bundle --path $OMF_CONFIG
|
||||
emit perf:timer:finish "Oh My Fish init user config path"
|
||||
set -g OMF_VERSION "1.1.0-dev"
|
||||
emit perf:timer:finish "Oh My Fish initialisation"
|
||||
|
|
111
lib/require.fish
111
lib/require.fish
|
@ -1,41 +1,82 @@
|
|||
# SYNOPSIS
|
||||
# require [name]
|
||||
#
|
||||
# OVERVIEW
|
||||
# Require a plugin:
|
||||
# - Autoload its functions and completions.
|
||||
# - Require bundle dependencies.
|
||||
# - Source its initialization file.
|
||||
# - Emit its initialization event.
|
||||
#
|
||||
# If the required plugin has already been loaded, does nothing.
|
||||
function require
|
||||
set packages $argv
|
||||
|
||||
function require -a name
|
||||
# Skip if plugin has already been loaded.
|
||||
contains -- $OMF_PATH/pkg/$name $fish_function_path;
|
||||
or contains -- $OMF_CONFIG/pkg/$name $fish_function_path;
|
||||
and return 0
|
||||
|
||||
for path in {$OMF_PATH,$OMF_CONFIG}/pkg/$name
|
||||
test -d $path; or continue
|
||||
|
||||
if autoload $path $path/functions $path/completions
|
||||
|
||||
if test -f $path/bundle
|
||||
for line in (cat $path/bundle)
|
||||
test (echo $line | cut -d' ' -f1) = package;
|
||||
and set dependency (basename (echo $line | cut -d' ' -f2));
|
||||
and require $dependency
|
||||
end
|
||||
end
|
||||
|
||||
source $path/init.fish ^/dev/null;
|
||||
or source $path/$name.fish ^/dev/null;
|
||||
and emit init_$name $path
|
||||
end
|
||||
if test -z "$packages"
|
||||
echo 'usage: require <name>...'
|
||||
echo ' require --path <path>...'
|
||||
echo ' require --no-bundle --path <path>...'
|
||||
return 1
|
||||
end
|
||||
|
||||
functions -e init # Cleanup previously sourced function
|
||||
# If bundle should be
|
||||
if set index (contains -i -- --no-bundle $packages)
|
||||
set -e packages[$index]
|
||||
set ignore_bundle
|
||||
end
|
||||
|
||||
# Requiring absolute paths
|
||||
if set index (contains -i -- --path $packages)
|
||||
set -e packages[$index]
|
||||
set package_path $packages
|
||||
|
||||
# Requiring specific packages from default paths
|
||||
else
|
||||
set package_path {$OMF_PATH,$OMF_CONFIG}/pkg*/$packages
|
||||
|
||||
# Exit with error if no package paths were generated
|
||||
test -z "$package_path"
|
||||
and return 1
|
||||
end
|
||||
|
||||
set function_path $package_path/functions*
|
||||
set completion_path $package_path/completions*
|
||||
set init_path $package_path/init.fish*
|
||||
|
||||
# Autoload functions
|
||||
test -n "$function_path"
|
||||
and set fish_function_path $fish_function_path[1] \
|
||||
$function_path \
|
||||
$fish_function_path[2..-1]
|
||||
|
||||
# Autoload completions
|
||||
test -n "$complete_path"
|
||||
and set fish_complete_path $fish_complete_path[1] \
|
||||
$complete_path \
|
||||
$fish_complete_path[2..-1]
|
||||
|
||||
for init in $init_path
|
||||
emit perf:timer:start $init
|
||||
set -l IFS '/'
|
||||
echo $init | read -la components
|
||||
|
||||
set path (printf '/%s' $components[1..-2])
|
||||
|
||||
contains $path $omf_init_path
|
||||
and continue
|
||||
|
||||
set package $components[-2]
|
||||
|
||||
if not set -q ignore_bundle
|
||||
set bundle $path/bundle
|
||||
set dependencies
|
||||
|
||||
if test -f $bundle
|
||||
set -l IFS ' '
|
||||
while read -l type dependency
|
||||
test "$type" != package
|
||||
and continue
|
||||
require "$dependency"
|
||||
set dependencies $dependencies $dependency
|
||||
end < $bundle
|
||||
end
|
||||
end
|
||||
|
||||
source $init $path
|
||||
emit init_$package $path
|
||||
|
||||
set -g omf_init_path $omf_init_path $path
|
||||
emit perf:timer:finish $init
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
|
|
@ -1,28 +1,26 @@
|
|||
function init -a path --on-event init_omf
|
||||
set -g OMF_MISSING_ARG 1
|
||||
set -g OMF_UNKNOWN_OPT 2
|
||||
set -g OMF_INVALID_ARG 3
|
||||
set -g OMF_UNKNOWN_ERR 4
|
||||
set -g OMF_MISSING_ARG 1
|
||||
set -g OMF_UNKNOWN_OPT 2
|
||||
set -g OMF_INVALID_ARG 3
|
||||
set -g OMF_UNKNOWN_ERR 4
|
||||
|
||||
function omf::em
|
||||
set_color $fish_color_match ^/dev/null; or set_color cyan
|
||||
end
|
||||
|
||||
function omf::dim
|
||||
set_color $fish_color_autosuggestion ^/dev/null; or set_color 555
|
||||
end
|
||||
|
||||
function omf::err
|
||||
set_color $fish_color_error ^/dev/null; or set_color red --bold
|
||||
end
|
||||
|
||||
function omf::under
|
||||
set_color --underline
|
||||
end
|
||||
|
||||
function omf::off
|
||||
set_color normal
|
||||
end
|
||||
|
||||
autoload $path/functions/{compat,core,packages,themes,bundle,util,repo,cli,search}
|
||||
function omf::em
|
||||
set_color $fish_color_match ^/dev/null; or set_color cyan
|
||||
end
|
||||
|
||||
function omf::dim
|
||||
set_color $fish_color_autosuggestion ^/dev/null; or set_color 555
|
||||
end
|
||||
|
||||
function omf::err
|
||||
set_color $fish_color_error ^/dev/null; or set_color red --bold
|
||||
end
|
||||
|
||||
function omf::under
|
||||
set_color --underline
|
||||
end
|
||||
|
||||
function omf::off
|
||||
set_color normal
|
||||
end
|
||||
|
||||
autoload $path/functions/{compat,core,packages,themes,bundle,util,repo,cli}
|
||||
|
|
|
@ -1 +1,7 @@
|
|||
# See → fishshell.com/docs/current/commands.html#complete
|
||||
# Always provide completions for command line utilities.
|
||||
#
|
||||
# Check Fish documentation about completions:
|
||||
# http://fishshell.com/docs/current/commands.html#complete
|
||||
#
|
||||
# If your package doesn't provide any command line utility,
|
||||
# feel free to remove completions directory from the project.
|
|
@ -1,10 +1,3 @@
|
|||
# SYNOPSIS
|
||||
# {{NAME}} [options]
|
||||
#
|
||||
# USAGE
|
||||
# Options
|
||||
#
|
||||
|
||||
function {{NAME}} -d "My package"
|
||||
# Package entry-point
|
||||
end
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
function init -a path --on-event init_{{NAME}}
|
||||
end
|
||||
|
||||
# {{NAME}} initialization hook
|
||||
#
|
||||
# You can use the following variables in this file:
|
||||
# * $package package name
|
||||
# * $path package path
|
||||
# * $dependencies package dependencies
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
function uninstall --on-event uninstall_{{NAME}}
|
||||
end
|
||||
|
||||
# {{NAME}} uninstall hook
|
||||
#
|
||||
# You can use this file to do custom cleanup when the package is uninstalled.
|
||||
# You can use the variable $path to access the package path.
|
||||
|
|
|
@ -1,12 +1,3 @@
|
|||
# Set global color styles, for example:
|
||||
#
|
||||
# function {{NAME}}_error
|
||||
# set_color -o red
|
||||
# end
|
||||
#
|
||||
# function {{NAME}}_normal
|
||||
# set_color normal
|
||||
#
|
||||
|
||||
function fish_greeting
|
||||
# Customize fish greeting message
|
||||
end
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
function fish_prompt
|
||||
set -l code $status
|
||||
prompt_pwd
|
||||
# Customize fish prompt
|
||||
end
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
function fish_right_prompt
|
||||
set -l code $status
|
||||
# Customize the right prompt
|
||||
end
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
function fish_title
|
||||
# Customize the title bar of the terminal window.
|
||||
# Customize terminal window title
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue
Block a user