diff --git a/book/src/generated/typable-cmd.md b/book/src/generated/typable-cmd.md index 66e6ac039..26ce6c050 100644 --- a/book/src/generated/typable-cmd.md +++ b/book/src/generated/typable-cmd.md @@ -73,3 +73,4 @@ | `:pipe` | Pipe each selection to the shell command. | | `:pipe-to` | Pipe each selection to the shell command, ignoring output. | | `:run-shell-command`, `:sh` | Run a shell command | +| `:help`, `:h` | Open documentation for a command or keybind. | diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 2119a48d6..242eee70f 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -1808,6 +1808,155 @@ fn run_shell_command( Ok(()) } +fn help(cx: &mut compositor::Context, args: &[Cow], event: PromptEvent) -> anyhow::Result<()> { + if event != PromptEvent::Validate { + return Ok(()); + } + + if args.is_empty() { + // TODO: Open a list of commands? + todo!() + } + + if args[0] == "topics" { + let dir_path = helix_loader::runtime_dir().join("help/topics"); + + struct Topic(PathBuf); + impl crate::ui::menu::Item for Topic { + type Data = (); + fn label(&self, _data: &Self::Data) -> Spans { + self.0 + .file_stem() + .and_then(|s| s.to_str()) + .map(From::from) + .unwrap_or_default() + } + } + + let entries: Vec = std::fs::read_dir(&dir_path) + .map(|entries| { + entries + .filter_map(|entry| { + let entry = entry.ok()?; + let path = entry.path(); + Some(path) + }) + .map(Topic) + .collect() + }) + .unwrap_or_default(); + + cx.jobs.callback(async move { + let callback = job::Callback::EditorCompositor(Box::new( + move |_editor: &mut Editor, compositor: &mut Compositor| { + let picker = FilePicker::new( + entries, + (), + |cx, Topic(path), _action| { + if let Err(e) = + cx.editor + .open(path, Action::HorizontalSplit) + .and_then(|id| { + cx.editor + .document_mut(id) + .unwrap() + .set_path(None) + .map_err(Into::into) + }) + { + cx.editor.set_error(e.to_string()); + } + }, + |_editor, Topic(path)| Some((path.clone().into(), None)), + ); + compositor.push(Box::new(picker)); + }, + )); + + Ok(callback) + }); + + return Ok(()); + } + + let args_msg = args.join(" "); + let open_help = + move |help_dir: &str, command: &str, editor: &mut Editor| -> anyhow::Result<()> { + let mut path = helix_loader::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 (help_dir, command): (&str, &str) = { + let arg = &args[0]; + if let Some(command) = arg.strip_prefix(':').and_then(|arg| { + TYPABLE_COMMAND_LIST.iter().find_map(|command| { + (command.name == arg || command.aliases.iter().any(|alias| *alias == arg)) + .then(|| command.name) + }) + }) { + (TYPABLE_HELP_DIR, command) + } else if MappableCommand::STATIC_COMMAND_LIST + .iter() + .any(|command| command.name() == arg) + { + (STATIC_HELP_DIR, arg) + } else { + let arg = arg.to_owned().into_owned(); + let keys = arg + .parse::() + .map(|key| vec![key]) + .or_else(|_| helix_view::input::parse_macro(&arg))?; + + cx.jobs.callback(async move { + let callback = job::Callback::EditorCompositor(Box::new( + move |editor: &mut Editor, compositor: &mut Compositor| { + use crate::keymap::KeymapResult; + let editor_view = compositor.find::().unwrap(); + let mode = editor.mode; + let keymaps = &mut editor_view.keymaps; + let (keys, last_key) = (&keys[..keys.len() - 1], keys.last().unwrap()); + keys.iter().for_each(|key| { + keymaps.get(mode, *key); + }); + let result = keymaps.get(mode, *last_key); + let res: anyhow::Result<(&str, &str)> = match &result { + KeymapResult::Matched(command) => match command { + MappableCommand::Static { name, .. } => Ok((STATIC_HELP_DIR, name)), + MappableCommand::Typable { name, .. } => { + Ok((TYPABLE_HELP_DIR, name)) + } + }, + KeymapResult::NotFound | KeymapResult::Cancelled(_) => { + Err(anyhow!("No command found for '{}'", arg)) + } + _ => todo!(), + }; + if let Err(e) = + res.and_then(|(help_dir, command)| open_help(help_dir, command, editor)) + { + editor.set_error(e.to_string()); + } + }, + )); + Ok(callback) + }); + return Ok(()); + } + }; + + open_help(help_dir, command, cx.editor) +} + pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ TypableCommand { name: "quit", @@ -2323,6 +2472,13 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ fun: run_shell_command, completer: Some(completers::directory), }, + TypableCommand { + name: "help", + aliases: &["h"], + doc: "Open documentation for a command or keybind.", + fun: help, + completer: Some(completers::help), + }, ]; pub static TYPABLE_COMMAND_MAP: Lazy> = diff --git a/helix-term/src/ui/mod.rs b/helix-term/src/ui/mod.rs index 107e48dd1..a68f423ad 100644 --- a/helix-term/src/ui/mod.rs +++ b/helix-term/src/ui/mod.rs @@ -441,6 +441,50 @@ pub mod completers { }) } + pub fn help(_editor: &Editor, input: &str) -> Vec { + let static_cmds_path = helix_loader::runtime_dir().join("help/static-commands"); + let typable_cmds_path = helix_loader::runtime_dir().join("help/typable-commands"); + let mut items: Vec = std::fs::read_dir(static_cmds_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()) + }) + .chain( + std::fs::read_dir(typable_cmds_path) + .map(|entries| { + entries.filter_map(|entry| { + let entry = entry.ok()?; + let path = entry.path(); + (path.extension()? == "txt").then(|| { + format!(":{}", path.file_stem().unwrap().to_string_lossy()) + }) + }) + }) + .into_iter() + .flatten(), + ) + .collect() + }) + .unwrap_or_default(); + items.push("topics".to_owned()); + + let matcher = Matcher::default(); + + let mut matches: Vec<_> = items + .into_iter() + .map(Cow::from) + .filter_map(|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)] enum FileMatch { /// Entry should be ignored diff --git a/runtime/help/static-commands/append_mode.txt b/runtime/help/static-commands/append_mode.txt new file mode 100644 index 000000000..a50dff179 --- /dev/null +++ b/runtime/help/static-commands/append_mode.txt @@ -0,0 +1,5 @@ +`append_mode` + +Enters Insert mode at the end of the selection. + +For information about Insert mode, see "Primary Modes". diff --git a/runtime/help/static-commands/append_to_line.txt b/runtime/help/static-commands/append_to_line.txt new file mode 100644 index 000000000..0550be6f5 --- /dev/null +++ b/runtime/help/static-commands/append_to_line.txt @@ -0,0 +1,5 @@ +`append_to_line` + +Enters Insert mode at the end of the line. + +For information about Insert mode, see "Primary Modes". diff --git a/runtime/help/static-commands/copy_selection_on_next_line.txt b/runtime/help/static-commands/copy_selection_on_next_line.txt new file mode 100644 index 000000000..0187444db --- /dev/null +++ b/runtime/help/static-commands/copy_selection_on_next_line.txt @@ -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. │ +└──────────────────────────────────┘ └──────────────────────────────────┘ diff --git a/runtime/help/static-commands/copy_selection_on_prev_line.txt b/runtime/help/static-commands/copy_selection_on_prev_line.txt new file mode 100644 index 000000000..756c2b364 --- /dev/null +++ b/runtime/help/static-commands/copy_selection_on_prev_line.txt @@ -0,0 +1,18 @@ +`copy_selection_on_prev_line` + +Copies the current primary selection to the first previous line long enough to accomodate it. + +--- Examples --- + +The selection is copied from line 2 to line 1. +┌───────────────────────────┐ ┌───────────────────────────┐ +│ 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 line of text. │ │ This is a longer li(ne of t]ext. │ +│ This is a shorter line. │ --> │ This is a shorter line. │ +│ This is another lon(ger lin]e. │ │ This is another lon(ger lin]e. │ +└──────────────────────────────────┘ └──────────────────────────────────┘ diff --git a/runtime/help/static-commands/extend_char_left.txt b/runtime/help/static-commands/extend_char_left.txt new file mode 100644 index 000000000..2e87ef608 --- /dev/null +++ b/runtime/help/static-commands/extend_char_left.txt @@ -0,0 +1,3 @@ +`extend_char_left` + +Extending version of `move_char_left`. diff --git a/runtime/help/static-commands/extend_char_right.txt b/runtime/help/static-commands/extend_char_right.txt new file mode 100644 index 000000000..7568169f9 --- /dev/null +++ b/runtime/help/static-commands/extend_char_right.txt @@ -0,0 +1,3 @@ +`extend_char_right` + +Extending version of `move_char_right`. diff --git a/runtime/help/static-commands/extend_line_down.txt b/runtime/help/static-commands/extend_line_down.txt new file mode 100644 index 000000000..f37497c53 --- /dev/null +++ b/runtime/help/static-commands/extend_line_down.txt @@ -0,0 +1,3 @@ +`extend_line_down` + +Extending version of `move_line_down`. diff --git a/runtime/help/static-commands/extend_line_up.txt b/runtime/help/static-commands/extend_line_up.txt new file mode 100644 index 000000000..2adcbac6c --- /dev/null +++ b/runtime/help/static-commands/extend_line_up.txt @@ -0,0 +1,3 @@ +`extend_line_up` + +Extending version of `move_line_up`. diff --git a/runtime/help/static-commands/extend_next_char.txt b/runtime/help/static-commands/extend_next_char.txt new file mode 100644 index 000000000..3a850520e --- /dev/null +++ b/runtime/help/static-commands/extend_next_char.txt @@ -0,0 +1,3 @@ +`extend_next_char` + +Extending version of `find_next_char`. diff --git a/runtime/help/static-commands/extend_next_long_word_end.txt b/runtime/help/static-commands/extend_next_long_word_end.txt new file mode 100644 index 000000000..edc3acecd --- /dev/null +++ b/runtime/help/static-commands/extend_next_long_word_end.txt @@ -0,0 +1,3 @@ +`extend_next_long_word_end` + +Extending version of `move_next_long_word_end`. diff --git a/runtime/help/static-commands/extend_next_long_word_start.txt b/runtime/help/static-commands/extend_next_long_word_start.txt new file mode 100644 index 000000000..04f8e2480 --- /dev/null +++ b/runtime/help/static-commands/extend_next_long_word_start.txt @@ -0,0 +1,3 @@ +`extend_next_long_word_start` + +Extending version of `move_next_long_word_start`. diff --git a/runtime/help/static-commands/extend_next_word_end.txt b/runtime/help/static-commands/extend_next_word_end.txt new file mode 100644 index 000000000..aee4840ee --- /dev/null +++ b/runtime/help/static-commands/extend_next_word_end.txt @@ -0,0 +1,3 @@ +`extend_next_word_end` + +Extending version of `move_next_word_end`. diff --git a/runtime/help/static-commands/extend_next_word_start.txt b/runtime/help/static-commands/extend_next_word_start.txt new file mode 100644 index 000000000..4c6e3875b --- /dev/null +++ b/runtime/help/static-commands/extend_next_word_start.txt @@ -0,0 +1,3 @@ +`extend_next_word_start` + +Extending version of `move_next_word_start`. diff --git a/runtime/help/static-commands/extend_prev_char.txt b/runtime/help/static-commands/extend_prev_char.txt new file mode 100644 index 000000000..631f83356 --- /dev/null +++ b/runtime/help/static-commands/extend_prev_char.txt @@ -0,0 +1,3 @@ +`extend_prev_char` + +Extending version of `find_prev_char`. diff --git a/runtime/help/static-commands/extend_prev_long_word_start.txt b/runtime/help/static-commands/extend_prev_long_word_start.txt new file mode 100644 index 000000000..26aa259c5 --- /dev/null +++ b/runtime/help/static-commands/extend_prev_long_word_start.txt @@ -0,0 +1,3 @@ +`extend_prev_long_word_start` + +Extending version of `move_prev_long_word_start`. diff --git a/runtime/help/static-commands/extend_prev_word_start.txt b/runtime/help/static-commands/extend_prev_word_start.txt new file mode 100644 index 000000000..699343c84 --- /dev/null +++ b/runtime/help/static-commands/extend_prev_word_start.txt @@ -0,0 +1,3 @@ +`extend_prev_word_start` + +Extending version of `move_prev_word_start`. diff --git a/runtime/help/static-commands/extend_till_char.txt b/runtime/help/static-commands/extend_till_char.txt new file mode 100644 index 000000000..e614fe28c --- /dev/null +++ b/runtime/help/static-commands/extend_till_char.txt @@ -0,0 +1,3 @@ +`extend_till_char` + +Extending version of `find_till_char`. diff --git a/runtime/help/static-commands/extend_till_prev_char.txt b/runtime/help/static-commands/extend_till_prev_char.txt new file mode 100644 index 000000000..7f7047bb2 --- /dev/null +++ b/runtime/help/static-commands/extend_till_prev_char.txt @@ -0,0 +1,3 @@ +`extend_till_prev_char` + +Extending version of `till_prev_char`. diff --git a/runtime/help/static-commands/find_next_char.txt b/runtime/help/static-commands/find_next_char.txt new file mode 100644 index 000000000..086754ea0 --- /dev/null +++ b/runtime/help/static-commands/find_next_char.txt @@ -0,0 +1,22 @@ +`find_next_char` + +Waits for another keypress, then moves and +selects forward, stopping at the first +instance of the pressed key. Can take +a count, which will cause it to stop +at the nth instance of the keypress, +rather than the first. + +--- Examples --- + +The cursor moves forward, stopping at 'c' +and selecting everything along the way. +┌───────────────────────┐ c ┌───────────────────────┐ +│ This i[s] a sentence. │ --> │ This i(s a sentenc]e. │ +└───────────────────────┘ └───────────────────────┘ + +The cursor is not stopped by line breaks. +┌───────────────────────────┐ ┌────────────────────────────┐ +│ This is the fi[r]st line. │ Q │ This is the fi(rst line. │ +│ This second line has a Q. │ --> │ This second line has a Q]. │ +└───────────────────────────┘ └────────────────────────────┘ diff --git a/runtime/help/static-commands/find_prev_char.txt b/runtime/help/static-commands/find_prev_char.txt new file mode 100644 index 000000000..4d277a408 --- /dev/null +++ b/runtime/help/static-commands/find_prev_char.txt @@ -0,0 +1,22 @@ +`find_prev_char` + +Waits for another keypress, then moves and +selects backward, stopping at the first +instance of the pressed key. Can take +a count, which will cause it to stop +at the nth instance of the keypress, +rather than the first. + +--- Examples --- + +The cursor moves backward, stopping at 'h' +and selecting everything along the way. +┌───────────────────────┐ h ┌───────────────────────┐ +│ This is a sent[e]nce. │ --> │ T[his is a sente)nce. │ +└───────────────────────┘ └───────────────────────┘ + +The cursor is not stopped by line breaks. +┌──────────────────────────────────┐ ┌───────────────────────────────────┐ +│ There is a Q in this first line. │ Q │ There is a [Q in this first line. │ +│ This is the se[c]ond line. │ --> │ This is the sec)ond line. │ +└──────────────────────────────────┘ └───────────────────────────────────┘ diff --git a/runtime/help/static-commands/find_till_char.txt b/runtime/help/static-commands/find_till_char.txt new file mode 100644 index 000000000..dc00bb847 --- /dev/null +++ b/runtime/help/static-commands/find_till_char.txt @@ -0,0 +1,22 @@ +`find_till_char` + +Waits for another keypress, then moves and +selects forward, stopping before the first +instance of the pressed key. Can take +a count, which will cause it to stop +before the nth instance of the keypress, +rather than the first. + +--- Examples --- + +The cursor moves forward, stopping before 'c' +and selecting everything along the way. +┌───────────────────────┐ c ┌───────────────────────┐ +│ This i[s] a sentence. │ --> │ This i(s a senten]ce. │ +└───────────────────────┘ └───────────────────────┘ + +The cursor is not stopped by line breaks. +┌───────────────────────────┐ ┌────────────────────────────┐ +│ This is the fi[r]st line. │ Q │ This is the fi(rst line. │ +│ This second line has a Q. │ --> │ This second line has a ]Q. │ +└───────────────────────────┘ └────────────────────────────┘ diff --git a/runtime/help/static-commands/half_page_down.txt b/runtime/help/static-commands/half_page_down.txt new file mode 100644 index 000000000..2ddeac6b9 --- /dev/null +++ b/runtime/help/static-commands/half_page_down.txt @@ -0,0 +1,3 @@ +`half_page_down` + +Scrolls down by half of a screen. diff --git a/runtime/help/static-commands/half_page_up.txt b/runtime/help/static-commands/half_page_up.txt new file mode 100644 index 000000000..1fdaec921 --- /dev/null +++ b/runtime/help/static-commands/half_page_up.txt @@ -0,0 +1,3 @@ +`half_page_up` + +Scrolls up by half of a screen. diff --git a/runtime/help/static-commands/insert_mode.txt b/runtime/help/static-commands/insert_mode.txt new file mode 100644 index 000000000..dda2f14ae --- /dev/null +++ b/runtime/help/static-commands/insert_mode.txt @@ -0,0 +1,5 @@ +`insert_mode` + +Enters Insert mode at the start of the selection. + +For information about Insert mode, see "Primary Modes". diff --git a/runtime/help/static-commands/move_char_left.txt b/runtime/help/static-commands/move_char_left.txt new file mode 100644 index 000000000..97b1363a4 --- /dev/null +++ b/runtime/help/static-commands/move_char_left.txt @@ -0,0 +1,4 @@ +`move_char_left` + +Moves all cursors 1 character left, removing +any selections and wrapping across line breaks. diff --git a/runtime/help/static-commands/move_char_right.txt b/runtime/help/static-commands/move_char_right.txt new file mode 100644 index 000000000..dc085d72d --- /dev/null +++ b/runtime/help/static-commands/move_char_right.txt @@ -0,0 +1,4 @@ +`move_char_right` + +Moves all cursors 1 character right, removing +any selections and wrapping across line breaks. diff --git a/runtime/help/static-commands/move_line_down.txt b/runtime/help/static-commands/move_line_down.txt new file mode 100644 index 000000000..7cbe45c02 --- /dev/null +++ b/runtime/help/static-commands/move_line_down.txt @@ -0,0 +1,15 @@ +`move_line_down` + +Moves all cursors 1 line down, removing any selections. +Repeating this will remember the vertical position of the cursors, +even when moving across shorter lines. + +--- Examples --- + +The cursor remembers its vertical position, +even after moving across the shorter line. +┌────────────────────────────┐ ┌────────────────────────────┐ ┌──────────────────────────────┐ +│ This is a longer l[i]ne. │ │ This is a longer line. │ │ This is a longer line. │ +│ Shorter line. │ --> │ Shorter line.[] │ --> │ Shorter line. │ +│ This is another long line. │ │ This is another long line. │ │ This is another lo[n]g line. │ +└────────────────────────────┘ └────────────────────────────┘ └──────────────────────────────┘ diff --git a/runtime/help/static-commands/move_line_up.txt b/runtime/help/static-commands/move_line_up.txt new file mode 100644 index 000000000..5fdef6c16 --- /dev/null +++ b/runtime/help/static-commands/move_line_up.txt @@ -0,0 +1,15 @@ +`move_line_up` + +Moves all cursors 1 line up, removing any selections. +Repeating this will remember the vertical position of the cursors, +even when moving across shorter lines. + +--- Examples --- + +The cursor remembers its vertical position, +even after moving across the shorter line. +┌──────────────────────────────┐ ┌────────────────────────────┐ ┌────────────────────────────┐ +│ This is a longer line. │ │ This is a longer line. │ │ This is a longer l[i]ne. │ +│ Shorter line. │ --> │ Shorter line.[] │ --> │ Shorter line. │ +│ This is another lo[n]g line. │ │ This is another long line. │ │ This is another long line. │ +└──────────────────────────────┘ └────────────────────────────┘ └────────────────────────────┘ diff --git a/runtime/help/static-commands/move_next_long_word_end.txt b/runtime/help/static-commands/move_next_long_word_end.txt new file mode 100644 index 000000000..fd5a5933c --- /dev/null +++ b/runtime/help/static-commands/move_next_long_word_end.txt @@ -0,0 +1,17 @@ +`move_next_long_word_end` + +Moves and selects forward, stopping at +the last character of the current WORD. + +For the difference between words and WORDS, see "Words vs. WORDS". + +--- Examples --- + +The cursor moves forward, stopping at the end of 'These-are' +and selecting everything along the way. +┌────────────────────┐ ┌────────────────────┐ +│ [T]hese-are WORDS. │ --> │ (These-are] WORDS. │ +└────────────────────┘ └────────────────────┘ +┌────────────────────┐ ┌────────────────────┐ +│ Th[e]se-are WORDS. │ --> │ Th(ese-are] WORDS. │ +└────────────────────┘ └────────────────────┘ diff --git a/runtime/help/static-commands/move_next_long_word_start.txt b/runtime/help/static-commands/move_next_long_word_start.txt new file mode 100644 index 000000000..86f4a6cf4 --- /dev/null +++ b/runtime/help/static-commands/move_next_long_word_start.txt @@ -0,0 +1,17 @@ +`move_next_long_word_start` + +Moves and selects forward, stopping before +the first character of the next WORD. + +For the difference between words and WORDS, see "Words vs. WORDS". + +--- Examples --- + +The cursor moves forward, stopping before the start of 'WORDS' +and selecting everything along the way. +┌────────────────────┐ ┌────────────────────┐ +│ [T]hese-are WORDS. │ --> │ (These-are ]WORDS. │ +└────────────────────┘ └────────────────────┘ +┌────────────────────┐ ┌────────────────────┐ +│ Th[e]se-are WORDS. │ --> │ Th(ese-are ]WORDS. │ +└────────────────────┘ └────────────────────┘ diff --git a/runtime/help/static-commands/move_next_word_end.txt b/runtime/help/static-commands/move_next_word_end.txt new file mode 100644 index 000000000..0b859a8a7 --- /dev/null +++ b/runtime/help/static-commands/move_next_word_end.txt @@ -0,0 +1,15 @@ +`move_next_word_end` + +Moves and selects forward, stopping at +the last character of the current word. + +--- Examples --- + +The cursor moves forward, stopping at the end of 'These' +and selecting everything along the way. +┌────────────────────┐ ┌────────────────────┐ +│ [T]hese are words. │ --> │ (These] are words. │ +└────────────────────┘ └────────────────────┘ +┌────────────────────┐ ┌────────────────────┐ +│ Th[e]se are words. │ --> │ Th(ese] are words. │ +└────────────────────┘ └────────────────────┘ diff --git a/runtime/help/static-commands/move_next_word_start.txt b/runtime/help/static-commands/move_next_word_start.txt new file mode 100644 index 000000000..ca8b11170 --- /dev/null +++ b/runtime/help/static-commands/move_next_word_start.txt @@ -0,0 +1,15 @@ +`move_next_word_start` + +Moves and selects forward, stopping before +the first character of the next word. + +--- Examples --- + +The cursor moves forward, stopping before the start of 'are' +and selecting everything along the way. +┌────────────────────┐ ┌────────────────────┐ +│ [T]hese are words. │ --> │ (These ]are words. │ +└────────────────────┘ └────────────────────┘ +┌────────────────────┐ ┌────────────────────┐ +│ Th[e]se are words. │ --> │ Th(ese ]are words. │ +└────────────────────┘ └────────────────────┘ diff --git a/runtime/help/static-commands/move_prev_long_word_start.txt b/runtime/help/static-commands/move_prev_long_word_start.txt new file mode 100644 index 000000000..1b223c96e --- /dev/null +++ b/runtime/help/static-commands/move_prev_long_word_start.txt @@ -0,0 +1,20 @@ +`move_prev_long_word_start` + +Moves and selects backward, stopping at +the first character of the previous WORD. + +For the difference between words and WORDS, see "Words vs. WORDS". + +--- Examples --- + +The cursor moves backwards, stopping at the start of 'These-are' +and selecting everything along the way. +┌────────────────────┐ ┌────────────────────┐ +│ These-are[ ]WORDS. │ --> │ [These-are )WORDS. │ +└────────────────────┘ └────────────────────┘ +┌────────────────────┐ ┌────────────────────┐ +│ These-are [W]ORDS. │ --> │ [These-are )WORDS. │ +└────────────────────┘ └────────────────────┘ +┌────────────────────┐ ┌────────────────────┐ +│ These-a[r]e WORDS. │ --> │ [These-ar)e WORDS. │ +└────────────────────┘ └────────────────────┘ diff --git a/runtime/help/static-commands/move_prev_word_start.txt b/runtime/help/static-commands/move_prev_word_start.txt new file mode 100644 index 000000000..0e71450ab --- /dev/null +++ b/runtime/help/static-commands/move_prev_word_start.txt @@ -0,0 +1,18 @@ +`move_prev_word_start` + +Moves and selects backward, stopping at +the first character of the previous word. + +--- Examples --- + +The cursor moves backwards, stopping at the start of 'These' +and selecting everything along the way. +┌────────────────────┐ ┌────────────────────┐ +│ These[ ]are words. │ --> │ [These )are words. │ +└────────────────────┘ └────────────────────┘ +┌────────────────────┐ ┌────────────────────┐ +│ These [a]re words. │ --> │ [These )are words. │ +└────────────────────┘ └────────────────────┘ +┌────────────────────┐ ┌────────────────────┐ +│ Th[e]se are words. │ --> │ [The)se are words. │ +└────────────────────┘ └────────────────────┘ diff --git a/runtime/help/static-commands/no_op.txt b/runtime/help/static-commands/no_op.txt new file mode 100644 index 000000000..b8e9d20cf --- /dev/null +++ b/runtime/help/static-commands/no_op.txt @@ -0,0 +1,3 @@ +`no_op` + +Does nothing. Use this to disable default keybinds. diff --git a/runtime/help/static-commands/page_down.txt b/runtime/help/static-commands/page_down.txt new file mode 100644 index 000000000..0679b1d4f --- /dev/null +++ b/runtime/help/static-commands/page_down.txt @@ -0,0 +1,3 @@ +`page_down` + +Scrolls down by one screen. diff --git a/runtime/help/static-commands/page_up.txt b/runtime/help/static-commands/page_up.txt new file mode 100644 index 000000000..dab743afa --- /dev/null +++ b/runtime/help/static-commands/page_up.txt @@ -0,0 +1,3 @@ +`page_up` + +Scrolls up by one screen. diff --git a/runtime/help/static-commands/prepend_to_line.txt b/runtime/help/static-commands/prepend_to_line.txt new file mode 100644 index 000000000..628d83629 --- /dev/null +++ b/runtime/help/static-commands/prepend_to_line.txt @@ -0,0 +1,5 @@ +`prepend_to_line` + +Enters Insert mode before the first non-whitespace character in the line. + +For information about Insert mode, see "Primary Modes". diff --git a/runtime/help/static-commands/replace.txt b/runtime/help/static-commands/replace.txt new file mode 100644 index 000000000..ebe1a41fd --- /dev/null +++ b/runtime/help/static-commands/replace.txt @@ -0,0 +1,21 @@ +`replace` + +Waits for another keypress, then replaces all +selected characters with the pressed key. + +--- Examples --- + +'a' is replaced with 'e'. +┌──────────────────────────┐ e ┌──────────────────────────┐ +│ Do this, th[a]n do that. │ --> │ Do this, th[e]n do that. │ +└──────────────────────────┘ └──────────────────────────┘ + +All instances of ',' are replaced with '.'. +┌──────────────────────────────┐ . ┌──────────────────────────────┐ +│ This sentence continues(,,,] │ --> │ This sentence continues(...] │ +└──────────────────────────────┘ └──────────────────────────────┘ + +All instances of 'a' are replaced with 'e'. +┌──────────────────────────────────┐ e ┌──────────────────────────────────┐ +│ 1, th[a]n 2, th[a]n 3, th[a]n 4. │ --> │ 1, th[e]n 2, th[e]n 3, th[e]n 4. │ +└──────────────────────────────────┘ └──────────────────────────────────┘ diff --git a/runtime/help/static-commands/select_all.txt b/runtime/help/static-commands/select_all.txt new file mode 100644 index 000000000..c3543a18a --- /dev/null +++ b/runtime/help/static-commands/select_all.txt @@ -0,0 +1,3 @@ +`select_all` + +Selects the entire buffer. diff --git a/runtime/help/static-commands/switch_case.txt b/runtime/help/static-commands/switch_case.txt new file mode 100644 index 000000000..84ca73c66 --- /dev/null +++ b/runtime/help/static-commands/switch_case.txt @@ -0,0 +1,13 @@ +`switch_case` + +Toggles the case of all selected letters. + +--- Examples --- + +┌───────────────────────┐ ┌───────────────────────┐ +│ [t]his is a sentence. │ --> │ [T]his is a sentence. │ +└───────────────────────┘ └───────────────────────┘ + +┌───────────────────────┐ ┌───────────────────────┐ +│ (tHIS] is a sentence. │ --> │ (This] is a sentence. │ +└───────────────────────┘ └───────────────────────┘ diff --git a/runtime/help/static-commands/switch_to_lowercase.txt b/runtime/help/static-commands/switch_to_lowercase.txt new file mode 100644 index 000000000..055692814 --- /dev/null +++ b/runtime/help/static-commands/switch_to_lowercase.txt @@ -0,0 +1,9 @@ +`switch_to_lowercase` + +Changes all selected letters to lowercase. + +--- Examples --- + +┌──────────────────────────────────┐ ┌──────────────────────────────────┐ +│ This (wOrD] should be lowercase. │ --> │ This (word] should be lowercase. │ +└──────────────────────────────────┘ └──────────────────────────────────┘ diff --git a/runtime/help/static-commands/switch_to_uppercase.txt b/runtime/help/static-commands/switch_to_uppercase.txt new file mode 100644 index 000000000..e04673b74 --- /dev/null +++ b/runtime/help/static-commands/switch_to_uppercase.txt @@ -0,0 +1,9 @@ +`switch_to_uppercase` + +Changes all selected letters to uppercase. + +--- Examples --- + +┌──────────────────────────────────┐ ┌──────────────────────────────────┐ +│ This (wOrD] should be uppercase. │ --> │ This (WORD] should be uppercase. │ +└──────────────────────────────────┘ └──────────────────────────────────┘ diff --git a/runtime/help/static-commands/till_prev_char.txt b/runtime/help/static-commands/till_prev_char.txt new file mode 100644 index 000000000..0ae3ad374 --- /dev/null +++ b/runtime/help/static-commands/till_prev_char.txt @@ -0,0 +1,22 @@ +`till_prev_char` + +Waits for another keypress, then moves and +selects backward, stopping before the first +instance of the pressed key. Can take +a count, which will cause it to stop +before the nth instance of the keypress, +rather than the first. + +--- Examples --- + +The cursor moves backward, stopping before 'h' +and selecting everything along the way. +┌───────────────────────┐ h ┌───────────────────────┐ +│ This is a sent[e]nce. │ --> │ Th[is is a sente)nce. │ +└───────────────────────┘ └───────────────────────┘ + +The cursor is not stopped by line breaks. +┌──────────────────────────────────┐ ┌───────────────────────────────────┐ +│ There is a Q in this first line. │ Q │ There is a Q[ in this first line. │ +│ This is the se[c]ond line. │ --> │ This is the sec)ond line. │ +└──────────────────────────────────┘ └───────────────────────────────────┘ diff --git a/runtime/help/topics/Primary Modes.txt b/runtime/help/topics/Primary Modes.txt new file mode 100644 index 000000000..d9026aa76 --- /dev/null +++ b/runtime/help/topics/Primary Modes.txt @@ -0,0 +1,21 @@ +Primary Modes + +Helix is a modal editor, and has two primary "modes" of operation. + +Normal mode, which is the mode you start in by default, and which +you will likely spend a substantial amount of time in, is the main +mode used for text editing operations. + +Insert mode, which can be entered in numerous ways — such as by +pressing i — is used for typing text. + +A third mode, called "Select" or "Extend" mode, is essentially a +subset of Normal mode, where moving cursors leaves selection +anchors in place — useful for making modifications to existing +selections. Select mode can be toggled by pressing v. + +You can see which of these three modes you are currently in by +looking at the left side of the statusline. It will display: + NOR — Normal mode + INS — Insert mode + SEL — Select mode diff --git a/runtime/help/topics/Words vs. WORDS.txt b/runtime/help/topics/Words vs. WORDS.txt new file mode 100644 index 000000000..ab1aa9b61 --- /dev/null +++ b/runtime/help/topics/Words vs. WORDS.txt @@ -0,0 +1,19 @@ +Words vs. WORDS + +Words and WORDS are two very similar types of text objects. A word +is a string of "word" characters, which include letters, numbers, +and underscores. A WORD, on the other hand, is any string of +non-whitespace characters. + +In the example below, the words are underlined by 'w', and the +WORDS are underlined by 'W'. + + This "stuff" is not-so difficult! + --------------------------------- + wwww wwwww ww www ww wwwwwwwww + WWWW WWWWWWW WW WWWWWW WWWWWWWWWW + +As is visible in the example, the words do not include any of the +non-alphanumeric punctuation, while the WORDS do include the +quotes, hyphen, and exclamation point. Also notice that 'not-so' +contains two words, but only one WORD. diff --git a/runtime/help/typable-commands/buffer-close!.txt b/runtime/help/typable-commands/buffer-close!.txt new file mode 100644 index 000000000..42be7a52e --- /dev/null +++ b/runtime/help/typable-commands/buffer-close!.txt @@ -0,0 +1,6 @@ +`:buffer-close!` + +Aliases: `:bc!`, `:bclose!` + +Closes the current buffer, discarding any +unsaved changes to the buffer. diff --git a/runtime/help/typable-commands/buffer-close.txt b/runtime/help/typable-commands/buffer-close.txt new file mode 100644 index 000000000..6dcb31520 --- /dev/null +++ b/runtime/help/typable-commands/buffer-close.txt @@ -0,0 +1,6 @@ +`:buffer-close` + +Aliases: `:bc`, `:bclose` + +Closes the current buffer, failing if the buffer +has unsaved changes. diff --git a/runtime/help/typable-commands/new.txt b/runtime/help/typable-commands/new.txt new file mode 100644 index 000000000..e077c11ae --- /dev/null +++ b/runtime/help/typable-commands/new.txt @@ -0,0 +1,6 @@ +`:new` + +Aliases: `:n` + +Creates and switches to a new scratch buffer. This +buffer will not be associated with any file path. diff --git a/runtime/help/typable-commands/open.txt b/runtime/help/typable-commands/open.txt new file mode 100644 index 000000000..d92d0f5d0 --- /dev/null +++ b/runtime/help/typable-commands/open.txt @@ -0,0 +1,8 @@ +`:open ` + +Aliases: `:o` + +If exists, opens the file at . +If does not exist, creates a new buffer +and associates it with . Note that this +does not automatically save the created buffer. diff --git a/runtime/help/typable-commands/quit!.txt b/runtime/help/typable-commands/quit!.txt new file mode 100644 index 000000000..ad40f76d1 --- /dev/null +++ b/runtime/help/typable-commands/quit!.txt @@ -0,0 +1,7 @@ +`:quit!` + +Aliases: `:q!` + +Closes the current view, exiting the editor if it is +the last view. If this would exit the editor, unsaved +changes are discarded. diff --git a/runtime/help/typable-commands/quit-all!.txt b/runtime/help/typable-commands/quit-all!.txt new file mode 100644 index 000000000..185533e0b --- /dev/null +++ b/runtime/help/typable-commands/quit-all!.txt @@ -0,0 +1,6 @@ +`:quit-all!` + +Aliases: `:qa!` + +Closes all views, exiting the editor. This will +discard any unsaved changes. diff --git a/runtime/help/typable-commands/quit-all.txt b/runtime/help/typable-commands/quit-all.txt new file mode 100644 index 000000000..69c570d71 --- /dev/null +++ b/runtime/help/typable-commands/quit-all.txt @@ -0,0 +1,6 @@ +`:quit-all` + +Aliases: `:qa` + +Closes all views, exiting the editor. This will +fail if there are any unsaved changes. diff --git a/runtime/help/typable-commands/quit.txt b/runtime/help/typable-commands/quit.txt new file mode 100644 index 000000000..14bf23afd --- /dev/null +++ b/runtime/help/typable-commands/quit.txt @@ -0,0 +1,7 @@ +`:quit` + +Aliases: `:q` + +Closes the current view, exiting the editor if it is +the last view. This will fail if it would exit the +editor while there are unsaved changes. diff --git a/runtime/help/typable-commands/write-all.txt b/runtime/help/typable-commands/write-all.txt new file mode 100644 index 000000000..3518402a8 --- /dev/null +++ b/runtime/help/typable-commands/write-all.txt @@ -0,0 +1,7 @@ +`:write-all` + +Aliases: `:wa` + +Writes (saves) all unsaved buffers to disk. +Scratch buffers (without associated paths) +will not be saved. diff --git a/runtime/help/typable-commands/write-quit!.txt b/runtime/help/typable-commands/write-quit!.txt new file mode 100644 index 000000000..916bd07f8 --- /dev/null +++ b/runtime/help/typable-commands/write-quit!.txt @@ -0,0 +1,9 @@ +`:write-quit! [path]` + +Aliases: `:wq!`, `:x!` + +Writes (saves) the buffer to disk, then +closes the view, discarding unsaved changes +if this would exit the editor. +Identical to `:write [path]` followed by `:quit!`. +See those commands for more info. diff --git a/runtime/help/typable-commands/write-quit-all!.txt b/runtime/help/typable-commands/write-quit-all!.txt new file mode 100644 index 000000000..cfb3394de --- /dev/null +++ b/runtime/help/typable-commands/write-quit-all!.txt @@ -0,0 +1,10 @@ +`:write-quit-all!` + +Aliases: `:wqa!`, `:xa!` + +Writes (saves) all unsaved buffers to disk, then +closes all views, exiting the editor. +Scratch buffers (without associated paths) will +not be saved, and will be discarded when the +editor exits. +Identical to `:write-all` followed by `:quit-all!`. diff --git a/runtime/help/typable-commands/write-quit-all.txt b/runtime/help/typable-commands/write-quit-all.txt new file mode 100644 index 000000000..b551bcb3f --- /dev/null +++ b/runtime/help/typable-commands/write-quit-all.txt @@ -0,0 +1,10 @@ +`:write-quit-all` + +Aliases: `:wqa`, `:xa` + +Writes (saves) all unsaved buffers to disk, then +closes all views, exiting the editor. +Scratch buffers (without associated paths) will +not be saved, and exiting the editor will fail +if there are any such buffers open. +Identical to `:write-all` followed by `:quit-all`. diff --git a/runtime/help/typable-commands/write-quit.txt b/runtime/help/typable-commands/write-quit.txt new file mode 100644 index 000000000..17629d5a1 --- /dev/null +++ b/runtime/help/typable-commands/write-quit.txt @@ -0,0 +1,8 @@ +`:write-quit [path]` + +Aliases: `:wq`, `:x` + +Writes (saves) the buffer to disk, then +closes the view. +Identical to `:write [path]` followed by `:quit`. +See those commands for more info. diff --git a/runtime/help/typable-commands/write.txt b/runtime/help/typable-commands/write.txt new file mode 100644 index 000000000..8035714a1 --- /dev/null +++ b/runtime/help/typable-commands/write.txt @@ -0,0 +1,9 @@ +`:write [path]` + +Aliases: `:w` + +Writes (saves) the buffer to disk. +If [path] is supplied, that path is written to. +If the buffer is a scratch buffer, meaning it +is not already bound to a file path, [path] +becomes required for this command to succeed.