mirror of
https://github.com/nix-community/nixvim.git
synced 2025-06-21 00:25:42 +02:00
flake-modules -> flake
This commit is contained in:
parent
cf647bc045
commit
998bae9dac
17 changed files with 1 additions and 1 deletions
24
flake/default.nix
Normal file
24
flake/default.nix
Normal file
|
@ -0,0 +1,24 @@
|
|||
{ inputs, ... }:
|
||||
{
|
||||
imports = [
|
||||
./dev
|
||||
./lib.nix
|
||||
./legacy-packages.nix
|
||||
./overlays.nix
|
||||
./packages.nix
|
||||
./templates.nix
|
||||
./tests.nix
|
||||
./wrappers.nix
|
||||
];
|
||||
|
||||
perSystem =
|
||||
{ system, ... }:
|
||||
{
|
||||
_module.args = {
|
||||
pkgsUnfree = import inputs.nixpkgs {
|
||||
inherit system;
|
||||
config.allowUnfree = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
109
flake/dev/default.nix
Normal file
109
flake/dev/default.nix
Normal file
|
@ -0,0 +1,109 @@
|
|||
{ lib, inputs, ... }:
|
||||
{
|
||||
imports =
|
||||
[
|
||||
./devshell.nix
|
||||
./list-plugins
|
||||
]
|
||||
++ lib.optional (inputs.git-hooks ? flakeModule) inputs.git-hooks.flakeModule
|
||||
++ lib.optional (inputs.treefmt-nix ? flakeModule) inputs.treefmt-nix.flakeModule;
|
||||
|
||||
perSystem =
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
system,
|
||||
...
|
||||
}:
|
||||
lib.optionalAttrs (inputs.treefmt-nix ? flakeModule) {
|
||||
treefmt.config = {
|
||||
projectRootFile = "flake.nix";
|
||||
flakeCheck = true;
|
||||
|
||||
programs = {
|
||||
isort.enable = true;
|
||||
nixfmt = {
|
||||
enable = true;
|
||||
package = pkgs.nixfmt-rfc-style;
|
||||
};
|
||||
prettier = {
|
||||
enable = true;
|
||||
excludes = [ "**.md" ];
|
||||
};
|
||||
ruff = {
|
||||
check = true;
|
||||
format = true;
|
||||
};
|
||||
statix.enable = true;
|
||||
stylua.enable = true;
|
||||
shfmt.enable = true;
|
||||
# FIXME: re-enable on darwin, currently broken: taplo with options '[format]' failed to apply: exit status 101
|
||||
taplo.enable = pkgs.stdenv.isLinux;
|
||||
};
|
||||
|
||||
settings = {
|
||||
global.excludes = [
|
||||
".editorconfig"
|
||||
".envrc"
|
||||
".git-blame-ignore-revs"
|
||||
".gitignore"
|
||||
"LICENSE"
|
||||
"flake.lock"
|
||||
"**.md"
|
||||
"**.scm"
|
||||
"**.svg"
|
||||
"**/man/*.5"
|
||||
# Those files are generated by pytest-regression, which then `diff`s them.
|
||||
# Formatting them will make the tests fail.
|
||||
"docs/gfm-alerts-to-admonitions/tests/**/*.yml"
|
||||
];
|
||||
formatter.ruff-format.options = [ "--isolated" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
// lib.optionalAttrs (inputs.git-hooks ? flakeModule) {
|
||||
pre-commit = {
|
||||
# We have a treefmt check already, so this is redundant.
|
||||
# We also can't run the test if it includes running `nix build`,
|
||||
# since the nix CLI can't build within a derivation builder.
|
||||
check.enable = false;
|
||||
|
||||
settings.hooks = {
|
||||
deadnix = {
|
||||
enable = true;
|
||||
|
||||
settings = {
|
||||
noLambdaArg = true;
|
||||
noLambdaPatternNames = true;
|
||||
edit = true;
|
||||
};
|
||||
};
|
||||
treefmt.enable = true;
|
||||
typos = {
|
||||
enable = true;
|
||||
excludes = [ "generated/*" ];
|
||||
};
|
||||
maintainers = {
|
||||
enable = true;
|
||||
name = "maintainers";
|
||||
description = "Check maintainers when it is modified.";
|
||||
files = "^lib/maintainers[.]nix$";
|
||||
package = pkgs.nix;
|
||||
entry = "nix build --no-link --print-build-logs";
|
||||
args = [ ".#checks.${system}.maintainers" ];
|
||||
pass_filenames = false;
|
||||
};
|
||||
plugins-by-name = {
|
||||
enable = true;
|
||||
name = "plugins-by-name";
|
||||
description = "Check `plugins/by-name` when it's modified.";
|
||||
files = "^(?:tests/test-sources/)?plugins/by-name/";
|
||||
package = pkgs.nix;
|
||||
entry = "nix build --no-link --print-build-logs";
|
||||
args = [ ".#checks.${system}.plugins-by-name" ];
|
||||
pass_filenames = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
122
flake/dev/devshell.nix
Normal file
122
flake/dev/devshell.nix
Normal file
|
@ -0,0 +1,122 @@
|
|||
{ lib, inputs, ... }:
|
||||
{
|
||||
imports = lib.optional (inputs.devshell ? flakeModule) inputs.devshell.flakeModule;
|
||||
|
||||
perSystem =
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
self',
|
||||
system,
|
||||
...
|
||||
}:
|
||||
lib.optionalAttrs (inputs.devshell ? flakeModule) {
|
||||
devshells.default = {
|
||||
devshell.startup.pre-commit.text = config.pre-commit.installationScript;
|
||||
|
||||
commands =
|
||||
let
|
||||
# Thanks to this, the user can choose to use `nix-output-monitor` (`nom`) instead of plain `nix`
|
||||
nix = ''$([ "$\{NIXVIM_NOM:-0}" = '1' ] && echo ${pkgs.lib.getExe pkgs.nix-output-monitor} || echo nix)'';
|
||||
in
|
||||
[
|
||||
{
|
||||
name = "checks";
|
||||
help = "Run all nixvim checks";
|
||||
command = ''
|
||||
echo "=> Running all nixvim checks..."
|
||||
|
||||
${nix} flake check "$@"
|
||||
'';
|
||||
}
|
||||
{
|
||||
name = "tests";
|
||||
help = "Run nixvim tests";
|
||||
command =
|
||||
let
|
||||
launchTest = pkgs.writeShellApplication {
|
||||
name = "launch-tests";
|
||||
runtimeInputs = with pkgs; [
|
||||
getopt
|
||||
jq
|
||||
fzf
|
||||
];
|
||||
|
||||
text = builtins.readFile ./launch-test.sh;
|
||||
};
|
||||
|
||||
tests =
|
||||
let
|
||||
checks' = self'.checks;
|
||||
names = builtins.filter (n: builtins.match "test-.*" n != null) (builtins.attrNames checks');
|
||||
in
|
||||
builtins.listToAttrs (
|
||||
builtins.concatMap (
|
||||
checkName:
|
||||
map (testName: {
|
||||
name = testName;
|
||||
value = "${checkName}.passthru.entries.${testName}";
|
||||
}) (builtins.attrNames checks'.${checkName}.passthru.entries)
|
||||
) names
|
||||
);
|
||||
in
|
||||
''
|
||||
export NIXVIM_SYSTEM=${system}
|
||||
export NIXVIM_NIX_COMMAND=${nix}
|
||||
export NIXVIM_TESTS=${pkgs.writers.writeJSON "tests.json" tests}
|
||||
${lib.getExe launchTest} "$@"
|
||||
'';
|
||||
}
|
||||
{
|
||||
name = "test-lib";
|
||||
help = "Run nixvim library tests";
|
||||
command = ''
|
||||
echo "=> Running nixvim library tests for the '${system}' architecture..."
|
||||
|
||||
${nix} build .#checks.${system}.lib-tests "$@"
|
||||
'';
|
||||
}
|
||||
{
|
||||
name = "format";
|
||||
help = "Format the entire codebase";
|
||||
command = "nix fmt";
|
||||
}
|
||||
{
|
||||
name = "docs";
|
||||
help = "Build nixvim documentation";
|
||||
command = ''
|
||||
echo "=> Building nixvim documentation..."
|
||||
|
||||
${nix} build .#docs "$@"
|
||||
'';
|
||||
}
|
||||
{
|
||||
name = "serve-docs";
|
||||
help = "Build and serve documentation locally";
|
||||
command = ''
|
||||
echo -e "=> Building nixvim documentation...\n"
|
||||
|
||||
doc_derivation=$(${nix} build .#docs --no-link --print-out-paths)
|
||||
|
||||
echo -e "\n=> Documentation successfully built ('$doc_derivation')"
|
||||
|
||||
echo -e "\n=> You can then open your browser to view the doc\n"
|
||||
|
||||
(cd "$doc_derivation"/share/doc && ${pkgs.lib.getExe pkgs.python3} ${./server.py})
|
||||
'';
|
||||
}
|
||||
{
|
||||
name = "locate-lsp-packages";
|
||||
command = ''${pkgs.python3.interpreter} ${./locate-lsp-packages.py}'';
|
||||
help = "Locate (with nix-index) LSP servers in nixpkgs";
|
||||
}
|
||||
{
|
||||
name = "new-plugin";
|
||||
command = ''${pkgs.python3.interpreter} ${./new-plugin.py} "$@"'';
|
||||
help = "Create a new plugin";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
115
flake/dev/launch-test.sh
Executable file
115
flake/dev/launch-test.sh
Executable file
|
@ -0,0 +1,115 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
: "${NIXVIM_NIX_COMMAND:=nix}"
|
||||
if [[ -z ${NIXVIM_SYSTEM+x} ]]; then
|
||||
NIXVIM_SYSTEM=$(nix eval --raw --impure --expr "builtins.currentSystem")
|
||||
fi
|
||||
|
||||
help() {
|
||||
cat <<EOF
|
||||
Usage: tests [OPTIONS] [tests...] -- [NIX OPTIONS...]
|
||||
|
||||
If tests are passed on the command line only these will be launched
|
||||
|
||||
All arguments after '--' starting with '-' will be passed to 'nix build'.
|
||||
For example to debug a failing test you can append '-- --show-trace'.
|
||||
|
||||
Options:
|
||||
-h, --help: Display this help message and exit
|
||||
-l, --list: Display the list of tests and exit
|
||||
-s, --system <system>: Launch checks for "<system>" instead of "${NIXVIM_SYSTEM}".
|
||||
-i, --interactive: Pick interactively the tests. Can't be supplied if tests where passed.
|
||||
EOF
|
||||
}
|
||||
|
||||
if ! OPTS=$(getopt -o "hlis:" -l "help,list,interactive,system:" -- "$@"); then
|
||||
echo "Invalid options" >&2
|
||||
help
|
||||
exit 1
|
||||
fi
|
||||
|
||||
eval set -- "$OPTS"
|
||||
|
||||
system=${NIXVIM_SYSTEM}
|
||||
specified_tests=()
|
||||
nix_args=()
|
||||
interactive=false
|
||||
|
||||
mk_test_list() {
|
||||
jq -r 'keys[]' "${NIXVIM_TESTS}"
|
||||
}
|
||||
|
||||
while true; do
|
||||
case "$1" in
|
||||
-h | --help)
|
||||
help
|
||||
exit 0
|
||||
;;
|
||||
-l | --list)
|
||||
mk_test_list
|
||||
exit 0
|
||||
;;
|
||||
-i | --interactive)
|
||||
interactive=true
|
||||
shift
|
||||
;;
|
||||
-s | --system)
|
||||
system=$2
|
||||
shift 2
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
for arg in "$@"; do
|
||||
if [[ $arg == -* ]]; then
|
||||
nix_args+=("$arg")
|
||||
else
|
||||
specified_tests+=("$arg")
|
||||
fi
|
||||
done
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
get_tests() {
|
||||
# Convert bash array to jq query
|
||||
# e.g. (foo bar baz) => ."foo",."bar",."baz"
|
||||
readarray -t queries < <(
|
||||
for test in "$@"; do
|
||||
echo '."'"$test"'"'
|
||||
done
|
||||
)
|
||||
query=$(
|
||||
IFS=,
|
||||
echo "${queries[*]}"
|
||||
)
|
||||
for test in $(jq -r "${query}" "${NIXVIM_TESTS}"); do
|
||||
echo "checks.${system}.${test}"
|
||||
done
|
||||
}
|
||||
|
||||
run_tests() {
|
||||
readarray -t test_list < <(get_tests "$@")
|
||||
if ! "${NIXVIM_NIX_COMMAND}" build "${nix_args[@]}" --no-link --file . "${test_list[@]}"; then
|
||||
echo "Test failure" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ $interactive == true && ${#specified_tests[@]} -ne 0 ]]; then
|
||||
echo "Can't use --interactive with tests on the command line" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $interactive == true ]]; then
|
||||
test_name=$(mk_test_list | fzf) || exit $?
|
||||
specified_tests+=("$test_name")
|
||||
fi
|
||||
|
||||
if [[ ${#specified_tests[@]} -eq 0 ]]; then
|
||||
readarray -t complete_test_list < <(mk_test_list)
|
||||
run_tests "${complete_test_list[@]}"
|
||||
else
|
||||
echo "Running ${#specified_tests[@]} tests: ${specified_tests[*]}" >&2
|
||||
run_tests "${specified_tests[@]}"
|
||||
fi
|
46
flake/dev/list-plugins/default.nix
Normal file
46
flake/dev/list-plugins/default.nix
Normal file
|
@ -0,0 +1,46 @@
|
|||
{ inputs, self, ... }:
|
||||
{
|
||||
perSystem =
|
||||
{
|
||||
self',
|
||||
config,
|
||||
lib,
|
||||
inputs',
|
||||
system,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
package = pkgs.writers.writePython3Bin "list-plugins" {
|
||||
# Disable flake8 checks that are incompatible with the ruff ones
|
||||
flakeIgnore = [
|
||||
# line too long
|
||||
"E501"
|
||||
# line break before binary operator
|
||||
"W503"
|
||||
];
|
||||
} (builtins.readFile ./list-plugins.py);
|
||||
in
|
||||
{
|
||||
packages.list-plugins = package;
|
||||
|
||||
checks.list-plugins-test =
|
||||
pkgs.runCommand "list-plugins-test"
|
||||
{
|
||||
nativeBuildInputs = [ package ];
|
||||
}
|
||||
''
|
||||
list-plugins --root-path ${self} > $out
|
||||
'';
|
||||
|
||||
}
|
||||
// lib.optionalAttrs (inputs.devshell ? flakeModule) {
|
||||
devshells.default.commands = [
|
||||
{
|
||||
name = "list-plugins";
|
||||
command = ''${lib.getExe package} "$@"'';
|
||||
help = "List plugins and get implementation infos";
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
282
flake/dev/list-plugins/list-plugins.py
Executable file
282
flake/dev/list-plugins/list-plugins.py
Executable file
|
@ -0,0 +1,282 @@
|
|||
import glob
|
||||
import os
|
||||
import re
|
||||
from argparse import ArgumentParser, RawTextHelpFormatter
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum
|
||||
from typing import Optional
|
||||
|
||||
# Ignore files that are not plugin definitions
|
||||
EXCLUDES: list[str] = [
|
||||
# Patterns
|
||||
"TEMPLATE.nix",
|
||||
"deprecations.nix",
|
||||
"helpers.nix",
|
||||
"renamed-options",
|
||||
"settings-options.nix",
|
||||
# Specific files
|
||||
"colorschemes/base16/theme-list.nix",
|
||||
"plugins/by-name/blink-cmp/provider-config.nix",
|
||||
"plugins/by-name/dap/dapHelpers.nix",
|
||||
"plugins/by-name/efmls-configs/packages.nix",
|
||||
"plugins/by-name/gitsigns/options.nix",
|
||||
"plugins/by-name/hydra/hydras-option.nix",
|
||||
"plugins/by-name/hydra/settings-options.nix",
|
||||
"plugins/by-name/neogit/options.nix",
|
||||
"plugins/by-name/neotest/adapters-list.nix",
|
||||
"plugins/by-name/neotest/adapters.nix",
|
||||
"plugins/by-name/neotest/options.nix",
|
||||
"plugins/by-name/none-ls/_mk-source-plugin.nix",
|
||||
"plugins/by-name/none-ls/packages.nix",
|
||||
"plugins/by-name/none-ls/prettier.nix",
|
||||
"plugins/by-name/none-ls/prettierd.nix",
|
||||
"plugins/by-name/none-ls/settings.nix",
|
||||
"plugins/by-name/none-ls/sources.nix",
|
||||
"plugins/by-name/openscad/fuzzy-finder-plugin-option.nix",
|
||||
"plugins/by-name/rustaceanvim/renamed-options.nix",
|
||||
"plugins/by-name/rustaceanvim/settings-options.nix",
|
||||
"plugins/by-name/startify/options.nix",
|
||||
"plugins/by-name/telescope/extensions/_mk-extension.nix",
|
||||
"plugins/by-name/telescope/extensions/default.nix",
|
||||
"plugins/cmp/auto-enable.nix",
|
||||
"plugins/cmp/options/",
|
||||
"plugins/cmp/sources/cmp-fish.nix",
|
||||
"plugins/cmp/sources/default.nix",
|
||||
"plugins/default.nix",
|
||||
"plugins/deprecation.nix",
|
||||
"plugins/lsp/language-servers/",
|
||||
"plugins/lsp/lsp-packages.nix",
|
||||
]
|
||||
|
||||
|
||||
class Kind(Enum):
|
||||
NEOVIM = 1
|
||||
VIM = 2
|
||||
MISC = 3
|
||||
|
||||
|
||||
class State(Enum):
|
||||
UNKNOWN = "❔"
|
||||
NEW = "✅"
|
||||
OLD = "❌"
|
||||
|
||||
|
||||
KNOWN_PATHS: dict[
|
||||
str,
|
||||
tuple[
|
||||
State, # If the implem is "legacy" or up to date
|
||||
Kind, # Vim / Neovim / misc
|
||||
bool, # Has deprecation warnings
|
||||
],
|
||||
] = {
|
||||
"plugins/by-name/chadtree/default.nix": (State.OLD, Kind.NEOVIM, False),
|
||||
"plugins/by-name/coq-thirdparty/default.nix": (State.OLD, Kind.NEOVIM, False),
|
||||
"plugins/by-name/dap/default.nix": (State.OLD, Kind.NEOVIM, False),
|
||||
"plugins/by-name/leap/default.nix": (State.OLD, Kind.NEOVIM, False),
|
||||
"plugins/by-name/lint/default.nix": (State.OLD, Kind.NEOVIM, False),
|
||||
"plugins/by-name/lspkind/default.nix": (State.OLD, Kind.NEOVIM, False),
|
||||
"plugins/by-name/nix-develop/default.nix": (State.OLD, Kind.NEOVIM, False),
|
||||
"plugins/by-name/rainbow-delimiters/default.nix": (State.OLD, Kind.NEOVIM, False),
|
||||
"plugins/by-name/treesitter-refactor/default.nix": (State.OLD, Kind.MISC, True),
|
||||
"plugins/by-name/treesitter-textobjects/default.nix": (
|
||||
State.OLD,
|
||||
Kind.NEOVIM,
|
||||
True,
|
||||
),
|
||||
"plugins/colorschemes/base16/default.nix": (State.NEW, Kind.VIM, True),
|
||||
"plugins/lsp/default.nix": (State.NEW, Kind.MISC, False),
|
||||
}
|
||||
for telescope_extension_name, has_depr_warnings in {
|
||||
"file-browser": True,
|
||||
"frecency": True,
|
||||
"fzf-native": True,
|
||||
"fzy-native": True,
|
||||
"live-greps-args": False,
|
||||
"manix": False,
|
||||
"media-files": True,
|
||||
"project": False,
|
||||
"ui-select": False,
|
||||
"undo": True,
|
||||
}.items():
|
||||
KNOWN_PATHS[
|
||||
f"plugins/by-name/telescope/extensions/{telescope_extension_name}.nix"
|
||||
] = (
|
||||
State.NEW,
|
||||
Kind.MISC,
|
||||
has_depr_warnings,
|
||||
)
|
||||
|
||||
|
||||
DEPRECATION_REGEX: list[re.Pattern] = [
|
||||
re.compile(rf".*{pattern}", re.DOTALL)
|
||||
for pattern in [
|
||||
"deprecateExtra",
|
||||
"mkRemovedOptionModule",
|
||||
"mkRenamedOptionModule",
|
||||
"optionsRenamedToSettings",
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
@dataclass
|
||||
class Plugin:
|
||||
path: str
|
||||
state: State
|
||||
kind: Kind
|
||||
dep_warnings: bool
|
||||
|
||||
def __str__(self) -> str:
|
||||
state_icon: str = self.state.value
|
||||
kind_icon: str
|
||||
match self.kind:
|
||||
case Kind.NEOVIM:
|
||||
kind_icon = "\033[94m" + " "
|
||||
case Kind.VIM:
|
||||
kind_icon = "\033[92m" + " "
|
||||
case Kind.MISC:
|
||||
kind_icon = "\033[92m" + "🟢"
|
||||
case _:
|
||||
assert False
|
||||
deprecation_icon: str = "⚠️ " if self.dep_warnings else " "
|
||||
|
||||
return (
|
||||
f"| {kind_icon}\033[0m | {state_icon} | {deprecation_icon} | {self.path}"
|
||||
)
|
||||
|
||||
def print_markdown(self) -> None:
|
||||
print(f"- [ ] {self.path} ({self.kind.name.lower()})")
|
||||
|
||||
|
||||
def has_deprecation_warnings(string: str) -> bool:
|
||||
for regex in DEPRECATION_REGEX:
|
||||
if re.match(regex, string):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def parse_file(path: str) -> Optional[Plugin]:
|
||||
file_content: str = ""
|
||||
with open(path, "r") as f:
|
||||
file_content = f.read()
|
||||
|
||||
known_path: str
|
||||
props: tuple[State, Kind, bool]
|
||||
for known_path, props in KNOWN_PATHS.items():
|
||||
if known_path in path:
|
||||
return Plugin(
|
||||
path=path,
|
||||
state=props[0],
|
||||
kind=props[1],
|
||||
dep_warnings=props[2],
|
||||
)
|
||||
|
||||
state: State = State.UNKNOWN
|
||||
kind: Kind
|
||||
if re.match(
|
||||
re.compile(r".*mkNeovimPlugin", re.DOTALL),
|
||||
file_content,
|
||||
):
|
||||
kind = Kind.NEOVIM
|
||||
state = State.NEW
|
||||
elif re.match(
|
||||
re.compile(r".*require.+setup", re.DOTALL),
|
||||
file_content,
|
||||
):
|
||||
kind = Kind.NEOVIM
|
||||
state = State.OLD
|
||||
elif re.match(
|
||||
re.compile(r".*mkVimPlugin", re.DOTALL),
|
||||
file_content,
|
||||
):
|
||||
kind = Kind.VIM
|
||||
state = State.NEW
|
||||
else:
|
||||
raise ValueError(
|
||||
f"I was not able to categorize `{path}`. Consider adding it to `EXCLUDES` or `KNOWN_PATHS`."
|
||||
)
|
||||
|
||||
return Plugin(
|
||||
path=path,
|
||||
state=state,
|
||||
kind=kind,
|
||||
dep_warnings=has_deprecation_warnings(string=file_content),
|
||||
)
|
||||
|
||||
|
||||
def _is_excluded(path: str) -> bool:
|
||||
for exclude_pattern in EXCLUDES:
|
||||
if exclude_pattern in path:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def main(args) -> None:
|
||||
pathname: str = os.path.join(args.root_path, "plugins/**/*.nix")
|
||||
paths: list[str] = glob.glob(pathname=pathname, recursive=True)
|
||||
filtered_paths: list[str] = list(filter(_is_excluded, paths))
|
||||
filtered_paths.sort()
|
||||
|
||||
if not args.markdown:
|
||||
print("| Typ | Sty | DW | path")
|
||||
print(
|
||||
"|-----|-----|----|--------------------------------------------------------"
|
||||
)
|
||||
|
||||
for plugin_path in filtered_paths:
|
||||
plugin: Optional[Plugin] = parse_file(path=plugin_path)
|
||||
if plugin is not None:
|
||||
if (
|
||||
(args.kind is None or plugin.kind.name.lower() == args.kind)
|
||||
and (args.state is None or plugin.state.name.lower() == args.state)
|
||||
and (not args.deprecation_warnings or plugin.dep_warnings)
|
||||
):
|
||||
if args.markdown:
|
||||
plugin.print_markdown()
|
||||
else:
|
||||
print(plugin)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser: ArgumentParser = ArgumentParser(
|
||||
description="""
|
||||
Analyze Nixvim plugin files
|
||||
Output formats a table showing:
|
||||
If a plugin is written for Neovim or Vim.
|
||||
If the plugin has been updated to latest style standards.
|
||||
If a plugin contains any deprecation warnings.
|
||||
""",
|
||||
formatter_class=RawTextHelpFormatter,
|
||||
)
|
||||
# TODO: consider automatically localizing the flake's root.
|
||||
parser.add_argument(
|
||||
"--root-path",
|
||||
type=str,
|
||||
default="./",
|
||||
help="The path to the root of the nixvim repo",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-k",
|
||||
"--kind",
|
||||
choices=[k.name.lower() for k in Kind],
|
||||
help="Filter plugins by kind (neovim, vim, misc)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-s",
|
||||
"--state",
|
||||
choices=[s.name.lower() for s in State],
|
||||
help="Filter plugins by state (new, old, unknown)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-d",
|
||||
"--deprecation-warnings",
|
||||
action="store_true",
|
||||
help="Show only plugins with deprecation warnings",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-m",
|
||||
"--markdown",
|
||||
action="store_true",
|
||||
help="Markdown output",
|
||||
)
|
||||
|
||||
main(parser.parse_args())
|
126
flake/dev/locate-lsp-packages.py
Executable file
126
flake/dev/locate-lsp-packages.py
Executable file
|
@ -0,0 +1,126 @@
|
|||
#!/usr/bin/env python3
|
||||
# This script requires nix-locate
|
||||
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
def find_project_root(root_identifier: str) -> None | str:
|
||||
current_path = os.getcwd()
|
||||
while True:
|
||||
if root_identifier in os.listdir(current_path):
|
||||
return current_path
|
||||
parent_path = os.path.dirname(current_path)
|
||||
if parent_path == current_path:
|
||||
return None
|
||||
os.chdir("..")
|
||||
current_path = os.getcwd()
|
||||
|
||||
|
||||
@dataclass
|
||||
class CustomCommand:
|
||||
package: str
|
||||
cmd: list[str]
|
||||
|
||||
|
||||
@dataclass
|
||||
class PackageList:
|
||||
unpackaged: list[str]
|
||||
packages: dict[str, str | list[str]]
|
||||
custom_cmd: dict[str, CustomCommand]
|
||||
|
||||
|
||||
def get_current_package(
|
||||
current_packages: PackageList, server: str
|
||||
) -> None | str | list[str]:
|
||||
if (package := current_packages.packages.get(server)) is not None:
|
||||
return package
|
||||
elif (custom_cmd := current_packages.custom_cmd.get(server)) is not None:
|
||||
return custom_cmd.package
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def search_for_package(command: list[str]) -> None | str:
|
||||
nix_locate = subprocess.run(
|
||||
[
|
||||
"nix-locate",
|
||||
"--top-level",
|
||||
"--whole-name",
|
||||
"--at-root",
|
||||
f"/bin/{command[0]}",
|
||||
],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
|
||||
if nix_locate.stdout == "":
|
||||
return None
|
||||
else:
|
||||
return nix_locate.stdout.strip()
|
||||
|
||||
|
||||
def main():
|
||||
repo = find_project_root("flake.nix")
|
||||
|
||||
# Extract the list of packages in JSON
|
||||
current_packages = subprocess.run(
|
||||
[
|
||||
"nix",
|
||||
"eval",
|
||||
"--impure",
|
||||
"--raw",
|
||||
"--expr",
|
||||
f"builtins.toJSON (import {repo}/plugins/lsp/lsp-packages.nix)",
|
||||
],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
current_packages = json.loads(current_packages.stdout)
|
||||
current_packages = PackageList(
|
||||
unpackaged=current_packages["unpackaged"],
|
||||
packages=current_packages["packages"],
|
||||
custom_cmd={
|
||||
server: CustomCommand(**info)
|
||||
for server, info in current_packages["customCmd"].items()
|
||||
},
|
||||
)
|
||||
|
||||
with open(f"{repo}/generated/lspconfig-servers.json") as f:
|
||||
generated_servers = json.load(f)
|
||||
|
||||
for info in generated_servers:
|
||||
server: str = info["name"]
|
||||
print(f"=== {server} ===")
|
||||
|
||||
current_package = get_current_package(current_packages, server)
|
||||
if current_package is not None:
|
||||
print(f" Current package: {current_package}")
|
||||
continue
|
||||
|
||||
cmd: list[str] | str | None = info.get("cmd")
|
||||
if cmd is None:
|
||||
print(" no upstream command")
|
||||
continue
|
||||
|
||||
if not isinstance(cmd, list):
|
||||
print(" upstream command is a function")
|
||||
continue
|
||||
|
||||
print(f" upstream command: {cmd}")
|
||||
|
||||
if len(cmd) == 0:
|
||||
continue
|
||||
|
||||
possible_packages = search_for_package(cmd)
|
||||
if possible_packages is None:
|
||||
print(" no package found for command")
|
||||
else:
|
||||
print(" POSSIBLE NEW PACKAGE:")
|
||||
print(possible_packages)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
146
flake/dev/new-plugin.py
Normal file
146
flake/dev/new-plugin.py
Normal file
|
@ -0,0 +1,146 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import re
|
||||
from argparse import ArgumentParser
|
||||
|
||||
# Template for default.nix
|
||||
# TODO: conditionally include parts of the template based on args
|
||||
default_nix_template = """{{ lib, ... }}:
|
||||
lib.nixvim.plugins.mkNeovimPlugin {{
|
||||
name = "{name}";
|
||||
packPathName = "{originalName}";
|
||||
package = "{package}";
|
||||
|
||||
maintainers = [ lib.maintainers.YOUR_NAME ]; # TODO
|
||||
|
||||
settingsOptions = {{
|
||||
exampleOption = lib.nixvim.defaultNullOpts.mkBool false ''
|
||||
Example option for the {name} plugin.
|
||||
'';
|
||||
}};
|
||||
}}
|
||||
"""
|
||||
|
||||
# Template for test file
|
||||
test_nix_template = """{{
|
||||
empty = {{
|
||||
plugins.{name}.enable = true;
|
||||
}};
|
||||
}}
|
||||
"""
|
||||
|
||||
|
||||
def kebab_case(input_string):
|
||||
"""
|
||||
Convert a string to kebab-case.
|
||||
|
||||
Args:
|
||||
input_string (str): The input string to convert.
|
||||
|
||||
Returns:
|
||||
str: The converted kebab-case string.
|
||||
"""
|
||||
# Replace non-alphanumeric characters with hyphens
|
||||
input_string = re.sub(r"[\W_]+", "-", input_string).lower()
|
||||
|
||||
# Remove leading and trailing standalone 'nvim'
|
||||
input_string = re.sub(r"(^nvim-|-nvim$|^nvim$)", "", input_string)
|
||||
|
||||
return input_string.strip("-")
|
||||
|
||||
|
||||
def create_nix_file(file_path, template, name, originalName, package):
|
||||
"""
|
||||
Create a nix file from a template.
|
||||
|
||||
Args:
|
||||
file_path (str): The path to the file to create.
|
||||
template (str): The template string to use for the file content.
|
||||
name (str): The name of the plugin.
|
||||
originalName (str): The original name of the plugin.
|
||||
package (str): The package name of the plugin.
|
||||
"""
|
||||
content = template.format(name=name, originalName=originalName, package=package)
|
||||
write_to_file(file_path, content)
|
||||
|
||||
|
||||
def create_test_file(file_path, template, name):
|
||||
"""
|
||||
Create a test file from a template.
|
||||
|
||||
Args:
|
||||
file_path (str): The path to the file to create.
|
||||
template (str): The template string to use for the file content.
|
||||
name (str): The name of the plugin.
|
||||
"""
|
||||
content = template.format(name=name)
|
||||
write_to_file(file_path, content)
|
||||
|
||||
|
||||
def write_to_file(file_path, content: str):
|
||||
"""
|
||||
Makes sure directories exist and write content to a file.
|
||||
|
||||
Args:
|
||||
file_path (str): The path to the file to write.
|
||||
content (str): The content to write to the file.
|
||||
"""
|
||||
os.makedirs(os.path.dirname(file_path), exist_ok=True)
|
||||
with open(file_path, "w") as f:
|
||||
f.write(content)
|
||||
|
||||
|
||||
def find_project_root(root_identifier):
|
||||
current_path = os.getcwd()
|
||||
while True:
|
||||
if root_identifier in os.listdir(current_path):
|
||||
return current_path
|
||||
parent_path = os.path.dirname(current_path)
|
||||
if parent_path == current_path:
|
||||
return None
|
||||
os.chdir("..")
|
||||
current_path = os.getcwd()
|
||||
|
||||
|
||||
# TODO: support interactive unmanaged args
|
||||
def main():
|
||||
"""
|
||||
Main function to generate default.nix and test files for a new plugin.
|
||||
"""
|
||||
parser = ArgumentParser(
|
||||
description="Generate default.nix and test files for a new plugin"
|
||||
)
|
||||
parser.add_argument(
|
||||
"originalName", type=str, help="Original name of the new plugin"
|
||||
)
|
||||
parser.add_argument("package", type=str, help="Package name of the new plugin")
|
||||
args = parser.parse_args()
|
||||
|
||||
# Calculate name
|
||||
name = kebab_case(args.originalName)
|
||||
|
||||
# Define paths
|
||||
root_identifier = "flake.nix"
|
||||
root_dir = find_project_root(root_identifier)
|
||||
|
||||
plugin_path = f"{root_dir}/plugins/by-name/{name}/default.nix"
|
||||
test_path = f"{root_dir}/tests/test-sources/plugins/by-name/{name}/default.nix"
|
||||
|
||||
# Create files
|
||||
create_nix_file(
|
||||
plugin_path,
|
||||
default_nix_template,
|
||||
name,
|
||||
args.originalName,
|
||||
args.package,
|
||||
)
|
||||
create_test_file(
|
||||
test_path,
|
||||
test_nix_template,
|
||||
name,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
16
flake/dev/server.py
Normal file
16
flake/dev/server.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
import http.server
|
||||
|
||||
PORT = 8000
|
||||
|
||||
|
||||
class UncachedHTTPHandler(http.server.SimpleHTTPRequestHandler):
|
||||
def end_headers(self):
|
||||
self.send_header("Cache-Control", "no-cache, no-store, must-revalidate")
|
||||
self.send_header("Pragma", "no-cache")
|
||||
self.send_header("Expires", "0")
|
||||
super().end_headers()
|
||||
|
||||
|
||||
with http.server.HTTPServer(("", PORT), UncachedHTTPHandler) as httpd:
|
||||
print(f"Serving documentation at http://localhost:{PORT}")
|
||||
httpd.serve_forever()
|
19
flake/legacy-packages.nix
Normal file
19
flake/legacy-packages.nix
Normal file
|
@ -0,0 +1,19 @@
|
|||
{ helpers, ... }:
|
||||
{
|
||||
perSystem =
|
||||
{
|
||||
makeNixvimWithModule,
|
||||
system,
|
||||
...
|
||||
}:
|
||||
{
|
||||
legacyPackages = rec {
|
||||
inherit makeNixvimWithModule;
|
||||
makeNixvim = module: makeNixvimWithModule { inherit module; };
|
||||
|
||||
nixvimConfiguration = helpers.modules.evalNixvim {
|
||||
inherit system;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
39
flake/lib.nix
Normal file
39
flake/lib.nix
Normal file
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
self,
|
||||
config,
|
||||
lib,
|
||||
withSystem,
|
||||
...
|
||||
}:
|
||||
{
|
||||
# Expose lib as a flake-parts module arg
|
||||
_module.args = {
|
||||
helpers = self.lib.nixvim;
|
||||
};
|
||||
|
||||
# Public `lib` flake output
|
||||
flake.lib =
|
||||
{
|
||||
nixvim = lib.makeOverridable (import ../lib) {
|
||||
inherit lib;
|
||||
flake = self;
|
||||
};
|
||||
overlay = lib.makeOverridable (import ../lib/overlay.nix) {
|
||||
flake = self;
|
||||
};
|
||||
}
|
||||
// lib.genAttrs config.systems (
|
||||
lib.flip withSystem (
|
||||
{ pkgs, system, ... }:
|
||||
{
|
||||
# NOTE: this is the publicly documented flake output we've had for a while
|
||||
check = pkgs.callPackage ../lib/tests.nix {
|
||||
inherit lib self system;
|
||||
};
|
||||
|
||||
# NOTE: no longer needs to be per-system
|
||||
helpers = lib.warn "nixvim: `<nixvim>.lib.${system}.helpers` has been moved to `<nixvim>.lib.nixvim` and no longer depends on a specific system" self.lib.nixvim;
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
18
flake/overlays.nix
Normal file
18
flake/overlays.nix
Normal file
|
@ -0,0 +1,18 @@
|
|||
{ inputs, ... }:
|
||||
{
|
||||
imports = [ inputs.flake-parts.flakeModules.easyOverlay ];
|
||||
perSystem =
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
final,
|
||||
...
|
||||
}:
|
||||
{
|
||||
overlayAttrs = {
|
||||
nixvim = {
|
||||
inherit (config.legacyPackages) makeNixvim makeNixvimWithModule;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
25
flake/packages.nix
Normal file
25
flake/packages.nix
Normal file
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
inputs,
|
||||
helpers,
|
||||
...
|
||||
}:
|
||||
{
|
||||
perSystem =
|
||||
{
|
||||
config,
|
||||
inputs',
|
||||
system,
|
||||
...
|
||||
}:
|
||||
{
|
||||
packages = import ../docs {
|
||||
inherit helpers;
|
||||
inherit system;
|
||||
inherit (inputs) nixpkgs;
|
||||
inherit (inputs') nuschtosSearch;
|
||||
};
|
||||
|
||||
# Test that all packages build fine when running `nix flake check`.
|
||||
checks = config.packages;
|
||||
};
|
||||
}
|
56
flake/templates.nix
Normal file
56
flake/templates.nix
Normal file
|
@ -0,0 +1,56 @@
|
|||
{ self, inputs, ... }:
|
||||
{
|
||||
flake.templates = {
|
||||
default = {
|
||||
path = ../templates/simple;
|
||||
description = "A simple nix flake template for getting started with nixvim";
|
||||
};
|
||||
};
|
||||
|
||||
# The following adds the template flake's checks to the main (current) flake's checks.
|
||||
# It ensures that the template's own checks are successful.
|
||||
perSystem =
|
||||
{
|
||||
pkgs,
|
||||
system,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
{
|
||||
checks =
|
||||
let
|
||||
# Approximates https://github.com/NixOS/nix/blob/7cd08ae379746749506f2e33c3baeb49b58299b8/src/libexpr/flake/call-flake.nix#L46
|
||||
# s/flake.outputs/args.outputs/
|
||||
callFlake =
|
||||
args@{
|
||||
inputs,
|
||||
outputs,
|
||||
sourceInfo,
|
||||
}:
|
||||
let
|
||||
outputs = args.outputs (inputs // { self = result; });
|
||||
result =
|
||||
outputs
|
||||
// sourceInfo
|
||||
// {
|
||||
inherit inputs outputs sourceInfo;
|
||||
_type = "flake";
|
||||
};
|
||||
in
|
||||
result;
|
||||
|
||||
templateFlakeOutputs = callFlake {
|
||||
inputs = {
|
||||
inherit (inputs) flake-parts nixpkgs;
|
||||
nixvim = self;
|
||||
};
|
||||
# Import and read the `outputs` field of the template flake.
|
||||
inherit (import ../templates/simple/flake.nix) outputs;
|
||||
sourceInfo = { };
|
||||
};
|
||||
|
||||
templateChecks = templateFlakeOutputs.checks.${system};
|
||||
in
|
||||
lib.concatMapAttrs (checkName: check: { "template-${checkName}" = check; }) templateChecks;
|
||||
};
|
||||
}
|
22
flake/tests.nix
Normal file
22
flake/tests.nix
Normal file
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
self,
|
||||
helpers,
|
||||
...
|
||||
}:
|
||||
{
|
||||
perSystem =
|
||||
{
|
||||
pkgs,
|
||||
pkgsUnfree,
|
||||
...
|
||||
}:
|
||||
{
|
||||
checks = pkgs.callPackages ../tests {
|
||||
inherit
|
||||
helpers
|
||||
pkgsUnfree
|
||||
self
|
||||
;
|
||||
};
|
||||
};
|
||||
}
|
66
flake/wrappers.nix
Normal file
66
flake/wrappers.nix
Normal file
|
@ -0,0 +1,66 @@
|
|||
{
|
||||
inputs,
|
||||
self,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
{
|
||||
perSystem =
|
||||
{ system, pkgs, ... }:
|
||||
{
|
||||
_module.args = {
|
||||
makeNixvimWithModule = import ../wrappers/standalone.nix {
|
||||
inherit lib self;
|
||||
defaultSystem = system;
|
||||
};
|
||||
};
|
||||
|
||||
checks =
|
||||
{
|
||||
home-manager-module =
|
||||
(import ../tests/modules/hm.nix {
|
||||
inherit pkgs;
|
||||
inherit (inputs) home-manager;
|
||||
nixvim = self;
|
||||
}).activationPackage;
|
||||
home-manager-extra-files-byte-compiling =
|
||||
import ../tests/modules/hm-extra-files-byte-compiling.nix
|
||||
{
|
||||
inherit pkgs;
|
||||
inherit (inputs) home-manager;
|
||||
nixvim = self;
|
||||
};
|
||||
}
|
||||
// pkgs.lib.optionalAttrs (!pkgs.stdenv.isDarwin) {
|
||||
nixos-module =
|
||||
(import ../tests/modules/nixos.nix {
|
||||
inherit system;
|
||||
inherit (inputs) nixpkgs;
|
||||
nixvim = self;
|
||||
}).config.system.build.toplevel;
|
||||
}
|
||||
// pkgs.lib.optionalAttrs pkgs.stdenv.isDarwin {
|
||||
darwin-module =
|
||||
(import ../tests/modules/darwin.nix {
|
||||
inherit system;
|
||||
inherit (inputs) nix-darwin;
|
||||
nixvim = self;
|
||||
}).system;
|
||||
};
|
||||
};
|
||||
|
||||
flake = {
|
||||
nixosModules = {
|
||||
nixvim = import ../wrappers/nixos.nix self;
|
||||
default = self.nixosModules.nixvim;
|
||||
};
|
||||
homeManagerModules = {
|
||||
nixvim = import ../wrappers/hm.nix self;
|
||||
default = self.homeManagerModules.nixvim;
|
||||
};
|
||||
nixDarwinModules = {
|
||||
nixvim = import ../wrappers/darwin.nix self;
|
||||
default = self.nixDarwinModules.nixvim;
|
||||
};
|
||||
};
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue