feat: Add support for action modifier keys like ctrl,shift,alt.
This commit is contained in:
@@ -7,6 +7,7 @@ use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::error::PiklError;
|
||||
use crate::event::Modifiers;
|
||||
|
||||
/// A lifecycle event emitted by the menu engine. Handler
|
||||
/// hooks receive these as JSON lines on stdin. The `event`
|
||||
@@ -16,11 +17,33 @@ use crate::error::PiklError;
|
||||
pub enum HookEvent {
|
||||
Open,
|
||||
Close,
|
||||
Hover { item: Value, index: usize },
|
||||
Select { item: Value, index: usize },
|
||||
Cancel,
|
||||
Filter { text: String },
|
||||
Quicklist { items: Vec<Value>, count: usize },
|
||||
Hover {
|
||||
item: Value,
|
||||
index: usize,
|
||||
#[serde(skip_serializing_if = "Modifiers::is_empty")]
|
||||
modifiers: Modifiers,
|
||||
},
|
||||
Select {
|
||||
item: Value,
|
||||
index: usize,
|
||||
#[serde(skip_serializing_if = "Modifiers::is_empty")]
|
||||
modifiers: Modifiers,
|
||||
},
|
||||
Cancel {
|
||||
#[serde(skip_serializing_if = "Modifiers::is_empty")]
|
||||
modifiers: Modifiers,
|
||||
},
|
||||
Filter {
|
||||
text: String,
|
||||
#[serde(skip_serializing_if = "Modifiers::is_empty")]
|
||||
modifiers: Modifiers,
|
||||
},
|
||||
Quicklist {
|
||||
items: Vec<Value>,
|
||||
count: usize,
|
||||
#[serde(skip_serializing_if = "Modifiers::is_empty")]
|
||||
modifiers: Modifiers,
|
||||
},
|
||||
}
|
||||
|
||||
/// Discriminant for [`HookEvent`], used as a key for
|
||||
@@ -44,7 +67,7 @@ impl HookEvent {
|
||||
HookEvent::Close => HookEventKind::Close,
|
||||
HookEvent::Hover { .. } => HookEventKind::Hover,
|
||||
HookEvent::Select { .. } => HookEventKind::Select,
|
||||
HookEvent::Cancel => HookEventKind::Cancel,
|
||||
HookEvent::Cancel { .. } => HookEventKind::Cancel,
|
||||
HookEvent::Filter { .. } => HookEventKind::Filter,
|
||||
HookEvent::Quicklist { .. } => HookEventKind::Quicklist,
|
||||
}
|
||||
@@ -116,11 +139,14 @@ mod tests {
|
||||
let event = HookEvent::Hover {
|
||||
item: json!({"label": "test"}),
|
||||
index: 5,
|
||||
modifiers: Modifiers::default(),
|
||||
};
|
||||
let json = serde_json::to_value(&event).unwrap_or_default();
|
||||
assert_eq!(json["event"], "hover");
|
||||
assert_eq!(json["item"]["label"], "test");
|
||||
assert_eq!(json["index"], 5);
|
||||
// Empty modifiers should be omitted
|
||||
assert!(json.get("modifiers").is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -128,6 +154,7 @@ mod tests {
|
||||
let event = HookEvent::Select {
|
||||
item: json!("hello"),
|
||||
index: 0,
|
||||
modifiers: Modifiers::default(),
|
||||
};
|
||||
let json = serde_json::to_value(&event).unwrap_or_default();
|
||||
assert_eq!(json["event"], "select");
|
||||
@@ -137,14 +164,19 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn event_cancel_serializes() {
|
||||
let json = serde_json::to_value(&HookEvent::Cancel).unwrap_or_default();
|
||||
let json = serde_json::to_value(&HookEvent::Cancel {
|
||||
modifiers: Modifiers::default(),
|
||||
})
|
||||
.unwrap_or_default();
|
||||
assert_eq!(json["event"], "cancel");
|
||||
assert!(json.get("modifiers").is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn event_filter_serializes() {
|
||||
let event = HookEvent::Filter {
|
||||
text: "foo".to_string(),
|
||||
modifiers: Modifiers::default(),
|
||||
};
|
||||
let json = serde_json::to_value(&event).unwrap_or_default();
|
||||
assert_eq!(json["event"], "filter");
|
||||
@@ -160,7 +192,8 @@ mod tests {
|
||||
assert_eq!(
|
||||
HookEvent::Hover {
|
||||
item: json!(null),
|
||||
index: 0
|
||||
index: 0,
|
||||
modifiers: Modifiers::default(),
|
||||
}
|
||||
.kind(),
|
||||
HookEventKind::Hover
|
||||
@@ -168,15 +201,23 @@ mod tests {
|
||||
assert_eq!(
|
||||
HookEvent::Select {
|
||||
item: json!(null),
|
||||
index: 0
|
||||
index: 0,
|
||||
modifiers: Modifiers::default(),
|
||||
}
|
||||
.kind(),
|
||||
HookEventKind::Select
|
||||
);
|
||||
assert_eq!(HookEvent::Cancel.kind(), HookEventKind::Cancel);
|
||||
assert_eq!(
|
||||
HookEvent::Cancel {
|
||||
modifiers: Modifiers::default()
|
||||
}
|
||||
.kind(),
|
||||
HookEventKind::Cancel
|
||||
);
|
||||
assert_eq!(
|
||||
HookEvent::Filter {
|
||||
text: String::new()
|
||||
text: String::new(),
|
||||
modifiers: Modifiers::default(),
|
||||
}
|
||||
.kind(),
|
||||
HookEventKind::Filter
|
||||
@@ -291,6 +332,7 @@ mod tests {
|
||||
let event = HookEvent::Quicklist {
|
||||
items: vec![json!("alpha"), json!("beta")],
|
||||
count: 2,
|
||||
modifiers: Modifiers::default(),
|
||||
};
|
||||
let json = serde_json::to_value(&event).unwrap_or_default();
|
||||
assert_eq!(json["event"], "quicklist");
|
||||
@@ -303,6 +345,7 @@ mod tests {
|
||||
let event = HookEvent::Quicklist {
|
||||
items: vec![],
|
||||
count: 0,
|
||||
modifiers: Modifiers::default(),
|
||||
};
|
||||
assert_eq!(event.kind(), HookEventKind::Quicklist);
|
||||
}
|
||||
@@ -314,6 +357,7 @@ mod tests {
|
||||
let event = HookEvent::Hover {
|
||||
item: json!({"label": "Firefox", "url": "https://firefox.com"}),
|
||||
index: 2,
|
||||
modifiers: Modifiers::default(),
|
||||
};
|
||||
let serialized = serde_json::to_string(&event).unwrap_or_default();
|
||||
let parsed: Value = serde_json::from_str(&serialized).unwrap_or_default();
|
||||
@@ -321,4 +365,35 @@ mod tests {
|
||||
assert_eq!(parsed["item"]["label"], "Firefox");
|
||||
assert_eq!(parsed["index"], 2);
|
||||
}
|
||||
|
||||
// -- Modifier serialization in hook events --
|
||||
|
||||
#[test]
|
||||
fn event_select_with_modifiers() {
|
||||
let event = HookEvent::Select {
|
||||
item: json!("test"),
|
||||
index: 0,
|
||||
modifiers: Modifiers {
|
||||
shift: true,
|
||||
ctrl: false,
|
||||
alt: false,
|
||||
},
|
||||
};
|
||||
let json = serde_json::to_value(&event).unwrap_or_default();
|
||||
assert_eq!(json["modifiers"], json!(["shift"]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn event_cancel_with_modifiers() {
|
||||
let event = HookEvent::Cancel {
|
||||
modifiers: Modifiers {
|
||||
shift: true,
|
||||
ctrl: true,
|
||||
alt: false,
|
||||
},
|
||||
};
|
||||
let json = serde_json::to_value(&event).unwrap_or_default();
|
||||
assert_eq!(json["event"], "cancel");
|
||||
assert_eq!(json["modifiers"], json!(["shift", "ctrl"]));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user