Move default keybinds out of config
This commit is contained in:
parent
b97eb0603b
commit
48258645bb
4 changed files with 148 additions and 138 deletions
129
src/config.rs
129
src/config.rs
|
|
@ -2,68 +2,13 @@
|
||||||
|
|
||||||
use cosmic::{
|
use cosmic::{
|
||||||
cosmic_config::{self, cosmic_config_derive::CosmicConfigEntry, CosmicConfigEntry},
|
cosmic_config::{self, cosmic_config_derive::CosmicConfigEntry, CosmicConfigEntry},
|
||||||
iced::keyboard::{KeyCode, Modifiers},
|
|
||||||
theme,
|
theme,
|
||||||
};
|
};
|
||||||
use cosmic_text::Metrics;
|
use cosmic_text::Metrics;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{collections::HashMap, fmt};
|
|
||||||
|
|
||||||
use crate::{ContextPage, Message};
|
|
||||||
|
|
||||||
pub const CONFIG_VERSION: u64 = 1;
|
pub const CONFIG_VERSION: u64 = 1;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
|
|
||||||
pub enum Action {
|
|
||||||
CloseFile,
|
|
||||||
CloseProject,
|
|
||||||
Copy,
|
|
||||||
Cut,
|
|
||||||
Find,
|
|
||||||
FindAndReplace,
|
|
||||||
NewFile,
|
|
||||||
NewWindow,
|
|
||||||
OpenFileDialog,
|
|
||||||
OpenProjectDialog,
|
|
||||||
Paste,
|
|
||||||
Quit,
|
|
||||||
Redo,
|
|
||||||
Save,
|
|
||||||
SelectAll,
|
|
||||||
ToggleGitManagement,
|
|
||||||
ToggleProjectSearch,
|
|
||||||
ToggleSettingsPage,
|
|
||||||
ToggleWordWrap,
|
|
||||||
Undo,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Action {
|
|
||||||
pub fn message(&self) -> Message {
|
|
||||||
match self {
|
|
||||||
Self::CloseFile => Message::CloseFile,
|
|
||||||
Self::CloseProject => Message::CloseProject,
|
|
||||||
Self::Copy => Message::Copy,
|
|
||||||
Self::Cut => Message::Cut,
|
|
||||||
Self::Find => Message::Find(Some(false)),
|
|
||||||
Self::FindAndReplace => Message::Find(Some(true)),
|
|
||||||
Self::NewFile => Message::NewFile,
|
|
||||||
Self::NewWindow => Message::NewWindow,
|
|
||||||
Self::OpenFileDialog => Message::OpenFileDialog,
|
|
||||||
Self::OpenProjectDialog => Message::OpenProjectDialog,
|
|
||||||
Self::Paste => Message::Paste,
|
|
||||||
Self::Quit => Message::Quit,
|
|
||||||
Self::Redo => Message::Redo,
|
|
||||||
Self::Save => Message::Save,
|
|
||||||
Self::SelectAll => Message::SelectAll,
|
|
||||||
Self::ToggleGitManagement => Message::ToggleContextPage(ContextPage::GitManagement),
|
|
||||||
Self::ToggleProjectSearch => Message::ToggleContextPage(ContextPage::ProjectSearch),
|
|
||||||
Self::ToggleSettingsPage => Message::ToggleContextPage(ContextPage::Settings),
|
|
||||||
Self::ToggleWordWrap => Message::ToggleWordWrap,
|
|
||||||
Self::Undo => Message::Undo,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
|
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
|
||||||
pub enum AppTheme {
|
pub enum AppTheme {
|
||||||
Dark,
|
Dark,
|
||||||
|
|
@ -81,78 +26,6 @@ impl AppTheme {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
|
|
||||||
pub enum Modifier {
|
|
||||||
Super,
|
|
||||||
Ctrl,
|
|
||||||
Alt,
|
|
||||||
Shift,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
|
|
||||||
pub struct KeyBind {
|
|
||||||
pub modifiers: Vec<Modifier>,
|
|
||||||
pub key_code: KeyCode,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl KeyBind {
|
|
||||||
//TODO: load from config
|
|
||||||
pub fn load() -> HashMap<KeyBind, Action> {
|
|
||||||
let mut keybinds = HashMap::new();
|
|
||||||
|
|
||||||
macro_rules! bind {
|
|
||||||
([$($modifier:ident),+ $(,)?], $key_code:ident, $action:ident) => {{
|
|
||||||
keybinds.insert(
|
|
||||||
KeyBind {
|
|
||||||
modifiers: vec![$(Modifier::$modifier),+],
|
|
||||||
key_code: KeyCode::$key_code,
|
|
||||||
},
|
|
||||||
Action::$action,
|
|
||||||
);
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
bind!([Ctrl], W, CloseFile);
|
|
||||||
bind!([Ctrl], X, Cut);
|
|
||||||
bind!([Ctrl], C, Copy);
|
|
||||||
bind!([Ctrl], F, Find);
|
|
||||||
bind!([Ctrl], H, FindAndReplace);
|
|
||||||
bind!([Ctrl], V, Paste);
|
|
||||||
bind!([Ctrl], T, NewFile);
|
|
||||||
bind!([Ctrl], N, NewWindow);
|
|
||||||
bind!([Ctrl], O, OpenFileDialog);
|
|
||||||
bind!([Ctrl, Shift], O, OpenProjectDialog);
|
|
||||||
bind!([Ctrl], Q, Quit);
|
|
||||||
bind!([Ctrl, Shift], Z, Redo);
|
|
||||||
bind!([Ctrl], S, Save);
|
|
||||||
bind!([Ctrl], A, SelectAll);
|
|
||||||
bind!([Ctrl, Shift], G, ToggleGitManagement);
|
|
||||||
bind!([Ctrl, Shift], F, ToggleProjectSearch);
|
|
||||||
bind!([Ctrl], Comma, ToggleSettingsPage);
|
|
||||||
bind!([Alt], Z, ToggleWordWrap);
|
|
||||||
bind!([Ctrl], Z, Undo);
|
|
||||||
|
|
||||||
keybinds
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn matches(&self, modifiers: Modifiers, key_code: KeyCode) -> bool {
|
|
||||||
self.key_code == key_code
|
|
||||||
&& modifiers.logo() == self.modifiers.contains(&Modifier::Super)
|
|
||||||
&& modifiers.control() == self.modifiers.contains(&Modifier::Ctrl)
|
|
||||||
&& modifiers.alt() == self.modifiers.contains(&Modifier::Alt)
|
|
||||||
&& modifiers.shift() == self.modifiers.contains(&Modifier::Shift)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for KeyBind {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
for modifier in self.modifiers.iter() {
|
|
||||||
write!(f, "{:?} + ", modifier)?;
|
|
||||||
}
|
|
||||||
write!(f, "{:?}", self.key_code)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, CosmicConfigEntry, Debug, Deserialize, Eq, PartialEq, Serialize)]
|
#[derive(Clone, CosmicConfigEntry, Debug, Deserialize, Eq, PartialEq, Serialize)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub app_theme: AppTheme,
|
pub app_theme: AppTheme,
|
||||||
|
|
@ -165,7 +38,6 @@ pub struct Config {
|
||||||
pub tab_width: u16,
|
pub tab_width: u16,
|
||||||
pub vim_bindings: bool,
|
pub vim_bindings: bool,
|
||||||
pub word_wrap: bool,
|
pub word_wrap: bool,
|
||||||
pub keybinds: HashMap<KeyBind, Action>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
|
|
@ -181,7 +53,6 @@ impl Default for Config {
|
||||||
tab_width: 4,
|
tab_width: 4,
|
||||||
vim_bindings: false,
|
vim_bindings: false,
|
||||||
word_wrap: false,
|
word_wrap: false,
|
||||||
keybinds: KeyBind::load(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
77
src/key_bind.rs
Normal file
77
src/key_bind.rs
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
use cosmic::iced::keyboard::{KeyCode, Modifiers};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::{collections::HashMap, fmt};
|
||||||
|
|
||||||
|
use crate::Action;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
|
||||||
|
pub enum Modifier {
|
||||||
|
Super,
|
||||||
|
Ctrl,
|
||||||
|
Alt,
|
||||||
|
Shift,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
|
||||||
|
pub struct KeyBind {
|
||||||
|
pub modifiers: Vec<Modifier>,
|
||||||
|
pub key_code: KeyCode,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KeyBind {
|
||||||
|
pub fn matches(&self, modifiers: Modifiers, key_code: KeyCode) -> bool {
|
||||||
|
self.key_code == key_code
|
||||||
|
&& modifiers.logo() == self.modifiers.contains(&Modifier::Super)
|
||||||
|
&& modifiers.control() == self.modifiers.contains(&Modifier::Ctrl)
|
||||||
|
&& modifiers.alt() == self.modifiers.contains(&Modifier::Alt)
|
||||||
|
&& modifiers.shift() == self.modifiers.contains(&Modifier::Shift)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for KeyBind {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
for modifier in self.modifiers.iter() {
|
||||||
|
write!(f, "{:?} + ", modifier)?;
|
||||||
|
}
|
||||||
|
write!(f, "{:?}", self.key_code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: load from config
|
||||||
|
pub fn key_binds() -> HashMap<KeyBind, Action> {
|
||||||
|
let mut key_binds = HashMap::new();
|
||||||
|
|
||||||
|
macro_rules! bind {
|
||||||
|
([$($modifier:ident),+ $(,)?], $key_code:ident, $action:ident) => {{
|
||||||
|
key_binds.insert(
|
||||||
|
KeyBind {
|
||||||
|
modifiers: vec![$(Modifier::$modifier),+],
|
||||||
|
key_code: KeyCode::$key_code,
|
||||||
|
},
|
||||||
|
Action::$action,
|
||||||
|
);
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
bind!([Ctrl], W, CloseFile);
|
||||||
|
bind!([Ctrl], X, Cut);
|
||||||
|
bind!([Ctrl], C, Copy);
|
||||||
|
bind!([Ctrl], F, Find);
|
||||||
|
bind!([Ctrl], H, FindAndReplace);
|
||||||
|
bind!([Ctrl], V, Paste);
|
||||||
|
bind!([Ctrl], T, NewFile);
|
||||||
|
bind!([Ctrl], N, NewWindow);
|
||||||
|
bind!([Ctrl], O, OpenFileDialog);
|
||||||
|
bind!([Ctrl, Shift], O, OpenProjectDialog);
|
||||||
|
bind!([Ctrl], Q, Quit);
|
||||||
|
bind!([Ctrl, Shift], Z, Redo);
|
||||||
|
bind!([Ctrl], S, Save);
|
||||||
|
bind!([Ctrl], A, SelectAll);
|
||||||
|
bind!([Ctrl, Shift], G, ToggleGitManagement);
|
||||||
|
bind!([Ctrl, Shift], F, ToggleProjectSearch);
|
||||||
|
bind!([Ctrl], Comma, ToggleSettingsPage);
|
||||||
|
bind!([Alt], Z, ToggleWordWrap);
|
||||||
|
bind!([Ctrl], Z, Undo);
|
||||||
|
|
||||||
|
key_binds
|
||||||
|
}
|
||||||
66
src/main.rs
66
src/main.rs
|
|
@ -18,8 +18,10 @@ use cosmic::{
|
||||||
Application, ApplicationExt, Apply, Element,
|
Application, ApplicationExt, Apply, Element,
|
||||||
};
|
};
|
||||||
use cosmic_text::{Cursor, Edit, Family, FontSystem, Selection, SwashCache, SyntaxSystem, ViMode};
|
use cosmic_text::{Cursor, Edit, Family, FontSystem, Selection, SwashCache, SyntaxSystem, ViMode};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{
|
use std::{
|
||||||
any::TypeId,
|
any::TypeId,
|
||||||
|
collections::HashMap,
|
||||||
env, fs, io,
|
env, fs, io,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
process,
|
process,
|
||||||
|
|
@ -27,7 +29,7 @@ use std::{
|
||||||
};
|
};
|
||||||
use tokio::time;
|
use tokio::time;
|
||||||
|
|
||||||
use config::{Action, AppTheme, Config, CONFIG_VERSION};
|
use config::{AppTheme, Config, CONFIG_VERSION};
|
||||||
mod config;
|
mod config;
|
||||||
|
|
||||||
use git::{GitDiff, GitDiffLine, GitRepository, GitStatus, GitStatusKind};
|
use git::{GitDiff, GitDiffLine, GitRepository, GitStatus, GitStatusKind};
|
||||||
|
|
@ -36,6 +38,9 @@ mod git;
|
||||||
use icon_cache::IconCache;
|
use icon_cache::IconCache;
|
||||||
mod icon_cache;
|
mod icon_cache;
|
||||||
|
|
||||||
|
use key_bind::{key_binds, KeyBind};
|
||||||
|
mod key_bind;
|
||||||
|
|
||||||
use line_number::LineNumberCache;
|
use line_number::LineNumberCache;
|
||||||
mod line_number;
|
mod line_number;
|
||||||
|
|
||||||
|
|
@ -149,6 +154,57 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
|
||||||
|
pub enum Action {
|
||||||
|
CloseFile,
|
||||||
|
CloseProject,
|
||||||
|
Copy,
|
||||||
|
Cut,
|
||||||
|
Find,
|
||||||
|
FindAndReplace,
|
||||||
|
NewFile,
|
||||||
|
NewWindow,
|
||||||
|
OpenFileDialog,
|
||||||
|
OpenProjectDialog,
|
||||||
|
Paste,
|
||||||
|
Quit,
|
||||||
|
Redo,
|
||||||
|
Save,
|
||||||
|
SelectAll,
|
||||||
|
ToggleGitManagement,
|
||||||
|
ToggleProjectSearch,
|
||||||
|
ToggleSettingsPage,
|
||||||
|
ToggleWordWrap,
|
||||||
|
Undo,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Action {
|
||||||
|
pub fn message(&self) -> Message {
|
||||||
|
match self {
|
||||||
|
Self::CloseFile => Message::CloseFile,
|
||||||
|
Self::CloseProject => Message::CloseProject,
|
||||||
|
Self::Copy => Message::Copy,
|
||||||
|
Self::Cut => Message::Cut,
|
||||||
|
Self::Find => Message::Find(Some(false)),
|
||||||
|
Self::FindAndReplace => Message::Find(Some(true)),
|
||||||
|
Self::NewFile => Message::NewFile,
|
||||||
|
Self::NewWindow => Message::NewWindow,
|
||||||
|
Self::OpenFileDialog => Message::OpenFileDialog,
|
||||||
|
Self::OpenProjectDialog => Message::OpenProjectDialog,
|
||||||
|
Self::Paste => Message::Paste,
|
||||||
|
Self::Quit => Message::Quit,
|
||||||
|
Self::Redo => Message::Redo,
|
||||||
|
Self::Save => Message::Save,
|
||||||
|
Self::SelectAll => Message::SelectAll,
|
||||||
|
Self::ToggleGitManagement => Message::ToggleContextPage(ContextPage::GitManagement),
|
||||||
|
Self::ToggleProjectSearch => Message::ToggleContextPage(ContextPage::ProjectSearch),
|
||||||
|
Self::ToggleSettingsPage => Message::ToggleContextPage(ContextPage::Settings),
|
||||||
|
Self::ToggleWordWrap => Message::ToggleWordWrap,
|
||||||
|
Self::Undo => Message::Undo,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Flags {
|
pub struct Flags {
|
||||||
config_handler: Option<cosmic_config::Config>,
|
config_handler: Option<cosmic_config::Config>,
|
||||||
|
|
@ -264,6 +320,7 @@ pub struct App {
|
||||||
tab_model: segmented_button::SingleSelectModel,
|
tab_model: segmented_button::SingleSelectModel,
|
||||||
config_handler: Option<cosmic_config::Config>,
|
config_handler: Option<cosmic_config::Config>,
|
||||||
config: Config,
|
config: Config,
|
||||||
|
key_binds: HashMap<KeyBind, Action>,
|
||||||
app_themes: Vec<String>,
|
app_themes: Vec<String>,
|
||||||
font_names: Vec<String>,
|
font_names: Vec<String>,
|
||||||
font_size_names: Vec<String>,
|
font_size_names: Vec<String>,
|
||||||
|
|
@ -970,6 +1027,7 @@ impl Application for App {
|
||||||
tab_model: segmented_button::Model::builder().build(),
|
tab_model: segmented_button::Model::builder().build(),
|
||||||
config_handler: flags.config_handler,
|
config_handler: flags.config_handler,
|
||||||
config: flags.config,
|
config: flags.config,
|
||||||
|
key_binds: key_binds(),
|
||||||
app_themes,
|
app_themes,
|
||||||
font_names,
|
font_names,
|
||||||
font_size_names,
|
font_size_names,
|
||||||
|
|
@ -1281,7 +1339,7 @@ impl Application for App {
|
||||||
self.git_project_status = Some(project_status);
|
self.git_project_status = Some(project_status);
|
||||||
}
|
}
|
||||||
Message::Key(modifiers, key_code) => {
|
Message::Key(modifiers, key_code) => {
|
||||||
for (key_bind, action) in self.config.keybinds.iter() {
|
for (key_bind, action) in self.key_binds.iter() {
|
||||||
if key_bind.matches(modifiers, key_code) {
|
if key_bind.matches(modifiers, key_code) {
|
||||||
return self.update(action.message());
|
return self.update(action.message());
|
||||||
}
|
}
|
||||||
|
|
@ -1765,7 +1823,7 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn header_start(&self) -> Vec<Element<Message>> {
|
fn header_start(&self) -> Vec<Element<Message>> {
|
||||||
vec![menu_bar(&self.config)]
|
vec![menu_bar(&self.config, &self.key_binds)]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view(&self) -> Element<Message> {
|
fn view(&self) -> Element<Message> {
|
||||||
|
|
@ -1838,7 +1896,7 @@ impl Application for App {
|
||||||
text_box = text_box.line_numbers();
|
text_box = text_box.line_numbers();
|
||||||
}
|
}
|
||||||
let mut popover =
|
let mut popover =
|
||||||
widget::popover(text_box, menu::context_menu(&self.config, tab_id));
|
widget::popover(text_box, menu::context_menu(&self.key_binds, tab_id));
|
||||||
popover = match tab.context_menu {
|
popover = match tab.context_menu {
|
||||||
Some(position) => popover.position(position),
|
Some(position) => popover.position(position),
|
||||||
None => popover.show_popup(false),
|
None => popover.show_popup(false),
|
||||||
|
|
|
||||||
14
src/menu.rs
14
src/menu.rs
|
|
@ -14,8 +14,9 @@ use cosmic::{
|
||||||
},
|
},
|
||||||
Element,
|
Element,
|
||||||
};
|
};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::{fl, icon_cache_get, Action, Config, ContextPage, Message};
|
use crate::{fl, icon_cache_get, Action, Config, ContextPage, KeyBind, Message};
|
||||||
|
|
||||||
macro_rules! menu_button {
|
macro_rules! menu_button {
|
||||||
($($x:expr),+ $(,)?) => (
|
($($x:expr),+ $(,)?) => (
|
||||||
|
|
@ -32,10 +33,13 @@ macro_rules! menu_button {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn context_menu<'a>(config: &Config, entity: segmented_button::Entity) -> Element<'a, Message> {
|
pub fn context_menu<'a>(
|
||||||
|
key_binds: &HashMap<KeyBind, Action>,
|
||||||
|
entity: segmented_button::Entity,
|
||||||
|
) -> Element<'a, Message> {
|
||||||
let menu_item = |menu_label, menu_action| {
|
let menu_item = |menu_label, menu_action| {
|
||||||
let mut key = String::new();
|
let mut key = String::new();
|
||||||
for (key_bind, key_action) in config.keybinds.iter() {
|
for (key_bind, key_action) in key_binds.iter() {
|
||||||
if key_action == &menu_action {
|
if key_action == &menu_action {
|
||||||
key = key_bind.to_string();
|
key = key_bind.to_string();
|
||||||
break;
|
break;
|
||||||
|
|
@ -76,7 +80,7 @@ pub fn context_menu<'a>(config: &Config, entity: segmented_button::Entity) -> El
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn menu_bar<'a>(config: &Config) -> Element<'a, Message> {
|
pub fn menu_bar<'a>(config: &Config, key_binds: &HashMap<KeyBind, Action>) -> Element<'a, Message> {
|
||||||
//TODO: port to libcosmic
|
//TODO: port to libcosmic
|
||||||
let menu_root = |label| {
|
let menu_root = |label| {
|
||||||
widget::button(widget::text(label))
|
widget::button(widget::text(label))
|
||||||
|
|
@ -89,7 +93,7 @@ pub fn menu_bar<'a>(config: &Config) -> Element<'a, Message> {
|
||||||
|
|
||||||
let find_key = |message: &Message| -> String {
|
let find_key = |message: &Message| -> String {
|
||||||
let mut key = String::new();
|
let mut key = String::new();
|
||||||
for (key_bind, action) in config.keybinds.iter() {
|
for (key_bind, action) in key_binds.iter() {
|
||||||
if &action.message() == message {
|
if &action.message() == message {
|
||||||
key = key_bind.to_string();
|
key = key_bind.to_string();
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue