aboutsummaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorArpit Chakladar <arpitchakladar+git@gmail.com>2026-07-23 18:30:05 +0530
committerArpit Chakladar <arpitchakladar+git@gmail.com>2026-07-23 18:42:18 +0530
commit5032239a236595451f22ea948c42281f8aa04645 (patch)
tree5e6be8235a04614c676d8883c3c756e1b9a5f4ff /modules
parent2ad7b06ced0ffa39d20e6be41466e5bd834ee956 (diff)
downloadhome-manager-config-5032239a236595451f22ea948c42281f8aa04645.tar.gz
home-manager-config-5032239a236595451f22ea948c42281f8aa04645.zip
feat: migrate from lf to yazi as default file manager
- Replace lf module with yazi module including base16 theme - Remove file-preview and file-preview-clean scripts (no longer needed) - Add yazi-file-chooser script for XDG Desktop Portal integration - Update i3 keybinding to use yazi - Add GTK_USE_PORTAL and TERMCMD session variables - Add extraLinks support to mkScriptModule
Diffstat (limited to 'modules')
-rw-r--r--modules/desktop/i3/keybindings.nix4
-rw-r--r--modules/desktop/xdg/default.nix7
-rw-r--r--modules/file-management/default.nix4
-rw-r--r--modules/file-management/lf/default.nix69
-rw-r--r--modules/file-management/lf/icons342
-rw-r--r--modules/file-management/lf/lfrc168
-rw-r--r--modules/file-management/yazi/default.nix32
-rw-r--r--modules/file-management/yazi/theme.nix258
-rw-r--r--modules/scripts/default.nix3
-rw-r--r--modules/scripts/file-preview-clean/assertions.nix7
-rw-r--r--modules/scripts/file-preview-clean/default.nix22
-rw-r--r--modules/scripts/file-preview-clean/script.sh1
-rw-r--r--modules/scripts/file-preview/assertions.nix19
-rw-r--r--modules/scripts/file-preview/default.nix36
-rw-r--r--modules/scripts/file-preview/script.sh142
-rw-r--r--modules/scripts/lib.nix18
-rw-r--r--modules/scripts/yazi-file-chooser/default.nix24
-rw-r--r--modules/scripts/yazi-file-chooser/script.sh20
18 files changed, 362 insertions, 814 deletions
diff --git a/modules/desktop/i3/keybindings.nix b/modules/desktop/i3/keybindings.nix
index 1392426..9956f23 100644
--- a/modules/desktop/i3/keybindings.nix
+++ b/modules/desktop/i3/keybindings.nix
@@ -14,8 +14,8 @@ in
"${mod}+Return" =
lib.mkIf config.terminal.kitty.enable "exec ${lib.getExe config.terminal.kitty.package}";
"${mod}+f" =
- lib.mkIf (config.terminal.kitty.enable && config.file-management.lf.enable)
- "exec ${lib.getExe config.terminal.kitty.package} --title 'File Manager' --class file-explorer -e ${lib.getExe config.file-management.lf.package}";
+ lib.mkIf (config.terminal.kitty.enable && config.file-management.yazi.enable)
+ "exec ${lib.getExe config.terminal.kitty.package} --title 'File Manager' --class file-explorer -e ${lib.getExe config.file-management.yazi.package}";
"${mod}+s" =
lib.mkIf config.terminal.kitty.enable "exec ${lib.getExe config.terminal.kitty.package} --title 'Keybindings' --class keybindings-viewer -e ${lib.getExe config.scripts.i3-keybindings.package}";
"${mod}+q" = "kill";
diff --git a/modules/desktop/xdg/default.nix b/modules/desktop/xdg/default.nix
index 4ccefc4..45d38a4 100644
--- a/modules/desktop/xdg/default.nix
+++ b/modules/desktop/xdg/default.nix
@@ -14,12 +14,17 @@
xdg-desktop-portal-gtk
];
config.common = {
+ "org.freedesktop.impl.portal.FileChooser" = [ "termfilechooser" ];
default = [
"gtk"
];
- "org.freedesktop.impl.portal.FileChooser" = [ "termfilechooser" ];
};
xdgOpenUsePortal = true;
};
+
+ home.sessionVariables = {
+ GTK_USE_PORTAL = "1";
+ TERMCMD = lib.mkIf config.terminal.kitty.enable (lib.getExe config.terminal.kitty.package);
+ };
};
}
diff --git a/modules/file-management/default.nix b/modules/file-management/default.nix
index 5b30f43..f31f998 100644
--- a/modules/file-management/default.nix
+++ b/modules/file-management/default.nix
@@ -1,9 +1,9 @@
-# File Management - File manager and utility modules (lf, lsd, ouch)
+# File Management - File manager and utility modules (yazi, lsd, ouch)
{ ... }:
{
imports = [
- ./lf
+ ./yazi
./lsd
./ouch
];
diff --git a/modules/file-management/lf/default.nix b/modules/file-management/lf/default.nix
deleted file mode 100644
index 15d34ae..0000000
--- a/modules/file-management/lf/default.nix
+++ /dev/null
@@ -1,69 +0,0 @@
-# lf - terminal file manager
-{
- pkgs,
- lib,
- config,
- ...
-}:
-{
- options.file-management.lf = {
- enable = lib.mkEnableOption "Enables lf.";
- package = lib.mkOption {
- type = lib.types.package;
- default = pkgs.lf.overrideAttrs (old: {
- dontWrapQtApps = true;
- dontPatchShebangs = true;
- });
- description = "The lf package to use.";
- };
- };
-
- config = lib.mkIf config.file-management.lf.enable {
- assertions = [
- {
- assertion = config.scripts.file-preview.enable;
- message = "file-management.lf.enable requires scripts.file-preview.enable for file previews.";
- }
- {
- assertion = config.scripts.file-preview-clean.enable;
- message = "file-management.lf.enable requires scripts.file-preview-clean.enable to clear kitty previews.";
- }
- ];
-
- xdg.mimeApps.defaultApplications = {
- "inode/directory" = "lf.desktop";
- };
-
- programs.lf = {
- enable = true;
- package = config.file-management.lf.package;
- settings = {
- number = true;
- icons = true;
- drawbox = true;
- hidden = true;
- preview = true;
-
- shell = config.home.sessionVariables.SHELL;
- ifs = "\n";
- scrolloff = "4";
- period = "1";
- incsearch = true;
- smartcase = true;
- info = "size";
- sortby = "natural";
- dirfirst = true;
-
- cleaner = lib.getExe config.scripts.file-preview-clean.package;
- };
-
- previewer = {
- source = lib.getExe config.scripts.file-preview.package;
- };
-
- extraConfig = builtins.readFile ./lfrc;
- };
-
- home.file.".config/lf/icons".source = ./icons;
- };
-}
diff --git a/modules/file-management/lf/icons b/modules/file-management/lf/icons
deleted file mode 100644
index 8697cf2..0000000
--- a/modules/file-management/lf/icons
+++ /dev/null
@@ -1,342 +0,0 @@
-# vim:ft=conf
-
-# file types (with matching order)
-ln  # LINK
-or  # ORPHAN
-tw t # STICKY_OTHER_WRITABLE
-ow  # OTHER_WRITABLE
-st t # STICKY
-di  # DIR
-pi p # FIFO
-so s # SOCK
-bd b # BLK
-cd c # CHR
-su u # SETUID
-sg g # SETGID
-ex  # EXEC
-fi  # FILE
-
-# file extensions (vim-devicons)
-*.styl 
-*.sass 
-*.scss 
-*.htm 
-*.html 
-*.slim 
-*.haml 
-*.ejs 
-*.css 
-*.less 
-*.md 
-*.mdx 
-*.markdown 
-*.rmd 
-*.json 
-*.webmanifest 
-*.js 
-*.mjs 
-*.jsx 
-*.rb 
-*.gemspec 
-*.rake 
-*.php 
-*.py 
-*.pyc 
-*.pyo 
-*.pyd 
-*.coffee 
-*.mustache 
-*.hbs 
-*.conf 
-*.ini 
-*.yml 
-*.yaml 
-*.toml 
-*.bat 
-*.mk 
-*.jpg 
-*.jpeg 
-*.bmp 
-*.png 
-*.webp 
-*.gif 
-*.ico 
-*.twig 
-*.cpp 
-*.c++ 
-*.cxx 
-*.cc 
-*.cp 
-*.c 
-*.cs 󰌛
-*.h 
-*.hh 
-*.hpp 
-*.hxx 
-*.hs 
-*.lhs 
-*.nix 
-*.lua 
-*.java 
-*.sh 
-*.fish 
-*.bash 
-*.zsh 
-*.ksh 
-*.csh 
-*.awk 
-*.ps1 
-*.ml λ
-*.mli λ
-*.diff 
-*.db 
-*.sql 
-*.dump 
-*.clj 
-*.cljc 
-*.cljs 
-*.edn 
-*.scala 
-*.go 
-*.dart 
-*.xul 
-*.sln 
-*.suo 
-*.pl 
-*.pm 
-*.t 
-*.rss 
-'*.f#' 
-*.fsscript 
-*.fsx 
-*.fs 
-*.fsi 
-*.rs 
-*.rlib 
-*.d 
-*.erl 
-*.hrl 
-*.ex 
-*.exs 
-*.eex 
-*.leex 
-*.heex 
-*.vim 
-*.ai 
-*.psd 
-*.psb 
-*.ts 
-*.tsx 
-*.jl 
-*.pp 
-*.vue 
-*.elm 
-*.swift 
-*.xcplayground 
-*.tex 󰙩
-*.r 󰟔
-*.rproj 󰗆
-*.sol 󰡪
-*.pem 
-
-# file names (vim-devicons) (case-insensitive not supported in lf)
-*gruntfile.coffee 
-*gruntfile.js 
-*gruntfile.ls 
-*gulpfile.coffee 
-*gulpfile.js 
-*gulpfile.ls 
-*mix.lock 
-*dropbox 
-*.ds_store 
-*.gitconfig 
-*.gitignore 
-*.gitattributes 
-*.gitlab-ci.yml 
-*.bashrc 
-*.zshrc 
-*.zshenv 
-*.zprofile 
-*.vimrc 
-*.gvimrc 
-*_vimrc 
-*_gvimrc 
-*.bashprofile 
-*favicon.ico 
-*license 
-*node_modules 
-*react.jsx 
-*procfile 
-*dockerfile 
-*docker-compose.yml 
-*docker-compose.yaml 
-*compose.yml 
-*compose.yaml 
-*rakefile 
-*config.ru 
-*gemfile 
-*makefile 
-*cmakelists.txt 
-*robots.txt 󰚩
-
-# file names (case-sensitive adaptations)
-*Gruntfile.coffee 
-*Gruntfile.js 
-*Gruntfile.ls 
-*Gulpfile.coffee 
-*Gulpfile.js 
-*Gulpfile.ls 
-*Dropbox 
-*.DS_Store 
-*LICENSE 
-*React.jsx 
-*Procfile 
-*Dockerfile 
-*Docker-compose.yml 
-*Docker-compose.yaml 
-*Rakefile 
-*Gemfile 
-*Makefile 
-*CMakeLists.txt 
-
-# file patterns (vim-devicons) (patterns not supported in lf)
-# .*jquery.*\.js$ 
-# .*angular.*\.js$ 
-# .*backbone.*\.js$ 
-# .*require.*\.js$ 
-# .*materialize.*\.js$ 
-# .*materialize.*\.css$ 
-# .*mootools.*\.js$ 
-# .*vimrc.* 
-# Vagrantfile$ 
-
-# file patterns (file name adaptations)
-*jquery.min.js 
-*angular.min.js 
-*backbone.min.js 
-*require.min.js 
-*materialize.min.js 
-*materialize.min.css 
-*mootools.min.js 
-*vimrc 
-Vagrantfile 
-
-# archives or compressed (extensions from dircolors defaults)
-*.tar 
-*.tgz 
-*.arc 
-*.arj 
-*.taz 
-*.lha 
-*.lz4 
-*.lzh 
-*.lzma 
-*.tlz 
-*.txz 
-*.tzo 
-*.t7z 
-*.zip 
-*.z 
-*.dz 
-*.gz 
-*.lrz 
-*.lz 
-*.lzo 
-*.xz 
-*.zst 
-*.tzst 
-*.bz2 
-*.bz 
-*.tbz 
-*.tbz2 
-*.tz 
-*.deb 
-*.rpm 
-*.jar 
-*.war 
-*.ear 
-*.sar 
-*.rar 
-*.alz 
-*.ace 
-*.zoo 
-*.cpio 
-*.7z 
-*.rz 
-*.cab 
-*.wim 
-*.swm 
-*.dwm 
-*.esd 
-
-# image formats (extensions from dircolors defaults)
-*.jpg 
-*.jpeg 
-*.mjpg 
-*.mjpeg 
-*.gif 
-*.bmp 
-*.pbm 
-*.pgm 
-*.ppm 
-*.tga 
-*.xbm 
-*.xpm 
-*.tif 
-*.tiff 
-*.png 
-*.svg 
-*.svgz 
-*.mng 
-*.pcx 
-*.mov 
-*.mpg 
-*.mpeg 
-*.m2v 
-*.mkv 
-*.webm 
-*.ogm 
-*.mp4 
-*.m4v 
-*.mp4v 
-*.vob 
-*.qt 
-*.nuv 
-*.wmv 
-*.asf 
-*.rm 
-*.rmvb 
-*.flc 
-*.avi 
-*.fli 
-*.flv 
-*.gl 
-*.dl 
-*.xcf 
-*.xwd 
-*.yuv 
-*.cgm 
-*.emf 
-*.ogv 
-*.ogx 
-
-# audio formats (extensions from dircolors defaults)
-*.aac 
-*.au 
-*.flac 
-*.m4a 
-*.mid 
-*.midi 
-*.mka 
-*.mp3 
-*.mpc 
-*.ogg 
-*.ra 
-*.wav 
-*.oga 
-*.opus 
-*.spx 
-*.xspf 
-
-# other formats
-*.pdf 
diff --git a/modules/file-management/lf/lfrc b/modules/file-management/lf/lfrc
deleted file mode 100644
index 7ae847c..0000000
--- a/modules/file-management/lf/lfrc
+++ /dev/null
@@ -1,168 +0,0 @@
-# =========================
-# BASIC MOVEMENT (nvim-like)
-# =========================
-
-map j down
-map k up
-map h updir
-map l open
-
-map gg top
-map G bottom
-
-map <c-u> half-up
-map <c-d> half-down
-
-map <c-b> page-up
-map <c-f> page-down
-
-# =========================
-# SELECTION
-# =========================
-
-map <space> toggle
-map v invert
-map V select
-
-# =========================
-# OPENING
-# =========================
-
-map o open
-map <enter> open
-map L open
-
-# =========================
-# DIRECTORY NAVIGATION
-# =========================
-
-map H cd ..
-map gh cd ~
-map ge cd /
-
-# =========================
-# FILE OPERATIONS
-# =========================
-
-map y copy
-map x cut
-map p paste
-
-map d delete
-
-map a :push %mkdir<space>
-map A :push %touch<space>
-
-map r rename
-
-# =========================
-# SEARCH
-# =========================
-
-map / search
-map n search-next
-map N search-prev
-
-map f find
-map F find-back
-
-# =========================
-# FILTER
-# =========================
-
-map zf filter
-map zc clear
-
-# =========================
-# MARKS (vim-style)
-# =========================
-
-map m mark-save
-map ' mark-load
-
-# =========================
-# HISTORY
-# =========================
-
-map <c-o> history-prev
-map <c-i> history-next
-
-# =========================
-# RELOAD
-# =========================
-
-map R reload
-
-# =========================
-# SHELL / COMMANDS
-# =========================
-
-map ! shell
-map : read
-
-map & shell-async
-
-# =========================
-# VISUAL MODES / TAGGING
-# =========================
-
-map t tag
-map T tag-toggle
-
-# =========================
-# SORTING
-# =========================
-
-map sn set sortby name
-map ss set sortby size
-map st set sortby time
-map se set sortby ext
-
-# =========================
-# TOGGLES
-# =========================
-
-map zh set hidden!
-map zr set reverse!
-
-# =========================
-# VIEW
-# =========================
-
-map zi set info
-map zs set preview
-
-# =========================
-# JUMPS
-# =========================
-
-map [ jump-prev
-map ] jump-next
-
-# =========================
-# CLIPBOARD-LIKE
-# =========================
-
-map c clear
-map u unselect
-
-# =========================
-# MULTI-SELECTION NAV
-# =========================
-
-map J down-select
-map K up-select
-
-# =========================
-# COMMAND MODE SHORTCUTS
-# =========================
-
-map w :write
-map q quit
-map Q quit!
-
-# =========================
-# FILE INFO
-# =========================
-
-map i info
diff --git a/modules/file-management/yazi/default.nix b/modules/file-management/yazi/default.nix
new file mode 100644
index 0000000..b43ed5e
--- /dev/null
+++ b/modules/file-management/yazi/default.nix
@@ -0,0 +1,32 @@
+# yazi - Terminal file manager with native previews
+{ config, lib, ... }:
+{
+ imports = [ ./theme.nix ];
+
+ options.file-management.yazi = {
+ enable = lib.mkEnableOption "Enables yazi.";
+ package = lib.mkOption {
+ type = lib.types.package;
+ default = config.programs.yazi.finalPackage;
+ defaultText = lib.literalExpression "config.programs.yazi.finalPackage";
+ description = "The yazi package to use. Defaults to the wrapped finalPackage from programs.yazi.";
+ };
+ };
+
+ config = lib.mkIf config.file-management.yazi.enable {
+ programs.yazi = {
+ enable = true;
+ shellWrapperName = "yy";
+ enableZshIntegration = config.terminal.zsh.enable;
+ settings = {
+ mgr = {
+ show_hidden = true;
+ };
+ };
+ };
+
+ xdg.mimeApps.defaultApplications = {
+ "inode/directory" = "yazi.desktop";
+ };
+ };
+}
diff --git a/modules/file-management/yazi/theme.nix b/modules/file-management/yazi/theme.nix
new file mode 100644
index 0000000..e960d84
--- /dev/null
+++ b/modules/file-management/yazi/theme.nix
@@ -0,0 +1,258 @@
+{ config, lib, ... }:
+{
+ config = lib.mkIf config.file-management.yazi.enable {
+ programs.yazi.theme = with config.scheme.withHashtag; {
+ manager = {
+ cwd = {
+ fg = base0D;
+ };
+
+ hovered = {
+ fg = base00;
+ bg = base0D;
+ };
+ preview_hovered = {
+ underline = true;
+ };
+
+ find_keyword = {
+ fg = base0A;
+ italic = true;
+ };
+ find_position = {
+ fg = base0C;
+ bg = base00;
+ italic = true;
+ };
+
+ marker_selected = {
+ fg = base0B;
+ bg = base0B;
+ };
+ marker_copied = {
+ fg = base0A;
+ bg = base0A;
+ };
+ marker_cut = {
+ fg = base08;
+ bg = base08;
+ };
+
+ tab_active = {
+ fg = base00;
+ bg = base0D;
+ };
+ tab_inactive = {
+ fg = base05;
+ bg = base01;
+ };
+
+ count_copied = {
+ fg = base00;
+ bg = base0A;
+ };
+ count_cut = {
+ fg = base00;
+ bg = base08;
+ };
+ count_selected = {
+ fg = base00;
+ bg = base0B;
+ };
+
+ border_symbol = "│";
+ border_style = {
+ fg = base02;
+ };
+
+ syntect_theme = "";
+ };
+
+ status = {
+ separator_open = "";
+ separator_close = "";
+ separator_style = {
+ fg = base01;
+ bg = base01;
+ };
+
+ mode_normal_main = {
+ fg = base00;
+ bg = base0D;
+ bold = true;
+ };
+ mode_normal_alt = {
+ fg = base0D;
+ bg = base01;
+ };
+
+ mode_select_main = {
+ fg = base00;
+ bg = base0B;
+ bold = true;
+ };
+ mode_select_alt = {
+ fg = base0B;
+ bg = base01;
+ };
+
+ mode_unset_main = {
+ fg = base00;
+ bg = base0E;
+ bold = true;
+ };
+ mode_unset_alt = {
+ fg = base0E;
+ bg = base01;
+ };
+
+ progress_label = {
+ fg = base06;
+ bold = true;
+ };
+ progress_normal = {
+ fg = base0D;
+ bg = base01;
+ };
+ progress_error = {
+ fg = base08;
+ bg = base01;
+ };
+
+ permissions_t = {
+ fg = base0D;
+ };
+ permissions_r = {
+ fg = base0A;
+ };
+ permissions_w = {
+ fg = base08;
+ };
+ permissions_x = {
+ fg = base0B;
+ };
+ permissions_s = {
+ fg = base03;
+ };
+ };
+
+ input = {
+ border = {
+ fg = base0D;
+ };
+ selected = {
+ reversed = true;
+ };
+ };
+
+ select = {
+ border = {
+ fg = base0D;
+ };
+ active = {
+ fg = base0E;
+ };
+ };
+
+ tasks = {
+ border = {
+ fg = base0D;
+ };
+ hovered = {
+ underline = true;
+ };
+ };
+
+ which = {
+ mask = {
+ bg = base01;
+ };
+ cand = {
+ fg = base0C;
+ };
+ rest = {
+ fg = base04;
+ };
+ desc = {
+ fg = base0D;
+ };
+ separator = " ";
+ separator_style = {
+ fg = base03;
+ };
+ };
+
+ notify = {
+ title_info = {
+ fg = base0D;
+ };
+ title_warn = {
+ fg = base0A;
+ };
+ title_error = {
+ fg = base08;
+ };
+ };
+
+ pick = {
+ border = {
+ fg = base0D;
+ };
+ active = {
+ fg = base0E;
+ };
+ };
+
+ confirm = {
+ border = {
+ fg = base0D;
+ };
+ };
+
+ completion = {
+ border = {
+ fg = base0D;
+ };
+ active = {
+ fg = base00;
+ bg = base0D;
+ };
+ icon_file = "";
+ icon_folder = "";
+ icon_command = "";
+ };
+
+ mode = {
+ normal_main = {
+ fg = base00;
+ bg = base0D;
+ bold = true;
+ };
+ normal_alt = {
+ fg = base0D;
+ bg = base01;
+ };
+
+ select_main = {
+ fg = base00;
+ bg = base0B;
+ bold = true;
+ };
+ select_alt = {
+ fg = base0B;
+ bg = base01;
+ };
+
+ unset_main = {
+ fg = base00;
+ bg = base0E;
+ bold = true;
+ };
+ unset_alt = {
+ fg = base0E;
+ bg = base01;
+ };
+ };
+ };
+ };
+}
diff --git a/modules/scripts/default.nix b/modules/scripts/default.nix
index fd610d0..31b5528 100644
--- a/modules/scripts/default.nix
+++ b/modules/scripts/default.nix
@@ -8,8 +8,6 @@
imports = [
./aria2-run
./deep-clean
- ./file-preview
- ./file-preview-clean
./fzf-launcher
./i3-keybindings
./neomutt-sync
@@ -17,6 +15,7 @@
./system-monitor
./vpn-connect
./vpn-disconnect
+ ./yazi-file-chooser
];
config = {
diff --git a/modules/scripts/file-preview-clean/assertions.nix b/modules/scripts/file-preview-clean/assertions.nix
deleted file mode 100644
index b801ee3..0000000
--- a/modules/scripts/file-preview-clean/assertions.nix
+++ /dev/null
@@ -1,7 +0,0 @@
-{ config, ... }:
-[
- {
- assertion = !config.scripts.file-preview-clean.enable || config.scripts.file-preview.enable;
- message = "scripts.file-preview-clean is enabled but requires `scripts.file-preview.enable`.";
- }
-]
diff --git a/modules/scripts/file-preview-clean/default.nix b/modules/scripts/file-preview-clean/default.nix
deleted file mode 100644
index 776e042..0000000
--- a/modules/scripts/file-preview-clean/default.nix
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- config,
- lib,
- pkgs,
- ...
-}:
-let
- inherit ((import ../lib.nix { inherit lib pkgs; })) mkScriptModule;
- base = mkScriptModule {
- name = "file-preview-clean";
- path = ./script.sh;
- description = "Clear kitty icat preview after lf exits";
- deps = [ config.terminal.kitty.package ];
- inherit config;
- };
-in
-{
- options = base.options;
- config = base.moduleConfig // {
- assertions = base.moduleConfig.assertions ++ (import ./assertions.nix { inherit config lib; });
- };
-}
diff --git a/modules/scripts/file-preview-clean/script.sh b/modules/scripts/file-preview-clean/script.sh
deleted file mode 100644
index ee8ca73..0000000
--- a/modules/scripts/file-preview-clean/script.sh
+++ /dev/null
@@ -1 +0,0 @@
-exec kitten icat --clear --stdin no --transfer-mode file </dev/null >/dev/tty
diff --git a/modules/scripts/file-preview/assertions.nix b/modules/scripts/file-preview/assertions.nix
deleted file mode 100644
index 41fd4d6..0000000
--- a/modules/scripts/file-preview/assertions.nix
+++ /dev/null
@@ -1,19 +0,0 @@
-{ config, ... }:
-[
- {
- assertion = !config.scripts.file-preview.enable || config.terminal.kitty.enable;
- message = "scripts.file-preview is enabled but requires `terminal.kitty.enable`.";
- }
- {
- assertion = !config.scripts.file-preview.enable || config.media.ffmpeg.enable;
- message = "scripts.file-preview is enabled but requires `media.ffmpeg.enable`.";
- }
- {
- assertion = !config.scripts.file-preview.enable || config.file-management.ouch.enable;
- message = "scripts.file-preview is enabled but requires `file-management.ouch.enable`.";
- }
- {
- assertion = !config.scripts.file-preview.enable || config.terminal.bat.enable;
- message = "scripts.file-preview is enabled but requires `terminal.bat.enable`.";
- }
-]
diff --git a/modules/scripts/file-preview/default.nix b/modules/scripts/file-preview/default.nix
deleted file mode 100644
index eec5fb2..0000000
--- a/modules/scripts/file-preview/default.nix
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- config,
- lib,
- pkgs,
- ...
-}:
-let
- inherit ((import ../lib.nix { inherit lib pkgs; })) mkScriptModule;
- base = mkScriptModule {
- name = "file-preview";
- path = ./script.sh;
- description = "Timeout protection (prevents hanging)";
- deps = [
- config.terminal.kitty.package
- config.terminal.bat.package
- config.media.ffmpeg.package
- config.file-management.ouch.package
- pkgs.coreutils
- pkgs.file
- pkgs.findutils
- pkgs.fontconfig
- pkgs.librsvg
- pkgs.antiword
- pkgs.pandoc
- pkgs.poppler-utils
- pkgs.util-linux
- ];
- inherit config;
- };
-in
-{
- options = base.options;
- config = base.moduleConfig // {
- assertions = base.moduleConfig.assertions ++ (import ./assertions.nix { inherit config lib; });
- };
-}
diff --git a/modules/scripts/file-preview/script.sh b/modules/scripts/file-preview/script.sh
deleted file mode 100644
index 748b1ea..0000000
--- a/modules/scripts/file-preview/script.sh
+++ /dev/null
@@ -1,142 +0,0 @@
-TIMEOUT=5
-if [ -z "$LF_PREVIEW_RUNNING" ]; then
- export LF_PREVIEW_RUNNING=1
- exec timeout "$TIMEOUT" "$0" "$@"
-fi
-
-# Parameters from lf
-FILE_PATH="$1"
-WIDTH="$2"
-HEIGHT="$3"
-X="$4"
-Y="$5"
-
-# Temp dir
-TMP_DIR="/tmp/file-preview-$(id -u)"
-mkdir -p "$TMP_DIR"
-
-# Unique temp file per actual file using inode
-INODE=$(stat -c '%i' "$FILE_PATH" 2>/dev/null || echo "0")
-
-# Render image via kitty
-render_image() {
- local file="$1"
- local tries=0
- while [ ! -s "$file" ]; do
- sleep 0.2
- tries=$((tries + 1))
- done
- [ ! -s "$file" ] && exit 0
- kitten icat --stdin no --transfer-mode file --place "${WIDTH}x${HEIGHT}@${X}x${Y}" "$file" </dev/null >/dev/tty
- exit 1
-}
-
-# Ensure file exists
-[ ! -r "$FILE_PATH" ] && exit 0
-
-MIMETYPE=$(file --dereference --brief --mime-type "$FILE_PATH")
-case "$MIMETYPE" in
- # --- IMAGES ---
- image/svg+xml)
- TMP_IMG="$TMP_DIR/svg-${INODE}.png"
- if [ ! -f "$TMP_IMG" ]; then
- rsvg-convert "$FILE_PATH" -o "$TMP_IMG" >/dev/null 2>&1
- [ -s "$TMP_IMG" ] && mv "$TMP_IMG" "$TMP_IMG"
- fi
- render_image "$TMP_IMG"
- ;;
-
- image/*)
- render_image "$FILE_PATH"
- ;;
-
- # --- VIDEOS ---
- video/*)
- TMP_IMG="$TMP_DIR/vid-${INODE}.png"
- if [ ! -f "$TMP_IMG" ]; then
- if command -v ffmpegthumbnailer >/dev/null; then
- ffmpegthumbnailer -i "$FILE_PATH" -o "$TMP_IMG" -s 0 -q 5 >/dev/null 2>&1
- else
- ffmpeg -y -i "$FILE_PATH" -ss 00:00:01 -vframes 1 "$TMP_IMG" >/dev/null 2>&1
- fi
- fi
- render_image "$TMP_IMG"
- ;;
-
- # --- AUDIO ---
- audio/*)
- TMP_IMG="$TMP_DIR/aud-${INODE}.png"
- if [ ! -f "$TMP_IMG" ]; then
- ffmpeg -y -i "$FILE_PATH" \
- -filter_complex "showwavespic=s=${WIDTH}x${HEIGHT}:colors=white" \
- -frames:v 1 "$TMP_IMG" >/dev/null 2>&1
- fi
- ffprobe -hide_banner -v quiet -show_format -show_streams "$FILE_PATH"
- render_image "$TMP_IMG"
- exit 0
- ;;
-
- # --- PDF ---
- application/pdf)
- TMP_IMG="$TMP_DIR/pdf-${INODE}.png"
- if [ ! -f "$TMP_IMG" ]; then
- pdftoppm -f 1 -l 1 -png -singlefile \
- -scale-to $((WIDTH * 8)) \
- -r 72 \
- "$FILE_PATH" "${TMP_IMG%.png}" >/dev/null 2>&1
- fi
- render_image "$TMP_IMG"
- ;;
-
- # --- EPUB / MOBI ---
- application/epub+zip|application/x-mobipocket-ebook)
- TMP_IMG="$TMP_DIR/epub-${INODE}.png"
- if [ ! -f "$TMP_IMG" ]; then
- EPUB_DIR="$TMP_DIR/epub-${INODE}"
- ouch decompress --yes --dir "$EPUB_DIR" "$FILE_PATH" >/dev/null 2>&1
- COVER=$(find "$EPUB_DIR" -type f \( -iname 'cover*.jpg' -o -iname 'cover*.jpeg' -o -iname 'cover*.png' \) -print -quit)
- [ -n "$COVER" ] && cp "$COVER" "$TMP_IMG"
- fi
- [ -s "$TMP_IMG" ] && render_image "$TMP_IMG"
- ;;
-
- # --- OFFICE DOCUMENTS ---
- # Extract text in the terminal instead of pulling in a graphical office suite.
- application/vnd.openxmlformats-officedocument.wordprocessingml.document|application/vnd.oasis.opendocument.text)
- pandoc --to plain "$FILE_PATH" 2>/dev/null
- exit 0
- ;;
-
- application/msword)
- antiword "$FILE_PATH" 2>/dev/null
- exit 0
- ;;
-
- # --- ARCHIVES ---
- application/zip|application/x-7z-compressed|application/x-rar|application/x-tar|application/x-gzip)
- ouch list -t "$FILE_PATH" 2>/dev/null
- exit 0
- ;;
-
- # --- TEXT / CODE ---
- text/*|application/json|application/javascript|application/xml)
- bat --color=always --style=numbers --line-range :200 "$FILE_PATH" 2>/dev/null
- exit 0
- ;;
-
- # --- FONTS ---
- font/*|application/vnd.ms-fontobject|application/x-font-ttf)
- fc-scan "$FILE_PATH"
- exit 0
- ;;
-
- # --- FALLBACK ---
- *)
- file --dereference --brief "$FILE_PATH"
- echo "------------------------------------------------"
- hexdump -C "$FILE_PATH" | head -n 100
- exit 0
- ;;
-esac
-
-exit 0
diff --git a/modules/scripts/lib.nix b/modules/scripts/lib.nix
index 8b04b5f..cab897d 100644
--- a/modules/scripts/lib.nix
+++ b/modules/scripts/lib.nix
@@ -41,9 +41,13 @@ let
env ? { },
deps ? [ ],
desktop ? null,
+ extraLinks ? [ ],
config,
description ? "",
}:
+ let
+ scriptDrv = mkScript name path description env deps;
+ in
{
options.scripts.${name} = {
enable = lib.mkOption {
@@ -73,10 +77,22 @@ let
moduleConfig = {
scripts.${name} = lib.mkIf config.scripts.${name}.enable (
{
- package = mkScript name path description env deps;
+ package = scriptDrv;
}
// lib.optionalAttrs (desktop != null) { inherit desktop; }
);
+
+ home.file = lib.mkIf config.scripts.${name}.enable (
+ builtins.listToAttrs (
+ map (linkPath: {
+ name = lib.removePrefix "~/" linkPath;
+ value = {
+ source = "${scriptDrv}/bin/${name}";
+ };
+ }) extraLinks
+ )
+ );
+
assertions = [
{
assertion =
diff --git a/modules/scripts/yazi-file-chooser/default.nix b/modules/scripts/yazi-file-chooser/default.nix
new file mode 100644
index 0000000..d06151a
--- /dev/null
+++ b/modules/scripts/yazi-file-chooser/default.nix
@@ -0,0 +1,24 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+let
+ inherit ((import ../lib.nix { inherit lib pkgs; })) mkScriptModule;
+ base = mkScriptModule {
+ name = "yazi-file-chooser";
+ path = ./script.sh;
+ description = "Yazi-based file chooser for XDG Desktop Portal";
+ deps = [
+ config.file-management.yazi.package
+ config.terminal.kitty.package
+ ];
+ extraLinks = [ "~/.config/xdg-desktop-portal-termfilechooser/config" ];
+ inherit config;
+ };
+in
+{
+ options = base.options;
+ config = base.moduleConfig;
+}
diff --git a/modules/scripts/yazi-file-chooser/script.sh b/modules/scripts/yazi-file-chooser/script.sh
new file mode 100644
index 0000000..a2f9166
--- /dev/null
+++ b/modules/scripts/yazi-file-chooser/script.sh
@@ -0,0 +1,20 @@
+# $1 = multiple selection (1/0)
+# $2 = directory select mode (1/0)
+# $3 = save file mode (1/0)
+# $4 = initial directory path
+# $5 = output path file (where portal expects selected paths)
+
+multiple="$1"
+directory="$2"
+save="$3"
+path="$4"
+out="$5"
+
+# Pick directory vs single/multiple file
+if [ "$directory" = "1" ]; then
+ # --cwd-file outputs the final working directory path when exiting
+ exec yazi "$path" --cwd-file="$out"
+else
+ # --chooser-file writes all selected file path(s) to $out on exit
+ exec yazi "$path" --chooser-file="$out"
+fi