Move Keymaps from EditorView to Context structs

We'll need this value when attempting to execute keymaps for other
Components. Previously it was only scoped to the EditorView.
md-compositor-key-remapping-idea
Michael Davis 1 year ago
parent 6c6923c39e
commit d6fc6a54b2
No known key found for this signature in database

@ -63,6 +63,7 @@ type Terminal = tui::terminal::Terminal<TerminalBackend>;
pub struct Application { pub struct Application {
compositor: Compositor, compositor: Compositor,
keymaps: Keymaps,
terminal: Terminal, terminal: Terminal,
pub editor: Editor, pub editor: Editor,
@ -156,7 +157,8 @@ impl Application {
let keys = Box::new(Map::new(Arc::clone(&config), |config: &Config| { let keys = Box::new(Map::new(Arc::clone(&config), |config: &Config| {
&config.keys &config.keys
})); }));
let editor_view = Box::new(ui::EditorView::new(Keymaps::new(keys))); let keymaps = Keymaps::new(keys);
let editor_view = Box::new(ui::EditorView::default());
compositor.push(editor_view); compositor.push(editor_view);
if args.load_tutor { if args.load_tutor {
@ -241,6 +243,7 @@ impl Application {
.context("build signal handler")?; .context("build signal handler")?;
let app = Self { let app = Self {
keymaps,
compositor, compositor,
terminal, terminal,
editor, editor,
@ -261,6 +264,7 @@ impl Application {
async fn render(&mut self) { async fn render(&mut self) {
let mut cx = crate::compositor::Context { let mut cx = crate::compositor::Context {
keymaps: &mut self.keymaps,
editor: &mut self.editor, editor: &mut self.editor,
jobs: &mut self.jobs, jobs: &mut self.jobs,
scroll: None, scroll: None,
@ -521,6 +525,7 @@ impl Application {
pub async fn handle_idle_timeout(&mut self) { pub async fn handle_idle_timeout(&mut self) {
let mut cx = crate::compositor::Context { let mut cx = crate::compositor::Context {
keymaps: &mut self.keymaps,
editor: &mut self.editor, editor: &mut self.editor,
jobs: &mut self.jobs, jobs: &mut self.jobs,
scroll: None, scroll: None,
@ -641,6 +646,7 @@ impl Application {
event: Result<CrosstermEvent, crossterm::ErrorKind>, event: Result<CrosstermEvent, crossterm::ErrorKind>,
) { ) {
let mut cx = crate::compositor::Context { let mut cx = crate::compositor::Context {
keymaps: &mut self.keymaps,
editor: &mut self.editor, editor: &mut self.editor,
jobs: &mut self.jobs, jobs: &mut self.jobs,
scroll: None, scroll: None,

@ -53,7 +53,7 @@ use crate::{
compositor::{self, Component, Compositor}, compositor::{self, Component, Compositor},
filter_picker_entry, filter_picker_entry,
job::Callback, job::Callback,
keymap::ReverseKeymap, keymap::{Keymaps, ReverseKeymap},
ui::{ ui::{
self, editor::InsertEvent, lsp::SignatureHelp, overlay::overlaid, CompletionItem, Picker, self, editor::InsertEvent, lsp::SignatureHelp, overlay::overlaid, CompletionItem, Picker,
Popup, Prompt, PromptEvent, Popup, Prompt, PromptEvent,
@ -81,6 +81,8 @@ use tokio_stream::wrappers::UnboundedReceiverStream;
pub type OnKeyCallback = Box<dyn FnOnce(&mut Context, KeyEvent)>; pub type OnKeyCallback = Box<dyn FnOnce(&mut Context, KeyEvent)>;
pub struct Context<'a> { pub struct Context<'a> {
pub keymaps: &'a mut Keymaps,
pub register: Option<char>, pub register: Option<char>,
pub count: Option<NonZeroUsize>, pub count: Option<NonZeroUsize>,
pub editor: &'a mut Editor, pub editor: &'a mut Editor,
@ -196,6 +198,7 @@ impl MappableCommand {
let args: Vec<Cow<str>> = args.iter().map(Cow::from).collect(); let args: Vec<Cow<str>> = args.iter().map(Cow::from).collect();
if let Some(command) = typed::TYPABLE_COMMAND_MAP.get(name.as_str()) { if let Some(command) = typed::TYPABLE_COMMAND_MAP.get(name.as_str()) {
let mut cx = compositor::Context { let mut cx = compositor::Context {
keymaps: cx.keymaps,
editor: cx.editor, editor: cx.editor,
jobs: cx.jobs, jobs: cx.jobs,
scroll: None, scroll: None,
@ -2716,9 +2719,8 @@ pub fn command_palette(cx: &mut Context) {
cx.callback = Some(Box::new( cx.callback = Some(Box::new(
move |compositor: &mut Compositor, cx: &mut compositor::Context| { move |compositor: &mut Compositor, cx: &mut compositor::Context| {
let keymap = compositor.find::<ui::EditorView>().unwrap().keymaps.map() let keymap =
[&cx.editor.mode] cx.keymaps.map()[&crate::keymap::Domain::Mode(cx.editor.mode)].reverse_map();
.reverse_map();
let mut commands: Vec<MappableCommand> = MappableCommand::STATIC_COMMAND_LIST.into(); let mut commands: Vec<MappableCommand> = MappableCommand::STATIC_COMMAND_LIST.into();
commands.extend(typed::TYPABLE_COMMAND_LIST.iter().map(|cmd| { commands.extend(typed::TYPABLE_COMMAND_LIST.iter().map(|cmd| {
@ -2733,6 +2735,7 @@ pub fn command_palette(cx: &mut Context) {
let mut ctx = Context { let mut ctx = Context {
register, register,
count, count,
keymaps: cx.keymaps,
editor: cx.editor, editor: cx.editor,
callback: None, callback: None,
on_next_key_callback: None, on_next_key_callback: None,

@ -15,12 +15,13 @@ pub enum EventResult {
Consumed(Option<Callback>), Consumed(Option<Callback>),
} }
use crate::job::Jobs; use crate::{job::Jobs, keymap::Keymaps};
use helix_view::Editor; use helix_view::Editor;
pub use helix_view::input::Event; pub use helix_view::input::Event;
pub struct Context<'a> { pub struct Context<'a> {
pub keymaps: &'a mut Keymaps,
pub editor: &'a mut Editor, pub editor: &'a mut Editor,
pub scroll: Option<usize>, pub scroll: Option<usize>,
pub jobs: &'a mut Jobs, pub jobs: &'a mut Jobs,

@ -3,7 +3,7 @@ use crate::{
compositor::{Component, Context, Event, EventResult}, compositor::{Component, Context, Event, EventResult},
job::{self, Callback}, job::{self, Callback},
key, key,
keymap::{KeymapResult, Keymaps}, keymap::KeymapResult,
ui::{ ui::{
document::{render_document, LinePos, TextRenderer, TranslatedPosition}, document::{render_document, LinePos, TextRenderer, TranslatedPosition},
Completion, ProgressSpinners, Completion, ProgressSpinners,
@ -37,7 +37,6 @@ use super::{completion::CompletionItem, statusline};
use super::{document::LineDecoration, lsp::SignatureHelp}; use super::{document::LineDecoration, lsp::SignatureHelp};
pub struct EditorView { pub struct EditorView {
pub keymaps: Keymaps,
on_next_key: Option<OnKeyCallback>, on_next_key: Option<OnKeyCallback>,
pseudo_pending: Vec<KeyEvent>, pseudo_pending: Vec<KeyEvent>,
pub(crate) last_insert: (commands::MappableCommand, Vec<InsertEvent>), pub(crate) last_insert: (commands::MappableCommand, Vec<InsertEvent>),
@ -58,14 +57,7 @@ pub enum InsertEvent {
impl Default for EditorView { impl Default for EditorView {
fn default() -> Self { fn default() -> Self {
Self::new(Keymaps::default())
}
}
impl EditorView {
pub fn new(keymaps: Keymaps) -> Self {
Self { Self {
keymaps,
on_next_key: None, on_next_key: None,
pseudo_pending: Vec::new(), pseudo_pending: Vec::new(),
last_insert: (commands::MappableCommand::normal_mode, Vec::new()), last_insert: (commands::MappableCommand::normal_mode, Vec::new()),
@ -73,7 +65,9 @@ impl EditorView {
spinners: ProgressSpinners::default(), spinners: ProgressSpinners::default(),
} }
} }
}
impl EditorView {
pub fn spinners_mut(&mut self) -> &mut ProgressSpinners { pub fn spinners_mut(&mut self) -> &mut ProgressSpinners {
&mut self.spinners &mut self.spinners
} }
@ -786,7 +780,7 @@ impl EditorView {
} }
} }
/// Handle events by looking them up in `self.keymaps`. Returns None /// Handle events by looking them up in `cxt.keymaps`. Returns None
/// if event was handled (a command was executed or a subkeymap was /// if event was handled (a command was executed or a subkeymap was
/// activated). Only KeymapResult::{NotFound, Cancelled} is returned /// activated). Only KeymapResult::{NotFound, Cancelled} is returned
/// otherwise. /// otherwise.
@ -797,9 +791,9 @@ impl EditorView {
event: KeyEvent, event: KeyEvent,
) -> Option<KeymapResult> { ) -> Option<KeymapResult> {
let mut last_mode = mode; let mut last_mode = mode;
self.pseudo_pending.extend(self.keymaps.pending()); self.pseudo_pending.extend(cxt.keymaps.pending());
let key_result = self.keymaps.get(mode, event); let key_result = cxt.keymaps.get(mode, event);
cxt.editor.autoinfo = self.keymaps.sticky().map(|node| node.infobox()); cxt.editor.autoinfo = cxt.keymaps.sticky().map(|node| node.infobox());
let mut execute_command = |command: &commands::MappableCommand| { let mut execute_command = |command: &commands::MappableCommand| {
command.execute(cxt); command.execute(cxt);
@ -864,7 +858,7 @@ impl EditorView {
Some(ch) => commands::insert::insert_char(cx, ch), Some(ch) => commands::insert::insert_char(cx, ch),
None => { None => {
if let KeymapResult::Matched(command) = if let KeymapResult::Matched(command) =
self.keymaps.get(Mode::Insert, ev) cx.keymaps.get_by_mode(Mode::Insert, ev)
{ {
command.execute(cx); command.execute(cx);
} }
@ -886,7 +880,7 @@ impl EditorView {
std::num::NonZeroUsize::new(cxt.editor.count.map_or(i, |c| c.get() * 10 + i)); std::num::NonZeroUsize::new(cxt.editor.count.map_or(i, |c| c.get() * 10 + i));
} }
// special handling for repeat operator // special handling for repeat operator
(key!('.'), _) if self.keymaps.pending().is_empty() => { (key!('.'), _) if cxt.keymaps.pending().is_empty() => {
for _ in 0..cxt.editor.count.map_or(1, NonZeroUsize::into) { for _ in 0..cxt.editor.count.map_or(1, NonZeroUsize::into) {
// first execute whatever put us into insert mode // first execute whatever put us into insert mode
self.last_insert.0.execute(cxt); self.last_insert.0.execute(cxt);
@ -944,7 +938,7 @@ impl EditorView {
cxt.register = cxt.editor.selected_register.take(); cxt.register = cxt.editor.selected_register.take();
self.handle_keymap_event(mode, cxt, event); self.handle_keymap_event(mode, cxt, event);
if self.keymaps.pending().is_empty() { if cxt.keymaps.pending().is_empty() {
cxt.editor.count = None cxt.editor.count = None
} else { } else {
cxt.editor.selected_register = cxt.register.take(); cxt.editor.selected_register = cxt.register.take();
@ -1225,6 +1219,7 @@ impl Component for EditorView {
context: &mut crate::compositor::Context, context: &mut crate::compositor::Context,
) -> EventResult { ) -> EventResult {
let mut cx = commands::Context { let mut cx = commands::Context {
keymaps: context.keymaps,
editor: context.editor, editor: context.editor,
count: None, count: None,
register: None, register: None,
@ -1280,6 +1275,7 @@ impl Component for EditorView {
let res = { let res = {
// use a fake context here // use a fake context here
let mut cx = Context { let mut cx = Context {
keymaps: cx.keymaps,
editor: cx.editor, editor: cx.editor,
jobs: cx.jobs, jobs: cx.jobs,
scroll: None, scroll: None,
@ -1445,7 +1441,7 @@ impl Component for EditorView {
if let Some(count) = cx.editor.count { if let Some(count) = cx.editor.count {
disp.push_str(&count.to_string()) disp.push_str(&count.to_string())
} }
for key in self.keymaps.pending() { for key in cx.keymaps.pending() {
disp.push_str(&key.key_sequence_format()); disp.push_str(&key.key_sequence_format());
} }
for key in &self.pseudo_pending { for key in &self.pseudo_pending {

Loading…
Cancel
Save