From e40e6db2271b9568352b7477ed8b9f9895881cf9 Mon Sep 17 00:00:00 2001 From: Gokul Soumya Date: Thu, 2 Sep 2021 22:05:33 +0530 Subject: feat: Default theme palette using 16 terminal colors --- book/src/themes.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'book') diff --git a/book/src/themes.md b/book/src/themes.md index 0a4d58ad..8642e659 100644 --- a/book/src/themes.md +++ b/book/src/themes.md @@ -123,3 +123,24 @@ black = "#000000" Remember that the `[palette]` table includes all keys after its header, so you should define the palette after normal theme options. + +If there is no `[palette]` section, a default palette which uses the terminal's default 16 colors are used: + +| Color Name | +| --- | +| `black` | +| `red` | +| `green` | +| `yellow` | +| `blue` | +| `magenta` | +| `cyan` | +| `gray` | +| `light-red` | +| `light-green` | +| `light-yellow` | +| `light-blue` | +| `light-magenta` | +| `light-cyan` | +| `light-gray` | +| `white` | -- cgit v1.2.3-70-g09d2 From e4e93e176ceca39a834abf7e67bf9bfaa34d886d Mon Sep 17 00:00:00 2001 From: Gokul Soumya Date: Fri, 3 Sep 2021 16:42:29 +0530 Subject: fix: Merge default palette with user palette --- book/src/themes.md | 4 +++- helix-view/src/theme.rs | 45 ++++++++++++++++++++++++++------------------- 2 files changed, 29 insertions(+), 20 deletions(-) (limited to 'book') diff --git a/book/src/themes.md b/book/src/themes.md index 8642e659..804baa1c 100644 --- a/book/src/themes.md +++ b/book/src/themes.md @@ -124,7 +124,9 @@ black = "#000000" Remember that the `[palette]` table includes all keys after its header, so you should define the palette after normal theme options. -If there is no `[palette]` section, a default palette which uses the terminal's default 16 colors are used: +The default palette uses the terminal's default 16 colors, and the colors names +are listed below. The `[palette]` section in the config file takes precedence +over it and is merged into the default palette. | Color Name | | --- | diff --git a/helix-view/src/theme.rs b/helix-view/src/theme.rs index 9f768505..9c33685b 100644 --- a/helix-view/src/theme.rs +++ b/helix-view/src/theme.rs @@ -143,30 +143,37 @@ struct ThemePalette { impl Default for ThemePalette { fn default() -> Self { - Self::new(hashmap! { - "black".to_string() => Color::Black, - "red".to_string() => Color::Red, - "green".to_string() => Color::Green, - "yellow".to_string() => Color::Yellow, - "blue".to_string() => Color::Blue, - "magenta".to_string() => Color::Magenta, - "cyan".to_string() => Color::Cyan, - "gray".to_string() => Color::Gray, - "light-red".to_string() => Color::LightRed, - "light-green".to_string() => Color::LightGreen, - "light-yellow".to_string() => Color::LightYellow, - "light-blue".to_string() => Color::LightBlue, - "light-magenta".to_string() => Color::LightMagenta, - "light-cyan".to_string() => Color::LightCyan, - "light-gray".to_string() => Color::LightGray, - "white".to_string() => Color::White, - }) + Self { + palette: hashmap! { + "black".to_string() => Color::Black, + "red".to_string() => Color::Red, + "green".to_string() => Color::Green, + "yellow".to_string() => Color::Yellow, + "blue".to_string() => Color::Blue, + "magenta".to_string() => Color::Magenta, + "cyan".to_string() => Color::Cyan, + "gray".to_string() => Color::Gray, + "light-red".to_string() => Color::LightRed, + "light-green".to_string() => Color::LightGreen, + "light-yellow".to_string() => Color::LightYellow, + "light-blue".to_string() => Color::LightBlue, + "light-magenta".to_string() => Color::LightMagenta, + "light-cyan".to_string() => Color::LightCyan, + "light-gray".to_string() => Color::LightGray, + "white".to_string() => Color::White, + }, + } } } impl ThemePalette { pub fn new(palette: HashMap) -> Self { - Self { palette } + let ThemePalette { + palette: mut default, + } = ThemePalette::default(); + + default.extend(palette); + Self { palette: default } } pub fn hex_string_to_rgb(s: &str) -> Result { -- cgit v1.2.3-70-g09d2 From 4cc562318a9987d58384fdb4e88e5a1f59f25a19 Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Tue, 7 Sep 2021 13:00:52 +0900 Subject: Improve docs, fix up a few highlight scopes --- book/book.toml | 3 +- book/src/configuration.md | 13 +++ book/src/from-vim.md | 2 + book/src/install.md | 4 +- book/src/keymap.md | 100 ++++++++--------- book/src/themes.md | 202 +++++++++++++++++++++-------------- book/theme/css/general.css | 13 +++ book/theme/css/variables.css | 24 +++-- book/theme/highlight.css | 101 +++++++----------- runtime/queries/ocaml/highlights.scm | 2 +- runtime/queries/rust/highlights.scm | 2 +- runtime/themes/dark_plus.toml | 1 + runtime/themes/monokai.toml | 1 + theme.toml | 4 +- 14 files changed, 265 insertions(+), 207 deletions(-) (limited to 'book') diff --git a/book/book.toml b/book/book.toml index 3ccaf71e..2277a0bd 100644 --- a/book/book.toml +++ b/book/book.toml @@ -3,8 +3,9 @@ authors = ["Blaž Hrastnik"] language = "en" multilingual = false src = "src" -theme = "colibri" edit-url-template = "https://github.com/helix-editor/helix/tree/master/book/{path}?mode=edit" [output.html] cname = "docs.helix-editor.com" +default-theme = "colibri" +preferred-dark-theme = "colibri" diff --git a/book/src/configuration.md b/book/src/configuration.md index 00dfbbd8..5a28362d 100644 --- a/book/src/configuration.md +++ b/book/src/configuration.md @@ -5,6 +5,19 @@ To override global configuration parameters, create a `config.toml` file located * Linux and Mac: `~/.config/helix/config.toml` * Windows: `%AppData%\helix\config.toml` +## Editor + +`[editor]` section of the config. + +| Key | Description | Default | +|--|--|---------| +| `scrolloff` | Number of lines of padding around the edge of the screen when scrolling. | `3` | +| `mouse` | Enable mouse mode. | `true` | +| `middle-click-paste` | Middle click paste support. | `true` | +| `scroll-lines` | Number of lines to scroll per scroll wheel step. | `3` | +| `shell` | Shell to use when running external commands. | Unix: `["sh", "-c"]`
Windows: `["cmd", "/C"]` | +| `line-number` | Line number display (`absolute`, `relative`) | `absolute` | + ## LSP To display all language server messages in the status line add the following to your `config.toml`: diff --git a/book/src/from-vim.md b/book/src/from-vim.md index 8e9bbac3..09f33386 100644 --- a/book/src/from-vim.md +++ b/book/src/from-vim.md @@ -7,4 +7,6 @@ going to act on (a word, a paragraph, a line, etc) is selected first and the action itself (delete, change, yank, etc) comes second. A cursor is simply a single width selection. +See also Kakoune's [Migrating from Vim](https://github.com/mawww/kakoune/wiki/Migrating-from-Vim). + > TODO: Mention texobjects, surround, registers diff --git a/book/src/install.md b/book/src/install.md index cd9c980e..b9febbcc 100644 --- a/book/src/install.md +++ b/book/src/install.md @@ -23,7 +23,9 @@ shell for working on Helix. ### Arch Linux -Binary packages are available on AUR: +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 diff --git a/book/src/keymap.md b/book/src/keymap.md index 861e46ac..51e56eaa 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -4,7 +4,7 @@ ### Movement -> NOTE: `f`, `F`, `t` and `T` are not confined to the current line. +> NOTE: Unlike vim, `f`, `F`, `t` and `T` are not confined to the current line. | Key | Description | Command | | ----- | ----------- | ------- | @@ -28,14 +28,14 @@ | `PageDown` | Move page down | `page_down` | | `Ctrl-u` | Move half page up | `half_page_up` | | `Ctrl-d` | Move half page down | `half_page_down` | -| `Ctrl-i` | Jump forward on the jumplist TODO: conflicts tab | `jump_forward` | +| `Ctrl-i` | Jump forward on the jumplist | `jump_forward` | | `Ctrl-o` | Jump backward on the jumplist | `jump_backward` | | `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 | | `:` | Enter command mode | `command_mode` | | `z` | Enter [view mode](#view-mode) | N/A | -| `Ctrl-w` | Enter [window mode](#window-mode) (maybe will be remove for spc w w later) | N/A | +| `Ctrl-w` | Enter [window mode](#window-mode) | N/A | | `Space` | Enter [space mode](#space-mode) | N/A | | `K` | Show documentation for the item under the cursor | `hover` | @@ -66,6 +66,16 @@ | `d` | Delete selection | `delete_selection` | | `c` | Change selection (delete and enter insert mode) | `change_selection` | +#### 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` | + + ### Selection manipulation | Key | Description | Command | @@ -87,17 +97,10 @@ | | Expand selection to parent syntax node TODO: pick a key | `expand_selection` | | `J` | Join lines inside selection | `join_selections` | | `K` | Keep selections matching the regex TODO: overlapped by hover help | `keep_selections` | +| `$` | Pipe each selection into shell command, keep selections where command returned 0 | `shell_keep_pipe` | | `Space` | Keep only the primary selection TODO: overlapped by space mode | `keep_primary_selection` | | `Ctrl-c` | Comment/uncomment the selections | `toggle_comments` | -### Insert Mode - -| Key | Description | Command | -| ----- | ----------- | ------- | -| `Escape` | Switch to normal mode | `normal_mode` | -| `Ctrl-x` | Autocomplete | `completion` | -| `Ctrl-w` | Delete previous word | `delete_word_backward` | - ### Search > TODO: The search implementation isn't ideal yet -- we don't support searching @@ -110,38 +113,11 @@ in reverse, or searching via smartcase. | `N` | Add next search match to selection | `extend_search_next` | | `*` | Use current selection as the search pattern | `search_selection` | -### Unimpaired - -Mappings in the style of [vim-unimpaired](https://github.com/tpope/vim-unimpaired) - -| Key | Description | Command | -| ----- | ----------- | ------- | -| `[d` | Go to previous diagnostic | `goto_prev_diag` | -| `]d` | Go to next diagnostic | `goto_next_diag` | -| `[D` | Go to first diagnostic in document | `goto_first_diag` | -| `]D` | Go to last diagnostic in document | `goto_last_diag` | -| `[space` | Add newline above | `add_newline_above` | -| `]space` | Add newline below | `add_newline_below` | - -### Shell +### Minor modes -| 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` | -| `$` | Pipe each selection into shell command, keep selections where command returned 0 | `shell_keep_pipe` | - -## Select / extend mode - -I'm still pondering whether to keep this mode or not. It changes movement -commands to extend the existing selection instead of replacing it. - -> NOTE: It's a bit confusing at the moment because extend hasn't been -> implemented for all movement commands yet. +These sub-modes are accessible from normal mode and typically switch back to normal mode after a command. -## View mode +#### View mode View mode is intended for scrolling and manipulating the view without changing the selection. @@ -155,7 +131,7 @@ the selection. | `j` | Scroll the view downwards | `scroll_down` | | `k` | Scroll the view upwards | `scroll_up` | -## Goto mode +#### Goto mode Jumps to various locations. @@ -177,7 +153,7 @@ Jumps to various locations. | `i` | Go to implementation | `goto_implementation` | | `a` | Go to the last accessed/alternate file | `goto_last_accessed_file` | -## Match mode +#### Match mode Enter this mode using `m` from normal mode. See the relavant section in [Usage](./usage.md) for an explanation about [surround](./usage.md#surround) @@ -192,11 +168,9 @@ and [textobject](./usage.md#textobject) usage. | `a` `` | Select around textobject | `select_textobject_around` | | `i` `` | Select inside textobject | `select_textobject_inner` | -## Object mode - TODO: Mappings for selecting syntax nodes (a superset of `[`). -## Window mode +#### Window mode This layer is similar to vim keybindings as kakoune does not support window. @@ -207,9 +181,9 @@ This layer is similar to vim keybindings as kakoune does not support window. | `h`, `Ctrl-h` | Horizontal bottom split | `hsplit` | | `q`, `Ctrl-q` | Close current window | `wclose` | -## Space mode +#### Space mode -This layer is a kludge of mappings I had under leader key in neovim. +This layer is a kludge of mappings, mostly pickers. | Key | Description | Command | | ----- | ----------- | ------- | @@ -226,6 +200,36 @@ This layer is a kludge of mappings I had under leader key in neovim. | `Y` | Yank main selection to clipboard | `yank_main_selection_to_clipboard` | | `R` | Replace selections by clipboard contents | `replace_selections_with_clipboard` | + +#### Unimpaired + +Mappings in the style of [vim-unimpaired](https://github.com/tpope/vim-unimpaired). + +| Key | Description | Command | +| ----- | ----------- | ------- | +| `[d` | Go to previous diagnostic | `goto_prev_diag` | +| `]d` | Go to next diagnostic | `goto_next_diag` | +| `[D` | Go to first diagnostic in document | `goto_first_diag` | +| `]D` | Go to last diagnostic in document | `goto_last_diag` | +| `[space` | Add newline above | `add_newline_above` | +| `]space` | Add newline below | `add_newline_below` | + +## Insert Mode + +| Key | Description | Command | +| ----- | ----------- | ------- | +| `Escape` | Switch to normal mode | `normal_mode` | +| `Ctrl-x` | Autocomplete | `completion` | +| `Ctrl-w` | Delete previous word | `delete_word_backward` | + +## Select / extend mode + +I'm still pondering whether to keep this mode or not. It changes movement +commands (including goto) to extend the existing selection instead of replacing it. + +> NOTE: It's a bit confusing at the moment because extend hasn't been +> implemented for all movement commands yet. + # Picker Keys to use within picker. Remapping currently not supported. diff --git a/book/src/themes.md b/book/src/themes.md index 804baa1c..fe5259d5 100644 --- a/book/src/themes.md +++ b/book/src/themes.md @@ -30,85 +30,9 @@ if the key contains a dot `'.'`, it must be quoted to prevent it being parsed as "key.key" = "#ffffff" ``` -Possible modifiers: +### Color palettes -| Modifier | -| --- | -| `bold` | -| `dim` | -| `italic` | -| `underlined` | -| `slow\_blink` | -| `rapid\_blink` | -| `reversed` | -| `hidden` | -| `crossed\_out` | - -Possible keys: - -| Key | Notes | -| --- | --- | -| `attribute` | | -| `keyword` | | -| `keyword.directive` | Preprocessor directives (\#if in C) | -| `keyword.control` | Control flow | -| `namespace` | | -| `punctuation` | | -| `punctuation.delimiter` | | -| `operator` | | -| `special` | | -| `property` | | -| `variable` | | -| `variable.parameter` | | -| `type` | | -| `type.builtin` | | -| `type.enum.variant` | Enum variants | -| `constructor` | | -| `function` | | -| `function.macro` | | -| `function.builtin` | | -| `comment` | | -| `variable.builtin` | | -| `constant` | | -| `constant.builtin` | | -| `string` | | -| `number` | | -| `escape` | Escaped characters | -| `label` | For lifetimes | -| `module` | | -| `ui.background` | | -| `ui.cursor` | | -| `ui.cursor.insert` | | -| `ui.cursor.select` | | -| `ui.cursor.match` | Matching bracket etc. | -| `ui.cursor.primary` | Cursor with primary selection | -| `ui.linenr` | | -| `ui.linenr.selected` | | -| `ui.statusline` | | -| `ui.statusline.inactive` | | -| `ui.popup` | | -| `ui.window` | | -| `ui.help` | | -| `ui.text` | | -| `ui.text.focus` | | -| `ui.info` | | -| `ui.info.text` | | -| `ui.menu` | | -| `ui.menu.selected` | | -| `ui.selection` | For selections in the editing area | -| `ui.selection.primary` | | -| `warning` | LSP warning | -| `error` | LSP error | -| `info` | LSP info | -| `hint` | LSP hint | - -These keys match [tree-sitter scopes](https://tree-sitter.github.io/tree-sitter/syntax-highlighting#theme). We half-follow the common scopes from [macromates language grammars](https://macromates.com/manual/en/language_grammars) with some differences. - -For a given highlight produced, styling will be determined based on the longest matching theme key. So it's enough to provide function to highlight `function.macro` and `function.builtin` as well, but you can use more specific scopes to highlight specific cases differently. - -## Color palettes - -You can define a palette of named colors, and refer to them from the +It's recommended define a palette of named colors, and refer to them from the configuration values in your theme. To do this, add a table called `palette` to your theme file: @@ -146,3 +70,125 @@ over it and is merged into the default palette. | `light-cyan` | | `light-gray` | | `white` | + +### Modifiers + +The following values may be used as modifiers. + +Less common modifiers might not be supported by your terminal emulator. + +| Modifier | +| --- | +| `bold` | +| `dim` | +| `italic` | +| `underlined` | +| `slow_blink` | +| `rapid_blink` | +| `reversed` | +| `hidden` | +| `crossed_out` | + +### Scopes + +The following is a list of scopes available to use for styling. + +#### Syntax highlighting + +These keys match [tree-sitter scopes](https://tree-sitter.github.io/tree-sitter/syntax-highlighting#theme). + +For a given highlight produced, styling will be determined based on the longest matching theme key. For example, the highlight `function.builtin.static` would match the key `function.builtin` rather than `function`. + +We use a similar set of scopes as +[SublimeText](https://www.sublimetext.com/docs/scope_naming.html). See also +[TextMate](https://macromates.com/manual/en/language_grammars) scopes. + +- `escape` (TODO: rename to (constant).character.escape) + +- `type` - Types + - `builtin` - Primitive types provided by the language (`int`, `usize`) + +- `constant` (TODO: constant.other.placeholder for %v) + - `builtin` Special constants provided by the language (`true`, `false`, `nil` etc) + - `boolean` + - `character` + +- `number` (TODO: rename to constant.number/.numeric.{integer, float, complex}) +- `string` (TODO: string.quoted.{single, double}, string.raw/.unquoted)? + - `regexp` - Regular expressions + - `special` + - `path` + - `url` + +- `comment` - Code comments + - `line` - Single line comments (`//`) + - `block` - Block comments (e.g. (`/* */`) + - `documentation` - Documentation comments (e.g. `///` in Rust) + +- `variable` - Variables + - `builtin` - Reserved language variables (`self`, `this`, `super`, etc) + - `parameter` - Function parameters + - `property` + - `function` (TODO: ?) + +- `label` + +- `punctuation` + - `delimiter` - Commas, colons + - `bracket` - Parentheses, angle brackets, etc. + +- `keyword` + - `control` + - `conditional` - `if`, `else` + - `repeat` - `for`, `while`, `loop` + - `import` - `import`, `export` + - (TODO: return?) + - `directive` - Preprocessor directives (`#if` in C) + - `function` - `fn`, `func` + +- `operator` - `||`, `+=`, `>`, `or` + +- `function` + - `builtin` + - `method` + - `macro` + - `special` (preprocesor in C) + +- `tag` - Tags (e.g. `` in HTML) + +- `namespace` + +#### Interface + +These scopes are used for theming the editor interface. + + +| Key | Notes | +| --- | --- | +| `ui.background` | | +| `ui.cursor` | | +| `ui.cursor.insert` | | +| `ui.cursor.select` | | +| `ui.cursor.match` | Matching bracket etc. | +| `ui.cursor.primary` | Cursor with primary selection | +| `ui.linenr` | | +| `ui.linenr.selected` | | +| `ui.statusline` | Statusline | +| `ui.statusline.inactive` | Statusline (unfocused document) | +| `ui.popup` | | +| `ui.window` | | +| `ui.help` | | +| `ui.text` | | +| `ui.text.focus` | | +| `ui.info` | | +| `ui.info.text` | | +| `ui.menu` | | +| `ui.menu.selected` | | +| `ui.selection` | For selections in the editing area | +| `ui.selection.primary` | | +| `warning` | Diagnostics warning | +| `error` | Diagnostics error | +| `info` | Diagnostics info | +| `hint` | Diagnostics hint | + + diff --git a/book/theme/css/general.css b/book/theme/css/general.css index 7749bded..ddc2387a 100644 --- a/book/theme/css/general.css +++ b/book/theme/css/general.css @@ -114,6 +114,19 @@ h6:target::before { margin-bottom: .875em; } +.content ul li { +margin-bottom: .25rem; +} +.content ul { + list-style-type: square; +} +.content ul ul, .content ol ul { + margin-bottom: .5rem; +} +.content li p { + margin-bottom: .5em; +} + .content p { line-height: 1.45em; } .content ol { line-height: 1.45em; } .content ul { line-height: 1.45em; } diff --git a/book/theme/css/variables.css b/book/theme/css/variables.css index a49d6794..db1a11b8 100644 --- a/book/theme/css/variables.css +++ b/book/theme/css/variables.css @@ -69,7 +69,7 @@ --links: #2b79a2; - --inline-code-color: #c5c8c6;; + --inline-code-color: #c5c8c6; --theme-popup-bg: #141617; --theme-popup-border: #43484d; @@ -110,7 +110,7 @@ --links: #20609f; - --inline-code-color: #301900; + --inline-code-color: #a39e9b; --theme-popup-bg: #fafafa; --theme-popup-border: #cccccc; @@ -151,7 +151,7 @@ --links: #2b79a2; - --inline-code-color: #c5c8c6;; + --inline-code-color: #c5c8c6; --theme-popup-bg: #161923; --theme-popup-border: #737480; @@ -192,7 +192,7 @@ --links: #2b79a2; - --inline-code-color: #6e6b5e; + --inline-code-color: #c5c8c6; --theme-popup-bg: #e1e1db; --theme-popup-border: #b38f6b; @@ -234,7 +234,7 @@ --links: #2b79a2; - --inline-code-color: #c5c8c6;; + --inline-code-color: #6e6b5e; --theme-popup-bg: #141617; --theme-popup-border: #43484d; @@ -261,6 +261,7 @@ .colibri { --bg: #3b224c; --fg: #bcbdd0; + --heading-fg: #fff; --sidebar-bg: #281733; --sidebar-fg: #c8c9db; @@ -276,18 +277,19 @@ /* --links: #a4a0e8; */ --links: #ECCDBA; - --inline-code-color: #c5c8c6;; + --inline-code-color: hsl(48.7, 7.8%, 70%); --theme-popup-bg: #161923; --theme-popup-border: #737480; --theme-hover: rgba(0,0,0, .2); - --quote-bg: hsl(226, 15%, 17%); + --quote-bg: #281733; --quote-border: hsl(226, 15%, 22%); - --table-border-color: hsl(226, 23%, 16%); - --table-header-bg: hsl(226, 23%, 31%); + --table-border-color: hsl(226, 23%, 76%); + --table-header-bg: hsla(226, 23%, 31%, 0); --table-alternate-bg: hsl(226, 23%, 14%); + --table-border-line: hsla(201deg, 20%, 92%, 0.2); --searchbar-border-color: #aaa; --searchbar-bg: #aeaec6; @@ -300,6 +302,7 @@ } .colibri { +/* --bg: #ffffff; --fg: #452859; --fg: #5a5977; @@ -318,7 +321,7 @@ --links: #6F44F0; - --inline-code-color: #697C81; + --inline-code-color: #a39e9b; --theme-popup-bg: #161923; --theme-popup-border: #737480; @@ -341,4 +344,5 @@ --searchresults-border-color: #5c5c68; --searchresults-li-bg: #242430; --search-mark-bg: #a2cff5; +*/ } diff --git a/book/theme/highlight.css b/book/theme/highlight.css index c2343227..8dce7d65 100644 --- a/book/theme/highlight.css +++ b/book/theme/highlight.css @@ -1,83 +1,56 @@ -/* - * An increased contrast highlighting scheme loosely based on the - * "Base16 Atelier Dune Light" theme by Bram de Haan - * (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune) - * Original Base16 color scheme by Chris Kempson - * (https://github.com/chriskempson/base16) - */ - -/* Comment */ +pre code.hljs { + display:block; + overflow-x:auto; + padding:1em +} +code.hljs { + padding:3px 5px +} +.hljs { + background:#2f1e2e; + color:#a39e9b +} .hljs-comment, .hljs-quote { - color: #575757; + color:#8d8687 } - -/* Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-attribute, -.hljs-tag, -.hljs-name, -.hljs-regexp, .hljs-link, +.hljs-meta, .hljs-name, +.hljs-regexp, +.hljs-selector-class, .hljs-selector-id, -.hljs-selector-class { - color: #d70025; +.hljs-tag, +.hljs-template-variable, +.hljs-variable { + color:#ef6155 } - -/* Orange */ -.hljs-number, -.hljs-meta, .hljs-built_in, -.hljs-builtin-name, +.hljs-deletion, .hljs-literal, -.hljs-type, -.hljs-params { - color: #b21e00; +.hljs-number, +.hljs-params, +.hljs-type { + color:#f99b15 } - -/* Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet { - color: #008200; +.hljs-attribute, +.hljs-section, +.hljs-title { + color:#fec418 } - -/* Blue */ -.hljs-title, -.hljs-section { - color: #0030f2; +.hljs-addition, +.hljs-bullet, +.hljs-string, +.hljs-symbol { + color:#48b685 } - -/* Purple */ .hljs-keyword, .hljs-selector-tag { - color: #9d00ec; -} - -.hljs { - display: block; - overflow-x: auto; - background: #f6f7f6; - color: #000; - padding: 0.5em; + color:#815ba4 } - .hljs-emphasis { - font-style: italic; + font-style:italic } - .hljs-strong { - font-weight: bold; -} - -.hljs-addition { - color: #22863a; - background-color: #f0fff4; -} - -.hljs-deletion { - color: #b31d28; - background-color: #ffeef0; + font-weight:700 } diff --git a/runtime/queries/ocaml/highlights.scm b/runtime/queries/ocaml/highlights.scm index 5554574d..160f2cb4 100644 --- a/runtime/queries/ocaml/highlights.scm +++ b/runtime/queries/ocaml/highlights.scm @@ -60,7 +60,7 @@ [(number) (signed_number)] @number -(character) @constant.builtin.character +(character) @constant.character (string) @string diff --git a/runtime/queries/rust/highlights.scm b/runtime/queries/rust/highlights.scm index c76d6adf..956a5dac 100644 --- a/runtime/queries/rust/highlights.scm +++ b/runtime/queries/rust/highlights.scm @@ -149,7 +149,7 @@ (mutable_specifier) @keyword.mut - +; TODO: variable.mut to highlight mutable identifiers via locals.scm ; ------- ; Guess Other Types diff --git a/runtime/themes/dark_plus.toml b/runtime/themes/dark_plus.toml index c105d52b..7eeb3f95 100644 --- a/runtime/themes/dark_plus.toml +++ b/runtime/themes/dark_plus.toml @@ -34,6 +34,7 @@ "comment" = { fg = "#6A9955" } "string" = { fg = "#ce9178" } +"string.regexp" = { fg = "regex" } "number" = { fg = "#b5cea8" } "escape" = { fg = "#d7ba7d" } diff --git a/runtime/themes/monokai.toml b/runtime/themes/monokai.toml index 2407591a..a8f03ff3 100644 --- a/runtime/themes/monokai.toml +++ b/runtime/themes/monokai.toml @@ -34,6 +34,7 @@ "comment" = { fg = "#88846F" } "string" = { fg = "#e6db74" } +"string.regexp" = { fg = "regex" } "number" = { fg = "#ae81ff" } "escape" = { fg = "#ae81ff" } diff --git a/theme.toml b/theme.toml index 867a0d2c..49f46b0b 100644 --- a/theme.toml +++ b/theme.toml @@ -28,9 +28,7 @@ escape = "honey" label = "honey" # TODO: diferentiate doc comment -# concat (ERROR) @syntax-error and "MISSING ;" selectors for errors - -module = "#ff0000" +# concat (ERROR) @error.syntax and "MISSING ;" selectors for errors "ui.background" = { bg = "midnight" } "ui.linenr" = { fg = "comet" } -- cgit v1.2.3-70-g09d2 From 94abc52b3b0929f399cea14e1efcf2c1d0a31ad8 Mon Sep 17 00:00:00 2001 From: Gokul Soumya Date: Fri, 10 Sep 2021 19:44:23 +0530 Subject: feat: Sticky view mode with Z (#719) --- book/src/keymap.md | 74 +++++++++++++++++++++++++++--------------------- helix-term/src/keymap.rs | 16 +++++++++++ 2 files changed, 57 insertions(+), 33 deletions(-) (limited to 'book') diff --git a/book/src/keymap.md b/book/src/keymap.md index 51e56eaa..4fa5033d 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -6,38 +6,39 @@ > NOTE: Unlike vim, `f`, `F`, `t` and `T` are not confined to the current line. -| Key | Description | Command | -| ----- | ----------- | ------- | -| `h`, `Left` | Move left | `move_char_left` | -| `j`, `Down` | Move down | `move_char_right` | -| `k`, `Up` | Move up | `move_line_up` | -| `l`, `Right` | Move right | `move_line_down` | -| `w` | Move next word start | `move_next_word_start` | -| `b` | Move previous word start | `move_prev_word_start` | -| `e` | Move next word end | `move_next_word_end` | -| `W` | Move next WORD start | `move_next_long_word_start` | -| `B` | Move previous WORD start | `move_prev_long_word_start` | -| `E` | Move next WORD end | `move_next_long_word_end` | -| `t` | Find 'till next char | `find_till_char` | -| `f` | Find next char | `find_next_char` | -| `T` | Find 'till previous char | `till_prev_char` | -| `F` | Find previous char | `find_prev_char` | -| `Home` | Move to the start of the line | `goto_line_start` | -| `End` | Move to the end of the line | `goto_line_end` | -| `PageUp` | Move page up | `page_up` | -| `PageDown` | Move page down | `page_down` | -| `Ctrl-u` | Move half page up | `half_page_up` | -| `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` | -| `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 | -| `:` | Enter command mode | `command_mode` | -| `z` | Enter [view mode](#view-mode) | N/A | -| `Ctrl-w` | Enter [window mode](#window-mode) | N/A | -| `Space` | Enter [space mode](#space-mode) | N/A | -| `K` | Show documentation for the item under the cursor | `hover` | +| Key | Description | Command | +| ----- | ----------- | ------- | +| `h`, `Left` | Move left | `move_char_left` | +| `j`, `Down` | Move down | `move_char_right` | +| `k`, `Up` | Move up | `move_line_up` | +| `l`, `Right` | Move right | `move_line_down` | +| `w` | Move next word start | `move_next_word_start` | +| `b` | Move previous word start | `move_prev_word_start` | +| `e` | Move next word end | `move_next_word_end` | +| `W` | Move next WORD start | `move_next_long_word_start` | +| `B` | Move previous WORD start | `move_prev_long_word_start` | +| `E` | Move next WORD end | `move_next_long_word_end` | +| `t` | Find 'till next char | `find_till_char` | +| `f` | Find next char | `find_next_char` | +| `T` | Find 'till previous char | `till_prev_char` | +| `F` | Find previous char | `find_prev_char` | +| `Home` | Move to the start of the line | `goto_line_start` | +| `End` | Move to the end of the line | `goto_line_end` | +| `PageUp` | Move page up | `page_up` | +| `PageDown` | Move page down | `page_down` | +| `Ctrl-u` | Move half page up | `half_page_up` | +| `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` | +| `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 | +| `:` | Enter command mode | `command_mode` | +| `z` | Enter [view mode](#view-mode) | N/A | +| `Z` | Enter sticky [view mode](#view-mode) | N/A | +| `Ctrl-w` | Enter [window mode](#window-mode) | N/A | +| `Space` | Enter [space mode](#space-mode) | N/A | +| `K` | Show documentation for the item under the cursor | `hover` | ### Changes @@ -120,7 +121,10 @@ These sub-modes are accessible from normal mode and typically switch back to nor #### View mode View mode is intended for scrolling and manipulating the view without changing -the selection. +the selection. The "sticky" variant of this mode is persistent; use the Escape +key to return to normal mode after usage (useful when you're simply looking +over text and not actively editing it). + | Key | Description | Command | | ----- | ----------- | ------- | @@ -130,6 +134,10 @@ the selection. | `m` | Align the line to the middle of the screen (horizontally) | `align_view_middle` | | `j` | Scroll the view downwards | `scroll_down` | | `k` | Scroll the view upwards | `scroll_up` | +| `f` | Move page down | `page_down` | +| `b` | Move page up | `page_up` | +| `d` | Move half page down | `half_page_down` | +| `u` | Move half page up | `half_page_up` | #### Goto mode diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index 1b9d87b5..f38c8a40 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -563,6 +563,22 @@ impl Default for Keymaps { "m" => align_view_middle, "k" => scroll_up, "j" => scroll_down, + "b" => page_up, + "f" => page_down, + "u" => half_page_up, + "d" => half_page_down, + }, + "Z" => { "View" sticky=true + "z" | "c" => align_view_center, + "t" => align_view_top, + "b" => align_view_bottom, + "m" => align_view_middle, + "k" => scroll_up, + "j" => scroll_down, + "b" => page_up, + "f" => page_down, + "u" => half_page_up, + "d" => half_page_down, }, "\"" => select_register, -- cgit v1.2.3-70-g09d2 From 3e12b0099342be12db1db64e36ca4ff29613f122 Mon Sep 17 00:00:00 2001 From: Omnikar Date: Mon, 13 Sep 2021 04:48:12 -0400 Subject: Add `no_op` command (#743) * Add `no_op` command * Document `no_op` in `remapping.md`--- book/src/remapping.md | 2 ++ helix-term/src/commands.rs | 3 +++ 2 files changed, 5 insertions(+) (limited to 'book') diff --git a/book/src/remapping.md b/book/src/remapping.md index 3f25e364..81f45da3 100644 --- a/book/src/remapping.md +++ b/book/src/remapping.md @@ -49,4 +49,6 @@ Control, Shift and Alt modifiers are encoded respectively with the prefixes | Null | `"null"` | | Escape | `"esc"` | +Keys can be disabled by binding them to the `no_op` command. + Commands can 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) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index fb885740..c5409494 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -162,6 +162,7 @@ impl Command { #[rustfmt::skip] commands!( + no_op, "Do nothing", move_char_left, "Move left", move_char_right, "Move right", move_line_up, "Move up", @@ -361,6 +362,8 @@ impl PartialEq for Command { } } +fn no_op(_cx: &mut Context) {} + fn move_impl(cx: &mut Context, move_fn: F, dir: Direction, behaviour: Movement) where F: Fn(RopeSlice, Range, Direction, usize, Movement) -> Range, -- cgit v1.2.3-70-g09d2 From 116e562ff652b54ba482143428bfbf4ac3fcd62e Mon Sep 17 00:00:00 2001 From: Gokul Soumya Date: Mon, 13 Sep 2021 14:18:58 +0530 Subject: Document `diagnostic` theme scope (#751) --- book/src/themes.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'book') diff --git a/book/src/themes.md b/book/src/themes.md index fe5259d5..a99e3a59 100644 --- a/book/src/themes.md +++ b/book/src/themes.md @@ -186,9 +186,9 @@ These scopes are used for theming the editor interface. | `ui.menu.selected` | | | `ui.selection` | For selections in the editing area | | `ui.selection.primary` | | -| `warning` | Diagnostics warning | -| `error` | Diagnostics error | -| `info` | Diagnostics info | -| `hint` | Diagnostics hint | - +| `warning` | Diagnostics warning (gutter) | +| `error` | Diagnostics error (gutter) | +| `info` | Diagnostics info (gutter) | +| `hint` | Diagnostics hint (gutter) | +| `diagnostic` | For text in editing area | -- cgit v1.2.3-70-g09d2 From 4a003782a51a94259ef3b5ddfacb2a148c5056e7 Mon Sep 17 00:00:00 2001 From: kraem Date: Mon, 20 Sep 2021 06:45:07 +0200 Subject: enable smart case regex search by default (#761) --- TODO.md | 2 -- book/src/configuration.md | 1 + book/src/keymap.md | 3 +-- helix-term/src/commands.rs | 12 ++++++++++-- helix-term/src/ui/mod.rs | 12 +++++++++++- helix-view/src/editor.rs | 3 +++ 6 files changed, 26 insertions(+), 7 deletions(-) (limited to 'book') diff --git a/TODO.md b/TODO.md index d81cf302..90e7e450 100644 --- a/TODO.md +++ b/TODO.md @@ -22,8 +22,6 @@ as you type completion! - [ ] lsp: signature help -- [ ] search: smart case by default: insensitive unless upper detected - 2 - [ ] macro recording - [ ] extend selection (treesitter select parent node) (replaces viw, vi(, va( etc ) diff --git a/book/src/configuration.md b/book/src/configuration.md index 5a28362d..90cdd8a7 100644 --- a/book/src/configuration.md +++ b/book/src/configuration.md @@ -17,6 +17,7 @@ To override global configuration parameters, create a `config.toml` file located | `scroll-lines` | Number of lines to scroll per scroll wheel step. | `3` | | `shell` | Shell to use when running external commands. | Unix: `["sh", "-c"]`
Windows: `["cmd", "/C"]` | | `line-number` | Line number display (`absolute`, `relative`) | `absolute` | +| `smart-case` | Enable smart case regex searching (case insensitive unless pattern contains upper case characters) | `true` | ## LSP diff --git a/book/src/keymap.md b/book/src/keymap.md index 4fa5033d..16d2420d 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -104,8 +104,7 @@ ### Search -> TODO: The search implementation isn't ideal yet -- we don't support searching -in reverse, or searching via smartcase. +> TODO: The search implementation isn't ideal yet -- we don't support searching in reverse. | Key | Description | Command | | ----- | ----------- | ------- | diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 703b92d1..d40bb9cf 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -5,7 +5,7 @@ use helix_core::{ match_brackets, movement::{self, Direction}, object, pos_at_coords, - regex::{self, Regex}, + regex::{self, Regex, RegexBuilder}, register::Register, search, selection, surround, textobject, LineEnding, Position, Range, Rope, RopeGraphemes, RopeSlice, Selection, SmallVec, Tendril, Transaction, @@ -1154,7 +1154,15 @@ fn search_next_impl(cx: &mut Context, extend: bool) { if let Some(query) = registers.read('/') { let query = query.last().unwrap(); let contents = doc.text().slice(..).to_string(); - if let Ok(regex) = Regex::new(query) { + let case_insensitive = if cx.editor.config.smart_case { + !query.chars().any(char::is_uppercase) + } else { + false + }; + if let Ok(regex) = RegexBuilder::new(query) + .case_insensitive(case_insensitive) + .build() + { search_impl(doc, view, &contents, ®ex, extend); } else { // get around warning `mutable_borrow_reservation_conflict` diff --git a/helix-term/src/ui/mod.rs b/helix-term/src/ui/mod.rs index 07eef352..f6536eb2 100644 --- a/helix-term/src/ui/mod.rs +++ b/helix-term/src/ui/mod.rs @@ -20,6 +20,7 @@ pub use spinner::{ProgressSpinners, Spinner}; pub use text::Text; use helix_core::regex::Regex; +use helix_core::regex::RegexBuilder; use helix_view::{Document, Editor, View}; use std::path::PathBuf; @@ -53,7 +54,16 @@ pub fn regex_prompt( return; } - match Regex::new(input) { + let case_insensitive = if cx.editor.config.smart_case { + !input.chars().any(char::is_uppercase) + } else { + false + }; + + match RegexBuilder::new(input) + .case_insensitive(case_insensitive) + .build() + { Ok(regex) => { let (view, doc) = current!(cx.editor); diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index a3d0d032..b7df4a9b 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -39,6 +39,8 @@ pub struct Config { pub line_number: LineNumber, /// Middle click paste support. Defaults to true pub middle_click_paste: bool, + /// Smart case: Case insensitive searching unless pattern contains upper case characters. Defaults to true. + pub smart_case: bool, } #[derive(Debug, Clone, PartialEq, Eq, Deserialize)] @@ -64,6 +66,7 @@ impl Default for Config { }, line_number: LineNumber::Absolute, middle_click_paste: true, + smart_case: true, } } } -- cgit v1.2.3-70-g09d2 From 9456d5c1a258e71bbb7e391dec8c3efb819e2d7d Mon Sep 17 00:00:00 2001 From: Leoi Hung Kin Date: Wed, 22 Sep 2021 00:03:12 +0800 Subject: Initial implementation of global search (#651) * initial implementation of global search * use tokio::sync::mpsc::unbounded_channel instead of Arc, Mutex, Waker poll_fn * use tokio_stream::wrappers::UnboundedReceiverStream to collect all search matches * regex_prompt: unified callback; refactor * global search doc--- Cargo.lock | 74 ++++++++++++++++++ book/src/keymap.md | 4 +- helix-term/Cargo.toml | 5 ++ helix-term/src/commands.rs | 188 +++++++++++++++++++++++++++++++++++++++------ helix-term/src/keymap.rs | 1 + helix-term/src/ui/mod.rs | 12 ++- 6 files changed, 259 insertions(+), 25 deletions(-) (limited to 'book') diff --git a/Cargo.lock b/Cargo.lock index 858c374b..2f586cb1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,9 +41,17 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279" dependencies = [ + "lazy_static", "memchr", + "regex-automata", ] +[[package]] +name = "bytecount" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72feb31ffc86498dacdbd0fcebb56138e7177a8cc5cea4516031d15ae85a742e" + [[package]] name = "bytes" version = "1.0.1" @@ -174,6 +182,15 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "encoding_rs_io" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cc3c5651fb62ab8aa3103998dade57efdd028544bd300516baa31840c252a83" +dependencies = [ + "encoding_rs", +] + [[package]] name = "error-code" version = "2.3.0" @@ -300,6 +317,45 @@ dependencies = [ "regex", ] +[[package]] +name = "grep-matcher" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d27563c33062cd33003b166ade2bb4fd82db1fd6a86db764dfdad132d46c1cc" +dependencies = [ + "memchr", +] + +[[package]] +name = "grep-regex" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121553c9768c363839b92fc2d7cdbbad44a3b70e8d6e7b1b72b05c977527bd06" +dependencies = [ + "aho-corasick", + "bstr", + "grep-matcher", + "log", + "regex", + "regex-syntax", + "thread_local", +] + +[[package]] +name = "grep-searcher" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fbdbde90ba52adc240d2deef7b6ad1f99f53142d074b771fe9b7bede6c4c23d" +dependencies = [ + "bstr", + "bytecount", + "encoding_rs", + "encoding_rs_io", + "grep-matcher", + "log", + "memmap2", +] + [[package]] name = "helix-core" version = "0.4.1" @@ -361,6 +417,8 @@ dependencies = [ "fern", "futures-util", "fuzzy-matcher", + "grep-regex", + "grep-searcher", "helix-core", "helix-lsp", "helix-tui", @@ -375,6 +433,7 @@ dependencies = [ "signal-hook", "signal-hook-tokio", "tokio", + "tokio-stream", "toml", ] @@ -552,6 +611,15 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +[[package]] +name = "memmap2" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b6c2ebff6180198788f5db08d7ce3bc1d0b617176678831a7510825973e357" +dependencies = [ + "libc", +] + [[package]] name = "mio" version = "0.7.13" @@ -753,6 +821,12 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" + [[package]] name = "regex-syntax" version = "0.6.25" diff --git a/book/src/keymap.md b/book/src/keymap.md index 16d2420d..5928a1ae 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -206,8 +206,10 @@ This layer is a kludge of mappings, mostly pickers. | `y` | Join and yank selections to clipboard | `yank_joined_to_clipboard` | | `Y` | Yank main selection to clipboard | `yank_main_selection_to_clipboard` | | `R` | Replace selections by clipboard contents | `replace_selections_with_clipboard` | +| `/` | Global search in workspace folder | `global_search` | - +> NOTE: Global search display results in a fuzzy picker, use `space + '` to bring it back up after opening a file. + #### Unimpaired Mappings in the style of [vim-unimpaired](https://github.com/tpope/vim-unimpaired). diff --git a/helix-term/Cargo.toml b/helix-term/Cargo.toml index 57d592cc..fe4da96e 100644 --- a/helix-term/Cargo.toml +++ b/helix-term/Cargo.toml @@ -55,5 +55,10 @@ toml = "0.5" serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } +# ripgrep for global search +grep-regex = "0.1.9" +grep-searcher = "0.1.8" +tokio-stream = "0.1.7" + [target.'cfg(not(windows))'.dependencies] # https://github.com/vorner/signal-hook/issues/100 signal-hook-tokio = { version = "0.3", features = ["futures-v0_3"] } diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index d40bb9cf..5005962f 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -31,7 +31,7 @@ use crate::{ }; use crate::job::{self, Job, Jobs}; -use futures_util::FutureExt; +use futures_util::{FutureExt, StreamExt}; use std::num::NonZeroUsize; use std::{fmt, future::Future}; @@ -43,6 +43,11 @@ use std::{ use once_cell::sync::Lazy; use serde::de::{self, Deserialize, Deserializer}; +use grep_regex::RegexMatcher; +use grep_searcher::{sinks, BinaryDetection, SearcherBuilder}; +use ignore::{DirEntry, WalkBuilder, WalkState}; +use tokio_stream::wrappers::UnboundedReceiverStream; + pub struct Context<'a> { pub register: Option, pub count: Option, @@ -209,6 +214,7 @@ impl Command { search_next, "Select next search match", extend_search_next, "Add next search match to selection", search_selection, "Use current selection as search pattern", + global_search, "Global Search in workspace folder", extend_line, "Select current line, if already selected, extend to next line", extend_to_line_bounds, "Extend selection to line bounds (line-wise selection)", delete_selection, "Delete selection", @@ -1061,24 +1067,41 @@ fn select_all(cx: &mut Context) { fn select_regex(cx: &mut Context) { let reg = cx.register.unwrap_or('/'); - let prompt = ui::regex_prompt(cx, "select:".into(), Some(reg), move |view, doc, regex| { - let text = doc.text().slice(..); - if let Some(selection) = selection::select_on_matches(text, doc.selection(view.id), ®ex) - { - doc.set_selection(view.id, selection); - } - }); + let prompt = ui::regex_prompt( + cx, + "select:".into(), + Some(reg), + move |view, doc, regex, event| { + if event != PromptEvent::Update { + return; + } + let text = doc.text().slice(..); + if let Some(selection) = + selection::select_on_matches(text, doc.selection(view.id), ®ex) + { + doc.set_selection(view.id, selection); + } + }, + ); cx.push_layer(Box::new(prompt)); } fn split_selection(cx: &mut Context) { let reg = cx.register.unwrap_or('/'); - let prompt = ui::regex_prompt(cx, "split:".into(), Some(reg), move |view, doc, regex| { - let text = doc.text().slice(..); - let selection = selection::split_on_matches(text, doc.selection(view.id), ®ex); - doc.set_selection(view.id, selection); - }); + let prompt = ui::regex_prompt( + cx, + "split:".into(), + Some(reg), + move |view, doc, regex, event| { + if event != PromptEvent::Update { + return; + } + let text = doc.text().slice(..); + let selection = selection::split_on_matches(text, doc.selection(view.id), ®ex); + doc.set_selection(view.id, selection); + }, + ); cx.push_layer(Box::new(prompt)); } @@ -1141,9 +1164,17 @@ fn search(cx: &mut Context) { // feed chunks into the regex yet let contents = doc.text().slice(..).to_string(); - let prompt = ui::regex_prompt(cx, "search:".into(), Some(reg), move |view, doc, regex| { - search_impl(doc, view, &contents, ®ex, false); - }); + let prompt = ui::regex_prompt( + cx, + "search:".into(), + Some(reg), + move |view, doc, regex, event| { + if event != PromptEvent::Update { + return; + } + search_impl(doc, view, &contents, ®ex, false); + }, + ); cx.push_layer(Box::new(prompt)); } @@ -1192,6 +1223,111 @@ fn search_selection(cx: &mut Context) { cx.editor.set_status(msg); } +fn global_search(cx: &mut Context) { + let (all_matches_sx, all_matches_rx) = + tokio::sync::mpsc::unbounded_channel::<(usize, PathBuf)>(); + let prompt = ui::regex_prompt( + cx, + "global search:".into(), + None, + move |_view, _doc, regex, event| { + if event != PromptEvent::Validate { + return; + } + if let Ok(matcher) = RegexMatcher::new_line_matcher(regex.as_str()) { + let searcher = SearcherBuilder::new() + .binary_detection(BinaryDetection::quit(b'\x00')) + .build(); + + let search_root = std::env::current_dir() + .expect("Global search error: Failed to get current dir"); + WalkBuilder::new(search_root).build_parallel().run(|| { + let mut searcher_cl = searcher.clone(); + let matcher_cl = matcher.clone(); + let all_matches_sx_cl = all_matches_sx.clone(); + Box::new(move |dent: Result| -> WalkState { + let dent = match dent { + Ok(dent) => dent, + Err(_) => return WalkState::Continue, + }; + + match dent.file_type() { + Some(fi) => { + if !fi.is_file() { + return WalkState::Continue; + } + } + None => return WalkState::Continue, + } + + let result_sink = sinks::UTF8(|line_num, _| { + match all_matches_sx_cl + .send((line_num as usize - 1, dent.path().to_path_buf())) + { + Ok(_) => Ok(true), + Err(_) => Ok(false), + } + }); + let result = searcher_cl.search_path(&matcher_cl, dent.path(), result_sink); + + if let Err(err) = result { + log::error!("Global search error: {}, {}", dent.path().display(), err); + } + WalkState::Continue + }) + }); + } else { + // Otherwise do nothing + // log::warn!("Global Search Invalid Pattern") + } + }, + ); + + cx.push_layer(Box::new(prompt)); + + let show_picker = async move { + let all_matches: Vec<(usize, PathBuf)> = + UnboundedReceiverStream::new(all_matches_rx).collect().await; + let call: job::Callback = + Box::new(move |editor: &mut Editor, compositor: &mut Compositor| { + if all_matches.is_empty() { + editor.set_status("No matches found".to_string()); + return; + } + let picker = FilePicker::new( + all_matches, + move |(_line_num, path)| path.to_str().unwrap().into(), + move |editor: &mut Editor, (line_num, path), action| { + match editor.open(path.into(), action) { + Ok(_) => {} + Err(e) => { + editor.set_error(format!( + "Failed to open file '{}': {}", + path.display(), + e + )); + return; + } + } + + let line_num = *line_num; + let (view, doc) = current!(editor); + let text = doc.text(); + let start = text.line_to_char(line_num); + let end = text.line_to_char((line_num + 1).min(text.len_lines())); + + doc.set_selection(view.id, Selection::single(start, end)); + align_view(doc, view, Align::Center); + }, + |_editor, (line_num, path)| Some((path.clone(), Some((*line_num, *line_num)))), + ); + compositor.push(Box::new(picker)); + }); + Ok(call) + }; + cx.jobs.callback(show_picker); +} + fn extend_line(cx: &mut Context) { let count = cx.count(); let (view, doc) = current!(cx.editor); @@ -3847,13 +3983,21 @@ fn join_selections(cx: &mut Context) { fn keep_selections(cx: &mut Context) { // keep selections matching regex let reg = cx.register.unwrap_or('/'); - let prompt = ui::regex_prompt(cx, "keep:".into(), Some(reg), move |view, doc, regex| { - let text = doc.text().slice(..); + let prompt = ui::regex_prompt( + cx, + "keep:".into(), + Some(reg), + move |view, doc, regex, event| { + if event != PromptEvent::Update { + return; + } + let text = doc.text().slice(..); - if let Some(selection) = selection::keep_matches(text, doc.selection(view.id), ®ex) { - doc.set_selection(view.id, selection); - } - }); + if let Some(selection) = selection::keep_matches(text, doc.selection(view.id), ®ex) { + doc.set_selection(view.id, selection); + } + }, + ); cx.push_layer(Box::new(prompt)); } diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index f38c8a40..f9bfcc50 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -555,6 +555,7 @@ impl Default for Keymaps { "P" => paste_clipboard_before, "R" => replace_selections_with_clipboard, "space" => keep_primary_selection, + "/" => global_search, }, "z" => { "View" "z" | "c" => align_view_center, diff --git a/helix-term/src/ui/mod.rs b/helix-term/src/ui/mod.rs index f6536eb2..810a9966 100644 --- a/helix-term/src/ui/mod.rs +++ b/helix-term/src/ui/mod.rs @@ -29,7 +29,7 @@ pub fn regex_prompt( cx: &mut crate::commands::Context, prompt: std::borrow::Cow<'static, str>, history_register: Option, - fun: impl Fn(&mut View, &mut Document, Regex) + 'static, + fun: impl Fn(&mut View, &mut Document, Regex, PromptEvent) + 'static, ) -> Prompt { let (view, doc) = current!(cx.editor); let view_id = view.id; @@ -47,6 +47,14 @@ pub fn regex_prompt( } PromptEvent::Validate => { // TODO: push_jump to store selection just before jump + + match Regex::new(input) { + Ok(regex) => { + let (view, doc) = current!(cx.editor); + fun(view, doc, regex, event); + } + Err(_err) => (), // TODO: mark command line as error + } } PromptEvent::Update => { // skip empty input, TODO: trigger default @@ -70,7 +78,7 @@ pub fn regex_prompt( // revert state to what it was before the last update doc.set_selection(view.id, snapshot.clone()); - fun(view, doc, regex); + fun(view, doc, regex, event); view.ensure_cursor_in_view(doc, cx.editor.config.scrolloff); } -- cgit v1.2.3-70-g09d2 From a958d34bfbcf45c01ce0d9c0d76e681fb863fc6a Mon Sep 17 00:00:00 2001 From: lurpahi Date: Thu, 23 Sep 2021 18:28:44 -0700 Subject: Add option for automatic insertion of closing-parens/brackets/etc (#779) * Add auto-pair editor option * Document auto-pair editor option * Make cargo fmt happy * Actually make cargo fmt happy * Rename auto-pair option to auto-pairs * Inline a few constants Co-authored-by: miaomai --- book/src/configuration.md | 1 + helix-term/src/commands.rs | 11 +++++++---- helix-view/src/editor.rs | 3 +++ 3 files changed, 11 insertions(+), 4 deletions(-) (limited to 'book') diff --git a/book/src/configuration.md b/book/src/configuration.md index 90cdd8a7..60b12bfd 100644 --- a/book/src/configuration.md +++ b/book/src/configuration.md @@ -18,6 +18,7 @@ To override global configuration parameters, create a `config.toml` file located | `shell` | Shell to use when running external commands. | Unix: `["sh", "-c"]`
Windows: `["cmd", "/C"]` | | `line-number` | Line number display (`absolute`, `relative`) | `absolute` | | `smart-case` | Enable smart case regex searching (case insensitive unless pattern contains upper case characters) | `true` | +| `auto-pairs` | Enable automatic insertion of pairs to parenthese, brackets, etc. | `true` | ## LSP diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index ac93b5d0..117ba046 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -3371,17 +3371,20 @@ pub mod insert { } use helix_core::auto_pairs; - const HOOKS: &[Hook] = &[auto_pairs::hook, insert]; - const POST_HOOKS: &[PostHook] = &[completion, signature_help]; pub fn insert_char(cx: &mut Context, c: char) { let (view, doc) = current!(cx.editor); + let hooks: &[Hook] = match cx.editor.config.auto_pairs { + true => &[auto_pairs::hook, insert], + false => &[insert], + }; + let text = doc.text(); let selection = doc.selection(view.id).clone().cursors(text.slice(..)); // run through insert hooks, stopping on the first one that returns Some(t) - for hook in HOOKS { + for hook in hooks { if let Some(transaction) = hook(text, &selection, c) { doc.apply(&transaction, view.id); break; @@ -3391,7 +3394,7 @@ pub mod insert { // TODO: need a post insert hook too for certain triggers (autocomplete, signature help, etc) // this could also generically look at Transaction, but it's a bit annoying to look at // Operation instead of Change. - for hook in POST_HOOKS { + for hook in &[completion, signature_help] { hook(cx, c); } } diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index b7df4a9b..b08a2df2 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -41,6 +41,8 @@ pub struct Config { pub middle_click_paste: bool, /// Smart case: Case insensitive searching unless pattern contains upper case characters. Defaults to true. pub smart_case: bool, + /// Automatic insertion of pairs to parentheses, brackets, etc. Defaults to true. + pub auto_pairs: bool, } #[derive(Debug, Clone, PartialEq, Eq, Deserialize)] @@ -67,6 +69,7 @@ impl Default for Config { line_number: LineNumber::Absolute, middle_click_paste: true, smart_case: true, + auto_pairs: true, } } } -- cgit v1.2.3-70-g09d2 From 9ea9e779b2eef293c14ae50d5767035c0a9544a5 Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Wed, 8 Sep 2021 16:53:10 +0900 Subject: experiment: Move keep_primary_selection to , --- book/src/keymap.md | 3 +-- helix-term/src/commands.rs | 4 ++++ helix-term/src/keymap.rs | 5 +---- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'book') diff --git a/book/src/keymap.md b/book/src/keymap.md index 5928a1ae..aed48d5b 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -86,6 +86,7 @@ | `Alt-s` | Split selection on newlines | `split_selection_on_newline` | | `;` | Collapse selection onto a single cursor | `collapse_selection` | | `Alt-;` | Flip selection cursor and anchor | `flip_selections` | +| `,` | Keep only the primary selection | `keep_primary_selection` | | `C` | Copy selection onto the next line | `copy_selection_on_next_line` | | `Alt-C` | Copy selection onto the previous line | `copy_selection_on_prev_line` | | `(` | Rotate main selection forward | `rotate_selections_backward` | @@ -99,7 +100,6 @@ | `J` | Join lines inside selection | `join_selections` | | `K` | Keep selections matching the regex TODO: overlapped by hover help | `keep_selections` | | `$` | Pipe each selection into shell command, keep selections where command returned 0 | `shell_keep_pipe` | -| `Space` | Keep only the primary selection TODO: overlapped by space mode | `keep_primary_selection` | | `Ctrl-c` | Comment/uncomment the selections | `toggle_comments` | ### Search @@ -200,7 +200,6 @@ This layer is a kludge of mappings, mostly pickers. | `a` | Apply code action | `code_action` | | `'` | Open last fuzzy picker | `last_picker` | | `w` | Enter [window mode](#window-mode) | N/A | -| `space` | Keep primary selection TODO: it's here because space mode replaced it | `keep_primary_selection` | | `p` | Paste system clipboard after selections | `paste_clipboard_after` | | `P` | Paste system clipboard before selections | `paste_clipboard_before` | | `y` | Join and yank selections to clipboard | `yank_joined_to_clipboard` | diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 117ba046..e3c351f6 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -2825,6 +2825,10 @@ fn open_above(cx: &mut Context) { fn normal_mode(cx: &mut Context) { let (view, doc) = current!(cx.editor); + if doc.mode == Mode::Normal { + return; + } + doc.mode = Mode::Normal; doc.append_changes_to_history(view.id); diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index f9bfcc50..a83b960e 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -436,7 +436,6 @@ impl Default for Keymaps { "A" => append_to_line, "o" => open_below, "O" => open_above, - // [ ] equivalents too (add blank new line, no edit) "d" => delete_selection, // TODO: also delete without yanking @@ -500,8 +499,7 @@ impl Default for Keymaps { "K" => keep_selections, // TODO: and another method for inverse - // TODO: clashes with space mode - "space" => keep_primary_selection, + "," => keep_primary_selection, // "q" => record_macro, // "Q" => replay_macro, @@ -554,7 +552,6 @@ impl Default for Keymaps { "p" => paste_clipboard_after, "P" => paste_clipboard_before, "R" => replace_selections_with_clipboard, - "space" => keep_primary_selection, "/" => global_search, }, "z" => { "View" -- cgit v1.2.3-70-g09d2 From 75dba1f9560c6ea579e79ff074e60ba2fb87ca63 Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Wed, 8 Sep 2021 17:21:10 +0900 Subject: experiment: space+k for LSP doc, K for keep_selections --- book/src/keymap.md | 4 ++-- helix-term/src/keymap.rs | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'book') diff --git a/book/src/keymap.md b/book/src/keymap.md index aed48d5b..78bac0cf 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -38,7 +38,6 @@ | `Z` | Enter sticky [view mode](#view-mode) | N/A | | `Ctrl-w` | Enter [window mode](#window-mode) | N/A | | `Space` | Enter [space mode](#space-mode) | N/A | -| `K` | Show documentation for the item under the cursor | `hover` | ### Changes @@ -98,7 +97,7 @@ | `X` | Extend selection to line bounds (line-wise selection) | `extend_to_line_bounds` | | | Expand selection to parent syntax node TODO: pick a key | `expand_selection` | | `J` | Join lines inside selection | `join_selections` | -| `K` | Keep selections matching the regex TODO: overlapped by hover help | `keep_selections` | +| `K` | Keep selections matching the regex | `keep_selections` | | `$` | Pipe each selection into shell command, keep selections where command returned 0 | `shell_keep_pipe` | | `Ctrl-c` | Comment/uncomment the selections | `toggle_comments` | @@ -194,6 +193,7 @@ This layer is a kludge of mappings, mostly pickers. | Key | Description | Command | | ----- | ----------- | ------- | +| `k` | Show documentation for the item under the cursor | `hover` | | `f` | Open file picker | `file_picker` | | `b` | Open buffer picker | `buffer_picker` | | `s` | Open symbol picker (current document) | `symbol_picker` | diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index a83b960e..4343a0b6 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -495,7 +495,6 @@ impl Default for Keymaps { "<" => unindent, "=" => format_selections, "J" => join_selections, - // TODO: conflicts hover/doc "K" => keep_selections, // TODO: and another method for inverse @@ -527,7 +526,6 @@ impl Default for Keymaps { // move under c "C-c" => toggle_comments, - "K" => hover, // z family for save/restore/combine from/to sels from register @@ -553,6 +551,7 @@ impl Default for Keymaps { "P" => paste_clipboard_before, "R" => replace_selections_with_clipboard, "/" => global_search, + "k" => hover, }, "z" => { "View" "z" | "c" => align_view_center, -- cgit v1.2.3-70-g09d2