Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added fg plugin #8

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ If you run the release version, use the corresponding branch, for example `yazi-
| `bypass` | Skip directories with only a single sub-directory | https://github.com/Rolv-Apneseth/bypass.yazi |
| `relative-motions` | basic vim motions like 3k, 12j, 10gg | https://github.com/dedukun/relative-motions.yazi |
| `starship` | Show starship prompt in header | https://github.com/Rolv-Apneseth/starship.yazi |
| `fg` | Search by file content or by filenames using ripgrep or ripgrep-all with fzf preview. Details in [plugins/fg/README.md](plugins/fg/README.md). | https://github.com/lpnh/fg.yazi |

## Contributing
To request a new plugin or an update to an existing one, you can open an issue.
Expand Down
69 changes: 36 additions & 33 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -54,45 +54,48 @@
homeManagerModulesImports = (
map (
v:
{ config, lib, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.yazi.yaziPlugins.plugins.${v.name};
in
{
imports = (
filter (v: v != { }) [
(
inputs:
lib.mkIf (cfg.enable && inputs.config.programs.yazi.yaziPlugins.enable) (
v.config ({ inherit cfg; } // (import ./lib.nix inputs)) inputs
)
imports = filter (v: v != { }) [
(
inputs:
lib.mkIf (cfg.enable && inputs.config.programs.yazi.yaziPlugins.enable) (
v.config ({ inherit cfg pkgs; } // (import ./lib.nix inputs)) inputs
)
(_: {
config = lib.mkIf (cfg.enable && cfg.package != null) {
programs.yazi.plugins.${v.name} = cfg.package;
};
})
(_: {
config = lib.mkIf (cfg.enable && cfg ? "runtimeDeps") {
programs.yazi.yaziPlugins.runtimeDeps = cfg.runtimeDeps;
};
})
(inputs: (v.options ({ inherit cfg; } // (import ./lib.nix inputs))) inputs)
(
{ pkgs, ... }:
{
options.programs.yazi.yaziPlugins.plugins.${v.name} = {
package = mkOption {
type = lib.types.nullOr lib.types.package;
description = "The ${v.name} package to use";
default = self.packages.${pkgs.system}.${v.name};
};
enable = mkEnableOption v.name;
)
(_: {
config = lib.mkIf (cfg.enable && cfg.package != null) {
programs.yazi.plugins.${v.name} = cfg.package;
};
})
(_: {
config = lib.mkIf (cfg.enable && cfg ? "runtimeDeps") {
programs.yazi.yaziPlugins.runtimeDeps = cfg.runtimeDeps;
};
})
(inputs: (v.options ({ inherit cfg; } // (import ./lib.nix inputs))) inputs)
(
{ pkgs, ... }:
{
options.programs.yazi.yaziPlugins.plugins.${v.name} = {
package = mkOption {
type = lib.types.nullOr lib.types.package;
description = "The ${v.name} package to use";
default = self.packages.${pkgs.system}.${v.name};
};
}
)
]
);
enable = mkEnableOption v.name;
};
}
)
];
}
) (attrValues homeManagerModulesRaised)
);
Expand Down
14 changes: 10 additions & 4 deletions module.nix
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
...
}:
let
inherit (lib) mkEnableOption mkOption;
inherit (lib) mkEnableOption mkPackageOption mkOption;
inherit (lib.types) lines;
cfg = config.programs.yazi.yaziPlugins;
in
{
options.programs.yazi.yaziPlugins = {
enable = mkEnableOption "yaziPlugins";
yaziBasePackage = mkPackageOption pkgs "yazi" { };
runtimeDeps = mkOption {
type = lib.types.listOf (lib.types.either lib.types.package lib.types.str);
description = ''
Expand All @@ -24,8 +25,13 @@ in
};
};
config = lib.mkIf (cfg.runtimeDeps != [ ]) {
programs.yazi.package = pkgs.yazi.override {
extraPackages = config.programs.yazi.yaziPlugins.runtimeDeps;
};
programs.yazi.package = cfg.yaziBasePackage.override (
# This is for the yazi wrapper from nixpkgs
if (lib.functionArgs cfg.yaziBasePackage.override) ? extraPackages then
{ extraPackages = cfg.runtimeDeps; }
# This is for the yazi wrapper from its flake
else
{ runtimeDeps = ps: ps ++ cfg.runtimeDeps; }
);
};
}
158 changes: 158 additions & 0 deletions plugins/fg/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
The following config can be used in a nix file imported from home manager to enable the plugin:

```nix
{ pkgs, ... }:

