mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
WIP [no ci]
This commit is contained in:
parent
530f8ca317
commit
50b7f1af2b
5 changed files with 161 additions and 149 deletions
|
|
@ -2,7 +2,7 @@ use anyhow::bail;
|
||||||
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
|
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Hash)]
|
||||||
#[serde(try_from = "String")]
|
#[serde(try_from = "String")]
|
||||||
pub struct Key {
|
pub struct Key {
|
||||||
pub code: KeyCode,
|
pub code: KeyCode,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
use tokio::fs;
|
use tokio::fs;
|
||||||
use tracing::info;
|
|
||||||
use yazi_config::keymap::{Exec, KeymapLayer};
|
use yazi_config::keymap::{Exec, KeymapLayer};
|
||||||
|
|
||||||
use crate::{completion::Completion, emit};
|
use crate::{completion::Completion, emit};
|
||||||
|
|
|
||||||
|
|
@ -70,27 +70,8 @@ impl Ctx {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn layer(&self) -> KeymapLayer {
|
|
||||||
if self.which.visible {
|
|
||||||
KeymapLayer::Which
|
|
||||||
} else if self.completion.visible {
|
|
||||||
KeymapLayer::Completion
|
|
||||||
} else if self.help.visible {
|
|
||||||
KeymapLayer::Help
|
|
||||||
} else if self.input.visible {
|
|
||||||
KeymapLayer::Input
|
|
||||||
} else if self.select.visible {
|
|
||||||
KeymapLayer::Select
|
|
||||||
} else if self.tasks.visible {
|
|
||||||
KeymapLayer::Tasks
|
|
||||||
} else {
|
|
||||||
KeymapLayer::Manager
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn image_layer(&self) -> bool {
|
pub fn image_layer(&self) -> bool {
|
||||||
!matches!(self.layer(), KeymapLayer::Which | KeymapLayer::Help | KeymapLayer::Tasks)
|
!self.which.visible && !self.help.visible && !self.tasks.visible
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,13 +59,13 @@ impl App {
|
||||||
|
|
||||||
fn dispatch_key(&mut self, key: KeyEvent) {
|
fn dispatch_key(&mut self, key: KeyEvent) {
|
||||||
let key = Key::from(key);
|
let key = Key::from(key);
|
||||||
if Executor::handle(&mut self.cx, key) {
|
if Executor::new(&mut self.cx).handle(key) {
|
||||||
emit!(Render);
|
emit!(Render);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dispatch_paste(&mut self, str: String) {
|
fn dispatch_paste(&mut self, str: String) {
|
||||||
if self.cx.layer() == KeymapLayer::Input {
|
if self.cx.input.visible {
|
||||||
let input = &mut self.cx.input;
|
let input = &mut self.cx.input;
|
||||||
if input.mode() == InputMode::Insert && input.type_str(&str) {
|
if input.mode() == InputMode::Insert && input.type_str(&str) {
|
||||||
emit!(Render);
|
emit!(Render);
|
||||||
|
|
@ -112,7 +112,7 @@ impl App {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn dispatch_call(&mut self, exec: Vec<Exec>, layer: KeymapLayer) {
|
fn dispatch_call(&mut self, exec: Vec<Exec>, layer: KeymapLayer) {
|
||||||
if Executor::dispatch(&mut self.cx, &exec, layer) {
|
if Executor::new(&mut self.cx).dispatch(&exec, layer) {
|
||||||
emit!(Render);
|
emit!(Render);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,79 +2,99 @@ use yazi_config::{keymap::{Control, Exec, Key, KeymapLayer}, KEYMAP};
|
||||||
use yazi_core::{emit, input::InputMode, tab::FinderCase, Ctx};
|
use yazi_core::{emit, input::InputMode, tab::FinderCase, Ctx};
|
||||||
use yazi_shared::{optional_bool, Url};
|
use yazi_shared::{optional_bool, Url};
|
||||||
|
|
||||||
pub(super) struct Executor;
|
pub(super) struct Executor<'a> {
|
||||||
|
cx: &'a mut Ctx,
|
||||||
|
}
|
||||||
|
|
||||||
impl Executor {
|
impl<'a> Executor<'a> {
|
||||||
pub(super) fn handle(cx: &mut Ctx, key: Key) -> bool {
|
#[inline]
|
||||||
let layer = cx.layer();
|
pub(super) fn new(cx: &'a mut Ctx) -> Self { Self { cx } }
|
||||||
if layer == KeymapLayer::Which {
|
|
||||||
return cx.which.press(key);
|
pub(super) fn handle(&mut self, key: Key) -> bool {
|
||||||
|
if self.cx.which.visible {
|
||||||
|
return self.cx.which.press(key);
|
||||||
}
|
}
|
||||||
|
if self.cx.input.visible && self.cx.input.type_(&key) {
|
||||||
if layer == KeymapLayer::Input && cx.input.type_(&key) {
|
return true;
|
||||||
|
}
|
||||||
|
if self.cx.help.visible && self.cx.help.type_(&key) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if layer == KeymapLayer::Help && cx.help.type_(&key) {
|
let b = if self.cx.completion.visible {
|
||||||
return true;
|
self.matches(KeymapLayer::Completion, key).or_else(|| self.matches(KeymapLayer::Input, key))
|
||||||
}
|
} else if self.cx.help.visible {
|
||||||
|
self.matches(KeymapLayer::Help, key)
|
||||||
|
} else if self.cx.input.visible {
|
||||||
|
self.matches(KeymapLayer::Input, key)
|
||||||
|
} else if self.cx.select.visible {
|
||||||
|
self.matches(KeymapLayer::Select, key)
|
||||||
|
} else if self.cx.tasks.visible {
|
||||||
|
self.matches(KeymapLayer::Tasks, key)
|
||||||
|
} else {
|
||||||
|
self.matches(KeymapLayer::Manager, key)
|
||||||
|
};
|
||||||
|
b == Some(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn matches(&mut self, layer: KeymapLayer, key: Key) -> Option<bool> {
|
||||||
for Control { on, exec, .. } in KEYMAP.get(layer) {
|
for Control { on, exec, .. } in KEYMAP.get(layer) {
|
||||||
if on.is_empty() || on[0] != key {
|
if on.is_empty() || on[0] != key {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return if on.len() > 1 {
|
return Some(if on.len() > 1 {
|
||||||
cx.which.show(&key, layer)
|
self.cx.which.show(&key, layer)
|
||||||
} else {
|
} else {
|
||||||
Self::dispatch(cx, exec, layer)
|
self.dispatch(exec, layer)
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
false
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super) fn dispatch(cx: &mut Ctx, exec: &[Exec], layer: KeymapLayer) -> bool {
|
pub(super) fn dispatch(&mut self, exec: &[Exec], layer: KeymapLayer) -> bool {
|
||||||
let mut render = false;
|
let mut render = false;
|
||||||
for e in exec {
|
for e in exec {
|
||||||
render |= match layer {
|
render |= match layer {
|
||||||
KeymapLayer::Manager => Self::manager(cx, e),
|
KeymapLayer::Manager => self.manager(e),
|
||||||
KeymapLayer::Tasks => Self::tasks(cx, e),
|
KeymapLayer::Tasks => self.tasks(e),
|
||||||
KeymapLayer::Select => Self::select(cx, e),
|
KeymapLayer::Select => self.select(e),
|
||||||
KeymapLayer::Input => Self::input(cx, e),
|
KeymapLayer::Input => self.input(e),
|
||||||
KeymapLayer::Help => Self::help(cx, e),
|
KeymapLayer::Help => self.help(e),
|
||||||
KeymapLayer::Completion => Self::completion(cx, e),
|
KeymapLayer::Completion => self.completion(e),
|
||||||
KeymapLayer::Which => unreachable!(),
|
KeymapLayer::Which => unreachable!(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
render
|
render
|
||||||
}
|
}
|
||||||
|
|
||||||
fn manager(cx: &mut Ctx, exec: &Exec) -> bool {
|
fn manager(&mut self, exec: &Exec) -> bool {
|
||||||
match exec.cmd.as_str() {
|
match exec.cmd.as_str() {
|
||||||
"escape" => cx.manager.active_mut().escape(exec),
|
"escape" => self.cx.manager.active_mut().escape(exec),
|
||||||
"quit" => cx.manager.quit(&cx.tasks, exec.named.contains_key("no-cwd-file")),
|
"quit" => self.cx.manager.quit(&self.cx.tasks, exec.named.contains_key("no-cwd-file")),
|
||||||
"close" => cx.manager.close(&cx.tasks),
|
"close" => self.cx.manager.close(&self.cx.tasks),
|
||||||
"suspend" => cx.manager.suspend(),
|
"suspend" => self.cx.manager.suspend(),
|
||||||
|
|
||||||
// Navigation
|
// Navigation
|
||||||
"arrow" => {
|
"arrow" => {
|
||||||
let step = exec.args.get(0).and_then(|s| s.parse().ok()).unwrap_or_default();
|
let step = exec.args.first().and_then(|s| s.parse().ok()).unwrap_or_default();
|
||||||
cx.manager.active_mut().arrow(step)
|
self.cx.manager.active_mut().arrow(step)
|
||||||
}
|
}
|
||||||
"peek" => {
|
"peek" => {
|
||||||
let step = exec.args.get(0).and_then(|s| s.parse().ok()).unwrap_or(0);
|
let step = exec.args.first().and_then(|s| s.parse().ok()).unwrap_or(0);
|
||||||
cx.manager.active_mut().preview.arrow(step);
|
self.cx.manager.active_mut().preview.arrow(step);
|
||||||
cx.manager.peek(true, cx.image_layer())
|
self.cx.manager.peek(true, self.cx.image_layer())
|
||||||
}
|
}
|
||||||
"leave" => cx.manager.active_mut().leave(),
|
"leave" => self.cx.manager.active_mut().leave(),
|
||||||
"enter" => cx.manager.active_mut().enter(),
|
"enter" => self.cx.manager.active_mut().enter(),
|
||||||
"back" => cx.manager.active_mut().back(),
|
"back" => self.cx.manager.active_mut().back(),
|
||||||
"forward" => cx.manager.active_mut().forward(),
|
"forward" => self.cx.manager.active_mut().forward(),
|
||||||
"cd" => {
|
"cd" => {
|
||||||
let url = exec.args.get(0).map(Url::from).unwrap_or_default();
|
let url = exec.args.first().map(Url::from).unwrap_or_default();
|
||||||
if exec.named.contains_key("interactive") {
|
if exec.named.contains_key("interactive") {
|
||||||
cx.manager.active_mut().cd_interactive(url)
|
self.cx.manager.active_mut().cd_interactive(url)
|
||||||
} else {
|
} else {
|
||||||
emit!(Cd(url));
|
emit!(Cd(url));
|
||||||
false
|
false
|
||||||
|
|
@ -84,64 +104,68 @@ impl Executor {
|
||||||
// Selection
|
// Selection
|
||||||
"select" => {
|
"select" => {
|
||||||
let state = exec.named.get("state").cloned().unwrap_or("none".to_string());
|
let state = exec.named.get("state").cloned().unwrap_or("none".to_string());
|
||||||
cx.manager.active_mut().select(optional_bool(&state))
|
self.cx.manager.active_mut().select(optional_bool(&state))
|
||||||
}
|
}
|
||||||
"select_all" => {
|
"select_all" => {
|
||||||
let state = exec.named.get("state").cloned().unwrap_or("none".to_string());
|
let state = exec.named.get("state").cloned().unwrap_or("none".to_string());
|
||||||
cx.manager.active_mut().select_all(optional_bool(&state))
|
self.cx.manager.active_mut().select_all(optional_bool(&state))
|
||||||
}
|
}
|
||||||
"visual_mode" => cx.manager.active_mut().visual_mode(exec.named.contains_key("unset")),
|
"visual_mode" => self.cx.manager.active_mut().visual_mode(exec.named.contains_key("unset")),
|
||||||
|
|
||||||
// Operation
|
// Operation
|
||||||
"open" => cx.manager.open(exec.named.contains_key("interactive")),
|
"open" => self.cx.manager.open(exec.named.contains_key("interactive")),
|
||||||
"yank" => cx.manager.yank(exec.named.contains_key("cut")),
|
"yank" => self.cx.manager.yank(exec.named.contains_key("cut")),
|
||||||
"paste" => {
|
"paste" => {
|
||||||
let dest = cx.manager.cwd();
|
let dest = self.cx.manager.cwd();
|
||||||
let (cut, ref src) = cx.manager.yanked;
|
let (cut, ref src) = self.cx.manager.yanked;
|
||||||
|
|
||||||
let force = exec.named.contains_key("force");
|
let force = exec.named.contains_key("force");
|
||||||
if cut { cx.tasks.file_cut(src, dest, force) } else { cx.tasks.file_copy(src, dest, force) }
|
if cut {
|
||||||
|
self.cx.tasks.file_cut(src, dest, force)
|
||||||
|
} else {
|
||||||
|
self.cx.tasks.file_copy(src, dest, force)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"link" => {
|
"link" => {
|
||||||
let (cut, ref src) = cx.manager.yanked;
|
let (cut, ref src) = self.cx.manager.yanked;
|
||||||
!cut
|
!cut
|
||||||
&& cx.tasks.file_link(
|
&& self.cx.tasks.file_link(
|
||||||
src,
|
src,
|
||||||
cx.manager.cwd(),
|
self.cx.manager.cwd(),
|
||||||
exec.named.contains_key("relative"),
|
exec.named.contains_key("relative"),
|
||||||
exec.named.contains_key("force"),
|
exec.named.contains_key("force"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
"remove" => {
|
"remove" => {
|
||||||
let targets = cx.manager.selected().into_iter().map(|f| f.url()).collect();
|
let targets = self.cx.manager.selected().into_iter().map(|f| f.url()).collect();
|
||||||
let force = exec.named.contains_key("force");
|
let force = exec.named.contains_key("force");
|
||||||
let permanently = exec.named.contains_key("permanently");
|
let permanently = exec.named.contains_key("permanently");
|
||||||
cx.tasks.file_remove(targets, force, permanently)
|
self.cx.tasks.file_remove(targets, force, permanently)
|
||||||
}
|
}
|
||||||
"create" => cx.manager.create(exec.named.contains_key("force")),
|
"create" => self.cx.manager.create(exec.named.contains_key("force")),
|
||||||
"rename" => cx.manager.rename(exec.named.contains_key("force")),
|
"rename" => self.cx.manager.rename(exec.named.contains_key("force")),
|
||||||
"copy" => cx.manager.active().copy(exec.args.get(0).map(|s| s.as_str()).unwrap_or("")),
|
"copy" => self.cx.manager.active().copy(exec.args.first().map(|s| s.as_str()).unwrap_or("")),
|
||||||
"shell" => cx.manager.active().shell(
|
"shell" => self.cx.manager.active().shell(
|
||||||
exec.args.get(0).map(|e| e.as_str()).unwrap_or(""),
|
exec.args.first().map(|e| e.as_str()).unwrap_or(""),
|
||||||
exec.named.contains_key("block"),
|
exec.named.contains_key("block"),
|
||||||
exec.named.contains_key("confirm"),
|
exec.named.contains_key("confirm"),
|
||||||
),
|
),
|
||||||
"hidden" => cx.manager.active_mut().hidden(exec),
|
"hidden" => self.cx.manager.active_mut().hidden(exec),
|
||||||
"linemode" => cx.manager.active_mut().linemode(exec),
|
"linemode" => self.cx.manager.active_mut().linemode(exec),
|
||||||
"search" => match exec.args.get(0).map(|s| s.as_str()).unwrap_or("") {
|
"search" => match exec.args.first().map(|s| s.as_str()).unwrap_or("") {
|
||||||
"rg" => cx.manager.active_mut().search(true),
|
"rg" => self.cx.manager.active_mut().search(true),
|
||||||
"fd" => cx.manager.active_mut().search(false),
|
"fd" => self.cx.manager.active_mut().search(false),
|
||||||
_ => cx.manager.active_mut().search_stop(),
|
_ => self.cx.manager.active_mut().search_stop(),
|
||||||
},
|
},
|
||||||
"jump" => match exec.args.get(0).map(|s| s.as_str()).unwrap_or("") {
|
"jump" => match exec.args.first().map(|s| s.as_str()).unwrap_or("") {
|
||||||
"fzf" => cx.manager.active_mut().jump(true),
|
"fzf" => self.cx.manager.active_mut().jump(true),
|
||||||
"zoxide" => cx.manager.active_mut().jump(false),
|
"zoxide" => self.cx.manager.active_mut().jump(false),
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
|
|
||||||
// Find
|
// Find
|
||||||
"find" => {
|
"find" => {
|
||||||
let query = exec.args.get(0).map(|s| s.as_str());
|
let query = exec.args.first().map(|s| s.as_str());
|
||||||
let prev = exec.named.contains_key("previous");
|
let prev = exec.named.contains_key("previous");
|
||||||
let case = match (exec.named.contains_key("smart"), exec.named.contains_key("insensitive"))
|
let case = match (exec.named.contains_key("smart"), exec.named.contains_key("insensitive"))
|
||||||
{
|
{
|
||||||
|
|
@ -149,152 +173,160 @@ impl Executor {
|
||||||
(_, false) => FinderCase::Sensitive,
|
(_, false) => FinderCase::Sensitive,
|
||||||
(_, true) => FinderCase::Insensitive,
|
(_, true) => FinderCase::Insensitive,
|
||||||
};
|
};
|
||||||
cx.manager.active_mut().find(query, prev, case)
|
self.cx.manager.active_mut().find(query, prev, case)
|
||||||
}
|
}
|
||||||
"find_arrow" => cx.manager.active_mut().find_arrow(exec.named.contains_key("previous")),
|
"find_arrow" => self.cx.manager.active_mut().find_arrow(exec.named.contains_key("previous")),
|
||||||
|
|
||||||
// Sorting
|
// Sorting
|
||||||
"sort" => {
|
"sort" => {
|
||||||
let b = cx.manager.active_mut().sort(exec);
|
let b = self.cx.manager.active_mut().sort(exec);
|
||||||
cx.tasks.precache_size(&cx.manager.current().files);
|
self.cx.tasks.precache_size(&self.cx.manager.current().files);
|
||||||
b
|
b
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tabs
|
// Tabs
|
||||||
"tab_create" => {
|
"tab_create" => {
|
||||||
let path = if exec.named.contains_key("current") {
|
let path = if exec.named.contains_key("current") {
|
||||||
cx.manager.cwd().to_owned()
|
self.cx.manager.cwd().to_owned()
|
||||||
} else {
|
} else {
|
||||||
exec.args.get(0).map(Url::from).unwrap_or_else(|| Url::from("/"))
|
exec.args.first().map(Url::from).unwrap_or_else(|| Url::from("/"))
|
||||||
};
|
};
|
||||||
cx.manager.tabs.create(&path)
|
self.cx.manager.tabs.create(&path)
|
||||||
}
|
}
|
||||||
"tab_close" => {
|
"tab_close" => {
|
||||||
let idx = exec.args.get(0).and_then(|i| i.parse().ok()).unwrap_or(0);
|
let idx = exec.args.first().and_then(|i| i.parse().ok()).unwrap_or(0);
|
||||||
cx.manager.tabs.close(idx)
|
self.cx.manager.tabs.close(idx)
|
||||||
}
|
}
|
||||||
"tab_switch" => {
|
"tab_switch" => {
|
||||||
let step = exec.args.get(0).and_then(|s| s.parse().ok()).unwrap_or(0);
|
let step = exec.args.first().and_then(|s| s.parse().ok()).unwrap_or(0);
|
||||||
let rel = exec.named.contains_key("relative");
|
let rel = exec.named.contains_key("relative");
|
||||||
cx.manager.tabs.switch(step, rel)
|
self.cx.manager.tabs.switch(step, rel)
|
||||||
}
|
}
|
||||||
"tab_swap" => {
|
"tab_swap" => {
|
||||||
let step = exec.args.get(0).and_then(|s| s.parse().ok()).unwrap_or(0);
|
let step = exec.args.first().and_then(|s| s.parse().ok()).unwrap_or(0);
|
||||||
cx.manager.tabs.swap(step)
|
self.cx.manager.tabs.swap(step)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tasks
|
// Tasks
|
||||||
"tasks_show" => cx.tasks.toggle(),
|
"tasks_show" => self.cx.tasks.toggle(),
|
||||||
|
|
||||||
// Help
|
// Help
|
||||||
"help" => cx.help.toggle(cx.layer()),
|
"help" => self.cx.help.toggle(KeymapLayer::Manager),
|
||||||
|
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tasks(cx: &mut Ctx, exec: &Exec) -> bool {
|
fn tasks(&mut self, exec: &Exec) -> bool {
|
||||||
match exec.cmd.as_str() {
|
match exec.cmd.as_str() {
|
||||||
"close" => cx.tasks.toggle(),
|
"close" => self.cx.tasks.toggle(),
|
||||||
|
|
||||||
"arrow" => {
|
"arrow" => {
|
||||||
let step = exec.args.get(0).and_then(|s| s.parse().ok()).unwrap_or(0);
|
let step = exec.args.first().and_then(|s| s.parse().ok()).unwrap_or(0);
|
||||||
if step > 0 { cx.tasks.next() } else { cx.tasks.prev() }
|
if step > 0 { self.cx.tasks.next() } else { self.cx.tasks.prev() }
|
||||||
}
|
}
|
||||||
|
|
||||||
"inspect" => cx.tasks.inspect(),
|
"inspect" => self.cx.tasks.inspect(),
|
||||||
"cancel" => cx.tasks.cancel(),
|
"cancel" => self.cx.tasks.cancel(),
|
||||||
|
|
||||||
"help" => cx.help.toggle(cx.layer()),
|
"help" => self.cx.help.toggle(KeymapLayer::Tasks),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn select(cx: &mut Ctx, exec: &Exec) -> bool {
|
fn select(&mut self, exec: &Exec) -> bool {
|
||||||
match exec.cmd.as_str() {
|
match exec.cmd.as_str() {
|
||||||
"close" => cx.select.close(exec.named.contains_key("submit")),
|
"close" => self.cx.select.close(exec.named.contains_key("submit")),
|
||||||
|
|
||||||
"arrow" => {
|
"arrow" => {
|
||||||
let step: isize = exec.args.get(0).and_then(|s| s.parse().ok()).unwrap_or(0);
|
let step: isize = exec.args.first().and_then(|s| s.parse().ok()).unwrap_or(0);
|
||||||
if step > 0 { cx.select.next(step as usize) } else { cx.select.prev(step.unsigned_abs()) }
|
if step > 0 {
|
||||||
|
self.cx.select.next(step as usize)
|
||||||
|
} else {
|
||||||
|
self.cx.select.prev(step.unsigned_abs())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"help" => cx.help.toggle(cx.layer()),
|
"help" => self.cx.help.toggle(KeymapLayer::Select),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn input(cx: &mut Ctx, exec: &Exec) -> bool {
|
fn input(&mut self, exec: &Exec) -> bool {
|
||||||
match exec.cmd.as_str() {
|
match exec.cmd.as_str() {
|
||||||
"close" => return cx.input.close(exec.named.contains_key("submit")),
|
"close" => return self.cx.input.close(exec.named.contains_key("submit")),
|
||||||
"escape" => return cx.input.escape(),
|
"escape" => return self.cx.input.escape(),
|
||||||
|
|
||||||
"move" => {
|
"move" => {
|
||||||
let step = exec.args.get(0).and_then(|s| s.parse().ok()).unwrap_or(0);
|
let step = exec.args.first().and_then(|s| s.parse().ok()).unwrap_or(0);
|
||||||
let in_operating = exec.named.contains_key("in-operating");
|
let in_operating = exec.named.contains_key("in-operating");
|
||||||
return if in_operating { cx.input.move_in_operating(step) } else { cx.input.move_(step) };
|
return if in_operating {
|
||||||
|
self.cx.input.move_in_operating(step)
|
||||||
|
} else {
|
||||||
|
self.cx.input.move_(step)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
"complete" => return cx.completion.trigger(exec),
|
"complete" => return self.cx.completion.trigger(exec),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
match cx.input.mode() {
|
match self.cx.input.mode() {
|
||||||
InputMode::Normal => match exec.cmd.as_str() {
|
InputMode::Normal => match exec.cmd.as_str() {
|
||||||
"insert" => cx.input.insert(exec.named.contains_key("append")),
|
"insert" => self.cx.input.insert(exec.named.contains_key("append")),
|
||||||
"visual" => cx.input.visual(),
|
"visual" => self.cx.input.visual(),
|
||||||
|
|
||||||
"backward" => cx.input.backward(),
|
"backward" => self.cx.input.backward(),
|
||||||
"forward" => cx.input.forward(exec.named.contains_key("end-of-word")),
|
"forward" => self.cx.input.forward(exec.named.contains_key("end-of-word")),
|
||||||
"delete" => {
|
"delete" => {
|
||||||
cx.input.delete(exec.named.contains_key("cut"), exec.named.contains_key("insert"))
|
self.cx.input.delete(exec.named.contains_key("cut"), exec.named.contains_key("insert"))
|
||||||
}
|
}
|
||||||
|
|
||||||
"yank" => cx.input.yank(),
|
"yank" => self.cx.input.yank(),
|
||||||
"paste" => cx.input.paste(exec.named.contains_key("before")),
|
"paste" => self.cx.input.paste(exec.named.contains_key("before")),
|
||||||
|
|
||||||
"undo" => cx.input.undo(),
|
"undo" => self.cx.input.undo(),
|
||||||
"redo" => cx.input.redo(),
|
"redo" => self.cx.input.redo(),
|
||||||
|
|
||||||
"help" => cx.help.toggle(cx.layer()),
|
"help" => self.cx.help.toggle(KeymapLayer::Input),
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
InputMode::Insert => false,
|
InputMode::Insert => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn help(cx: &mut Ctx, exec: &Exec) -> bool {
|
fn help(&mut self, exec: &Exec) -> bool {
|
||||||
match exec.cmd.as_str() {
|
match exec.cmd.as_str() {
|
||||||
"close" => cx.help.toggle(cx.layer()),
|
"close" => self.cx.help.toggle(KeymapLayer::Help),
|
||||||
"escape" => cx.help.escape(),
|
"escape" => self.cx.help.escape(),
|
||||||
|
|
||||||
"arrow" => {
|
"arrow" => {
|
||||||
let step = exec.args.get(0).and_then(|s| s.parse().ok()).unwrap_or(0);
|
let step = exec.args.first().and_then(|s| s.parse().ok()).unwrap_or(0);
|
||||||
cx.help.arrow(step)
|
self.cx.help.arrow(step)
|
||||||
}
|
}
|
||||||
|
|
||||||
"filter" => cx.help.filter(),
|
"filter" => self.cx.help.filter(),
|
||||||
|
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn completion(cx: &mut Ctx, exec: &Exec) -> bool {
|
fn completion(&mut self, exec: &Exec) -> bool {
|
||||||
match exec.cmd.as_str() {
|
match exec.cmd.as_str() {
|
||||||
"trigger" => cx.completion.trigger(exec),
|
"trigger" => self.cx.completion.trigger(exec),
|
||||||
"show" => cx.completion.show(exec),
|
"show" => self.cx.completion.show(exec),
|
||||||
"close" => cx.completion.close(exec.named.contains_key("submit")),
|
"close" => self.cx.completion.close(exec.named.contains_key("submit")),
|
||||||
|
|
||||||
"arrow" => {
|
"arrow" => {
|
||||||
let step: isize = exec.args.first().and_then(|s| s.parse().ok()).unwrap_or(0);
|
let step: isize = exec.args.first().and_then(|s| s.parse().ok()).unwrap_or(0);
|
||||||
if step > 0 {
|
if step > 0 {
|
||||||
cx.completion.next(step as usize)
|
self.cx.completion.next(step as usize)
|
||||||
} else {
|
} else {
|
||||||
cx.completion.prev(step.unsigned_abs())
|
self.cx.completion.prev(step.unsigned_abs())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"help" => cx.help.toggle(cx.layer()),
|
"help" => self.cx.help.toggle(KeymapLayer::Completion),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue