Implement `:help <keybind>` for non-branching key sequences

pull/997/head
Omnikar 3 years ago
parent cc4c78608b
commit d18d745392
No known key found for this signature in database
GPG Key ID: 7DE6694CDA7885ED

@ -2797,9 +2797,24 @@ pub mod cmd {
return Ok(()); return Ok(());
} }
let help_dir; let args_msg = args.join(" ");
let open_help =
move |help_dir: &str, command: &str, editor: &mut Editor| -> anyhow::Result<()> {
let mut path = helix_core::runtime_dir();
path.push("help");
path.push(help_dir);
path.push(format!("{}.txt", command));
ensure!(path.is_file(), "No help available for '{}'", args_msg);
let id = editor.open(path, Action::HorizontalSplit)?;
editor.document_mut(id).unwrap().set_path(None)?;
Ok(())
};
const STATIC_HELP_DIR: &str = "static-commands";
const TYPABLE_HELP_DIR: &str = "typable-commands";
let command = { let (help_dir, command): (&str, &str) = {
let arg = &args[0]; let arg = &args[0];
if let Some(command) = arg.strip_prefix(':').and_then(|arg| { if let Some(command) = arg.strip_prefix(':').and_then(|arg| {
TYPABLE_COMMAND_LIST.iter().find_map(|command| { TYPABLE_COMMAND_LIST.iter().find_map(|command| {
@ -2807,31 +2822,50 @@ pub mod cmd {
.then(|| command.name) .then(|| command.name)
}) })
}) { }) {
help_dir = "typable-commands"; (TYPABLE_HELP_DIR, command)
command
} else if MappableCommand::STATIC_COMMAND_LIST } else if MappableCommand::STATIC_COMMAND_LIST
.iter() .iter()
.any(|command| command.name() == arg) .any(|command| command.name() == arg)
{ {
help_dir = "static-commands"; (STATIC_HELP_DIR, arg)
arg
} else { } else {
let _keys = helix_view::input::parse_macro(arg)?; let keys = arg
// TODO: Need to access the keymap here to find the corresponding command .parse::<KeyEvent>()
todo!() .map(|key| vec![key])
.or_else(|_| helix_view::input::parse_macro(arg))?;
let callback = Box::pin(async move {
let call: job::Callback =
Box::new(move |editor: &mut Editor, compositor: &mut Compositor| {
use crate::keymap::KeymapResultKind;
let editor_view = compositor.find::<ui::EditorView>().unwrap();
let mode = doc!(editor).mode;
let keymap = editor_view.keymaps.get_mut(&mode).unwrap();
let (keys, last_key) = (&keys[..keys.len() - 1], keys.last().unwrap());
keys.into_iter().for_each(|key| {
keymap.get(*key);
});
let result = keymap.get(*last_key);
let (help_dir, command): (&str, &str) = match &result.kind {
KeymapResultKind::Matched(command) => match command {
MappableCommand::Static { name, .. } => (STATIC_HELP_DIR, name),
MappableCommand::Typable { name, .. } => {
(TYPABLE_HELP_DIR, name)
}
},
_ => todo!(),
};
if let Err(e) = open_help(help_dir, command, editor) {
editor.set_error(e.to_string());
}
});
Ok(call)
});
cx.jobs.callback(callback);
return Ok(());
} }
}; };
let mut path = helix_core::runtime_dir(); open_help(help_dir, command, &mut cx.editor)
path.push("help");
path.push(help_dir);
path.push(format!("{}.txt", command));
ensure!(path.is_file(), "No help available for '{}'", args.join(" "));
let id = cx.editor.open(path, Action::HorizontalSplit)?;
cx.editor.document_mut(id).unwrap().set_path(None)?;
Ok(())
} }
pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[

@ -29,7 +29,7 @@ use crossterm::event::{Event, MouseButton, MouseEvent, MouseEventKind};
use tui::buffer::Buffer as Surface; use tui::buffer::Buffer as Surface;
pub struct EditorView { pub struct EditorView {
keymaps: Keymaps, pub keymaps: Keymaps,
on_next_key: Option<Box<dyn FnOnce(&mut commands::Context, KeyEvent)>>, on_next_key: Option<Box<dyn FnOnce(&mut commands::Context, KeyEvent)>>,
last_insert: (commands::MappableCommand, Vec<KeyEvent>), last_insert: (commands::MappableCommand, Vec<KeyEvent>),
pub(crate) completion: Option<Completion>, pub(crate) completion: Option<Completion>,

Loading…
Cancel
Save