Add :help command

This commit is contained in:
Omnikar 2022-12-12 19:51:28 -06:00 committed by Michael Davis
parent fa436fa680
commit 321fce3ba6
No known key found for this signature in database
63 changed files with 742 additions and 0 deletions

View File

@ -73,3 +73,4 @@
| `:pipe` | Pipe each selection to the shell command. | | `:pipe` | Pipe each selection to the shell command. |
| `:pipe-to` | Pipe each selection to the shell command, ignoring output. | | `:pipe-to` | Pipe each selection to the shell command, ignoring output. |
| `:run-shell-command`, `:sh` | Run a shell command | | `:run-shell-command`, `:sh` | Run a shell command |
| `:help`, `:h` | Open documentation for a command or keybind. |

View File

@ -1808,6 +1808,155 @@ fn run_shell_command(
Ok(()) Ok(())
} }
fn help(cx: &mut compositor::Context, args: &[Cow<str>], 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<Topic> = 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::<KeyEvent>()
.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::<ui::EditorView>().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] = &[ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
TypableCommand { TypableCommand {
name: "quit", name: "quit",
@ -2323,6 +2472,13 @@ fn run_shell_command(
fun: run_shell_command, fun: run_shell_command,
completer: Some(completers::directory), 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<HashMap<&'static str, &'static TypableCommand>> = pub static TYPABLE_COMMAND_MAP: Lazy<HashMap<&'static str, &'static TypableCommand>> =

View File

@ -441,6 +441,50 @@ pub fn directory(editor: &Editor, input: &str) -> Vec<Completion> {
}) })
} }
pub fn help(_editor: &Editor, input: &str) -> Vec<Completion> {
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<String> = 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)] #[derive(Copy, Clone, PartialEq, Eq)]
enum FileMatch { enum FileMatch {
/// Entry should be ignored /// Entry should be ignored

View File

@ -0,0 +1,5 @@
`append_mode`
Enters Insert mode at the end of the selection.
For information about Insert mode, see "Primary Modes".

View File

@ -0,0 +1,5 @@
`append_to_line`
Enters Insert mode at the end of the line.
For information about Insert mode, see "Primary Modes".

View File

@ -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. │
└──────────────────────────────────┘ └──────────────────────────────────┘

View File

@ -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. │
└──────────────────────────────────┘ └──────────────────────────────────┘

View File

@ -0,0 +1,3 @@
`extend_char_left`
Extending version of `move_char_left`.

View File

@ -0,0 +1,3 @@
`extend_char_right`
Extending version of `move_char_right`.

View File

@ -0,0 +1,3 @@
`extend_line_down`
Extending version of `move_line_down`.

View File

@ -0,0 +1,3 @@
`extend_line_up`
Extending version of `move_line_up`.

View File

@ -0,0 +1,3 @@
`extend_next_char`
Extending version of `find_next_char`.

View File

@ -0,0 +1,3 @@
`extend_next_long_word_end`
Extending version of `move_next_long_word_end`.

View File

@ -0,0 +1,3 @@
`extend_next_long_word_start`
Extending version of `move_next_long_word_start`.

View File

@ -0,0 +1,3 @@
`extend_next_word_end`
Extending version of `move_next_word_end`.

View File

@ -0,0 +1,3 @@
`extend_next_word_start`
Extending version of `move_next_word_start`.

View File

@ -0,0 +1,3 @@
`extend_prev_char`
Extending version of `find_prev_char`.

View File

@ -0,0 +1,3 @@
`extend_prev_long_word_start`
Extending version of `move_prev_long_word_start`.

View File

@ -0,0 +1,3 @@
`extend_prev_word_start`
Extending version of `move_prev_word_start`.

View File

@ -0,0 +1,3 @@
`extend_till_char`
Extending version of `find_till_char`.

View File

@ -0,0 +1,3 @@
`extend_till_prev_char`
Extending version of `till_prev_char`.

View File

@ -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]. │
└───────────────────────────┘ └────────────────────────────┘

View File

@ -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. │
└──────────────────────────────────┘ └───────────────────────────────────┘

View File

@ -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. │
└───────────────────────────┘ └────────────────────────────┘

View File

@ -0,0 +1,3 @@
`half_page_down`
Scrolls down by half of a screen.

View File

@ -0,0 +1,3 @@
`half_page_up`
Scrolls up by half of a screen.

View File

@ -0,0 +1,5 @@
`insert_mode`
Enters Insert mode at the start of the selection.
For information about Insert mode, see "Primary Modes".

View File

@ -0,0 +1,4 @@
`move_char_left`
Moves all cursors 1 character left, removing
any selections and wrapping across line breaks.

View File

@ -0,0 +1,4 @@
`move_char_right`
Moves all cursors 1 character right, removing
any selections and wrapping across line breaks.

View File

@ -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. │
└────────────────────────────┘ └────────────────────────────┘ └──────────────────────────────┘

View File

@ -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. │
└──────────────────────────────┘ └────────────────────────────┘ └────────────────────────────┘

View File

@ -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. │
└────────────────────┘ └────────────────────┘

View File

@ -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. │
└────────────────────┘ └────────────────────┘

View File

@ -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. │
└────────────────────┘ └────────────────────┘

View File

@ -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. │
└────────────────────┘ └────────────────────┘

View File

@ -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. │
└────────────────────┘ └────────────────────┘

View File

@ -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. │
└────────────────────┘ └────────────────────┘

View File

@ -0,0 +1,3 @@
`no_op`
Does nothing. Use this to disable default keybinds.

View File

@ -0,0 +1,3 @@
`page_down`
Scrolls down by one screen.

View File

@ -0,0 +1,3 @@
`page_up`
Scrolls up by one screen.

View File

@ -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".

View File

@ -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. │
└──────────────────────────────────┘ └──────────────────────────────────┘

View File

@ -0,0 +1,3 @@
`select_all`
Selects the entire buffer.

View File

@ -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. │
└───────────────────────┘ └───────────────────────┘

View File

@ -0,0 +1,9 @@
`switch_to_lowercase`
Changes all selected letters to lowercase.
--- Examples ---
┌──────────────────────────────────┐ ┌──────────────────────────────────┐
│ This (wOrD] should be lowercase. │ --> │ This (word] should be lowercase. │
└──────────────────────────────────┘ └──────────────────────────────────┘

View File

@ -0,0 +1,9 @@
`switch_to_uppercase`
Changes all selected letters to uppercase.
--- Examples ---
┌──────────────────────────────────┐ ┌──────────────────────────────────┐
│ This (wOrD] should be uppercase. │ --> │ This (WORD] should be uppercase. │
└──────────────────────────────────┘ └──────────────────────────────────┘

View File

@ -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. │
└──────────────────────────────────┘ └───────────────────────────────────┘

View File

@ -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

View File

@ -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.

View File

@ -0,0 +1,6 @@
`:buffer-close!`
Aliases: `:bc!`, `:bclose!`
Closes the current buffer, discarding any
unsaved changes to the buffer.

View File

@ -0,0 +1,6 @@
`:buffer-close`
Aliases: `:bc`, `:bclose`
Closes the current buffer, failing if the buffer
has unsaved changes.

View File

@ -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.

View File

@ -0,0 +1,8 @@
`:open <path>`
Aliases: `:o`
If <path> exists, opens the file at <path>.
If <path> does not exist, creates a new buffer
and associates it with <path>. Note that this
does not automatically save the created buffer.

View File

@ -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.

View File

@ -0,0 +1,6 @@
`:quit-all!`
Aliases: `:qa!`
Closes all views, exiting the editor. This will
discard any unsaved changes.

View File

@ -0,0 +1,6 @@
`:quit-all`
Aliases: `:qa`
Closes all views, exiting the editor. This will
fail if there are any unsaved changes.

View File

@ -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.

View File

@ -0,0 +1,7 @@
`:write-all`
Aliases: `:wa`
Writes (saves) all unsaved buffers to disk.
Scratch buffers (without associated paths)
will not be saved.

View File

@ -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.

View File

@ -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!`.

View File

@ -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`.

View File

@ -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.

View File

@ -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.