{
programs.yazi = {
enable = true;
plugins = {
fg = pkgs.yaziPlugins.fg;
};
keymap = {
# Basic yazi keybinds - only the first three have something to do with the plugin itself,
# the remainder are some of the default yazi keybinds. Those have to be re-defined explicitly as otherwise
# they will stop working. This is because the entire keybinds file is overwritten using the
# keybinds defined here, so any keybind not explicitly defined here will not work.
# All default keybinds can be found at https://github.com/sxyazi/yazi/blob/main/yazi-config/preset/keymap-default.toml
manager.keymap = [
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the reason you needed to explicitly redefine all the default keybinds is that you used manager.keymap instead of manager.prepend_keymap or manager.append_keymap.

I never had to redefine these keybinds.
Incidentally I think it's still useful to keep the nixified default keybinds around in this repo or the home-manager repo because it would allow us to check for conflicts between keybinds better. I'm working on a PR for the upstream home-manager yazi module that adds such a check: nix-community/home-manager#6343

{ on = [ "f" "f" ]; run = "plugin fg --args='fzf'"; desc = "find file by filename"; }
{ on = [ "f" "g" ]; run = "plugin fg"; desc = "find file by content (fuzzy match)"; }
{ on = [ "f" "G" ]; run = "plugin fg --args='rg'"; desc = "find file by content (exact match)"; }

{ on = [ "<Left>" ]; run = "leave"; desc = "Go back to the parent directory"; }
{ on = [ "<Down>" ]; run = "arrow 1"; desc = "Move cursor down"; }
{ on = [ "<Up>" ]; run = "arrow -1"; desc = "Move cursor up"; }
{ on = [ "<Right>" ]; run = "enter"; desc = "Enter the child directory"; }


# tabs

{ on = [ "t" ]; run = "tab_create --current"; desc = "Create a new tab using the current path"; }
{ on = [ "<C-q>" ]; run = "close"; desc = "Close the current tab, or quit if it is last tab"; }
{ on = [ "1" ]; run = "tab_switch 0"; desc = "Switch to the first tab"; }
{ on = [ "2" ]; run = "tab_switch 1"; desc = "Switch to the second tab"; }
{ on = [ "3" ]; run = "tab_switch 2"; desc = "Switch to the third tab"; }
{ on = [ "4" ]; run = "tab_switch 3"; desc = "Switch to the fourth tab"; }
{ on = [ "5" ]; run = "tab_switch 4"; desc = "Switch to the fifth tab"; }
{ on = [ "6" ]; run = "tab_switch 5"; desc = "Switch to the sixth tab"; }
{ on = [ "7" ]; run = "tab_switch 6"; desc = "Switch to the seventh tab"; }
{ on = [ "8" ]; run = "tab_switch 7"; desc = "Switch to the eighth tab"; }
{ on = [ "9" ]; run = "tab_switch 8"; desc = "Switch to the ninth tab"; }
{ on = [ "0" ]; run = "tab_switch 9"; desc = "Switch to the tenth tab"; }


# goto

{ on = [ "g" "h" ]; run = "cd ~"; desc = "Go to home"; }


# selection

{ on = [ "<Space>" ]; run = [ "select --state=none" "arrow 1" ]; desc = "Toggle the current selection state"; }
{ on = [ "<C-a>" ]; run = "select_all --state=true"; desc = "Select all files"; }
{ on = [ "<C-r>" ]; run = "select_all --state=none"; desc = "Inverse selection of all files"; }
{ on = [ "m" ]; run = "visual_mode"; desc = "Enter visual mode (selection mode)"; }
{ on = [ "M" ]; run = "visual_mode --unset"; desc = "Enter visual mode (unset mode)"; }


# basic file operations

{ on = [ "<Enter>" ]; run = "open"; desc = "Open the selected files"; }
{ on = [ "<C-Enter>" ]; run = "open --interactive"; desc = "Open the selected files interactively"; }
{ on = [ "y" ]; run = "yank"; desc = "Copy the selected files"; }
{ on = [ "Y" ]; run = "unyank"; desc = "Cancel the yank status of files"; }
{ on = [ "x" ]; run = "yank --cut"; desc = "Cut the selected files"; }
{ on = [ "X" ]; run = "unyank"; desc = "Cancel the yank status of files"; }
{ on = [ "p" ]; run = "paste"; desc = "Paste the files"; }
{ on = [ "P" ]; run = "paste --force"; desc = "Paste the files (overwrite if the destination exists)"; }
{ on = [ "-" ]; run = "link"; desc = "Symlink the absolute path of files"; }
{ on = [ "—" ]; run = "link --relative"; desc = "Symlink the relative path of files"; }
{ on = [ "d" ]; run = "remove --permanently"; desc = "Delete the files"; } # I don't use the trash, use permanent delete by default.
{ on = [ "a" ]; run = "create"; desc = "Create a file or directory (ends with / for directories)"; }
{ on = [ "r" ]; run = "rename --cursor=before_ext"; desc = "Rename a file or directory"; }


# extra operations

{ on = [ ":" ]; run = "shell --interactive --block"; desc = "Run a shell command (block until command finishes)"; }
{ on = [ ";" ]; run = "shell --interactive"; desc = "Run a shell command"; }


# copying paths

{ on = [ "," "c" ]; run = "copy path"; desc = "Copy the absolute path"; }
{ on = [ "," "d" ]; run = "copy dirname"; desc = "Copy the path of the parent directory"; }
{ on = [ "," "f" ]; run = "copy filename"; desc = "Copy the name of the file"; }
{ on = [ "," "n" ]; run = "copy name_without_ext"; desc = "Copy the name of the file without the extension"; }


# filtering and searching

{ on = [ "/" ]; run = "find --smart"; desc = "Find next file"; }
{ on = [ "?" ]; run = "find --previous --smart"; desc = "Find previous file"; }
{ on = [ "n" ]; run = "find_arrow"; desc = "Go to next found file"; }
{ on = [ "N" ]; run = "find_arrow --previous"; desc = "Go to previous found file"; }
{ on = [ "s" ]; run = "search fd"; desc = "Search files by name using fd"; }
{ on = [ "S" ]; run = "search rg"; desc = "Search files by content using ripgrep"; }
{ on = [ "<C-s>" ]; run = "search none"; desc = "Cancel the ongoing search"; }


# exiting

{ on = [ "<Esc>" ]; run = "escape"; desc = "Exit visual mode, clear selected, or cancel search"; }
{ on = [ "q" ]; run = "quit"; desc = "Exit the process"; }
{ on = [ "Q" ]; run = "quit --no-cwd-file"; desc = "Exit the process without writing cwd-file"; }


# misc

{ on = [ "." ]; run = "hidden toggle"; desc = "Toggle the visibility of hidden files"; }
{ on = [ "w" ]; run = "tasks_show"; desc = "Show the tasks manager"; }
{ on = [ "h" ]; run = "help"; desc = "Open help"; }

];
};
};
}
```

If using flakes, the overlay needs to be enabled in flake.nix for this to work, e.g.:

```nix
{
inputs = {
#...
nix-yazi-plugins = {
url = "git+ssh://[email protected]/lordkekz/nix-yazi-plugins";
inputs.nixpkgs.follows = "nixpkgs";
};
};

outputs = inputs@{
#...
nix-yazi-plugins,
...
}: {
nixosConfigurations = {
my-system-name = nixpkgs.lib.nixosSystem rec {
system = "x86_64-linux";
#...
modules = [
{
# Here, the overlay is activated
nixpkgs.overlays = [
nix-yazi-plugins.overlays.default
];
}
home-manager.nixosModules.home-manager {
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.users.wojtek = import ./home.nix;
}
];
};
};
};
}
```
Comment on lines +120 to +158
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not plugin-specific and most of it isn't even specific to this project. While I appreciate the effort I think we should expect users to know how to apply overlays on their config (since there are multiple ways to do it and tradeoffs depending on the use case).

67 changes: 67 additions & 0 deletions plugins/fg/hm-module.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
{
options =
{ mkKeyOption, ... }:
{ lib, ... }:
{
enableRuntimeDependencies = lib.mkOption {
default = true;
example = false;
description = ''
Whether to add the required runtime packages
to `programs.yazi.yaziPlugins.runtimeDeps`.

They are currently: bat fzf ripgrep-all
'';
type = lib.types.bool;
};
keys = {
findByName = mkKeyOption {
on = [
"f"
"f"
];
run = "plugin fg --args='fzf'";
desc = "find file by filename";
};
findByContentFuzzy = mkKeyOption {
on = [
"f"
"g"
];
run = "plugin fg";
desc = "find file by content (fuzzy match)";
};
findByContentExact = mkKeyOption {
on = [
"f"
"G"
];
run = "plugin fg --args='rg'";
desc = "find file by content (exact match)";
};
};
};
config =
{
cfg,
setKeys,
pkgs,
...
}:
{ lib, ... }:
lib.mkMerge [
(setKeys cfg.keys)
{
# Note: If dependencies are missing here, the plugin might still work
# if the dependencies are available on your regular PATH.
programs.yazi.yaziPlugins.runtimeDeps = lib.mkIf cfg.enableRuntimeDependencies (
with pkgs;
[
bat
fzf
ripgrep-all
]
);
}
];
}
30 changes: 30 additions & 0 deletions plugins/fg/package.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
lib,
stdenv,
fetchFromGitHub,
}:

stdenv.mkDerivation {
pname = "yaziPlugins-fg";
version = "2024-11-09";

src = fetchFromGitHub {
owner = "lpnh";
repo = "fg.yazi";
rev = "a7e1a828ef4dfb01ace5b03fe0691c909466a645";
sha256 = "QxtWyp91XcW8+PSYtER47Pcc1Y9i3LplJyTzeC5Gp2s=";
};

buildPhase = ''
mkdir $out
cp $src/* $out
'';

meta = with lib; {
description = "A Yazi plugin for searching by file content or by filenames using ripgrep or ripgrep-all with fzf preview.";
homepage = "https://github.com/lpnh/fg.yazi";
license = licenses.mit;
maintainers = [ ];
platforms = platforms.all;
};
}
3 changes: 2 additions & 1 deletion plugins/relative-motions/hm-module.nix
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
show_motion = lib.mkEnableOption "Shows current motion in Status bar";
only_motions = lib.mkEnableOption ''
If true, only the motion movements will be enabled,
i.e., the commands for delete, cut, yank and visual selection will be disabled'';
i.e., the commands for delete, cut, yank and visual selection will be disabled
'';
};
config =
{ cfg, setKeys, ... }:
Expand Down