From 9254d170236eeb9d9e113915c89ec4cab34a5f98 Mon Sep 17 00:00:00 2001 From: Arpit Chakladar Date: Thu, 24 Sep 2026 04:40:56 +0530 Subject: feat(communication/neomutt): added auto syncing daemon that runs with the client --- modules/communication/neomutt/default.nix | 55 +++++++++++++++++++--- modules/communication/neomutt/neomutt-launcher.sh | 16 +++++++ .../communication/neomutt/neomutt-sync-daemon.sh | 39 +++++++++++++++ 3 files changed, 104 insertions(+), 6 deletions(-) create mode 100644 modules/communication/neomutt/neomutt-launcher.sh create mode 100644 modules/communication/neomutt/neomutt-sync-daemon.sh (limited to 'modules/communication') diff --git a/modules/communication/neomutt/default.nix b/modules/communication/neomutt/default.nix index e091a7d..3354213 100644 --- a/modules/communication/neomutt/default.nix +++ b/modules/communication/neomutt/default.nix @@ -8,6 +8,12 @@ let cfg = config.communication.neomutt; + mbsyncNamesFromName = (import ./lib.nix { inherit lib; }).mbsyncNamesFromName; + + fullSyncChannels = lib.mapAttrsToList (name: account: (mbsyncNamesFromName name).channels.full) ( + lib.filterAttrs (name: account: account.enable) config.communication.neomutt.accounts + ); + neomuttSyncScript = pkgs.writeShellApplication { name = "neomutt-sync"; runtimeInputs = [ @@ -23,6 +29,37 @@ let text = builtins.readFile ./neomutt-sync.sh; }; + neomuttSyncDaemon = pkgs.writeShellApplication { + name = "neomutt-sync-daemon"; + runtimeInputs = [ + config.terminal.bash.package + pkgs.coreutils + pkgs.procps + config.programs.mbsync.package + config.programs.notmuch.package + ]; + text = builtins.readFile ./neomutt-sync-daemon.sh; + }; + + neomuttLauncher = pkgs.writeShellScriptBin "neomutt" ( + builtins.replaceStrings + [ + "@@SYSTEMCTL@@" + "@@PGREP@@" + "@@NEOMUTT@@" + "@@PROFILE_BIN@@" + "@@URLSCAN_BIN@@" + ] + [ + (lib.getExe' pkgs.systemd "systemctl") + (lib.getExe' pkgs.procps "pgrep") + (lib.getExe pkgs.neomutt) + "${config.home.profileDirectory}/bin" + (lib.makeBinPath [ pkgs.urlscan ]) + ] + (builtins.readFile ./neomutt-launcher.sh) + ); + neomuttSyncCompletion = pkgs.runCommand "neomutt-sync-completion" { @@ -72,19 +109,15 @@ in (builtins.readFile ./mailcap); home.file.".local/share/icons/hicolor/scalable/apps/neomutt.svg".source = config.lib.file.mkOutOfStoreSymlink "${config.programs.neomutt.package}/share/neomutt/logo/neomutt.svg"; + programs.neomutt = { enable = true; package = pkgs.symlinkJoin { name = "neomutt-wrapped"; paths = [ - pkgs.neomutt + neomuttLauncher neomuttSync ]; - nativeBuildInputs = [ pkgs.makeWrapper ]; - postBuild = '' - wrapProgram $out/bin/neomutt \ - --prefix PATH : ${config.home.profileDirectory}/bin:${lib.makeBinPath [ pkgs.urlscan ]} - ''; meta.mainProgram = "neomutt"; }; sidebar.enable = true; @@ -96,6 +129,16 @@ in builtins.readFile ./.neomuttrc ); }; + + systemd.user.services.neomutt-sync = { + Unit = { + Description = "Full mail sync while neomutt is running"; + }; + Service = { + Type = "simple"; + ExecStart = "${lib.getExe neomuttSyncDaemon} ${lib.concatStringsSep " " fullSyncChannels}"; + }; + }; }) (lib.mkIf (cfg.enable && config.terminal.kitty.enable) { xdg.desktopEntries."neomutt" = { diff --git a/modules/communication/neomutt/neomutt-launcher.sh b/modules/communication/neomutt/neomutt-launcher.sh new file mode 100644 index 0000000..d677680 --- /dev/null +++ b/modules/communication/neomutt/neomutt-launcher.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +# Wrapped neomutt: keeps the neomutt-sync systemd daemon alive for the +# lifetime of a neomutt session. +set -uo pipefail +SYSTEMCTL='@@SYSTEMCTL@@' +PGREP='@@PGREP@@' +NEOMUTT='@@NEOMUTT@@' + +"$SYSTEMCTL" --user start neomutt-sync.service || true +stop_service() { + "$PGREP" -x neomutt >/dev/null || "$SYSTEMCTL" --user stop neomutt-sync.service || true +} +trap stop_service EXIT + +export PATH="@@PROFILE_BIN@@:@@URLSCAN_BIN@@:$PATH" +"$NEOMUTT" "$@" diff --git a/modules/communication/neomutt/neomutt-sync-daemon.sh b/modules/communication/neomutt/neomutt-sync-daemon.sh new file mode 100644 index 0000000..a78ef5f --- /dev/null +++ b/modules/communication/neomutt/neomutt-sync-daemon.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# systemd daemon: full-sync the -full channels every 10 minutes while +# neomutt is open. Started/stopped by the wrapped neomutt launcher. + +set -uo pipefail + +INTERVAL="$((10 * 60))" +MBSYNCRC="${MBSYNCRC:-$HOME/.config/mbsync/.mbsyncrc}" + +if [[ $# -eq 0 ]]; then + echo "Usage: $0 [channel...]" >&2 + exit 2 +fi + +sync_once() { + echo "Syncing: $*" + + mbsync -c "$MBSYNCRC" "$@" + local status=$? + if ((status != 0)); then + echo "mbsync failed (status $status) for: $*" >&2 + return "$status" + fi + + echo "Indexing new mail with notmuch..." + notmuch new --quiet +} + +while true; do + sync_once "$@" + sleep "$INTERVAL" + + # Safety net: the launcher stops this service when neomutt exits; if that + # didn't happen (hard kill), bail out once neomutt is gone. + if ! pgrep -x neomutt >/dev/null; then + echo "neomutt is not running; stopping sync daemon" >&2 + exit 0 + fi +done -- cgit v1.2.3 From 9523f5ea00c85583fa9372557d6d003d2ca4b3c4 Mon Sep 17 00:00:00 2001 From: Arpit Chakladar Date: Thu, 24 Sep 2026 04:59:50 +0530 Subject: fix: icons for desktop items are working --- modules/communication/neomutt/default.nix | 33 ++++++++++------------- modules/communication/neomutt/neomutt-launcher.sh | 11 +++----- modules/file-management/yazi/default.nix | 2 +- modules/gaming/heroic/default.nix | 2 +- 4 files changed, 20 insertions(+), 28 deletions(-) (limited to 'modules/communication') diff --git a/modules/communication/neomutt/default.nix b/modules/communication/neomutt/default.nix index 3354213..da64a13 100644 --- a/modules/communication/neomutt/default.nix +++ b/modules/communication/neomutt/default.nix @@ -41,24 +41,18 @@ let text = builtins.readFile ./neomutt-sync-daemon.sh; }; - neomuttLauncher = pkgs.writeShellScriptBin "neomutt" ( - builtins.replaceStrings - [ - "@@SYSTEMCTL@@" - "@@PGREP@@" - "@@NEOMUTT@@" - "@@PROFILE_BIN@@" - "@@URLSCAN_BIN@@" - ] - [ - (lib.getExe' pkgs.systemd "systemctl") - (lib.getExe' pkgs.procps "pgrep") - (lib.getExe pkgs.neomutt) - "${config.home.profileDirectory}/bin" - (lib.makeBinPath [ pkgs.urlscan ]) - ] - (builtins.readFile ./neomutt-launcher.sh) - ); + neomuttLauncher = pkgs.writeShellApplication { + name = "neomutt"; + runtimeInputs = [ + pkgs.systemd + pkgs.procps + pkgs.neomutt + pkgs.urlscan + ]; + text = builtins.replaceStrings [ "@@PROFILE_BIN@@" ] [ "${config.home.profileDirectory}/bin" ] ( + builtins.readFile ./neomutt-launcher.sh + ); + }; neomuttSyncCompletion = pkgs.runCommand "neomutt-sync-completion" @@ -108,7 +102,7 @@ in builtins.replaceStrings [ "@@HTML_VIEWER@@" ] [ (lib.getExe config.web.chawan.package) ] (builtins.readFile ./mailcap); home.file.".local/share/icons/hicolor/scalable/apps/neomutt.svg".source = - config.lib.file.mkOutOfStoreSymlink "${config.programs.neomutt.package}/share/neomutt/logo/neomutt.svg"; + "${config.programs.neomutt.package}/share/neomutt/logo/neomutt.svg"; programs.neomutt = { enable = true; @@ -116,6 +110,7 @@ in name = "neomutt-wrapped"; paths = [ neomuttLauncher + pkgs.neomutt neomuttSync ]; meta.mainProgram = "neomutt"; diff --git a/modules/communication/neomutt/neomutt-launcher.sh b/modules/communication/neomutt/neomutt-launcher.sh index d677680..3caa9df 100644 --- a/modules/communication/neomutt/neomutt-launcher.sh +++ b/modules/communication/neomutt/neomutt-launcher.sh @@ -2,15 +2,12 @@ # Wrapped neomutt: keeps the neomutt-sync systemd daemon alive for the # lifetime of a neomutt session. set -uo pipefail -SYSTEMCTL='@@SYSTEMCTL@@' -PGREP='@@PGREP@@' -NEOMUTT='@@NEOMUTT@@' -"$SYSTEMCTL" --user start neomutt-sync.service || true +systemctl --user start neomutt-sync.service || true stop_service() { - "$PGREP" -x neomutt >/dev/null || "$SYSTEMCTL" --user stop neomutt-sync.service || true + pgrep -x neomutt >/dev/null || systemctl --user stop neomutt-sync.service || true } trap stop_service EXIT -export PATH="@@PROFILE_BIN@@:@@URLSCAN_BIN@@:$PATH" -"$NEOMUTT" "$@" +export PATH="@@PROFILE_BIN@@:$PATH" +neomutt "$@" diff --git a/modules/file-management/yazi/default.nix b/modules/file-management/yazi/default.nix index 72a4568..b56c816 100644 --- a/modules/file-management/yazi/default.nix +++ b/modules/file-management/yazi/default.nix @@ -65,7 +65,7 @@ in }; home.file.".local/share/icons/hicolor/scalable/apps/yazi.png" = { - source = config.lib.file.mkOutOfStoreSymlink "${cfg.package}/share/pixmaps/yazi.png"; + source = "${cfg.package}/share/pixmaps/yazi.png"; }; home.sessionVariables = { diff --git a/modules/gaming/heroic/default.nix b/modules/gaming/heroic/default.nix index 61eceb5..cf4c03d 100644 --- a/modules/gaming/heroic/default.nix +++ b/modules/gaming/heroic/default.nix @@ -35,7 +35,7 @@ in home.packages = [ cfg.package ]; home.file.".local/share/icons/hicolor/scalable/apps/com.heroicgameslauncher.hgl.svg".source = - config.lib.file.mkOutOfStoreSymlink "${pkgs.heroic}/share/icons/hicolor/scalable/apps/com.heroicgameslauncher.hgl.svg"; + "${pkgs.heroic}/share/icons/hicolor/scalable/apps/com.heroicgameslauncher.hgl.svg"; xdg.desktopEntries."heroic" = { name = "Heroic Games Launcher"; -- cgit v1.2.3 From c37c4a69fc895099109fc5211bf9449592ebc518 Mon Sep 17 00:00:00 2001 From: Arpit Chakladar Date: Thu, 24 Sep 2026 05:06:05 +0530 Subject: fix(communication/neomutt): fixed neomutt-launcher wrapper paths --- modules/communication/neomutt/default.nix | 16 +++++++++++----- modules/communication/neomutt/neomutt-launcher.sh | 3 +-- 2 files changed, 12 insertions(+), 7 deletions(-) (limited to 'modules/communication') diff --git a/modules/communication/neomutt/default.nix b/modules/communication/neomutt/default.nix index da64a13..6bc363b 100644 --- a/modules/communication/neomutt/default.nix +++ b/modules/communication/neomutt/default.nix @@ -42,16 +42,22 @@ let }; neomuttLauncher = pkgs.writeShellApplication { - name = "neomutt"; + name = "neomutt-launcher"; runtimeInputs = [ pkgs.systemd pkgs.procps pkgs.neomutt pkgs.urlscan ]; - text = builtins.replaceStrings [ "@@PROFILE_BIN@@" ] [ "${config.home.profileDirectory}/bin" ] ( - builtins.readFile ./neomutt-launcher.sh - ); + text = + builtins.replaceStrings + [ + "@@NEOMUTT_BIN@@" + ] + [ + (lib.getExe pkgs.neomutt) + ] + (builtins.readFile ./neomutt-launcher.sh); }; neomuttSyncCompletion = @@ -113,7 +119,7 @@ in pkgs.neomutt neomuttSync ]; - meta.mainProgram = "neomutt"; + meta.mainProgram = "neomutt-launcher"; }; sidebar.enable = true; sort = "reverse-threads"; diff --git a/modules/communication/neomutt/neomutt-launcher.sh b/modules/communication/neomutt/neomutt-launcher.sh index 3caa9df..62cbe09 100644 --- a/modules/communication/neomutt/neomutt-launcher.sh +++ b/modules/communication/neomutt/neomutt-launcher.sh @@ -9,5 +9,4 @@ stop_service() { } trap stop_service EXIT -export PATH="@@PROFILE_BIN@@:$PATH" -neomutt "$@" +"@@NEOMUTT_BIN@@" "$@" -- cgit v1.2.3