From 7961355ba1c0cd521372496c507a31a51b41ddf2 Mon Sep 17 00:00:00 2001 From: Gokul Soumya Date: Wed, 24 Nov 2021 12:17:41 +0530 Subject: Change cursor shape on mode change Fixes #323. Due to terminal limitations we can only change the shape of the primary cursor. --- book/src/configuration.md | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) (limited to 'book/src/configuration.md') diff --git a/book/src/configuration.md b/book/src/configuration.md index 2ed48d51..a40a8959 100644 --- a/book/src/configuration.md +++ b/book/src/configuration.md @@ -5,9 +5,26 @@ To override global configuration parameters, create a `config.toml` file located * Linux and Mac: `~/.config/helix/config.toml` * Windows: `%AppData%\helix\config.toml` +Example config: + +```toml +theme = "onedark" + +[editor] +line-number = "relative" +mouse = false + +[editor.cursor-shape] +normal = "underline" +insert = "block" + +[editor.file-picker] +hidden = false +``` + ## Editor -`[editor]` section of the config. +### `[editor]` Section | Key | Description | Default | |--|--|---------| @@ -24,7 +41,28 @@ To override global configuration parameters, create a `config.toml` file located | `completion-trigger-len` | The min-length of word under cursor to trigger autocompletion | `2` | | `auto-info` | Whether to display infoboxes | `true` | -`[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. +### `[editor.cursor-shape]` Section + +Defines the shape of cursor in each mode. Note that due to limitations +of the terminal environment, only the primary cursor can change shape. + +| Key | Description | Default | +| --- | ----------- | -------- | +| `normal` | Cursor shape in [normal mode][normal mode] | `block` | +| `insert` | Cursor shape in [insert mode][insert mode] | `bar` | +| `select` | Cursor shape in [select mode][select mode] | `underline` | + +[normal mode]: ./keymap.md#normal-mode +[insert mode]: ./keymap.md#insert-mode +[select mode]: ./keymap.md#select--extend-mode + +### `[editor.filepicker]` Section + +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. | Key | Description | Default | |--|--|---------| -- cgit v1.2.3-70-g09d2 From 058796c18e786309322731ff68b15a0f3901b60b Mon Sep 17 00:00:00 2001 From: Gokul Soumya Date: Mon, 29 Nov 2021 11:09:04 +0530 Subject: Change default cursors to block for all modes --- book/src/configuration.md | 15 ++++++++------- helix-view/src/editor.rs | 4 ++-- 2 files changed, 10 insertions(+), 9 deletions(-) (limited to 'book/src/configuration.md') diff --git a/book/src/configuration.md b/book/src/configuration.md index a40a8959..2998bcdc 100644 --- a/book/src/configuration.md +++ b/book/src/configuration.md @@ -15,8 +15,9 @@ line-number = "relative" mouse = false [editor.cursor-shape] -normal = "underline" -insert = "block" +insert = "bar" +normal = "block" +select = "underline" [editor.file-picker] hidden = false @@ -46,11 +47,11 @@ hidden = false Defines the shape of cursor in each mode. Note that due to limitations of the terminal environment, only the primary cursor can change shape. -| Key | Description | Default | -| --- | ----------- | -------- | -| `normal` | Cursor shape in [normal mode][normal mode] | `block` | -| `insert` | Cursor shape in [insert mode][insert mode] | `bar` | -| `select` | Cursor shape in [select mode][select mode] | `underline` | +| Key | Description | Default | +| --- | ----------- | ------- | +| `normal` | Cursor shape in [normal mode][normal mode] | `block` | +| `insert` | Cursor shape in [insert mode][insert mode] | `block` | +| `select` | Cursor shape in [select mode][select mode] | `block` | [normal mode]: ./keymap.md#normal-mode [insert mode]: ./keymap.md#insert-mode diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 9c77f270..b558c183 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -122,9 +122,9 @@ impl std::ops::Deref for CursorShapeConfig { impl Default for CursorShapeConfig { fn default() -> Self { Self(hashmap!( - Mode::Insert => CursorKind::Bar, + Mode::Insert => CursorKind::Block, Mode::Normal => CursorKind::Block, - Mode::Select => CursorKind::Underline, + Mode::Select => CursorKind::Block, )) } } -- 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/configuration.md') 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 97e12f5c5a26cbbc2eddffd91a2e506403d4d453 Mon Sep 17 00:00:00 2001 From: Cottser Date: Sat, 8 Jan 2022 21:45:54 -0500 Subject: docs: editor.filepicker -> editor.file-picker (#1465) --- book/src/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'book/src/configuration.md') diff --git a/book/src/configuration.md b/book/src/configuration.md index 33a933b2..be1a0809 100644 --- a/book/src/configuration.md +++ b/book/src/configuration.md @@ -25,7 +25,7 @@ To override global configuration parameters, create a `config.toml` file located | `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. +`[editor.file-picker]` 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. | Key | Description | Default | |--|--|---------| -- cgit v1.2.3-70-g09d2 From 333c2949c2b036f8aafa77be2286eb3c135ea269 Mon Sep 17 00:00:00 2001 From: Andrew Neth Date: Tue, 25 Jan 2022 09:18:01 -0600 Subject: feat(helix-view): dynamic line numbers (#1522) * feat(helix-view): dynamic line numbers * docs: describe editor.line-number in more detail * Make dynamic numbers the default behavior of `relative`--- book/src/configuration.md | 2 +- helix-view/src/editor.rs | 4 +++- helix-view/src/gutter.rs | 24 +++++++++++++----------- 3 files changed, 17 insertions(+), 13 deletions(-) (limited to 'book/src/configuration.md') diff --git a/book/src/configuration.md b/book/src/configuration.md index 7f2a4acf..8048f548 100644 --- a/book/src/configuration.md +++ b/book/src/configuration.md @@ -34,7 +34,7 @@ hidden = false | `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` | +| `line-number` | Line number display: `absolute` simply shows each line's number, while `relative` shows the distance from the current line. When unfocused or in insert mode, `relative` will still show absolute line numbers. | `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` | | `auto-completion` | Enable automatic pop up of auto-completion. | `true` | diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 82ef0cdc..aa2df6f7 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -170,7 +170,9 @@ impl Default for CursorShapeConfig { pub enum LineNumber { /// Show absolute line number Absolute, - /// Show relative line number to the primary cursor + + /// If focused and in normal/select mode, show relative line number to the primary cursor. + /// If unfocused or in insert mode, show absolute line number. Relative, } diff --git a/helix-view/src/gutter.rs b/helix-view/src/gutter.rs index af016c56..113da642 100644 --- a/helix-view/src/gutter.rs +++ b/helix-view/src/gutter.rs @@ -58,29 +58,31 @@ pub fn line_number<'doc>( .char_to_line(doc.selection(view.id).primary().cursor(text)); let config = config.line_number; + let mode = doc.mode; Box::new(move |line: usize, selected: bool, out: &mut String| { if line == last_line && !draw_last { write!(out, "{:>1$}", '~', width).unwrap(); Some(linenr) } else { - use crate::editor::LineNumber; - let line = match config { - LineNumber::Absolute => line + 1, - LineNumber::Relative => { - if current_line == line { - line + 1 - } else { - abs_diff(current_line, line) - } - } + use crate::{document::Mode, editor::LineNumber}; + + let relative = config == LineNumber::Relative + && mode != Mode::Insert + && is_focused + && current_line != line; + + let display_num = if relative { + abs_diff(current_line, line) + } else { + line + 1 }; let style = if selected && is_focused { linenr_select } else { linenr }; - write!(out, "{:>1$}", line, width).unwrap(); + write!(out, "{:>1$}", display_num, width).unwrap(); Some(style) } }) -- cgit v1.2.3-70-g09d2