-
-
Notifications
You must be signed in to change notification settings - Fork 78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added key maps in config #104
base: main
Are you sure you want to change the base?
Changes from 9 commits
46cbfc2
058898d
d21b487
1ee8d16
c6b16bb
554fcb6
3e1f7dc
bc19d18
05f7cf7
676c01d
2408735
4abf39e
53b0f09
d222e1d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
use crossterm::event::{KeyCode, KeyModifiers}; | ||
use serde::{de, Deserialize}; | ||
|
||
#[derive(Debug, Deserialize, Default)] | ||
#[serde(default)] | ||
pub struct KeyMap { | ||
#[serde(deserialize_with = "deseralize_key")] | ||
pub remove_previous_word: Option<Key>, | ||
Praaa181203 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
#[serde(deserialize_with = "deseralize_key")] | ||
pub remove_previous_char: Option<Key>, | ||
#[serde(deserialize_with = "deseralize_key")] | ||
pub next_word: Option<Key>, | ||
} | ||
|
||
fn deseralize_key<'de, D>(deserializer: D) -> Result<Option<Key>, D::Error> | ||
where | ||
D: de::Deserializer<'de>, | ||
{ | ||
struct KeyVisitor; | ||
impl<'de> de::Visitor<'de> for KeyVisitor { | ||
type Value = Option<Key>; | ||
|
||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
formatter.write_str("") | ||
Praaa181203 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> | ||
where | ||
E: de::Error, | ||
{ | ||
Ok(get_key_from_string(v)) | ||
} | ||
} | ||
|
||
return deserializer.deserialize_str(KeyVisitor); | ||
} | ||
|
||
#[derive(Debug)] | ||
pub struct Key { | ||
pub code: KeyCode, | ||
pub modifier: KeyModifiers, | ||
} | ||
|
||
impl Default for Key { | ||
fn default() -> Self { | ||
Self { | ||
code: KeyCode::Null, | ||
modifier: KeyModifiers::NONE, | ||
} | ||
} | ||
} | ||
|
||
fn get_key_code_from_string(string: &str) -> KeyCode { | ||
if string.len() == 1 { | ||
Praaa181203 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
let key_code_char = string.chars().next(); | ||
if let Some(key_code_char) = key_code_char { | ||
if key_code_char.is_lowercase() { | ||
return KeyCode::Char(key_code_char); | ||
} | ||
} | ||
} | ||
match string { | ||
"Backspace" => KeyCode::Backspace, | ||
"Enter" => KeyCode::Enter, | ||
"Left" => KeyCode::Left, | ||
"Right" => KeyCode::Right, | ||
"Up" => KeyCode::Up, | ||
"Down" => KeyCode::Down, | ||
"Home" => KeyCode::Home, | ||
"End" => KeyCode::End, | ||
"PageUp" => KeyCode::PageUp, | ||
"PageDown" => KeyCode::PageDown, | ||
"Tab" => KeyCode::Tab, | ||
"BackTab" => KeyCode::BackTab, | ||
"Delete" => KeyCode::Delete, | ||
"Insert" => KeyCode::Insert, | ||
"Esc" => KeyCode::Esc, | ||
"CapsLock" => KeyCode::CapsLock, | ||
"ScrollLock" => KeyCode::ScrollLock, | ||
"NumLock" => KeyCode::NumLock, | ||
"PrintScreen" => KeyCode::PrintScreen, | ||
"Pause" => KeyCode::Pause, | ||
"Menu" => KeyCode::Menu, | ||
"KeypadBegin" => KeyCode::KeypadBegin, | ||
_ => KeyCode::Null, | ||
} | ||
} | ||
|
||
fn get_key_modifier_from_string(string: &str) -> KeyModifiers { | ||
match string { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would probably be good to support non-abbreviated modifiers for each of these also. For example, "Ctrl", "Alt", etc. Some people also call the Meta key "Super" or "Win". There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did not quite understand this? |
||
"C" => KeyModifiers::CONTROL, | ||
"A" => KeyModifiers::ALT, | ||
"W" => KeyModifiers::SUPER, | ||
"H" => KeyModifiers::HYPER, | ||
"M" => KeyModifiers::META, | ||
_ => KeyModifiers::NONE, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. An unknown modifier should probably be an error, not a silent fallback to no modifier. |
||
} | ||
} | ||
|
||
fn get_key_from_string(string: &str) -> Option<Key> { | ||
let mut key = Key { | ||
code: KeyCode::Null, | ||
modifier: KeyModifiers::NONE, | ||
}; | ||
match string.split('-').count() { | ||
1 => { | ||
if string.len() == 1 { | ||
key.code = KeyCode::Null; | ||
} else { | ||
key.code = get_key_code_from_string(string); | ||
} | ||
} | ||
2 => { | ||
let mut split = string.split('-'); | ||
let key_code = split.next(); | ||
if let Some(key_code) = key_code { | ||
if key_code.len() == 1 { | ||
key.modifier = get_key_modifier_from_string(key_code); | ||
} | ||
} | ||
if key.modifier != KeyModifiers::NONE { | ||
let key_code = split.next(); | ||
if let Some(key_code) = key_code { | ||
key.code = get_key_code_from_string(key_code); | ||
if key.code == KeyCode::Null { | ||
key.modifier = KeyModifiers::NONE; | ||
} | ||
} | ||
} | ||
} | ||
_ => {} | ||
} | ||
if key.modifier == KeyModifiers::NONE && key.code == KeyCode::Null { | ||
return None; | ||
} | ||
Some(key) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think these should be named
delete_word
anddelete_char
. Ctrl-Backspace usually removes the current word.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Usually Ctrl+Backspace, removes the word (part of the word if the cursor is between the word) before the cursor, that's why i chose it to name it remove_previous_word. In my opinion
delete_word
would somewhat be misleading, becausedelete_word
indicates the its deleting the whole word, but instead it removes the word before the cursor.