on master help sign in
Load alt default theme if true color is not supported
98ce2a3Omnikar
runtime/themes/base16_terminal.toml → base16_theme.tomlrenamed

The content is the same.

book/src/configuration.md+1
@@ -23,6 +23,7 @@ To override global configuration parameters, create a `config.toml` file located
23| `idle-timeout` | Time in milliseconds since last keypress before idle timers trigger. Used for autocompletion, set to 0 for instant. | `400` |
23| `idle-timeout` | Time in milliseconds since last keypress before idle timers trigger. Used for autocompletion, set to 0 for instant. | `400` |
24| `completion-trigger-len` | The min-length of word under cursor to trigger autocompletion | `2` |
24| `completion-trigger-len` | The min-length of word under cursor to trigger autocompletion | `2` |
25| `auto-info` | Whether to display infoboxes | `true` |
25| `auto-info` | Whether to display infoboxes | `true` |
26+| `true-color` | Set to `true` to override automatic detection of terminal truecolor support in the event of a false negative. | `false` |
26
27
27`[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.
28`[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.
28
29
helix-term/src/application.rs+19−9
@@ -76,17 +76,27 @@ impl Application {
76 None => Ok(def_lang_conf),
76 None => Ok(def_lang_conf),
77 };
77 };
78
78
79+ let true_color = config.editor.true_color || crate::true_color();
79− let theme = if let Some(theme) = &config.theme {
80+ let theme = config
81+ .theme
82+ .as_ref()
83+ .and_then(|theme| {
80− match theme_loader.load(theme) {
84+ theme_loader
81− Ok(theme) => theme,
85+ .load(theme)
82− Err(e) => {
86+ .map_err(|e| {
83− log::warn!("failed to load theme `{}` - {}", theme, e);
87+ log::warn!("failed to load theme `{}` - {}", theme, e);
88+ e
89+ })
90+ .ok()
91+ .filter(|theme| (true_color || theme.is_16_color()))
92+ })
93+ .unwrap_or_else(|| {
94+ if true_color {
84 theme_loader.default()
95 theme_loader.default()
96+ } else {
97+ theme_loader.base16_default()
85 }
98 }
86− }
99+ });
87− } else {
88− theme_loader.default()
89− };
90
100
91 let syn_loader_conf: helix_core::syntax::Configuration = lang_conf
101 let syn_loader_conf: helix_core::syntax::Configuration = lang_conf
92 .and_then(|conf| conf.try_into())
102 .and_then(|conf| conf.try_into())
helix-term/src/commands.rs+12−2
@@ -2366,8 +2366,18 @@ pub mod cmd {
2366 args: &[Cow<str>],
2366 args: &[Cow<str>],
2367 _event: PromptEvent,
2367 _event: PromptEvent,
2368 ) -> anyhow::Result<()> {
2368 ) -> anyhow::Result<()> {
2369− let theme = args.first().context("theme not provided")?;
2369+ let theme = args.first().context("Theme not provided")?;
2370− cx.editor.set_theme_from_name(theme)
2370+ let theme = cx
2371+ .editor
2372+ .theme_loader
2373+ .load(theme)
2374+ .with_context(|| format!("Failed setting theme {}", theme))?;
2375+ let true_color = cx.editor.config.true_color || crate::true_color();
2376+ if !(true_color || theme.is_16_color()) {
2377+ bail!("Unsupported theme: theme requires true color support");
2378+ }
2379+ cx.editor.set_theme(theme);
2380+ Ok(())
2371 }
2381 }
2372
2382
2373 fn yank_main_selection_to_clipboard(
2383 fn yank_main_selection_to_clipboard(
helix-term/src/lib.rs+6
@@ -9,3 +9,9 @@ pub mod config;
9pub mod job;
9pub mod job;
10pub mod keymap;
10pub mod keymap;
11pub mod ui;
11pub mod ui;
12+
13+fn true_color() -> bool {
14+ std::env::var("COLORTERM")
15+ .map(|v| matches!(v.as_str(), "truecolor" | "24bit"))
16+ .unwrap_or(false)
17+}
helix-term/src/ui/mod.rs+1
@@ -186,6 +186,7 @@ pub mod completers {
186 &helix_core::config_dir().join("themes"),
186 &helix_core::config_dir().join("themes"),
187 ));
187 ));
188 names.push("default".into());
188 names.push("default".into());
189+ names.push("base16_default".into());
189
190
190 let mut names: Vec<_> = names
191 let mut names: Vec<_> = names
191 .into_iter()
192 .into_iter()
helix-view/src/editor.rs+3−9
@@ -105,6 +105,8 @@ pub struct Config {
105 /// Whether to display infoboxes. Defaults to true.
105 /// Whether to display infoboxes. Defaults to true.
106 pub auto_info: bool,
106 pub auto_info: bool,
107 pub file_picker: FilePickerConfig,
107 pub file_picker: FilePickerConfig,
108+ /// Set to `true` to override automatic detection of terminal truecolor support in the event of a false negative. Defaults to `false`.
109+ pub true_color: bool,
108}
110}
109
111
110#[derive(Debug, Copy, Clone, PartialEq, Eq, Deserialize)]
112#[derive(Debug, Copy, Clone, PartialEq, Eq, Deserialize)]
@@ -137,6 +139,7 @@ impl Default for Config {
137 completion_trigger_len: 2,
139 completion_trigger_len: 2,
138 auto_info: true,
140 auto_info: true,
139 file_picker: FilePickerConfig::default(),
141 file_picker: FilePickerConfig::default(),
142+ true_color: false,
140 }
143 }
141 }
144 }
142}
145}
@@ -265,15 +268,6 @@ impl Editor {
265 self._refresh();
268 self._refresh();
266 }
269 }
267
270
268− pub fn set_theme_from_name(&mut self, theme: &str) -> anyhow::Result<()> {
269− let theme = self
270− .theme_loader
271− .load(theme.as_ref())
272− .with_context(|| format!("failed setting theme `{}`", theme))?;
273− self.set_theme(theme);
274− Ok(())
275− }
276−
277 /// Refreshes the language server for a given document
271 /// Refreshes the language server for a given document
278 pub fn refresh_language_server(&mut self, doc_id: DocumentId) -> Option<()> {
272 pub fn refresh_language_server(&mut self, doc_id: DocumentId) -> Option<()> {
279 let doc = self.documents.get_mut(&doc_id)?;
273 let doc = self.documents.get_mut(&doc_id)?;
helix-view/src/theme.rs+20
@@ -15,6 +15,10 @@ pub use crate::graphics::{Color, Modifier, Style};
15pub static DEFAULT_THEME: Lazy<Theme> = Lazy::new(|| {
15pub static DEFAULT_THEME: Lazy<Theme> = Lazy::new(|| {
16 toml::from_slice(include_bytes!("../../theme.toml")).expect("Failed to parse default theme")
16 toml::from_slice(include_bytes!("../../theme.toml")).expect("Failed to parse default theme")
17});
17});
18+pub static BASE16_DEFAULT_THEME: Lazy<Theme> = Lazy::new(|| {
19+ toml::from_slice(include_bytes!("../../base16_theme.toml"))
20+ .expect("Failed to parse base 16 default theme")
21+});
18
22
19#[derive(Clone, Debug)]
23#[derive(Clone, Debug)]
20pub struct Loader {
24pub struct Loader {
@@ -35,6 +39,9 @@ impl Loader {
35 if name == "default" {
39 if name == "default" {
36 return Ok(self.default());
40 return Ok(self.default());
37 }
41 }
42+ if name == "base16_default" {
43+ return Ok(self.base16_default());
44+ }
38 let filename = format!("{}.toml", name);
45 let filename = format!("{}.toml", name);
39
46
40 let user_path = self.user_dir.join(&filename);
47 let user_path = self.user_dir.join(&filename);
@@ -74,6 +81,11 @@ impl Loader {
74 pub fn default(&self) -> Theme {
81 pub fn default(&self) -> Theme {
75 DEFAULT_THEME.clone()
82 DEFAULT_THEME.clone()
76 }
83 }
84+
85+ /// Returns the alternative 16-color default theme
86+ pub fn base16_default(&self) -> Theme {
87+ BASE16_DEFAULT_THEME.clone()
88+ }
77}
89}
78
90
79#[derive(Clone, Debug)]
91#[derive(Clone, Debug)]
@@ -154,6 +166,14 @@ impl Theme {
154 pub fn find_scope_index(&self, scope: &str) -> Option<usize> {
166 pub fn find_scope_index(&self, scope: &str) -> Option<usize> {
155 self.scopes().iter().position(|s| s == scope)
167 self.scopes().iter().position(|s| s == scope)
156 }
168 }
169+
170+ pub fn is_16_color(&self) -> bool {
171+ self.styles.iter().all(|(_, style)| {
172+ [style.fg, style.bg]
173+ .into_iter()
174+ .all(|color| !matches!(color, Some(Color::Rgb(..))))
175+ })
176+ }
157}
177}
158
178
159struct ThemePalette {
179struct ThemePalette {