diff options
author | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2025-06-29 10:32:13 +0200 |
---|---|---|
committer | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2025-06-29 10:32:13 +0200 |
commit | 3d507acb42554b2551024ee3ca8490c203a1a9f8 (patch) | |
tree | ceca79f3696cf9eab522be55c07c32e38de5edaf /pkgs/by-name/ri/river-mk-keymap/src/key_map/mod.rs | |
parent | flake.lock: Update (diff) | |
download | nixos-config-3d507acb42554b2551024ee3ca8490c203a1a9f8.zip |
pkgs/river-mk-keymap: Improve with key-chord support and which-key interface
Diffstat (limited to 'pkgs/by-name/ri/river-mk-keymap/src/key_map/mod.rs')
-rw-r--r-- | pkgs/by-name/ri/river-mk-keymap/src/key_map/mod.rs | 105 |
1 files changed, 69 insertions, 36 deletions
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 index 2c82ee05..60ed41b8 100644 --- 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 @@ -8,40 +8,91 @@ // You should have received a copy of the License along with this program. // If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -use std::{collections::HashMap, fmt::Display, ops::Deref, str::FromStr}; +use std::{fmt::Display, ops::Deref, str::FromStr}; -use anyhow::Context; -use keymaps::{key_repr::Key, map_tree::MapTrie}; +use anyhow::{anyhow, bail, Context, Result}; +use keymaps::{ + key_repr::{Key, Keys}, + map_tree::MapTrie, +}; use serde::{Deserialize, Serialize}; +use serde_json::{Map, Value}; 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..>` +/// What values to use for: `riverctl <command..>` +#[serde(deny_unknown_fields)] pub struct KeyConfig { command: Vec<String>, - #[serde(default = "default_mode")] - modes: Vec<String>, - - #[serde(default = "MapMode::default")] - map_mode: MapMode, + /// Whether to allow this key mapping in the “locked” mode. + #[serde(default)] + allow_locked: bool, } 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.")?; + fn decode_value( + output: &mut MapTrie<KeyConfig>, + current_key: Vec<Key>, + value: &Value, + ) -> Result<()> { + let key_config = if let Some(value) = value.as_array() { + KeyConfig { + command: value + .iter() + .map(|v| v.as_str().map(ToOwned::to_owned)) + .collect::<Option<_>>() + .ok_or(anyhow!("A array contained a non-string value: {value:#?}"))?, + allow_locked: false, + } + } else if let Some(object) = value.as_object() { + if object.contains_key("command") { + serde_json::from_value(value.to_owned()) + .with_context(|| format!("Failed to parse key config: {value:#?}"))? + } else { + for (key, value) in object { + let mut local_current_key = current_key.clone(); + local_current_key.push( + Key::from_str(key) + .with_context(|| format!("Failed to parse key '{key}'"))?, + ); + + decode_value(output, local_current_key, value)?; + } + return Ok(()); + } + } else { + bail!("Value ({}) is invalid (not array or object).", value) + }; + + output + .insert(¤t_key, key_config.clone()) + .with_context(|| { + format!( + "Failed to insert mapping {} -> {key_config}", + Keys::from(current_key) + ) + })?; + + Ok(()) + } + 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}"))?; + + let raw: Map<String, Value> = + serde_json::from_str(s).context("Failed to parse the keymap config file as json.")?; + + for (key, value) in raw { + decode_value( + &mut out, + vec![Key::from_str(&key) + .with_context(|| format!("Failed to parse key ('{key}')"))?], + &value, + )?; } Ok(Self(out)) @@ -53,24 +104,6 @@ impl Display for KeyConfig { } } -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>); |