mirror of https://github.com/helix-editor/helix
Compare commits
2 Commits
27d8bd20bf
...
5ce27b0087
Author | SHA1 | Date |
---|---|---|
|
5ce27b0087 | |
|
70deab1b19 |
|
@ -3215,9 +3215,9 @@ fn buffer_picker(cx: &mut Context) {
|
|||
spans.push(icon.to_span_with(|icon| format!("{icon} ")));
|
||||
}
|
||||
|
||||
spans.push(Span::raw(name.to_string()));
|
||||
spans.push(name.to_string().into());
|
||||
|
||||
Cell::from(Spans::from(spans))
|
||||
Spans::from(spans).into()
|
||||
}),
|
||||
];
|
||||
let picker = Picker::new(columns, 2, items, (), |cx, meta, action| {
|
||||
|
@ -3281,7 +3281,6 @@ fn jumplist_picker(cx: &mut Context) {
|
|||
.as_deref()
|
||||
.and_then(Path::to_str)
|
||||
.unwrap_or(SCRATCH_BUFFER_NAME);
|
||||
|
||||
let icons = ICONS.load();
|
||||
|
||||
let mut spans = Vec::with_capacity(2);
|
||||
|
@ -3290,9 +3289,9 @@ fn jumplist_picker(cx: &mut Context) {
|
|||
spans.push(icon.to_span_with(|icon| format!("{icon} ")));
|
||||
}
|
||||
|
||||
spans.push(Span::raw(name.to_string()));
|
||||
spans.push(name.to_string().into());
|
||||
|
||||
Cell::from(Spans::from(spans))
|
||||
Spans::from(spans).into()
|
||||
}),
|
||||
ui::PickerColumn::new("flags", |item: &JumpMeta, _| {
|
||||
let mut flags = Vec::new();
|
||||
|
|
|
@ -247,7 +247,6 @@ fn diag_picker(
|
|||
"severity",
|
||||
|item: &PickerDiagnostic, styles: &DiagnosticStyles| {
|
||||
let icons = ICONS.load();
|
||||
|
||||
match item.diag.severity {
|
||||
Some(DiagnosticSeverity::HINT) => {
|
||||
Span::styled(format!("{} HINT", icons.diagnostic().hint()), styles.hint)
|
||||
|
@ -416,9 +415,8 @@ pub fn symbol_picker(cx: &mut Context) {
|
|||
let call = move |_editor: &mut Editor, compositor: &mut Compositor| {
|
||||
let columns = [
|
||||
ui::PickerColumn::new("kind", |item: &SymbolInformationItem, _| {
|
||||
let name = display_symbol_kind(item.symbol.kind);
|
||||
|
||||
let icons = ICONS.load();
|
||||
let name = display_symbol_kind(item.symbol.kind);
|
||||
|
||||
if let Some(icon) = icons.kind().get(name) {
|
||||
icon.to_span_with(|icon| format!("{icon} {name}")).into()
|
||||
|
|
|
@ -107,8 +107,8 @@ impl menu::Item for CompletionItem {
|
|||
};
|
||||
|
||||
let icons = ICONS.load();
|
||||
|
||||
let name = &kind.0[0].content;
|
||||
|
||||
let is_folder = kind.0[0].content == "folder";
|
||||
|
||||
if let Some(icon) = icons.kind().get(name) {
|
||||
|
|
|
@ -9,7 +9,6 @@ use helix_core::{visual_offset_from_block, Position, RopeSlice};
|
|||
use helix_stdx::rope::RopeSliceExt;
|
||||
use helix_view::editor::{WhitespaceConfig, WhitespaceRenderValue};
|
||||
use helix_view::graphics::Rect;
|
||||
use helix_view::icons::ICONS;
|
||||
use helix_view::theme::Style;
|
||||
use helix_view::view::ViewPosition;
|
||||
use helix_view::{Document, Theme};
|
||||
|
@ -207,41 +206,38 @@ impl<'a> TextRenderer<'a> {
|
|||
viewport: Rect,
|
||||
) -> TextRenderer<'a> {
|
||||
let editor_config = doc.config.load();
|
||||
|
||||
let WhitespaceConfig { render } = &editor_config.whitespace;
|
||||
let WhitespaceConfig {
|
||||
render: ws_render,
|
||||
characters: ws_chars,
|
||||
} = &editor_config.whitespace;
|
||||
|
||||
let tab_width = doc.tab_width();
|
||||
|
||||
let icons = ICONS.load();
|
||||
|
||||
let whitespace = icons.ui().r#virtual();
|
||||
|
||||
let tab = if render.tab() == WhitespaceRenderValue::All {
|
||||
std::iter::once(whitespace.tab())
|
||||
.chain(std::iter::repeat(whitespace.tabpad()).take(tab_width - 1))
|
||||
let tab = if ws_render.tab() == WhitespaceRenderValue::All {
|
||||
std::iter::once(ws_chars.tab)
|
||||
.chain(std::iter::repeat(ws_chars.tabpad).take(tab_width - 1))
|
||||
.collect()
|
||||
} else {
|
||||
" ".repeat(tab_width)
|
||||
};
|
||||
let virtual_tab = " ".repeat(tab_width);
|
||||
let newline = if render.newline() == WhitespaceRenderValue::All {
|
||||
whitespace.newline().into()
|
||||
let newline = if ws_render.newline() == WhitespaceRenderValue::All {
|
||||
ws_chars.newline.into()
|
||||
} else {
|
||||
" ".to_owned()
|
||||
};
|
||||
|
||||
let space = if render.space() == WhitespaceRenderValue::All {
|
||||
whitespace.space().into()
|
||||
let space = if ws_render.space() == WhitespaceRenderValue::All {
|
||||
ws_chars.space.into()
|
||||
} else {
|
||||
" ".to_owned()
|
||||
};
|
||||
let nbsp = if render.nbsp() == WhitespaceRenderValue::All {
|
||||
whitespace.nbsp().into()
|
||||
let nbsp = if ws_render.nbsp() == WhitespaceRenderValue::All {
|
||||
ws_chars.nbsp.into()
|
||||
} else {
|
||||
" ".to_owned()
|
||||
};
|
||||
let nnbsp = if render.nnbsp() == WhitespaceRenderValue::All {
|
||||
whitespace.nnbsp().into()
|
||||
let nnbsp = if ws_render.nnbsp() == WhitespaceRenderValue::All {
|
||||
ws_chars.nnbsp.into()
|
||||
} else {
|
||||
" ".to_owned()
|
||||
};
|
||||
|
@ -275,7 +271,6 @@ impl<'a> TextRenderer<'a> {
|
|||
offset,
|
||||
}
|
||||
}
|
||||
|
||||
/// Draws a single `grapheme` at the current render position with a specified `style`.
|
||||
pub fn draw_decoration_grapheme(
|
||||
&mut self,
|
||||
|
|
|
@ -235,8 +235,7 @@ impl EditorView {
|
|||
theme: &Theme,
|
||||
) {
|
||||
let editor_rulers = &editor.config().rulers;
|
||||
|
||||
let style = theme
|
||||
let ruler_theme = theme
|
||||
.try_get("ui.virtual.ruler")
|
||||
.unwrap_or_else(|| Style::default().bg(Color::Red));
|
||||
|
||||
|
@ -254,12 +253,7 @@ impl EditorView {
|
|||
.filter_map(|ruler| ruler.checked_sub(1 + view_offset.horizontal_offset as u16))
|
||||
.filter(|ruler| ruler < &viewport.width)
|
||||
.map(|ruler| viewport.clip_left(ruler).with_width(1))
|
||||
.for_each(|area| {
|
||||
let icons = ICONS.load();
|
||||
for y in area.y..area.height {
|
||||
surface.set_string(area.x, y, icons.ui().r#virtual().ruler(), style);
|
||||
}
|
||||
});
|
||||
.for_each(|area| surface.set_style(area, ruler_theme))
|
||||
}
|
||||
|
||||
fn viewport_byte_range(
|
||||
|
@ -589,7 +583,7 @@ impl EditorView {
|
|||
let mut x = viewport.x;
|
||||
let current_doc = view!(editor).doc;
|
||||
|
||||
for doc in editor.documents() {
|
||||
for (idx, doc) in editor.documents().enumerate() {
|
||||
let fname = doc
|
||||
.path()
|
||||
.unwrap_or(&scratch)
|
||||
|
@ -604,9 +598,24 @@ impl EditorView {
|
|||
bufferline_inactive
|
||||
};
|
||||
|
||||
let lang = doc.language_name().unwrap_or(DEFAULT_LANGUAGE_NAME);
|
||||
|
||||
let icons = ICONS.load();
|
||||
|
||||
let lang = doc.language_name().unwrap_or(DEFAULT_LANGUAGE_NAME);
|
||||
// Render the separator before the text if the current document is not first.
|
||||
if idx > 0 {
|
||||
let used_width = viewport.x.saturating_sub(x);
|
||||
let rem_width = surface.area.width.saturating_sub(used_width);
|
||||
x = surface
|
||||
.set_stringn(
|
||||
x,
|
||||
viewport.y,
|
||||
icons.ui().bufferline().separator(),
|
||||
rem_width as usize,
|
||||
bufferline_inactive,
|
||||
)
|
||||
.0;
|
||||
}
|
||||
|
||||
if let Some(icon) = icons
|
||||
.fs()
|
||||
|
|
|
@ -32,7 +32,6 @@ pub use text::Text;
|
|||
|
||||
use helix_view::Editor;
|
||||
use tui::text::{Span, Spans, ToSpan};
|
||||
use tui::widgets::Cell;
|
||||
|
||||
use std::path::Path;
|
||||
use std::{error::Error, path::PathBuf};
|
||||
|
@ -334,7 +333,7 @@ pub fn file_explorer(root: PathBuf, editor: &Editor) -> Result<FileExplorer, std
|
|||
spans.push(icon.to_span_with(|icon| format!("{icon} ")));
|
||||
spans.push(Span::raw(name));
|
||||
|
||||
Cell::from(Spans::from(spans))
|
||||
Spans::from(spans).into()
|
||||
} else {
|
||||
name.into()
|
||||
}
|
||||
|
|
|
@ -236,7 +236,6 @@ where
|
|||
});
|
||||
|
||||
let icons = ICONS.load();
|
||||
|
||||
for sev in &context.editor.config().statusline.diagnostics {
|
||||
match sev {
|
||||
Severity::Hint if hints > 0 => {
|
||||
|
@ -487,10 +486,10 @@ fn render_file_type<'a, F>(context: &mut RenderContext<'a>, write: F)
|
|||
where
|
||||
F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,
|
||||
{
|
||||
let icons = ICONS.load();
|
||||
|
||||
let lang = context.doc.language_name().unwrap_or(DEFAULT_LANGUAGE_NAME);
|
||||
|
||||
let icons = ICONS.load();
|
||||
|
||||
if let Some(icon) = icons
|
||||
.fs()
|
||||
.from_optional_path_or_lang(context.doc.path().map(|path| path.as_path()), lang)
|
||||
|
@ -578,13 +577,10 @@ fn render_separator<'a, F>(context: &mut RenderContext<'a>, write: F)
|
|||
where
|
||||
F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,
|
||||
{
|
||||
let sep = &context.editor.config().statusline.separator;
|
||||
let style = context.editor.theme.get("ui.statusline.separator");
|
||||
|
||||
let icons = ICONS.load();
|
||||
|
||||
let separator = icons.ui().statusline().separator().to_string();
|
||||
|
||||
write(context, Span::styled(separator, style));
|
||||
write(context, Span::styled(sep.to_string(), style));
|
||||
}
|
||||
|
||||
fn render_spacer<'a, F>(context: &mut RenderContext<'a>, write: F)
|
||||
|
|
|
@ -43,7 +43,6 @@ use helix_core::{
|
|||
ChangeSet, Diagnostic, LineEnding, Range, Rope, RopeBuilder, Selection, Syntax, Transaction,
|
||||
};
|
||||
|
||||
use crate::icons::{Icons, ICONS};
|
||||
use crate::{
|
||||
editor::Config,
|
||||
events::{DocumentDidChange, SelectionDidChange},
|
||||
|
@ -2244,10 +2243,8 @@ impl Document {
|
|||
.unwrap_or(40);
|
||||
let wrap_indicator = language_soft_wrap
|
||||
.and_then(|soft_wrap| soft_wrap.wrap_indicator.clone())
|
||||
.unwrap_or_else(|| {
|
||||
let icons: arc_swap::access::DynGuard<Icons> = ICONS.load();
|
||||
icons.ui().r#virtual().wrap().to_string()
|
||||
});
|
||||
.or_else(|| config.soft_wrap.wrap_indicator.clone())
|
||||
.unwrap_or_else(|| "↪ ".into());
|
||||
let tab_width = self.tab_width() as u16;
|
||||
TextFormat {
|
||||
soft_wrap: enable_soft_wrap && viewport_width > 10,
|
||||
|
|
|
@ -508,6 +508,7 @@ pub struct StatusLineConfig {
|
|||
pub left: Vec<StatusLineElement>,
|
||||
pub center: Vec<StatusLineElement>,
|
||||
pub right: Vec<StatusLineElement>,
|
||||
pub separator: String,
|
||||
pub mode: ModeConfig,
|
||||
pub diagnostics: Vec<Severity>,
|
||||
pub workspace_diagnostics: Vec<Severity>,
|
||||
|
@ -533,6 +534,7 @@ impl Default for StatusLineConfig {
|
|||
E::Position,
|
||||
E::FileEncoding,
|
||||
],
|
||||
separator: String::from("│"),
|
||||
mode: ModeConfig::default(),
|
||||
diagnostics: vec![Severity::Warning, Severity::Error],
|
||||
workspace_diagnostics: vec![Severity::Warning, Severity::Error],
|
||||
|
@ -751,12 +753,14 @@ impl std::str::FromStr for GutterType {
|
|||
#[serde(default)]
|
||||
pub struct WhitespaceConfig {
|
||||
pub render: WhitespaceRender,
|
||||
pub characters: WhitespaceCharacters,
|
||||
}
|
||||
|
||||
impl Default for WhitespaceConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
render: WhitespaceRender::Basic(WhitespaceRenderValue::None),
|
||||
characters: WhitespaceCharacters::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -882,6 +886,30 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(default)]
|
||||
pub struct WhitespaceCharacters {
|
||||
pub space: char,
|
||||
pub nbsp: char,
|
||||
pub nnbsp: char,
|
||||
pub tab: char,
|
||||
pub tabpad: char,
|
||||
pub newline: char,
|
||||
}
|
||||
|
||||
impl Default for WhitespaceCharacters {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
space: '·', // U+00B7
|
||||
nbsp: '⍽', // U+237D
|
||||
nnbsp: '␣', // U+2423
|
||||
tab: '→', // U+2192
|
||||
newline: '⏎', // U+23CE
|
||||
tabpad: ' ',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(default, rename_all = "kebab-case")]
|
||||
pub struct IndentGuidesConfig {
|
||||
|
|
|
@ -127,18 +127,17 @@ pub fn diff<'doc>(
|
|||
let icons = ICONS.load();
|
||||
|
||||
let (icon, style) = if hunk.is_pure_insertion() {
|
||||
(icons.ui().gutter().added(), added)
|
||||
(icons.gutter().added(), added)
|
||||
} else if hunk.is_pure_removal() {
|
||||
if !first_visual_line {
|
||||
return None;
|
||||
}
|
||||
(icons.ui().gutter().removed(), deleted)
|
||||
(icons.gutter().removed(), deleted)
|
||||
} else {
|
||||
(icons.ui().gutter().modified(), modified)
|
||||
(icons.gutter().modified(), modified)
|
||||
};
|
||||
|
||||
write!(out, "{icon}").unwrap();
|
||||
|
||||
write!(out, "{}", icon).unwrap();
|
||||
Some(style)
|
||||
},
|
||||
)
|
||||
|
|
|
@ -20,6 +20,7 @@ pub struct Icons {
|
|||
diagnostic: Diagnostic,
|
||||
vcs: Vcs,
|
||||
dap: Dap,
|
||||
gutter: Gutter,
|
||||
ui: Ui,
|
||||
}
|
||||
|
||||
|
@ -49,6 +50,11 @@ impl Icons {
|
|||
&self.dap
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn gutter(&self) -> &Gutter {
|
||||
&self.gutter
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn ui(&self) -> &Ui {
|
||||
&self.ui
|
||||
|
@ -107,46 +113,48 @@ impl Kind {
|
|||
return None;
|
||||
}
|
||||
|
||||
match kind {
|
||||
"file" => self.file(),
|
||||
"folder" => self.folder(),
|
||||
"module" => self.module(),
|
||||
"namespace" => self.namespace(),
|
||||
"package" => self.package(),
|
||||
"class" => self.class(),
|
||||
"method" => self.method(),
|
||||
"property" => self.property(),
|
||||
"field" => self.field(),
|
||||
"construct" => self.constructor(),
|
||||
"enum" => self.r#enum(),
|
||||
"interface" => self.interface(),
|
||||
"function" => self.function(),
|
||||
"variable" => self.variable(),
|
||||
"constant" => self.constant(),
|
||||
"string" => self.string(),
|
||||
"number" => self.number(),
|
||||
"boolean" => self.boolean(),
|
||||
"array" => self.array(),
|
||||
"object" => self.object(),
|
||||
"key" => self.key(),
|
||||
"null" => self.null(),
|
||||
"enum_member" => self.enum_member(),
|
||||
"struct" => self.r#struct(),
|
||||
"event" => self.event(),
|
||||
"operator" => self.operator(),
|
||||
"typeparam" => self.type_parameter(),
|
||||
"color" => Some(self.color()),
|
||||
"keyword" => self.keyword(),
|
||||
"value" => self.value(),
|
||||
"snippet" => self.snippet(),
|
||||
"reference" => self.reference(),
|
||||
"text" => self.text(),
|
||||
"unit" => self.unit(),
|
||||
"word" => self.word(),
|
||||
"spellcheck" => self.spellcheck(),
|
||||
let icon = match kind {
|
||||
"file" => self.file()?,
|
||||
"folder" => self.folder()?,
|
||||
"module" => self.module()?,
|
||||
"namespace" => self.namespace()?,
|
||||
"package" => self.package()?,
|
||||
"class" => self.class()?,
|
||||
"method" => self.method()?,
|
||||
"property" => self.property()?,
|
||||
"field" => self.field()?,
|
||||
"construct" => self.constructor()?,
|
||||
"enum" => self.r#enum()?,
|
||||
"interface" => self.interface()?,
|
||||
"function" => self.function()?,
|
||||
"variable" => self.variable()?,
|
||||
"constant" => self.constant()?,
|
||||
"string" => self.string()?,
|
||||
"number" => self.number()?,
|
||||
"boolean" => self.boolean()?,
|
||||
"array" => self.array()?,
|
||||
"object" => self.object()?,
|
||||
"key" => self.key()?,
|
||||
"null" => self.null()?,
|
||||
"enum_member" => self.enum_member()?,
|
||||
"struct" => self.r#struct()?,
|
||||
"event" => self.event()?,
|
||||
"operator" => self.operator()?,
|
||||
"typeparam" => self.type_parameter()?,
|
||||
"color" => self.color(),
|
||||
"keyword" => self.keyword()?,
|
||||
"value" => self.value()?,
|
||||
"snippet" => self.snippet()?,
|
||||
"reference" => self.reference()?,
|
||||
"text" => self.text()?,
|
||||
"unit" => self.unit()?,
|
||||
"word" => self.word()?,
|
||||
"spellcheck" => self.spellcheck()?,
|
||||
|
||||
_ => None,
|
||||
}
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
Some(icon)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -548,23 +556,21 @@ pub struct Fs {
|
|||
mime: HashMap<String, Icon>,
|
||||
}
|
||||
|
||||
macro_rules! iconmap {
|
||||
macro_rules! mimes {
|
||||
( $( $key:literal => { glyph: $glyph:expr $(, color: $color:expr)? } ),* $(,)? ) => {{
|
||||
HashMap::from(
|
||||
[
|
||||
$(
|
||||
(String::from($key), Icon {
|
||||
glyph: String::from($glyph),
|
||||
color: None $(.or( Some(Color::from_hex($color).unwrap())) )?,
|
||||
}),
|
||||
)*
|
||||
]
|
||||
)
|
||||
let mut map = HashMap::new();
|
||||
$(
|
||||
map.insert(String::from($key), Icon {
|
||||
glyph: String::from($glyph),
|
||||
color: None $(.or( Some(Color::from_hex($color).unwrap())) )?,
|
||||
});
|
||||
)*
|
||||
map
|
||||
}};
|
||||
}
|
||||
|
||||
static MIMES: once_cell::sync::Lazy<HashMap<String, Icon>> = once_cell::sync::Lazy::new(|| {
|
||||
iconmap! {
|
||||
mimes! {
|
||||
// Language name
|
||||
"git-commit" => {glyph: "", color: "#f15233" },
|
||||
"git-rebase" => {glyph: "", color: "#f15233" },
|
||||
|
@ -689,11 +695,13 @@ impl Fs {
|
|||
return None;
|
||||
}
|
||||
|
||||
if is_open {
|
||||
self.directory_open.as_deref().or(Some(""))
|
||||
let dir = if is_open {
|
||||
self.directory_open.as_deref().unwrap_or("")
|
||||
} else {
|
||||
self.directory.as_deref().or(Some(""))
|
||||
}
|
||||
self.directory.as_deref().unwrap_or("")
|
||||
};
|
||||
|
||||
Some(dir)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -800,41 +808,6 @@ impl Dap {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq, Eq, Clone, Default)]
|
||||
#[serde(default, deny_unknown_fields)]
|
||||
pub struct Ui {
|
||||
workspace: Option<Icon>,
|
||||
gutter: Gutter,
|
||||
#[serde(rename = "virtual")]
|
||||
r#virtual: Virtual,
|
||||
statusline: Statusline,
|
||||
}
|
||||
|
||||
impl Ui {
|
||||
/// Returns a workspace diagnostic icon.
|
||||
///
|
||||
/// If no icon is set in the config, it will return `W` by default.
|
||||
#[inline]
|
||||
pub fn workspace(&self) -> Icon {
|
||||
self.workspace.clone().unwrap_or_else(|| Icon::from("W"))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn gutter(&self) -> &Gutter {
|
||||
&self.gutter
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn r#virtual(&self) -> &Virtual {
|
||||
&self.r#virtual
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn statusline(&self) -> &Statusline {
|
||||
&self.statusline
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Default)]
|
||||
pub struct Gutter {
|
||||
added: Option<String>,
|
||||
|
@ -859,100 +832,46 @@ impl Gutter {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Default)]
|
||||
pub struct Virtual {
|
||||
// Whitespace
|
||||
space: Option<String>,
|
||||
nbsp: Option<String>,
|
||||
nnbsp: Option<String>,
|
||||
tab: Option<String>,
|
||||
newline: Option<String>,
|
||||
tabpad: Option<String>,
|
||||
|
||||
// Soft-wrap
|
||||
wrap: Option<String>,
|
||||
|
||||
// Indentation guide
|
||||
indentation: Option<String>,
|
||||
|
||||
// Ruler
|
||||
ruler: Option<String>,
|
||||
}
|
||||
|
||||
impl Virtual {
|
||||
#[inline]
|
||||
pub fn space(&self) -> &str {
|
||||
// Default: U+00B7
|
||||
self.space.as_deref().unwrap_or("·")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn nbsp(&self) -> &str {
|
||||
// Default: U+237D
|
||||
self.nbsp.as_deref().unwrap_or("⍽")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn nnbsp(&self) -> &str {
|
||||
// Default: U+2423
|
||||
self.nnbsp.as_deref().unwrap_or("␣")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn tab(&self) -> &str {
|
||||
// Default: U+2192
|
||||
self.tab.as_deref().unwrap_or("→")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn newline(&self) -> &str {
|
||||
// Default: U+23CE
|
||||
self.newline.as_deref().unwrap_or("⏎")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn tabpad(&self) -> &str {
|
||||
// Default: U+23CE
|
||||
self.tabpad.as_deref().unwrap_or(" ")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn wrap(&self) -> &str {
|
||||
// Default: U+21AA
|
||||
self.wrap.as_deref().unwrap_or("↪")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn indentation(&self) -> &str {
|
||||
// Default: U+254E
|
||||
self.indentation.as_deref().unwrap_or("╎")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn ruler(&self) -> &str {
|
||||
// TODO: Default: U+00A6: ¦
|
||||
self.ruler.as_deref().unwrap_or(" ")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq, Eq, Clone, Default)]
|
||||
pub struct Statusline {
|
||||
separator: Option<String>,
|
||||
}
|
||||
|
||||
impl Statusline {
|
||||
#[inline]
|
||||
pub fn separator(&self) -> &str {
|
||||
self.separator.as_deref().unwrap_or("│")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Eq, Clone)]
|
||||
pub struct Icon {
|
||||
glyph: String,
|
||||
color: Option<Color>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq, Eq, Clone, Default)]
|
||||
#[serde(default, deny_unknown_fields)]
|
||||
pub struct Ui {
|
||||
workspace: Option<Icon>,
|
||||
bufferline: BufferLine,
|
||||
}
|
||||
|
||||
impl Ui {
|
||||
/// Returns a workspace diagnostic icon.
|
||||
///
|
||||
/// If no icon is set in the config, it will return `W` by default.
|
||||
#[inline]
|
||||
pub fn workspace(&self) -> Icon {
|
||||
self.workspace.clone().unwrap_or_else(|| Icon::from("W"))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn bufferline(&self) -> &BufferLine {
|
||||
&self.bufferline
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq, Eq, Clone, Default)]
|
||||
pub struct BufferLine {
|
||||
separator: Option<String>,
|
||||
}
|
||||
|
||||
impl BufferLine {
|
||||
#[inline]
|
||||
pub fn separator(&self) -> &str {
|
||||
self.separator.as_deref().unwrap_or("│")
|
||||
}
|
||||
}
|
||||
|
||||
impl Icon {
|
||||
pub fn glyph(&self) -> &str {
|
||||
self.glyph.as_str()
|
||||
|
|
Loading…
Reference in New Issue