feh: allow binding actions to multiple buttons/keys

In feh you can bind multiple keys to the same action, but Home Manager
only let you set a single key to an action. You can cheat and pass a
string with space-separated keys, but with this change you can pass a
list for each action to bind multiple keys to it.

Also adds a couple of tests.

Fixes #1366
This commit is contained in:
Olmo Kramer 2020-09-27 14:20:19 +02:00 committed by Robert Helgesson
parent 6fed10a09a
commit 41147ae09a
No known key found for this signature in database
GPG key ID: 36BDAA14C2797E89
7 changed files with 89 additions and 18 deletions

View file

@ -6,8 +6,22 @@ let
cfg = config.programs.feh; cfg = config.programs.feh;
disableBinding = func: key: func; bindingsOf = t: with types; attrsOf (nullOr (either t (listOf t)));
enableBinding = func: key: "${func} ${toString key}";
renderBindings = bindings:
let
enabled = filterAttrs (n: v: v != null) bindings;
disabled = filterAttrs (n: v: v == null) bindings;
render = mapAttrsToList renderBinding;
in concatStringsSep "\n" (render disabled ++ render enabled);
renderBinding = func: key:
if key == null then
func
else if isList key then
concatStringsSep " " ([ func ] ++ map toString key)
else
"${func} ${toString key}";
in { in {
options.programs.feh = { options.programs.feh = {
@ -15,14 +29,16 @@ in {
buttons = mkOption { buttons = mkOption {
default = { }; default = { };
type = with types; attrsOf (nullOr (either str int)); type = with types; bindingsOf (either str int);
example = { example = {
zoom_in = 4; zoom_in = 4;
zoom_out = "C-4"; zoom_out = "C-4";
prev_img = [ 3 "C-3" ];
}; };
description = '' description = ''
Override feh's default mouse button mapping. If you want to disable an Override feh's default mouse button mapping. If you want to disable an
action, set its value to null. action, set its value to null. If you want to bind multiple buttons to
an action, set its value to a list.
See <link xlink:href="https://man.finalrewind.org/1/feh/#x425554544f4e53"/> for See <link xlink:href="https://man.finalrewind.org/1/feh/#x425554544f4e53"/> for
default bindings and available commands. default bindings and available commands.
''; '';
@ -30,14 +46,16 @@ in {
keybindings = mkOption { keybindings = mkOption {
default = { }; default = { };
type = types.attrsOf (types.nullOr types.str); type = bindingsOf types.str;
example = { example = {
zoom_in = "plus"; zoom_in = "plus";
zoom_out = "minus"; zoom_out = "minus";
prev_img = [ "h" "Left" ];
}; };
description = '' description = ''
Override feh's default keybindings. If you want to disable a keybinding Override feh's default keybindings. If you want to disable a keybinding
set its value to null. set its value to null. If you want to bind multiple keys to an action,
set its value to a list.
See <link xlink:href="https://man.finalrewind.org/1/feh/#x4b455953"/> for See <link xlink:href="https://man.finalrewind.org/1/feh/#x4b455953"/> for
default bindings and available commands. default bindings and available commands.
''; '';
@ -53,18 +71,11 @@ in {
home.packages = [ pkgs.feh ]; home.packages = [ pkgs.feh ];
xdg.configFile."feh/buttons".text = '' xdg.configFile."feh/buttons" =
${concatStringsSep "\n" (mapAttrsToList disableBinding mkIf (cfg.buttons != { }) { text = renderBindings cfg.buttons + "\n"; };
(filterAttrs (n: v: v == null) cfg.buttons))}
${concatStringsSep "\n" (mapAttrsToList enableBinding
(filterAttrs (n: v: v != null) cfg.buttons))}
'';
xdg.configFile."feh/keys".text = '' xdg.configFile."feh/keys" = mkIf (cfg.keybindings != { }) {
${concatStringsSep "\n" (mapAttrsToList disableBinding text = renderBindings cfg.keybindings + "\n";
(filterAttrs (n: v: v == null) cfg.keybindings))} };
${concatStringsSep "\n" (mapAttrsToList enableBinding
(filterAttrs (n: v: v != null) cfg.keybindings))}
'';
}; };
} }

View file

@ -45,6 +45,7 @@ import nmt {
./modules/programs/browserpass ./modules/programs/browserpass
./modules/programs/dircolors ./modules/programs/dircolors
./modules/programs/direnv ./modules/programs/direnv
./modules/programs/feh
./modules/programs/fish ./modules/programs/fish
./modules/programs/git ./modules/programs/git
./modules/programs/gpg ./modules/programs/gpg

View file

@ -0,0 +1,4 @@
{
feh-empty-config = ./feh-empty-settings.nix;
feh-bindings = ./feh-bindings.nix;
}

View file

@ -0,0 +1,4 @@
zoom_in
next_img C-4
prev_img 3 C-3
zoom_out 4

View file

@ -0,0 +1,3 @@
zoom_in
prev_img h Left
zoom_out minus

View file

@ -0,0 +1,33 @@
{ pkgs, ... }:
{
config = {
programs.feh.enable = true;
programs.feh.buttons = {
zoom_in = null;
zoom_out = 4;
next_img = "C-4";
prev_img = [ 3 "C-3" ];
};
programs.feh.keybindings = {
zoom_in = null;
zoom_out = "minus";
prev_img = [ "h" "Left" ];
};
nixpkgs.overlays =
[ (self: super: { feh = pkgs.writeScriptBin "dummy-feh" ""; }) ];
nmt.script = ''
assertFileContent \
home-files/.config/feh/buttons \
${./feh-bindings-expected-buttons}
assertFileContent \
home-files/.config/feh/keys \
${./feh-bindings-expected-keys}
'';
};
}

View file

@ -0,0 +1,15 @@
{ pkgs, ... }:
{
config = {
programs.feh.enable = true;
nixpkgs.overlays =
[ (self: super: { feh = pkgs.writeScriptBin "dummy-feh" ""; }) ];
nmt.script = ''
assertPathNotExists home-files/.config/feh/buttons
assertPathNotExists home-files/.config/feh/keys
'';
};
}