Compare commits

..

33 Commits
0.0.6 ... main

Author SHA1 Message Date
LeMarsu a4cc5d9b9c feat: can declare extra lua packages 2024-06-18 01:12:08 +02:00
LeMarsu b5a3526f8a chore: bump version 2024-06-10 01:14:35 +02:00
LeMarsu 23c9863c97 feat: add option init config object to generate `init.lua` 2024-06-10 01:08:56 +02:00
LeMarsu b6630684fb feat!: `init.lua` configuration is now a `mkNeovimPkg`'s option
BREAKING CHANGE: The init configuration has moved out of runtime
configuration. It is now in the mkNeovimPkg confuguration.
2024-06-10 01:08:50 +02:00
LeMarsu 815a099805 feat: runtime is now optional
as it should be according to docs...
2024-06-10 00:36:56 +02:00
LeMarsu 3d20bc0ade chore: add alejandra to nix shell 2024-06-09 04:01:18 +02:00
LeMarsu 182c7cd83d chore: bump version 2024-06-09 02:02:47 +02:00
LeMarsu af9565fa95 feat: introduce mkPluginsFromInputs function
This permit creation of plugin before declaration of dependencies. The
biggest benefit is using those on-the-fly plugins in dependencies.
2024-06-09 00:00:56 +02:00
LeMarsu 6c499b1441 fix: plugins with init are now loaded as they should be 2024-06-08 23:57:29 +02:00
LeMarsu cbd08e5258 chore: move back to flake-utils 2024-06-08 20:03:23 +02:00
LeMarsu b36722bfe6 chore: remove sourcesWith fn, using lib.fileset 2024-06-07 20:22:01 +02:00
LeMarsu 61381e2ba0 fix: init/config are loaded to on-the-fly build plugins 2024-06-07 16:20:46 +02:00
LeMarsu da637930bc feat: add describe subcommand 2024-06-05 02:47:46 +02:00
LeMarsu c20336ee60 refactor: filters are now fully dynamic 2024-06-05 02:02:57 +02:00
LeMarsu f50f314c98 feat: Sloth command has now completion 2024-06-05 01:54:41 +02:00
LeMarsu 459eadfae4 chore: bump version 2024-06-04 03:37:08 +02:00
LeMarsu ada07e10d6 chore: switch from nixpkgs `23.11` to `unstable` 2024-06-04 03:35:08 +02:00
LeMarsu f52525abd1 feat: can load lazy plugins on keymaps 2024-06-04 03:26:27 +02:00
LeMarsu 70484e221f feat: can load lazy plugins on events 2024-06-04 03:26:24 +02:00
LeMarsu eb11cfbe1a fix: Sloth list was broken since refactoring 2024-06-04 00:48:37 +02:00
LeMarsu 3d35555ef7 fix: move files instead of copying them
There was left over files in sloth-flake in the store.
2024-06-04 00:47:37 +02:00
LeMarsu cf036bd26c chore: bump version 2024-06-03 03:43:06 +02:00
LeMarsu 2eaecf17a0 fix: init function is called before plugin is loaded 2024-06-03 03:18:44 +02:00
LeMarsu 3732144c33 refactor: deps are now loaded via a FSM 2024-06-03 02:59:42 +02:00
LeMarsu a2bc77f229 refactor: deps provides accessors via metatables 2024-06-03 02:59:42 +02:00
LeMarsu 29e8841a3d refactor: split Sloth subcommands in their own files 2024-06-03 02:59:42 +02:00
LeMarsu ab361c86b4 refactor: extract Sloth command code in its own module 2024-06-03 02:59:42 +02:00
LeMarsu 3204b5a39d refactor: extract all dep logic in Dep object 2024-06-03 02:59:29 +02:00
LeMarsu 9cb43cfd1f flake.lock: Update
Flake lock file updates:

• Updated input 'nil':
    'github:oxalica/nil/2f3ed6348bbf1440fcd1ab0411271497a0fbbfa4' (2024-05-01)
  → 'github:oxalica/nil/ab3ddb8f063774cf7e22eb610f5ecfdb77309f3c' (2024-05-30)
• Updated input 'nil/nixpkgs':
    'github:nixos/nixpkgs/cf8cc1201be8bc71b7cbbbdaf349b22f4f99c7ae' (2024-04-28)
  → 'github:nixos/nixpkgs/ac82a513e55582291805d6f09d35b6d8b60637a1' (2024-05-29)
