Compare commits
50 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
a4cc5d9b9c | |
|
|
b5a3526f8a | |
|
|
23c9863c97 | |
|
|
b6630684fb | |
|
|
815a099805 | |
|
|
3d20bc0ade | |
|
|
182c7cd83d | |
|
|
af9565fa95 | |
|
|
6c499b1441 | |
|
|
cbd08e5258 | |
|
|
b36722bfe6 | |
|
|
61381e2ba0 | |
|
|
da637930bc | |
|
|
c20336ee60 | |
|
|
f50f314c98 | |
|
|
459eadfae4 | |
|
|
ada07e10d6 | |
|
|
f52525abd1 | |
|
|
70484e221f | |
|
|
eb11cfbe1a | |
|
|
3d35555ef7 | |
|
|
cf036bd26c | |
|
|
2eaecf17a0 | |
|
|
3732144c33 | |
|
|
a2bc77f229 | |
|
|
29e8841a3d | |
|
|
ab361c86b4 | |
|
|
3204b5a39d | |
|
|
9cb43cfd1f | |
|
|
a396afc2c4 | |
|
|
359462b075 | |
|
|
2903d288e2 | |
|
|
d9ba9c8232 | |
|
|
bf963e67ab | |
|
|
b323cd8396 | |
|
|
75bca38fb1 | |
|
|
edab526dd0 | |
|
|
3864d3b9b9 | |
|
|
805b41ed58 | |
|
|
cece8f6464 | |
|
|
b087119333 | |
|
|
81d82e05a2 | |
|
|
5291529e6f | |
|
|
067dec167d | |
|
|
2b33fbe527 | |
|
|
6f488b266d | |
|
|
09aa1485b1 | |
|
|
d66d4b80e0 | |
|
|
bbb0953209 | |
|
|
861dd6c22c |
|
|
@ -0,0 +1,146 @@
|
||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [0.0.10] - 2024-06-09
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
- Runtime is now optional
|
||||||
|
- [**breaking**] `init.lua` configuration is now a `mkNeovimPkg`'s option
|
||||||
|
- Add option init config object to generate `init.lua`
|
||||||
|
|
||||||
|
### Miscellaneous Tasks
|
||||||
|
|
||||||
|
- Add alejandra to nix shell
|
||||||
|
|
||||||
|
## [0.0.9] - 2024-06-09
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
- Sloth command has now completion
|
||||||
|
- Add describe subcommand
|
||||||
|
- Introduce mkPluginsFromInputs function
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- Init/config are loaded to on-the-fly build plugins
|
||||||
|
- Plugins with init are now loaded as they should be
|
||||||
|
|
||||||
|
### Refactor
|
||||||
|
|
||||||
|
- Filters are now fully dynamic
|
||||||
|
|
||||||
|
### Miscellaneous Tasks
|
||||||
|
|
||||||
|
- Remove sourcesWith fn, using lib.fileset
|
||||||
|
- Move back to flake-utils
|
||||||
|
|
||||||
|
## [0.0.8] - 2024-06-04
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
- Can load lazy plugins on events
|
||||||
|
- Can load lazy plugins on keymaps
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- Move files instead of copying them
|
||||||
|
- Sloth list was broken since refactoring
|
||||||
|
|
||||||
|
### Miscellaneous Tasks
|
||||||
|
|
||||||
|
- Switch from nixpkgs `23.11` to `unstable`
|
||||||
|
|
||||||
|
## [0.0.7] - 2024-06-03
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
- Add `version` Sloth subcommand
|
||||||
|
- Add `viAlias` and `vimAlias` mkNeovimPkg options
|
||||||
|
- Add `vimdiffAlias` and `nvimdiffAlias` mkNeovimPkg options
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- Init function is called before plugin is loaded
|
||||||
|
|
||||||
|
### Documentation
|
||||||
|
|
||||||
|
- Fix url in the import example
|
||||||
|
|
||||||
|
### Refactor
|
||||||
|
|
||||||
|
- Extract all dep logic in Dep object
|
||||||
|
- Extract Sloth command code in its own module
|
||||||
|
- Split Sloth subcommands in their own files
|
||||||
|
- Deps provides accessors via metatables
|
||||||
|
- Deps are now loaded via a FSM
|
||||||
|
|
||||||
|
## [0.0.6] - 2024-05-30
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
- Can load lazy plugins
|
||||||
|
- Can load lazy plugins via placeholder `cmd`s
|
||||||
|
- Loading plugins respect dependencies option
|
||||||
|
- Can load lazy plugins on FileType autocommand
|
||||||
|
- Introduce new Sloth command with list subcommand
|
||||||
|
- Add `Sloth load` subcommand
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- Prevent `setup` function to be called twice
|
||||||
|
|
||||||
|
### Refactor
|
||||||
|
|
||||||
|
- Plugin normalization
|
||||||
|
|
||||||
|
### Miscellaneous Tasks
|
||||||
|
|
||||||
|
- Delete dead code
|
||||||
|
- Add CHANGELOG with `git-cliff`
|
||||||
|
|
||||||
|
## [0.0.5] - 2024-05-28
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
- Add real documentation
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- Give default init.lua if none provided
|
||||||
|
- Remove namePrefix and nameSuffix
|
||||||
|
|
||||||
|
### Miscellaneous Tasks
|
||||||
|
|
||||||
|
- Refactor lua generation
|
||||||
|
- Remove dead code
|
||||||
|
|
||||||
|
## [0.0.4] - 2024-05-28
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
- Generating plugins lua definition from nix
|
||||||
|
- Simplify lua api
|
||||||
|
|
||||||
|
## [0.0.3] - 2024-05-26
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
- Rename neofalke to sloth-flake.nvim
|
||||||
|
- Check inputs of functions with yants
|
||||||
|
|
||||||
|
## [0.0.2] - 2024-05-26
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
- Can give dependencies to new package
|
||||||
|
- Can build package with all config
|
||||||
|
- Remove neovim from nix-shell
|
||||||
|
- Neoflake and runtime plugin have their version
|
||||||
|
|
||||||
|
### Miscellaneous Tasks
|
||||||
|
|
||||||
|
- Release v0.0.2
|
||||||
|
|
||||||
|
<!-- generated by git-cliff -->
|
||||||
342
README.md
342
README.md
|
|
@ -1,15 +1,335 @@
|
||||||
# TODO
|
# sloth-flake.nvim
|
||||||
|
|
||||||
## MVP
|
A [neovim] plugin and configuration management plugin, highly inspired by [lazy], using [nix].
|
||||||
|
|
||||||
- [X] Find a way to handle local plugins (like spos.nvim)
|
<!-- TOC GFM -->
|
||||||
- [X] Generate static init.nvim file
|
|
||||||
|
|
||||||
## Backlog
|
- [Description](#description)
|
||||||
|
- [Features](#features)
|
||||||
|
- [SemVer](#semver)
|
||||||
|
- [Installation](#installation)
|
||||||
|
- [Flake installation](#flake-installation)
|
||||||
|
- [Usage](#usage)
|
||||||
|
- [Documentation](#documentation)
|
||||||
|
- [nix](#nix)
|
||||||
|
- [`mkPluginsFromInputs`](#mkpluginsfrominputs)
|
||||||
|
- [`mkNeovimPkg`](#mkneovimpkg)
|
||||||
|
- [neovim (lua)](#neovim-lua)
|
||||||
|
- [Using default `init.lua`](#using-default-initlua)
|
||||||
|
- [Using your own `init.lua`](#using-your-own-initlua)
|
||||||
|
- [`:Sloth` command](#sloth-command)
|
||||||
|
- [`list` subcommand](#list-subcommand)
|
||||||
|
- [`load` subcommand](#load-subcommand)
|
||||||
|
- [`version` subcommand](#version-subcommand)
|
||||||
|
- [API](#api)
|
||||||
|
|
||||||
- [ ] handle dependencies
|
<!-- TOC -->
|
||||||
- [ ] Explore how lazy load plugins
|
|
||||||
- [ ] load manual plugins
|
## Description
|
||||||
- [ ] play with hm dag
|
|
||||||
- [ ] respect dependencies in loading
|
> `sloth-flake.nvim` is an alpha software. Please use caution when using it.
|
||||||
- [ ] Generate spell files on build ?
|
|
||||||
|
`sloth-flake.nvim` is both
|
||||||
|
- a [neovim] plugin to manage your plugins
|
||||||
|
- a [nix] flake to build your neovim package with your own configuration and plugins.
|
||||||
|
|
||||||
|
> :information_source: If you never heard of [nix] or you never used it, then this plugin is not for you.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- [X] Declare your plugin via `nix` files
|
||||||
|
- [X] Declare nix package as dependencies
|
||||||
|
- [X] Generate nix package from local files
|
||||||
|
- [X] Generate default `init.lua`
|
||||||
|
- [X] Accepts your own `init.lua`
|
||||||
|
- [X] Lazy load your plugins
|
||||||
|
- [X] on command
|
||||||
|
- [X] on filetype
|
||||||
|
- [X] on event
|
||||||
|
- [X] on keybinding
|
||||||
|
- [X] load plugins in order (via plugin `dependencies` property)
|
||||||
|
- [X] Have a `:Sloth` command to load or query your plugins
|
||||||
|
- [ ] Generate spell files on build (maybe)
|
||||||
|
|
||||||
|
## SemVer
|
||||||
|
|
||||||
|
This project will respect SemVer in the end, but will adopt a slightly different semantics in the beginning.
|
||||||
|
|
||||||
|
This project is considered alpha as long as the version is `0.0.x`, therefore
|
||||||
|
you can expect breaking change on each version. You can see the version as
|
||||||
|
`0.0.MAJOR`.
|
||||||
|
|
||||||
|
When this project will hit `0.1.0`, the project will be in beta phase. If a new
|
||||||
|
version have breaking change, then it will be `0.2.0` and `0.1.1` otherwise.
|
||||||
|
You can see the version as `0.MAJOR.MINOR`.
|
||||||
|
|
||||||
|
When this project will hit `1.0.0`, it will then follow full SemVer
|
||||||
|
(`MAJOR.MINOR.PATCH`).
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Only flake installation is supported.
|
||||||
|
|
||||||
|
### Flake installation
|
||||||
|
|
||||||
|
Import `sloth-flake.nvim` flake latest version:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
inputs.sloth-flake.url = "github:lemarsu/sloth-flake.nvim";
|
||||||
|
```
|
||||||
|
|
||||||
|
You can give a specific version:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
inputs.sloth-flake.url = "github:lemarsu/sloth-flake.nvim?tag=0.0.5";
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Once installed, you can call the `sloth-flake.lib.mkNeovimPkg` to build your neovim package.
|
||||||
|
|
||||||
|
`mkNeovimPkg` requires a *set* as argument with at least `pkgs` that represents your nixpkgs.
|
||||||
|
|
||||||
|
```nix
|
||||||
|
sloth-flake.lib.mkNeovimPkg {
|
||||||
|
inherit pkgs;
|
||||||
|
viAlias = true;
|
||||||
|
vimAlias = true;
|
||||||
|
runtime = {
|
||||||
|
version = "0.1";
|
||||||
|
src = sloth-flake.lib.sourcesWith ./. [
|
||||||
|
./after
|
||||||
|
./colors
|
||||||
|
./ftplugin
|
||||||
|
./lua
|
||||||
|
./plugin
|
||||||
|
./queries
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
rust-vim
|
||||||
|
vim-openscad
|
||||||
|
./lsp
|
||||||
|
{
|
||||||
|
plugin = telescope-nvim;
|
||||||
|
config = ./telescope.lua;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
### nix
|
||||||
|
|
||||||
|
#### `mkPluginsFromInputs`
|
||||||
|
|
||||||
|
`mkPluginsFromInputs` is a helper function that converts flake inputs (starting by `"plugin-"` by default) into vimPlugins.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||||
|
sloth-flake.url = "github:lemarsu/sloth-flake.nvim";
|
||||||
|
utils.url = "github:numtide/flake-utils";
|
||||||
|
|
||||||
|
plugin-base64 = {
|
||||||
|
url = "github:moevis/base64.nvim";
|
||||||
|
flake = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
plugin-cellular-automaton = {
|
||||||
|
url = "github:eandrju/cellular-automaton.nvim";
|
||||||
|
flake = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
outputs = {utils, sloth-flake, ...}@inputs: let
|
||||||
|
fu = utils.lib;
|
||||||
|
in fu.eachDefaultSystem (system: let
|
||||||
|
plugins = sloth-flake.lib.mkPluginsFromInputs {
|
||||||
|
inherit pkgs inputs;
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
packages = rec {
|
||||||
|
default = neovim;
|
||||||
|
neovim = pkgs.callPackage ./package.nix {
|
||||||
|
# By adding `plugins` here, we can use `with plugins; base64 cellular-automaton`,
|
||||||
|
inherit plugins sloth-flake;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The function accepts the following attributes:
|
||||||
|
|
||||||
|
- `pkgs` **REQUIRED** the nixpkgs set.
|
||||||
|
- `inputs` **REQUIRED** the inputs from a flake.
|
||||||
|
- `predicate` **optional** predicate to filter input by name. By default, it's
|
||||||
|
filter inputs with `hasPrefix "plugin-"`.
|
||||||
|
- `nameMap` **optional** function to change the key of the input in the resulting
|
||||||
|
set. By default, the 7 first letters are removed, so to remove the "plugin-"
|
||||||
|
prefix.
|
||||||
|
- `buildVimPlugin` **optional** function used to build the plugin. Defaults to
|
||||||
|
`pkgs.vimUtils.buildVimPlugin`.
|
||||||
|
|
||||||
|
#### `mkNeovimPkg`
|
||||||
|
|
||||||
|
`mkNeovimPkg` requires only the `pkgs` argument.
|
||||||
|
|
||||||
|
Here's a list of all accepted arguments
|
||||||
|
|
||||||
|
| name | default | description |
|
||||||
|
|-------------------------|-------------------------|---------------------------------------------------------------------|
|
||||||
|
| `pkgs` | N/A | The nixpkgs set. **REQUIRED** |
|
||||||
|
| `package` | `pkgs.neovim-unwrapped` | The unwrapped neovim package to use |
|
||||||
|
| `init` | `null` | The `init.lua` of your config (string, path or init config object)¹ |
|
||||||
|
| `runtime` | `{}` | Your Runtime configuration (see below) |
|
||||||
|
| `dependencies` | `[]` | A list of your dependencies (see below) |
|
||||||
|
| `dependenciesExtraArgs` | `{}` | Extra arguments to load your dependencies in other files |
|
||||||
|
| `extraLuaPackages` | `null` | Extra lua packages needed for the plugin |
|
||||||
|
| `viAlias` | `false` | Wether to create a `vi` alias to run neovim |
|
||||||
|
| `vimAlias` | `false` | Wether to create a `vim` alias to run neovim |
|
||||||
|
| `vimdiffAlias` | `false` | Wether to create a `vimdiff` alias to run neovim in diff mode |
|
||||||
|
| `nvimdiffAlias` | `false` | Wether to create a `nvimdiff` alias to run neovim in diff mode |
|
||||||
|
|
||||||
|
> ¹ If you give your own `init.lua` as string or path, you'll have to call `sloth-flake` lua plugin yourself. See more below.
|
||||||
|
|
||||||
|
The init configuration object accepts the following properties:
|
||||||
|
|
||||||
|
| name | default | description |
|
||||||
|
|------------|---------|----------------------------------------------------------------------------|
|
||||||
|
| `init` | `null` | Lua code call before plugins init. String or path. |
|
||||||
|
| `postInit` | `null` | Lua code call after plugins init and before plugin config. String or path. |
|
||||||
|
| `config` | `null` | Luas cod call after plugins config. String or path. |
|
||||||
|
|
||||||
|
The Runtime configuration object accepts the following properties:
|
||||||
|
|
||||||
|
| name | default | description |
|
||||||
|
|-----------|---------|--------------------------------|
|
||||||
|
| `version` | `null` | The version of your runtime |
|
||||||
|
| `src` | `null` | The content of your runtime |
|
||||||
|
|
||||||
|
The dependencies is a list of element of either:
|
||||||
|
- path: the path of the file to load other dependencies
|
||||||
|
- package: a nix package of a neovim/vim plugin
|
||||||
|
- Plugin configuration object: an object describing a plugin and its configuration.
|
||||||
|
|
||||||
|
The Plugin configuration object accepts the following properties:
|
||||||
|
|
||||||
|
| name | default | description |
|
||||||
|
|--------------------|---------|----------------------------------------------------------------|
|
||||||
|
| `plugin` | N/A | The plugin to load² **REQUIRED** |
|
||||||
|
| `init` | `null` | Lua code (as string of path) to call before loading the plugin |
|
||||||
|
| `config` | `null` | Lua code (as string of path) to call after loading the plugin |
|
||||||
|
| `dependencies` | `[]` | The plugin dependencies³ |
|
||||||
|
| `extraLuaPackages` | `null` | Extra lua packages needed for the plugin |
|
||||||
|
| `lazy` | `false` | Should the plugin be loaded lazily |
|
||||||
|
| `cmd` | `[]` | Command to put as place_holder to load the lazy plugin⁴ |
|
||||||
|
| `ft` | `[]` | Filetype to watch to load the lazy plugin⁴ |
|
||||||
|
| `events` | `[]` | Events to watch to load the lazy plugin⁴⁵ |
|
||||||
|
| `keymaps` | `[]` | Keymaps that when press will load the lazy plugin⁴⁶ |
|
||||||
|
|
||||||
|
> ² The plugin can be either a nix package or an object with only `name` and
|
||||||
|
> `src` as properties. The latter will be used to create a nix package of your
|
||||||
|
> plugin on the fly.
|
||||||
|
|
||||||
|
> ³ `nix` handles the installation of your plugin, therefore, this list is
|
||||||
|
> **NOT** to declare dependencies that the nix package of the plugin doesn't
|
||||||
|
> know. This will tell `sloth-flake` in what order your plugins should be
|
||||||
|
> loaded.
|
||||||
|
|
||||||
|
> ⁴ Setting this property implicitly set `lazy` to `true`.
|
||||||
|
|
||||||
|
> ⁵ Events can be a string, an Event object or a list of either. You can
|
||||||
|
> represent a simple event name and pattern with the following string format :
|
||||||
|
> "BufRead *.md".
|
||||||
|
|
||||||
|
> ⁶ Keymaps can be a string, an Keymap object or a list of either.
|
||||||
|
|
||||||
|
The Event configuration object accepts the following properties:
|
||||||
|
|
||||||
|
| name | default | description |
|
||||||
|
|-----------|---------|----------------------------------------------------------------|
|
||||||
|
| `name` | N/A | The name of the event as string or list of string **REQUIRED** |
|
||||||
|
| `pattern` | `null` | Pattern (as string or list of string) associated to the event |
|
||||||
|
|
||||||
|
The Keymap configuration object accepts the following properties:
|
||||||
|
|
||||||
|
| name | default | description |
|
||||||
|
|-----------|---------|----------------------------------------------------|
|
||||||
|
| `mode` | `"n"` | The mode of the keymap as string or list of string |
|
||||||
|
| `mapping` | N/A | The actual mapping **REQUIRED** |
|
||||||
|
|
||||||
|
### neovim (lua)
|
||||||
|
|
||||||
|
#### Using default `init.lua`
|
||||||
|
|
||||||
|
If your neovim configuration is only plugin configuration, `sloth-flake` will
|
||||||
|
give you a default `init.lua` that will load `sloth-flake` plugin that will, in
|
||||||
|
turn, load all your plugins. If you need more control over configuration
|
||||||
|
startup, please look at next section.
|
||||||
|
|
||||||
|
#### Using your own `init.lua`
|
||||||
|
|
||||||
|
You can provide your `init.lua`, but you must call `sloth-flake` your self.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
-- Requiring sloth-flake plugin
|
||||||
|
local sloth_flake = require 'sloth-flake'
|
||||||
|
|
||||||
|
-- Before this point, no plugin nor configuration is loaded
|
||||||
|
-- You can configure what you need before loading any plugin.
|
||||||
|
sloth_flake.setup {
|
||||||
|
-- This function is called after calling all optional `init` functions of your plugins
|
||||||
|
-- but before loading those plugins
|
||||||
|
post_init = function()
|
||||||
|
-- [...]
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
-- From here, your plugins are loaded and their optional `config` function called
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `:Sloth` command
|
||||||
|
|
||||||
|
`sloth-flake` give a `Sloth` command that you can call to gather some
|
||||||
|
informations about or load your plugins.
|
||||||
|
|
||||||
|
Usage: `Sloth [command] [args...]`
|
||||||
|
|
||||||
|
If no arguments are given, the `Sloth` command will call the `list` subcommand.
|
||||||
|
|
||||||
|
##### `list` subcommand
|
||||||
|
|
||||||
|
Summary: List plugins.
|
||||||
|
|
||||||
|
Usage: `Sloth list [filter]`
|
||||||
|
|
||||||
|
- `filter`: filter the list of plugins.
|
||||||
|
- `all`: list all declared plugins. Same as if no filter is given.
|
||||||
|
- `loaded`: list only loaded plugins.
|
||||||
|
- `notloaded`: list only not loaded plugins.
|
||||||
|
|
||||||
|
##### `load` subcommand
|
||||||
|
|
||||||
|
Summary: Load lazy plugins.
|
||||||
|
|
||||||
|
Usage: `Sloth load <plugin> [plugin [...]]`
|
||||||
|
- `plugin`: a plugin to load
|
||||||
|
|
||||||
|
##### `version` subcommand
|
||||||
|
|
||||||
|
Summary: Return Sloth version
|
||||||
|
|
||||||
|
Usage: `Sloth version`
|
||||||
|
|
||||||
|
#### API
|
||||||
|
|
||||||
|
The lua API is not really defined yet. This documentation will be completed then.
|
||||||
|
|
||||||
|
[neovim]: http://neovim.io/
|
||||||
|
[nix]: https://nixos.org
|
||||||
|
[lazy]: https://github.com/folke/lazy.nvim
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
# git-cliff ~ default configuration file
|
||||||
|
# https://git-cliff.org/docs/configuration
|
||||||
|
#
|
||||||
|
# Lines starting with "#" are comments.
|
||||||
|
# Configuration options are organized into tables and keys.
|
||||||
|
# See documentation for more information on available options.
|
||||||
|
|
||||||
|
[changelog]
|
||||||
|
# changelog header
|
||||||
|
header = """
|
||||||
|
# Changelog\n
|
||||||
|
All notable changes to this project will be documented in this file.\n
|
||||||
|
"""
|
||||||
|
# template for the changelog body
|
||||||
|
# https://keats.github.io/tera/docs/#introduction
|
||||||
|
body = """
|
||||||
|
{% if version %}\
|
||||||
|
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
|
||||||
|
{% else %}\
|
||||||
|
## [unreleased]
|
||||||
|
{% endif %}\
|
||||||
|
{% for group, commits in commits | group_by(attribute="group") %}
|
||||||
|
### {{ group | striptags | trim | upper_first }}
|
||||||
|
{% for commit in commits %}
|
||||||
|
- {% if commit.breaking %}[**breaking**] {% endif %}{{ commit.message | upper_first }}\
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}\n
|
||||||
|
"""
|
||||||
|
# remove the leading and trailing whitespace from the template
|
||||||
|
trim = true
|
||||||
|
# changelog footer
|
||||||
|
footer = """
|
||||||
|
<!-- generated by git-cliff -->
|
||||||
|
"""
|
||||||
|
# postprocessors
|
||||||
|
postprocessors = [
|
||||||
|
# { pattern = '<REPO>', replace = "https://github.com/orhun/git-cliff" }, # replace repository URL
|
||||||
|
]
|
||||||
|
[git]
|
||||||
|
# parse the commits based on https://www.conventionalcommits.org
|
||||||
|
conventional_commits = true
|
||||||
|
# filter out the commits that are not conventional
|
||||||
|
filter_unconventional = true
|
||||||
|
# process each line of a commit as an individual commit
|
||||||
|
split_commits = false
|
||||||
|
# regex for preprocessing the commit messages
|
||||||
|
commit_preprocessors = [
|
||||||
|
# { pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](<REPO>/issues/${2}))"}, # replace issue numbers
|
||||||
|
]
|
||||||
|
# regex for parsing and grouping commits
|
||||||
|
commit_parsers = [
|
||||||
|
{ message = "^feat", group = "<!-- 1 -->Features" },
|
||||||
|
{ message = "^fix", group = "<!-- 2 -->Bug Fixes" },
|
||||||
|
{ message = "^doc", group = "<!-- 3 -->Documentation" },
|
||||||
|
{ message = "^perf", group = "<!-- 4 -->Performance" },
|
||||||
|
{ message = "^refactor", group = "<!-- 5 -->Refactor" },
|
||||||
|
{ message = "^style", group = "<!-- 6 -->Styling" },
|
||||||
|
{ message = "^test", group = "<!-- 7 -->Testing" },
|
||||||
|
{ message = "^chore\\(release\\): prepare for", skip = true },
|
||||||
|
{ message = "^chore\\(deps\\)", skip = true },
|
||||||
|
{ message = "^chore\\(pr\\)", skip = true },
|
||||||
|
{ message = "^chore\\(pull\\)", skip = true },
|
||||||
|
{ message = "^chore: bump version", skip = true },
|
||||||
|
{ message = "^chore|ci", group = "<!-- 8 -->Miscellaneous Tasks" },
|
||||||
|
{ message = "^flake\\.lock: Update", skip = true },
|
||||||
|
{ body = ".*security", group = "<!-- 9 -->Security" },
|
||||||
|
{ message = "^revert", group = "<!-- 10 -->Revert" },
|
||||||
|
]
|
||||||
|
# protect breaking changes from being skipped due to matching a skipping commit_parser
|
||||||
|
protect_breaking_commits = false
|
||||||
|
# filter out the commits that are not matched by commit parsers
|
||||||
|
filter_commits = false
|
||||||
|
# regex for matching git tags
|
||||||
|
tag_pattern = "[0-9].*"
|
||||||
|
|
||||||
|
breaking_always_bump_major = false
|
||||||
|
|
||||||
|
# regex for skipping tags
|
||||||
|
skip_tags = "v0.1.0-beta.1"
|
||||||
|
# regex for ignoring tags
|
||||||
|
ignore_tags = ""
|
||||||
|
# sort the tags topologically
|
||||||
|
topo_order = false
|
||||||
|
# sort the commits inside sections by oldest/newest order
|
||||||
|
sort_commits = "oldest"
|
||||||
|
# limit the number of commits included in the changelog.
|
||||||
|
# limit_commits = 42
|
||||||
61
flake.lock
61
flake.lock
|
|
@ -63,24 +63,6 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-utils_2": {
|
|
||||||
"inputs": {
|
|
||||||
"systems": "systems_2"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1694529238,
|
|
||||||
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flakeCompat": {
|
"flakeCompat": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
|
|
@ -104,11 +86,11 @@
|
||||||
"rust-overlay": "rust-overlay"
|
"rust-overlay": "rust-overlay"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1714571717,
|
"lastModified": 1717086091,
|
||||||
"narHash": "sha256-o4tqlTzi9kcVub167kTGXgCac9jM3kW4+v9MH/ue4Hk=",
|
"narHash": "sha256-GmsEQa4HZeMfec37LZnwG/Lt/XmqFLXsjv5QWojeNiM=",
|
||||||
"owner": "oxalica",
|
"owner": "oxalica",
|
||||||
"repo": "nil",
|
"repo": "nil",
|
||||||
"rev": "2f3ed6348bbf1440fcd1ab0411271497a0fbbfa4",
|
"rev": "ab3ddb8f063774cf7e22eb610f5ecfdb77309f3c",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -119,11 +101,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1714314149,
|
"lastModified": 1716977081,
|
||||||
"narHash": "sha256-yNAevSKF4krRWacmLUsLK7D7PlfuY3zF0lYnGYNi9vQ=",
|
"narHash": "sha256-pFe5jLeIPlKEln5n2h998d7cpzXFdbrBMRe3suz4K1o=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "cf8cc1201be8bc71b7cbbbdaf349b22f4f99c7ae",
|
"rev": "ac82a513e55582291805d6f09d35b6d8b60637a1",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -135,16 +117,16 @@
|
||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1716633019,
|
"lastModified": 1717196966,
|
||||||
"narHash": "sha256-xim1b5/HZYbWaZKyI7cn9TJCM6ewNVZnesRr00mXeS4=",
|
"narHash": "sha256-yZKhxVIKd2lsbOqYd5iDoUIwsRZFqE87smE2Vzf6Ck0=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "9d29cd266cebf80234c98dd0b87256b6be0af44e",
|
"rev": "57610d2f8f0937f39dbd72251e9614b1561942d8",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"ref": "nixos-23.11",
|
"ref": "nixos-unstable",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
|
@ -202,11 +184,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1714529851,
|
"lastModified": 1717035469,
|
||||||
"narHash": "sha256-YMKJW880f7LHXVRzu93xa6Ek+QLECIu0IRQbXbzZe38=",
|
"narHash": "sha256-MzH+yjKULH3HCRj9QCTwBvqq4LZkR0ZqRE/QfGOGC2E=",
|
||||||
"owner": "oxalica",
|
"owner": "oxalica",
|
||||||
"repo": "rust-overlay",
|
"repo": "rust-overlay",
|
||||||
"rev": "9ca720fdcf7865385ae3b93ecdf65f1a64cb475e",
|
"rev": "095702e63a40e86f339d11864da9dc965b70a01e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -247,20 +229,19 @@
|
||||||
},
|
},
|
||||||
"utils": {
|
"utils": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-utils": "flake-utils_2"
|
"systems": "systems_2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1696281284,
|
"lastModified": 1710146030,
|
||||||
"narHash": "sha256-xcmtTmoiiAOSk4abifbtqVZk0iwBcqJfg47iUbkwhcE=",
|
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||||
"owner": "gytis-ivaskevicius",
|
"owner": "numtide",
|
||||||
"repo": "flake-utils-plus",
|
"repo": "flake-utils",
|
||||||
"rev": "6cf1e312fb259693c4930d07ca3cbe1d07ef4a48",
|
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "gytis-ivaskevicius",
|
"owner": "numtide",
|
||||||
"ref": "v1.4.0",
|
"repo": "flake-utils",
|
||||||
"repo": "flake-utils-plus",
|
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
39
flake.nix
39
flake.nix
|
|
@ -2,8 +2,8 @@
|
||||||
description = "My neovim configuration";
|
description = "My neovim configuration";
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11";
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||||
utils.url = "github:gytis-ivaskevicius/flake-utils-plus/v1.4.0";
|
utils.url = "github:numtide/flake-utils";
|
||||||
nil.url = "github:oxalica/nil";
|
nil.url = "github:oxalica/nil";
|
||||||
yants.url = "github:divnix/yants";
|
yants.url = "github:divnix/yants";
|
||||||
alejandra = {
|
alejandra = {
|
||||||
|
|
@ -20,24 +20,25 @@
|
||||||
yants,
|
yants,
|
||||||
...
|
...
|
||||||
} @ inputs: let
|
} @ inputs: let
|
||||||
versionFile = builtins.replaceStrings ["\n"] [""] (builtins.readFile ./VERSION);
|
inherit (builtins) readFile replaceStrings;
|
||||||
|
fu = utils.lib;
|
||||||
|
versionFile = replaceStrings ["\n"] [""] (readFile ./VERSION);
|
||||||
|
version =
|
||||||
|
if self.sourceInfo ? dirtyShortRev
|
||||||
|
then "${versionFile}-${self.sourceInfo.dirtyShortRev}"
|
||||||
|
else versionFile;
|
||||||
|
|
||||||
version = if self.sourceInfo ? dirtyShortRev
|
forSystem = system: let
|
||||||
then "${versionFile}-${self.sourceInfo.dirtyShortRev}"
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
else versionFile;
|
formatter = alejandra.defaultPackage.${system};
|
||||||
in
|
inherit (inputs.nil.packages.${system}) nil;
|
||||||
utils.lib.mkFlake {
|
in {
|
||||||
inherit self inputs;
|
inherit formatter;
|
||||||
outputsBuilder = channel: let
|
devShells.default = import ./shell.nix {
|
||||||
system = channel.nixpkgs.system;
|
inherit pkgs nil formatter;
|
||||||
in {
|
|
||||||
formatter = alejandra.defaultPackage.${channel.nixpkgs.system};
|
|
||||||
devShells.default = import ./shell.nix {
|
|
||||||
pkgs = channel.nixpkgs;
|
|
||||||
inherit (inputs.nil.packages.${system}) nil;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
lib = import ./lib {inherit version yants;};
|
|
||||||
};
|
};
|
||||||
|
in
|
||||||
|
(fu.eachDefaultSystem forSystem)
|
||||||
|
// {lib = import ./lib {inherit version yants;};};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
152
hm-file-type.nix
152
hm-file-type.nix
|
|
@ -1,152 +0,0 @@
|
||||||
# Imported from home-manager. Couldn't find another way to access it
|
|
||||||
{
|
|
||||||
homeDirectory,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
}: let
|
|
||||||
inherit
|
|
||||||
(lib)
|
|
||||||
hasPrefix
|
|
||||||
hm
|
|
||||||
literalExpression
|
|
||||||
mkDefault
|
|
||||||
mkIf
|
|
||||||
mkOption
|
|
||||||
removePrefix
|
|
||||||
types
|
|
||||||
;
|
|
||||||
in rec {
|
|
||||||
# Constructs a type suitable for a `home.file."specific/path"` like option. The
|
|
||||||
# target path may be either absolute or relative, in which case it
|
|
||||||
# is relative the `basePath` argument (which itself must be an
|
|
||||||
# absolute path).
|
|
||||||
#
|
|
||||||
# Arguments:
|
|
||||||
# - opt the name of the option, for self-references
|
|
||||||
# - basePathDesc docbook compatible description of the base path
|
|
||||||
# - basePath the file base path
|
|
||||||
fileTypeSubmodule = opt: basePathDesc: basePath:
|
|
||||||
types.submodule ({
|
|
||||||
name,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
options = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
description = ''
|
|
||||||
Whether this file should be generated. This option allows specific
|
|
||||||
files to be disabled.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
target = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
apply = p: let
|
|
||||||
absPath =
|
|
||||||
if hasPrefix "/" p
|
|
||||||
then p
|
|
||||||
else "${basePath}/${p}";
|
|
||||||
in
|
|
||||||
removePrefix (homeDirectory + "/") absPath;
|
|
||||||
defaultText = literalExpression "name";
|
|
||||||
description = ''
|
|
||||||
Path to target file relative to ${basePathDesc}.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
text = mkOption {
|
|
||||||
default = null;
|
|
||||||
type = types.nullOr types.lines;
|
|
||||||
description = ''
|
|
||||||
Text of the file. If this option is null then
|
|
||||||
[](#opt-${opt}._name_.source)
|
|
||||||
must be set.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
source = mkOption {
|
|
||||||
type = types.path;
|
|
||||||
description = ''
|
|
||||||
Path of the source file or directory. If
|
|
||||||
[](#opt-${opt}._name_.text)
|
|
||||||
is non-null then this option will automatically point to a file
|
|
||||||
containing that text.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
executable = mkOption {
|
|
||||||
type = types.nullOr types.bool;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Set the execute bit. If `null`, defaults to the mode
|
|
||||||
of the {var}`source` file or to `false`
|
|
||||||
for files created through the {var}`text` option.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
recursive = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
If the file source is a directory, then this option
|
|
||||||
determines whether the directory should be recursively
|
|
||||||
linked to the target location. This option has no effect
|
|
||||||
if the source is a file.
|
|
||||||
|
|
||||||
If `false` (the default) then the target
|
|
||||||
will be a symbolic link to the source directory. If
|
|
||||||
`true` then the target will be a
|
|
||||||
directory structure matching the source's but whose leafs
|
|
||||||
are symbolic links to the files of the source directory.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
onChange = mkOption {
|
|
||||||
type = types.lines;
|
|
||||||
default = "";
|
|
||||||
description = ''
|
|
||||||
Shell commands to run when file has changed between
|
|
||||||
generations. The script will be run
|
|
||||||
*after* the new files have been linked
|
|
||||||
into place.
|
|
||||||
|
|
||||||
Note, this code is always run when `recursive` is
|
|
||||||
enabled.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
force = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
visible = false;
|
|
||||||
description = ''
|
|
||||||
Whether the target path should be unconditionally replaced
|
|
||||||
by the managed file source. Warning, this will silently
|
|
||||||
delete the target regardless of whether it is a file or
|
|
||||||
link.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
|
||||||
target = mkDefault name;
|
|
||||||
source = mkIf (config.text != null) (mkDefault (pkgs.writeTextFile {
|
|
||||||
inherit (config) text;
|
|
||||||
executable = config.executable == true; # can be null
|
|
||||||
name = hm.strings.storeFileName name;
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
});
|
|
||||||
# Constructs a type suitable for a `home.file` like option. The
|
|
||||||
# target path may be either absolute or relative, in which case it
|
|
||||||
# is relative the `basePath` argument (which itself must be an
|
|
||||||
# absolute path).
|
|
||||||
#
|
|
||||||
# Arguments:
|
|
||||||
# - opt the name of the option, for self-references
|
|
||||||
# - basePathDesc docbook compatible description of the base path
|
|
||||||
# - basePath the file base path
|
|
||||||
fileTypeAttrSet = opt: basePathDesc: basePath:
|
|
||||||
types.attrsOf (fileTypeSubmodule opt basePathDesc basePath);
|
|
||||||
}
|
|
||||||
|
|
@ -1,18 +1,9 @@
|
||||||
{version, yants}: let
|
{
|
||||||
|
version,
|
||||||
|
yants,
|
||||||
|
}: let
|
||||||
types = import ./types.nix {inherit yants;};
|
types = import ./types.nix {inherit yants;};
|
||||||
in {
|
in {
|
||||||
mkNeovimPkg = import ./mkNeovimPkg.nix {inherit version types;};
|
mkNeovimPkg = import ./mkNeovimPkg.nix {inherit version types;};
|
||||||
|
mkPluginsFromInputs = import ./mkPluginsFromInputs.nix;
|
||||||
sourcesWith = path: paths: let
|
|
||||||
samePath = a: let a' = builtins.toString a; in b: a' == builtins.toString b;
|
|
||||||
isRoot = samePath "/";
|
|
||||||
isInPath = path: subPath:
|
|
||||||
if isRoot subPath
|
|
||||||
then false
|
|
||||||
else (samePath path subPath) || (isInPath path (builtins.dirOf subPath));
|
|
||||||
filter = src: _type: builtins.any (includePath: isInPath includePath src) paths;
|
|
||||||
in
|
|
||||||
builtins.path {
|
|
||||||
inherit path filter;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
139
lib/deps.nix
139
lib/deps.nix
|
|
@ -6,18 +6,29 @@
|
||||||
types,
|
types,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (builtins) isPath foldl';
|
inherit (builtins) foldl' isPath isList isString mapAttrs match elemAt;
|
||||||
inherit (lib.attrsets) attrNames optionalAttrs;
|
inherit (lib.attrsets) attrNames optionalAttrs;
|
||||||
inherit (lib.lists) concatMap optional;
|
inherit (lib.lists) concatMap;
|
||||||
inherit (lib.strings) concatStringsSep fileContents;
|
inherit (lib.strings) fileContents splitString;
|
||||||
lua = callPackage ./lua.nix {};
|
lua = callPackage ./lua.nix {};
|
||||||
|
|
||||||
callPackage = lib.callPackageWith (pkgs // dependenciesExtraArgs);
|
callPackage = lib.callPackageWith (pkgs // dependenciesExtraArgs);
|
||||||
|
|
||||||
|
hasMatch = pattern: str: isList (match pattern str);
|
||||||
|
wrapArray = value:
|
||||||
|
if isList value
|
||||||
|
then value
|
||||||
|
else [value];
|
||||||
|
|
||||||
defaultPlugin = {
|
defaultPlugin = {
|
||||||
enabled = true;
|
enabled = true;
|
||||||
init = null;
|
init = null;
|
||||||
config = null;
|
config = null;
|
||||||
|
dependencies = [];
|
||||||
|
lazy = false;
|
||||||
|
cmd = [];
|
||||||
|
ft = [];
|
||||||
|
events = [];
|
||||||
|
keymaps = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
remotePluginToNeovimPlugin = p:
|
remotePluginToNeovimPlugin = p:
|
||||||
|
|
@ -26,20 +37,64 @@
|
||||||
pname = name;
|
pname = name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
defaultKeymap = {mode = "n";};
|
||||||
|
normalizeKeymap = keymap: let
|
||||||
|
value = (
|
||||||
|
if isString keymap
|
||||||
|
then {mapping = keymap;}
|
||||||
|
else keymap
|
||||||
|
);
|
||||||
|
in
|
||||||
|
mapAttrs (_: wrapArray) (defaultKeymap // value);
|
||||||
|
normalizeKeymaps = keymaps:
|
||||||
|
if isList keymaps
|
||||||
|
then map normalizeKeymap keymaps
|
||||||
|
else [(normalizeKeymap keymaps)];
|
||||||
|
|
||||||
|
normalizeEvent = event: let
|
||||||
|
value =
|
||||||
|
if ! isString event
|
||||||
|
then event
|
||||||
|
else if ! hasMatch ".* .*" event
|
||||||
|
then {name = event;}
|
||||||
|
else let
|
||||||
|
part = elemAt (splitString " " event);
|
||||||
|
in {
|
||||||
|
name = part 0;
|
||||||
|
pattern = part 1;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
mapAttrs (_: wrapArray) value;
|
||||||
|
normalizeEvents = events:
|
||||||
|
if isList events
|
||||||
|
then map normalizeEvent events
|
||||||
|
else [(normalizeEvent events)];
|
||||||
|
|
||||||
withPluginDefaults = dep: defaultPlugin // dep;
|
withPluginDefaults = dep: defaultPlugin // dep;
|
||||||
normalizePlugin = d: let
|
normalizePlugin = d: let
|
||||||
dep = types.dependency d;
|
dep = types.dependency d;
|
||||||
p =
|
plugin =
|
||||||
if ! dep ? plugin
|
if ! dep ? plugin
|
||||||
then {plugin = dep;}
|
then {plugin = dep;}
|
||||||
else let
|
else let
|
||||||
inherit (dep) plugin;
|
inherit (dep) plugin;
|
||||||
in
|
in
|
||||||
if attrNames plugin == ["name" "src"]
|
if attrNames plugin == ["name" "src"]
|
||||||
then {plugin = remotePluginToNeovimPlugin plugin;}
|
then dep // {plugin = remotePluginToNeovimPlugin plugin;}
|
||||||
else dep;
|
else dep;
|
||||||
|
p = withPluginDefaults plugin;
|
||||||
in
|
in
|
||||||
withPluginDefaults p;
|
p
|
||||||
|
// rec {
|
||||||
|
hasCommands = p.cmd != [];
|
||||||
|
hasFileTypes = p.ft != [];
|
||||||
|
keymaps = normalizeKeymaps p.keymaps;
|
||||||
|
hasKeymaps = p.keymaps != [];
|
||||||
|
events = normalizeEvents p.events;
|
||||||
|
hasEvents = p.events != [];
|
||||||
|
lazy = p.lazy || hasCommands || hasFileTypes || hasEvents || hasKeymaps;
|
||||||
|
optional = lazy || p.init != null;
|
||||||
|
};
|
||||||
|
|
||||||
normalizeOrImportPlugin = dep:
|
normalizeOrImportPlugin = dep:
|
||||||
if isPath dep
|
if isPath dep
|
||||||
|
|
@ -63,55 +118,36 @@
|
||||||
pname = "runtime";
|
pname = "runtime";
|
||||||
}));
|
}));
|
||||||
|
|
||||||
mkSlothFlakePlugin = version: plugins: let
|
mkSlothFlakePlugin = version: plugins:
|
||||||
getLua = type: p: let
|
|
||||||
content = p.${type};
|
|
||||||
textContent = textOrContent content;
|
|
||||||
pluginName =
|
|
||||||
if p.plugin ? name
|
|
||||||
then p.plugin.name
|
|
||||||
else baseNameOf p.plugin;
|
|
||||||
in
|
|
||||||
optional (! isNull content)
|
|
||||||
(lua.wrapSelfInvokingFunction {
|
|
||||||
section = "${type} for ${pluginName}";
|
|
||||||
lua = textContent;
|
|
||||||
});
|
|
||||||
|
|
||||||
getAllLua = type:
|
|
||||||
concatStringsSep "\n"
|
|
||||||
(concatMap (getLua type) plugins);
|
|
||||||
in
|
|
||||||
vimUtils.buildVimPlugin {
|
vimUtils.buildVimPlugin {
|
||||||
inherit version;
|
inherit version;
|
||||||
pname = "sloth-flake";
|
pname = "sloth-flake";
|
||||||
src = ../lua/sloth-flake;
|
src = with lib.fileset;
|
||||||
|
toSource {
|
||||||
|
root = ../.;
|
||||||
|
fileset = ../lua/sloth-flake;
|
||||||
|
};
|
||||||
buildPhase = ''
|
buildPhase = ''
|
||||||
dir=lua/sloth-flake
|
dir=lua/sloth-flake
|
||||||
mkdir -p $dir
|
|
||||||
mv init.lua $dir
|
|
||||||
|
|
||||||
cat <<'LUA' > $dir/initialize.lua
|
cat <<'LUA' > $dir/dependencies.lua
|
||||||
${lua.wrapReturnFunction (getAllLua "init")}
|
${pluginsLuaDef plugins}
|
||||||
LUA
|
LUA
|
||||||
|
|
||||||
cat <<'LUA' > $dir/config.lua
|
cat <<'LUA' > $dir/version.lua
|
||||||
${lua.wrapReturnFunction (getAllLua "config")}
|
${versionLua version}
|
||||||
LUA
|
|
||||||
|
|
||||||
cat <<'LUA' > $dir/deps.lua
|
|
||||||
return ${pluginsLuaDef plugins}
|
|
||||||
LUA
|
LUA
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
versionLua = version: with lua; nix2lua (return (lambda (return version)));
|
||||||
|
|
||||||
textOrContent = content:
|
textOrContent = content:
|
||||||
if isPath content
|
if isPath content
|
||||||
then fileContents content
|
then fileContents content
|
||||||
else content;
|
else content;
|
||||||
|
|
||||||
pluginLuaDef = memo: plugin: let
|
pluginLuaDef = memo: plugin: let
|
||||||
# plugin = builtins.removeAttrs plugin ["dependencies" "plugin"];
|
|
||||||
mkTypeFn = type: let
|
mkTypeFn = type: let
|
||||||
content = textOrContent plugin.${type};
|
content = textOrContent plugin.${type};
|
||||||
in
|
in
|
||||||
|
|
@ -122,24 +158,39 @@
|
||||||
if plugin ? pname
|
if plugin ? pname
|
||||||
then plugin.pname
|
then plugin.pname
|
||||||
else plugin.name;
|
else plugin.name;
|
||||||
hasDeps = plugin ? dependencies && plugin.dependencies != [];
|
|
||||||
name = pluginName plugin.plugin;
|
name = pluginName plugin.plugin;
|
||||||
in
|
in
|
||||||
memo
|
memo
|
||||||
// {
|
// {
|
||||||
${name} =
|
${name} =
|
||||||
{name = pluginName plugin.plugin;}
|
{
|
||||||
|
name = pluginName plugin.plugin;
|
||||||
|
dependencies = map pluginName plugin.dependencies;
|
||||||
|
}
|
||||||
// (mkTypeFn "init")
|
// (mkTypeFn "init")
|
||||||
// (mkTypeFn "config")
|
// (mkTypeFn "config")
|
||||||
// (optionalAttrs hasDeps {
|
// (optionalAttrs plugin.lazy {
|
||||||
dependencies = map pluginName plugin.dependencies;
|
lazy = true;
|
||||||
|
})
|
||||||
|
// (optionalAttrs plugin.hasCommands {
|
||||||
|
inherit (plugin) cmd;
|
||||||
|
})
|
||||||
|
// (optionalAttrs plugin.hasFileTypes {
|
||||||
|
inherit (plugin) ft;
|
||||||
|
})
|
||||||
|
// (optionalAttrs plugin.hasEvents {
|
||||||
|
inherit (plugin) events;
|
||||||
|
})
|
||||||
|
// (optionalAttrs plugin.hasKeymaps {
|
||||||
|
inherit (plugin) keymaps;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
pluginsLuaDef = plugins: lua.nix2lua (foldl' pluginLuaDef {} plugins);
|
pluginsLuaDef = plugins:
|
||||||
|
with lua; nix2lua (return (foldl' pluginLuaDef {} plugins));
|
||||||
in {
|
in {
|
||||||
|
inherit normalizePlugin;
|
||||||
inherit normalizePlugins;
|
inherit normalizePlugins;
|
||||||
inherit mkSlothFlakePlugin;
|
inherit mkSlothFlakePlugin;
|
||||||
inherit mkRuntimePlugin;
|
inherit mkRuntimePlugin;
|
||||||
inherit textOrContent;
|
inherit textOrContent;
|
||||||
inherit pluginsLuaDef;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
157
lib/lua.nix
157
lib/lua.nix
|
|
@ -1,95 +1,92 @@
|
||||||
{lib, ...}: let
|
{...}: let
|
||||||
inherit (lib.strings) removeSuffix;
|
inherit (builtins) match isNull typeOf concatStringsSep attrNames concatMap;
|
||||||
inherit (builtins) match;
|
|
||||||
handleAst = data: let
|
commaJoin = concatStringsSep ", ";
|
||||||
ast = data.__ast;
|
wrapNotNull' = val: value:
|
||||||
in
|
if isNull val
|
||||||
if ast == "raw"
|
then []
|
||||||
then data.data
|
else [value];
|
||||||
else if ast == "return"
|
wrapNotNull = val: wrapNotNull' val val;
|
||||||
# TODO nix2lua can return null
|
|
||||||
then "return ${nix2lua data.data}"
|
toLua = {
|
||||||
else if ast == "fn"
|
ast = {
|
||||||
then "function ${data.name}()\n${nix2lua data.data}\nend"
|
raw = {data, ...}: data;
|
||||||
else abort ''Unknown ast type ${ast.__ast}'';
|
return = {data, ...}: "return ${nix2lua data}";
|
||||||
|
fn = {
|
||||||
|
data,
|
||||||
|
name,
|
||||||
|
args,
|
||||||
|
...
|
||||||
|
}: "function ${name}(${commaJoin args})\n${nix2lua data}\nend";
|
||||||
|
};
|
||||||
|
|
||||||
|
type = rec {
|
||||||
|
null = _: "nil";
|
||||||
|
string = data: ''"${data}"'';
|
||||||
|
path = string;
|
||||||
|
lambda = data: builtins.trace "Skipping function" null;
|
||||||
|
int = data: toString data;
|
||||||
|
|
||||||
|
bool = data:
|
||||||
|
if data
|
||||||
|
then "true"
|
||||||
|
else "false";
|
||||||
|
|
||||||
|
ast = data: let
|
||||||
|
astType = data.__ast;
|
||||||
|
in
|
||||||
|
if toLua.ast ? ${astType}
|
||||||
|
then toLua.ast.${astType} data
|
||||||
|
else abort ''Unknown ast type ${astType}'';
|
||||||
|
|
||||||
|
list = data: let
|
||||||
|
nix2luaList = val: wrapNotNull (nix2lua val);
|
||||||
|
listContent = commaJoin (concatMap nix2luaList data);
|
||||||
|
in "{ ${listContent} }";
|
||||||
|
|
||||||
|
set = data: let
|
||||||
|
mkKeyValue = key: let
|
||||||
|
value = data.${key};
|
||||||
|
luaKey =
|
||||||
|
if isNull (match "[a-zA-Z_][a-zA-Z_0-9]+" key)
|
||||||
|
then ''["${key}"]''
|
||||||
|
else key;
|
||||||
|
luaValue = nix2lua value;
|
||||||
|
in
|
||||||
|
wrapNotNull' luaValue ''
|
||||||
|
${luaKey} = ${luaValue},
|
||||||
|
'';
|
||||||
|
attrsContent = concatMap mkKeyValue (attrNames data);
|
||||||
|
in ''
|
||||||
|
{
|
||||||
|
${concatStringsSep "" attrsContent}}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
newAst = type: set: set // {__ast = type;};
|
||||||
|
|
||||||
nix2lua = data: let
|
nix2lua = data: let
|
||||||
inherit (builtins) isInt isBool isNull isString isList isPath isAttrs isFunction typeOf concatStringsSep attrNames concatMap;
|
|
||||||
type = typeOf data;
|
type = typeOf data;
|
||||||
condValue2list = val: value:
|
|
||||||
if isNull val
|
|
||||||
then []
|
|
||||||
else [value];
|
|
||||||
value2list = val: condValue2list val val;
|
|
||||||
in
|
in
|
||||||
if data ? __ast
|
if data ? __ast
|
||||||
then handleAst data
|
then toLua.type.ast data
|
||||||
else if isInt data
|
else if toLua.type ? ${type}
|
||||||
then toString data
|
then toLua.type.${type} data
|
||||||
else if isBool data
|
|
||||||
then
|
|
||||||
if data
|
|
||||||
then "true"
|
|
||||||
else "false"
|
|
||||||
else if isString data || isPath data
|
|
||||||
then ''"${data}"''
|
|
||||||
else if isNull data
|
|
||||||
then "nil"
|
|
||||||
else if isFunction data
|
|
||||||
then (builtins.trace "Skipping function" null)
|
|
||||||
else if isList data
|
|
||||||
then let
|
|
||||||
nix2luaList = val: value2list (nix2lua val);
|
|
||||||
listContent = concatStringsSep ", " (concatMap nix2luaList data);
|
|
||||||
in "{ ${listContent} }"
|
|
||||||
else if isAttrs data
|
|
||||||
then let
|
|
||||||
mkKeyValue = key: let
|
|
||||||
value = data.${key};
|
|
||||||
luaKey =
|
|
||||||
if isNull (match "[a-zA-Z_][a-zA-Z_0-9]+" key)
|
|
||||||
then ''["${key}"]''
|
|
||||||
else key;
|
|
||||||
luaValue = nix2lua value;
|
|
||||||
in
|
|
||||||
# TODO Handle indentifier keys
|
|
||||||
condValue2list luaValue ''
|
|
||||||
${luaKey} = ${luaValue},
|
|
||||||
'';
|
|
||||||
attrsContent = concatMap mkKeyValue (attrNames data);
|
|
||||||
in ''
|
|
||||||
{
|
|
||||||
${concatStringsSep "" attrsContent}}
|
|
||||||
''
|
|
||||||
else abort ''Type "${type}"'';
|
else abort ''Type "${type}"'';
|
||||||
in rec {
|
in rec {
|
||||||
inherit nix2lua;
|
inherit nix2lua;
|
||||||
|
|
||||||
wrapFunction = content: "function()\n${content}\nend";
|
raw = data: newAst "raw" {inherit data;};
|
||||||
wrapReturnFunction = content: "return ${wrapFunction content}";
|
|
||||||
wrapSelfInvokingFunction = {
|
|
||||||
section,
|
|
||||||
lua,
|
|
||||||
}: ''
|
|
||||||
-- begin ${section}
|
|
||||||
(${wrapFunction (removeSuffix "\n" lua)})();
|
|
||||||
-- end ${section}
|
|
||||||
'';
|
|
||||||
|
|
||||||
raw = data: {
|
functionWithArgs = name: args: data:
|
||||||
inherit data;
|
newAst "fn" {
|
||||||
__ast = "raw";
|
inherit name data args;
|
||||||
};
|
};
|
||||||
|
|
||||||
function = name: data: {
|
function = name: data: functionWithArgs name [] data;
|
||||||
inherit name data;
|
|
||||||
__ast = "fn";
|
|
||||||
};
|
|
||||||
|
|
||||||
lambda = function "";
|
lambda = function "";
|
||||||
|
|
||||||
return = data: {
|
return = data: newAst "return" {inherit data;};
|
||||||
inherit data;
|
|
||||||
__ast = "return";
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,41 +4,112 @@
|
||||||
}: {
|
}: {
|
||||||
pkgs,
|
pkgs,
|
||||||
package ? pkgs.neovim-unwrapped,
|
package ? pkgs.neovim-unwrapped,
|
||||||
namePrefix ? "",
|
|
||||||
nameSuffix ? "",
|
|
||||||
dependencies ? [],
|
dependencies ? [],
|
||||||
dependenciesExtraArgs ? {},
|
dependenciesExtraArgs ? {},
|
||||||
runtime ? {},
|
extraLuaPackages ? (_: []),
|
||||||
|
runtime ? null,
|
||||||
|
init ? null,
|
||||||
|
viAlias ? false,
|
||||||
|
vimAlias ? false,
|
||||||
|
vimdiffAlias ? false,
|
||||||
|
nvimdiffAlias ? false,
|
||||||
...
|
...
|
||||||
} @ config: let
|
} @ config: let
|
||||||
inherit (builtins) map;
|
inherit (builtins) isString isPath map;
|
||||||
inherit (pkgs) callPackage;
|
inherit (pkgs) callPackage bash lib;
|
||||||
# inherit (lib.lists) concatMap filter foldl' map optional reverseList;
|
inherit (lib.strings) optionalString;
|
||||||
# inherit (lib.attrsets) attrNames optionalAttrs;
|
inherit (lib.lists) concatMap optional;
|
||||||
# inherit (lib.strings) concatStringsSep fileContents hasSuffix removePrefix removeSuffix replaceStrings;
|
inherit (lib.trivial) flip;
|
||||||
# inherit (lib.debug) traceIf traceSeq traceVal traceValSeq traceValFn;
|
inherit (lib.attrsets) optionalAttrs;
|
||||||
|
|
||||||
deps = callPackage ./deps.nix {inherit dependenciesExtraArgs types;};
|
deps = callPackage ./deps.nix {inherit dependenciesExtraArgs types;};
|
||||||
|
|
||||||
sloth-flake.plugin = deps.mkSlothFlakePlugin version plugins;
|
normalizedPlugins = deps.normalizePlugins dependencies;
|
||||||
runtimePlugin.plugin = deps.mkRuntimePlugin runtime;
|
sloth-flake = deps.mkSlothFlakePlugin version normalizedPlugins;
|
||||||
plugins = deps.normalizePlugins (dependencies ++ [runtimePlugin sloth-flake]);
|
runtimePlugin = deps.mkRuntimePlugin runtime;
|
||||||
|
plugins =
|
||||||
|
normalizedPlugins
|
||||||
|
++ (
|
||||||
|
deps.normalizePlugins
|
||||||
|
([sloth-flake] ++ (optional (runtime != null) runtimePlugin))
|
||||||
|
);
|
||||||
|
|
||||||
extractPlugin = map (p: p.plugin);
|
extractPlugin = p: {inherit (p) optional plugin;};
|
||||||
|
extractPlugins = map extractPlugin;
|
||||||
|
|
||||||
customRC = let
|
extractLuaPackageFn = plugin:
|
||||||
rc = ({init ? "", ...}: init) runtime;
|
optional (plugin ? extraLuaPackages) plugin.extraLuaPackages;
|
||||||
|
extractLuaPackagesFn = plugins: let
|
||||||
|
fnList = concatMap extractLuaPackageFn plugins;
|
||||||
|
concatPackages = ps: fn: fn ps;
|
||||||
in
|
in
|
||||||
deps.textOrContent rc;
|
ps: concatMap (concatPackages ps) fnList;
|
||||||
|
|
||||||
|
buildInit = {
|
||||||
|
init ? null,
|
||||||
|
postInit ? null,
|
||||||
|
config ? null,
|
||||||
|
}: let
|
||||||
|
initStr = optionalString (! isNull init) ''
|
||||||
|
(function()
|
||||||
|
${deps.textOrContent init}
|
||||||
|
end)();
|
||||||
|
|
||||||
|
'';
|
||||||
|
|
||||||
|
slothCall =
|
||||||
|
if isNull postInit
|
||||||
|
then "require('sloth-flake').setup {}"
|
||||||
|
else ''
|
||||||
|
require('sloth-flake').setup {
|
||||||
|
post_init = function()
|
||||||
|
${deps.textOrContent postInit}
|
||||||
|
end,
|
||||||
|
};
|
||||||
|
'';
|
||||||
|
|
||||||
|
configStr = optionalString (! isNull config) ''
|
||||||
|
|
||||||
|
(function()
|
||||||
|
${deps.textOrContent config}
|
||||||
|
end)()
|
||||||
|
'';
|
||||||
|
in ''
|
||||||
|
-- Generated by sloth-flake
|
||||||
|
${initStr}
|
||||||
|
${slothCall}
|
||||||
|
${configStr}
|
||||||
|
'';
|
||||||
|
|
||||||
|
customRC =
|
||||||
|
if isString init || isPath init
|
||||||
|
then deps.textOrContent init
|
||||||
|
else buildInit (optionalAttrs (! isNull init) init);
|
||||||
|
|
||||||
neovimConfig =
|
neovimConfig =
|
||||||
pkgs.neovimUtils.makeNeovimConfig {
|
pkgs.neovimUtils.makeNeovimConfig {
|
||||||
inherit customRC;
|
inherit customRC;
|
||||||
plugins = extractPlugin plugins;
|
plugins = extractPlugins plugins;
|
||||||
|
extraLuaPackages = ps:
|
||||||
|
(extractLuaPackagesFn plugins ps) ++ (extraLuaPackages ps);
|
||||||
}
|
}
|
||||||
// {luaRcContent = customRC;};
|
// {luaRcContent = customRC;};
|
||||||
pkg = pkgs.wrapNeovimUnstable package (removeAttrs neovimConfig ["manifestRc" "neovimRcContent"]);
|
params =
|
||||||
# TODO nameSuffix is buggy :'(
|
removeAttrs neovimConfig ["manifestRc" "neovimRcContent"]
|
||||||
name = "${namePrefix}${pkg.name}${nameSuffix}";
|
// {inherit viAlias vimAlias;};
|
||||||
|
pkg = pkgs.wrapNeovimUnstable package params;
|
||||||
|
mkDiffAlias = name:
|
||||||
|
(flip optionalString) ''
|
||||||
|
cat <<SH > $out/bin/${name}
|
||||||
|
#!${bash}/bin/bash
|
||||||
|
exec $out/bin/nvim -d "\''${@}"
|
||||||
|
SH
|
||||||
|
chmod 555 $out/bin/${name}
|
||||||
|
'';
|
||||||
in
|
in
|
||||||
builtins.seq (types.mkNeovimPkgOptions config) pkg // {inherit name;}
|
builtins.seq (types.mkNeovimPkgOptions config) (pkg.overrideAttrs (final: super: {
|
||||||
|
postBuild =
|
||||||
|
super.postBuild
|
||||||
|
+ (mkDiffAlias "vimdiff" vimdiffAlias)
|
||||||
|
+ (mkDiffAlias "nvimdiff" nvimdiffAlias);
|
||||||
|
}))
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
inputs,
|
||||||
|
predicate ? pkgs.lib.strings.hasPrefix "plugin-",
|
||||||
|
nameMap ? builtins.substring 7 (-1),
|
||||||
|
buildVimPlugin ? pkgs.vimUtils.buildVimPlugin,
|
||||||
|
}: let
|
||||||
|
inherit (builtins) attrNames filter foldl' mapAttrs;
|
||||||
|
names = filter predicate (attrNames inputs);
|
||||||
|
mkPlugin = m: k: let
|
||||||
|
name = nameMap k;
|
||||||
|
pluginDef = {
|
||||||
|
inherit name;
|
||||||
|
src = inputs.${k};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
m // {${name} = pluginDef;};
|
||||||
|
plugins = foldl' mkPlugin {} names;
|
||||||
|
in
|
||||||
|
mapAttrs (_: buildVimPlugin) plugins
|
||||||
|
|
@ -1,17 +1,30 @@
|
||||||
{yants, ...}: rec {
|
{yants, ...}: let
|
||||||
|
stringList = with yants; list string;
|
||||||
|
stringOrStringList = with yants; either string stringList;
|
||||||
|
stringOrStringListOr = type:
|
||||||
|
with yants;
|
||||||
|
option (eitherN [string type (list (either string type))]);
|
||||||
|
in rec {
|
||||||
# The runtime object
|
# The runtime object
|
||||||
runtimeType = with yants;
|
runtimeType = with yants;
|
||||||
struct "runtime" {
|
struct "runtime" {
|
||||||
# The version of the runtime
|
# The version of the runtime
|
||||||
version = option string;
|
version = option string;
|
||||||
|
|
||||||
# The init configuration file
|
|
||||||
init = option (either path string);
|
|
||||||
|
|
||||||
# The content of the runtime directory
|
# The content of the runtime directory
|
||||||
src = any;
|
src = any;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
neovimInitType = with yants;
|
||||||
|
struct "neovimInit" {
|
||||||
|
# Lua code to call before plugins loaded
|
||||||
|
init = option (either string path);
|
||||||
|
# Lua code called after init but before import
|
||||||
|
postInit = option (either string path);
|
||||||
|
# Lua code called after all plugins are loaded
|
||||||
|
config = option (either string path);
|
||||||
|
};
|
||||||
|
|
||||||
# As simple remote plugin definition
|
# As simple remote plugin definition
|
||||||
basicPluginType = with yants;
|
basicPluginType = with yants;
|
||||||
struct "basicPlugin" {
|
struct "basicPlugin" {
|
||||||
|
|
@ -22,9 +35,24 @@
|
||||||
src = any;
|
src = any;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
eventType = with yants;
|
||||||
|
struct "event" {
|
||||||
|
# The name of the event
|
||||||
|
name = stringOrStringList;
|
||||||
|
# The pattern of the event
|
||||||
|
pattern = stringOrStringList;
|
||||||
|
};
|
||||||
|
|
||||||
|
keymapType = with yants;
|
||||||
|
struct "keymap" {
|
||||||
|
# The mode of the keymap
|
||||||
|
mode = option stringOrStringList;
|
||||||
|
# The mapping of the keymap
|
||||||
|
mapping = stringOrStringList;
|
||||||
|
};
|
||||||
|
|
||||||
# The plugin type of dependencies
|
# The plugin type of dependencies
|
||||||
pluginType = with yants;
|
pluginType = with yants;
|
||||||
# let stringList = list string in
|
|
||||||
struct "plugin" {
|
struct "plugin" {
|
||||||
# Whether this plugin should be enabled. This option allows specific
|
# Whether this plugin should be enabled. This option allows specific
|
||||||
# plugins to be disabled.
|
# plugins to be disabled.
|
||||||
|
|
@ -44,20 +72,23 @@
|
||||||
# Ensure thoses plugins are loaded before the current one
|
# Ensure thoses plugins are loaded before the current one
|
||||||
dependencies = option (list drv);
|
dependencies = option (list drv);
|
||||||
|
|
||||||
|
# Ensure those packages are available
|
||||||
|
extraLuaPackages = option function;
|
||||||
|
|
||||||
# Should this plugin be load lazily ?
|
# Should this plugin be load lazily ?
|
||||||
# lazy = option bool;
|
lazy = option bool;
|
||||||
|
|
||||||
# List of events on which the plugin should be loaded
|
# List of events on which the plugin should be loaded
|
||||||
# events = option stringList;
|
events = option (stringOrStringListOr eventType);
|
||||||
|
|
||||||
# List of commands on which the plugin should be loaded
|
# List of commands on which the plugin should be loaded
|
||||||
# commands = option stringList;
|
cmd = option stringList;
|
||||||
|
|
||||||
# List of filetypes on which the plugin should be loaded
|
# List of filetypes on which the plugin should be loaded
|
||||||
# filetypes = option stringList;
|
ft = option stringList;
|
||||||
|
|
||||||
# List of keystrokes on which the plugin should be loaded
|
# List of keystrokes on which the plugin should be loaded
|
||||||
# keys = option stringList;
|
keymaps = option (stringOrStringListOr keymapType);
|
||||||
|
|
||||||
# Priority of the module. Influence the order of loading plugins.
|
# Priority of the module. Influence the order of loading plugins.
|
||||||
# Highest values get loaded before.
|
# Highest values get loaded before.
|
||||||
|
|
@ -77,19 +108,31 @@
|
||||||
# Default is pkgs.neovim-unwrapped
|
# Default is pkgs.neovim-unwrapped
|
||||||
package = option drv;
|
package = option drv;
|
||||||
|
|
||||||
# The prefix to add to the name of the package
|
# init.lua configuration
|
||||||
namePrefix = option string;
|
init = option (eitherN [string path neovimInitType]);
|
||||||
|
|
||||||
# The suffix to add to the name of the package
|
|
||||||
nameSuffix = option string;
|
|
||||||
|
|
||||||
# An array of dependencies.
|
# An array of dependencies.
|
||||||
dependencies = list dependency;
|
dependencies = option (list dependency);
|
||||||
|
|
||||||
# Extra argument to pass to dependencies files
|
# Extra argument to pass to dependencies files
|
||||||
dependenciesExtraArgs = attrs any;
|
dependenciesExtraArgs = option (attrs any);
|
||||||
|
|
||||||
|
# Ensure those packages are available
|
||||||
|
extraLuaPackages = option function;
|
||||||
|
|
||||||
# Runtime configuration
|
# Runtime configuration
|
||||||
runtime = runtimeType;
|
runtime = option runtimeType;
|
||||||
|
|
||||||
|
# Create a vi alias
|
||||||
|
viAlias = option bool;
|
||||||
|
|
||||||
|
# Create a vim alias
|
||||||
|
vimAlias = option bool;
|
||||||
|
|
||||||
|
# Create a vimdiff alias to run neovim in diff mode
|
||||||
|
vimdiffAlias = option bool;
|
||||||
|
|
||||||
|
# Create a nvimdiff alias to run neovim in diff mode
|
||||||
|
nvimdiffAlias = option bool;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
local Dep = require 'sloth-flake.dep'
|
||||||
|
local utils = require 'sloth-flake.utils'
|
||||||
|
|
||||||
|
local function yesno(value)
|
||||||
|
return value and "Yes" or "No"
|
||||||
|
end
|
||||||
|
|
||||||
|
local function list(items)
|
||||||
|
if items == nil or #items == 0 then
|
||||||
|
return "None"
|
||||||
|
end
|
||||||
|
return vim.iter(items):join(', ')
|
||||||
|
end
|
||||||
|
|
||||||
|
local function describe(dep)
|
||||||
|
utils.info('Name: %s', dep.name)
|
||||||
|
utils.info('Is loaded: %s', yesno(dep.is_loaded))
|
||||||
|
utils.info('Is lazy: %s', yesno(dep.is_lazy))
|
||||||
|
utils.info('Has init: %s', yesno(dep.init))
|
||||||
|
utils.info('Has config: %s', yesno(dep.config))
|
||||||
|
utils.info('Dependencies: %s', list(dep.dependency_names))
|
||||||
|
utils.info('Filetypes: %s', list(dep.ft))
|
||||||
|
utils.info('Commands: %s', list(dep.cmd))
|
||||||
|
if dep.events == nil then
|
||||||
|
utils.info('Events: None')
|
||||||
|
else
|
||||||
|
utils.info('Events:')
|
||||||
|
for _, event in ipairs(dep.events) do
|
||||||
|
for _, name in ipairs(event.name) do
|
||||||
|
for _, pattern in ipairs(event.pattern) do
|
||||||
|
utils.info(' - %s %s', name, pattern)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if dep.keymaps == nil then
|
||||||
|
utils.info('Keymaps: None')
|
||||||
|
else
|
||||||
|
utils.info('Keymaps:')
|
||||||
|
for _, keymap in ipairs(dep.keymaps) do
|
||||||
|
for _, mode in ipairs(keymap.mode) do
|
||||||
|
for _, mapping in ipairs(keymap.mapping) do
|
||||||
|
utils.info(' - %s %s', mode, mapping)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
complete = function(line)
|
||||||
|
if line.arg_idx == 3 then
|
||||||
|
local prefix = line.args[line.arg_idx].arg
|
||||||
|
return vim.iter(Dep.all()):map(function(name)
|
||||||
|
return name
|
||||||
|
end):filter(function(name)
|
||||||
|
return vim.startswith(name, prefix)
|
||||||
|
end):totable()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
cmd = function(plugins)
|
||||||
|
if #plugins == 0 then
|
||||||
|
utils.error("You should at least give a plugin to describe!")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local plugin = plugins[1]
|
||||||
|
local dep = Dep.get(plugin)
|
||||||
|
if dep == nil then
|
||||||
|
return utils.error([[Unknown plugin "%s"]], plugin)
|
||||||
|
end
|
||||||
|
describe(dep)
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
local Dep = require 'sloth-flake.dep'
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
local commands = {
|
||||||
|
list = require 'sloth-flake.command.list',
|
||||||
|
load = require 'sloth-flake.command.load',
|
||||||
|
version = require 'sloth-flake.command.version',
|
||||||
|
describe = require 'sloth-flake.command.describe',
|
||||||
|
}
|
||||||
|
|
||||||
|
local function parse_line(line, cursor_pos)
|
||||||
|
local raw_args = vim.split(line, ' +', { trimempty = true })
|
||||||
|
local parse_pos = 1
|
||||||
|
local args = vim.iter(raw_args):map(function(arg)
|
||||||
|
local start, stop = string.find(line, arg, parse_pos, { plain = true })
|
||||||
|
parse_pos = stop
|
||||||
|
return {
|
||||||
|
arg = arg,
|
||||||
|
start = start,
|
||||||
|
stop = stop,
|
||||||
|
}
|
||||||
|
end):totable()
|
||||||
|
parse_pos = 1
|
||||||
|
local arg_idx = 1
|
||||||
|
vim.iter(args):find(function(arg)
|
||||||
|
if cursor_pos < arg.start then
|
||||||
|
arg_idx = arg_idx - 1
|
||||||
|
return true
|
||||||
|
elseif cursor_pos <= arg.stop then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
arg_idx = arg_idx + 1
|
||||||
|
return false
|
||||||
|
end)
|
||||||
|
arg_idx = arg_idx < 1 and 1 or arg_idx
|
||||||
|
if arg_idx > #args then
|
||||||
|
args[#args + 1] = {
|
||||||
|
arg = "",
|
||||||
|
start = line:len(),
|
||||||
|
stop = line:len(),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
return {
|
||||||
|
line = line,
|
||||||
|
args = args,
|
||||||
|
arg_idx = arg_idx,
|
||||||
|
pos = cursor_pos,
|
||||||
|
in_arg_pos = args[arg_idx] and cursor_pos - args[arg_idx].start + 1,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
-- print(vim.inspect(parse_line('Sloth ', 6)))
|
||||||
|
|
||||||
|
local function sloth_cmd_complete(arg_lead, cmd_line, cursor_pos)
|
||||||
|
local parsed_line = parse_line(cmd_line, cursor_pos)
|
||||||
|
local arg = parsed_line.args[parsed_line.arg_idx]
|
||||||
|
if parsed_line.arg_idx == 2 then
|
||||||
|
return vim.iter(commands):map(function(name, command)
|
||||||
|
return vim.startswith(name, arg.arg) and name or nil
|
||||||
|
end):totable()
|
||||||
|
elseif parsed_line.arg_idx > 2 then
|
||||||
|
local cmd = parsed_line.args[2].arg
|
||||||
|
local command = commands[cmd]
|
||||||
|
return command and command.complete(parsed_line)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function sloth_cmd(param)
|
||||||
|
local args = param.fargs
|
||||||
|
local cmd = args[1] or "list";
|
||||||
|
table.remove(args, 1)
|
||||||
|
local command = commands[cmd]
|
||||||
|
if command then
|
||||||
|
command.cmd(args)
|
||||||
|
else
|
||||||
|
vim.api.nvim_err_writeln(string.format([[No Sloth subcommand "%s"]], cmd))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.register()
|
||||||
|
vim.api.nvim_create_user_command('Sloth', sloth_cmd, {
|
||||||
|
nargs = '*',
|
||||||
|
complete = sloth_cmd_complete
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
local Dep = require 'sloth-flake.dep'
|
||||||
|
local utils = require 'sloth-flake.utils'
|
||||||
|
|
||||||
|
local filters = {
|
||||||
|
all = {
|
||||||
|
filter = function(iter)
|
||||||
|
-- Nothing to do
|
||||||
|
return iter
|
||||||
|
end
|
||||||
|
},
|
||||||
|
loaded = {
|
||||||
|
filter = function(iter)
|
||||||
|
return iter:filter(function(dep)
|
||||||
|
return Dep.get(dep).is_loaded
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
},
|
||||||
|
notloaded = {
|
||||||
|
filter = function(iter)
|
||||||
|
return iter:filter(function(dep)
|
||||||
|
return not Dep.get(dep).is_loaded
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
complete = function(line)
|
||||||
|
if line.arg_idx == 3 then
|
||||||
|
local prefix = line.args[3].arg
|
||||||
|
return vim.iter(vim.tbl_keys(filters)):filter(function(name)
|
||||||
|
return vim.startswith(name, prefix)
|
||||||
|
end):totable()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
cmd = function(args)
|
||||||
|
local filter_name = args[1] or "all"
|
||||||
|
local filter = filters[filter_name]
|
||||||
|
if not filter then
|
||||||
|
utils.error([[No Sloth list filter "%s".]], cmd)
|
||||||
|
utils.error("Filters are: %s", vim.iter(vim.tbl_keys(filters)):join(', '))
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local deps = vim.iter(Dep.all()):map(function(_, dep)
|
||||||
|
return dep.name
|
||||||
|
end)
|
||||||
|
deps = filter.filter(deps):totable()
|
||||||
|
table.sort(deps)
|
||||||
|
for _, dep in ipairs(deps) do
|
||||||
|
print(string.format("- %s", dep))
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
local Dep = require 'sloth-flake.dep'
|
||||||
|
local utils = require 'sloth-flake.utils'
|
||||||
|
|
||||||
|
return {
|
||||||
|
complete = function(line)
|
||||||
|
local previous_deps = vim.iter(line.args):enumerate():map(function(i, arg)
|
||||||
|
if i < 3 or i > line.arg_idx then return end
|
||||||
|
return arg.arg
|
||||||
|
end):totable()
|
||||||
|
|
||||||
|
local prefix = line.args[line.arg_idx].arg
|
||||||
|
return vim.iter(Dep.all()):filter(function(name, dep)
|
||||||
|
return vim.startswith(name, prefix) and not dep.is_loaded
|
||||||
|
and not vim.list_contains(previous_deps, name)
|
||||||
|
end):map(function(name)
|
||||||
|
return name
|
||||||
|
end):totable()
|
||||||
|
end,
|
||||||
|
|
||||||
|
cmd = function(plugins)
|
||||||
|
if #plugins == 0 then
|
||||||
|
utils.error("You should at least give a plugin to load!")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
for _, plugin in ipairs(plugins) do
|
||||||
|
local dep = Dep.get(plugin)
|
||||||
|
if dep ~= nil then
|
||||||
|
dep:load()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
return {
|
||||||
|
complete = function() end,
|
||||||
|
cmd = function()
|
||||||
|
local version = require('sloth-flake.version')
|
||||||
|
print(string.format('Sloth v%s', version()))
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,268 @@
|
||||||
|
local raw_deps = require 'sloth-flake.dependencies'
|
||||||
|
local state_machine = require 'sloth-flake.state_machine'
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
local State = state_machine.build_states {
|
||||||
|
'NotLoaded',
|
||||||
|
'Shimed',
|
||||||
|
'Inited',
|
||||||
|
'Imported',
|
||||||
|
'Loaded',
|
||||||
|
}
|
||||||
|
|
||||||
|
function M.new(values)
|
||||||
|
local self = {
|
||||||
|
values = values,
|
||||||
|
}
|
||||||
|
self.sm = state_machine.build(State, {
|
||||||
|
enter = {
|
||||||
|
[State.Shimed] = function()
|
||||||
|
return self:_shim()
|
||||||
|
end,
|
||||||
|
[State.Inited] = function()
|
||||||
|
for _, dep in ipairs(self.dependencies) do
|
||||||
|
dep:init()
|
||||||
|
end
|
||||||
|
|
||||||
|
local init = self.values.init or function() end
|
||||||
|
init()
|
||||||
|
end,
|
||||||
|
[State.Imported] = function()
|
||||||
|
for _, dep in ipairs(self.dependencies) do
|
||||||
|
dep:import()
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.is_lazy or self.values.init then
|
||||||
|
vim.cmd("packadd " .. self.name)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
[State.Loaded] = function()
|
||||||
|
for _, dep in ipairs(self.dependencies) do
|
||||||
|
dep:config()
|
||||||
|
end
|
||||||
|
|
||||||
|
local config = self.values.config or function() end
|
||||||
|
config()
|
||||||
|
end
|
||||||
|
},
|
||||||
|
exit = {
|
||||||
|
[State.Shimed] = function()
|
||||||
|
self:_unshim()
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
events = {
|
||||||
|
shim = { from = State.NotLoaded, to = State.Shimed, },
|
||||||
|
init = { from = { State.NotLoaded, State.Shimed }, to = State.Inited, },
|
||||||
|
import = { from = State.Inited, to = State.Imported, },
|
||||||
|
config = { from = State.Imported, to = State.Loaded, },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
return setmetatable(self, {
|
||||||
|
__index = function(self, k)
|
||||||
|
local fn = M[k]
|
||||||
|
if fn then
|
||||||
|
return fn
|
||||||
|
end
|
||||||
|
fn = M['get_' .. k]
|
||||||
|
if fn then
|
||||||
|
return fn(self)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
__newindex = function(self, k, v)
|
||||||
|
-- Ignore new values
|
||||||
|
end
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
function M:get_name()
|
||||||
|
return self.values.name
|
||||||
|
end
|
||||||
|
|
||||||
|
function M:get_dependencies()
|
||||||
|
local ret = {}
|
||||||
|
for _, name in ipairs(self.values.dependencies) do
|
||||||
|
local dep = M.get(name)
|
||||||
|
if dep ~= nil then
|
||||||
|
ret[#ret + 1] = dep
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
function M:get_dependency_names()
|
||||||
|
local ret = {}
|
||||||
|
for _, name in ipairs(self.values.dependencies) do
|
||||||
|
ret[#ret + 1] = name
|
||||||
|
end
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
function M:get_cmd()
|
||||||
|
return self.values.cmd
|
||||||
|
end
|
||||||
|
|
||||||
|
function M:get_ft()
|
||||||
|
return self.values.ft
|
||||||
|
end
|
||||||
|
|
||||||
|
function M:get_events()
|
||||||
|
return self.values.events
|
||||||
|
end
|
||||||
|
|
||||||
|
function M:get_keymaps()
|
||||||
|
return self.values.keymaps
|
||||||
|
end
|
||||||
|
|
||||||
|
function M:get_is_lazy()
|
||||||
|
return self.values.lazy or false
|
||||||
|
end
|
||||||
|
|
||||||
|
function M:get_state()
|
||||||
|
return self.sm.state
|
||||||
|
end
|
||||||
|
|
||||||
|
function M:get_is_imported()
|
||||||
|
return self.state >= State.Imported
|
||||||
|
end
|
||||||
|
|
||||||
|
function M:get_is_loaded()
|
||||||
|
return self.state >= State.Loaded
|
||||||
|
end
|
||||||
|
|
||||||
|
function M:get_has_events()
|
||||||
|
return self.ft or self.events
|
||||||
|
end
|
||||||
|
|
||||||
|
function M:get_augroup_name()
|
||||||
|
return "Sloth-plugin-" .. self.name
|
||||||
|
end
|
||||||
|
|
||||||
|
function M:shim()
|
||||||
|
return self.sm:shim()
|
||||||
|
end
|
||||||
|
|
||||||
|
function M:_shim()
|
||||||
|
if self.cmd then
|
||||||
|
for _, cmd in ipairs(self.cmd) do
|
||||||
|
vim.api.nvim_create_user_command(cmd, self:lazy_load_cmd(cmd), {
|
||||||
|
desc = "Sloth-flake placeholder for plugin " .. self.name,
|
||||||
|
nargs = '*',
|
||||||
|
bang = true,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.has_events then
|
||||||
|
local group_id = vim.api.nvim_create_augroup(self.augroup_name, {
|
||||||
|
clear = true,
|
||||||
|
})
|
||||||
|
|
||||||
|
if self.ft then
|
||||||
|
vim.api.nvim_create_autocmd('FileType', {
|
||||||
|
group = group_id,
|
||||||
|
pattern = self.ft,
|
||||||
|
callback = self:lazy_load_event('FileType')
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.events then
|
||||||
|
for _, event in ipairs(self.events) do
|
||||||
|
vim.api.nvim_create_autocmd(event.name, {
|
||||||
|
group = group_id,
|
||||||
|
pattern = event.pattern,
|
||||||
|
callback = self:lazy_load_event(event.name)
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.keymaps then
|
||||||
|
for _, keymap in ipairs(self.keymaps) do
|
||||||
|
for _, mapping in ipairs(keymap.mapping) do
|
||||||
|
vim.keymap.set(keymap.mode, mapping, self:lazy_load_mapping(mapping))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function M:_unshim()
|
||||||
|
if self.cmd then
|
||||||
|
for _, cmd in ipairs(self.cmd) do
|
||||||
|
vim.api.nvim_del_user_command(cmd)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.has_events then
|
||||||
|
vim.api.nvim_del_augroup_by_name(self.augroup_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.keymaps then
|
||||||
|
for _, keymap in ipairs(self.keymaps) do
|
||||||
|
for _, mapping in ipairs(keymap.mapping) do
|
||||||
|
vim.keymap.del(keymap.mode, mapping)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function M:init()
|
||||||
|
return self.sm:init()
|
||||||
|
end
|
||||||
|
|
||||||
|
function M:import()
|
||||||
|
self:init()
|
||||||
|
return self.sm:import()
|
||||||
|
end
|
||||||
|
|
||||||
|
function M:config()
|
||||||
|
self:init()
|
||||||
|
self:import()
|
||||||
|
return self.sm:config()
|
||||||
|
end
|
||||||
|
|
||||||
|
function M:load()
|
||||||
|
self:init()
|
||||||
|
self:import()
|
||||||
|
return self:config()
|
||||||
|
end
|
||||||
|
|
||||||
|
function M:lazy_load_cmd(cmd)
|
||||||
|
return function(param)
|
||||||
|
self:load()
|
||||||
|
local bang = param.bang and '!' or ''
|
||||||
|
vim.cmd(cmd .. bang .. ' ' .. param.args)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function M:lazy_load_event(name)
|
||||||
|
return function(param)
|
||||||
|
self:load()
|
||||||
|
vim.api.nvim_exec_autocmds(name, {
|
||||||
|
pattern = param.match,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function M:lazy_load_mapping(mapping)
|
||||||
|
return function(param)
|
||||||
|
self:load()
|
||||||
|
vim.cmd.normal(mapping)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local deps = {}
|
||||||
|
for k, v in pairs(raw_deps) do
|
||||||
|
deps[k] = M.new(v)
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.get(name)
|
||||||
|
return deps[name]
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.all()
|
||||||
|
return deps
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
|
|
@ -1,80 +1,76 @@
|
||||||
local deps = require 'sloth-flake.deps'
|
local Dep = require 'sloth-flake.dep'
|
||||||
|
local command = require 'sloth-flake.command'
|
||||||
local priv = {
|
local priv = {
|
||||||
is_loaded = {}
|
setup_called = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
function M.get(name)
|
function M.get(name)
|
||||||
return deps[name]
|
return Dep.get(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.init_all()
|
function M.init_non_lazy()
|
||||||
for k, v in pairs(deps) do
|
for _, dep in ipairs(M.non_lazy_deps()) do
|
||||||
M.init(k)
|
dep:init()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.config_all()
|
function M.import_non_lazy()
|
||||||
for k, v in pairs(deps) do
|
for _, dep in ipairs(M.non_lazy_deps()) do
|
||||||
M.config(k)
|
dep:import()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.init(name)
|
function M.config_non_lazy()
|
||||||
local dep = M.get(name)
|
for _, dep in ipairs(M.non_lazy_deps()) do
|
||||||
if name == nil then
|
dep:config()
|
||||||
-- TODO Report error ?
|
|
||||||
elseif dep.init ~= nil then
|
|
||||||
dep.init()
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.load(name)
|
function M.dep_names()
|
||||||
if name == nil then
|
return M.dep_names_by(function() return true end):totable()
|
||||||
-- TODO Report error ?
|
|
||||||
elseif M.is_loaded(name) then
|
|
||||||
-- TODO Nothing todo
|
|
||||||
else
|
|
||||||
-- TODO Laod dynamic plugin
|
|
||||||
priv.is_loaded[name] = true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.config(name)
|
function M.dep_names_by(fn)
|
||||||
local dep = M.get(name)
|
return M.deps_iter_by(fn):map(function(v) return v:name() end)
|
||||||
if name == nil then
|
|
||||||
-- TODO Report error ?
|
|
||||||
elseif dep.config ~= nil then
|
|
||||||
dep.config()
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.get_dep_names()
|
function M.deps_iter_by(fn)
|
||||||
local ret = {}
|
return vim.iter(Dep.all()):map(function(k, v) return v end):filter(fn)
|
||||||
for k, v in pairs(deps) do
|
|
||||||
ret[#ret + 1] = v.name
|
|
||||||
end
|
|
||||||
return ret
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.load_all()
|
function M.non_lazy_deps()
|
||||||
for k, _v in pairs(deps) do
|
return M.deps_iter_by(function(dep)
|
||||||
M.load(k)
|
return not dep.is_lazy
|
||||||
end
|
end):totable()
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.is_loaded(name)
|
function M.lazy_deps()
|
||||||
return priv.is_loaded[name] or false
|
return M.deps_iter_by(function(dep)
|
||||||
|
return dep.is_lazy
|
||||||
|
end):totable()
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.setup(config)
|
function M.setup(config)
|
||||||
local post_init = config.post_init or function() end
|
if priv.setup_called then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
priv.setup_called = true
|
||||||
|
|
||||||
M.init_all()
|
local post_init = config and config.post_init or function() end
|
||||||
|
|
||||||
|
M.init_non_lazy()
|
||||||
post_init()
|
post_init()
|
||||||
M.load_all()
|
M.import_non_lazy()
|
||||||
M.config_all()
|
M.config_non_lazy()
|
||||||
|
|
||||||
|
local lazy_deps = M.lazy_deps()
|
||||||
|
for _, dep in ipairs(lazy_deps) do
|
||||||
|
dep:shim()
|
||||||
|
end
|
||||||
|
|
||||||
|
command.register()
|
||||||
end
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,104 @@
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
local stateMeta
|
||||||
|
|
||||||
|
local function are_both_states(a, b)
|
||||||
|
return a.is_state and b.is_state
|
||||||
|
end
|
||||||
|
|
||||||
|
stateMeta = {
|
||||||
|
__tostring = function(v)
|
||||||
|
return v.name
|
||||||
|
end,
|
||||||
|
__le = function(self, other)
|
||||||
|
if not are_both_states(self, other) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return self.idx <= other.idx
|
||||||
|
end,
|
||||||
|
__lt = function(self, other)
|
||||||
|
if not are_both_states(self, other) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return self.idx < other.idx
|
||||||
|
end,
|
||||||
|
__index = function(self, name)
|
||||||
|
if name == 'is_state' then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
function M.build_states(defs)
|
||||||
|
local states = {}
|
||||||
|
for i, name in ipairs(defs) do
|
||||||
|
local state = setmetatable({ idx = i, name = name }, stateMeta)
|
||||||
|
states[i] = state
|
||||||
|
states[name] = state
|
||||||
|
end
|
||||||
|
return states
|
||||||
|
end
|
||||||
|
|
||||||
|
local SM = {}
|
||||||
|
|
||||||
|
local function empty_fn()
|
||||||
|
end
|
||||||
|
|
||||||
|
function SM:run_enter_state(state)
|
||||||
|
local enter_fn = self.defs.enter and self.defs.enter[state] or empty_fn
|
||||||
|
enter_fn(self.state)
|
||||||
|
end
|
||||||
|
|
||||||
|
function SM:run_exit_state(state)
|
||||||
|
local exit_fn = self.defs.exit and self.defs.exit[state] or empty_fn
|
||||||
|
exit_fn(self.state)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function wrap_state_array(val)
|
||||||
|
return val.is_state and { val } or val
|
||||||
|
end
|
||||||
|
|
||||||
|
local function canonicalize_event(event)
|
||||||
|
return {
|
||||||
|
from = wrap_state_array(event.from),
|
||||||
|
to = event.to,
|
||||||
|
transition = event.transition or function() end,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.build(states, defs)
|
||||||
|
local machine = {
|
||||||
|
state = states[1],
|
||||||
|
defs = defs,
|
||||||
|
}
|
||||||
|
local prototype = {}
|
||||||
|
|
||||||
|
for name, infos in pairs(defs.events) do
|
||||||
|
local event = canonicalize_event(infos)
|
||||||
|
prototype[name] = function(self)
|
||||||
|
if not vim.list_contains(event.from, self.state) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local previous = self.state
|
||||||
|
self:run_exit_state(previous)
|
||||||
|
self.state = event.to
|
||||||
|
event.transition(previous, self.state)
|
||||||
|
self:run_enter_state(self.state)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local ret = setmetatable(machine, { __index = vim.tbl_extend('error', SM, prototype)})
|
||||||
|
ret:run_enter_state(states[1])
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
local State = M.build_states {
|
||||||
|
'NotLoaded',
|
||||||
|
'Shimed',
|
||||||
|
'Inited',
|
||||||
|
'Imported',
|
||||||
|
'Loaded',
|
||||||
|
}
|
||||||
|
|
||||||
|
return M
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
function M.info(...)
|
||||||
|
print(string.format(...))
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.error(...)
|
||||||
|
vim.api.nvim_err_writeln(string.format(...))
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
Loading…
Reference in New Issue