zellijPlugins: init

This commit is contained in:
PerchunPak
2026-03-02 19:26:40 +01:00
committed by Perchun Pak
parent 37ac128b2b
commit 6c6cee98a0
11 changed files with 303 additions and 5 deletions

View File

@@ -526,3 +526,6 @@ pkgs/by-name/wa/warp-terminal/ @emilytrau @imadnyc @FlameFlag @johnrtitor
# Radicle
/pkgs/build-support/fetchradicle/ @NixOS/radicle
/pkgs/build-support/fetchradiclepatch/ @NixOS/radicle
# Zellij plugins
/pkgs/by-name/ze/zellij/plugins/ @PerchunPak

View File

@@ -0,0 +1,35 @@
{
lib,
callPackage,
makeBinaryWrapper,
stdenvNoCC,
nix-update-script,
extraPackages ? [ ],
}:
let
unwrapped = callPackage ./unwrapped.nix { };
in
stdenvNoCC.mkDerivation {
inherit (unwrapped) version meta;
pname = "zellij";
__structuredAttrs = true;
strictDeps = true;
src = unwrapped;
dontUnpack = true;
nativeBuildInputs = [ makeBinaryWrapper ];
buildPhase = ''
cp -rs --no-preserve=mode "$src" "$out"
wrapProgram "$out/bin/zellij" \
--prefix PATH : '${lib.makeBinPath extraPackages}'
'';
passthru = unwrapped.passthru or { } // {
inherit unwrapped;
updateScript = nix-update-script { attrPath = "zellij.unwrapped"; };
};
}

View File

