aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArpit Chakladar <arpitchakladar+git@gmail.com>2026-07-23 00:56:24 +0530
committerArpit Chakladar <arpitchakladar+git@gmail.com>2026-07-23 00:56:24 +0530
commit2ad7b06ced0ffa39d20e6be41466e5bd834ee956 (patch)
tree86bc522072c09c80098bff8854d2377137a6c39c
parenta61001ad8696f6d9a5ebe0f18a71d747941ec9d0 (diff)
downloadhome-manager-config-2ad7b06ced0ffa39d20e6be41466e5bd834ee956.tar.gz
home-manager-config-2ad7b06ced0ffa39d20e6be41466e5bd834ee956.zip
feat(w3m): add module with desktop entry + integrate into neomutt
- modules/web/w3m: enable/package options, desktop entry via kitty, assertion - modules/web/w3m: delegate to programs.w3m under the hood - modules/web/w3m: default package to programs.w3m.finalPackage - modules/desktop/xdg: add portal config with common.default = "*" - neomutt/nix: use lib.getExe' config.web.w3m.package for w3m refs - neomutt/assertions: add w3m dependency assertion - users/arpit: enable web.w3m
-rw-r--r--flake.nix1
-rw-r--r--modules/communication/neomutt/.neomuttrc1
-rw-r--r--modules/communication/neomutt/assertions.nix9
-rw-r--r--modules/communication/neomutt/keybindings.nix6
-rw-r--r--modules/communication/neomutt/macros.nix24
-rw-r--r--modules/communication/neomutt/neomutt.nix33
-rw-r--r--modules/desktop/default.nix1
-rw-r--r--modules/desktop/xdg/default.nix25
-rw-r--r--modules/web/default.nix3
-rw-r--r--modules/web/w3m/assertions.nix13
-rw-r--r--modules/web/w3m/default.nix42
-rw-r--r--users/arpit.nix1
12 files changed, 131 insertions, 28 deletions
diff --git a/flake.nix b/flake.nix
index 56723a1..49ff473 100644
--- a/flake.nix
+++ b/flake.nix
@@ -22,7 +22,6 @@
outputs =
{
- self,
nixpkgs,
home-manager,
base16,
diff --git a/modules/communication/neomutt/.neomuttrc b/modules/communication/neomutt/.neomuttrc
index 829951a..877e265 100644
--- a/modules/communication/neomutt/.neomuttrc
+++ b/modules/communication/neomutt/.neomuttrc
@@ -4,6 +4,7 @@
# Each column in the index receives a distinct color to keep the UI organized.
set menu_scroll = yes
+set pager_stop = yes
# cancel any prompt/command-line entry with Esc, vim-style
set abort_key = "<Esc>"
diff --git a/modules/communication/neomutt/assertions.nix b/modules/communication/neomutt/assertions.nix
index dea9d41..c4ce62a 100644
--- a/modules/communication/neomutt/assertions.nix
+++ b/modules/communication/neomutt/assertions.nix
@@ -1,4 +1,4 @@
-# Assertions - Validates neomutt dependencies (less, bat, kitty) are enabled
+# Assertions - Validates neomutt dependencies (less, bat, kitty, w3m) are enabled
{ config, ... }:
{
assertions = [
@@ -23,5 +23,12 @@
neomutt's desktop entry requires kitty as the terminal launcher. Please enable terminal.kitty.
'';
}
+ {
+ assertion = !config.communication.neomutt.enable || config.web.w3m.enable;
+ message = ''
+ communication.neomutt is enabled but web.w3m.enable is not.
+ neomutt uses w3m for HTML email rendering. Please enable web.w3m.
+ '';
+ }
];
}
diff --git a/modules/communication/neomutt/keybindings.nix b/modules/communication/neomutt/keybindings.nix
index b84386c..929d3e2 100644
--- a/modules/communication/neomutt/keybindings.nix
+++ b/modules/communication/neomutt/keybindings.nix
@@ -304,5 +304,11 @@
key = "g?";
action = "help";
}
+
+ {
+ map = [ "pager" ];
+ key = "H";
+ action = "display-toggle-weed";
+ }
];
}
diff --git a/modules/communication/neomutt/macros.nix b/modules/communication/neomutt/macros.nix
index 0548a0f..87c05d1 100644
--- a/modules/communication/neomutt/macros.nix
+++ b/modules/communication/neomutt/macros.nix
@@ -11,13 +11,31 @@
action = "<enter-command>set my_wait_key=$wait_key wait_key=no<enter><sync-mailbox><shell-escape>${lib.getExe config.scripts.neomutt-sync.package}<enter><sync-mailbox><enter-command>set wait_key=$my_wait_key<enter>";
}
{
- # gx: extract links from the current message and open one, vim-netrw style
+ # gx: open the message body in interactive w3m -- real vim-style
+ # cursor navigation (hjkl, Tab/Shift-Tab between links, Enter to
+ # follow, B back, q to return to neomutt). Replaces the old
+ # urlscan-based link picker.
map = [
"index"
"pager"
];
key = "gx";
- action = "<pipe-message>urlscan<Enter>";
+ action = "<pipe-message>urlscan<enter>";
+ }
+ {
+ # Ctrl-B in the pager: same interactive w3m view as gx, kept as
+ # a second binding since Ctrl-B is a common muscle-memory key
+ # for "open this in a browser-like view".
+ map = [ "pager" ];
+ key = "\\Cb";
+ action = "<enter-command>set my_pipe_decode=$pipe_decode pipe_decode=yes<enter><pipe-message>${lib.getExe' config.web.w3m.package "w3m"} -T text/html<enter><enter-command>set pipe_decode=$my_pipe_decode<enter>";
+ }
+ {
+ # Ctrl-B on a specific attachment (not just the top-level
+ # message): pipe-entry sends the selected attachment instead.
+ map = [ "attach" ];
+ key = "\\Cb";
+ action = "<pipe-entry>${lib.getExe' config.web.w3m.package "w3m"} -cols 100 -T text/html<enter>";
}
{
map = [
@@ -32,7 +50,7 @@
# the counterpart to gf (interactive limit prompt) in binds.nix
map = [ "index" ];
key = "gF";
- action = "<limit>~A<enter>";
+ action = "<limit>all<enter>";
}
{
# ZZ: save and quit, vim-style (sync mailbox, then quit)
diff --git a/modules/communication/neomutt/neomutt.nix b/modules/communication/neomutt/neomutt.nix
index f6c7f8e..6cabf98 100644
--- a/modules/communication/neomutt/neomutt.nix
+++ b/modules/communication/neomutt/neomutt.nix
@@ -9,7 +9,7 @@ let
neomuttDesktopItem = pkgs.makeDesktopItem {
name = "neomutt";
desktopName = "NeoMutt";
- exec = "${lib.getExe config.programs.kitty.package} -e ${lib.getExe config.programs.neomutt.package}";
+ exec = "${lib.getExe config.terminal.kitty.package} -e ${lib.getExe config.programs.neomutt.package}";
icon = "kitty";
categories = [
"Network"
@@ -25,27 +25,21 @@ in
xdg.mimeApps.defaultApplications = {
"x-scheme-handler/mailto" = "neomutt.desktop";
};
-
home.packages = with pkgs; [
urlscan
- w3m
neomuttDesktopItem
];
-
xdg.configFile."neomutt/mailcap".text = ''
- text/html; w3m -dump -T text/html '%s'; copiousoutput; nametemplate=%s.html
- text/html; $BROWSER '%s'; nametemplate=%s.html
+ text/html; ${lib.getExe' config.web.w3m.package "w3m"} -dump -cols 100 -T text/html '%s'; copiousoutput; nametemplate=%s.html
image/*; xdg-open '%s' &
application/pdf; xdg-open '%s'; nametemplate=%s.pdf
video/*; xdg-open '%s' &
audio/*; xdg-open '%s' &
application/*; xdg-open '%s' &
'';
-
xdg.configFile."neomutt/flag_legend.txt".text = ''
NeoMutt Index Flags
===================
-
Message state ($flag_chars) -- unchanged defaults
N New - unread, arrived since you last checked
O Old - unread, but seen in a previous session
@@ -55,25 +49,21 @@ in
* Tagged - selected for a bulk operation (toggle with t)
r Replied - you've replied to this message
(blank) - read, nothing else notable
-
Cryptography ($crypt_chars)
-  Verified - signed, and the signature checks out
-  Encrypted - PGP/SMIME encrypted
-  Signed - PGP/SMIME signed (unverified)
-  PGP key - message contains a PGP public key
+ Verified - signed, and the signature checks out
+ Encrypted - PGP/SMIME encrypted
+ Signed - PGP/SMIME signed (unverified)
+ PGP key - message contains a PGP public key
(blank) - no cryptography info
-
Addressing ($to_chars)
-  To you only - sent to you and only you
-  To (with others) - you're in the To: list, among others
-  Cc only - you're only in the Cc: list
-  From you - sent by you
-  Mailing list - sent to a list you're subscribed to
+ To you only - sent to you and only you
+ To (with others) - you're in the To: list, among others
+ Cc only - you're only in the Cc: list
+ From you - sent by you
+ Mailing list - sent to a list you're subscribed to
(blank) - not in To/Cc (e.g. Bcc, unlisted)
-
Press q to close.
'';
-
programs.neomutt = {
enable = true;
sidebar.enable = true;
@@ -81,7 +71,6 @@ in
vimKeys = true;
unmailboxes = true;
checkStatsInterval = 20;
-
extraConfig = builtins.readFile ./.neomuttrc;
};
};
diff --git a/modules/desktop/default.nix b/modules/desktop/default.nix
index 76ac223..eb2eea6 100644
--- a/modules/desktop/default.nix
+++ b/modules/desktop/default.nix
@@ -9,6 +9,7 @@
./i3
./gtk
./polybar
+ ./xdg
];
options.desktop = {
diff --git a/modules/desktop/xdg/default.nix b/modules/desktop/xdg/default.nix
new file mode 100644
index 0000000..4ccefc4
--- /dev/null
+++ b/modules/desktop/xdg/default.nix
@@ -0,0 +1,25 @@
+# xdg - XDG Desktop Portal configuration
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+{
+ config = lib.mkIf config.desktop.enable {
+ xdg.portal = {
+ enable = true;
+ extraPortals = with pkgs; [
+ xdg-desktop-portal-termfilechooser
+ xdg-desktop-portal-gtk
+ ];
+ config.common = {
+ default = [
+ "gtk"
+ ];
+ "org.freedesktop.impl.portal.FileChooser" = [ "termfilechooser" ];
+ };
+ xdgOpenUsePortal = true;
+ };
+ };
+}
diff --git a/modules/web/default.nix b/modules/web/default.nix
index a5c2ae6..436241a 100644
--- a/modules/web/default.nix
+++ b/modules/web/default.nix
@@ -1,8 +1,9 @@
-# Web - Web browser and downloader modules (aria2, brave)
+# Web - Web browser and downloader modules (aria2, brave, w3m)
{ ... }:
{
imports = [
./aria2
./brave
+ ./w3m
];
}
diff --git a/modules/web/w3m/assertions.nix b/modules/web/w3m/assertions.nix
new file mode 100644
index 0000000..b5ae2be
--- /dev/null
+++ b/modules/web/w3m/assertions.nix
@@ -0,0 +1,13 @@
+# Assertions - Validates kitty is enabled for w3m desktop entry
+{ config, ... }:
+{
+ assertions = [
+ {
+ assertion = !config.web.w3m.enable || config.terminal.kitty.enable;
+ message = ''
+ web.w3m is enabled but terminal.kitty.enable is not.
+ w3m's desktop entry requires kitty as the terminal launcher. Please enable terminal.kitty.
+ '';
+ }
+ ];
+}
diff --git a/modules/web/w3m/default.nix b/modules/web/w3m/default.nix
new file mode 100644
index 0000000..3dad0a2
--- /dev/null
+++ b/modules/web/w3m/default.nix
@@ -0,0 +1,42 @@
+# w3m - Text-based web browser and pager
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+let
+ w3mDesktopItem = pkgs.makeDesktopItem {
+ name = "w3m";
+ desktopName = "w3m";
+ exec = "${lib.getExe config.terminal.kitty.package} -e ${lib.getExe' config.web.w3m.package "w3m"}";
+ icon = "kitty";
+ categories = [ "Network" ];
+ comment = "Text-based web browser";
+ terminal = false;
+ type = "Application";
+ };
+in
+{
+ imports = [
+ ./assertions.nix
+ ];
+
+ options.web.w3m = {
+ enable = lib.mkEnableOption "Enables w3m.";
+ package = lib.mkOption {
+ type = lib.types.package;
+ default = config.programs.w3m.finalPackage;
+ defaultText = lib.literalExpression "config.programs.w3m.finalPackage";
+ description = "Package to use for w3m. Defaults to the wrapped finalPackage from programs.w3m.";
+ };
+ };
+
+ config = lib.mkIf config.web.w3m.enable {
+ programs.w3m.enable = true;
+ home.packages = [
+ config.web.w3m.package
+ w3mDesktopItem
+ ];
+ };
+}
diff --git a/users/arpit.nix b/users/arpit.nix
index 75d394a..de0072a 100644
--- a/users/arpit.nix
+++ b/users/arpit.nix
@@ -80,6 +80,7 @@
# Web
web.aria2.enable = true;
web.brave.enable = true;
+ web.w3m.enable = true;
development.git.signing.signByDefault = true;