From 72f606ee19a20eca7901ac1647e8efa58ea4f8b8 Mon Sep 17 00:00:00 2001 From: ath3 Date: Wed, 24 Nov 2021 08:46:40 +0100 Subject: Implement no-yank delete/change (#1099) --- book/src/keymap.md | 72 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 35 deletions(-) (limited to 'book/src') diff --git a/book/src/keymap.md b/book/src/keymap.md index fbe77267..4d542800 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -45,44 +45,46 @@ ### Changes -| Key | Description | Command | -| ----- | ----------- | ------- | -| `r` | Replace with a character | `replace` | -| `R` | Replace with yanked text | `replace_with_yanked` | -| `~` | Switch case of the selected text | `switch_case` | -| `` ` `` | Set the selected text to lower case | `switch_to_lowercase` | -| `` Alt-` `` | Set the selected text to upper case | `switch_to_uppercase` | -| `i` | Insert before selection | `insert_mode` | -| `a` | Insert after selection (append) | `append_mode` | -| `I` | Insert at the start of the line | `prepend_to_line` | -| `A` | Insert at the end of the line | `append_to_line` | -| `o` | Open new line below selection | `open_below` | -| `O` | Open new line above selection | `open_above` | -| `.` | Repeat last change | N/A | -| `u` | Undo change | `undo` | -| `U` | Redo change | `redo` | -| `Alt-u` | Move backward in history | `earlier` | -| `Alt-U` | Move forward in history | `later` | -| `y` | Yank selection | `yank` | -| `p` | Paste after selection | `paste_after` | -| `P` | Paste before selection | `paste_before` | -| `"` `` | Select a register to yank to or paste from | `select_register` | -| `>` | Indent selection | `indent` | -| `<` | Unindent selection | `unindent` | -| `=` | Format selection (**LSP**) | `format_selections` | -| `d` | Delete selection | `delete_selection` | -| `c` | Change selection (delete and enter insert mode) | `change_selection` | -| `Ctrl-a` | Increment object (number) under cursor | `increment` | -| `Ctrl-x` | Decrement object (number) under cursor | `decrement` | +| Key | Description | Command | +| ----- | ----------- | ------- | +| `r` | Replace with a character | `replace` | +| `R` | Replace with yanked text | `replace_with_yanked` | +| `~` | Switch case of the selected text | `switch_case` | +| `` ` `` | Set the selected text to lower case | `switch_to_lowercase` | +| `` Alt-` `` | Set the selected text to upper case | `switch_to_uppercase` | +| `i` | Insert before selection | `insert_mode` | +| `a` | Insert after selection (append) | `append_mode` | +| `I` | Insert at the start of the line | `prepend_to_line` | +| `A` | Insert at the end of the line | `append_to_line` | +| `o` | Open new line below selection | `open_below` | +| `O` | Open new line above selection | `open_above` | +| `.` | Repeat last change | N/A | +| `u` | Undo change | `undo` | +| `U` | Redo change | `redo` | +| `Alt-u` | Move backward in history | `earlier` | +| `Alt-U` | Move forward in history | `later` | +| `y` | Yank selection | `yank` | +| `p` | Paste after selection | `paste_after` | +| `P` | Paste before selection | `paste_before` | +| `"` `` | Select a register to yank to or paste from | `select_register` | +| `>` | Indent selection | `indent` | +| `<` | Unindent selection | `unindent` | +| `=` | Format selection (**LSP**) | `format_selections` | +| `d` | Delete selection | `delete_selection` | +| `Alt-d` | Delete selection, without yanking | `delete_selection_noyank` | +| `c` | Change selection (delete and enter insert mode) | `change_selection` | +| `Alt-c` | Change selection (delete and enter insert mode, without yanking) | `change_selection_noyank` | +| `Ctrl-a` | Increment object (number) under cursor | `increment` | +| `Ctrl-x` | Decrement object (number) under cursor | `decrement` | #### Shell -| Key | Description | Command | -| ------ | ----------- | ------- | -| | | Pipe each selection through shell command, replacing with output | `shell_pipe` | -| A-| | Pipe each selection into shell command, ignoring output | `shell_pipe_to` | -| `!` | Run shell command, inserting output before each selection | `shell_insert_output` | -| `A-!` | Run shell command, appending output after each selection | `shell_append_output` | +| Key | Description | Command | +| ------ | ----------- | ------- | +| | | Pipe each selection through shell command, replacing with output | `shell_pipe` | +| Alt-| | Pipe each selection into shell command, ignoring output | `shell_pipe_to` | +| `!` | Run shell command, inserting output before each selection | `shell_insert_output` | +| `Alt-!` | Run shell command, appending output after each selection | `shell_append_output` | ### Selection manipulation -- cgit v1.2.3-70-g09d2 From 3b2b7341a5d3d616496e8f13e6522d08c7864fb4 Mon Sep 17 00:00:00 2001 From: ath3 Date: Sun, 28 Nov 2021 02:18:25 +0100 Subject: Fix next char delete key documentation for prompt (#1180) --- book/src/keymap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'book/src') diff --git a/book/src/keymap.md b/book/src/keymap.md index 4d542800..5e861cfb 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -317,7 +317,7 @@ Keys to use within prompt, Remapping currently not supported. | `Ctrl-u` | Delete to start of line | | `Ctrl-k` | Delete to end of line | | `backspace`, `Ctrl-h` | Delete previous char | -| `delete`, `Ctrl-d` | Delete previous char | +| `delete`, `Ctrl-d` | Delete next char | | `Ctrl-s` | Insert a word under doc cursor, may be changed to Ctrl-r Ctrl-w later | | `Ctrl-p`, `Up` | Select previous history | | `Ctrl-n`, `Down` | Select next history | -- cgit v1.2.3-70-g09d2 From 1d773bcefb40f69fe31dc048bfbdd83601fe0e62 Mon Sep 17 00:00:00 2001 From: ath3 Date: Sun, 28 Nov 2021 02:21:40 +0100 Subject: Implement black hole register (#1165) --- book/src/usage.md | 2 ++ helix-core/src/register.rs | 14 +++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'book/src') diff --git a/book/src/usage.md b/book/src/usage.md index 6b7cbc41..cf7d9d48 100644 --- a/book/src/usage.md +++ b/book/src/usage.md @@ -23,8 +23,10 @@ If there is a selected register before invoking a change or delete command, the | `/` | Last search | | `:` | Last executed command | | `"` | Last yanked text | +| `_` | Black hole | > There is no special register for copying to system clipboard, instead special commands and keybindings are provided. See the [keymap](keymap.md#space-mode) for the specifics. +> The black hole register works as a no-op register, meaning no data will be written to / read from it. ## Surround diff --git a/helix-core/src/register.rs b/helix-core/src/register.rs index c5444eb7..b9eb497d 100644 --- a/helix-core/src/register.rs +++ b/helix-core/src/register.rs @@ -15,7 +15,11 @@ impl Register { } pub fn new_with_values(name: char, values: Vec) -> Self { - Self { name, values } + if name == '_' { + Self::new(name) + } else { + Self { name, values } + } } pub const fn name(&self) -> char { @@ -27,11 +31,15 @@ impl Register { } pub fn write(&mut self, values: Vec) { - self.values = values; + if self.name != '_' { + self.values = values; + } } pub fn push(&mut self, value: String) { - self.values.push(value); + if self.name != '_' { + self.values.push(value); + } } } -- cgit v1.2.3-70-g09d2 From 6f1a7b1220c2ae565a2542fb089eb6d87f0a9421 Mon Sep 17 00:00:00 2001 From: Kirawi Date: Sun, 28 Nov 2021 20:38:17 -0500 Subject: Add llvm grammar (#1167) --- .gitmodules | 4 ++++ book/src/themes.md | 5 +++-- languages.toml | 8 ++++++++ runtime/queries/llvm/highlights.scm | 14 ++++++++++++++ 4 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 runtime/queries/llvm/highlights.scm (limited to 'book/src') diff --git a/.gitmodules b/.gitmodules index 039a3ee3..6295b9e9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -146,3 +146,7 @@ path = helix-syntax/languages/tree-sitter-wgsl url = https://github.com/szebniok/tree-sitter-wgsl shallow = true +[submodule "helix-syntax/tree-sitter-llvm"] + path = helix-syntax/languages/tree-sitter-llvm + url = https://github.com/benwilliamgraham/tree-sitter-llvm + shallow = true diff --git a/book/src/themes.md b/book/src/themes.md index ecbbb6e9..fd3f5b1e 100644 --- a/book/src/themes.md +++ b/book/src/themes.md @@ -145,11 +145,12 @@ We use a similar set of scopes as - `conditional` - `if`, `else` - `repeat` - `for`, `while`, `loop` - `import` - `import`, `export` - - (TODO: return?) + - `return` + - `operator` - `or`, `in` - `directive` - Preprocessor directives (`#if` in C) - `function` - `fn`, `func` -- `operator` - `||`, `+=`, `>`, `or` +- `operator` - `||`, `+=`, `>` - `function` - `builtin` diff --git a/languages.toml b/languages.toml index 5dcbd872..4208e4b6 100644 --- a/languages.toml +++ b/languages.toml @@ -413,3 +413,11 @@ file-types = ["wgsl"] roots = [] comment-token = "//" indent = { tab-width = 4, unit = " " } + +[[language]] +name = "llvm" +scope = "source.llvm" +roots = [] +file-types = ["ll"] +comment-token = ";" +indent = { tab-width = 2, unit = " " } diff --git a/runtime/queries/llvm/highlights.scm b/runtime/queries/llvm/highlights.scm new file mode 100644 index 00000000..73afe85e --- /dev/null +++ b/runtime/queries/llvm/highlights.scm @@ -0,0 +1,14 @@ +(type) @type +(statement) @keyword.operator +(number) @constant.numeric.integer +(comment) @comment +(string) @string +(label) @label +(keyword) @keyword +"ret" @keyword.control.return +(boolean) @constant.builtin.boolean +(float) @constant.numeric.float +(constant) @constant +(identifier) @variable +(symbol) @punctuation.delimiter +(bracket) @punctuation.bracket -- cgit v1.2.3-70-g09d2 From 4f9390a435a44578bcedf1da63ea1fad92185afc Mon Sep 17 00:00:00 2001 From: Bob Date: Mon, 29 Nov 2021 09:53:29 +0800 Subject: gf as goto_file (#1102) * goto_file * support goto_file under current cursor * add C-w f/F * sync space w with window mode * Update helix-term/src/commands.rs Co-authored-by: Blaž Hrastnik --- book/src/keymap.md | 3 +++ helix-term/src/commands.rs | 46 ++++++++++++++++++++++++++++++++++++++++++++++ helix-term/src/keymap.rs | 5 +++++ 3 files changed, 54 insertions(+) (limited to 'book/src') diff --git a/book/src/keymap.md b/book/src/keymap.md index 5e861cfb..865a700b 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -160,6 +160,7 @@ Jumps to various locations. | ----- | ----------- | ------- | | `g` | Go to the start of the file | `goto_file_start` | | `e` | Go to the end of the file | `goto_last_line` | +| `f` | Go to files in the selection | `goto_file` | | `h` | Go to the start of the line | `goto_line_start` | | `l` | Go to the end of the line | `goto_line_end` | | `s` | Go to first non-whitespace character of the line | `goto_first_nonwhitespace` | @@ -202,6 +203,8 @@ This layer is similar to vim keybindings as kakoune does not support window. | `v`, `Ctrl-v` | Vertical right split | `vsplit` | | `s`, `Ctrl-s` | Horizontal bottom split | `hsplit` | | `h`, `Ctrl-h`, `left` | Move to left split | `jump_view_left` | +| `f` | Go to files in the selection in horizontal splits | `goto_file` | +| `F` | Go to files in the selection in vertical splits | `goto_file` | | `j`, `Ctrl-j`, `down` | Move to split below | `jump_view_down` | | `k`, `Ctrl-k`, `up` | Move to split above | `jump_view_up` | | `l`, `Ctrl-l`, `right` | Move to right split | `jump_view_right` | diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 8e57ef30..aafeb476 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -259,6 +259,9 @@ impl Command { goto_implementation, "Goto implementation", goto_file_start, "Goto file start/line", goto_file_end, "Goto file end", + goto_file, "Goto files in the selection", + goto_file_hsplit, "Goto files in the selection in horizontal splits", + goto_file_vsplit, "Goto files in the selection in vertical splits", goto_reference, "Goto references", goto_window_top, "Goto window top", goto_window_middle, "Goto window middle", @@ -835,6 +838,49 @@ fn goto_file_end(cx: &mut Context) { doc.set_selection(view.id, selection); } +fn goto_file(cx: &mut Context) { + goto_file_impl(cx, Action::Replace); +} + +fn goto_file_hsplit(cx: &mut Context) { + goto_file_impl(cx, Action::HorizontalSplit); +} + +fn goto_file_vsplit(cx: &mut Context) { + goto_file_impl(cx, Action::VerticalSplit); +} + +fn goto_file_impl(cx: &mut Context, action: Action) { + let (view, doc) = current_ref!(cx.editor); + let text = doc.text(); + let selections = doc.selection(view.id); + let mut paths: Vec<_> = selections + .iter() + .map(|r| text.slice(r.from()..r.to()).to_string()) + .collect(); + let primary = selections.primary(); + if selections.len() == 1 && primary.to() - primary.from() == 1 { + let current_word = movement::move_next_long_word_start( + text.slice(..), + movement::move_prev_long_word_start(text.slice(..), primary, 1), + 1, + ); + paths.clear(); + paths.push( + text.slice(current_word.from()..current_word.to()) + .to_string(), + ); + } + for sel in paths { + let p = sel.trim(); + if !p.is_empty() { + if let Err(e) = cx.editor.open(PathBuf::from(p), action) { + cx.editor.set_error(format!("Open file failed: {:?}", e)); + } + } + } +} + fn extend_word_impl(cx: &mut Context, extend_fn: F) where F: Fn(RopeSlice, Range, usize) -> Range, diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index 0062e636..06639dcd 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -512,6 +512,7 @@ impl Default for Keymaps { "g" => { "Goto" "g" => goto_file_start, "e" => goto_last_line, + "f" => goto_file, "h" => goto_line_start, "l" => goto_line_end, "s" => goto_first_nonwhitespace, @@ -622,6 +623,8 @@ impl Default for Keymaps { "C-w" | "w" => rotate_view, "C-s" | "s" => hsplit, "C-v" | "v" => vsplit, + "f" => goto_file_hsplit, + "F" => goto_file_vsplit, "C-q" | "q" => wclose, "C-o" | "o" => wonly, "C-h" | "h" | "left" => jump_view_left, @@ -650,6 +653,8 @@ impl Default for Keymaps { "C-w" | "w" => rotate_view, "C-s" | "s" => hsplit, "C-v" | "v" => vsplit, + "f" => goto_file_hsplit, + "F" => goto_file_vsplit, "C-q" | "q" => wclose, "C-o" | "o" => wonly, "C-h" | "h" | "left" => jump_view_left, -- cgit v1.2.3-70-g09d2 From 6204c385561287b9586ed99d8e61c515243d50e2 Mon Sep 17 00:00:00 2001 From: Nicholas Boyd Isacsson Date: Mon, 29 Nov 2021 13:07:32 +0100 Subject: Remove defunct helix-bin AUR link --- book/src/install.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'book/src') diff --git a/book/src/install.md b/book/src/install.md index b9febbcc..d831934c 100644 --- a/book/src/install.md +++ b/book/src/install.md @@ -25,9 +25,7 @@ shell for working on Helix. Releases are available in the `community` repository. -Packages are also available on AUR: -- [helix-bin](https://aur.archlinux.org/packages/helix-bin/) contains the pre-built release -- [helix-git](https://aur.archlinux.org/packages/helix-git/) builds the master branch +A [helix-git](https://aur.archlinux.org/packages/helix-git/) package is also available on the AUR, which builds the master branch. ## Build from source -- cgit v1.2.3-70-g09d2 From 3e15aead4adc5139417230d15b38112cdc4f7043 Mon Sep 17 00:00:00 2001 From: George Rodrigues Date: Tue, 30 Nov 2021 21:11:25 -0300 Subject: Fix typo on docs (#1201) --- book/src/guides/adding_languages.md | 2 +- helix-core/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'book/src') diff --git a/book/src/guides/adding_languages.md b/book/src/guides/adding_languages.md index 446eb479..9ad2c285 100644 --- a/book/src/guides/adding_languages.md +++ b/book/src/guides/adding_languages.md @@ -2,7 +2,7 @@ ## Submodules -To add a new langauge, you should first add a tree-sitter submodule. To do this, +To add a new language, you should first add a tree-sitter submodule. To do this, you can run the command ```sh git submodule add -f helix-syntax/languages/tree-sitter- diff --git a/helix-core/src/lib.rs b/helix-core/src/lib.rs index de7e95c1..8ef41ef3 100644 --- a/helix-core/src/lib.rs +++ b/helix-core/src/lib.rs @@ -158,7 +158,7 @@ mod merge_toml_tests { "; let base: Value = toml::from_slice(include_bytes!("../../languages.toml")) - .expect("Couldn't parse built-in langauges config"); + .expect("Couldn't parse built-in languages config"); let user: Value = toml::from_str(USER).unwrap(); let merged = merge_toml_values(base, user); -- cgit v1.2.3-70-g09d2 From e2b428cc2d23965ab7a91809c5705ede0298107d Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Thu, 2 Dec 2021 12:46:57 +0800 Subject: Add last modified file (gm) (#1093) --- book/src/keymap.md | 3 ++- helix-term/src/commands.rs | 19 +++++++++++++++++-- helix-term/src/keymap.rs | 3 ++- helix-view/src/document.rs | 6 ++++++ helix-view/src/editor.rs | 14 ++++++++++++-- helix-view/src/view.rs | 6 ++++++ 6 files changed, 45 insertions(+), 6 deletions(-) (limited to 'book/src') diff --git a/book/src/keymap.md b/book/src/keymap.md index 865a700b..59353db9 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -165,13 +165,14 @@ Jumps to various locations. | `l` | Go to the end of the line | `goto_line_end` | | `s` | Go to first non-whitespace character of the line | `goto_first_nonwhitespace` | | `t` | Go to the top of the screen | `goto_window_top` | -| `m` | Go to the middle of the screen | `goto_window_middle` | +| `c` | Go to the middle of the screen | `goto_window_center` | | `b` | Go to the bottom of the screen | `goto_window_bottom` | | `d` | Go to definition (**LSP**) | `goto_definition` | | `y` | Go to type definition (**LSP**) | `goto_type_definition` | | `r` | Go to references (**LSP**) | `goto_reference` | | `i` | Go to implementation (**LSP**) | `goto_implementation` | | `a` | Go to the last accessed/alternate file | `goto_last_accessed_file` | +| `m` | Go to the last modified/alternate file | `goto_last_modified_file` | | `n` | Go to next buffer | `goto_next_buffer` | | `p` | Go to previous buffer | `goto_previous_buffer` | | `.` | Go to last modification in current file | `goto_last_modification` | diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 4a389429..a50b16f3 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -264,9 +264,10 @@ impl Command { goto_file_vsplit, "Goto files in the selection in vertical splits", goto_reference, "Goto references", goto_window_top, "Goto window top", - goto_window_middle, "Goto window middle", + goto_window_center, "Goto window center", goto_window_bottom, "Goto window bottom", goto_last_accessed_file, "Goto last accessed file", + goto_last_modified_file, "Goto last modified file", goto_last_modification, "Goto last modification", goto_line, "Goto line", goto_last_line, "Goto last line", @@ -763,7 +764,7 @@ fn goto_window_top(cx: &mut Context) { goto_window(cx, Align::Top) } -fn goto_window_middle(cx: &mut Context) { +fn goto_window_center(cx: &mut Context) { goto_window(cx, Align::Center) } @@ -3610,6 +3611,20 @@ fn goto_last_modification(cx: &mut Context) { } } +fn goto_last_modified_file(cx: &mut Context) { + let view = view!(cx.editor); + let alternate_file = view + .last_modified_docs + .into_iter() + .flatten() + .find(|&id| id != view.doc); + if let Some(alt) = alternate_file { + cx.editor.switch(alt, Action::Replace); + } else { + cx.editor.set_error("no last modified buffer".to_owned()) + } +} + fn select_mode(cx: &mut Context) { let (view, doc) = current!(cx.editor); let text = doc.text().slice(..); diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index 06639dcd..73cb15f8 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -521,9 +521,10 @@ impl Default for Keymaps { "r" => goto_reference, "i" => goto_implementation, "t" => goto_window_top, - "m" => goto_window_middle, + "c" => goto_window_center, "b" => goto_window_bottom, "a" => goto_last_accessed_file, + "m" => goto_last_modified_file, "n" => goto_next_buffer, "p" => goto_previous_buffer, "." => goto_last_modification, diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index 76b19a07..2cb33fe3 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -104,6 +104,7 @@ pub struct Document { last_saved_revision: usize, version: i32, // should be usize? + pub(crate) modified_since_accessed: bool, diagnostics: Vec, language_server: Option>, @@ -127,6 +128,7 @@ impl fmt::Debug for Document { // .field("history", &self.history) .field("last_saved_revision", &self.last_saved_revision) .field("version", &self.version) + .field("modified_since_accessed", &self.modified_since_accessed) .field("diagnostics", &self.diagnostics) // .field("language_server", &self.language_server) .finish() @@ -344,6 +346,7 @@ impl Document { history: Cell::new(History::default()), savepoint: None, last_saved_revision: 0, + modified_since_accessed: false, language_server: None, } } @@ -639,6 +642,9 @@ impl Document { selection.clone().ensure_invariants(self.text.slice(..)), ); } + + // set modified since accessed + self.modified_since_accessed = true; } if !transaction.changes().is_empty() { diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index d5913a51..9034d12c 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -369,7 +369,8 @@ impl Editor { .tree .traverse() .any(|(_, v)| v.doc == doc.id && v.id != view.id); - let view = view_mut!(self); + + let (view, doc) = current!(self); if remove_empty_scratch { // Copy `doc.id` into a variable before calling `self.documents.remove`, which requires a mutable // borrow, invalidating direct access to `doc.id`. @@ -378,7 +379,16 @@ impl Editor { } else { let jump = (view.doc, doc.selection(view.id).clone()); view.jumps.push(jump); - view.last_accessed_doc = Some(view.doc); + // Set last accessed doc if it is a different document + if doc.id != id { + view.last_accessed_doc = Some(view.doc); + // Set last modified doc if modified and last modified doc is different + if std::mem::take(&mut doc.modified_since_accessed) + && view.last_modified_docs[0] != Some(id) + { + view.last_modified_docs = [Some(view.doc), view.last_modified_docs[0]]; + } + } } let view_id = view.id; diff --git a/helix-view/src/view.rs b/helix-view/src/view.rs index 217a4940..94d67acd 100644 --- a/helix-view/src/view.rs +++ b/helix-view/src/view.rs @@ -75,6 +75,11 @@ pub struct View { pub jumps: JumpList, /// the last accessed file before the current one pub last_accessed_doc: Option, + /// the last modified files before the current one + /// ordered from most frequent to least frequent + // uses two docs because we want to be able to swap between the + // two last modified docs which we need to manually keep track of + pub last_modified_docs: [Option; 2], } impl View { @@ -86,6 +91,7 @@ impl View { area: Rect::default(), // will get calculated upon inserting into tree jumps: JumpList::new((doc, Selection::point(0))), // TODO: use actual sel last_accessed_doc: None, + last_modified_docs: [None, None], } } -- cgit v1.2.3-70-g09d2 From cab09093dd5bf9b4707bfdfd8529b348c02670ea Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Mon, 6 Dec 2021 12:24:25 +0900 Subject: fix: Normalize backtab into shift-tab Fixes #1150 --- book/src/remapping.md | 5 ++--- helix-term/src/ui/menu.rs | 2 +- helix-term/src/ui/picker.rs | 2 +- helix-term/src/ui/prompt.rs | 2 +- helix-view/src/input.rs | 24 ++++++++++++++---------- helix-view/src/keyboard.rs | 5 +---- 6 files changed, 20 insertions(+), 20 deletions(-) (limited to 'book/src') diff --git a/book/src/remapping.md b/book/src/remapping.md index fffd189b..ad63b60b 100644 --- a/book/src/remapping.md +++ b/book/src/remapping.md @@ -42,10 +42,9 @@ Control, Shift and Alt modifiers are encoded respectively with the prefixes | Down | `"down"` | | Home | `"home"` | | End | `"end"` | -| Page | `"pageup"` | -| Page | `"pagedown"` | +| Page Up | `"pageup"` | +| Page Down | `"pagedown"` | | Tab | `"tab"` | -| Back | `"backtab"` | | Delete | `"del"` | | Insert | `"ins"` | | Null | `"null"` | diff --git a/helix-term/src/ui/menu.rs b/helix-term/src/ui/menu.rs index e891c149..9a885a36 100644 --- a/helix-term/src/ui/menu.rs +++ b/helix-term/src/ui/menu.rs @@ -202,7 +202,7 @@ impl Component for Menu { return close_fn; } // arrow up/ctrl-p/shift-tab prev completion choice (including updating the doc) - shift!(BackTab) | key!(Up) | ctrl!('p') | ctrl!('k') => { + shift!(Tab) | key!(Up) | ctrl!('p') | ctrl!('k') => { self.move_up(); (self.callback_fn)(cx.editor, self.selection(), MenuEvent::Update); return EventResult::Consumed(None); diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs index 16bf08a3..1c963f97 100644 --- a/helix-term/src/ui/picker.rs +++ b/helix-term/src/ui/picker.rs @@ -410,7 +410,7 @@ impl Component for Picker { }))); match key_event.into() { - shift!(BackTab) | key!(Up) | ctrl!('p') | ctrl!('k') => { + shift!(Tab) | key!(Up) | ctrl!('p') | ctrl!('k') => { self.move_up(); } key!(Tab) | key!(Down) | ctrl!('n') | ctrl!('j') => { diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs index e90b0772..a7ef231c 100644 --- a/helix-term/src/ui/prompt.rs +++ b/helix-term/src/ui/prompt.rs @@ -505,7 +505,7 @@ impl Component for Prompt { self.change_completion_selection(CompletionDirection::Forward); (self.callback_fn)(cx, &self.line, PromptEvent::Update) } - shift!(BackTab) => { + shift!(Tab) => { self.change_completion_selection(CompletionDirection::Backward); (self.callback_fn)(cx, &self.line, PromptEvent::Update) } diff --git a/helix-view/src/input.rs b/helix-view/src/input.rs index 580204cc..b207c3ed 100644 --- a/helix-view/src/input.rs +++ b/helix-view/src/input.rs @@ -36,7 +36,6 @@ pub(crate) mod keys { pub(crate) const PAGEUP: &str = "pageup"; pub(crate) const PAGEDOWN: &str = "pagedown"; pub(crate) const TAB: &str = "tab"; - pub(crate) const BACKTAB: &str = "backtab"; pub(crate) const DELETE: &str = "del"; pub(crate) const INSERT: &str = "ins"; pub(crate) const NULL: &str = "null"; @@ -82,7 +81,6 @@ impl fmt::Display for KeyEvent { KeyCode::PageUp => f.write_str(keys::PAGEUP)?, KeyCode::PageDown => f.write_str(keys::PAGEDOWN)?, KeyCode::Tab => f.write_str(keys::TAB)?, - KeyCode::BackTab => f.write_str(keys::BACKTAB)?, KeyCode::Delete => f.write_str(keys::DELETE)?, KeyCode::Insert => f.write_str(keys::INSERT)?, KeyCode::Null => f.write_str(keys::NULL)?, @@ -116,7 +114,6 @@ impl UnicodeWidthStr for KeyEvent { KeyCode::PageUp => keys::PAGEUP.len(), KeyCode::PageDown => keys::PAGEDOWN.len(), KeyCode::Tab => keys::TAB.len(), - KeyCode::BackTab => keys::BACKTAB.len(), KeyCode::Delete => keys::DELETE.len(), KeyCode::Insert => keys::INSERT.len(), KeyCode::Null => keys::NULL.len(), @@ -166,7 +163,6 @@ impl std::str::FromStr for KeyEvent { keys::PAGEUP => KeyCode::PageUp, keys::PAGEDOWN => KeyCode::PageDown, keys::TAB => KeyCode::Tab, - keys::BACKTAB => KeyCode::BackTab, keys::DELETE => KeyCode::Delete, keys::INSERT => KeyCode::Insert, keys::NULL => KeyCode::Null, @@ -220,12 +216,20 @@ impl<'de> Deserialize<'de> for KeyEvent { #[cfg(feature = "term")] impl From for KeyEvent { - fn from( - crossterm::event::KeyEvent { code, modifiers }: crossterm::event::KeyEvent, - ) -> KeyEvent { - KeyEvent { - code: code.into(), - modifiers: modifiers.into(), + fn from(crossterm::event::KeyEvent { code, modifiers }: crossterm::event::KeyEvent) -> Self { + if code == crossterm::event::KeyCode::BackTab { + // special case for BackTab -> Shift-Tab + let mut modifiers: KeyModifiers = modifiers.into(); + modifiers.insert(KeyModifiers::SHIFT); + Self { + code: KeyCode::Tab, + modifiers, + } + } else { + Self { + code: code.into(), + modifiers: modifiers.into(), + } } } } diff --git a/helix-view/src/keyboard.rs b/helix-view/src/keyboard.rs index 810aa063..f1717209 100644 --- a/helix-view/src/keyboard.rs +++ b/helix-view/src/keyboard.rs @@ -79,8 +79,6 @@ pub enum KeyCode { PageDown, /// Tab key. Tab, - /// Shift + Tab key. - BackTab, /// Delete key. Delete, /// Insert key. @@ -116,7 +114,6 @@ impl From for crossterm::event::KeyCode { KeyCode::PageUp => CKeyCode::PageUp, KeyCode::PageDown => CKeyCode::PageDown, KeyCode::Tab => CKeyCode::Tab, - KeyCode::BackTab => CKeyCode::BackTab, KeyCode::Delete => CKeyCode::Delete, KeyCode::Insert => CKeyCode::Insert, KeyCode::F(f_number) => CKeyCode::F(f_number), @@ -144,7 +141,7 @@ impl From for KeyCode { CKeyCode::PageUp => KeyCode::PageUp, CKeyCode::PageDown => KeyCode::PageDown, CKeyCode::Tab => KeyCode::Tab, - CKeyCode::BackTab => KeyCode::BackTab, + CKeyCode::BackTab => unreachable!("BackTab should have been handled on KeyEvent level"), CKeyCode::Delete => KeyCode::Delete, CKeyCode::Insert => KeyCode::Insert, CKeyCode::F(f_number) => KeyCode::F(f_number), -- cgit v1.2.3-70-g09d2 From 178cd5ecfc75280ae12810cf3c0aeb22284bfdf2 Mon Sep 17 00:00:00 2001 From: Omnikar Date: Mon, 6 Dec 2021 11:44:50 -0500 Subject: Add note to `keymap.md` regarding `format_selections` (#1230) --- book/src/keymap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'book/src') diff --git a/book/src/keymap.md b/book/src/keymap.md index 59353db9..e1b1bad8 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -69,7 +69,7 @@ | `"` `` | Select a register to yank to or paste from | `select_register` | | `>` | Indent selection | `indent` | | `<` | Unindent selection | `unindent` | -| `=` | Format selection (**LSP**) | `format_selections` | +| `=` | Format selection (currently nonfunctional/disabled) (**LSP**) | `format_selections` | | `d` | Delete selection | `delete_selection` | | `Alt-d` | Delete selection, without yanking | `delete_selection_noyank` | | `c` | Change selection (delete and enter insert mode) | `change_selection` | -- cgit v1.2.3-70-g09d2 From 71292f9f11bd2b50568efd111239f693be26a36a Mon Sep 17 00:00:00 2001 From: Gokul Soumya Date: Wed, 17 Nov 2021 19:00:11 +0530 Subject: docs: Auto generate command list --- .cargo/config | 2 + Cargo.lock | 7 ++++ Cargo.toml | 1 + README.md | 16 +------- book/src/SUMMARY.md | 3 +- book/src/commands.md | 5 +++ book/src/generated/typable-cmd.md | 43 ++++++++++++++++++++ docs/CONTRIBUTING.md | 37 +++++++++++++++++ helix-term/src/commands.rs | 8 ++-- xtask/Cargo.toml | 9 ++++ xtask/src/main.rs | 86 +++++++++++++++++++++++++++++++++++++++ 11 files changed, 197 insertions(+), 20 deletions(-) create mode 100644 .cargo/config create mode 100644 book/src/commands.md create mode 100644 book/src/generated/typable-cmd.md create mode 100644 docs/CONTRIBUTING.md create mode 100644 xtask/Cargo.toml create mode 100644 xtask/src/main.rs (limited to 'book/src') diff --git a/.cargo/config b/.cargo/config new file mode 100644 index 00000000..35049cbc --- /dev/null +++ b/.cargo/config @@ -0,0 +1,2 @@ +[alias] +xtask = "run --package xtask --" diff --git a/Cargo.lock b/Cargo.lock index 47a6c01e..b3032465 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1259,3 +1259,10 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "xtask" +version = "0.5.0" +dependencies = [ + "helix-term", +] diff --git a/Cargo.toml b/Cargo.toml index 580cccd6..8c3ee671 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ members = [ "helix-tui", "helix-syntax", "helix-lsp", + "xtask", ] # Build helix-syntax in release mode to make the code path faster in development. diff --git a/README.md b/README.md index 3f4087b9..f651e30c 100644 --- a/README.md +++ b/README.md @@ -65,21 +65,7 @@ brew install helix # Contributing -Contributors are very welcome! **No contribution is too small and all contributions are valued.** - -Some suggestions to get started: - -- You can look at the [good first issue](https://github.com/helix-editor/helix/issues?q=is%3Aopen+label%3AE-easy+label%3AE-good-first-issue) label on the issue tracker. -- Help with packaging on various distributions needed! -- To use print debugging to the [Helix log file](https://github.com/helix-editor/helix/wiki/FAQ#access-the-log-file), you must: - * Print using `log::info!`, `warn!`, or `error!`. (`log::info!("helix!")`) - * Pass the appropriate verbosity level option for the desired log level. (`hx -v ` for info, more `v`s for higher severity inclusive) -- If your preferred language is missing, integrating a tree-sitter grammar for - it and defining syntax highlight queries for it is straight forward and - doesn't require much knowledge of the internals. - -We provide an [architecture.md](./docs/architecture.md) that should give you -a good overview of the internals. +Contributing guidelines can be found [here](./docs/CONTRIBUTING.md). # Getting help diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index 8cadb663..4da79925 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -2,10 +2,11 @@ - [Installation](./install.md) - [Usage](./usage.md) + - [Keymap](./keymap.md) + - [Commands](./commands.md) - [Migrating from Vim](./from-vim.md) - [Configuration](./configuration.md) - [Themes](./themes.md) - - [Keymap](./keymap.md) - [Key Remapping](./remapping.md) - [Hooks](./hooks.md) - [Languages](./languages.md) diff --git a/book/src/commands.md b/book/src/commands.md new file mode 100644 index 00000000..4c4a5c05 --- /dev/null +++ b/book/src/commands.md @@ -0,0 +1,5 @@ +# Commands + +Command mode can be activated by pressing `:`, similar to vim. Built-in commands: + +{{#include ./generated/typable-cmd.md}} diff --git a/book/src/generated/typable-cmd.md b/book/src/generated/typable-cmd.md new file mode 100644 index 00000000..5de5c787 --- /dev/null +++ b/book/src/generated/typable-cmd.md @@ -0,0 +1,43 @@ +| Name | Description | +| --- | --- | +| `:quit`, `:q` | Close the current view. | +| `:quit!`, `:q!` | Close the current view forcefully (ignoring unsaved changes). | +| `:open`, `:o` | Open a file from disk into the current view. | +| `:buffer-close`, `:bc`, `:bclose` | Close the current buffer. | +| `:buffer-close!`, `:bc!`, `:bclose!` | Close the current buffer forcefully (ignoring unsaved changes). | +| `:write`, `:w` | Write changes to disk. Accepts an optional path (:write some/path.txt) | +| `:new`, `:n` | Create a new scratch buffer. | +| `:format`, `:fmt` | Format the file using the LSP formatter. | +| `:indent-style` | Set the indentation style for editing. ('t' for tabs or 1-8 for number of spaces.) | +| `:line-ending` | Set the document's default line ending. Options: crlf, lf, cr, ff, nel. | +| `:earlier`, `:ear` | Jump back to an earlier point in edit history. Accepts a number of steps or a time span. | +| `:later`, `:lat` | Jump to a later point in edit history. Accepts a number of steps or a time span. | +| `:write-quit`, `:wq`, `:x` | Write changes to disk and close the current view. Accepts an optional path (:wq some/path.txt) | +| `:write-quit!`, `:wq!`, `:x!` | Write changes to disk and close the current view forcefully. Accepts an optional path (:wq! some/path.txt) | +| `:write-all`, `:wa` | Write changes from all views to disk. | +| `:write-quit-all`, `:wqa`, `:xa` | Write changes from all views to disk and close all views. | +| `:write-quit-all!`, `:wqa!`, `:xa!` | Write changes from all views to disk and close all views forcefully (ignoring unsaved changes). | +| `:quit-all`, `:qa` | Close all views. | +| `:quit-all!`, `:qa!` | Close all views forcefully (ignoring unsaved changes). | +| `:cquit`, `:cq` | Quit with exit code (default 1). Accepts an optional integer exit code (:cq 2). | +| `:theme` | Change the editor theme. | +| `:clipboard-yank` | Yank main selection into system clipboard. | +| `:clipboard-yank-join` | Yank joined selections into system clipboard. A separator can be provided as first argument. Default value is newline. | +| `:primary-clipboard-yank` | Yank main selection into system primary clipboard. | +| `:primary-clipboard-yank-join` | Yank joined selections into system primary clipboard. A separator can be provided as first argument. Default value is newline. | +| `:clipboard-paste-after` | Paste system clipboard after selections. | +| `:clipboard-paste-before` | Paste system clipboard before selections. | +| `:clipboard-paste-replace` | Replace selections with content of system clipboard. | +| `:primary-clipboard-paste-after` | Paste primary clipboard after selections. | +| `:primary-clipboard-paste-before` | Paste primary clipboard before selections. | +| `:primary-clipboard-paste-replace` | Replace selections with content of system primary clipboard. | +| `:show-clipboard-provider` | Show clipboard provider name in status bar. | +| `:change-current-directory`, `:cd` | Change the current working directory. | +| `:show-directory`, `:pwd` | Show the current working directory. | +| `:encoding` | Set encoding based on `https://encoding.spec.whatwg.org` | +| `:reload` | Discard changes and reload from the source file. | +| `:tree-sitter-scopes` | Display tree sitter scopes, primarily for theming and development. | +| `:vsplit`, `:vs` | Open the file in a vertical split. | +| `:hsplit`, `:hs`, `:sp` | Open the file in a horizontal split. | +| `:tutor` | Open the tutorial. | +| `:goto`, `:g` | Go to line number. | diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md new file mode 100644 index 00000000..7b923db8 --- /dev/null +++ b/docs/CONTRIBUTING.md @@ -0,0 +1,37 @@ +# Contributing + +Contributors are very welcome! **No contribution is too small and all contributions are valued.** + +Some suggestions to get started: + +- You can look at the [good first issue][good-first-issue] label on the issue tracker. +- Help with packaging on various distributions needed! +- To use print debugging to the [Helix log file][log-file], you must: + * Print using `log::info!`, `warn!`, or `error!`. (`log::info!("helix!")`) + * Pass the appropriate verbosity level option for the desired log level. (`hx -v ` for info, more `v`s for higher severity inclusive) +- If your preferred language is missing, integrating a tree-sitter grammar for + it and defining syntax highlight queries for it is straight forward and + doesn't require much knowledge of the internals. + +We provide an [architecture.md][architecture.md] that should give you +a good overview of the internals. + +# Auto generated documentation + +Some parts of [the book][docs] are autogenerated from the code itself, +like the list of `:commands` and supported languages. To generate these +files, run + +```shell +cargo xtask bookgen +``` + +inside the project. We use [xtask][xtask] as an ad-hoc task runner and +thus do not require any dependencies other than `cargo` (You don't have +to `cargo install` anything either). + +[good-first-issue]: https://github.com/helix-editor/helix/labels/E-easy +[log-file]: https://github.com/helix-editor/helix/wiki/FAQ#access-the-log-file +[architecture.md]: ./architecture.md +[docs]: https://docs.helix-editor.com/ +[xtask]: https://github.com/matklad/cargo-xtask diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 3e7ce712..4910790a 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -1949,7 +1949,7 @@ fn append_mode(cx: &mut Context) { doc.set_selection(view.id, selection); } -mod cmd { +pub mod cmd { use super::*; use std::collections::HashMap; @@ -2679,7 +2679,7 @@ mod cmd { TypableCommand { name: "format", aliases: &["fmt"], - doc: "Format the file using a formatter.", + doc: "Format the file using the LSP formatter.", fun: format, completer: None, }, @@ -2770,7 +2770,7 @@ mod cmd { TypableCommand { name: "theme", aliases: &[], - doc: "Change the theme of current view. Requires theme name as argument (:theme )", + doc: "Change the editor theme.", fun: theme, completer: Some(completers::theme), }, @@ -2854,7 +2854,7 @@ mod cmd { TypableCommand { name: "change-current-directory", aliases: &["cd"], - doc: "Change the current working directory (:cd ).", + doc: "Change the current working directory.", fun: change_current_directory, completer: Some(completers::directory), }, diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml new file mode 100644 index 00000000..cb890de9 --- /dev/null +++ b/xtask/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "xtask" +version = "0.5.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +helix-term = { version = "0.5", path = "../helix-term" } diff --git a/xtask/src/main.rs b/xtask/src/main.rs new file mode 100644 index 00000000..4bf0ae9f --- /dev/null +++ b/xtask/src/main.rs @@ -0,0 +1,86 @@ +use std::env; + +pub mod md_gen { + use super::path; + use std::fs; + + use helix_term::commands::cmd::TYPABLE_COMMAND_LIST; + + pub const TYPABLE_COMMANDS_MD_OUTPUT: &str = "typable-cmd.md"; + + pub fn typable_commands() -> String { + let mut md = String::new(); + md.push_str("| Name | Description |\n"); + md.push_str("| --- | --- |\n"); + + let cmdify = |s: &str| format!("`:{}`", s); + + for cmd in TYPABLE_COMMAND_LIST { + let names = std::iter::once(&cmd.name) + .chain(cmd.aliases.iter()) + .map(|a| cmdify(a)) + .collect::>() + .join(", "); + + let entry = format!("| {} | {} |\n", names, cmd.doc); + md.push_str(&entry); + } + + md + } + + pub fn write(filename: &str, data: &str) { + let error = format!("Could not write to {}", filename); + let path = path::book_gen().join(filename); + fs::write(path, data).expect(&error); + } +} + +pub mod path { + use std::path::{Path, PathBuf}; + + pub fn project_root() -> PathBuf { + Path::new(env!("CARGO_MANIFEST_DIR")) + .parent() + .unwrap() + .to_path_buf() + } + + pub fn book_gen() -> PathBuf { + project_root().join("book/src/generated/") + } +} + +pub mod tasks { + use super::md_gen; + + pub fn bookgen() { + md_gen::write( + md_gen::TYPABLE_COMMANDS_MD_OUTPUT, + &md_gen::typable_commands(), + ); + } + + pub fn print_help() { + println!( + " +Usage: Run with `cargo xtask `, eg. `cargo xtask bookgen`. + + Tasks: + bookgen: Generate files to be included in the mdbook output. +" + ); + } +} + +fn main() -> Result<(), String> { + let task = env::args().nth(1); + match task { + None => tasks::print_help(), + Some(t) => match t.as_str() { + "bookgen" => tasks::bookgen(), + invalid => return Err(format!("Invalid task name: {}", invalid)), + }, + }; + Ok(()) +} -- cgit v1.2.3-70-g09d2 From a78b7894066b6ccf56c404b7543b45e2dfd99982 Mon Sep 17 00:00:00 2001 From: Gokul Soumya Date: Mon, 22 Nov 2021 00:25:08 +0530 Subject: Auto generate docs for language support --- Cargo.lock | 2 + book/src/SUMMARY.md | 1 + book/src/generated/lang-support.md | 41 +++++++ book/src/generated/typable-cmd.md | 2 +- book/src/lang-support.md | 10 ++ docs/CONTRIBUTING.md | 2 +- helix-core/src/indent.rs | 1 + helix-core/src/syntax.rs | 3 +- languages.toml | 40 +++++++ xtask/Cargo.toml | 2 + xtask/src/main.rs | 229 ++++++++++++++++++++++++++++++++++--- 11 files changed, 311 insertions(+), 22 deletions(-) create mode 100644 book/src/generated/lang-support.md create mode 100644 book/src/lang-support.md (limited to 'book/src') diff --git a/Cargo.lock b/Cargo.lock index b3032465..25b4f6cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1264,5 +1264,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" name = "xtask" version = "0.5.0" dependencies = [ + "helix-core", "helix-term", + "toml", ] diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index 4da79925..a8f165c0 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -4,6 +4,7 @@ - [Usage](./usage.md) - [Keymap](./keymap.md) - [Commands](./commands.md) + - [Language Support](./lang-support.md) - [Migrating from Vim](./from-vim.md) - [Configuration](./configuration.md) - [Themes](./themes.md) diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md new file mode 100644 index 00000000..729801ad --- /dev/null +++ b/book/src/generated/lang-support.md @@ -0,0 +1,41 @@ +| Language | Syntax Highlighting | Treesitter Textobjects | Auto Indent | Default LSP | +| --- | --- | --- | --- | --- | +| Bash | ✓ | | | `bash-language-server` | +| C | ✓ | | | `clangd` | +| C# | ✓ | | | | +| CMake | ✓ | | | `cmake-language-server` | +| C++ | ✓ | | | `clangd` | +| CSS | ✓ | | | | +| Elixir | ✓ | | | `elixir-ls` | +| GLSL | ✓ | | ✓ | | +| Go | ✓ | ✓ | ✓ | `gopls` | +| HTML | ✓ | | | | +| Java | ✓ | | | | +| JavaScript | ✓ | | ✓ | | +| JSON | ✓ | | ✓ | | +| Julia | ✓ | | | `julia` | +| LaTeX | ✓ | | | | +| Ledger | ✓ | | | | +| LLVM | ✓ | | | | +| Lua | ✓ | | ✓ | | +| Mint | | | | `mint` | +| Nix | ✓ | | ✓ | `rnix-lsp` | +| OCaml | ✓ | | ✓ | | +| OCaml-Interface | ✓ | | | | +| Perl | ✓ | ✓ | | | +| PHP | ✓ | | ✓ | | +| Prolog | | | | `swipl` | +| Protobuf | ✓ | | ✓ | | +| Python | ✓ | ✓ | ✓ | `pylsp` | +| Racket | | | | `racket` | +| Ruby | ✓ | | | `solargraph` | +| Rust | ✓ | ✓ | ✓ | `rust-analyzer` | +| Svelte | ✓ | | ✓ | `svelteserver` | +| TOML | ✓ | | | | +| TSQ | ✓ | | | | +| TSX | ✓ | | | `typescript-language-server` | +| TypeScript | ✓ | | ✓ | `typescript-language-server` | +| Vue | ✓ | | | | +| WGSL | ✓ | | | | +| YAML | ✓ | | ✓ | | +| Zig | ✓ | | ✓ | `zls` | diff --git a/book/src/generated/typable-cmd.md b/book/src/generated/typable-cmd.md index 5de5c787..bb21fd6b 100644 --- a/book/src/generated/typable-cmd.md +++ b/book/src/generated/typable-cmd.md @@ -1,5 +1,5 @@ | Name | Description | -| --- | --- | +| --- | --- | | `:quit`, `:q` | Close the current view. | | `:quit!`, `:q!` | Close the current view forcefully (ignoring unsaved changes). | | `:open`, `:o` | Open a file from disk into the current view. | diff --git a/book/src/lang-support.md b/book/src/lang-support.md new file mode 100644 index 00000000..3920f342 --- /dev/null +++ b/book/src/lang-support.md @@ -0,0 +1,10 @@ +# Language Support + +For more information like arguments passed to default LSP server, +extensions assosciated with a filetype, custom LSP settings, filetype +specific indent settings, etc see the default +[`languages.toml`][languages.toml] file. + +{{#include ./generated/lang-support.md}} + +[languages.toml]: https://github.com/helix-editor/helix/blob/master/languages.toml diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 7b923db8..bdd771aa 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -23,7 +23,7 @@ like the list of `:commands` and supported languages. To generate these files, run ```shell -cargo xtask bookgen +cargo xtask docgen ``` inside the project. We use [xtask][xtask] as an ad-hoc task runner and diff --git a/helix-core/src/indent.rs b/helix-core/src/indent.rs index b6f5081a..3ce3620a 100644 --- a/helix-core/src/indent.rs +++ b/helix-core/src/indent.rs @@ -452,6 +452,7 @@ where file_types: vec!["rs".to_string()], shebangs: vec![], language_id: "Rust".to_string(), + display_name: "Rust".to_string(), highlight_config: OnceCell::new(), config: None, // diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index ba78adaa..3c65ae33 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -50,7 +50,8 @@ pub struct Configuration { #[serde(rename_all = "kebab-case", deny_unknown_fields)] pub struct LanguageConfiguration { #[serde(rename = "name")] - pub language_id: String, + pub language_id: String, // c-sharp, rust + pub display_name: String, // C#, Rust pub scope: String, // source.rust pub file_types: Vec, // filename ends_with? #[serde(default)] diff --git a/languages.toml b/languages.toml index 4208e4b6..ca339c98 100644 --- a/languages.toml +++ b/languages.toml @@ -1,5 +1,6 @@ [[language]] name = "rust" +display-name = "Rust" scope = "source.rust" injection-regex = "rust" file-types = ["rs"] @@ -14,6 +15,7 @@ procMacro = { enable = false } [[language]] name = "toml" +display-name = "TOML" scope = "source.toml" injection-regex = "toml" file-types = ["toml"] @@ -24,6 +26,7 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "protobuf" +display-name = "Protobuf" scope = "source.proto" injection-regex = "protobuf" file-types = ["proto"] @@ -34,6 +37,7 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "elixir" +display-name = "Elixir" scope = "source.elixir" injection-regex = "elixir" file-types = ["ex", "exs"] @@ -46,6 +50,7 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "mint" +display-name = "Mint" scope = "source.mint" injection-regex = "mint" file-types = ["mint"] @@ -58,6 +63,7 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "json" +display-name = "JSON" scope = "source.json" injection-regex = "json" file-types = ["json"] @@ -67,6 +73,7 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "c" +display-name = "C" scope = "source.c" injection-regex = "c" file-types = ["c"] # TODO: ["h"] @@ -78,6 +85,7 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "cpp" +display-name = "C++" scope = "source.cpp" injection-regex = "cpp" file-types = ["cc", "hh", "cpp", "hpp", "h", "ipp", "tpp", "cxx", "hxx", "ixx", "txx", "ino"] @@ -89,6 +97,7 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "c-sharp" +display-name = "C#" scope = "source.csharp" injection-regex = "c-?sharp" file-types = ["cs"] @@ -99,6 +108,7 @@ indent = { tab-width = 4, unit = "\t" } [[language]] name = "go" +display-name = "Go" scope = "source.go" injection-regex = "go" file-types = ["go"] @@ -112,6 +122,7 @@ indent = { tab-width = 4, unit = "\t" } [[language]] name = "javascript" +display-name = "JavaScript" scope = "source.js" injection-regex = "^(js|javascript)$" file-types = ["js", "mjs"] @@ -124,6 +135,7 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "typescript" +display-name = "TypeScript" scope = "source.ts" injection-regex = "^(ts|typescript)$" file-types = ["ts"] @@ -136,6 +148,7 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "tsx" +display-name = "TSX" scope = "source.tsx" injection-regex = "^(tsx)$" # |typescript file-types = ["tsx"] @@ -147,6 +160,7 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "css" +display-name = "CSS" scope = "source.css" injection-regex = "css" file-types = ["css"] @@ -156,6 +170,7 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "html" +display-name = "HTML" scope = "text.html.basic" injection-regex = "html" file-types = ["html"] @@ -165,6 +180,7 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "python" +display-name = "Python" scope = "source.python" injection-regex = "python" file-types = ["py"] @@ -178,6 +194,7 @@ indent = { tab-width = 4, unit = " " } [[language]] name = "nix" +display-name = "Nix" scope = "source.nix" injection-regex = "nix" file-types = ["nix"] @@ -190,6 +207,7 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "ruby" +display-name = "Ruby" scope = "source.ruby" injection-regex = "ruby" file-types = ["rb"] @@ -202,6 +220,7 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "bash" +display-name = "Bash" scope = "source.bash" injection-regex = "bash" file-types = ["sh", "bash"] @@ -214,6 +233,7 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "php" +display-name = "PHP" scope = "source.php" injection-regex = "php" file-types = ["php"] @@ -224,6 +244,7 @@ indent = { tab-width = 4, unit = " " } [[language]] name = "latex" +display-name = "LaTeX" scope = "source.tex" injection-regex = "tex" file-types = ["tex"] @@ -234,6 +255,7 @@ indent = { tab-width = 4, unit = "\t" } [[language]] name = "julia" +display-name = "Julia" scope = "source.julia" injection-regex = "julia" file-types = ["jl"] @@ -259,6 +281,7 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "java" +display-name = "Java" scope = "source.java" injection-regex = "java" file-types = ["java"] @@ -267,6 +290,7 @@ indent = { tab-width = 4, unit = " " } [[language]] name = "ledger" +display-name = "Ledger" scope = "source.ledger" injection-regex = "ledger" file-types = ["ldg", "ledger", "journal"] @@ -276,6 +300,7 @@ indent = { tab-width = 4, unit = " " } [[language]] name = "ocaml" +display-name = "OCaml" scope = "source.ocaml" injection-regex = "ocaml" file-types = ["ml"] @@ -286,6 +311,7 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "ocaml-interface" +display-name = "OCaml-Interface" scope = "source.ocaml.interface" file-types = ["mli"] shebangs = [] @@ -295,6 +321,7 @@ indent = { tab-width = 2, unit = " "} [[language]] name = "lua" +display-name = "Lua" scope = "source.lua" file-types = ["lua"] shebangs = ["lua"] @@ -304,6 +331,7 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "svelte" +display-name = "Svelte" scope = "source.svelte" injection-regex = "svelte" file-types = ["svelte"] @@ -314,6 +342,7 @@ language-server = { command = "svelteserver", args = ["--stdio"] } [[language]] name = "vue" +display-name = "Vue" scope = "source.vue" injection-regex = "vue" file-types = ["vue"] @@ -322,6 +351,7 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "yaml" +display-name = "YAML" scope = "source.yaml" file-types = ["yml", "yaml"] roots = [] @@ -330,6 +360,7 @@ indent = { tab-width = 2, unit = " " } # [[language]] # name = "haskell" +# display-name = "Haskell" # scope = "source.haskell" # injection-regex = "haskell" # file-types = ["hs"] @@ -340,6 +371,7 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "zig" +display-name = "Zig" scope = "source.zig" injection-regex = "zig" file-types = ["zig"] @@ -352,6 +384,7 @@ indent = { tab-width = 4, unit = " " } [[language]] name = "prolog" +display-name = "Prolog" scope = "source.prolog" roots = [] file-types = ["pl", "prolog"] @@ -365,6 +398,7 @@ language-server = { command = "swipl", args = [ [[language]] name = "tsq" +display-name = "TSQ" scope = "source.tsq" file-types = ["scm"] roots = [] @@ -373,6 +407,7 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "cmake" +display-name = "CMake" scope = "source.cmake" file-types = ["cmake", "CMakeLists.txt"] roots = [] @@ -382,6 +417,7 @@ language-server = { command = "cmake-language-server" } [[language]] name = "glsl" +display-name = "GLSL" scope = "source.glsl" file-types = ["glsl", "vert", "tesc", "tese", "geom", "frag", "comp" ] roots = [] @@ -390,6 +426,7 @@ indent = { tab-width = 4, unit = " " } [[language]] name = "perl" +display-name = "Perl" scope = "source.perl" file-types = ["pl", "pm"] shebangs = ["perl"] @@ -399,6 +436,7 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "racket" +display-name = "Racket" scope = "source.rkt" roots = [] file-types = ["rkt"] @@ -408,6 +446,7 @@ language-server = { command = "racket", args = ["-l", "racket-langserver"] } [[language]] name = "wgsl" +display-name = "WGSL" scope = "source.wgsl" file-types = ["wgsl"] roots = [] @@ -416,6 +455,7 @@ indent = { tab-width = 4, unit = " " } [[language]] name = "llvm" +display-name = "LLVM" scope = "source.llvm" roots = [] file-types = ["ll"] diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index cb890de9..fe5d55d4 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -7,3 +7,5 @@ edition = "2021" [dependencies] helix-term = { version = "0.5", path = "../helix-term" } +helix-core = { version = "0.5", path = "../helix-core" } +toml = "0.5" diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 4bf0ae9f..37e70592 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -1,17 +1,138 @@ -use std::env; +use std::{env, error::Error}; + +type DynError = Box; + +pub mod helpers { + use std::{ + fmt::Display, + path::{Path, PathBuf}, + }; + + use crate::path; + use helix_core::syntax::Configuration as LangConfig; + + #[derive(Copy, Clone)] + pub enum TsFeature { + Highlight, + TextObjects, + AutoIndent, + } + + impl TsFeature { + pub fn all() -> &'static [Self] { + &[Self::Highlight, Self::TextObjects, Self::AutoIndent] + } + + pub fn runtime_filename(&self) -> &'static str { + match *self { + Self::Highlight => "highlights.scm", + Self::TextObjects => "textobjects.scm", + Self::AutoIndent => "indents.toml", + } + } + } + + impl Display for TsFeature { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + match *self { + Self::Highlight => "Syntax Highlighting", + Self::TextObjects => "Treesitter Textobjects", + Self::AutoIndent => "Auto Indent", + } + ) + } + } + + /// Get the list of languages that support a particular tree-sitter + /// based feature. + pub fn ts_lang_support(feat: TsFeature) -> Vec { + let queries_dir = path::ts_queries(); + + find_files(&queries_dir, feat.runtime_filename()) + .iter() + .map(|f| { + // .../helix/runtime/queries/python/highlights.scm + let tail = f.strip_prefix(&queries_dir).unwrap(); // python/highlights.scm + let lang = tail.components().next().unwrap(); // python + lang.as_os_str().to_string_lossy().to_string() + }) + .collect() + } + + /// Get the list of languages that have any form of tree-sitter + /// queries defined in the runtime directory. + pub fn langs_with_ts_queries() -> Vec { + std::fs::read_dir(path::ts_queries()) + .unwrap() + .filter_map(|entry| { + let entry = entry.ok()?; + entry + .file_type() + .ok()? + .is_dir() + .then(|| entry.file_name().to_string_lossy().to_string()) + }) + .collect() + } + + // naive implementation, but suffices for our needs + pub fn find_files(dir: &Path, filename: &str) -> Vec { + std::fs::read_dir(dir) + .unwrap() + .filter_map(|entry| { + let path = entry.ok()?.path(); + if path.is_dir() { + Some(find_files(&path, filename)) + } else { + (path.file_name()?.to_string_lossy() == filename).then(|| vec![path]) + } + }) + .flatten() + .collect() + } + + pub fn lang_config() -> LangConfig { + let bytes = std::fs::read(path::lang_config()).unwrap(); + toml::from_slice(&bytes).unwrap() + } +} pub mod md_gen { - use super::path; + use crate::DynError; + + use crate::helpers; + use crate::path; use std::fs; use helix_term::commands::cmd::TYPABLE_COMMAND_LIST; pub const TYPABLE_COMMANDS_MD_OUTPUT: &str = "typable-cmd.md"; + pub const LANG_SUPPORT_MD_OUTPUT: &str = "lang-support.md"; + + fn md_table_heading(cols: &[String]) -> String { + let mut header = String::new(); + header += &md_table_row(cols); + header += &md_table_row(&vec!["---".to_string(); cols.len()]); + header + } + + fn md_table_row(cols: &[String]) -> String { + "| ".to_owned() + &cols.join(" | ") + " |\n" + } + + fn md_mono(s: &str) -> String { + format!("`{}`", s) + } - pub fn typable_commands() -> String { + pub fn typable_commands() -> Result { let mut md = String::new(); - md.push_str("| Name | Description |\n"); - md.push_str("| --- | --- |\n"); + md.push_str(&md_table_heading(&[ + "Name".to_owned(), + "Description".to_owned(), + ])); let cmdify = |s: &str| format!("`:{}`", s); @@ -22,11 +143,72 @@ pub mod md_gen { .collect::>() .join(", "); - let entry = format!("| {} | {} |\n", names, cmd.doc); - md.push_str(&entry); + md.push_str(&md_table_row(&[names.to_owned(), cmd.doc.to_owned()])); + } + + Ok(md) + } + + pub fn lang_features() -> Result { + let mut md = String::new(); + let ts_features = helpers::TsFeature::all(); + + let mut cols = vec!["Language".to_owned()]; + cols.append( + &mut ts_features + .iter() + .map(|t| t.to_string()) + .collect::>(), + ); + cols.push("Default LSP".to_owned()); + + md.push_str(&md_table_heading(&cols)); + let config = helpers::lang_config(); + + let mut langs = config + .language + .iter() + .map(|l| l.language_id.clone()) + .collect::>(); + langs.sort_unstable(); + + let mut ts_features_to_langs = Vec::new(); + for &feat in ts_features { + ts_features_to_langs.push((feat, helpers::ts_lang_support(feat))); } - md + let mut row = Vec::new(); + for lang in langs { + let lc = config + .language + .iter() + .find(|l| l.language_id == lang) + .unwrap(); // lang comes from config + row.push(lc.display_name.clone()); + + for (_feat, support_list) in &ts_features_to_langs { + row.push( + if support_list.contains(&lang) { + "✓" + } else { + "" + } + .to_owned(), + ); + } + row.push( + lc.language_server + .as_ref() + .map(|s| s.command.clone()) + .map(|c| md_mono(&c)) + .unwrap_or_default(), + ); + + md.push_str(&md_table_row(&row)); + row.clear(); + } + + Ok(md) } pub fn write(filename: &str, data: &str) { @@ -49,37 +231,46 @@ pub mod path { pub fn book_gen() -> PathBuf { project_root().join("book/src/generated/") } + + pub fn ts_queries() -> PathBuf { + project_root().join("runtime/queries") + } + + pub fn lang_config() -> PathBuf { + project_root().join("languages.toml") + } } pub mod tasks { - use super::md_gen; + use crate::md_gen; + use crate::DynError; - pub fn bookgen() { - md_gen::write( - md_gen::TYPABLE_COMMANDS_MD_OUTPUT, - &md_gen::typable_commands(), - ); + pub fn docgen() -> Result<(), DynError> { + use md_gen::*; + write(TYPABLE_COMMANDS_MD_OUTPUT, &typable_commands()?); + write(LANG_SUPPORT_MD_OUTPUT, &lang_features()?); + Ok(()) } pub fn print_help() { println!( " -Usage: Run with `cargo xtask `, eg. `cargo xtask bookgen`. +Usage: Run with `cargo xtask `, eg. `cargo xtask docgen`. Tasks: - bookgen: Generate files to be included in the mdbook output. + docgen: Generate files to be included in the mdbook output. " ); } } -fn main() -> Result<(), String> { +fn main() -> Result<(), DynError> { let task = env::args().nth(1); match task { None => tasks::print_help(), Some(t) => match t.as_str() { - "bookgen" => tasks::bookgen(), - invalid => return Err(format!("Invalid task name: {}", invalid)), + "docgen" => tasks::docgen()?, + invalid => return Err(format!("Invalid task name: {}", invalid).into()), }, }; Ok(()) -- cgit v1.2.3-70-g09d2 From d08bdfa838098769afc59146b62f9d613d4a7ff4 Mon Sep 17 00:00:00 2001 From: Gokul Soumya Date: Tue, 7 Dec 2021 21:27:21 +0530 Subject: Use same name used in config files for langs in docs --- book/src/generated/lang-support.md | 78 +++++++++++++++++++------------------- helix-core/src/indent.rs | 1 - helix-core/src/syntax.rs | 1 - languages.toml | 41 -------------------- xtask/src/main.rs | 2 +- 5 files changed, 40 insertions(+), 83 deletions(-) (limited to 'book/src') diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 729801ad..96d9b6a0 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -1,41 +1,41 @@ | Language | Syntax Highlighting | Treesitter Textobjects | Auto Indent | Default LSP | | --- | --- | --- | --- | --- | -| Bash | ✓ | | | `bash-language-server` | -| C | ✓ | | | `clangd` | -| C# | ✓ | | | | -| CMake | ✓ | | | `cmake-language-server` | -| C++ | ✓ | | | `clangd` | -| CSS | ✓ | | | | -| Elixir | ✓ | | | `elixir-ls` | -| GLSL | ✓ | | ✓ | | -| Go | ✓ | ✓ | ✓ | `gopls` | -| HTML | ✓ | | | | -| Java | ✓ | | | | -| JavaScript | ✓ | | ✓ | | -| JSON | ✓ | | ✓ | | -| Julia | ✓ | | | `julia` | -| LaTeX | ✓ | | | | -| Ledger | ✓ | | | | -| LLVM | ✓ | | | | -| Lua | ✓ | | ✓ | | -| Mint | | | | `mint` | -| Nix | ✓ | | ✓ | `rnix-lsp` | -| OCaml | ✓ | | ✓ | | -| OCaml-Interface | ✓ | | | | -| Perl | ✓ | ✓ | | | -| PHP | ✓ | | ✓ | | -| Prolog | | | | `swipl` | -| Protobuf | ✓ | | ✓ | | -| Python | ✓ | ✓ | ✓ | `pylsp` | -| Racket | | | | `racket` | -| Ruby | ✓ | | | `solargraph` | -| Rust | ✓ | ✓ | ✓ | `rust-analyzer` | -| Svelte | ✓ | | ✓ | `svelteserver` | -| TOML | ✓ | | | | -| TSQ | ✓ | | | | -| TSX | ✓ | | | `typescript-language-server` | -| TypeScript | ✓ | | ✓ | `typescript-language-server` | -| Vue | ✓ | | | | -| WGSL | ✓ | | | | -| YAML | ✓ | | ✓ | | -| Zig | ✓ | | ✓ | `zls` | +| bash | ✓ | | | `bash-language-server` | +| c | ✓ | | | `clangd` | +| c-sharp | ✓ | | | | +| cmake | ✓ | | | `cmake-language-server` | +| cpp | ✓ | | | `clangd` | +| css | ✓ | | | | +| elixir | ✓ | | | `elixir-ls` | +| glsl | ✓ | | ✓ | | +| go | ✓ | ✓ | ✓ | `gopls` | +| html | ✓ | | | | +| java | ✓ | | | | +| javascript | ✓ | | ✓ | | +| json | ✓ | | ✓ | | +| julia | ✓ | | | `julia` | +| latex | ✓ | | | | +| ledger | ✓ | | | | +| llvm | ✓ | | | | +| lua | ✓ | | ✓ | | +| mint | | | | `mint` | +| nix | ✓ | | ✓ | `rnix-lsp` | +| ocaml | ✓ | | ✓ | | +| ocaml-interface | ✓ | | | | +| perl | ✓ | ✓ | | | +| php | ✓ | | ✓ | | +| prolog | | | | `swipl` | +| protobuf | ✓ | | ✓ | | +| python | ✓ | ✓ | ✓ | `pylsp` | +| racket | | | | `racket` | +| ruby | ✓ | | | `solargraph` | +| rust | ✓ | ✓ | ✓ | `rust-analyzer` | +| svelte | ✓ | | ✓ | `svelteserver` | +| toml | ✓ | | | | +| tsq | ✓ | | | | +| tsx | ✓ | | | `typescript-language-server` | +| typescript | ✓ | | ✓ | `typescript-language-server` | +| vue | ✓ | | | | +| wgsl | ✓ | | | | +| yaml | ✓ | | ✓ | | +| zig | ✓ | | ✓ | `zls` | diff --git a/helix-core/src/indent.rs b/helix-core/src/indent.rs index 3ce3620a..b6f5081a 100644 --- a/helix-core/src/indent.rs +++ b/helix-core/src/indent.rs @@ -452,7 +452,6 @@ where file_types: vec!["rs".to_string()], shebangs: vec![], language_id: "Rust".to_string(), - display_name: "Rust".to_string(), highlight_config: OnceCell::new(), config: None, // diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index 3c65ae33..ef35fc75 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -51,7 +51,6 @@ pub struct Configuration { pub struct LanguageConfiguration { #[serde(rename = "name")] pub language_id: String, // c-sharp, rust - pub display_name: String, // C#, Rust pub scope: String, // source.rust pub file_types: Vec, // filename ends_with? #[serde(default)] diff --git a/languages.toml b/languages.toml index ca339c98..428051a7 100644 --- a/languages.toml +++ b/languages.toml @@ -1,6 +1,5 @@ [[language]] name = "rust" -display-name = "Rust" scope = "source.rust" injection-regex = "rust" file-types = ["rs"] @@ -15,7 +14,6 @@ procMacro = { enable = false } [[language]] name = "toml" -display-name = "TOML" scope = "source.toml" injection-regex = "toml" file-types = ["toml"] @@ -26,7 +24,6 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "protobuf" -display-name = "Protobuf" scope = "source.proto" injection-regex = "protobuf" file-types = ["proto"] @@ -37,7 +34,6 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "elixir" -display-name = "Elixir" scope = "source.elixir" injection-regex = "elixir" file-types = ["ex", "exs"] @@ -50,7 +46,6 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "mint" -display-name = "Mint" scope = "source.mint" injection-regex = "mint" file-types = ["mint"] @@ -63,7 +58,6 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "json" -display-name = "JSON" scope = "source.json" injection-regex = "json" file-types = ["json"] @@ -73,7 +67,6 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "c" -display-name = "C" scope = "source.c" injection-regex = "c" file-types = ["c"] # TODO: ["h"] @@ -85,7 +78,6 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "cpp" -display-name = "C++" scope = "source.cpp" injection-regex = "cpp" file-types = ["cc", "hh", "cpp", "hpp", "h", "ipp", "tpp", "cxx", "hxx", "ixx", "txx", "ino"] @@ -97,7 +89,6 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "c-sharp" -display-name = "C#" scope = "source.csharp" injection-regex = "c-?sharp" file-types = ["cs"] @@ -108,7 +99,6 @@ indent = { tab-width = 4, unit = "\t" } [[language]] name = "go" -display-name = "Go" scope = "source.go" injection-regex = "go" file-types = ["go"] @@ -122,7 +112,6 @@ indent = { tab-width = 4, unit = "\t" } [[language]] name = "javascript" -display-name = "JavaScript" scope = "source.js" injection-regex = "^(js|javascript)$" file-types = ["js", "mjs"] @@ -135,7 +124,6 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "typescript" -display-name = "TypeScript" scope = "source.ts" injection-regex = "^(ts|typescript)$" file-types = ["ts"] @@ -148,7 +136,6 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "tsx" -display-name = "TSX" scope = "source.tsx" injection-regex = "^(tsx)$" # |typescript file-types = ["tsx"] @@ -160,7 +147,6 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "css" -display-name = "CSS" scope = "source.css" injection-regex = "css" file-types = ["css"] @@ -170,7 +156,6 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "html" -display-name = "HTML" scope = "text.html.basic" injection-regex = "html" file-types = ["html"] @@ -180,7 +165,6 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "python" -display-name = "Python" scope = "source.python" injection-regex = "python" file-types = ["py"] @@ -194,7 +178,6 @@ indent = { tab-width = 4, unit = " " } [[language]] name = "nix" -display-name = "Nix" scope = "source.nix" injection-regex = "nix" file-types = ["nix"] @@ -207,7 +190,6 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "ruby" -display-name = "Ruby" scope = "source.ruby" injection-regex = "ruby" file-types = ["rb"] @@ -220,7 +202,6 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "bash" -display-name = "Bash" scope = "source.bash" injection-regex = "bash" file-types = ["sh", "bash"] @@ -233,7 +214,6 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "php" -display-name = "PHP" scope = "source.php" injection-regex = "php" file-types = ["php"] @@ -244,7 +224,6 @@ indent = { tab-width = 4, unit = " " } [[language]] name = "latex" -display-name = "LaTeX" scope = "source.tex" injection-regex = "tex" file-types = ["tex"] @@ -255,7 +234,6 @@ indent = { tab-width = 4, unit = "\t" } [[language]] name = "julia" -display-name = "Julia" scope = "source.julia" injection-regex = "julia" file-types = ["jl"] @@ -271,7 +249,6 @@ language-server = { command = "julia", args = [ using Pkg; import StaticLint; env_path = dirname(Pkg.Types.Context().env.project_file); - server = LanguageServer.LanguageServerInstance(stdin, stdout, env_path, ""); server.runlinter = true; run(server); @@ -281,7 +258,6 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "java" -display-name = "Java" scope = "source.java" injection-regex = "java" file-types = ["java"] @@ -290,7 +266,6 @@ indent = { tab-width = 4, unit = " " } [[language]] name = "ledger" -display-name = "Ledger" scope = "source.ledger" injection-regex = "ledger" file-types = ["ldg", "ledger", "journal"] @@ -300,7 +275,6 @@ indent = { tab-width = 4, unit = " " } [[language]] name = "ocaml" -display-name = "OCaml" scope = "source.ocaml" injection-regex = "ocaml" file-types = ["ml"] @@ -311,7 +285,6 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "ocaml-interface" -display-name = "OCaml-Interface" scope = "source.ocaml.interface" file-types = ["mli"] shebangs = [] @@ -321,7 +294,6 @@ indent = { tab-width = 2, unit = " "} [[language]] name = "lua" -display-name = "Lua" scope = "source.lua" file-types = ["lua"] shebangs = ["lua"] @@ -331,7 +303,6 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "svelte" -display-name = "Svelte" scope = "source.svelte" injection-regex = "svelte" file-types = ["svelte"] @@ -342,7 +313,6 @@ language-server = { command = "svelteserver", args = ["--stdio"] } [[language]] name = "vue" -display-name = "Vue" scope = "source.vue" injection-regex = "vue" file-types = ["vue"] @@ -351,7 +321,6 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "yaml" -display-name = "YAML" scope = "source.yaml" file-types = ["yml", "yaml"] roots = [] @@ -360,7 +329,6 @@ indent = { tab-width = 2, unit = " " } # [[language]] # name = "haskell" -# display-name = "Haskell" # scope = "source.haskell" # injection-regex = "haskell" # file-types = ["hs"] @@ -371,7 +339,6 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "zig" -display-name = "Zig" scope = "source.zig" injection-regex = "zig" file-types = ["zig"] @@ -384,7 +351,6 @@ indent = { tab-width = 4, unit = " " } [[language]] name = "prolog" -display-name = "Prolog" scope = "source.prolog" roots = [] file-types = ["pl", "prolog"] @@ -398,7 +364,6 @@ language-server = { command = "swipl", args = [ [[language]] name = "tsq" -display-name = "TSQ" scope = "source.tsq" file-types = ["scm"] roots = [] @@ -407,7 +372,6 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "cmake" -display-name = "CMake" scope = "source.cmake" file-types = ["cmake", "CMakeLists.txt"] roots = [] @@ -417,7 +381,6 @@ language-server = { command = "cmake-language-server" } [[language]] name = "glsl" -display-name = "GLSL" scope = "source.glsl" file-types = ["glsl", "vert", "tesc", "tese", "geom", "frag", "comp" ] roots = [] @@ -426,7 +389,6 @@ indent = { tab-width = 4, unit = " " } [[language]] name = "perl" -display-name = "Perl" scope = "source.perl" file-types = ["pl", "pm"] shebangs = ["perl"] @@ -436,7 +398,6 @@ indent = { tab-width = 2, unit = " " } [[language]] name = "racket" -display-name = "Racket" scope = "source.rkt" roots = [] file-types = ["rkt"] @@ -446,7 +407,6 @@ language-server = { command = "racket", args = ["-l", "racket-langserver"] } [[language]] name = "wgsl" -display-name = "WGSL" scope = "source.wgsl" file-types = ["wgsl"] roots = [] @@ -455,7 +415,6 @@ indent = { tab-width = 4, unit = " " } [[language]] name = "llvm" -display-name = "LLVM" scope = "source.llvm" roots = [] file-types = ["ll"] diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 37e70592..7256653a 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -184,7 +184,7 @@ pub mod md_gen { .iter() .find(|l| l.language_id == lang) .unwrap(); // lang comes from config - row.push(lc.display_name.clone()); + row.push(lc.language_id.clone()); for (_feat, support_list) in &ts_features_to_langs { row.push( -- cgit v1.2.3-70-g09d2 From a1e64815cbffe1a35d0692c61cd59cd777a77d67 Mon Sep 17 00:00:00 2001 From: Oskar Nehlin Date: Wed, 8 Dec 2021 16:26:33 +0100 Subject: Update book to include typable command remapping (#1240) * Update book to include typable command remapping * Add additional example--- book/src/remapping.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'book/src') diff --git a/book/src/remapping.md b/book/src/remapping.md index ad63b60b..1cdf9b1f 100644 --- a/book/src/remapping.md +++ b/book/src/remapping.md @@ -11,6 +11,8 @@ this: ```toml # At most one section each of 'keys.normal', 'keys.insert' and 'keys.select' [keys.normal] +C-s = ":w" # Maps the Control-s to the typable command :w which is an alias for :write (save file) +C-o = ":open ~/.config/helix/config.toml" # Maps the Control-o to opening of the helix config file a = "move_char_left" # Maps the 'a' key to the move_char_left command w = "move_line_up" # Maps the 'w' key move_line_up "C-S-esc" = "extend_line" # Maps Control-Shift-Escape to extend_line @@ -21,6 +23,7 @@ g = { a = "code_action" } # Maps `ga` to show possible code actions "A-x" = "normal_mode" # Maps Alt-X to enter normal mode j = { k = "normal_mode" } # Maps `jk` to exit insert mode ``` +> NOTE: Typable commands can also be remapped, remember to keep the `:` prefix to indicate it's a typable command. Control, Shift and Alt modifiers are encoded respectively with the prefixes `C-`, `S-` and `A-`. Special keys are encoded as follows: @@ -53,4 +56,4 @@ Control, Shift and Alt modifiers are encoded respectively with the prefixes Keys can be disabled by binding them to the `no_op` command. Commands can be found at [Keymap](https://docs.helix-editor.com/keymap.html) Commands. -> Commands can also be found in the source code at [`helix-term/src/commands.rs`](https://github.com/helix-editor/helix/blob/master/helix-term/src/commands.rs) at the invocation of `commands!` macro. +> Commands can also be found in the source code at [`helix-term/src/commands.rs`](https://github.com/helix-editor/helix/blob/master/helix-term/src/commands.rs) at the invocation of `static_commands!` macro and the `TypableCommandList`. -- cgit v1.2.3-70-g09d2 From b66d3d3d9dccbb9c28d8611c4a0fc5d74ccb27d6 Mon Sep 17 00:00:00 2001 From: Omnikar Date: Thu, 9 Dec 2021 21:46:24 -0500 Subject: Add `save_selection` command (#1247) --- book/src/keymap.md | 1 + helix-term/src/commands.rs | 7 +++++++ helix-term/src/keymap.rs | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) (limited to 'book/src') diff --git a/book/src/keymap.md b/book/src/keymap.md index e1b1bad8..5a804c3c 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -34,6 +34,7 @@ | `Ctrl-d` | Move half page down | `half_page_down` | | `Ctrl-i` | Jump forward on the jumplist | `jump_forward` | | `Ctrl-o` | Jump backward on the jumplist | `jump_backward` | +| `Ctrl-s` | Save the current selection to the jumplist | `save_selection` | | `v` | Enter [select (extend) mode](#select--extend-mode) | `select_mode` | | `g` | Enter [goto mode](#goto-mode) | N/A | | `m` | Enter [match mode](#match-mode) | N/A | diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 1f7a2275..87c5a63f 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -362,6 +362,7 @@ impl MappableCommand { expand_selection, "Expand selection to parent syntax node", jump_forward, "Jump forward on jumplist", jump_backward, "Jump backward on jumplist", + save_selection, "Save the current selection to the jumplist", jump_view_right, "Jump to the split to the right", jump_view_left, "Jump to the split to the left", jump_view_up, "Jump to the split above", @@ -5285,6 +5286,12 @@ fn jump_backward(cx: &mut Context) { }; } +fn save_selection(cx: &mut Context) { + push_jump(cx.editor); + cx.editor + .set_status("Selection saved to jumplist".to_owned()); +} + fn rotate_view(cx: &mut Context) { cx.editor.focus_next() } diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index 9debbbac..b1613252 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -641,7 +641,7 @@ impl Default for Keymaps { "tab" => jump_forward, // tab == "C-o" => jump_backward, - // "C-s" => save_selection, + "C-s" => save_selection, "space" => { "Space" "f" => file_picker, -- cgit v1.2.3-70-g09d2 From e91d357fae04766b9781fe51a0809d35175fe1cf Mon Sep 17 00:00:00 2001 From: Omnikar Date: Sun, 12 Dec 2021 07:16:48 -0500 Subject: Macros (#1234) * Macros WIP `helix_term::compositor::Callback` changed to take a `&mut Context` as a parameter for use by `play_macro` * Default to `@` register for macros * Import `KeyEvent` * Special-case shift-tab -> backtab in `KeyEvent` conversion * Move key recording to the compositor * Add comment * Add persistent display of macro recording status When macro recording is active, the pending keys display will be shifted 3 characters left, and the register being recorded to will be displayed between brackets — e.g., `[@]` — right of the pending keys display. * Fix/add documentation--- book/src/keymap.md | 2 ++ helix-term/src/commands.rs | 59 ++++++++++++++++++++++++++++++++++++++++++-- helix-term/src/compositor.rs | 9 +++++-- helix-term/src/keymap.rs | 3 +++ helix-term/src/ui/editor.rs | 22 +++++++++++++++-- helix-term/src/ui/menu.rs | 2 +- helix-term/src/ui/picker.rs | 2 +- helix-term/src/ui/popup.rs | 2 +- helix-term/src/ui/prompt.rs | 2 +- helix-view/src/editor.rs | 3 +++ helix-view/src/input.rs | 20 +++++++++++++++ 11 files changed, 116 insertions(+), 10 deletions(-) (limited to 'book/src') diff --git a/book/src/keymap.md b/book/src/keymap.md index 5a804c3c..f0a2cb30 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -77,6 +77,8 @@ | `Alt-c` | Change selection (delete and enter insert mode, without yanking) | `change_selection_noyank` | | `Ctrl-a` | Increment object (number) under cursor | `increment` | | `Ctrl-x` | Decrement object (number) under cursor | `decrement` | +| `q` | Start/stop macro recording to the selected register | `record_macro` | +| `Q` | Play back a recorded macro from the selected register | `play_macro` | #### Shell diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 314cd11f..50554731 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -70,7 +70,7 @@ pub struct Context<'a> { impl<'a> Context<'a> { /// Push a new component onto the compositor. pub fn push_layer(&mut self, component: Box) { - self.callback = Some(Box::new(|compositor: &mut Compositor| { + self.callback = Some(Box::new(|compositor: &mut Compositor, _| { compositor.push(component) })); } @@ -395,6 +395,8 @@ impl MappableCommand { rename_symbol, "Rename symbol", increment, "Increment", decrement, "Decrement", + record_macro, "Record macro", + play_macro, "Play macro", ); } @@ -3441,7 +3443,7 @@ fn apply_workspace_edit( fn last_picker(cx: &mut Context) { // TODO: last picker does not seem to work well with buffer_picker - cx.callback = Some(Box::new(|compositor: &mut Compositor| { + cx.callback = Some(Box::new(|compositor: &mut Compositor, _| { if let Some(picker) = compositor.last_picker.take() { compositor.push(picker); } @@ -5870,3 +5872,56 @@ fn increment_impl(cx: &mut Context, amount: i64) { doc.append_changes_to_history(view.id); } } + +fn record_macro(cx: &mut Context) { + if let Some((reg, mut keys)) = cx.editor.macro_recording.take() { + // Remove the keypress which ends the recording + keys.pop(); + let s = keys + .into_iter() + .map(|key| format!("{}", key)) + .collect::>() + .join(" "); + cx.editor.registers.get_mut(reg).write(vec![s]); + cx.editor + .set_status(format!("Recorded to register {}", reg)); + } else { + let reg = cx.register.take().unwrap_or('@'); + cx.editor.macro_recording = Some((reg, Vec::new())); + cx.editor + .set_status(format!("Recording to register {}", reg)); + } +} + +fn play_macro(cx: &mut Context) { + let reg = cx.register.unwrap_or('@'); + let keys = match cx + .editor + .registers + .get(reg) + .and_then(|reg| reg.read().get(0)) + .context("Register empty") + .and_then(|s| { + s.split_whitespace() + .map(str::parse::) + .collect::, _>>() + .context("Failed to parse macro") + }) { + Ok(keys) => keys, + Err(e) => { + cx.editor.set_error(format!("{}", e)); + return; + } + }; + let count = cx.count(); + + cx.callback = Some(Box::new( + move |compositor: &mut Compositor, cx: &mut compositor::Context| { + for _ in 0..count { + for &key in keys.iter() { + compositor.handle_event(crossterm::event::Event::Key(key.into()), cx); + } + } + }, + )); +} diff --git a/helix-term/src/compositor.rs b/helix-term/src/compositor.rs index 30554ebb..321f56a5 100644 --- a/helix-term/src/compositor.rs +++ b/helix-term/src/compositor.rs @@ -7,7 +7,7 @@ use helix_view::graphics::{CursorKind, Rect}; use crossterm::event::Event; use tui::buffer::Buffer as Surface; -pub type Callback = Box; +pub type Callback = Box; // --> EventResult should have a callback that takes a context with methods like .popup(), // .prompt() etc. That way we can abstract it from the renderer. @@ -131,12 +131,17 @@ impl Compositor { } pub fn handle_event(&mut self, event: Event, cx: &mut Context) -> bool { + // If it is a key event and a macro is being recorded, push the key event to the recording. + if let (Event::Key(key), Some((_, keys))) = (event, &mut cx.editor.macro_recording) { + keys.push(key.into()); + } + // propagate events through the layers until we either find a layer that consumes it or we // run out of layers (event bubbling) for layer in self.layers.iter_mut().rev() { match layer.handle_event(event, cx) { EventResult::Consumed(Some(callback)) => { - callback(self); + callback(self, cx); return true; } EventResult::Consumed(None) => return true, diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index b1613252..257d5f29 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -593,6 +593,9 @@ impl Default for Keymaps { // paste_all "P" => paste_before, + "q" => record_macro, + "Q" => play_macro, + ">" => indent, "<" => unindent, "=" => format_selections, diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 39ee15b4..bac1f171 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -1100,13 +1100,31 @@ impl Component for EditorView { disp.push_str(&s); } } + let style = cx.editor.theme.get("ui.text"); + let macro_width = if cx.editor.macro_recording.is_some() { + 3 + } else { + 0 + }; surface.set_string( - area.x + area.width.saturating_sub(key_width), + area.x + area.width.saturating_sub(key_width + macro_width), area.y + area.height.saturating_sub(1), disp.get(disp.len().saturating_sub(key_width as usize)..) .unwrap_or(&disp), - cx.editor.theme.get("ui.text"), + style, ); + if let Some((reg, _)) = cx.editor.macro_recording { + let disp = format!("[{}]", reg); + let style = style + .fg(helix_view::graphics::Color::Yellow) + .add_modifier(Modifier::BOLD); + surface.set_string( + area.x + area.width.saturating_sub(3), + area.y + area.height.saturating_sub(1), + &disp, + style, + ); + } } if let Some(completion) = self.completion.as_mut() { diff --git a/helix-term/src/ui/menu.rs b/helix-term/src/ui/menu.rs index 9a885a36..69053db3 100644 --- a/helix-term/src/ui/menu.rs +++ b/helix-term/src/ui/menu.rs @@ -190,7 +190,7 @@ impl Component for Menu { _ => return EventResult::Ignored, }; - let close_fn = EventResult::Consumed(Some(Box::new(|compositor: &mut Compositor| { + let close_fn = EventResult::Consumed(Some(Box::new(|compositor: &mut Compositor, _| { // remove the layer compositor.pop(); }))); diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs index 1c963f97..1ef94df0 100644 --- a/helix-term/src/ui/picker.rs +++ b/helix-term/src/ui/picker.rs @@ -404,7 +404,7 @@ impl Component for Picker { _ => return EventResult::Ignored, }; - let close_fn = EventResult::Consumed(Some(Box::new(|compositor: &mut Compositor| { + let close_fn = EventResult::Consumed(Some(Box::new(|compositor: &mut Compositor, _| { // remove the layer compositor.last_picker = compositor.pop(); }))); diff --git a/helix-term/src/ui/popup.rs b/helix-term/src/ui/popup.rs index c55f030f..bf7510a2 100644 --- a/helix-term/src/ui/popup.rs +++ b/helix-term/src/ui/popup.rs @@ -100,7 +100,7 @@ impl Component for Popup { _ => return EventResult::Ignored, }; - let close_fn = EventResult::Consumed(Some(Box::new(|compositor: &mut Compositor| { + let close_fn = EventResult::Consumed(Some(Box::new(|compositor: &mut Compositor, _| { // remove the layer compositor.pop(); }))); diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs index a7ef231c..07e1b33c 100644 --- a/helix-term/src/ui/prompt.rs +++ b/helix-term/src/ui/prompt.rs @@ -426,7 +426,7 @@ impl Component for Prompt { _ => return EventResult::Ignored, }; - let close_fn = EventResult::Consumed(Some(Box::new(|compositor: &mut Compositor| { + let close_fn = EventResult::Consumed(Some(Box::new(|compositor: &mut Compositor, _| { // remove the layer compositor.pop(); }))); diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 9034d12c..dcbcbe4f 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -2,6 +2,7 @@ use crate::{ clipboard::{get_clipboard_provider, ClipboardProvider}, document::SCRATCH_BUFFER_NAME, graphics::{CursorKind, Rect}, + input::KeyEvent, theme::{self, Theme}, tree::{self, Tree}, Document, DocumentId, View, ViewId, @@ -160,6 +161,7 @@ pub struct Editor { pub count: Option, pub selected_register: Option, pub registers: Registers, + pub macro_recording: Option<(char, Vec)>, pub theme: Theme, pub language_servers: helix_lsp::Registry, pub clipboard_provider: Box, @@ -203,6 +205,7 @@ impl Editor { documents: BTreeMap::new(), count: None, selected_register: None, + macro_recording: None, theme: theme_loader.default(), language_servers, syn_loader, diff --git a/helix-view/src/input.rs b/helix-view/src/input.rs index b207c3ed..92caa517 100644 --- a/helix-view/src/input.rs +++ b/helix-view/src/input.rs @@ -234,6 +234,26 @@ impl From for KeyEvent { } } +#[cfg(feature = "term")] +impl From for crossterm::event::KeyEvent { + fn from(KeyEvent { code, modifiers }: KeyEvent) -> Self { + if code == KeyCode::Tab && modifiers.contains(KeyModifiers::SHIFT) { + // special case for Shift-Tab -> BackTab + let mut modifiers = modifiers; + modifiers.remove(KeyModifiers::SHIFT); + crossterm::event::KeyEvent { + code: crossterm::event::KeyCode::BackTab, + modifiers: modifiers.into(), + } + } else { + crossterm::event::KeyEvent { + code: code.into(), + modifiers: modifiers.into(), + } + } + } +} + #[cfg(test)] mod test { use super::*; -- cgit v1.2.3-70-g09d2 From 98ce2a301da25152563137047377026d72fd644c Mon Sep 17 00:00:00 2001 From: Omnikar Date: Sun, 14 Nov 2021 07:26:48 -0500 Subject: Load alt default theme if true color is not supported * Move `runtime/themes/base16_default_terminal.toml` to `base16_theme.toml` alongside `theme.toml` * Use `terminfo` crate to detect whether the terminal supports true color and, if the user has no theme configured and their terminal does not support true color, load the alt default theme instead of the normal default. Remove `terminfo` dependency, use `COLORTERM` env instead Prevent user from switching to an unsupported theme Add `true-color-override` option If the terminal is wrongly detected to not support true color, `true-color-override = true` will override the detection. Rename `true-color-override` to `true-color` --- base16_theme.toml | 41 +++++++++++++++++++++++++++++++++++++ book/src/configuration.md | 1 + helix-term/src/application.rs | 28 +++++++++++++++++-------- helix-term/src/commands.rs | 14 +++++++++++-- helix-term/src/lib.rs | 6 ++++++ helix-term/src/ui/mod.rs | 1 + helix-view/src/editor.rs | 12 +++-------- helix-view/src/theme.rs | 20 ++++++++++++++++++ runtime/themes/base16_terminal.toml | 41 ------------------------------------- 9 files changed, 103 insertions(+), 61 deletions(-) create mode 100644 base16_theme.toml delete mode 100644 runtime/themes/base16_terminal.toml (limited to 'book/src') diff --git a/base16_theme.toml b/base16_theme.toml new file mode 100644 index 00000000..bf3c73f1 --- /dev/null +++ b/base16_theme.toml @@ -0,0 +1,41 @@ +# Author: NNB + +"ui.menu" = "black" +"ui.menu.selected" = { fg = "white", bg = "black" } +"ui.linenr" = { fg = "light-gray", bg = "black" } +"ui.popup" = { bg = "black" } +"ui.window" = { bg = "black" } +"ui.linenr.selected" = { fg = "white", bg = "black", modifiers = ["bold"] } +"ui.selection" = { fg = "gray", modifiers = ["reversed"] } +"comment" = { fg = "light-gray", modifiers = ["italic"] } +"ui.statusline" = { fg = "white", bg = "black" } +"ui.help" = { fg = "white", bg = "black" } +"ui.cursor" = { fg = "light-gray", modifiers = ["reversed"] } +"ui.cursor.primary" = { fg = "white", modifiers = ["reversed"] } #FIXME +"ui.text" = "white" #FIXME +"operator" = "white" #FIXME +"ui.text.focus" = "white" #FIXME +"variable" = "light-red" +"constant.numeric" = "yellow" +"constant" = "yellow" +"attributes" = "yellow" +"type" = "light-yellow" +"ui.cursor.match" = { fg = "light-yellow", modifiers = ["underlined"] } +"string" = "light-green" +"variable.other.member" = "light-green" +"constant.character.escape" = "light-cyan" +"function" = "light-blue" +"constructor" = "light-blue" +"special" = "light-blue" +"keyword" = "light-magenta" +"label" = "light-magenta" +"namespace" = "light-magenta" +"ui.popup" = { bg = "black" } +"ui.window" = { bg = "base00" } +"ui.help" = { fg = "white", bg = "black" } + +"info" = "light-gray" +"hint" = "light-gray" +"debug" = "light-gray" +"diagnostic" = "light-gray" +"error" = "light-magenta" diff --git a/book/src/configuration.md b/book/src/configuration.md index 2ed48d51..33a933b2 100644 --- a/book/src/configuration.md +++ b/book/src/configuration.md @@ -23,6 +23,7 @@ To override global configuration parameters, create a `config.toml` file located | `idle-timeout` | Time in milliseconds since last keypress before idle timers trigger. Used for autocompletion, set to 0 for instant. | `400` | | `completion-trigger-len` | The min-length of word under cursor to trigger autocompletion | `2` | | `auto-info` | Whether to display infoboxes | `true` | +| `true-color` | Set to `true` to override automatic detection of terminal truecolor support in the event of a false negative. | `false` | `[editor.filepicker]` section of the config. Sets options for file picker and global search. All but the last key listed in the default file-picker configuration below are IgnoreOptions: whether hidden files and files listed within ignore files are ignored by (not visible in) the helix file picker and global search. There is also one other key, `max-depth` available, which is not defined by default. diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index 90330751..3e0b6d59 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -76,17 +76,27 @@ impl Application { None => Ok(def_lang_conf), }; - let theme = if let Some(theme) = &config.theme { - match theme_loader.load(theme) { - Ok(theme) => theme, - Err(e) => { - log::warn!("failed to load theme `{}` - {}", theme, e); + let true_color = config.editor.true_color || crate::true_color(); + let theme = config + .theme + .as_ref() + .and_then(|theme| { + theme_loader + .load(theme) + .map_err(|e| { + log::warn!("failed to load theme `{}` - {}", theme, e); + e + }) + .ok() + .filter(|theme| (true_color || theme.is_16_color())) + }) + .unwrap_or_else(|| { + if true_color { theme_loader.default() + } else { + theme_loader.base16_default() } - } - } else { - theme_loader.default() - }; + }); let syn_loader_conf: helix_core::syntax::Configuration = lang_conf .and_then(|conf| conf.try_into()) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 0ae225e9..22c23043 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -2366,8 +2366,18 @@ pub mod cmd { args: &[Cow], _event: PromptEvent, ) -> anyhow::Result<()> { - let theme = args.first().context("theme not provided")?; - cx.editor.set_theme_from_name(theme) + let theme = args.first().context("Theme not provided")?; + let theme = cx + .editor + .theme_loader + .load(theme) + .with_context(|| format!("Failed setting theme {}", theme))?; + let true_color = cx.editor.config.true_color || crate::true_color(); + if !(true_color || theme.is_16_color()) { + bail!("Unsupported theme: theme requires true color support"); + } + cx.editor.set_theme(theme); + Ok(()) } fn yank_main_selection_to_clipboard( diff --git a/helix-term/src/lib.rs b/helix-term/src/lib.rs index f5e3a8cd..4fe76cd5 100644 --- a/helix-term/src/lib.rs +++ b/helix-term/src/lib.rs @@ -9,3 +9,9 @@ pub mod config; pub mod job; pub mod keymap; pub mod ui; + +fn true_color() -> bool { + std::env::var("COLORTERM") + .map(|v| matches!(v.as_str(), "truecolor" | "24bit")) + .unwrap_or(false) +} diff --git a/helix-term/src/ui/mod.rs b/helix-term/src/ui/mod.rs index cdf42311..f57e2e2b 100644 --- a/helix-term/src/ui/mod.rs +++ b/helix-term/src/ui/mod.rs @@ -186,6 +186,7 @@ pub mod completers { &helix_core::config_dir().join("themes"), )); names.push("default".into()); + names.push("base16_default".into()); let mut names: Vec<_> = names .into_iter() diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index dcbcbe4f..753defa1 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -105,6 +105,8 @@ pub struct Config { /// Whether to display infoboxes. Defaults to true. pub auto_info: bool, pub file_picker: FilePickerConfig, + /// Set to `true` to override automatic detection of terminal truecolor support in the event of a false negative. Defaults to `false`. + pub true_color: bool, } #[derive(Debug, Copy, Clone, PartialEq, Eq, Deserialize)] @@ -137,6 +139,7 @@ impl Default for Config { completion_trigger_len: 2, auto_info: true, file_picker: FilePickerConfig::default(), + true_color: false, } } } @@ -265,15 +268,6 @@ impl Editor { self._refresh(); } - pub fn set_theme_from_name(&mut self, theme: &str) -> anyhow::Result<()> { - let theme = self - .theme_loader - .load(theme.as_ref()) - .with_context(|| format!("failed setting theme `{}`", theme))?; - self.set_theme(theme); - Ok(()) - } - /// Refreshes the language server for a given document pub fn refresh_language_server(&mut self, doc_id: DocumentId) -> Option<()> { let doc = self.documents.get_mut(&doc_id)?; diff --git a/helix-view/src/theme.rs b/helix-view/src/theme.rs index 47fc6262..ddcdad99 100644 --- a/helix-view/src/theme.rs +++ b/helix-view/src/theme.rs @@ -15,6 +15,10 @@ pub use crate::graphics::{Color, Modifier, Style}; pub static DEFAULT_THEME: Lazy = Lazy::new(|| { toml::from_slice(include_bytes!("../../theme.toml")).expect("Failed to parse default theme") }); +pub static BASE16_DEFAULT_THEME: Lazy = Lazy::new(|| { + toml::from_slice(include_bytes!("../../base16_theme.toml")) + .expect("Failed to parse base 16 default theme") +}); #[derive(Clone, Debug)] pub struct Loader { @@ -35,6 +39,9 @@ impl Loader { if name == "default" { return Ok(self.default()); } + if name == "base16_default" { + return Ok(self.base16_default()); + } let filename = format!("{}.toml", name); let user_path = self.user_dir.join(&filename); @@ -74,6 +81,11 @@ impl Loader { pub fn default(&self) -> Theme { DEFAULT_THEME.clone() } + + /// Returns the alternative 16-color default theme + pub fn base16_default(&self) -> Theme { + BASE16_DEFAULT_THEME.clone() + } } #[derive(Clone, Debug)] @@ -154,6 +166,14 @@ impl Theme { pub fn find_scope_index(&self, scope: &str) -> Option { self.scopes().iter().position(|s| s == scope) } + + pub fn is_16_color(&self) -> bool { + self.styles.iter().all(|(_, style)| { + [style.fg, style.bg] + .into_iter() + .all(|color| !matches!(color, Some(Color::Rgb(..)))) + }) + } } struct ThemePalette { diff --git a/runtime/themes/base16_terminal.toml b/runtime/themes/base16_terminal.toml deleted file mode 100644 index bf3c73f1..00000000 --- a/runtime/themes/base16_terminal.toml +++ /dev/null @@ -1,41 +0,0 @@ -# Author: NNB - -"ui.menu" = "black" -"ui.menu.selected" = { fg = "white", bg = "black" } -"ui.linenr" = { fg = "light-gray", bg = "black" } -"ui.popup" = { bg = "black" } -"ui.window" = { bg = "black" } -"ui.linenr.selected" = { fg = "white", bg = "black", modifiers = ["bold"] } -"ui.selection" = { fg = "gray", modifiers = ["reversed"] } -"comment" = { fg = "light-gray", modifiers = ["italic"] } -"ui.statusline" = { fg = "white", bg = "black" } -"ui.help" = { fg = "white", bg = "black" } -"ui.cursor" = { fg = "light-gray", modifiers = ["reversed"] } -"ui.cursor.primary" = { fg = "white", modifiers = ["reversed"] } #FIXME -"ui.text" = "white" #FIXME -"operator" = "white" #FIXME -"ui.text.focus" = "white" #FIXME -"variable" = "light-red" -"constant.numeric" = "yellow" -"constant" = "yellow" -"attributes" = "yellow" -"type" = "light-yellow" -"ui.cursor.match" = { fg = "light-yellow", modifiers = ["underlined"] } -"string" = "light-green" -"variable.other.member" = "light-green" -"constant.character.escape" = "light-cyan" -"function" = "light-blue" -"constructor" = "light-blue" -"special" = "light-blue" -"keyword" = "light-magenta" -"label" = "light-magenta" -"namespace" = "light-magenta" -"ui.popup" = { bg = "black" } -"ui.window" = { bg = "base00" } -"ui.help" = { fg = "white", bg = "black" } - -"info" = "light-gray" -"hint" = "light-gray" -"debug" = "light-gray" -"diagnostic" = "light-gray" -"error" = "light-magenta" -- cgit v1.2.3-70-g09d2 From 9bfb701c9446416a3e6f6500871ae4025001bd7c Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Wed, 15 Dec 2021 17:38:03 +0900 Subject: Update lang-support.md --- book/src/generated/lang-support.md | 1 + 1 file changed, 1 insertion(+) (limited to 'book/src') diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 96d9b6a0..80fb28a5 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -18,6 +18,7 @@ | ledger | ✓ | | | | | llvm | ✓ | | | | | lua | ✓ | | ✓ | | +| markdown | ✓ | | | | | mint | | | | `mint` | | nix | ✓ | | ✓ | `rnix-lsp` | | ocaml | ✓ | | ✓ | | -- cgit v1.2.3-70-g09d2 From 40969ad4528bbb774e2b95dce0749b1dd3734ebf Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Wed, 15 Dec 2021 17:46:40 +0900 Subject: Partly fix latex highlights and add markup scope docs --- book/src/themes.md | 14 ++++++++++++++ runtime/queries/latex/highlights.scm | 26 +++++++++++++------------- 2 files changed, 27 insertions(+), 13 deletions(-) (limited to 'book/src') diff --git a/book/src/themes.md b/book/src/themes.md index fd3f5b1e..b6de7002 100644 --- a/book/src/themes.md +++ b/book/src/themes.md @@ -162,6 +162,20 @@ We use a similar set of scopes as - `namespace` +- `markup` + - `heading` + - `list` + - `unnumbered` + - `numbered` + - `bold` + - `italic` + - `underline` + - `link` + - `quote` + - `raw` + - `inline` + - `block` + #### Interface These scopes are used for theming the editor interface. diff --git a/runtime/queries/latex/highlights.scm b/runtime/queries/latex/highlights.scm index f045c82d..8406bd04 100644 --- a/runtime/queries/latex/highlights.scm +++ b/runtime/queries/latex/highlights.scm @@ -318,60 +318,60 @@ ["[" "]" "{" "}"] @punctuation.bracket ;"(" ")" is has no special meaning in LaTeX (chapter - text: (brace_group) @text.title) + text: (brace_group) @markup.heading) (part - text: (brace_group) @text.title) + text: (brace_group) @markup.heading) (section - text: (brace_group) @text.title) + text: (brace_group) @markup.heading) (subsection - text: (brace_group) @text.title) + text: (brace_group) @markup.heading) (subsubsection - text: (brace_group) @text.title) + text: (brace_group) @markup.heading) (paragraph - text: (brace_group) @text.title) + text: (brace_group) @markup.heading) (subparagraph - text: (brace_group) @text.title) + text: (brace_group) @markup.heading) ((environment (begin name: (word) @_frame) (brace_group - child: (text) @text.title)) + child: (text) @markup.heading)) (#eq? @_frame "frame")) ((generic_command name:(generic_command_name) @_name arg: (brace_group - (text) @text.title)) + (text) @markup.heading)) (#eq? @_name "\\frametitle")) ;; Formatting ((generic_command name:(generic_command_name) @_name - arg: (_) @text.emphasis) + arg: (_) @markup.italic) (#eq? @_name "\\emph")) ((generic_command name:(generic_command_name) @_name - arg: (_) @text.emphasis) + arg: (_) @markup.italic) (#match? @_name "^(\\\\textit|\\\\mathit)$")) ((generic_command name:(generic_command_name) @_name - arg: (_) @text.strong) + arg: (_) @markup.bold) (#match? @_name "^(\\\\textbf|\\\\mathbf)$")) ((generic_command name:(generic_command_name) @_name . - arg: (_) @text.uri) + arg: (_) @markup.underline.link) (#match? @_name "^(\\\\url|\\\\href)$")) (ERROR) @error -- cgit v1.2.3-70-g09d2 From a8060c06d14935d18e27fcb64b8a58ae6dc5eaf3 Mon Sep 17 00:00:00 2001 From: ath3 Date: Fri, 17 Dec 2021 01:56:07 +0100 Subject: Add indents.toml to perl (#1280) --- book/src/generated/lang-support.md | 2 +- runtime/queries/perl/indents.toml | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 runtime/queries/perl/indents.toml (limited to 'book/src') diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 80fb28a5..80989e63 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -23,7 +23,7 @@ | nix | ✓ | | ✓ | `rnix-lsp` | | ocaml | ✓ | | ✓ | | | ocaml-interface | ✓ | | | | -| perl | ✓ | ✓ | | | +| perl | ✓ | ✓ | ✓ | | | php | ✓ | | ✓ | | | prolog | | | | `swipl` | | protobuf | ✓ | | ✓ | | diff --git a/runtime/queries/perl/indents.toml b/runtime/queries/perl/indents.toml new file mode 100644 index 00000000..365e0663 --- /dev/null +++ b/runtime/queries/perl/indents.toml @@ -0,0 +1,17 @@ +indent = [ + "function", + "identifier", + "method_invocation", + "if_statement", + "unless_statement", + "if_simple_statement", + "unless_simple_statement", + "variable_declaration", + "block", + "list_item", + "word_list_qw" +] + +outdent = [ + "}" +] -- cgit v1.2.3-70-g09d2 From 3ef115d4203fab93f7efe4f65d8dd63cc4535b91 Mon Sep 17 00:00:00 2001 From: Chetan Vardhan Date: Fri, 17 Dec 2021 20:16:32 +0530 Subject: Add instructions for Fedora Linux (#1270) * Add instructions for Fedora Linux * Update README.md * Update install.md--- book/src/install.md | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'book/src') diff --git a/book/src/install.md b/book/src/install.md index d831934c..1a5a9daa 100644 --- a/book/src/install.md +++ b/book/src/install.md @@ -27,6 +27,15 @@ Releases are available in the `community` repository. A [helix-git](https://aur.archlinux.org/packages/helix-git/) package is also available on the AUR, which builds the master branch. +### Fedora Linux + +You can install the COPR package for Helix via + +``` +sudo dnf copr enable varlad/helix +sudo dnf install helix +``` + ## Build from source ``` -- cgit v1.2.3-70-g09d2