@@ -0,0 +1,83 @@
# Zellij plugins
Zellij offers a Webassembly / WASI plugin system, allowing plugin developers to
develop plugins in many different languages. Currently, nixpkgs focuses only on
Rust plugins (the majority of them).
Most of the plugins were generated using `nix-init` on [awesome-zellij].
Excluded plugins from that list (should be packaged later anyway):
- [bar-theme-config](https://github.com/allisonhere/zellij-bar-theme-config): not a plugin, but a separate application
- [fzf-zellij](https://github.com/k-kuroguro/fzf-zellij): [closed source](https://github.com/k-kuroguro/fzf-zellij/issues/1)
- [gitpod-zellij](https://github.com/ona-samples/gitpod.zellij): not a plugin, but a separate application?
- [opencode-zellij-namer](https://github.com/24601/opencode-zellij-namer): written in TypeScript, not Rust
- [theme-configurator](https://rosmur.github.io/zellij-theme-configurator/): not a plugin, but a separate application
- [yazelix](https://github.com/luccahuguet/yazelix): written in Nushell
- [zeco](https://github.com/julianbuettner/zeco): not a plugin, but a separate application?
- [zellij-load](https://github.com/Christian-Prather/zellij-load): has daemon, so that needs to be packaged too
- [zellij-vscode-toolkit](https://github.com/atoolz/zellij-vscode-toolkit): not a plugin, but a VSCode plugin
- [zellix](https://github.com/EmeraldPandaTurtle/zellix): written in Nushell
- [zj-quit](https://github.com/cristiand391/zj-quit): archived
- [zj-status-bar](https://github.com/cristiand391/zj-status-bar): archived
- [zrw](https://github.com/ivoronin/zrw): written in Go
Contributions are welcome!
[awesome-zellij]: https://github.com/zellij-org/awesome-zellij/blob/95fce2c02a2dcca33e4972eed3eba64d516693c9/README.md
## Specifying runtime dependencies
Runtime dependencies are packages, that will be used by the plugin inside
a Zellij session. Those are specified in `passthru.runtimeDeps` attribute from
`pkgsBuildBuild` attrset.
Since we compile all plugins on WASI, everything that the plugin gets as
derivation arguments are also get compiled for WASI. However, `coreutils` is
not available on WASI and so is the vast majority of packages. This is why
runtime dependencies need to be specified from `pkgsBuildBuild` attrs set
(which points to the user's system).
```nix
# assume we build the plugin on a x86_64-linux machine
{
lib,
fetchFromGitHub,
rustPlatform,
# these will be compiled for WASI, not x86_64-linux!
just,
bacon,
# but pkgsBuildBuild points to x86_64-linux
pkgsBuildBuild,
}:
rustPlatform.buildRustPackage (finalAttrs: {
pname = "jbz";
version = "0.39.0";
src = fetchFromGitHub {
owner = "nim65s";
repo = "jbz";
tag = "v${finalAttrs.version}";
hash = "sha256-3n3Bv3YDb1+MYJTTAmMkIgGY7kX9IVUoDNV4c/n0Ydo=";
};
cargoHash = "sha256-U+P2LlhmXwaZy2a2eigrg545HTuV1T01jZfUOEUQ5+w=";
# this is the only way how to specify dependencies
passthru.runtimeDeps = with pkgsBuildBuild; [
bacon
just
];
meta = {
description = "Display your Just commands wrapped in Bacon";
homepage = "https://github.com/nim65s/jbz";
changelog = "https://github.com/nim65s/jbz/releases/tag/${finalAttrs.src.tag}";
license = lib.licenses.mit;
maintainers = with lib.maintainers; [ PerchunPak ];
};
})
```
If you are wondering why `pkgsBuildBuild` is named like that, refer to
[the docs on cross-compilation](https://nixos.org/manual/nixpkgs/unstable/#possible-dependency-types).

View File

@@ -0,0 +1,53 @@
{
lib,
callPackage,
nix-update-script,
stdenvNoCC,
zellij,
}:
let
# wrapper for changing the output path from directory to single file
# from /nix/store/...-zsm-static-wasm32-unknown-wasi-0.4.1/bin/zsm.wasm
# to /nix/store/...-zellij-plugin-zsm-0.4.1.wasm
wrapper =
attrName: pkg:
assert lib.assertMsg (
!((lib.hasAttr "runtimeDeps" pkg) && (!lib.hasAttr "runtimeDeps" pkg.passthru))
) "Plugin ${pkg.pname} has specified `runtimeDeps` instead of `passthru.runtimeDeps`";
stdenvNoCC.mkDerivation (finalAttrs: {
inherit (pkg)
pname
version
;
name = "zellij-plugin-${finalAttrs.pname}-${finalAttrs.version}.wasm";
src = pkg;
dontUnpack = true;
buildPhase = ''
resultFile=$(find "$src" -name '*.wasm')
if [ $(echo "$resultFile" | wc -l) -ne 1 ]; then
echo "The unwrapped plugin ($src) contains more than one WASM file"
echo "$resultFile"
exit 1
fi
# there should probably be `ln -s` here, but it produces a permission error for me
cp "$resultFile" "$out"
'';
passthru = pkg.passthru or { } // {
unwrapped = pkg;
updateScript = pkg.passthru.updateScript or nix-update-script {
attrPath = "zellijPlugins.${attrName}.unwrapped";
};
};
meta = pkg.meta // {
maintainers = pkg.meta.maintainers or [ ] ++ [ lib.maintainers.PerchunPak ];
platforms = pkg.meta.platforms or zellij.platforms;
};
});
rustPlugins = lib.mapAttrs wrapper (callPackage ./rust { });
in
rustPlugins // { inherit wrapper; }

View File

@@ -0,0 +1,25 @@
{ pkgsCross, lib }:
let
root = ./.;
pkgs' = pkgsCross.wasi32;
call = name: override (pkgs'.callPackage (root + "/${name}") { });
override =
pkg:
pkg.overrideAttrs (old: {
# these hacks are needed until https://github.com/NixOS/nixpkgs/pull/463720#pullrequestreview-3841639011 is resolved
nativeBuildInputs = old.nativeBuildInputs or [ ] ++ [ pkgs'.lld ];
env = old.env or { } // {
RUSTFLAGS = old.env.RUSTFLAGS or "" + " -C linker=wasm-ld";
};
meta = old.meta or { } // {
platforms = old.meta.platforms or lib.platforms.linux;
};
});
in
lib.pipe root [
builtins.readDir
(lib.filterAttrs (name: _: name != "default.nix" && name != "README.md"))
(lib.mapAttrs' (name: _: lib.nameValuePair (lib.removeSuffix ".nix" name) (call name)))
]

View File

@@ -0,0 +1,32 @@
{
lib,
fetchFromGitHub,
rustPlatform,
pkgsBuildBuild,
}:
rustPlatform.buildRustPackage (finalAttrs: {
pname = "jbz";
version = "0.39.0";
src = fetchFromGitHub {
owner = "nim65s";
repo = "jbz";
tag = "v${finalAttrs.version}";
hash = "sha256-3n3Bv3YDb1+MYJTTAmMkIgGY7kX9IVUoDNV4c/n0Ydo=";
};
cargoHash = "sha256-U+P2LlhmXwaZy2a2eigrg545HTuV1T01jZfUOEUQ5+w=";
passthru.runtimeDeps = with pkgsBuildBuild; [
bacon
just
];
meta = {
description = "Display your Just commands wrapped in Bacon";
homepage = "https://github.com/nim65s/jbz";
changelog = "https://github.com/nim65s/jbz/releases/tag/${finalAttrs.src.tag}";
license = lib.licenses.mit;
maintainers = with lib.maintainers; [ PerchunPak ];
};
})

View File

@@ -0,0 +1,26 @@
{
lib,
rustPlatform,
fetchFromGitHub,
}:
rustPlatform.buildRustPackage (finalAttrs: {
pname = "vim-zellij-navigator";
version = "0.3.0";
src = fetchFromGitHub {
owner = "hiasr";
repo = "vim-zellij-navigator";
tag = finalAttrs.version;
hash = "sha256-1zzY1Z8ZpiNTdFW+gKRYaRR+oCzMnbJA2szY0k24bGg=";
};
cargoHash = "sha256-AbfgDhQEbm5qULw2HHxG5EMCYdML4VhHxJaAqP2g3u0=";
meta = {
description = "Seamless navigation between Zellij panes and Vim splits";
homepage = "https://github.com/hiasr/vim-zellij-navigator";
changelog = "https://github.com/hiasr/vim-zellij-navigator/releases/tag/${finalAttrs.src.tag}";
license = lib.licenses.mit;
maintainers = with lib.maintainers; [ PerchunPak ];
};
})

View File

@@ -0,0 +1,12 @@
{ callPackage }:
# zjstatus and zjframes are contained in the same repository, but as different crates
let
zjstatus = callPackage ./zjstatus.nix { _binaryName = "zjframes"; };
in
zjstatus.overrideAttrs (old: {
pname = "zjframes";
meta = old.meta // {
description = "Toggle Zellij pane frames based on different conditions";
};
})

View File

@@ -0,0 +1,30 @@
{
lib,
fetchFromGitHub,
rustPlatform,
_binaryName ? "zjstatus", # passed to `cargo build --bin`
}:
rustPlatform.buildRustPackage (finalAttrs: {
pname = "zjstatus";
version = "0.23.0";
src = fetchFromGitHub {
owner = "dj95";
repo = "zjstatus";
tag = "v${finalAttrs.version}";
hash = "sha256-sjMs63OaRhwCrl46v1A+K2EJdqnw63Pc7BMnHqiU790=";
};
cargoHash = "sha256-jg7EpcA3o/Qdb1eIspZQI3TX3+7gc3YX+FB4l4FZX44=";
cargoBuildFlags = [ "--bin=${_binaryName}" ];
meta = {
description = "Configurable statusbar plugin for Zellij";
homepage = "https://github.com/dj95/zjstatus";
changelog = "https://github.com/dj95/zjstatus/releases/tag/${finalAttrs.src.tag}";
license = lib.licenses.mit;
maintainers = with lib.maintainers; [ PerchunPak ];
};
})

View File

@@ -10,11 +10,10 @@
openssl,
writableTmpDirAsHomeHook,
versionCheckHook,
nix-update-script,
}:
rustPlatform.buildRustPackage (finalAttrs: {
pname = "zellij";
pname = "zellij-unwrapped";
version = "0.44.3";
__structuredAttrs = true;
@@ -71,14 +70,12 @@ rustPlatform.buildRustPackage (finalAttrs: {
installManPage zellij.1
''
+ lib.optionalString (stdenv.buildPlatform.canExecute stdenv.hostPlatform) ''
installShellCompletion --cmd $pname \
installShellCompletion --cmd zellij \
--bash <($out/bin/zellij setup --generate-completion bash) \
--fish <($out/bin/zellij setup --generate-completion fish) \
--zsh <($out/bin/zellij setup --generate-completion zsh)
'';
passthru.updateScript = nix-update-script { };
meta = {
description = "Terminal workspace with batteries included";
homepage = "https://zellij.dev/";

View File

@@ -3511,6 +3511,8 @@ with pkgs;
nvidiaSupport = true;
};
zellijPlugins = recurseIntoAttrs (callPackage ../by-name/ze/zellij/plugins { });
zstd = callPackage ../tools/compression/zstd {
cmake = buildPackages.cmakeMinimal;
};