about summary refs log tree commit diff stats
path: root/pkgs
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-02-02 18:14:33 +0100
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-02-02 18:25:39 +0100
commit34b8b4c52e4afa8b854e6c3d37780ce5faf74c05 (patch)
tree31079c091c83c7d02d1e9a4f7a9a34eb9db7f91e /pkgs
parentfeat(lib): Init `baseLib` (diff)
downloadnixos-config-34b8b4c52e4afa8b854e6c3d37780ce5faf74c05.zip
refactor(modules/river): Migrate to `by-name`
This includes a near rewrite `river-mk-keymap` (previously,
`river_init_lesser`.)
Diffstat (limited to '')
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/.envrc3
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/.gitignore2
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/Cargo.lock334
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/Cargo.toml71
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/TODO1
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/contrib/example.json5
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/flake.lock27
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/flake.nix25
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/package.nix14
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/src/cli.rs11
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/src/key_map/commands.rs109
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/src/key_map/mod.rs79
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/src/main.rs34
-rwxr-xr-xpkgs/by-name/ri/river-mk-keymap/update.sh3
14 files changed, 718 insertions, 0 deletions
diff --git a/pkgs/by-name/ri/river-mk-keymap/.envrc b/pkgs/by-name/ri/river-mk-keymap/.envrc
new file mode 100644
index 00000000..fdd3e9d8
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/.envrc
@@ -0,0 +1,3 @@
+#!/usr/bin/env sh
+
+use flake
diff --git a/pkgs/by-name/ri/river-mk-keymap/.gitignore b/pkgs/by-name/ri/river-mk-keymap/.gitignore
new file mode 100644
index 00000000..2d5df85d
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/.gitignore
@@ -0,0 +1,2 @@
+/target
+.direnv
diff --git a/pkgs/by-name/ri/river-mk-keymap/Cargo.lock b/pkgs/by-name/ri/river-mk-keymap/Cargo.lock
new file mode 100644
index 00000000..c8b05795
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/Cargo.lock
@@ -0,0 +1,334 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "anstream"
+version = "0.6.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
+dependencies = [
+ "anstyle",
+ "anstyle-parse",
+ "anstyle-query",
+ "anstyle-wincon",
+ "colorchoice",
+ "is_terminal_polyfill",
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
+
+[[package]]
+name = "anstyle-parse"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
+dependencies = [
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle-query"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
+dependencies = [
+ "windows-sys",
+]
+
+[[package]]
+name = "anstyle-wincon"
+version = "3.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
+dependencies = [
+ "anstyle",
+ "once_cell",
+ "windows-sys",
+]
+
+[[package]]
+name = "anyhow"
+version = "1.0.95"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
+
+[[package]]
+name = "clap"
+version = "4.5.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "769b0145982b4b48713e01ec42d61614425f27b7058bda7180a3a41f30104796"
+dependencies = [
+ "clap_builder",
+ "clap_derive",
+]
+
+[[package]]
+name = "clap_builder"
+version = "4.5.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7"
+dependencies = [
+ "anstream",
+ "anstyle",
+ "clap_lex",
+ "strsim",
+]
+
+[[package]]
+name = "clap_derive"
+version = "4.5.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "clap_lex"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
+
+[[package]]
+name = "colorchoice"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
+
+[[package]]
+name = "heck"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
+
+[[package]]
+name = "is_terminal_polyfill"
+version = "1.70.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
+
+[[package]]
+name = "itoa"
+version = "1.0.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
+
+[[package]]
+name = "keymaps"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6cec33e805ecc09c4e4f91ca26e536978ad1ae28f2e1dc02fadafeec6d2f8504"
+dependencies = [
+ "serde",
+ "thiserror",
+]
+
+[[package]]
+name = "memchr"
+version = "2.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
+
+[[package]]
+name = "once_cell"
+version = "1.20.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.93"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.38"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "river-mk-keymap"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "clap",
+ "keymaps",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "ryu"
+version = "1.0.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd"
+
+[[package]]
+name = "serde"
+version = "1.0.217"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.217"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.138"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949"
+dependencies = [
+ "itoa",
+ "memchr",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "strsim"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
+
+[[package]]
+name = "syn"
+version = "2.0.97"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5dabd04e3b9a8c3c03d5e743f5ef5e1207befc9de704d477f7198cc28049763e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "thiserror"
+version = "2.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "2.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
+
+[[package]]
+name = "utf8parse"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
+
+[[package]]
+name = "windows-sys"
+version = "0.59.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_gnullvm",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
diff --git a/pkgs/by-name/ri/river-mk-keymap/Cargo.toml b/pkgs/by-name/ri/river-mk-keymap/Cargo.toml
new file mode 100644
index 00000000..974ad06d
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/Cargo.toml
@@ -0,0 +1,71 @@
+[package]
+name = "river-mk-keymap"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+anyhow = "1.0.95"
+clap = { version = "4.5.27", features = ["derive"] }
+keymaps = { version = "1.0.0", features = ["serde", "mouse-keys"] }
+serde = { version = "1.0.217", features = ["derive"] }
+serde_json = "1.0.138"
+
+[profile.release]
+lto = true
+codegen-units = 1
+panic = "abort"
+split-debuginfo = "off"
+
+[lints.rust]
+# rustc lint groups https://doc.rust-lang.org/rustc/lints/groups.html
+warnings = "warn"
+future_incompatible = { level = "warn", priority = -1 }
+let_underscore = { level = "warn", priority = -1 }
+nonstandard_style = { level = "warn", priority = -1 }
+rust_2018_compatibility = { level = "warn", priority = -1 }
+rust_2018_idioms = { level = "warn", priority = -1 }
+rust_2021_compatibility = { level = "warn", priority = -1 }
+unused = { level = "warn", priority = -1 }
+# rustc allowed-by-default lints https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html
+# missing_docs = "warn"
+macro_use_extern_crate = "warn"
+meta_variable_misuse = "warn"
+missing_abi = "warn"
+missing_copy_implementations = "warn"
+missing_debug_implementations = "warn"
+non_ascii_idents = "warn"
+noop_method_call = "warn"
+single_use_lifetimes = "warn"
+trivial_casts = "warn"
+trivial_numeric_casts = "warn"
+unreachable_pub = "warn"
+unsafe_op_in_unsafe_fn = "warn"
+unused_crate_dependencies = "warn"
+unused_import_braces = "warn"
+unused_lifetimes = "warn"
+unused_qualifications = "warn"
+variant_size_differences = "warn"
+
+[lints.rustdoc]
+# rustdoc lints https://doc.rust-lang.org/rustdoc/lints.html
+broken_intra_doc_links = "warn"
+private_intra_doc_links = "warn"
+missing_crate_level_docs = "warn"
+private_doc_tests = "warn"
+invalid_codeblock_attributes = "warn"
+invalid_rust_codeblocks = "warn"
+bare_urls = "warn"
+
+[lints.clippy]
+# clippy allowed by default
+dbg_macro = "warn"
+# clippy categories https://doc.rust-lang.org/clippy/
+all = { level = "warn", priority = -1 }
+correctness = { level = "warn", priority = -1 }
+suspicious = { level = "warn", priority = -1 }
+style = { level = "warn", priority = -1 }
+complexity = { level = "warn", priority = -1 }
+perf = { level = "warn", priority = -1 }
+pedantic = { level = "warn", priority = -1 }
diff --git a/pkgs/by-name/ri/river-mk-keymap/TODO b/pkgs/by-name/ri/river-mk-keymap/TODO
new file mode 100644
index 00000000..be77953e
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/TODO
@@ -0,0 +1 @@
+Look at https://github.com/stefur/flow for river wayland inclusion
diff --git a/pkgs/by-name/ri/river-mk-keymap/contrib/example.json b/pkgs/by-name/ri/river-mk-keymap/contrib/example.json
new file mode 100644
index 00000000..c8673f9a
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/contrib/example.json
@@ -0,0 +1,5 @@
+{
+    "<M-a>": {
+        "command": ["focus-view", "next"]
+    }
+}
diff --git a/pkgs/by-name/ri/river-mk-keymap/flake.lock b/pkgs/by-name/ri/river-mk-keymap/flake.lock
new file mode 100644
index 00000000..2f4a1210
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/flake.lock
@@ -0,0 +1,27 @@
+{
+  "nodes": {
+    "nixpkgs": {
+      "locked": {
+        "lastModified": 1738297584,
+        "narHash": "sha256-AYvaFBzt8dU0fcSK2jKD0Vg23K2eIRxfsVXIPCW9a0E=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "9189ac18287c599860e878e905da550aa6dec1cd",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "nixpkgs-unstable",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "root": {
+      "inputs": {
+        "nixpkgs": "nixpkgs"
+      }
+    }
+  },
+  "root": "root",
+  "version": 7
+}
diff --git a/pkgs/by-name/ri/river-mk-keymap/flake.nix b/pkgs/by-name/ri/river-mk-keymap/flake.nix
new file mode 100644
index 00000000..95a14456
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/flake.nix
@@ -0,0 +1,25 @@
+{
+  description = "A smart way to configure river keybindings";
+
+  inputs = {
+    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
+  };
+
+  outputs = {nixpkgs, ...}: let
+    system = "x86_64-linux";
+    pkgs = nixpkgs.legacyPackages."${system}";
+  in {
+    devShells."${system}".default = pkgs.mkShell {
+      packages = with pkgs; [
+        cargo
+        clippy
+        rustc
+        rustfmt
+
+        cargo-edit
+      ];
+    };
+  };
+}
+# vim: ts=2
+
diff --git a/pkgs/by-name/ri/river-mk-keymap/package.nix b/pkgs/by-name/ri/river-mk-keymap/package.nix
new file mode 100644
index 00000000..d9519d48
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/package.nix
@@ -0,0 +1,14 @@
+{rustPlatform}:
+rustPlatform.buildRustPackage {
+  pname = "river-mk-keymap";
+  version = "0.1.0";
+
+  src = ./.;
+  cargoLock = {
+    lockFile = ./Cargo.lock;
+  };
+
+  meta = {
+    mainProgram = "river-mk-keymap";
+  };
+}
diff --git a/pkgs/by-name/ri/river-mk-keymap/src/cli.rs b/pkgs/by-name/ri/river-mk-keymap/src/cli.rs
new file mode 100644
index 00000000..55b87e1a
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/src/cli.rs
@@ -0,0 +1,11 @@
+use std::path::PathBuf;
+
+use clap::Parser;
+
+#[derive(Parser, Debug)]
+#[command(author, version, about, long_about = None)]
+/// A tool to manage your key mappings for the river window manager
+pub(super) struct Args {
+    /// Path to mappings JSON file
+    pub path: PathBuf,
+}
diff --git a/pkgs/by-name/ri/river-mk-keymap/src/key_map/commands.rs b/pkgs/by-name/ri/river-mk-keymap/src/key_map/commands.rs
new file mode 100644
index 00000000..a4ac0ebd
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/src/key_map/commands.rs
@@ -0,0 +1,109 @@
+use std::process::Command;
+
+use keymaps::key_repr::{KeyValue, MediaKeyCode, MouseKeyValue};
+
+use super::{KeyMap, MapMode};
+
+impl KeyMap {
+    #[must_use]
+    pub fn to_commands(self) -> Vec<Command> {
+        self.0
+            .iter()
+            .flat_map(|(key, value)| {
+                let key = key.last().expect("Will exist");
+                let mods = {
+                    let modifiers = key.modifiers();
+                    let mut output = vec![];
+
+                    if modifiers.alt() {
+                        output.push("Alt");
+                    }
+                    if modifiers.ctrl() {
+                        output.push("Control");
+                    }
+                    if modifiers.meta() {
+                        output.push("Super");
+                    }
+                    if modifiers.shift() {
+                        output.push("Shift");
+                    }
+                    if output.is_empty() {
+                        "None".to_owned()
+                    } else {
+                        output.join("+")
+                    }
+                };
+                let key_value = match key.value() {
+                    KeyValue::Backspace => "BackSpace".to_owned(),
+                    KeyValue::Enter => "Enter".to_owned(),
+                    KeyValue::Left => "Left".to_owned(),
+                    KeyValue::Right => "Right".to_owned(),
+                    KeyValue::Up => "Up".to_owned(),
+                    KeyValue::Down => "Down".to_owned(),
+                    KeyValue::Home => "Home".to_owned(),
+                    KeyValue::End => "End".to_owned(),
+                    KeyValue::PageUp => "Page_Up".to_owned(),
+                    KeyValue::PageDown => "Page_Down".to_owned(),
+                    KeyValue::Tab => "Tab".to_owned(),
+                    KeyValue::BackTab => "BackTab".to_owned(),
+                    KeyValue::Delete => "Delete".to_owned(),
+                    KeyValue::Insert => "Insert".to_owned(),
+                    KeyValue::F(num) => format!("F{num}"),
+                    KeyValue::Char(a) => a.to_string(),
+                    KeyValue::Null => "Null".to_owned(),
+                    KeyValue::Esc => "Esc".to_owned(),
+                    KeyValue::CapsLock => "CapsLock".to_owned(),
+                    KeyValue::ScrollLock => "ScrollLock".to_owned(),
+                    KeyValue::NumLock => "NumLock".to_owned(),
+                    KeyValue::PrintScreen => "Print".to_owned(),
+                    KeyValue::Pause => "Pause".to_owned(),
+                    KeyValue::Menu => "Menu".to_owned(),
+                    KeyValue::KeypadBegin => "KeypadBegin".to_owned(),
+                    KeyValue::Media(media_key_code) => match media_key_code {
+                        MediaKeyCode::Play => "XF86AudioPlay".to_owned(),
+                        MediaKeyCode::Pause => "XF86AudioPause".to_owned(),
+                        MediaKeyCode::PlayPause => "XF86AudioPlayPause".to_owned(),
+                        MediaKeyCode::Reverse => "XF86AudioReverse".to_owned(),
+                        MediaKeyCode::Stop => "XF86AudioStop".to_owned(),
+                        MediaKeyCode::FastForward => "XF86AudioFastForward".to_owned(),
+                        MediaKeyCode::Rewind => "XF86AudioRewind".to_owned(),
+                        MediaKeyCode::TrackNext => "XF86AudioTrackNext".to_owned(),
+                        MediaKeyCode::TrackPrevious => "XF86AudioTrackPrevious".to_owned(),
+                        MediaKeyCode::Record => "XF86AudioRecord".to_owned(),
+                        MediaKeyCode::LowerVolume => "XF86AudioLowerVolume".to_owned(),
+                        MediaKeyCode::RaiseVolume => "XF86AudioRaiseVolume".to_owned(),
+                        MediaKeyCode::MuteVolume => "XF86AudioMuteVolume".to_owned(),
+                    },
+                    KeyValue::MouseKey(mouse_key_value) => match mouse_key_value {
+                        MouseKeyValue::Left => "BTN_LEFT".to_owned(),
+                        MouseKeyValue::Right => "BTN_RIGHT".to_owned(),
+                        MouseKeyValue::Middle => "BTN_MIDDLE".to_owned(),
+                    },
+                    _ => todo!(),
+                };
+
+                value
+                    .modes
+                    .iter()
+                    .map(|mode| {
+                        let mut riverctl = Command::new("riverctl");
+                        riverctl.args([value.map_mode.as_command(), mode, &mods, &key_value]);
+
+                        riverctl.args(value.command.iter().map(String::as_str));
+                        riverctl
+                    })
+                    .collect::<Vec<_>>()
+            })
+            .collect()
+    }
+}
+
+impl MapMode {
+    pub(crate) fn as_command(self) -> &'static str {
+        match self {
+            MapMode::Map => "map",
+            MapMode::MapMouse => "map-pointer",
+            MapMode::Unmap => "unmap",
+        }
+    }
+}
diff --git a/pkgs/by-name/ri/river-mk-keymap/src/key_map/mod.rs b/pkgs/by-name/ri/river-mk-keymap/src/key_map/mod.rs
new file mode 100644
index 00000000..84a16c9d
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/src/key_map/mod.rs
@@ -0,0 +1,79 @@
+use std::{collections::HashMap, fmt::Display, ops::Deref, str::FromStr};
+
+use anyhow::Context;
+use keymaps::{key_repr::Key, map_tree::MapTrie};
+use serde::{Deserialize, Serialize};
+
+pub mod commands;
+
+#[derive(Deserialize, Serialize, Debug)]
+#[allow(clippy::module_name_repetitions)]
+pub struct RawKeyMap(HashMap<Key, KeyConfig>);
+
+#[derive(Clone, Deserialize, Serialize, Debug, PartialEq, PartialOrd)]
+/// What values to use for: `riverctl <map_mode> <mode> <mods> <key> <command..>`
+pub struct KeyConfig {
+    command: Vec<String>,
+
+    #[serde(default = "default_mode")]
+    modes: Vec<String>,
+
+    #[serde(default = "MapMode::default")]
+    map_mode: MapMode,
+}
+
+impl FromStr for KeyMap {
+    type Err = anyhow::Error;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        let raw: RawKeyMap =
+            serde_json::from_str(s).context("Failed to parse the keymap config file as json.")?;
+        let mut out = MapTrie::<KeyConfig>::new();
+        for (key, value) in raw.0 {
+            out.insert(&[key], value.clone())
+                .with_context(|| format!("Failed to insert mapping {key} -> {value}"))?;
+        }
+
+        Ok(Self(out))
+    }
+}
+impl Display for KeyConfig {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.write_str(self.command.join(" ").as_str())
+    }
+}
+
+fn default_mode() -> Vec<String> {
+    vec!["normal".to_owned()]
+}
+
+#[derive(Copy, Deserialize, Serialize, Debug, Clone, Default, PartialEq, PartialOrd)]
+enum MapMode {
+    #[default]
+    Map,
+    MapMouse,
+    Unmap,
+}
+
+impl Display for MapMode {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        <Self as std::fmt::Debug>::fmt(self, f)
+    }
+}
+
+#[derive(Debug)]
+pub struct KeyMap(MapTrie<KeyConfig>);
+
+impl Display for KeyMap {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        self.0.fmt(f)
+    }
+}
+
+impl Deref for KeyMap {
+    type Target = MapTrie<KeyConfig>;
+
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
diff --git a/pkgs/by-name/ri/river-mk-keymap/src/main.rs b/pkgs/by-name/ri/river-mk-keymap/src/main.rs
new file mode 100644
index 00000000..5cb99f74
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/src/main.rs
@@ -0,0 +1,34 @@
+use std::fs;
+
+use anyhow::Context;
+use clap::Parser;
+
+mod cli;
+pub mod key_map;
+
+use crate::{cli::Args, key_map::KeyMap};
+
+fn main() -> Result<(), anyhow::Error> {
+    let args = Args::parse();
+    let keymap_file = fs::read_to_string(&args.path)
+        .with_context(|| format!("Failed to open keymap file at: '{}'.", args.path.display()))?;
+
+    let keymap: KeyMap = keymap_file
+        .parse()
+        .with_context(|| format!("Failed to parse keymap file at: {}", args.path.display()))?;
+
+    // println!("{keymap}");
+    // println!("Commands:");
+    for mut command in keymap.to_commands() {
+        // println!("Executing {command:?}");
+        let status = command
+            .status()
+            .with_context(|| format!("Failed to run command: '{command:?}'"))?;
+
+        if !status.success() {
+            eprintln!("Command ('{command:?}') returned with non zero exit code: {status}");
+        }
+    }
+
+    Ok(())
+}
diff --git a/pkgs/by-name/ri/river-mk-keymap/update.sh b/pkgs/by-name/ri/river-mk-keymap/update.sh
new file mode 100755
index 00000000..9268caf2
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/update.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+cargo update && cargo upgrade