feat: add wlr-which module and config

This commit is contained in:
Lucien Cartier-Tilet 2025-11-02 17:56:58 +01:00
parent e038daa765
commit 065f094cdf
5 changed files with 320 additions and 34 deletions

View File

@ -16,6 +16,7 @@ in {
./rofi
./swaync.nix
./waybar.nix
./wlr-which.nix
./wlsunset.nix
];
@ -28,5 +29,6 @@ in {
obs.enable = mkDefault cfg.fullDesktop;
qt.enable = mkDefault cfg.fullDesktop;
rofi.enable = mkDefault cfg.fullDesktop;
wlr-which-key.enable = mkDefault cfg.fullDesktop;
};
}

View File

@ -117,8 +117,8 @@ in {
$menu = rofi -combi-modi drun,calc -show combi
bind = SUPER, Return, exec, ${pkgs.kitty}/bin/kitty ${pkgs.tmux}/bin/tmux
bind = SUPER, Space, submap, leader
bind = , Print, submap, screenshot
bind = SUPER, Space, exec, ${pkgs.wlr-which-key}/bin/wlr-which-key
bind = , Print, exec, ${pkgs.wlr-which-key}/bin/wlr-which-key -k s
submap = leader
bind = , l, exec, plock
@ -147,11 +147,13 @@ in {
bind = , u, submap, reset
bind = , escape, submap, reset
bind = CTRL, g, submap, reset
submap = buffers
bind = , d, killactive,
bind = , d, submap, reset
bind = , escape, submap, reset
bind = CTRL, g, submap, reset
submap = resize
binde = , $left, resizeactive, -10 0
binde = , $right, resizeactive, 10 0
@ -160,6 +162,7 @@ in {
bind = , q, submap, reset
bind = , escape, submap, reset
bind = CTRL, g, submap, reset
submap = rofi
bind = , b, exec, rofi-bluetooth
bind = , b, submap, reset
@ -173,6 +176,7 @@ in {
bind = , y, submap, reset
bind = , escape, submap, reset
bind = CTRL, g, submap, reset
submap = screenshot
bind = , Print, exec, screenshot
bind = , Print, submap, reset
@ -188,6 +192,7 @@ in {
bind = Shift, s, submap, reset
bind = , escape, submap, reset
bind = CTRL, g, submap, reset
submap = windows
bind = , period, submap, resize
bind = , $left, movefocus, l

View File

@ -0,0 +1,190 @@
{
config,
lib,
pkgs,
...
}: let
inherit
(lib)
literalExpression
mkIf
mkOption
mkEnableOption
types
;
cfg = config.home.desktop.wlr-which-key;
yamlFormat = pkgs.formats.yaml {};
# Convert kebab-case to snake_case
toSnakeCase = str: builtins.replaceStrings ["-"] ["_"] str;
# Recursively filter out null values and convert kebab-case keys to snake_case
filterNulls = value:
if lib.isAttrs value
then lib.mapAttrs' (n: v: lib.nameValuePair (toSnakeCase n) (filterNulls v)) (lib.filterAttrs (n: v: v != null) value)
else if lib.isList value
then map filterNulls value
else value;
menuEntryType = types.submodule {
freeformType = yamlFormat.type;
options = with types; {
key = mkOption {
type = str;
example = "p";
};
desc = mkOption {
type = str;
example = "Power";
};
cmd = mkOption {
type = nullOr str;
default = null;
example = "echo example";
};
keep-open = mkOption {
type = nullOr bool;
default = null;
example = true;
};
submenu = mkOption {
type = nullOr (listOf menuEntryType);
default = null;
example = literalExpression ''
[
{ key = "s"; desc = "Suspend"; cmd = "systemctl suspend"; }
{ key = "r"; desc = "Reboot"; cmd = "systemctl reboot"; }
{ key = "o"; desc = "Poweroff"; cmd = "systemctl poweroff"; }
]
'';
};
};
};
settingsType = types.submodule {
freeformType = yamlFormat.type;
options = with types; {
background = mkOption {
type = nullOr str;
default = null;
example = "#282828FF";
};
color = mkOption {
type = nullOr str;
default = null;
example = "#FBF1C7FF";
};
border = mkOption {
type = nullOr str;
default = null;
example = "#8EC07CFF";
};
anchor = mkOption {
type = nullOr (enum ["center" "top" "bottom" "left" "right" "top-left" "top-right" "bottom-left" "bottom-right"]);
default = null;
example = "top-left";
};
margin-top = mkOption {
type = nullOr int;
default = null;
example = "0";
};
margin-right = mkOption {
type = nullOr int;
default = null;
example = "0";
};
margin-bottom = mkOption {
type = nullOr int;
default = null;
example = "0";
};
margin-left = mkOption {
type = nullOr int;
default = null;
example = "0";
};
font = mkOption {
type = nullOr str;
default = null;
example = "monospace 10";
};
separator = mkOption {
type = nullOr str;
default = null;
example = " ";
};
border-width = mkOption {
type = nullOr (either float int);
default = null;
example = 4.0;
};
corder-r = mkOption {
type = nullOr (either float int);
default = null;
example = 20.0;
};
padding = mkOption {
type = nullOr (either float int);
default = null;
example = 15.0;
};
rows-per-column = mkOption {
type = nullOr int;
default = null;
example = 5;
};
column-padding = mkOption {
type = nullOr (either float int);
default = null;
example = 25.0;
};
inhibit-compositor-keyboard-shortcuts = mkOption {
type = bool;
default = true;
example = false;
};
auto_kbd_layout = mkOption {
type = bool;
default = true;
example = false;
};
namespace = mkOption {
type = nullOr str;
default = null;
example = "wlr_which_key";
};
menu = mkOption {
type = listOf menuEntryType;
default = [];
example = literalExpression ''
[
{
key = "p";
desc = "Power";
submenu = [
{ key = "s"; desc = "Suspend"; cmd = "systemctl suspend"; }
{ key = "r"; desc = "Reboot"; cmd = "systemctl reboot"; }
{ key = "o"; desc = "Poweroff"; cmd = "systemctl poweroff"; }
];
}
]
'';
};
};
};
in {
options.home.desktop.wlr-which-key = {
enable = mkEnableOption "Enables wlr-which-key";
package = lib.mkPackageOption pkgs "wlr-which-key" {};
settings = mkOption {
type = settingsType;
default = {};
description = "Configuration written to {file}`$XDG_CONFIG_HOME/wlr-which-key/config.yaml`.";
};
};
config = mkIf cfg.enable {
home.packages = [cfg.package];
xdg.configFile = {
"wlr-which-key/config.yaml".source = yamlFormat.generate "wlr-which-key-config.yml" (filterNulls cfg.settings);
};
};
}

View File

@ -10,31 +10,6 @@ with lib; let
with epkgs; [
mu4e
pdf-tools
tree-sitter
tree-sitter-langs
(treesit-grammars.with-grammars (grammar:
with grammar; [
tree-sitter-bash
tree-sitter-c
tree-sitter-cpp
tree-sitter-css
tree-sitter-dockerfile
tree-sitter-http
tree-sitter-javascript
tree-sitter-jsdoc
tree-sitter-json
tree-sitter-just
tree-sitter-markdown
tree-sitter-markdown-inline
tree-sitter-nix
tree-sitter-rust
tree-sitter-sql
tree-sitter-toml
tree-sitter-typescript
tree-sitter-typst
tree-sitter-vue
tree-sitter-yaml
]))
]
));
cfg = config.home.dev.editors.emacs;

View File

@ -1,6 +1,7 @@
{
pkgs,
config,
lib,
...
}: {
imports = [
@ -11,10 +12,36 @@
];
config = let
emacsPkg = with pkgs; ((emacsPackagesFor emacs).emacsWithPackages (
epkgs: [
epkgs.mu4e
epkgs.pdf-tools
emacsPackage = with pkgs; ((emacsPackagesFor emacs).emacsWithPackages (
epkgs:
with epkgs; [
mu4e
pdf-tools
tree-sitter
tree-sitter-langs
(treesit-grammars.with-grammars (grammar:
with grammar; [
tree-sitter-bash
tree-sitter-c
tree-sitter-cpp
tree-sitter-css
tree-sitter-dockerfile
tree-sitter-http
tree-sitter-javascript
tree-sitter-jsdoc
tree-sitter-json
tree-sitter-just
tree-sitter-markdown
tree-sitter-markdown-inline
tree-sitter-nix
tree-sitter-rust
tree-sitter-sql
tree-sitter-toml
tree-sitter-typescript
tree-sitter-typst
tree-sitter-vue
tree-sitter-yaml
]))
]
));
askpass = import ../modules/cli/scripts/askpass.nix {inherit pkgs;};
@ -30,14 +57,101 @@
home = {
sessionVariables = {
EDITOR = "${emacsPkg}/bin/emacsclient -c -a ${emacsPkg}/bin/emacs";
EDITOR = "${emacsPackage}/bin/emacsclient -c -a ${emacsPackage}/bin/emacs";
LAUNCH_EDITOR = "${launchWithEmacsclient}/bin/launch-with-emacsclient";
SUDO_ASKPASS = "${askpass}/bin/askpass";
LSP_USE_PLISTS = "true";
};
desktop.waybar.style = ./config/waybar/style.css;
dev.ai.claude.enable = true;
desktop = {
waybar.style = ./config/waybar/style.css;
wlr-which-key.settings = {
font = "Cascadia Code 12";
background = "#3b4252d0";
color = "#eceff4";
border = "#2e3440";
border_width = 2;
corner_r = 10;
rows_per_column = 5;
column_padding = 25;
inhibit_compositor_keyboard_shortcuts = true;
auto_kbd_layout = true;
menu = let
left = "c";
down = "t";
up = "s";
right = "r";
in [
{
key = "a";
desc = "Apps";
submenu = [
{ key = "b"; desc = "Browser"; cmd = "zen"; }
{ key = "B"; desc = "Qutebrowser"; cmd = "${pkgs.qutebrowser}/bin/qutebrowser"; }
{ key = "d"; desc = "Discord"; cmd = "${pkgs.vesktop}/bin/vesktop"; }
{ key = "e"; desc = "Emacs"; cmd = "${emacsPackage}/bin/emacsclient -c -n"; }
{ key = "g"; desc = "Gimp"; cmd = "${pkgs.gimp}/bin/gimp"; }
{ key = "n"; desc = "Nemo"; cmd = "${pkgs.nemo}/bin/nemo"; }
{
key = "r";
desc = "Rofi";
submenu = [
{ key = "b"; desc = "Bluetooth"; cmd = "rofi-bluetooth"; }
{ key = "e"; desc = "Emoji"; cmd = "rofi -show emoji"; }
{ key = "r"; desc = "App Menu"; cmd = "rofi -combi-modi drun,calc -show combi"; }
{ key = "s"; desc = "SSH"; cmd = "rofi -show ssh"; }
{ key = "y"; desc = "YouTube"; cmd = "ytplay"; }
];
}
];
}
{
key = "b";
desc = "Buffers";
submenu = [
{ key = "d"; desc = "Close"; cmd = "echo close"; }
{ key = "f"; desc = "Fullscreen"; cmd = "echo fullscreen"; }
{ key = "F"; desc = "Float"; cmd = "echo float"; }
{
key = ".";
desc = "Resize";
submenu = [
{ key = left; desc = "Decrease Width"; cmd = "echo decrease width"; keep-open = true; }
{ key = down; desc = "Increase Height"; cmd = "echo decrease height"; keep-open = true; }
{ key = up; desc = "Decrease Height"; cmd = "echo decrease height"; keep-open = true; }
{ key = right; desc = "Increase Width"; cmd = "echo increase width"; keep-open = true; }
];
}
];
}
{
key = "p";
desc = "Power";
submenu = [
{ key = "s"; desc = "Suspend"; cmd = "systemctl suspend"; }
{ key = "r"; desc = "Reboot"; cmd = "systemctl reboot"; }
{ key = "o"; desc = "Poweroff"; cmd = "systemctl poweroff"; }
];
}
{
key = "s";
desc = "Screenshots";
submenu = [
{ key = "Print"; desc = "Screenshot"; cmd = "screenshot"; }
{ key = "d"; desc = "Delayed"; cmd = "screenshot -d 3"; }
{ key = "D"; desc = "Select, Delay, Edit, and Copy"; cmd = "screenshot -secd 3"; }
{ key = "e"; desc = "Select, Edit, and Copy"; cmd = "screenshot -sec"; }
{ key = "g"; desc = "Select, Gimp, and Copy"; cmd = "screenshot -sgc"; }
{ key = "s"; desc = "Select and Copy"; cmd = "screenshot -sc"; }
];
}
];
};
};
dev = {
ai.claude.enable = true;
editors.emacs.package = emacsPackage;
};
fullDesktop = true;
shell.fish.enable = true;
};