Help command WIP

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

@ -2229,6 +2229,45 @@ mod cmd {
Ok(()) Ok(())
} }
fn help(
cx: &mut compositor::Context,
args: &[&str],
_event: PromptEvent,
) -> anyhow::Result<()> {
if args.is_empty() {
// TODO: Open a list of commands?
todo!()
}
let command = {
if Command::COMMAND_LIST
.iter()
.any(|command| command.name() == args[0])
{
args[0]
} else {
let _keys = args
.iter()
.map(|key| key.parse::<KeyEvent>())
.collect::<Result<Vec<KeyEvent>, _>>()?;
// TODO: Need to access the keymap here to find the corresponding command
todo!()
}
};
let mut path = helix_core::runtime_dir();
path.push("help");
path.push(format!("{}.txt", command));
if !path.is_file() {
return Err(anyhow!("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] = &[
TypableCommand { TypableCommand {
name: "quit", name: "quit",
@ -2489,6 +2528,13 @@ mod cmd {
fun: tutor, fun: tutor,
completer: None, completer: None,
}, },
TypableCommand {
name: "help",
aliases: &["h"],
doc: "Open documentation for a command or keybind.",
fun: help,
completer: Some(completers::help),
},
]; ];
pub static COMMANDS: Lazy<HashMap<&'static str, &'static TypableCommand>> = Lazy::new(|| { pub static COMMANDS: Lazy<HashMap<&'static str, &'static TypableCommand>> = Lazy::new(|| {

@ -220,6 +220,36 @@ pub mod completers {
}) })
} }
pub fn help(input: &str) -> Vec<Completion> {
let path = helix_core::runtime_dir().join("help");
let commands: Vec<String> = std::fs::read_dir(path)
.map(|entries| {
entries
.filter_map(|entry| {
let entry = entry.ok()?;
let path = entry.path();
(path.extension()? == "txt")
.then(|| path.file_stem().unwrap().to_string_lossy().into_owned())
})
.collect()
})
.unwrap_or_default();
let matcher = Matcher::default();
let mut matches: Vec<_> = commands
.into_iter()
.map(|name| ((0..), Cow::from(name)))
.filter_map(|(_range, name)| {
matcher.fuzzy_match(&name, input).map(|score| (name, score))
})
.collect();
matches.sort_unstable_by_key(|(_file, score)| Reverse(*score));
matches.into_iter().map(|(name, _)| ((0..), name)).collect()
}
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq)]
enum FileMatch { enum FileMatch {
/// Entry should be ignored /// Entry should be ignored

@ -0,0 +1,18 @@
`copy_selection_on_next_line`
Copies the current primary selection to the next line long enough to accomodate it.
--- Examples ---
The selection is copied from line 1 to line 2.
┌───────────────────────────┐ ┌───────────────────────────┐
│ This is text [on line 1]. │ --> │ This is text [on line 1]. │
│ This is text on line 2. │ │ This is text [on line 2]. │
└───────────────────────────┘ └───────────────────────────┘
The selection duplication skips line 2 because it is too short.
┌──────────────────────────────────┐ ┌──────────────────────────────────┐
│ This is a longer li[ne of t]ext. │ │ This is a longer li[ne of t]ext. │
│ This is a shorter line. │ --> │ This is a shorter line. │
│ This is another longer line. │ │ This is another lon[ger lin]e. │
└──────────────────────────────────┘ └──────────────────────────────────┘
Loading…
Cancel
Save