Skip to content

Commit

Permalink
Load alt default theme if true color is not supported
Browse files Browse the repository at this point in the history
* 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`
  • Loading branch information
Omnikar authored and archseer committed Dec 13, 2021
1 parent 43d17c4 commit 98ce2a3
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 20 deletions.
File renamed without changes.
1 change: 1 addition & 0 deletions book/src/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
28 changes: 19 additions & 9 deletions helix-term/src/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
14 changes: 12 additions & 2 deletions helix-term/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2366,8 +2366,18 @@ pub mod cmd {
args: &[Cow<str>],
_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(
Expand Down
6 changes: 6 additions & 0 deletions helix-term/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
1 change: 1 addition & 0 deletions helix-term/src/ui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
12 changes: 3 additions & 9 deletions helix-view/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -137,6 +139,7 @@ impl Default for Config {
completion_trigger_len: 2,
auto_info: true,
file_picker: FilePickerConfig::default(),
true_color: false,
}
}
}
Expand Down Expand Up @@ -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)?;
Expand Down
20 changes: 20 additions & 0 deletions helix-view/src/theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ pub use crate::graphics::{Color, Modifier, Style};
pub static DEFAULT_THEME: Lazy<Theme> = Lazy::new(|| {
toml::from_slice(include_bytes!("../../theme.toml")).expect("Failed to parse default theme")
});
pub static BASE16_DEFAULT_THEME: Lazy<Theme> = Lazy::new(|| {
toml::from_slice(include_bytes!("../../base16_theme.toml"))
.expect("Failed to parse base 16 default theme")
});

#[derive(Clone, Debug)]
pub struct Loader {
Expand All @@ -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);
Expand Down Expand Up @@ -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)]
Expand Down Expand Up @@ -154,6 +166,14 @@ impl Theme {
pub fn find_scope_index(&self, scope: &str) -> Option<usize> {
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 {
Expand Down

0 comments on commit 98ce2a3

Please sign in to comment.