• Updated input 'nil/rust-overlay':
    'github:oxalica/rust-overlay/9ca720fdcf7865385ae3b93ecdf65f1a64cb475e' (2024-05-01)
  → 'github:oxalica/rust-overlay/095702e63a40e86f339d11864da9dc965b70a01e' (2024-05-30)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/9d29cd266cebf80234c98dd0b87256b6be0af44e' (2024-05-25)
  → 'github:nixos/nixpkgs/25cf937a30bf0801447f6bf544fc7486c6309234' (2024-05-29)
2024-05-31 18:19:05 +02:00
LeMarsu a396afc2c4 feat: add `vimdiffAlias` and `nvimdiffAlias` mkNeovimPkg options 2024-05-31 02:56:27 +02:00
LeMarsu 359462b075 feat: add `viAlias` and `vimAlias` mkNeovimPkg options 2024-05-31 02:44:08 +02:00
LeMarsu 2903d288e2 feat: add `version` Sloth subcommand 2024-05-30 23:44:34 +02:00
LeMarsu d9ba9c8232 doc: fix url in the import example 2024-05-30 03:55:41 +02:00
20 changed files with 1143 additions and 365 deletions

View File

@ -2,6 +2,80 @@
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

169
README.md
View File

@ -8,18 +8,20 @@ A [neovim] plugin and configuration management plugin, highly inspired by [lazy]
- [Features](#features)
- [SemVer](#semver)
- [Installation](#installation)
- [Flake installation](#flake-installation)
- [Flake installation](#flake-installation)
- [Usage](#usage)
- [Documentation](#documentation)
- [nix](#nix)
- [`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)
- [API](#api)
- [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)
<!-- TOC -->
@ -43,8 +45,8 @@ A [neovim] plugin and configuration management plugin, highly inspired by [lazy]
- [X] Lazy load your plugins
- [X] on command
- [X] on filetype
- [ ] on event
- [ ] on keybinding
- [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)
@ -79,7 +81,7 @@ 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?ref=0.0.5";
inputs.sloth-flake.url = "github:lemarsu/sloth-flake.nvim?tag=0.0.5";
```
## Usage
@ -91,6 +93,8 @@ Once installed, you can call the `sloth-flake.lib.mkNeovimPkg` to build your neo
```nix
sloth-flake.lib.mkNeovimPkg {
inherit pkgs;
viAlias = true;
vimAlias = true;
runtime = {
version = "0.1";
src = sloth-flake.lib.sourcesWith ./. [
@ -119,30 +123,95 @@ sloth-flake.lib.mkNeovimPkg {
### 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 |
| `runtime` | `{}` | Your Runtime configuration (see below) |
| `dependencies` | `[]` | A list of your dependencies (see below) |
| `dependenciesExtraArgs` | `{}` | Extra arguments to load your dependencies in other files |
| 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 |
| `init` | `null` | The `init.lua` of your config¹ |
| `src` | `null` | The content of your runtime |
> ¹ If you give your own `init.lua`, you'll have to call `sloth-flake` lua plugin yourself. See more below.
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
@ -150,29 +219,49 @@ The dependencies is a list of element of either:
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⁴ |
| `lazy` | `false` | Should the plugin be loaded lazily |
| `cmd` | `[]` | Command to put as place_holder to lazy load the plugin⁵ |
| `ft` | `[]` | Filetype to watch to lazy load the plugin⁵ |
| 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.
> ³ When the plugin is not lazy, the `init` function is called after the plugin
> is loaded as all non lazy plugin are loaded automatically.
> ⁴ `nix` handles the installation of your plugin, therefore, this list is
> ³ `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`.
> ⁴ 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)
@ -231,6 +320,12 @@ 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.

View File

@ -1 +1 @@
0.0.6
0.0.10

View File

@ -63,24 +63,6 @@
"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": {
"flake": false,
"locked": {
@ -104,11 +86,11 @@
"rust-overlay": "rust-overlay"
},
"locked": {
"lastModified": 1714571717,
"narHash": "sha256-o4tqlTzi9kcVub167kTGXgCac9jM3kW4+v9MH/ue4Hk=",
"lastModified": 1717086091,
"narHash": "sha256-GmsEQa4HZeMfec37LZnwG/Lt/XmqFLXsjv5QWojeNiM=",
"owner": "oxalica",
"repo": "nil",
"rev": "2f3ed6348bbf1440fcd1ab0411271497a0fbbfa4",
"rev": "ab3ddb8f063774cf7e22eb610f5ecfdb77309f3c",
"type": "github"
},
"original": {
@ -119,11 +101,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1714314149,
"narHash": "sha256-yNAevSKF4krRWacmLUsLK7D7PlfuY3zF0lYnGYNi9vQ=",
"lastModified": 1716977081,
"narHash": "sha256-pFe5jLeIPlKEln5n2h998d7cpzXFdbrBMRe3suz4K1o=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "cf8cc1201be8bc71b7cbbbdaf349b22f4f99c7ae",
"rev": "ac82a513e55582291805d6f09d35b6d8b60637a1",
"type": "github"
},
"original": {
@ -135,16 +117,16 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1716633019,
"narHash": "sha256-xim1b5/HZYbWaZKyI7cn9TJCM6ewNVZnesRr00mXeS4=",
"lastModified": 1717196966,
"narHash": "sha256-yZKhxVIKd2lsbOqYd5iDoUIwsRZFqE87smE2Vzf6Ck0=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "9d29cd266cebf80234c98dd0b87256b6be0af44e",
"rev": "57610d2f8f0937f39dbd72251e9614b1561942d8",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-23.11",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
@ -202,11 +184,11 @@
]
},
"locked": {
"lastModified": 1714529851,
"narHash": "sha256-YMKJW880f7LHXVRzu93xa6Ek+QLECIu0IRQbXbzZe38=",
"lastModified": 1717035469,
"narHash": "sha256-MzH+yjKULH3HCRj9QCTwBvqq4LZkR0ZqRE/QfGOGC2E=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "9ca720fdcf7865385ae3b93ecdf65f1a64cb475e",
"rev": "095702e63a40e86f339d11864da9dc965b70a01e",
"type": "github"
},
"original": {
@ -247,20 +229,19 @@
},
"utils": {
"inputs": {
"flake-utils": "flake-utils_2"
"systems": "systems_2"
},
"locked": {
"lastModified": 1696281284,
"narHash": "sha256-xcmtTmoiiAOSk4abifbtqVZk0iwBcqJfg47iUbkwhcE=",
"owner": "gytis-ivaskevicius",
"repo": "flake-utils-plus",
"rev": "6cf1e312fb259693c4930d07ca3cbe1d07ef4a48",
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github"
},
"original": {
"owner": "gytis-ivaskevicius",
"ref": "v1.4.0",
"repo": "flake-utils-plus",
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},

View File

@ -2,8 +2,8 @@
description = "My neovim configuration";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11";
utils.url = "github:gytis-ivaskevicius/flake-utils-plus/v1.4.0";
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
utils.url = "github:numtide/flake-utils";
nil.url = "github:oxalica/nil";
yants.url = "github:divnix/yants";
alejandra = {
@ -20,24 +20,25 @@
yants,
...
} @ 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
then "${versionFile}-${self.sourceInfo.dirtyShortRev}"
else versionFile;
in
utils.lib.mkFlake {
inherit self inputs;
outputsBuilder = channel: let
system = channel.nixpkgs.system;
in {
formatter = alejandra.defaultPackage.${channel.nixpkgs.system};
devShells.default = import ./shell.nix {
pkgs = channel.nixpkgs;
inherit (inputs.nil.packages.${system}) nil;
};
forSystem = system: let
pkgs = nixpkgs.legacyPackages.${system};
formatter = alejandra.defaultPackage.${system};
inherit (inputs.nil.packages.${system}) nil;
in {
inherit formatter;
devShells.default = import ./shell.nix {
inherit pkgs nil formatter;
};
lib = import ./lib {inherit version yants;};
};
in
(fu.eachDefaultSystem forSystem)
// {lib = import ./lib {inherit version yants;};};
}

View File

@ -1,18 +1,9 @@
{version, yants}: let
{
version,
yants,
}: let
types = import ./types.nix {inherit yants;};
in {
mkNeovimPkg = import ./mkNeovimPkg.nix {inherit version types;};
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;
};
mkPluginsFromInputs = import ./mkPluginsFromInputs.nix;
}

View File

@ -6,14 +6,19 @@
types,
...
}: let
inherit (builtins) isPath foldl';
inherit (builtins) foldl' isPath isList isString mapAttrs match elemAt;
inherit (lib.attrsets) attrNames optionalAttrs;
inherit (lib.lists) concatMap;
inherit (lib.strings) fileContents;
inherit (lib.strings) fileContents splitString;
lua = callPackage ./lua.nix {};
callPackage = lib.callPackageWith (pkgs // dependenciesExtraArgs);
hasMatch = pattern: str: isList (match pattern str);
wrapArray = value:
if isList value
then value
else [value];
defaultPlugin = {
enabled = true;
init = null;
@ -22,6 +27,8 @@
lazy = false;
cmd = [];
ft = [];
events = [];
keymaps = [];
};
remotePluginToNeovimPlugin = p:
@ -30,6 +37,39 @@
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;
normalizePlugin = d: let
dep = types.dependency d;
@ -40,7 +80,7 @@
inherit (dep) plugin;
in
if attrNames plugin == ["name" "src"]
then {plugin = remotePluginToNeovimPlugin plugin;}
then dep // {plugin = remotePluginToNeovimPlugin plugin;}
else dep;
p = withPluginDefaults plugin;
in
@ -48,7 +88,12 @@
// rec {
hasCommands = p.cmd != [];
hasFileTypes = p.ft != [];
lazy = p.lazy || hasCommands || hasFileTypes;
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:
@ -77,25 +122,32 @@
vimUtils.buildVimPlugin {
inherit version;
pname = "sloth-flake";
src = ../lua/sloth-flake;
src = with lib.fileset;
toSource {
root = ../.;
fileset = ../lua/sloth-flake;
};
buildPhase = ''
dir=lua/sloth-flake
mkdir -p $dir
mv init.lua $dir
cat <<'LUA' > $dir/deps.lua
return ${pluginsLuaDef plugins}
cat <<'LUA' > $dir/dependencies.lua
${pluginsLuaDef plugins}
LUA
cat <<'LUA' > $dir/version.lua
${versionLua version}
LUA
'';
};
versionLua = version: with lua; nix2lua (return (lambda (return version)));
textOrContent = content:
if isPath content
then fileContents content
else content;
pluginLuaDef = memo: plugin: let
# plugin = builtins.removeAttrs plugin ["dependencies" "plugin"];
mkTypeFn = type: let
content = textOrContent plugin.${type};
in
@ -125,9 +177,16 @@
})
// (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 {
inherit normalizePlugin;
inherit normalizePlugins;

View File

@ -6,15 +6,21 @@
package ? pkgs.neovim-unwrapped,
dependencies ? [],
dependenciesExtraArgs ? {},
runtime ? {},
extraLuaPackages ? (_: []),
runtime ? null,
init ? null,
viAlias ? false,
vimAlias ? false,
vimdiffAlias ? false,
nvimdiffAlias ? false,
...
} @ config: let
inherit (builtins) map;
inherit (pkgs) callPackage;
# inherit (lib.lists) concatMap filter foldl' map optional reverseList;
# inherit (lib.attrsets) attrNames optionalAttrs;
# inherit (lib.strings) concatStringsSep fileContents hasSuffix removePrefix removeSuffix replaceStrings;
# inherit (lib.debug) traceIf traceSeq traceVal traceValSeq traceValFn;
inherit (builtins) isString isPath map;
inherit (pkgs) callPackage bash lib;
inherit (lib.strings) optionalString;
inherit (lib.lists) concatMap optional;
inherit (lib.trivial) flip;
inherit (lib.attrsets) optionalAttrs;
deps = callPackage ./deps.nix {inherit dependenciesExtraArgs types;};
@ -23,25 +29,87 @@
runtimePlugin = deps.mkRuntimePlugin runtime;
plugins =
normalizedPlugins
++ (deps.normalizePlugins [runtimePlugin sloth-flake]);
++ (
deps.normalizePlugins
([sloth-flake] ++ (optional (runtime != null) runtimePlugin))
);
extractPlugin = p: {
inherit (p) plugin;
optional = p.lazy;
};
extractPlugin = p: {inherit (p) optional plugin;};
extractPlugins = map extractPlugin;
customRC = let
rc = ({init ? ../lua/default_init.lua, ...}: init) runtime;
extractLuaPackageFn = plugin:
optional (plugin ? extraLuaPackages) plugin.extraLuaPackages;
extractLuaPackagesFn = plugins: let
fnList = concatMap extractLuaPackageFn plugins;
concatPackages = ps: fn: fn ps;
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 =
pkgs.neovimUtils.makeNeovimConfig {
inherit customRC;
plugins = extractPlugins plugins;
extraLuaPackages = ps:
(extractLuaPackagesFn plugins ps) ++ (extraLuaPackages ps);
}
// {luaRcContent = customRC;};
pkg = pkgs.wrapNeovimUnstable package (removeAttrs neovimConfig ["manifestRc" "neovimRcContent"]);
params =
removeAttrs neovimConfig ["manifestRc" "neovimRcContent"]
// {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
builtins.seq (types.mkNeovimPkgOptions config) pkg
builtins.seq (types.mkNeovimPkgOptions config) (pkg.overrideAttrs (final: super: {
postBuild =
super.postBuild
+ (mkDiffAlias "vimdiff" vimdiffAlias)
+ (mkDiffAlias "nvimdiff" nvimdiffAlias);
}))

View File

@ -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

View File

@ -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
runtimeType = with yants;
struct "runtime" {
# The version of the runtime
version = option string;
# The init configuration file
init = option (either path string);
# The content of the runtime directory
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
basicPluginType = with yants;
struct "basicPlugin" {
@ -22,10 +35,24 @@
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
pluginType = with yants; let
stringList = list string;
in
pluginType = with yants;
struct "plugin" {
# Whether this plugin should be enabled. This option allows specific
# plugins to be disabled.
@ -45,11 +72,14 @@
# Ensure thoses plugins are loaded before the current one
dependencies = option (list drv);
# Ensure those packages are available
extraLuaPackages = option function;
# Should this plugin be load lazily ?
lazy = option bool;
# 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
cmd = option stringList;
@ -58,7 +88,7 @@
ft = option stringList;
# 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.
# Highest values get loaded before.
@ -78,13 +108,31 @@
# Default is pkgs.neovim-unwrapped
package = option drv;
# init.lua configuration
init = option (eitherN [string path neovimInitType]);
# An array of dependencies.
dependencies = list dependency;
dependencies = option (list dependency);
# 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 = 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;
};
}

View File

@ -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,
}

View File

@ -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

View File

@ -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,
}

View File

@ -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,
}

View File

@ -0,0 +1,7 @@
return {
complete = function() end,
cmd = function()
local version = require('sloth-flake.version')
print(string.format('Sloth v%s', version()))
end,
}

268
lua/sloth-flake/dep.lua Normal file
View File

@ -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

View File

@ -1,256 +1,57 @@
local deps = require 'sloth-flake.deps'
local Dep = require 'sloth-flake.dep'
local command = require 'sloth-flake.command'
local priv = {
setup_called = false,
is = {
init = {},
import = {},
config = {},
shim = {},
},
}
local M = {}
function M.get(name)
return deps[name]
return Dep.get(name)
end
function M.init_non_lazy()
for _, dep in ipairs(M.non_lazy_deps()) do
M.init(dep.name)
dep:init()
end
end
function M.import_non_lazy()
for _, dep in ipairs(M.non_lazy_deps()) do
M.import(dep.name)
dep:import()
end
end
function M.config_non_lazy()
for _, dep in ipairs(M.non_lazy_deps()) do
M.config(dep.name)
dep:config()
end
end
function load_fn(type)
local function fn(name)
local dep = M.get(name)
if dep == nil then
-- TODO Handle missing deps
return
end
if priv.is[type][name] then
return
end
priv.is[type][name] = true
if dep[type] ~= nil then
for _, child in ipairs(dep.dependencies) do
fn(child)
end
dep[type]()
end
end
return fn
end
M.init = load_fn('init')
M.config = load_fn('config')
function M.import(name)
if M.is_imported(name) then
return
end
local plugin = M.get(name)
if plugin == nil then
-- TODO Handle missing deps
return
end
priv.is.import[name] = true
if plugin.lazy then
for _, dep in ipairs(plugin.dependencies) do
M.import(dep)
end
vim.cmd("packadd " .. name)
end
end
function M.is_imported(name)
return priv.is.import[name] or false
end
function M.is_loaded(name)
return priv.is.config[name] or false
end
function M.load(name)
unshim_plugin(name)
M.init(name)
M.import(name)
M.config(name)
end
function M.dep_names()
return M.dep_names_by(function() return true end):totable()
end
function M.dep_names_by(fn)
return M.deps_iter_by(fn):map(function(v) return v.name end)
return M.deps_iter_by(fn):map(function(v) return v:name() end)
end
function M.deps_iter_by(fn)
return vim.iter(deps):map(function(k, v) return v end):filter(fn)
return vim.iter(Dep.all()):map(function(k, v) return v end):filter(fn)
end
function M.non_lazy_deps()
return M.deps_iter_by(function(dep)
return not dep.lazy
return not dep.is_lazy
end):totable()
end
function M.lazy_deps()
return M.deps_iter_by(function(dep)
return dep.lazy
return dep.is_lazy
end):totable()
end
function lazy_load_cmd(dep, cmd)
return function(param)
M.load(dep.name)
local bang = param.bang and '!' or ''
vim.cmd(cmd .. bang .. ' ' .. param.args)
end
end
function lazy_load_ft(dep)
return function(param)
M.load(dep.name)
print(param.match)
vim.api.nvim_exec_autocmds('FileType', {
pattern = param.match,
})
end
end
function augroup_name(dep)
return "Sloth-plugin-" .. dep.name
end
function shim_plugin(dep)
if priv.is.shim[dep.name] then
return
end
priv.is.shim[dep.name] = true
if dep.cmd then
for _, cmd in ipairs(dep.cmd) do
vim.api.nvim_create_user_command(cmd, lazy_load_cmd(dep, cmd), {
desc = "Sloth-flake placeholder for plugin " .. dep.name,
nargs = '*',
bang = true,
})
end
end
if dep.ft then
local group_id = vim.api.nvim_create_augroup(augroup_name(dep), {
clear = true,
})
vim.api.nvim_create_autocmd('FileType', {
group = group_id,
pattern = dep.ft,
callback = lazy_load_ft(dep)
})
end
end
function unshim_plugin(name)
local dep = M.get(name)
if not priv.is.shim[name] then
return
end
priv.is.shim[name] = nil
if dep.cmd then
for _, cmd in ipairs(dep.cmd) do
vim.api.nvim_del_user_command(cmd)
end
end
if dep.ft then
vim.api.nvim_del_augroup_by_name(augroup_name(dep))
end
end
function name_compare(a, b)
if a < b then
return -1
elseif a > b then
return 1
else
return 0
end
end
local function vim_error(...)
vim.api.nvim_err_writeln(string.format(...))
end
local commands = {
list = function(args)
local filter = args[1] or "all"
local deps = vim.iter(M.dep_names())
if filter == "all" then
-- Nothing to do
elseif filter == "loaded" then
deps = deps:filter(function (dep)
return M.is_loaded(dep)
end)
elseif filter == "notloaded" then
deps = deps:filter(function (dep)
return not M.is_loaded(dep)
end)
else
vim_error([[No Sloth list filter "%s".]], cmd)
vim_error("Filters are: all, loaded, notloaded")
return
end
deps = deps:totable()
table.sort(deps, dep_name_compare)
for _, dep in ipairs(deps) do
print(string.format("- %s", dep))
end
end,
load = function(plugins)
if #plugins == 0 then
vim_error("You should at least give a plugin to load!")
return
end
for _, plugin in ipairs(plugins) do
M.load(plugin)
end
end
}
function sloth_cmd(param)
local args = param.fargs
local cmd = args[1] or "list";
table.remove(args, 1)
local fn = commands[cmd]
if fn then
fn(args)
else
vim.api.nvim_err_writeln(string.format([[No Sloth subcommand "%s"]], cmd))
end
end
function register_command()
vim.api.nvim_create_user_command('Sloth', sloth_cmd, {
nargs = '*',
})
end
function M.setup(config)
if priv.setup_called then
return
@ -266,10 +67,10 @@ function M.setup(config)
local lazy_deps = M.lazy_deps()
for _, dep in ipairs(lazy_deps) do
shim_plugin(dep)
dep:shim()
end
register_command()
command.register()
end
return M

View File

@ -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

11
lua/sloth-flake/utils.lua Normal file
View File

@ -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

View File

@ -1,13 +1,15 @@
{
pkgs,
formatter,
nil,
pkgs,
...
}:
with pkgs;
mkShell {
buildInputs = [
formatter
git-cliff
nil
sumneko-lua-language-server
git-cliff
];
}