emma
/
breed
Archived
forked from mars/breed
1
0
Fork 0

Compare commits

...

8 Commits

2 changed files with 88 additions and 37 deletions

View File

@ -50,7 +50,12 @@ impl Default for Keybinds {
(End, goto_line_end_newline),
];
let normalish_keys = &[
let goto_keys = &[
(Char('h'), goto_line_start as Action),
(Char('l'), goto_line_end_newline),
];
let normalish_keys = [
(Char(':'), command_mode as Action),
(Char('h'), move_char_left),
(Char('j'), move_line_down),
@ -68,7 +73,10 @@ impl Default for Keybinds {
.iter()
.chain(basic_nav);
let insert_keys = &[
let normalish_submodes: HashMap<Key, KeyMap> =
[(Char('g'), key_map_from_iter(goto_keys))].into();
let insert_keys = [
(Backspace, delete_char_backward as Action),
(Delete, delete_char_forward),
(Enter, insert_newline),
@ -77,34 +85,28 @@ impl Default for Keybinds {
.chain(basic_nav);
Self {
normal: normalish_keys.clone().into(),
insert: insert_keys.clone().into(),
visual: normalish_keys.clone().into(),
normal: ModeKeys {
submodes: normalish_submodes.clone(),
map: key_map_from_iter(normalish_keys.clone()),
},
insert: ModeKeys {
submodes: [].into(),
map: key_map_from_iter(insert_keys),
},
visual: ModeKeys {
submodes: normalish_submodes,
map: key_map_from_iter(normalish_keys.clone()),
},
}
}
}
#[derive(Clone, Default)]
pub struct ModeKeys {
pub minor_modes: HashMap<Key, KeyMap>,
pub submodes: HashMap<Key, KeyMap>,
pub map: KeyMap,
}
impl<'a, T> From<T> for ModeKeys
where
T: IntoIterator<Item = &'a (Key, Action)>,
{
fn from(iter: T) -> Self {
let minor_modes = HashMap::new();
let mut map = KeyMap::new();
for (key, action) in iter {
map.insert(*key, Keybind::Action(*action));
}
Self { minor_modes, map }
}
}
impl ModeKeys {
pub fn apply_table(values: Table) -> Result<Self, String> {
let mut keys = Self::default();
@ -114,7 +116,7 @@ impl ModeKeys {
match value {
Value::Table(table) => {
let map = parse_key_map(table)?;
keys.minor_modes.insert(key, map);
keys.submodes.insert(key, map);
}
Value::String(keybind) => {
let bind = Keybind::try_from(keybind.as_str())?;
@ -162,6 +164,18 @@ impl TryFrom<&str> for Keybind {
}
}
pub fn key_map_from_iter<'a, T>(iter: T) -> KeyMap
where
T: IntoIterator<Item = &'a (Key, Action)>,
{
let mut map = KeyMap::new();
for (key, action) in iter {
map.insert(*key, Keybind::Action(*action));
}
map
}
pub fn parse_key_map(values: Table) -> Result<KeyMap, String> {
let mut map = KeyMap::with_capacity(values.len());

View File

@ -33,7 +33,6 @@ use crossterm::{
event::{Event, KeyCode, KeyEvent},
terminal, QueueableCommand, Result,
};
use keybinds::Keybind;
use parking_lot::Mutex;
use ropey::Rope;
use yacexits::{exit, EX_DATAERR, EX_UNAVAILABLE};
@ -46,6 +45,7 @@ mod theme;
use buffer::Buffer;
use config::Config;
use keybinds::{Key, Keybind};
use theme::StyleStore;
#[derive(Copy, Clone, Debug, Default)]
@ -111,6 +111,7 @@ pub struct State {
pub cursor: Cursor,
pub file: Option<OsString>,
pub mode: Mode,
pub submode: Option<Key>,
pub last_saved: Rope,
pub scroll: Cursor,
pub size: (usize, usize),
@ -133,6 +134,7 @@ impl State {
cursor: Cursor::default(),
file: file_name,
mode: Mode::default(),
submode: None,
last_saved,
scroll: Cursor::default(),
size: (cols as usize, rows as usize),
@ -179,6 +181,12 @@ impl State {
.buffer
.draw(cols, buffer_rows, self.scroll, self.cursor, out)?;
// draw submode
if let Some(submode) = self.submode {
out.queue(cursor::MoveTo(cols - 10, rows - 1))?;
write!(out, "{:?}", submode)?;
}
// draw cursor
let cursor_pos = set_cursor_pos.unwrap_or_else(|| {
// calculate cursor position on buffer
@ -222,9 +230,7 @@ impl State {
match event {
Event::Key(KeyEvent { code, .. }) => {
if let Some(keybind) = self.config.keybinds.visual.map.get(&code) {
self.execute_keybind(keybind.clone());
}
self.on_key(code);
}
event => self.on_any_event(event),
}
@ -274,9 +280,7 @@ impl State {
fn on_visual_event(&mut self, event: Event) {
match event {
Event::Key(KeyEvent { code, .. }) => {
if let Some(keybind) = self.config.keybinds.visual.map.get(&code) {
self.execute_keybind(keybind.clone());
}
self.on_key(code);
}
event => self.on_any_event(event),
}
@ -284,19 +288,53 @@ impl State {
fn on_insert_event(&mut self, event: Event, _state: InsertState) {
match event {
Event::Key(KeyEvent { code, .. }) => match self.config.keybinds.insert.map.get(&code) {
Some(keybind) => self.execute_keybind(keybind.clone()),
None => {
Event::Key(KeyEvent { code, .. }) => {
if !self.on_key(code) {
if let KeyCode::Char(c) = code {
self.buffer.insert_char(self.cursor, c);
self.move_cursor(Direction::Right);
}
}
},
}
event => self.on_any_event(event),
}
}
/// Processes a key press event.
///
/// Returns `true` if the key was handled by a keybind, `false` otherwise.
fn on_key(&mut self, key: Key) -> bool {
let keybinds = match &self.mode {
Mode::Normal(_) => &self.config.keybinds.normal,
Mode::Insert(_) => &self.config.keybinds.insert,
Mode::Visual => &self.config.keybinds.visual,
Mode::Command(_) => return false, // command mode is handled in [on_command_event]
};
if let Some(submode) = self.submode {
// if we're currently in a submode, try to run this submode's keybind
keybinds
.submodes
.get(&submode)
.and_then(|submode| submode.get(&key))
.cloned()
.map(|keybind| self.execute_keybind(keybind));
// whether or not there is a keybind we exit the submode
self.submode = None;
} else if keybinds.submodes.contains_key(&key) {
// enter a submode if available
self.submode = Some(key);
} else if let Some(keybind) = keybinds.map.get(&key) {
// run the keybind if available
self.execute_keybind(keybind.clone());
} else {
// key is not bound; don't handle
return false;
}
true
}
fn on_any_event(&mut self, event: Event) {
match event {
Event::Resize(cols, rows) => {
@ -434,12 +472,12 @@ fn main() -> Result<()> {
if unsafe { libc::isatty(stdin) } == 0 {
unsafe { File::from_raw_fd(stdin) }
} else {
File::open("/dev/null").unwrap()
File::open("/dev/null")?
}
}
Some(path) => {
let input_file = Path::new(path);
file_name = Some(OsString::from(input_file.clone().display().to_string()));
file_name = Some(OsString::from(&path));
File::open(input_file).unwrap_or_else(|_| {
let mut err = String::new();
@ -453,8 +491,7 @@ fn main() -> Result<()> {
})
}
}
.read_to_end(&mut buf)
.unwrap();
.read_to_end(&mut buf)?;
let text = String::from_utf8(buf).unwrap_or_else(|_| {
eprintln!(