add tests
This commit is contained in:
parent
345377544b
commit
49278ceec0
1 changed files with 263 additions and 11 deletions
|
@ -5,17 +5,6 @@ use std::{
|
|||
fmt::{Display, Write},
|
||||
};
|
||||
|
||||
/// TODO:
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct KeystrokeDisplay {
|
||||
/// TODO:
|
||||
pub inner: Keystroke,
|
||||
/// TODO:
|
||||
pub modifiers: Modifiers,
|
||||
/// TODO:
|
||||
pub key: String,
|
||||
}
|
||||
|
||||
/// A keystroke and associated metadata generated by the platform
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Default, Deserialize, Hash)]
|
||||
pub struct Keystroke {
|
||||
|
@ -35,6 +24,17 @@ pub struct Keystroke {
|
|||
pub key_char: Option<String>,
|
||||
}
|
||||
|
||||
/// TODO:
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct KeystrokeDisplay {
|
||||
/// TODO:
|
||||
pub inner: Keystroke,
|
||||
/// TODO:
|
||||
pub modifiers: Modifiers,
|
||||
/// TODO:
|
||||
pub key: String,
|
||||
}
|
||||
|
||||
/// Error type for `Keystroke::parse`. This is used instead of `anyhow::Error` so that Zed can use
|
||||
/// markdown to display it.
|
||||
#[derive(Debug)]
|
||||
|
@ -275,6 +275,34 @@ impl Keystroke {
|
|||
}
|
||||
self
|
||||
}
|
||||
|
||||
fn into_shifted(self) -> Self {
|
||||
let Keystroke {
|
||||
modifiers,
|
||||
key,
|
||||
key_char,
|
||||
} = self;
|
||||
let (key, modifiers) = into_shifted_key(key, modifiers);
|
||||
Self {
|
||||
key,
|
||||
modifiers,
|
||||
key_char,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl KeystrokeDisplay {
|
||||
/// TODO:
|
||||
pub fn parse(source: &str) -> std::result::Result<Self, InvalidKeystrokeError> {
|
||||
let keystroke = Keystroke::parse(source)?;
|
||||
let (key, modifiers) = to_unshifted_key(&keystroke.key, &keystroke.modifiers);
|
||||
let inner = keystroke.into_shifted();
|
||||
Ok(KeystrokeDisplay {
|
||||
inner,
|
||||
key,
|
||||
modifiers,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn is_printable_key(key: &str) -> bool {
|
||||
|
@ -611,3 +639,227 @@ pub struct Capslock {
|
|||
#[serde(default)]
|
||||
pub on: bool,
|
||||
}
|
||||
|
||||
fn to_unshifted_key(key: &str, modifiers: &Modifiers) -> (String, Modifiers) {
|
||||
let mut modifiers = modifiers.clone();
|
||||
match key {
|
||||
"~" => {
|
||||
modifiers.shift = true;
|
||||
("`".to_string(), modifiers)
|
||||
}
|
||||
"!" => {
|
||||
modifiers.shift = true;
|
||||
("1".to_string(), modifiers)
|
||||
}
|
||||
"@" => {
|
||||
modifiers.shift = true;
|
||||
("2".to_string(), modifiers)
|
||||
}
|
||||
"#" => {
|
||||
modifiers.shift = true;
|
||||
("3".to_string(), modifiers)
|
||||
}
|
||||
"$" => {
|
||||
modifiers.shift = true;
|
||||
("4".to_string(), modifiers)
|
||||
}
|
||||
"%" => {
|
||||
modifiers.shift = true;
|
||||
("5".to_string(), modifiers)
|
||||
}
|
||||
"^" => {
|
||||
modifiers.shift = true;
|
||||
("6".to_string(), modifiers)
|
||||
}
|
||||
"&" => {
|
||||
modifiers.shift = true;
|
||||
("7".to_string(), modifiers)
|
||||
}
|
||||
"*" => {
|
||||
modifiers.shift = true;
|
||||
("8".to_string(), modifiers)
|
||||
}
|
||||
"(" => {
|
||||
modifiers.shift = true;
|
||||
("9".to_string(), modifiers)
|
||||
}
|
||||
")" => {
|
||||
modifiers.shift = true;
|
||||
("0".to_string(), modifiers)
|
||||
}
|
||||
"_" => {
|
||||
modifiers.shift = true;
|
||||
("-".to_string(), modifiers)
|
||||
}
|
||||
"+" => {
|
||||
modifiers.shift = true;
|
||||
("=".to_string(), modifiers)
|
||||
}
|
||||
"{" => {
|
||||
modifiers.shift = true;
|
||||
("[".to_string(), modifiers)
|
||||
}
|
||||
"}" => {
|
||||
modifiers.shift = true;
|
||||
("]".to_string(), modifiers)
|
||||
}
|
||||
"|" => {
|
||||
modifiers.shift = true;
|
||||
("\\".to_string(), modifiers)
|
||||
}
|
||||
":" => {
|
||||
modifiers.shift = true;
|
||||
(";".to_string(), modifiers)
|
||||
}
|
||||
"\"" => {
|
||||
modifiers.shift = true;
|
||||
("'".to_string(), modifiers)
|
||||
}
|
||||
"<" => {
|
||||
modifiers.shift = true;
|
||||
(",".to_string(), modifiers)
|
||||
}
|
||||
">" => {
|
||||
modifiers.shift = true;
|
||||
(">".to_string(), modifiers)
|
||||
}
|
||||
"?" => {
|
||||
modifiers.shift = true;
|
||||
("/".to_string(), modifiers)
|
||||
}
|
||||
_ => (key.to_string(), modifiers),
|
||||
}
|
||||
}
|
||||
|
||||
fn into_shifted_key(key: String, mut modifiers: Modifiers) -> (String, Modifiers) {
|
||||
if !modifiers.shift {
|
||||
(key, modifiers)
|
||||
} else {
|
||||
match key.as_str() {
|
||||
"`" => {
|
||||
modifiers.shift = false;
|
||||
("~".to_string(), modifiers)
|
||||
}
|
||||
"1" => {
|
||||
modifiers.shift = false;
|
||||
("!".to_string(), modifiers)
|
||||
}
|
||||
"2" => {
|
||||
modifiers.shift = false;
|
||||
("@".to_string(), modifiers)
|
||||
}
|
||||
"3" => {
|
||||
modifiers.shift = false;
|
||||
("#".to_string(), modifiers)
|
||||
}
|
||||
"4" => {
|
||||
modifiers.shift = false;
|
||||
("$".to_string(), modifiers)
|
||||
}
|
||||
"5" => {
|
||||
modifiers.shift = false;
|
||||
("%".to_string(), modifiers)
|
||||
}
|
||||
"6" => {
|
||||
modifiers.shift = false;
|
||||
("^".to_string(), modifiers)
|
||||
}
|
||||
"7" => {
|
||||
modifiers.shift = false;
|
||||
("&".to_string(), modifiers)
|
||||
}
|
||||
"8" => {
|
||||
modifiers.shift = false;
|
||||
("*".to_string(), modifiers)
|
||||
}
|
||||
"9" => {
|
||||
modifiers.shift = false;
|
||||
("(".to_string(), modifiers)
|
||||
}
|
||||
"0" => {
|
||||
modifiers.shift = false;
|
||||
(")".to_string(), modifiers)
|
||||
}
|
||||
"-" => {
|
||||
modifiers.shift = false;
|
||||
("_".to_string(), modifiers)
|
||||
}
|
||||
"=" => {
|
||||
modifiers.shift = false;
|
||||
("+".to_string(), modifiers)
|
||||
}
|
||||
"[" => {
|
||||
modifiers.shift = false;
|
||||
("{".to_string(), modifiers)
|
||||
}
|
||||
"]" => {
|
||||
modifiers.shift = false;
|
||||
("}".to_string(), modifiers)
|
||||
}
|
||||
"\\" => {
|
||||
modifiers.shift = false;
|
||||
("|".to_string(), modifiers)
|
||||
}
|
||||
";" => {
|
||||
modifiers.shift = false;
|
||||
(":".to_string(), modifiers)
|
||||
}
|
||||
"'" => {
|
||||
modifiers.shift = false;
|
||||
("\"".to_string(), modifiers)
|
||||
}
|
||||
"," => {
|
||||
modifiers.shift = false;
|
||||
("<".to_string(), modifiers)
|
||||
}
|
||||
"." => {
|
||||
modifiers.shift = false;
|
||||
(">".to_string(), modifiers)
|
||||
}
|
||||
"/" => {
|
||||
modifiers.shift = false;
|
||||
("?".to_string(), modifiers)
|
||||
}
|
||||
_ => (key, modifiers),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{Keystroke, KeystrokeDisplay, Modifiers};
|
||||
|
||||
#[test]
|
||||
fn test_parsing_keystroke_on_windows() {
|
||||
// On windows, users prefer to use "ctrl-shift-key", so here we support
|
||||
// both "ctrl-$" and "ctrl-shift-4"
|
||||
let source = "ctrl-$";
|
||||
let keystroke = Keystroke::parse(source).unwrap();
|
||||
assert_eq!(keystroke.modifiers, Modifiers::control());
|
||||
assert_eq!(keystroke.key, "$");
|
||||
assert_eq!(keystroke.key_char, None);
|
||||
|
||||
let keystroke_display = KeystrokeDisplay::parse(source).unwrap();
|
||||
assert_eq!(keystroke_display.inner, keystroke);
|
||||
assert_eq!(keystroke_display.key, "4");
|
||||
assert_eq!(keystroke_display.modifiers, Modifiers::control_shift());
|
||||
|
||||
let source = "ctrl-shift-4";
|
||||
let keystroke = Keystroke::parse(source).unwrap();
|
||||
assert_eq!(keystroke.modifiers, Modifiers::control_shift());
|
||||
assert_eq!(keystroke.key, "4");
|
||||
assert_eq!(keystroke.key_char, None);
|
||||
|
||||
let keystroke_display = KeystrokeDisplay::parse(source).unwrap();
|
||||
assert_eq!(
|
||||
keystroke_display.inner,
|
||||
Keystroke {
|
||||
modifiers: Modifiers::control(),
|
||||
key: "$".to_string(),
|
||||
key_char: None
|
||||
}
|
||||
);
|
||||
assert_eq!(keystroke_display.key, "4");
|
||||
assert_eq!(keystroke_display.modifiers, Modifiers::control_shift());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue