mirror of
https://github.com/alexpasmantier/television.git
synced 2025-06-06 11:35:25 +00:00
feat(config): allow specifying multiple keymaps for the same action + better defaults (#149)
Fixes #135
This commit is contained in:
parent
499bfdb8e5
commit
557686e197
@ -75,8 +75,8 @@ theme = "Coldark-Dark"
|
||||
# Quit the application
|
||||
quit = "esc"
|
||||
# Scrolling through entries
|
||||
select_next_entry = "down"
|
||||
select_prev_entry = "up"
|
||||
select_next_entry = ["down", "ctrl-n", "ctrl-j"]
|
||||
select_prev_entry = ["up", "ctrl-p", "ctrl-k"]
|
||||
select_next_page = "pagedown"
|
||||
select_prev_page = "pageup"
|
||||
# Scrolling the preview pane
|
||||
@ -102,8 +102,8 @@ toggle_preview = "ctrl-o"
|
||||
# Quit the application
|
||||
quit = "esc"
|
||||
# Scrolling through entries
|
||||
select_next_entry = "down"
|
||||
select_prev_entry = "up"
|
||||
select_next_entry = ["down", "ctrl-n", "ctrl-j"]
|
||||
select_prev_entry = ["up", "ctrl-p", "ctrl-k"]
|
||||
select_next_page = "pagedown"
|
||||
select_prev_page = "pageup"
|
||||
# Select an entry
|
||||
@ -122,8 +122,8 @@ toggle_preview = "ctrl-o"
|
||||
# Quit the application
|
||||
quit = "esc"
|
||||
# Scrolling through entries
|
||||
select_next_entry = "down"
|
||||
select_prev_entry = "up"
|
||||
select_next_entry = ["down", "ctrl-n", "ctrl-j"]
|
||||
select_prev_entry = ["up", "ctrl-p", "ctrl-k"]
|
||||
select_next_page = "pagedown"
|
||||
select_prev_page = "pageup"
|
||||
# Select an entry
|
||||
|
@ -3,8 +3,7 @@ use std::{env, path::PathBuf};
|
||||
|
||||
use color_eyre::Result;
|
||||
use directories::ProjectDirs;
|
||||
pub use keybindings::parse_key;
|
||||
pub use keybindings::KeyBindings;
|
||||
pub use keybindings::{parse_key, Binding, KeyBindings};
|
||||
use lazy_static::lazy_static;
|
||||
use previewers::PreviewersConfig;
|
||||
use serde::Deserialize;
|
||||
@ -118,7 +117,7 @@ impl Config {
|
||||
for (command, key) in default_bindings {
|
||||
user_bindings
|
||||
.entry(command.clone())
|
||||
.or_insert_with(|| *key);
|
||||
.or_insert_with(|| key.clone());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,14 +3,34 @@ use crate::event::{convert_raw_event_to_key, Key};
|
||||
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
|
||||
use serde::{Deserialize, Deserializer};
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Display;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use television_screen::mode::Mode;
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
pub enum Binding {
|
||||
SingleKey(Key),
|
||||
MultipleKeys(Vec<Key>),
|
||||
}
|
||||
|
||||
impl Display for Binding {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Binding::SingleKey(key) => write!(f, "{}", key),
|
||||
Binding::MultipleKeys(keys) => {
|
||||
let keys_str: Vec<String> =
|
||||
keys.iter().map(|k| k.to_string()).collect();
|
||||
write!(f, "{}", keys_str.join(", "))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct KeyBindings(pub config::Map<Mode, config::Map<Action, Key>>);
|
||||
pub struct KeyBindings(pub config::Map<Mode, config::Map<Action, Binding>>);
|
||||
|
||||
impl Deref for KeyBindings {
|
||||
type Target = config::Map<Mode, config::Map<Action, Key>>;
|
||||
type Target = config::Map<Mode, config::Map<Action, Binding>>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
@ -22,13 +42,20 @@ impl DerefMut for KeyBindings {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum SerializedBinding {
|
||||
SingleKey(String),
|
||||
MultipleKeys(Vec<String>),
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for KeyBindings {
|
||||
fn deserialize<D>(deserializer: D) -> color_eyre::Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let parsed_map =
|
||||
HashMap::<Mode, HashMap<Action, String>>::deserialize(
|
||||
HashMap::<Mode, HashMap<Action, SerializedBinding>>::deserialize(
|
||||
deserializer,
|
||||
)?;
|
||||
|
||||
@ -37,7 +64,28 @@ impl<'de> Deserialize<'de> for KeyBindings {
|
||||
.map(|(mode, inner_map)| {
|
||||
let converted_inner_map = inner_map
|
||||
.into_iter()
|
||||
.map(|(cmd, key_str)| (cmd, parse_key(&key_str).unwrap()))
|
||||
.map(|(cmd, binding)| {
|
||||
(
|
||||
cmd,
|
||||
match binding {
|
||||
SerializedBinding::SingleKey(key_str) => {
|
||||
Binding::SingleKey(
|
||||
parse_key(&key_str).unwrap(),
|
||||
)
|
||||
}
|
||||
SerializedBinding::MultipleKeys(keys_str) => {
|
||||
Binding::MultipleKeys(
|
||||
keys_str
|
||||
.iter()
|
||||
.map(|key_str| {
|
||||
parse_key(key_str).unwrap()
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
(mode, converted_inner_map)
|
||||
})
|
||||
|
@ -5,7 +5,7 @@ use color_eyre::Result;
|
||||
use television_screen::mode::Mode;
|
||||
|
||||
use crate::action::Action;
|
||||
use crate::config::KeyBindings;
|
||||
use crate::config::{Binding, KeyBindings};
|
||||
use crate::event::Key;
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
@ -23,9 +23,18 @@ impl From<&KeyBindings> for Keymap {
|
||||
let mut keymap = HashMap::new();
|
||||
for (mode, bindings) in keybindings.iter() {
|
||||
let mut mode_keymap = HashMap::new();
|
||||
for (action, key) in bindings {
|
||||
for (action, binding) in bindings {
|
||||
match binding {
|
||||
Binding::SingleKey(key) => {
|
||||
mode_keymap.insert(*key, action.clone());
|
||||
}
|
||||
Binding::MultipleKeys(keys) => {
|
||||
for key in keys {
|
||||
mode_keymap.insert(*key, action.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
keymap.insert(*mode, mode_keymap);
|
||||
}
|
||||
Self(keymap)
|
||||
|
@ -458,6 +458,7 @@ impl Television {
|
||||
.get(&self.mode)
|
||||
.unwrap()
|
||||
.get(&Action::ToggleHelp)
|
||||
// just display the first keybinding
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
&self
|
||||
@ -466,6 +467,7 @@ impl Television {
|
||||
.get(&self.mode)
|
||||
.unwrap()
|
||||
.get(&Action::TogglePreview)
|
||||
// just display the first keybinding
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
)?;
|
||||
|
Loading…
x
Reference in New Issue
Block a user