diff --git a/book/src/generated/typable-cmd.md b/book/src/generated/typable-cmd.md index cf1b550dc45a..1294a448dedc 100644 --- a/book/src/generated/typable-cmd.md +++ b/book/src/generated/typable-cmd.md @@ -88,3 +88,4 @@ | `:move` | Move the current buffer and its corresponding file to a different path | | `:yank-diagnostic` | Yank diagnostic(s) under primary cursor to register, or clipboard by default | | `:read`, `:r` | Load a file into buffer | +| `: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 f38ae6bba4d4..c3abbe368106 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -2401,7 +2401,6 @@ fn move_buffer( if event != PromptEvent::Validate { return Ok(()); } - ensure!(args.len() == 1, format!(":move takes one argument")); let doc = doc!(cx.editor); let old_path = doc @@ -2488,6 +2487,116 @@ fn read(cx: &mut compositor::Context, args: &[Cow], event: PromptEvent) -> Ok(()) } +fn help(cx: &mut compositor::Context, args: &[Cow], event: PromptEvent) -> anyhow::Result<()> { + if event != PromptEvent::Validate { + return Ok(()); + } + + const STATIC_HELP_DIR: &str = "static-commands"; + const TYPABLE_HELP_DIR: &str = "typable-commands"; + + let args_msg = args.join(" "); + let open_help = + move |help_dir: &str, command: &str, editor: &mut Editor| -> anyhow::Result<()> { + let path = Path::new("help").join(help_dir).join(command); + let path = helix_loader::runtime_file(&path); + 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(()) + }; + + if args.is_empty() { + return open_help(TYPABLE_HELP_DIR, "help", cx.editor); + } + + if args[0] == "topics" { + let dir_path = helix_loader::runtime_file(Path::new("help/topics")); + + let callback = async move { + let call: job::Callback = job::Callback::EditorCompositor(Box::new( + move |editor: &mut Editor, compositor: &mut Compositor| { + let picker = ui::file_picker(dir_path, &editor.config()); + compositor.push(Box::new(overlaid(picker))); + }, + )); + Ok(call) + }; + cx.jobs.callback(callback); + + return Ok(()); + } + + 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.contains(&arg)).then_some(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.clone().into_owned(); + let keys = arg + .parse::() + .map(|key| vec![key]) + .or_else(|_| helix_view::input::parse_macro(&arg))?; + let callback = async move { + let call: job::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 key_result = keymaps.get(mode, *last_key); + let result: anyhow::Result<(&str, &str)> = match &key_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)) + } + KeymapResult::Pending(_) => { + // Clear pending keys + keymaps.get(mode, crate::keymap::macros::key!(Esc)); + Err(anyhow!( + "`:help` for branching keybinds is not yet supported." + )) + } + KeymapResult::MatchedSequence(_) => Err(anyhow!( + "`:help` for sequence bindings is not yet supported." + )), + }; + if let Err(e) = result + .and_then(|(help_dir, command)| open_help(help_dir, command, editor)) + { + editor.set_error(e.to_string()); + } + }, + )); + Ok(call) + }; + cx.jobs.callback(callback); + return Ok(()); + } + }; + + open_help(help_dir, command, cx.editor) +} + pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ TypableCommand { name: "quit", @@ -3109,6 +3218,13 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ fun: read, signature: CommandSignature::positional(&[completers::filename]), }, + TypableCommand { + name: "help", + aliases: &["h"], + doc: "Open documentation for a command or keybind.", + fun: help, + signature: CommandSignature::positional(&[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 5211c2e272ef..acadf2080c38 100644 --- a/helix-term/src/ui/mod.rs +++ b/helix-term/src/ui/mod.rs @@ -397,6 +397,42 @@ pub mod completers { }) } + pub fn help(_editor: &Editor, input: &str) -> Vec { + use std::path::Path; + let static_cmds_path = helix_loader::runtime_file(Path::new("help/static-commands")); + let typable_cmds_path = helix_loader::runtime_file(Path::new("help/typable-commands")); + + let static_cmds = std::fs::read_dir(static_cmds_path) + .into_iter() + .flat_map(|entries| { + entries.filter_map(|entry| { + let path = entry.ok()?.path(); + path.extension() + .is_none() + .then(|| path.file_stem().unwrap().to_string_lossy().into_owned()) + }) + }); + let typable_cmds = std::fs::read_dir(typable_cmds_path) + .into_iter() + .flat_map(|entries| { + entries.filter_map(|entry| { + let path = entry.ok()?.path(); + path.extension() + .is_none() + .then(|| format!(":{}", path.file_stem().unwrap().to_string_lossy())) + }) + }); + + let items = std::iter::once("topics".to_owned()) + .chain(static_cmds) + .chain(typable_cmds); + + fuzzy_match(input, items, false) + .into_iter() + .map(|(name, _)| (0.., name.into())) + .collect() + } + #[derive(Copy, Clone, PartialEq, Eq)] enum FileMatch { /// Entry should be ignored diff --git a/runtime/help/static-commands/append_mode b/runtime/help/static-commands/append_mode new file mode 100644 index 000000000000..a50dff179fe7 --- /dev/null +++ b/runtime/help/static-commands/append_mode @@ -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 b/runtime/help/static-commands/append_to_line new file mode 100644 index 000000000000..0550be6f57cb --- /dev/null +++ b/runtime/help/static-commands/append_to_line @@ -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 b/runtime/help/static-commands/copy_selection_on_next_line new file mode 100644 index 000000000000..0187444dbcd9 --- /dev/null +++ b/runtime/help/static-commands/copy_selection_on_next_line @@ -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 b/runtime/help/static-commands/copy_selection_on_prev_line new file mode 100644 index 000000000000..756c2b364084 --- /dev/null +++ b/runtime/help/static-commands/copy_selection_on_prev_line @@ -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 b/runtime/help/static-commands/extend_char_left new file mode 100644 index 000000000000..2e87ef6085c0 --- /dev/null +++ b/runtime/help/static-commands/extend_char_left @@ -0,0 +1,3 @@ +`extend_char_left` + +Extending version of `move_char_left`. diff --git a/runtime/help/static-commands/extend_char_right b/runtime/help/static-commands/extend_char_right new file mode 100644 index 000000000000..7568169f9e30 --- /dev/null +++ b/runtime/help/static-commands/extend_char_right @@ -0,0 +1,3 @@ +`extend_char_right` + +Extending version of `move_char_right`. diff --git a/runtime/help/static-commands/extend_line_down b/runtime/help/static-commands/extend_line_down new file mode 100644 index 000000000000..f37497c53d33 --- /dev/null +++ b/runtime/help/static-commands/extend_line_down @@ -0,0 +1,3 @@ +`extend_line_down` + +Extending version of `move_line_down`. diff --git a/runtime/help/static-commands/extend_line_up b/runtime/help/static-commands/extend_line_up new file mode 100644 index 000000000000..2adcbac6c86c --- /dev/null +++ b/runtime/help/static-commands/extend_line_up @@ -0,0 +1,3 @@ +`extend_line_up` + +Extending version of `move_line_up`. diff --git a/runtime/help/static-commands/extend_next_char b/runtime/help/static-commands/extend_next_char new file mode 100644 index 000000000000..3a850520e63b --- /dev/null +++ b/runtime/help/static-commands/extend_next_char @@ -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 b/runtime/help/static-commands/extend_next_long_word_end new file mode 100644 index 000000000000..edc3acecd220 --- /dev/null +++ b/runtime/help/static-commands/extend_next_long_word_end @@ -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 b/runtime/help/static-commands/extend_next_long_word_start new file mode 100644 index 000000000000..04f8e2480cd1 --- /dev/null +++ b/runtime/help/static-commands/extend_next_long_word_start @@ -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 b/runtime/help/static-commands/extend_next_word_end new file mode 100644 index 000000000000..aee4840eeb92 --- /dev/null +++ b/runtime/help/static-commands/extend_next_word_end @@ -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 b/runtime/help/static-commands/extend_next_word_start new file mode 100644 index 000000000000..4c6e3875beec --- /dev/null +++ b/runtime/help/static-commands/extend_next_word_start @@ -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 b/runtime/help/static-commands/extend_prev_char new file mode 100644 index 000000000000..631f8335617d --- /dev/null +++ b/runtime/help/static-commands/extend_prev_char @@ -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 b/runtime/help/static-commands/extend_prev_long_word_start new file mode 100644 index 000000000000..26aa259c5933 --- /dev/null +++ b/runtime/help/static-commands/extend_prev_long_word_start @@ -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 b/runtime/help/static-commands/extend_prev_word_start new file mode 100644 index 000000000000..699343c842de --- /dev/null +++ b/runtime/help/static-commands/extend_prev_word_start @@ -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 b/runtime/help/static-commands/extend_till_char new file mode 100644 index 000000000000..e614fe28c0e3 --- /dev/null +++ b/runtime/help/static-commands/extend_till_char @@ -0,0 +1,3 @@ +`extend_till_char` + +Extending version of `find_till_char`. diff --git a/runtime/help/static-commands/extend_till_prev_char b/runtime/help/static-commands/extend_till_prev_char new file mode 100644 index 000000000000..7f7047bb218c --- /dev/null +++ b/runtime/help/static-commands/extend_till_prev_char @@ -0,0 +1,3 @@ +`extend_till_prev_char` + +Extending version of `till_prev_char`. diff --git a/runtime/help/static-commands/find_next_char b/runtime/help/static-commands/find_next_char new file mode 100644 index 000000000000..086754ea0b48 --- /dev/null +++ b/runtime/help/static-commands/find_next_char @@ -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 b/runtime/help/static-commands/find_prev_char new file mode 100644 index 000000000000..4d277a408c68 --- /dev/null +++ b/runtime/help/static-commands/find_prev_char @@ -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 b/runtime/help/static-commands/find_till_char new file mode 100644 index 000000000000..dc00bb8475f1 --- /dev/null +++ b/runtime/help/static-commands/find_till_char @@ -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 b/runtime/help/static-commands/half_page_down new file mode 100644 index 000000000000..2ddeac6b90fb --- /dev/null +++ b/runtime/help/static-commands/half_page_down @@ -0,0 +1,3 @@ +`half_page_down` + +Scrolls down by half of a screen. diff --git a/runtime/help/static-commands/half_page_up b/runtime/help/static-commands/half_page_up new file mode 100644 index 000000000000..1fdaec921ce7 --- /dev/null +++ b/runtime/help/static-commands/half_page_up @@ -0,0 +1,3 @@ +`half_page_up` + +Scrolls up by half of a screen. diff --git a/runtime/help/static-commands/insert_mode b/runtime/help/static-commands/insert_mode new file mode 100644 index 000000000000..dda2f14ae6be --- /dev/null +++ b/runtime/help/static-commands/insert_mode @@ -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 b/runtime/help/static-commands/move_char_left new file mode 100644 index 000000000000..97b1363a4899 --- /dev/null +++ b/runtime/help/static-commands/move_char_left @@ -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 b/runtime/help/static-commands/move_char_right new file mode 100644 index 000000000000..dc085d72d435 --- /dev/null +++ b/runtime/help/static-commands/move_char_right @@ -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 b/runtime/help/static-commands/move_line_down new file mode 100644 index 000000000000..7cbe45c029b6 --- /dev/null +++ b/runtime/help/static-commands/move_line_down @@ -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 b/runtime/help/static-commands/move_line_up new file mode 100644 index 000000000000..5fdef6c166fe --- /dev/null +++ b/runtime/help/static-commands/move_line_up @@ -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 b/runtime/help/static-commands/move_next_long_word_end new file mode 100644 index 000000000000..fd5a5933c688 --- /dev/null +++ b/runtime/help/static-commands/move_next_long_word_end @@ -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 b/runtime/help/static-commands/move_next_long_word_start new file mode 100644 index 000000000000..86f4a6cf4993 --- /dev/null +++ b/runtime/help/static-commands/move_next_long_word_start @@ -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 b/runtime/help/static-commands/move_next_word_end new file mode 100644 index 000000000000..0b859a8a73dc --- /dev/null +++ b/runtime/help/static-commands/move_next_word_end @@ -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 b/runtime/help/static-commands/move_next_word_start new file mode 100644 index 000000000000..ca8b1117043b --- /dev/null +++ b/runtime/help/static-commands/move_next_word_start @@ -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 b/runtime/help/static-commands/move_prev_long_word_start new file mode 100644 index 000000000000..1b223c96ea6b --- /dev/null +++ b/runtime/help/static-commands/move_prev_long_word_start @@ -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 b/runtime/help/static-commands/move_prev_word_start new file mode 100644 index 000000000000..0e71450abace --- /dev/null +++ b/runtime/help/static-commands/move_prev_word_start @@ -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 b/runtime/help/static-commands/no_op new file mode 100644 index 000000000000..b8e9d20cf48d --- /dev/null +++ b/runtime/help/static-commands/no_op @@ -0,0 +1,3 @@ +`no_op` + +Does nothing. Use this to disable default keybinds. diff --git a/runtime/help/static-commands/page_down b/runtime/help/static-commands/page_down new file mode 100644 index 000000000000..0679b1d4ffba --- /dev/null +++ b/runtime/help/static-commands/page_down @@ -0,0 +1,3 @@ +`page_down` + +Scrolls down by one screen. diff --git a/runtime/help/static-commands/page_up b/runtime/help/static-commands/page_up new file mode 100644 index 000000000000..dab743afa584 --- /dev/null +++ b/runtime/help/static-commands/page_up @@ -0,0 +1,3 @@ +`page_up` + +Scrolls up by one screen. diff --git a/runtime/help/static-commands/prepend_to_line b/runtime/help/static-commands/prepend_to_line new file mode 100644 index 000000000000..628d83629879 --- /dev/null +++ b/runtime/help/static-commands/prepend_to_line @@ -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 b/runtime/help/static-commands/replace new file mode 100644 index 000000000000..ebe1a41fd09c --- /dev/null +++ b/runtime/help/static-commands/replace @@ -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 b/runtime/help/static-commands/select_all new file mode 100644 index 000000000000..c3543a18a028 --- /dev/null +++ b/runtime/help/static-commands/select_all @@ -0,0 +1,3 @@ +`select_all` + +Selects the entire buffer. diff --git a/runtime/help/static-commands/switch_case b/runtime/help/static-commands/switch_case new file mode 100644 index 000000000000..84ca73c66d26 --- /dev/null +++ b/runtime/help/static-commands/switch_case @@ -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 b/runtime/help/static-commands/switch_to_lowercase new file mode 100644 index 000000000000..0556928146d2 --- /dev/null +++ b/runtime/help/static-commands/switch_to_lowercase @@ -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 b/runtime/help/static-commands/switch_to_uppercase new file mode 100644 index 000000000000..e04673b74a3e --- /dev/null +++ b/runtime/help/static-commands/switch_to_uppercase @@ -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 b/runtime/help/static-commands/till_prev_char new file mode 100644 index 000000000000..0ae3ad3747b9 --- /dev/null +++ b/runtime/help/static-commands/till_prev_char @@ -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 b/runtime/help/topics/Primary Modes new file mode 100644 index 000000000000..d9026aa76784 --- /dev/null +++ b/runtime/help/topics/Primary Modes @@ -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 b/runtime/help/topics/Words vs. WORDS new file mode 100644 index 000000000000..ab1aa9b61c1b --- /dev/null +++ b/runtime/help/topics/Words vs. WORDS @@ -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 b/runtime/help/typable-commands/buffer-close new file mode 100644 index 000000000000..6dcb31520978 --- /dev/null +++ b/runtime/help/typable-commands/buffer-close @@ -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/buffer-close! b/runtime/help/typable-commands/buffer-close! new file mode 100644 index 000000000000..42be7a52ea5a --- /dev/null +++ b/runtime/help/typable-commands/buffer-close! @@ -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/help b/runtime/help/typable-commands/help new file mode 100644 index 000000000000..e3057694bcdd --- /dev/null +++ b/runtime/help/typable-commands/help @@ -0,0 +1,21 @@ +`:help [command|keybind|'topics']` + +Aliases: `:h` + +Opens documentation for a command or keybind, or for the +editor in general. + +`:help` +Opens this page. + +`:help ` +Opens help for `command`, +e.g. `:help find_next_char`, `:help :open`. + +`:help ` +Opens help for the command associated with `keybind`, +e.g. `:help f`, `:help C-o`. + +`:help topics` +Opens a picker with various help topics not related to +specific commands or keybinds. diff --git a/runtime/help/typable-commands/new b/runtime/help/typable-commands/new new file mode 100644 index 000000000000..e077c11aeb4c --- /dev/null +++ b/runtime/help/typable-commands/new @@ -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 b/runtime/help/typable-commands/open new file mode 100644 index 000000000000..d92d0f5d042a --- /dev/null +++ b/runtime/help/typable-commands/open @@ -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 b/runtime/help/typable-commands/quit new file mode 100644 index 000000000000..14bf23afd845 --- /dev/null +++ b/runtime/help/typable-commands/quit @@ -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/quit! b/runtime/help/typable-commands/quit! new file mode 100644 index 000000000000..ad40f76d169c --- /dev/null +++ b/runtime/help/typable-commands/quit! @@ -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 b/runtime/help/typable-commands/quit-all new file mode 100644 index 000000000000..69c570d717b2 --- /dev/null +++ b/runtime/help/typable-commands/quit-all @@ -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-all! b/runtime/help/typable-commands/quit-all! new file mode 100644 index 000000000000..185533e0b929 --- /dev/null +++ b/runtime/help/typable-commands/quit-all! @@ -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/write b/runtime/help/typable-commands/write new file mode 100644 index 000000000000..8035714a1ee0 --- /dev/null +++ b/runtime/help/typable-commands/write @@ -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. diff --git a/runtime/help/typable-commands/write-all b/runtime/help/typable-commands/write-all new file mode 100644 index 000000000000..3518402a82f3 --- /dev/null +++ b/runtime/help/typable-commands/write-all @@ -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 b/runtime/help/typable-commands/write-quit new file mode 100644 index 000000000000..17629d5a19de --- /dev/null +++ b/runtime/help/typable-commands/write-quit @@ -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-quit! b/runtime/help/typable-commands/write-quit! new file mode 100644 index 000000000000..916bd07f81b8 --- /dev/null +++ b/runtime/help/typable-commands/write-quit! @@ -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 b/runtime/help/typable-commands/write-quit-all new file mode 100644 index 000000000000..b551bcb3f154 --- /dev/null +++ b/runtime/help/typable-commands/write-quit-all @@ -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-all! b/runtime/help/typable-commands/write-quit-all! new file mode 100644 index 000000000000..cfb3394ded48 --- /dev/null +++ b/runtime/help/typable-commands/write-quit-all! @@ -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!`.