From aa27bc7b4a1e82172d5215b655eb94eefadeb9cb Mon Sep 17 00:00:00 2001
From: Rolo <roloedits@gmail.com>
Date: Mon, 30 Dec 2024 04:57:13 -0800
Subject: [PATCH 01/16] feat: add support for basic icons

---
 helix-term/src/ui/editor.rs     |  12 +-
 helix-term/src/ui/statusline.rs |  43 ++++--
 helix-view/src/editor.rs        |   6 +
 helix-view/src/editor/config.rs | 250 ++++++++++++++++++++++++++++++++
 helix-view/src/gutter.rs        |  18 ++-
 5 files changed, 307 insertions(+), 22 deletions(-)
 create mode 100644 helix-view/src/editor/config.rs

diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs
index 6fecd512..b1d5fb2e 100644
--- a/helix-term/src/ui/editor.rs
+++ b/helix-term/src/ui/editor.rs
@@ -24,7 +24,7 @@ use helix_core::{
 };
 use helix_view::{
     annotations::diagnostics::DiagnosticFilter,
-    document::{Mode, SCRATCH_BUFFER_NAME},
+    document::{Mode, DEFAULT_LANGUAGE_NAME, SCRATCH_BUFFER_NAME},
     editor::{CompleteAction, CursorShapeConfig},
     graphics::{Color, CursorKind, Modifier, Rect, Style},
     input::{KeyEvent, MouseButton, MouseEvent, MouseEventKind},
@@ -646,7 +646,15 @@ impl EditorView {
                 bufferline_inactive
             };
 
-            let text = format!(" {}{} ", fname, if doc.is_modified() { "[+]" } else { "" });
+            let lang = doc.language_name().unwrap_or(DEFAULT_LANGUAGE_NAME);
+            let config = editor.config();
+            let icon = config.icons.mime.lang(lang);
+
+            let text = format!(
+                " {icon} {}{} ",
+                fname,
+                if doc.is_modified() { "[+]" } else { "" }
+            );
             let used_width = viewport.x.saturating_sub(x);
             let rem_width = surface.area.width.saturating_sub(used_width);
 
diff --git a/helix-term/src/ui/statusline.rs b/helix-term/src/ui/statusline.rs
index 7437cbd0..b096a475 100644
--- a/helix-term/src/ui/statusline.rs
+++ b/helix-term/src/ui/statusline.rs
@@ -243,7 +243,13 @@ where
     if warnings > 0 {
         write(
             context,
-            "●".to_string(),
+            context
+                .editor
+                .config()
+                .icons
+                .diagnostic
+                .warning()
+                .to_string(),
             Some(context.editor.theme.get("warning")),
         );
         write(context, format!(" {} ", warnings), None);
@@ -252,7 +258,7 @@ where
     if errors > 0 {
         write(
             context,
-            "●".to_string(),
+            context.editor.config().icons.diagnostic.error().to_string(),
             Some(context.editor.theme.get("error")),
         );
         write(context, format!(" {} ", errors), None);
@@ -285,7 +291,13 @@ where
     if warnings > 0 {
         write(
             context,
-            "●".to_string(),
+            context
+                .editor
+                .config()
+                .icons
+                .diagnostic
+                .warning()
+                .to_string(),
             Some(context.editor.theme.get("warning")),
         );
         write(context, format!(" {} ", warnings), None);
@@ -294,7 +306,7 @@ where
     if errors > 0 {
         write(
             context,
-            "●".to_string(),
+            context.editor.config().icons.diagnostic.error().to_string(),
             Some(context.editor.theme.get("error")),
         );
         write(context, format!(" {} ", errors), None);
@@ -410,9 +422,11 @@ fn render_file_type<F>(context: &mut RenderContext, write: F)
 where
     F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
 {
-    let file_type = context.doc.language_name().unwrap_or(DEFAULT_LANGUAGE_NAME);
+    let mime = &context.editor.config().icons.mime;
 
-    write(context, format!(" {} ", file_type), None);
+    let icon = mime.lang(context.doc.language_name().unwrap_or(DEFAULT_LANGUAGE_NAME));
+
+    write(context, format!(" {} ", icon), None);
 }
 
 fn render_file_name<F>(context: &mut RenderContext, write: F)
@@ -514,13 +528,18 @@ fn render_version_control<F>(context: &mut RenderContext, write: F)
 where
     F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
 {
-    let head = context
-        .doc
-        .version_control_head()
-        .unwrap_or_default()
-        .to_string();
+    let head = context.doc.version_control_head().unwrap_or_default();
 
-    write(context, head, None);
+    let config = context.editor.config();
+    let icon = config.icons.vcs.icon();
+
+    let vcs = if head.is_empty() {
+        format!("{head}")
+    } else {
+        format!("{icon}{head}")
+    };
+
+    write(context, vcs, None);
 }
 
 fn render_register<F>(context: &mut RenderContext, write: F)
diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs
index 739dcfb4..004d0bf1 100644
--- a/helix-view/src/editor.rs
+++ b/helix-view/src/editor.rs
@@ -14,6 +14,7 @@ use crate::{
     tree::{self, Tree},
     Document, DocumentId, View, ViewId,
 };
+use config::Icons;
 use dap::StackFrame;
 use helix_event::dispatch;
 use helix_vcs::DiffProviderRegistry;
@@ -23,6 +24,8 @@ use futures_util::{future, StreamExt};
 use helix_lsp::{Call, LanguageServerId};
 use tokio_stream::wrappers::UnboundedReceiverStream;
 
+mod config;
+
 use std::{
     borrow::Cow,
     cell::Cell,
@@ -360,6 +363,8 @@ pub struct Config {
     pub end_of_line_diagnostics: DiagnosticFilter,
     // Set to override the default clipboard provider
     pub clipboard_provider: ClipboardProvider,
+
+    pub icons: Icons,
 }
 
 #[derive(Debug, Clone, PartialEq, Deserialize, Serialize, Eq, PartialOrd, Ord)]
@@ -1001,6 +1006,7 @@ impl Default for Config {
             inline_diagnostics: InlineDiagnosticsConfig::default(),
             end_of_line_diagnostics: DiagnosticFilter::Disable,
             clipboard_provider: ClipboardProvider::default(),
+            icons: Icons::default(),
         }
     }
 }
diff --git a/helix-view/src/editor/config.rs b/helix-view/src/editor/config.rs
new file mode 100644
index 00000000..5f645f88
--- /dev/null
+++ b/helix-view/src/editor/config.rs
@@ -0,0 +1,250 @@
+use std::collections::HashMap;
+
+use serde::{Deserialize, Serialize};
+
+// TODO: Dap: verified ●, unverified ◯
+
+#[derive(Debug, Serialize, Deserialize, Default, PartialEq, Eq, Clone)]
+pub struct Icons {
+    pub mime: Mime,
+    pub lsp: Lsp,
+    pub diagnostic: Diagnostic,
+    pub vcs: Vcs,
+}
+
+// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_documentSymbol
+#[derive(Debug, Serialize, Deserialize, Default, PartialEq, Eq, Clone)]
+pub struct Lsp {
+    file: Option<String>,
+    module: Option<String>,
+    namespace: Option<String>,
+    package: Option<String>,
+    class: Option<String>,
+    method: Option<String>,
+    property: Option<String>,
+    field: Option<String>,
+    constructor: Option<String>,
+    #[serde(rename = "enum")]
+    r#enum: Option<String>,
+    interface: Option<String>,
+    function: Option<String>,
+    variable: Option<String>,
+    constant: Option<String>,
+    string: Option<String>,
+    number: Option<String>,
+    boolean: Option<String>,
+    array: Option<String>,
+    object: Option<String>,
+    key: Option<String>,
+    null: Option<String>,
+    enum_member: Option<String>,
+    #[serde(rename = "struct")]
+    r#struct: Option<String>,
+    event: Option<String>,
+    operator: Option<String>,
+    type_parameter: Option<String>,
+}
+
+impl Lsp {
+    const DEFAULT: &str = "*";
+
+    pub fn file(&self) -> &str {
+        self.file.as_ref().map_or(Self::DEFAULT, |file| file)
+    }
+    pub fn module(&self) -> &str {
+        self.module.as_ref().map_or(Self::DEFAULT, |module| module)
+    }
+    pub fn namespace(&self) -> &str {
+        self.namespace
+            .as_ref()
+            .map_or(Self::DEFAULT, |namespace| namespace)
+    }
+    pub fn package(&self) -> &str {
+        self.package
+            .as_ref()
+            .map_or(Self::DEFAULT, |package| package)
+    }
+    pub fn class(&self) -> &str {
+        self.class.as_ref().map_or(Self::DEFAULT, |class| class)
+    }
+    pub fn method(&self) -> &str {
+        self.method.as_ref().map_or(Self::DEFAULT, |method| method)
+    }
+    pub fn property(&self) -> &str {
+        self.property
+            .as_ref()
+            .map_or(Self::DEFAULT, |property| property)
+    }
+    pub fn field(&self) -> &str {
+        self.field.as_ref().map_or(Self::DEFAULT, |field| field)
+    }
+    pub fn constructor(&self) -> &str {
+        self.constructor
+            .as_ref()
+            .map_or(Self::DEFAULT, |constructor| constructor)
+    }
+    pub fn r#enum(&self) -> &str {
+        self.r#enum.as_ref().map_or(Self::DEFAULT, |r#enum| r#enum)
+    }
+    pub fn interface(&self) -> &str {
+        self.interface
+            .as_ref()
+            .map_or(Self::DEFAULT, |interface| interface)
+    }
+    pub fn function(&self) -> &str {
+        self.function
+            .as_ref()
+            .map_or(Self::DEFAULT, |function| function)
+    }
+    pub fn variable(&self) -> &str {
+        self.variable
+            .as_ref()
+            .map_or(Self::DEFAULT, |variable| variable)
+    }
+    pub fn constant(&self) -> &str {
+        self.constant
+            .as_ref()
+            .map_or(Self::DEFAULT, |constant| constant)
+    }
+    pub fn string(&self) -> &str {
+        self.string.as_ref().map_or(Self::DEFAULT, |string| string)
+    }
+    pub fn number(&self) -> &str {
+        self.number.as_ref().map_or(Self::DEFAULT, |number| number)
+    }
+    pub fn boolean(&self) -> &str {
+        self.boolean
+            .as_ref()
+            .map_or(Self::DEFAULT, |boolean| boolean)
+    }
+    pub fn array(&self) -> &str {
+        self.array.as_ref().map_or(Self::DEFAULT, |array| array)
+    }
+    pub fn object(&self) -> &str {
+        self.object.as_ref().map_or(Self::DEFAULT, |object| object)
+    }
+    pub fn key(&self) -> &str {
+        self.key.as_ref().map_or(Self::DEFAULT, |key| key)
+    }
+    pub fn null(&self) -> &str {
+        self.null.as_ref().map_or(Self::DEFAULT, |null| null)
+    }
+    pub fn enum_member(&self) -> &str {
+        self.enum_member
+            .as_ref()
+            .map_or(Self::DEFAULT, |enum_member| enum_member)
+    }
+    pub fn r#struct(&self) -> &str {
+        self.r#struct
+            .as_ref()
+            .map_or(Self::DEFAULT, |r#struct| r#struct)
+    }
+    pub fn event(&self) -> &str {
+        self.event.as_ref().map_or(Self::DEFAULT, |event| event)
+    }
+    pub fn operator(&self) -> &str {
+        self.operator
+            .as_ref()
+            .map_or(Self::DEFAULT, |operator| operator)
+    }
+    pub fn type_parameter(&self) -> &str {
+        self.type_parameter
+            .as_ref()
+            .map_or(Self::DEFAULT, |type_parameter| type_parameter)
+    }
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
+pub struct Diagnostic {
+    hint: Option<String>,
+    info: Option<String>,
+    warning: Option<String>,
+    error: Option<String>,
+}
+
+impl Default for Diagnostic {
+    fn default() -> Self {
+        Self {
+            hint: Some(String::from("○")),
+            info: Some(String::from("●")),
+            warning: Some(String::from("▲")),
+            error: Some(String::from("■")),
+        }
+    }
+}
+
+impl Diagnostic {
+    const DEFAULT: &str = "●";
+
+    pub fn hint(&self) -> &str {
+        self.hint.as_ref().map_or(Self::DEFAULT, |hint| hint)
+    }
+    pub fn info(&self) -> &str {
+        self.info.as_ref().map_or(Self::DEFAULT, |info| info)
+    }
+    pub fn warning(&self) -> &str {
+        self.warning
+            .as_ref()
+            .map_or(Self::DEFAULT, |warning| warning)
+    }
+    pub fn error(&self) -> &str {
+        self.error.as_ref().map_or(Self::DEFAULT, |error| error)
+    }
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
+pub struct Vcs {
+    icon: Option<String>,
+}
+
+impl Default for Vcs {
+    fn default() -> Self {
+        Self {
+            icon: Some(String::from(" ")),
+        }
+    }
+}
+
+impl Vcs {
+    const DEFAULT: &str = "";
+
+    pub fn icon(&self) -> &str {
+        self.icon
+            .as_ref()
+            .map_or(Self::DEFAULT, |icon| icon.as_str())
+    }
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
+pub struct Mime {
+    directory: Option<String>,
+    mime: HashMap<String, String>,
+}
+
+impl Default for Mime {
+    fn default() -> Self {
+        Self {
+            directory: None,
+            mime: {
+                let mut mime = HashMap::new();
+                mime.insert(String::from("rust"), String::from("󱘗 "));
+                mime.insert(String::from("markdown"), String::from(" "));
+                mime.insert(String::from("css"), String::from("󰌜 "));
+                mime.insert(String::from("toml"), String::from(" "));
+                mime.insert(String::from("lock"), String::from("󱌼 "));
+                mime.insert(String::from("text"), String::from(" "));
+                mime
+            },
+        }
+    }
+}
+
+impl Mime {
+    pub fn directory(&self) -> &str {
+        self.directory.as_ref().map_or("🖿 ", |directory| directory)
+    }
+
+    pub fn lang(&self, mime: &str) -> &str {
+        self.mime.get(mime).map_or("*", |mime| mime)
+    }
+}
diff --git a/helix-view/src/gutter.rs b/helix-view/src/gutter.rs
index 7cd91271..bac4a380 100644
--- a/helix-view/src/gutter.rs
+++ b/helix-view/src/gutter.rs
@@ -46,7 +46,7 @@ impl GutterType {
 }
 
 pub fn diagnostic<'doc>(
-    _editor: &'doc Editor,
+    editor: &'doc Editor,
     doc: &'doc Document,
     _view: &View,
     theme: &Theme,
@@ -57,6 +57,7 @@ pub fn diagnostic<'doc>(
     let info = theme.get("info");
     let hint = theme.get("hint");
     let diagnostics = &doc.diagnostics;
+    let symbols = editor.config().icons.diagnostic.clone();
 
     Box::new(
         move |line: usize, _selected: bool, first_visual_line: bool, out: &mut String| {
@@ -74,13 +75,14 @@ pub fn diagnostic<'doc>(
                             .any(|ls| ls.id() == d.provider)
                 });
             diagnostics_on_line.max_by_key(|d| d.severity).map(|d| {
-                write!(out, "●").ok();
-                match d.severity {
-                    Some(Severity::Error) => error,
-                    Some(Severity::Warning) | None => warning,
-                    Some(Severity::Info) => info,
-                    Some(Severity::Hint) => hint,
-                }
+                let (style, symbol) = match d.severity {
+                    Some(Severity::Error) => (error, symbols.error()),
+                    Some(Severity::Warning) | None => (warning, symbols.warning()),
+                    Some(Severity::Info) => (info, symbols.info()),
+                    Some(Severity::Hint) => (hint, symbols.hint()),
+                };
+                out.push_str(symbol);
+                style
             })
         },
     )

From 0ef7bad77ea32526070badcbff058c4164f5cea4 Mon Sep 17 00:00:00 2001
From: Rolo <roloedits@gmail.com>
Date: Mon, 30 Dec 2024 07:15:30 -0800
Subject: [PATCH 02/16] lint: add 'static lifetime to const's

---
 helix-view/src/editor/config.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/helix-view/src/editor/config.rs b/helix-view/src/editor/config.rs
index 5f645f88..00100ff5 100644
--- a/helix-view/src/editor/config.rs
+++ b/helix-view/src/editor/config.rs
@@ -46,7 +46,7 @@ pub struct Lsp {
 }
 
 impl Lsp {
-    const DEFAULT: &str = "*";
+    const DEFAULT: &'static str = "*";
 
     pub fn file(&self) -> &str {
         self.file.as_ref().map_or(Self::DEFAULT, |file| file)
@@ -174,7 +174,7 @@ impl Default for Diagnostic {
 }
 
 impl Diagnostic {
-    const DEFAULT: &str = "●";
+    const DEFAULT: &'static str = "●";
 
     pub fn hint(&self) -> &str {
         self.hint.as_ref().map_or(Self::DEFAULT, |hint| hint)
@@ -206,7 +206,7 @@ impl Default for Vcs {
 }
 
 impl Vcs {
-    const DEFAULT: &str = "";
+    const DEFAULT: &'static str = "";
 
     pub fn icon(&self) -> &str {
         self.icon

From 55ead2f0ae5c7207c7854bd7aa9c21de9afa07fc Mon Sep 17 00:00:00 2001
From: Rolo <roloedits@gmail.com>
Date: Mon, 30 Dec 2024 09:07:56 -0800
Subject: [PATCH 03/16] feat: add dap symbols to config

---
 helix-view/src/editor/config.rs | 26 ++++++++++++++++++++++++--
 helix-view/src/gutter.rs        |  8 +++++++-
 2 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/helix-view/src/editor/config.rs b/helix-view/src/editor/config.rs
index 00100ff5..5c7f5345 100644
--- a/helix-view/src/editor/config.rs
+++ b/helix-view/src/editor/config.rs
@@ -2,14 +2,13 @@ use std::collections::HashMap;
 
 use serde::{Deserialize, Serialize};
 
-// TODO: Dap: verified ●, unverified ◯
-
 #[derive(Debug, Serialize, Deserialize, Default, PartialEq, Eq, Clone)]
 pub struct Icons {
     pub mime: Mime,
     pub lsp: Lsp,
     pub diagnostic: Diagnostic,
     pub vcs: Vcs,
+    pub dap: Dap,
 }
 
 // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_documentSymbol
@@ -248,3 +247,26 @@ impl Mime {
         self.mime.get(mime).map_or("*", |mime| mime)
     }
 }
+
+#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Default)]
+pub struct Dap {
+    verified: Option<String>,
+    unverified: Option<String>,
+}
+
+impl Dap {
+    const DEFAULT_VERIFIED: &'static str = "●";
+    const DEFAULT_UNVERIFIED: &'static str = "◯";
+
+    pub fn verified(&self) -> &str {
+        self.verified
+            .as_ref()
+            .map_or(Self::DEFAULT_VERIFIED, |verified| verified)
+    }
+
+    pub fn unverified(&self) -> &str {
+        self.verified
+            .as_ref()
+            .map_or(Self::DEFAULT_UNVERIFIED, |verified| verified)
+    }
+}
diff --git a/helix-view/src/gutter.rs b/helix-view/src/gutter.rs
index bac4a380..ac5c2f0b 100644
--- a/helix-view/src/gutter.rs
+++ b/helix-view/src/gutter.rs
@@ -265,7 +265,13 @@ pub fn breakpoints<'doc>(
                 breakpoint_style
             };
 
-            let sym = if breakpoint.verified { "●" } else { "◯" };
+            let config = editor.config();
+
+            let sym = if breakpoint.verified {
+                config.icons.dap.verified()
+            } else {
+                config.icons.dap.unverified()
+            };
             write!(out, "{}", sym).unwrap();
             Some(style)
         },

From 88da9ee7bf6e5e1ec76fe4d2ab684699230280a8 Mon Sep 17 00:00:00 2001
From: Rolo <roloedits@gmail.com>
Date: Mon, 30 Dec 2024 09:35:06 -0800
Subject: [PATCH 04/16] refactor: remove `Default` impls and add config parsing

---
 helix-term/src/ui/editor.rs     |  2 +-
 helix-term/src/ui/statusline.rs |  4 +--
 helix-view/src/editor/config.rs | 52 ++++++---------------------------
 3 files changed, 12 insertions(+), 46 deletions(-)

diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs
index b1d5fb2e..4f5b1cc3 100644
--- a/helix-term/src/ui/editor.rs
+++ b/helix-term/src/ui/editor.rs
@@ -648,7 +648,7 @@ impl EditorView {
 
             let lang = doc.language_name().unwrap_or(DEFAULT_LANGUAGE_NAME);
             let config = editor.config();
-            let icon = config.icons.mime.lang(lang);
+            let icon = config.icons.mime.get(lang);
 
             let text = format!(
                 " {icon} {}{} ",
diff --git a/helix-term/src/ui/statusline.rs b/helix-term/src/ui/statusline.rs
index b096a475..0034db61 100644
--- a/helix-term/src/ui/statusline.rs
+++ b/helix-term/src/ui/statusline.rs
@@ -424,7 +424,7 @@ where
 {
     let mime = &context.editor.config().icons.mime;
 
-    let icon = mime.lang(context.doc.language_name().unwrap_or(DEFAULT_LANGUAGE_NAME));
+    let icon = mime.get(context.doc.language_name().unwrap_or(DEFAULT_LANGUAGE_NAME));
 
     write(context, format!(" {} ", icon), None);
 }
@@ -536,7 +536,7 @@ where
     let vcs = if head.is_empty() {
         format!("{head}")
     } else {
-        format!("{icon}{head}")
+        format!("{icon} {head}")
     };
 
     write(context, vcs, None);
diff --git a/helix-view/src/editor/config.rs b/helix-view/src/editor/config.rs
index 5c7f5345..db0fbe63 100644
--- a/helix-view/src/editor/config.rs
+++ b/helix-view/src/editor/config.rs
@@ -3,6 +3,7 @@ use std::collections::HashMap;
 use serde::{Deserialize, Serialize};
 
 #[derive(Debug, Serialize, Deserialize, Default, PartialEq, Eq, Clone)]
+#[serde(default)]
 pub struct Icons {
     pub mime: Mime,
     pub lsp: Lsp,
@@ -153,7 +154,7 @@ impl Lsp {
     }
 }
 
-#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
+#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Default)]
 pub struct Diagnostic {
     hint: Option<String>,
     info: Option<String>,
@@ -161,17 +162,6 @@ pub struct Diagnostic {
     error: Option<String>,
 }
 
-impl Default for Diagnostic {
-    fn default() -> Self {
-        Self {
-            hint: Some(String::from("○")),
-            info: Some(String::from("●")),
-            warning: Some(String::from("▲")),
-            error: Some(String::from("■")),
-        }
-    }
-}
-
 impl Diagnostic {
     const DEFAULT: &'static str = "●";
 
@@ -191,19 +181,11 @@ impl Diagnostic {
     }
 }
 
-#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
+#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Default)]
 pub struct Vcs {
     icon: Option<String>,
 }
 
-impl Default for Vcs {
-    fn default() -> Self {
-        Self {
-            icon: Some(String::from(" ")),
-        }
-    }
-}
-
 impl Vcs {
     const DEFAULT: &'static str = "";
 
@@ -214,37 +196,21 @@ impl Vcs {
     }
 }
 
-#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
+#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Default)]
 pub struct Mime {
     directory: Option<String>,
+    #[serde(flatten)]
     mime: HashMap<String, String>,
 }
 
-impl Default for Mime {
-    fn default() -> Self {
-        Self {
-            directory: None,
-            mime: {
-                let mut mime = HashMap::new();
-                mime.insert(String::from("rust"), String::from("󱘗 "));
-                mime.insert(String::from("markdown"), String::from(" "));
-                mime.insert(String::from("css"), String::from("󰌜 "));
-                mime.insert(String::from("toml"), String::from(" "));
-                mime.insert(String::from("lock"), String::from("󱌼 "));
-                mime.insert(String::from("text"), String::from(" "));
-                mime
-            },
-        }
-    }
-}
-
 impl Mime {
     pub fn directory(&self) -> &str {
-        self.directory.as_ref().map_or("🖿 ", |directory| directory)
+        self.directory.as_ref().map_or("", |directory| directory)
     }
 
-    pub fn lang(&self, mime: &str) -> &str {
-        self.mime.get(mime).map_or("*", |mime| mime)
+    // Returns the symbol that matches the name, if any, otherwise returns the name back.
+    pub fn get<'name, 'mime: 'name>(&'mime self, r#type: &'name str) -> &'name str {
+        self.mime.get(r#type).map_or(r#type, |mime| mime)
     }
 }
 

From 0e94d21d18430622bd0be5ae1370b4eb50c22446 Mon Sep 17 00:00:00 2001
From: Rolo <roloedits@gmail.com>
Date: Mon, 30 Dec 2024 09:43:06 -0800
Subject: [PATCH 05/16] chore: add comment for default diagnostic symbols

---
 helix-view/src/editor/config.rs | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/helix-view/src/editor/config.rs b/helix-view/src/editor/config.rs
index db0fbe63..52528ad2 100644
--- a/helix-view/src/editor/config.rs
+++ b/helix-view/src/editor/config.rs
@@ -162,6 +162,19 @@ pub struct Diagnostic {
     error: Option<String>,
 }
 
+// NOTE: #6646 can be achieved by uncommenting this or adding the symbols
+// to the `map_or` default.
+// impl Default for Diagnostic {
+//     fn default() -> Self {
+//         Self {
+//             hint: Some(String::from("○")),
+//             info: Some(String::from("●")),
+//             warning: Some(String::from("▲")),
+//             error: Some(String::from("■")),
+//         }
+//     }
+// }
+
 impl Diagnostic {
     const DEFAULT: &'static str = "●";
 

From c18a71deba3d94577537ad54a8aa0c4ef8e15d00 Mon Sep 17 00:00:00 2001
From: Rolo <roloedits@gmail.com>
Date: Mon, 30 Dec 2024 10:10:38 -0800
Subject: [PATCH 06/16] perf: add `#[inline]` attribute to getters

---
 helix-view/src/editor/config.rs | 63 +++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/helix-view/src/editor/config.rs b/helix-view/src/editor/config.rs
index 52528ad2..a404e852 100644
--- a/helix-view/src/editor/config.rs
+++ b/helix-view/src/editor/config.rs
@@ -48,105 +48,156 @@ pub struct Lsp {
 impl Lsp {
     const DEFAULT: &'static str = "*";
 
+    #[inline]
     pub fn file(&self) -> &str {
         self.file.as_ref().map_or(Self::DEFAULT, |file| file)
     }
+
+    #[inline]
     pub fn module(&self) -> &str {
         self.module.as_ref().map_or(Self::DEFAULT, |module| module)
     }
+
+    #[inline]
     pub fn namespace(&self) -> &str {
         self.namespace
             .as_ref()
             .map_or(Self::DEFAULT, |namespace| namespace)
     }
+
+    #[inline]
     pub fn package(&self) -> &str {
         self.package
             .as_ref()
             .map_or(Self::DEFAULT, |package| package)
     }
+
+    #[inline]
     pub fn class(&self) -> &str {
         self.class.as_ref().map_or(Self::DEFAULT, |class| class)
     }
+
+    #[inline]
     pub fn method(&self) -> &str {
         self.method.as_ref().map_or(Self::DEFAULT, |method| method)
     }
+
+    #[inline]
     pub fn property(&self) -> &str {
         self.property
             .as_ref()
             .map_or(Self::DEFAULT, |property| property)
     }
+
+    #[inline]
     pub fn field(&self) -> &str {
         self.field.as_ref().map_or(Self::DEFAULT, |field| field)
     }
+
+    #[inline]
     pub fn constructor(&self) -> &str {
         self.constructor
             .as_ref()
             .map_or(Self::DEFAULT, |constructor| constructor)
     }
+
+    #[inline]
     pub fn r#enum(&self) -> &str {
         self.r#enum.as_ref().map_or(Self::DEFAULT, |r#enum| r#enum)
     }
+
+    #[inline]
     pub fn interface(&self) -> &str {
         self.interface
             .as_ref()
             .map_or(Self::DEFAULT, |interface| interface)
     }
+
+    #[inline]
     pub fn function(&self) -> &str {
         self.function
             .as_ref()
             .map_or(Self::DEFAULT, |function| function)
     }
+
+    #[inline]
     pub fn variable(&self) -> &str {
         self.variable
             .as_ref()
             .map_or(Self::DEFAULT, |variable| variable)
     }
+
+    #[inline]
     pub fn constant(&self) -> &str {
         self.constant
             .as_ref()
             .map_or(Self::DEFAULT, |constant| constant)
     }
+
+    #[inline]
     pub fn string(&self) -> &str {
         self.string.as_ref().map_or(Self::DEFAULT, |string| string)
     }
+
+    #[inline]
     pub fn number(&self) -> &str {
         self.number.as_ref().map_or(Self::DEFAULT, |number| number)
     }
+
+    #[inline]
     pub fn boolean(&self) -> &str {
         self.boolean
             .as_ref()
             .map_or(Self::DEFAULT, |boolean| boolean)
     }
+
+    #[inline]
     pub fn array(&self) -> &str {
         self.array.as_ref().map_or(Self::DEFAULT, |array| array)
     }
+
+    #[inline]
     pub fn object(&self) -> &str {
         self.object.as_ref().map_or(Self::DEFAULT, |object| object)
     }
+
+    #[inline]
     pub fn key(&self) -> &str {
         self.key.as_ref().map_or(Self::DEFAULT, |key| key)
     }
+
+    #[inline]
     pub fn null(&self) -> &str {
         self.null.as_ref().map_or(Self::DEFAULT, |null| null)
     }
+
+    #[inline]
     pub fn enum_member(&self) -> &str {
         self.enum_member
             .as_ref()
             .map_or(Self::DEFAULT, |enum_member| enum_member)
     }
+
+    #[inline]
     pub fn r#struct(&self) -> &str {
         self.r#struct
             .as_ref()
             .map_or(Self::DEFAULT, |r#struct| r#struct)
     }
+
+    #[inline]
     pub fn event(&self) -> &str {
         self.event.as_ref().map_or(Self::DEFAULT, |event| event)
     }
+
+    #[inline]
     pub fn operator(&self) -> &str {
         self.operator
             .as_ref()
             .map_or(Self::DEFAULT, |operator| operator)
     }
+
+    #[inline]
     pub fn type_parameter(&self) -> &str {
         self.type_parameter
             .as_ref()
@@ -178,17 +229,24 @@ pub struct Diagnostic {
 impl Diagnostic {
     const DEFAULT: &'static str = "●";
 
+    #[inline]
     pub fn hint(&self) -> &str {
         self.hint.as_ref().map_or(Self::DEFAULT, |hint| hint)
     }
+
+    #[inline]
     pub fn info(&self) -> &str {
         self.info.as_ref().map_or(Self::DEFAULT, |info| info)
     }
+
+    #[inline]
     pub fn warning(&self) -> &str {
         self.warning
             .as_ref()
             .map_or(Self::DEFAULT, |warning| warning)
     }
+
+    #[inline]
     pub fn error(&self) -> &str {
         self.error.as_ref().map_or(Self::DEFAULT, |error| error)
     }
@@ -202,6 +260,7 @@ pub struct Vcs {
 impl Vcs {
     const DEFAULT: &'static str = "";
 
+    #[inline]
     pub fn icon(&self) -> &str {
         self.icon
             .as_ref()
@@ -217,11 +276,13 @@ pub struct Mime {
 }
 
 impl Mime {
+    #[inline]
     pub fn directory(&self) -> &str {
         self.directory.as_ref().map_or("", |directory| directory)
     }
 
     // Returns the symbol that matches the name, if any, otherwise returns the name back.
+    #[inline]
     pub fn get<'name, 'mime: 'name>(&'mime self, r#type: &'name str) -> &'name str {
         self.mime.get(r#type).map_or(r#type, |mime| mime)
     }
@@ -237,12 +298,14 @@ impl Dap {
     const DEFAULT_VERIFIED: &'static str = "●";
     const DEFAULT_UNVERIFIED: &'static str = "◯";
 
+    #[inline]
     pub fn verified(&self) -> &str {
         self.verified
             .as_ref()
             .map_or(Self::DEFAULT_VERIFIED, |verified| verified)
     }
 
+    #[inline]
     pub fn unverified(&self) -> &str {
         self.verified
             .as_ref()

From 7f7d9f080275fe4134b2afcf6d5bbc722b3daa05 Mon Sep 17 00:00:00 2001
From: Rolo <roloedits@gmail.com>
Date: Mon, 30 Dec 2024 16:23:18 -0800
Subject: [PATCH 07/16] refactor: add nerdfont defaults for common mime types

---
 helix-view/src/editor/config.rs | 286 ++++++++++++++++++++++----------
 1 file changed, 195 insertions(+), 91 deletions(-)

diff --git a/helix-view/src/editor/config.rs b/helix-view/src/editor/config.rs
index a404e852..34d2a2cb 100644
--- a/helix-view/src/editor/config.rs
+++ b/helix-view/src/editor/config.rs
@@ -15,6 +15,8 @@ pub struct Icons {
 // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_documentSymbol
 #[derive(Debug, Serialize, Deserialize, Default, PartialEq, Eq, Clone)]
 pub struct Lsp {
+    enabled: bool,
+
     file: Option<String>,
     module: Option<String>,
     namespace: Option<String>,
@@ -46,162 +48,221 @@ pub struct Lsp {
 }
 
 impl Lsp {
-    const DEFAULT: &'static str = "*";
-
     #[inline]
     pub fn file(&self) -> &str {
-        self.file.as_ref().map_or(Self::DEFAULT, |file| file)
+        if self.enabled {
+            return self.file.as_ref().map_or("", |file| file);
+        }
+        ""
     }
 
     #[inline]
     pub fn module(&self) -> &str {
-        self.module.as_ref().map_or(Self::DEFAULT, |module| module)
+        if self.enabled {
+            return self.module.as_ref().map_or("", |module| module);
+        }
+        ""
     }
 
     #[inline]
     pub fn namespace(&self) -> &str {
-        self.namespace
-            .as_ref()
-            .map_or(Self::DEFAULT, |namespace| namespace)
+        if self.enabled {
+            return self.namespace.as_ref().map_or("", |namespace| namespace);
+        }
+        ""
     }
 
     #[inline]
     pub fn package(&self) -> &str {
-        self.package
-            .as_ref()
-            .map_or(Self::DEFAULT, |package| package)
+        if self.enabled {
+            return self.package.as_ref().map_or("", |package| package);
+        }
+        ""
     }
 
     #[inline]
     pub fn class(&self) -> &str {
-        self.class.as_ref().map_or(Self::DEFAULT, |class| class)
+        if self.enabled {
+            return self.class.as_ref().map_or("", |class| class);
+        }
+        ""
     }
 
     #[inline]
     pub fn method(&self) -> &str {
-        self.method.as_ref().map_or(Self::DEFAULT, |method| method)
+        if self.enabled {
+            return self.method.as_ref().map_or("", |method| method);
+        }
+        ""
     }
 
     #[inline]
     pub fn property(&self) -> &str {
-        self.property
-            .as_ref()
-            .map_or(Self::DEFAULT, |property| property)
+        if self.enabled {
+            return self.property.as_ref().map_or("", |property| property);
+        }
+        ""
     }
 
     #[inline]
     pub fn field(&self) -> &str {
-        self.field.as_ref().map_or(Self::DEFAULT, |field| field)
+        if self.enabled {
+            return self.field.as_ref().map_or("", |field| field);
+        }
+        ""
     }
 
     #[inline]
     pub fn constructor(&self) -> &str {
-        self.constructor
-            .as_ref()
-            .map_or(Self::DEFAULT, |constructor| constructor)
+        if self.enabled {
+            return self
+                .constructor
+                .as_ref()
+                .map_or("", |constructor| constructor);
+        }
+        ""
     }
 
     #[inline]
     pub fn r#enum(&self) -> &str {
-        self.r#enum.as_ref().map_or(Self::DEFAULT, |r#enum| r#enum)
+        if self.enabled {
+            return self.r#enum.as_ref().map_or("", |r#enum| r#enum);
+        }
+        ""
     }
 
     #[inline]
     pub fn interface(&self) -> &str {
-        self.interface
-            .as_ref()
-            .map_or(Self::DEFAULT, |interface| interface)
+        if self.enabled {
+            return self.interface.as_ref().map_or("", |interface| interface);
+        }
+        ""
     }
 
     #[inline]
     pub fn function(&self) -> &str {
-        self.function
-            .as_ref()
-            .map_or(Self::DEFAULT, |function| function)
+        if self.enabled {
+            return self.function.as_ref().map_or("", |function| function);
+        }
+        ""
     }
 
     #[inline]
     pub fn variable(&self) -> &str {
-        self.variable
-            .as_ref()
-            .map_or(Self::DEFAULT, |variable| variable)
+        if self.enabled {
+            return self.variable.as_ref().map_or("", |variable| variable);
+        }
+        ""
     }
 
     #[inline]
     pub fn constant(&self) -> &str {
-        self.constant
-            .as_ref()
-            .map_or(Self::DEFAULT, |constant| constant)
+        if self.enabled {
+            return self.constant.as_ref().map_or("", |constant| constant);
+        }
+        ""
     }
 
     #[inline]
     pub fn string(&self) -> &str {
-        self.string.as_ref().map_or(Self::DEFAULT, |string| string)
+        if self.enabled {
+            return self.string.as_ref().map_or("", |string| string);
+        }
+        ""
     }
 
     #[inline]
     pub fn number(&self) -> &str {
-        self.number.as_ref().map_or(Self::DEFAULT, |number| number)
+        if self.enabled {
+            return self.number.as_ref().map_or("", |number| number);
+        }
+        ""
     }
 
     #[inline]
     pub fn boolean(&self) -> &str {
-        self.boolean
-            .as_ref()
-            .map_or(Self::DEFAULT, |boolean| boolean)
+        if self.enabled {
+            return self.boolean.as_ref().map_or("", |boolean| boolean);
+        }
+        ""
     }
 
     #[inline]
     pub fn array(&self) -> &str {
-        self.array.as_ref().map_or(Self::DEFAULT, |array| array)
+        if self.enabled {
+            return self.array.as_ref().map_or("", |array| array);
+        }
+        ""
     }
 
     #[inline]
     pub fn object(&self) -> &str {
-        self.object.as_ref().map_or(Self::DEFAULT, |object| object)
+        if self.enabled {
+            return self.object.as_ref().map_or("", |object| object);
+        }
+        ""
     }
 
     #[inline]
     pub fn key(&self) -> &str {
-        self.key.as_ref().map_or(Self::DEFAULT, |key| key)
+        if self.enabled {
+            return self.key.as_ref().map_or("", |key| key);
+        }
+        ""
     }
 
     #[inline]
     pub fn null(&self) -> &str {
-        self.null.as_ref().map_or(Self::DEFAULT, |null| null)
+        if self.enabled {
+            return self.null.as_ref().map_or("󰟢", |null| null);
+        }
+        ""
     }
 
     #[inline]
     pub fn enum_member(&self) -> &str {
-        self.enum_member
-            .as_ref()
-            .map_or(Self::DEFAULT, |enum_member| enum_member)
+        if self.enabled {
+            return self
+                .enum_member
+                .as_ref()
+                .map_or("", |enum_member| enum_member);
+        }
+        ""
     }
 
     #[inline]
     pub fn r#struct(&self) -> &str {
-        self.r#struct
-            .as_ref()
-            .map_or(Self::DEFAULT, |r#struct| r#struct)
+        if self.enabled {
+            return self.r#struct.as_ref().map_or("", |r#struct| r#struct);
+        }
+        ""
     }
 
     #[inline]
     pub fn event(&self) -> &str {
-        self.event.as_ref().map_or(Self::DEFAULT, |event| event)
+        if self.enabled {
+            return self.event.as_ref().map_or("", |event| event);
+        }
+        ""
     }
 
     #[inline]
     pub fn operator(&self) -> &str {
-        self.operator
-            .as_ref()
-            .map_or(Self::DEFAULT, |operator| operator)
+        if self.enabled {
+            return self.operator.as_ref().map_or("", |operator| operator);
+        }
+        ""
     }
 
     #[inline]
     pub fn type_parameter(&self) -> &str {
-        self.type_parameter
-            .as_ref()
-            .map_or(Self::DEFAULT, |type_parameter| type_parameter)
+        if self.enabled {
+            return self
+                .type_parameter
+                .as_ref()
+                .map_or("", |type_parameter| type_parameter);
+        }
+        ""
     }
 }
 
@@ -213,78 +274,128 @@ pub struct Diagnostic {
     error: Option<String>,
 }
 
-// NOTE: #6646 can be achieved by uncommenting this or adding the symbols
-// to the `map_or` default.
-// impl Default for Diagnostic {
-//     fn default() -> Self {
-//         Self {
-//             hint: Some(String::from("○")),
-//             info: Some(String::from("●")),
-//             warning: Some(String::from("▲")),
-//             error: Some(String::from("■")),
-//         }
-//     }
-// }
-
 impl Diagnostic {
-    const DEFAULT: &'static str = "●";
-
     #[inline]
     pub fn hint(&self) -> &str {
-        self.hint.as_ref().map_or(Self::DEFAULT, |hint| hint)
+        self.hint.as_ref().map_or("○", |hint| hint)
     }
 
     #[inline]
     pub fn info(&self) -> &str {
-        self.info.as_ref().map_or(Self::DEFAULT, |info| info)
+        self.info.as_ref().map_or("●", |info| info)
     }
 
     #[inline]
     pub fn warning(&self) -> &str {
-        self.warning
-            .as_ref()
-            .map_or(Self::DEFAULT, |warning| warning)
+        self.warning.as_ref().map_or("▲", |warning| warning)
     }
 
     #[inline]
     pub fn error(&self) -> &str {
-        self.error.as_ref().map_or(Self::DEFAULT, |error| error)
+        self.error.as_ref().map_or("■", |error| error)
     }
 }
 
 #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Default)]
 pub struct Vcs {
+    enabled: bool,
     icon: Option<String>,
 }
 
 impl Vcs {
-    const DEFAULT: &'static str = "";
-
     #[inline]
     pub fn icon(&self) -> &str {
-        self.icon
-            .as_ref()
-            .map_or(Self::DEFAULT, |icon| icon.as_str())
+        if self.enabled {
+            return self.icon.as_ref().map_or("", |icon| icon.as_str());
+        }
+        ""
     }
 }
 
 #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Default)]
 pub struct Mime {
+    enabled: bool,
     directory: Option<String>,
     #[serde(flatten)]
     mime: HashMap<String, String>,
 }
 
+static MIMES: once_cell::sync::Lazy<HashMap<String, String>> = once_cell::sync::Lazy::new(|| {
+    let mut mimes = HashMap::new();
+
+    mimes.insert(String::from("rust"), String::from("󱘗"));
+    mimes.insert(String::from("python"), String::from("󰌠"));
+    mimes.insert(String::from("c"), String::from(""));
+    mimes.insert(String::from("cpp"), String::from(""));
+    mimes.insert(String::from("c-sharp"), String::from("󰌛"));
+    mimes.insert(String::from("d"), String::from(""));
+    mimes.insert(String::from("elixir"), String::from(""));
+    mimes.insert(String::from("fsharp"), String::from(""));
+    mimes.insert(String::from("go"), String::from("󰟓"));
+    mimes.insert(String::from("haskell"), String::from("󰲒"));
+    mimes.insert(String::from("java"), String::from("󰬷"));
+    mimes.insert(String::from("javascript"), String::from("󰌞"));
+    mimes.insert(String::from("kotlin"), String::from("󱈙"));
+    mimes.insert(String::from("html"), String::from("󰌝"));
+    mimes.insert(String::from("css"), String::from("󰌜"));
+    mimes.insert(String::from("typescript"), String::from("󰛦"));
+    mimes.insert(String::from("bash"), String::from(""));
+    mimes.insert(String::from("php"), String::from("󰌟"));
+    mimes.insert(String::from("powershell"), String::from("󰨊"));
+    mimes.insert(String::from("dart"), String::from(""));
+    mimes.insert(String::from("ruby"), String::from("󰴭"));
+    mimes.insert(String::from("swift"), String::from("󰛥"));
+    mimes.insert(String::from("r"), String::from("󰟔"));
+    mimes.insert(String::from("groovy"), String::from(""));
+    mimes.insert(String::from("scala"), String::from(""));
+    mimes.insert(String::from("perl"), String::from(""));
+    mimes.insert(String::from("closure"), String::from(""));
+    mimes.insert(String::from("julia"), String::from(""));
+    mimes.insert(String::from("zig"), String::from(""));
+    mimes.insert(String::from("fortran"), String::from("󱈚"));
+    mimes.insert(String::from("erlang"), String::from(""));
+    mimes.insert(String::from("ocaml"), String::from(""));
+    mimes.insert(String::from("crystal"), String::from(""));
+    mimes.insert(String::from("svelte"), String::from(""));
+    mimes.insert(String::from("gdscript"), String::from(""));
+    mimes.insert(String::from("nim"), String::from(""));
+
+    mimes.insert(String::from("docker"), String::from("󰡨"));
+    mimes.insert(String::from("make"), String::from(""));
+    mimes.insert(String::from("cmake"), String::from(""));
+    mimes.insert(String::from("nix"), String::from(""));
+
+    mimes.insert(String::from("text"), String::from(""));
+    mimes.insert(String::from("markdown"), String::from(""));
+    mimes.insert(String::from("json"), String::from("󰘦"));
+    mimes.insert(String::from("toml"), String::from(""));
+    mimes.insert(String::from("xml"), String::from("󰗀"));
+
+    mimes
+});
+
 impl Mime {
     #[inline]
     pub fn directory(&self) -> &str {
-        self.directory.as_ref().map_or("", |directory| directory)
+        if self.enabled {
+            return self.directory.as_ref().map_or("󰉋", |directory| directory);
+        } else if let Some(directory) = &self.directory {
+            return directory;
+        }
+        ""
     }
 
     // Returns the symbol that matches the name, if any, otherwise returns the name back.
     #[inline]
     pub fn get<'name, 'mime: 'name>(&'mime self, r#type: &'name str) -> &'name str {
-        self.mime.get(r#type).map_or(r#type, |mime| mime)
+        if self.enabled {
+            if let Some(symbol) = self.mime.get(r#type) {
+                return symbol;
+            } else if let Some(symbol) = MIMES.get(r#type) {
+                return symbol;
+            }
+        }
+        r#type
     }
 }
 
@@ -295,20 +406,13 @@ pub struct Dap {
 }
 
 impl Dap {
-    const DEFAULT_VERIFIED: &'static str = "●";
-    const DEFAULT_UNVERIFIED: &'static str = "◯";
-
     #[inline]
     pub fn verified(&self) -> &str {
-        self.verified
-            .as_ref()
-            .map_or(Self::DEFAULT_VERIFIED, |verified| verified)
+        self.verified.as_ref().map_or("●", |verified| verified)
     }
 
     #[inline]
     pub fn unverified(&self) -> &str {
-        self.verified
-            .as_ref()
-            .map_or(Self::DEFAULT_UNVERIFIED, |verified| verified)
+        self.verified.as_ref().map_or("◯", |verified| verified)
     }
 }

From 0865ca281210b7abb6842752262b052b5c663dd7 Mon Sep 17 00:00:00 2001
From: Rolo <roloedits@gmail.com>
Date: Mon, 30 Dec 2024 16:31:49 -0800
Subject: [PATCH 08/16] perf: switch from `String` to `SmartString`

---
 Cargo.lock                      | 2 ++
 helix-view/Cargo.toml           | 2 ++
 helix-view/src/editor/config.rs | 4 ++++
 3 files changed, 8 insertions(+)

diff --git a/Cargo.lock b/Cargo.lock
index 8531d0a3..bff6e1db 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1564,6 +1564,7 @@ dependencies = [
  "serde",
  "serde_json",
  "slotmap",
+ "smartstring",
  "tempfile",
  "thiserror 2.0.11",
  "tokio",
@@ -2419,6 +2420,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29"
 dependencies = [
  "autocfg",
+ "serde",
  "static_assertions",
  "version_check",
 ]
diff --git a/helix-view/Cargo.toml b/helix-view/Cargo.toml
index da9f52a2..eb1b660f 100644
--- a/helix-view/Cargo.toml
+++ b/helix-view/Cargo.toml
@@ -52,6 +52,8 @@ log = "~0.4"
 parking_lot = "0.12.3"
 thiserror.workspace = true
 
+smartstring = { version = "1.0.1", features = ["serde"]}
+
 [target.'cfg(windows)'.dependencies]
 clipboard-win = { version = "5.4", features = ["std"] }
 
diff --git a/helix-view/src/editor/config.rs b/helix-view/src/editor/config.rs
index 34d2a2cb..7865bd95 100644
--- a/helix-view/src/editor/config.rs
+++ b/helix-view/src/editor/config.rs
@@ -2,6 +2,10 @@ use std::collections::HashMap;
 
 use serde::{Deserialize, Serialize};
 
+use smartstring::{LazyCompact, SmartString};
+
+type String = SmartString<LazyCompact>;
+
 #[derive(Debug, Serialize, Deserialize, Default, PartialEq, Eq, Clone)]
 #[serde(default)]
 pub struct Icons {

From 952c9721674bf43975ccff10e8544b40bfbc3281 Mon Sep 17 00:00:00 2001
From: Rolo <roloedits@gmail.com>
Date: Tue, 31 Dec 2024 03:34:17 -0800
Subject: [PATCH 09/16] refactor: rename config.rs to icons.rs and move to top
 level

---
 helix-view/src/editor.rs                      | 5 ++---
 helix-view/src/{editor/config.rs => icons.rs} | 0
 helix-view/src/lib.rs                         | 1 +
 3 files changed, 3 insertions(+), 3 deletions(-)
 rename helix-view/src/{editor/config.rs => icons.rs} (100%)

diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs
index 004d0bf1..eb30db62 100644
--- a/helix-view/src/editor.rs
+++ b/helix-view/src/editor.rs
@@ -7,6 +7,7 @@ use crate::{
     events::DocumentFocusLost,
     graphics::{CursorKind, Rect},
     handlers::Handlers,
+    icons,
     info::Info,
     input::KeyEvent,
     register::Registers,
@@ -14,18 +15,16 @@ use crate::{
     tree::{self, Tree},
     Document, DocumentId, View, ViewId,
 };
-use config::Icons;
 use dap::StackFrame;
 use helix_event::dispatch;
 use helix_vcs::DiffProviderRegistry;
+use icons::Icons;
 
 use futures_util::stream::select_all::SelectAll;
 use futures_util::{future, StreamExt};
 use helix_lsp::{Call, LanguageServerId};
 use tokio_stream::wrappers::UnboundedReceiverStream;
 
-mod config;
-
 use std::{
     borrow::Cow,
     cell::Cell,
diff --git a/helix-view/src/editor/config.rs b/helix-view/src/icons.rs
similarity index 100%
rename from helix-view/src/editor/config.rs
rename to helix-view/src/icons.rs
diff --git a/helix-view/src/lib.rs b/helix-view/src/lib.rs
index d54b49ef..a5b45159 100644
--- a/helix-view/src/lib.rs
+++ b/helix-view/src/lib.rs
@@ -10,6 +10,7 @@ pub mod events;
 pub mod graphics;
 pub mod gutter;
 pub mod handlers;
+pub mod icons;
 pub mod info;
 pub mod input;
 pub mod keyboard;

From cec003ce99b35232f9da023b07f0e728666cea48 Mon Sep 17 00:00:00 2001
From: Rolo <roloedits@gmail.com>
Date: Tue, 31 Dec 2024 03:38:39 -0800
Subject: [PATCH 10/16] refactor: rename mime get param from type to name

---
 helix-view/src/icons.rs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/helix-view/src/icons.rs b/helix-view/src/icons.rs
index 7865bd95..9d736973 100644
--- a/helix-view/src/icons.rs
+++ b/helix-view/src/icons.rs
@@ -391,15 +391,15 @@ impl Mime {
 
     // Returns the symbol that matches the name, if any, otherwise returns the name back.
     #[inline]
-    pub fn get<'name, 'mime: 'name>(&'mime self, r#type: &'name str) -> &'name str {
+    pub fn get<'name, 'mime: 'name>(&'mime self, name: &'name str) -> &'name str {
         if self.enabled {
-            if let Some(symbol) = self.mime.get(r#type) {
+            if let Some(symbol) = self.mime.get(name) {
                 return symbol;
-            } else if let Some(symbol) = MIMES.get(r#type) {
+            } else if let Some(symbol) = MIMES.get(name) {
                 return symbol;
             }
         }
-        r#type
+        name
     }
 }
 

From 7267097e91dcdd2766d93b0ef77565b9a1acdf79 Mon Sep 17 00:00:00 2001
From: Rolo <roloedits@gmail.com>
Date: Tue, 31 Dec 2024 03:50:51 -0800
Subject: [PATCH 11/16] refactor: small renames for better clarity

---
 helix-term/src/ui/statusline.rs | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/helix-term/src/ui/statusline.rs b/helix-term/src/ui/statusline.rs
index 0034db61..f02b4b88 100644
--- a/helix-term/src/ui/statusline.rs
+++ b/helix-term/src/ui/statusline.rs
@@ -422,9 +422,11 @@ fn render_file_type<F>(context: &mut RenderContext, write: F)
 where
     F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
 {
-    let mime = &context.editor.config().icons.mime;
+    let icons = &context.editor.config().icons;
 
-    let icon = mime.get(context.doc.language_name().unwrap_or(DEFAULT_LANGUAGE_NAME));
+    let icon = icons
+        .mime
+        .get(context.doc.language_name().unwrap_or(DEFAULT_LANGUAGE_NAME));
 
     write(context, format!(" {} ", icon), None);
 }
@@ -530,8 +532,8 @@ where
 {
     let head = context.doc.version_control_head().unwrap_or_default();
 
-    let config = context.editor.config();
-    let icon = config.icons.vcs.icon();
+    let icons = &context.editor.config().icons;
+    let icon = icons.vcs.icon();
 
     let vcs = if head.is_empty() {
         format!("{head}")

From c8e3a569ce071ba492d6b55a330c77d66067f415 Mon Sep 17 00:00:00 2001
From: Rolo <roloedits@gmail.com>
Date: Tue, 31 Dec 2024 03:51:19 -0800
Subject: [PATCH 12/16] doc: add description for `Icons` in `Editor`

---
 helix-view/src/editor.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs
index eb30db62..f48eb77b 100644
--- a/helix-view/src/editor.rs
+++ b/helix-view/src/editor.rs
@@ -362,7 +362,7 @@ pub struct Config {
     pub end_of_line_diagnostics: DiagnosticFilter,
     // Set to override the default clipboard provider
     pub clipboard_provider: ClipboardProvider,
-
+    /// Centralized location for icons that can be used throughout the UI  
     pub icons: Icons,
 }
 

From 0d3e4f3bb89ad4bffd32d85ca250abe8eb4b3e32 Mon Sep 17 00:00:00 2001
From: Rolo <roloedits@gmail.com>
Date: Tue, 31 Dec 2024 08:10:54 -0800
Subject: [PATCH 13/16] refactor: tweak with bufferline icon spacing

---
 helix-term/src/ui/editor.rs | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs
index 4f5b1cc3..267e63cc 100644
--- a/helix-term/src/ui/editor.rs
+++ b/helix-term/src/ui/editor.rs
@@ -650,11 +650,16 @@ impl EditorView {
             let config = editor.config();
             let icon = config.icons.mime.get(lang);
 
-            let text = format!(
-                " {icon} {}{} ",
-                fname,
-                if doc.is_modified() { "[+]" } else { "" }
-            );
+            let text = if lang == icon {
+                format!(" {} {}", fname, if doc.is_modified() { "[+] " } else { "" })
+            } else {
+                format!(
+                    " {icon} {} {}",
+                    fname,
+                    if doc.is_modified() { "[+] " } else { "" }
+                )
+            };
+
             let used_width = viewport.x.saturating_sub(x);
             let rem_width = surface.area.width.saturating_sub(used_width);
 

From 4a37fe0f58fa95dddeb72c0fe6399cefa0ab1dcd Mon Sep 17 00:00:00 2001
From: Rolo <roloedits@gmail.com>
Date: Sat, 4 Jan 2025 07:44:22 -0800
Subject: [PATCH 14/16] refactor: change lsp icons to `nf-cod-symbol` where
 possible

---
 helix-view/src/icons.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/helix-view/src/icons.rs b/helix-view/src/icons.rs
index 9d736973..c46e1dcf 100644
--- a/helix-view/src/icons.rs
+++ b/helix-view/src/icons.rs
@@ -170,7 +170,7 @@ impl Lsp {
     #[inline]
     pub fn string(&self) -> &str {
         if self.enabled {
-            return self.string.as_ref().map_or("", |string| string);
+            return self.string.as_ref().map_or("", |string| string);
         }
         ""
     }
@@ -178,7 +178,7 @@ impl Lsp {
     #[inline]
     pub fn number(&self) -> &str {
         if self.enabled {
-            return self.number.as_ref().map_or("", |number| number);
+            return self.number.as_ref().map_or("", |number| number);
         }
         ""
     }
@@ -210,7 +210,7 @@ impl Lsp {
     #[inline]
     pub fn key(&self) -> &str {
         if self.enabled {
-            return self.key.as_ref().map_or("", |key| key);
+            return self.key.as_ref().map_or("", |key| key);
         }
         ""
     }

From fd54ee930cce4f1fc6c63aad2abd7c9fec62177b Mon Sep 17 00:00:00 2001
From: Rolo <roloedits@gmail.com>
Date: Sat, 4 Jan 2025 09:01:31 -0800
Subject: [PATCH 15/16] feat: add more icons for supported languages

---
 helix-view/src/icons.rs | 44 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 43 insertions(+), 1 deletion(-)

diff --git a/helix-view/src/icons.rs b/helix-view/src/icons.rs
index c46e1dcf..d22ed522 100644
--- a/helix-view/src/icons.rs
+++ b/helix-view/src/icons.rs
@@ -6,6 +6,7 @@ use smartstring::{LazyCompact, SmartString};
 
 type String = SmartString<LazyCompact>;
 
+
 #[derive(Debug, Serialize, Deserialize, Default, PartialEq, Eq, Clone)]
 #[serde(default)]
 pub struct Icons {
@@ -342,6 +343,7 @@ static MIMES: once_cell::sync::Lazy<HashMap<String, String>> = once_cell::sync::
     mimes.insert(String::from("kotlin"), String::from("󱈙"));
     mimes.insert(String::from("html"), String::from("󰌝"));
     mimes.insert(String::from("css"), String::from("󰌜"));
+    mimes.insert(String::from("scss"), String::from("󰌜"));
     mimes.insert(String::from("typescript"), String::from("󰛦"));
     mimes.insert(String::from("bash"), String::from(""));
     mimes.insert(String::from("php"), String::from("󰌟"));
@@ -353,7 +355,7 @@ static MIMES: once_cell::sync::Lazy<HashMap<String, String>> = once_cell::sync::
     mimes.insert(String::from("groovy"), String::from(""));
     mimes.insert(String::from("scala"), String::from(""));
     mimes.insert(String::from("perl"), String::from(""));
-    mimes.insert(String::from("closure"), String::from(""));
+    mimes.insert(String::from("clojure"), String::from(""));
     mimes.insert(String::from("julia"), String::from(""));
     mimes.insert(String::from("zig"), String::from(""));
     mimes.insert(String::from("fortran"), String::from("󱈚"));
@@ -363,17 +365,57 @@ static MIMES: once_cell::sync::Lazy<HashMap<String, String>> = once_cell::sync::
     mimes.insert(String::from("svelte"), String::from(""));
     mimes.insert(String::from("gdscript"), String::from(""));
     mimes.insert(String::from("nim"), String::from(""));
+    mimes.insert(String::from("jsx"), String::from(""));
+    mimes.insert(String::from("tsx"), String::from(""));
+    mimes.insert(String::from("twig"), String::from(""));
+    mimes.insert(String::from("lua"), String::from(""));
+    mimes.insert(String::from("vue"), String::from(""));
+    mimes.insert(String::from("prolog"), String::from(""));
+    mimes.insert(String::from("common-lisp"), String::from(""));
+    mimes.insert(String::from("elm"), String::from(""));
+    mimes.insert(String::from("rescript"), String::from(""));
+    mimes.insert(String::from("solidity"), String::from(""));
+    mimes.insert(String::from("vala"), String::from(""));
+    mimes.insert(String::from("scheme"), String::from(""));
+    mimes.insert(String::from("v"), String::from(""));
+    mimes.insert(String::from("prisma"), String::from(""));
+    mimes.insert(String::from("ada"), String::from(""));
+    mimes.insert(String::from("astro"), String::from(""));
+    mimes.insert(String::from("matlab"), String::from(""));
+    mimes.insert(String::from("rst"), String::from(""));
+    mimes.insert(String::from("opencl"), String::from(""));
+    mimes.insert(String::from("nunjuks"), String::from(""));
+    mimes.insert(String::from("jinja"), String::from(""));
+
+    mimes.insert(String::from("bicep"), String::from(""));
+
+    mimes.insert(String::from("wasm"), String::from(""));
 
     mimes.insert(String::from("docker"), String::from("󰡨"));
+    mimes.insert(String::from("docker-compose"), String::from("󰡨"));
     mimes.insert(String::from("make"), String::from(""));
     mimes.insert(String::from("cmake"), String::from(""));
     mimes.insert(String::from("nix"), String::from(""));
+    mimes.insert(String::from("awk"), String::from(""));
+    mimes.insert(String::from("llvm"), String::from(""));
+    mimes.insert(String::from("llvm-mir"), String::from(""));
+    mimes.insert(String::from("regex"), String::from(""));
+    mimes.insert(String::from("graphql"), String::from(""));
 
     mimes.insert(String::from("text"), String::from(""));
     mimes.insert(String::from("markdown"), String::from(""));
+    mimes.insert(String::from("typst"), String::from(""));
     mimes.insert(String::from("json"), String::from("󰘦"));
     mimes.insert(String::from("toml"), String::from(""));
     mimes.insert(String::from("xml"), String::from("󰗀"));
+    mimes.insert(String::from("latex"), String::from(""));
+    mimes.insert(String::from("git-commit"), String::from(""));
+    mimes.insert(String::from("git-rebase"), String::from(""));
+    mimes.insert(String::from("git-config"), String::from(""));
+    mimes.insert(String::from("todotxt"), String::from(""));
+    mimes.insert(String::from("hyprlang"), String::from(""));
+    mimes.insert(String::from("helm"), String::from(""));
+    mimes.insert(String::from("nginx"), String::from(""));
 
     mimes
 });

From f445f86d26737bdff6bc88cf974928dfa09f0d05 Mon Sep 17 00:00:00 2001
From: Rolo <roloedits@gmail.com>
Date: Sat, 4 Jan 2025 09:02:52 -0800
Subject: [PATCH 16/16] todo: outline more icon domains and sets

---
 helix-view/src/icons.rs | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/helix-view/src/icons.rs b/helix-view/src/icons.rs
index d22ed522..f7e1984e 100644
--- a/helix-view/src/icons.rs
+++ b/helix-view/src/icons.rs
@@ -6,6 +6,9 @@ use smartstring::{LazyCompact, SmartString};
 
 type String = SmartString<LazyCompact>;
 
+// TODO: Vcs { added  , removed  , ignored  , modified  , renamed  }
+// TODO: Snippet {enabled, icon  }
+// TODO: Text/Spellcheck { enabled, icon 󰓆 }
 
 #[derive(Debug, Serialize, Deserialize, Default, PartialEq, Eq, Clone)]
 #[serde(default)]