Skip to main content

Mountain/ApplicationState/State/FeatureState/Keybindings/
KeybindingState.rs

1use std::sync::{Arc, Mutex as StandardMutex};
2
3use serde::{Deserialize, Serialize};
4
5use crate::dev_log;
6
7/// A single registered dynamic keybinding entry.
8#[derive(Clone, Debug, Serialize, Deserialize)]
9pub struct KeybindingEntry {
10	/// Command identifier (e.g. "workbench.action.files.save").
11	pub CommandId:String,
12
13	/// Key expression (e.g. "ctrl+s", "cmd+shift+p").
14	pub Keybinding:String,
15
16	/// Optional when-clause (e.g. "editorFocus && !editorReadonly").
17	pub When:Option<String>,
18}
19
20/// Stores dynamically registered keyboard shortcuts.
21#[derive(Clone)]
22pub struct KeybindingState {
23	Entries:Arc<StandardMutex<Vec<KeybindingEntry>>>,
24}
25
26impl Default for KeybindingState {
27	fn default() -> Self {
28		dev_log!("keybinding", "[KeybindingState] Initializing default keybinding state...");
29
30		Self { Entries:Arc::new(StandardMutex::new(Vec::new())) }
31	}
32}
33
34impl KeybindingState {
35	/// Register a dynamic keybinding (replaces any existing entry for the same
36	/// command).
37	pub fn AddKeybinding(&self, CommandId:String, Keybinding:String, When:Option<String>) {
38		if let Ok(mut Guard) = self.Entries.lock() {
39			Guard.retain(|E| E.CommandId != CommandId);
40
41			Guard.push(KeybindingEntry { CommandId:CommandId.clone(), Keybinding, When });
42
43			dev_log!("keybinding", "[KeybindingState] Keybinding added for: {}", CommandId);
44		}
45	}
46
47	/// Remove all dynamic keybindings for a command.
48	pub fn RemoveKeybinding(&self, CommandId:&str) {
49		if let Ok(mut Guard) = self.Entries.lock() {
50			Guard.retain(|E| E.CommandId != CommandId);
51
52			dev_log!("keybinding", "[KeybindingState] Keybinding removed for: {}", CommandId);
53		}
54	}
55
56	/// Return the resolved keybinding string for a command, or `None`.
57	pub fn LookupKeybinding(&self, CommandId:&str) -> Option<String> {
58		self.Entries
59			.lock()
60			.ok()
61			.and_then(|Guard| Guard.iter().find(|E| E.CommandId == CommandId).map(|E| E.Keybinding.clone()))
62	}
63
64	/// Return all registered dynamic keybinding entries.
65	pub fn GetAllKeybindings(&self) -> Vec<KeybindingEntry> {
66		self.Entries.lock().ok().map(|Guard| Guard.clone()).unwrap_or_default()
67	}
68}