From a0a622d20dfeb784e40830a49a82680df5d0a8e7 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:20:26 +0000 Subject: [PATCH 01/30] feat: show color boxes in color completion --- Cargo.lock | 38 +++++++++++++++++ helix-term/src/ui/completion.rs | 76 ++++++++++++++++++++------------- helix-view/Cargo.toml | 2 + helix-view/src/graphics.rs | 7 +++ 4 files changed, 93 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 559e9eb8..322d1d66 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -122,6 +122,12 @@ version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytes" version = "1.7.1" @@ -1455,6 +1461,7 @@ dependencies = [ "helix-stdx", "helix-tui", "helix-vcs", + "hex_color", "libc", "log", "once_cell", @@ -1477,6 +1484,15 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hex_color" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d37f101bf4c633f7ca2e4b5e136050314503dd198e78e325ea602c327c484ef0" +dependencies = [ + "rand", +] + [[package]] name = "home" version = "0.5.9" @@ -1978,6 +1994,15 @@ version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + [[package]] name = "proc-macro2" version = "1.0.86" @@ -2032,6 +2057,18 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", "rand_core", ] @@ -2982,6 +3019,7 @@ version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index ad317e39..91b11534 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -9,7 +9,7 @@ use helix_view::{ document::SavePoint, editor::CompleteAction, handlers::lsp::SignatureHelpInvoked, - theme::{Modifier, Style}, + theme::{Color, Modifier, Style}, ViewId, }; use tui::{buffer::Buffer as Surface, text::Span}; @@ -25,7 +25,10 @@ use helix_view::{graphics::Rect, Document, Editor}; use crate::ui::{menu, Markdown, Menu, Popup, PromptEvent}; -use helix_lsp::{lsp, util, OffsetEncoding}; +use helix_lsp::{ + lsp::{self, Documentation, MarkupContent}, + util, OffsetEncoding, +}; impl menu::Item for CompletionItem { type Data = Style; @@ -64,38 +67,51 @@ impl menu::Item for CompletionItem { let kind = match self { CompletionItem::Lsp(LspCompletionItem { item, .. }) => match item.kind { - Some(lsp::CompletionItemKind::TEXT) => "text", - Some(lsp::CompletionItemKind::METHOD) => "method", - Some(lsp::CompletionItemKind::FUNCTION) => "function", - Some(lsp::CompletionItemKind::CONSTRUCTOR) => "constructor", - Some(lsp::CompletionItemKind::FIELD) => "field", - Some(lsp::CompletionItemKind::VARIABLE) => "variable", - Some(lsp::CompletionItemKind::CLASS) => "class", - Some(lsp::CompletionItemKind::INTERFACE) => "interface", - Some(lsp::CompletionItemKind::MODULE) => "module", - Some(lsp::CompletionItemKind::PROPERTY) => "property", - Some(lsp::CompletionItemKind::UNIT) => "unit", - Some(lsp::CompletionItemKind::VALUE) => "value", - Some(lsp::CompletionItemKind::ENUM) => "enum", - Some(lsp::CompletionItemKind::KEYWORD) => "keyword", - Some(lsp::CompletionItemKind::SNIPPET) => "snippet", - Some(lsp::CompletionItemKind::COLOR) => "color", - Some(lsp::CompletionItemKind::FILE) => "file", - Some(lsp::CompletionItemKind::REFERENCE) => "reference", - Some(lsp::CompletionItemKind::FOLDER) => "folder", - Some(lsp::CompletionItemKind::ENUM_MEMBER) => "enum_member", - Some(lsp::CompletionItemKind::CONSTANT) => "constant", - Some(lsp::CompletionItemKind::STRUCT) => "struct", - Some(lsp::CompletionItemKind::EVENT) => "event", - Some(lsp::CompletionItemKind::OPERATOR) => "operator", - Some(lsp::CompletionItemKind::TYPE_PARAMETER) => "type_param", + Some(lsp::CompletionItemKind::TEXT) => "text".into(), + Some(lsp::CompletionItemKind::METHOD) => "method".into(), + Some(lsp::CompletionItemKind::FUNCTION) => "function".into(), + Some(lsp::CompletionItemKind::CONSTRUCTOR) => "constructor".into(), + Some(lsp::CompletionItemKind::FIELD) => "field".into(), + Some(lsp::CompletionItemKind::VARIABLE) => "variable".into(), + Some(lsp::CompletionItemKind::CLASS) => "class".into(), + Some(lsp::CompletionItemKind::INTERFACE) => "interface".into(), + Some(lsp::CompletionItemKind::MODULE) => "module".into(), + Some(lsp::CompletionItemKind::PROPERTY) => "property".into(), + Some(lsp::CompletionItemKind::UNIT) => "unit".into(), + Some(lsp::CompletionItemKind::VALUE) => "value".into(), + Some(lsp::CompletionItemKind::ENUM) => "enum".into(), + Some(lsp::CompletionItemKind::KEYWORD) => "keyword".into(), + Some(lsp::CompletionItemKind::SNIPPET) => "snippet".into(), + Some(lsp::CompletionItemKind::COLOR) => { + let doc = item.documentation.clone(); + let maybe_hex_color = match &doc { + Some(Documentation::String(text)) => Some(text), + Some(Documentation::MarkupContent(MarkupContent { value, .. })) => { + Some(value) + } + None => None, + }; + maybe_hex_color.map_or(Span::raw("color"), |c| match Color::from_hex(c) { + Ok(l) => Span::styled("●", Style::default().fg(l)), + Err(_) => Span::raw("color"), + }) + } + Some(lsp::CompletionItemKind::FILE) => "file".into(), + Some(lsp::CompletionItemKind::REFERENCE) => "reference".into(), + Some(lsp::CompletionItemKind::FOLDER) => "folder".into(), + Some(lsp::CompletionItemKind::ENUM_MEMBER) => "enum_member".into(), + Some(lsp::CompletionItemKind::CONSTANT) => "constant".into(), + Some(lsp::CompletionItemKind::STRUCT) => "struct".into(), + Some(lsp::CompletionItemKind::EVENT) => "event".into(), + Some(lsp::CompletionItemKind::OPERATOR) => "operator".into(), + Some(lsp::CompletionItemKind::TYPE_PARAMETER) => "type_param".into(), Some(kind) => { log::error!("Received unknown completion item kind: {:?}", kind); - "" + "".into() } - None => "", + None => "".into(), }, - CompletionItem::Other(core::CompletionItem { kind, .. }) => kind, + CompletionItem::Other(core::CompletionItem { kind, .. }) => Span::raw(kind.to_string()), }; menu::Row::new([ diff --git a/helix-view/Cargo.toml b/helix-view/Cargo.toml index 6f71fa05..8247bab4 100644 --- a/helix-view/Cargo.toml +++ b/helix-view/Cargo.toml @@ -44,6 +44,8 @@ slotmap = "1" chardetng = "0.1" +hex_color = "3.0" + serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" toml = "0.8" diff --git a/helix-view/src/graphics.rs b/helix-view/src/graphics.rs index a26823b9..45d3d1a1 100644 --- a/helix-view/src/graphics.rs +++ b/helix-view/src/graphics.rs @@ -1,4 +1,5 @@ use bitflags::bitflags; +use hex_color::{HexColor, ParseHexColorError}; use serde::{Deserialize, Serialize}; use std::{ cmp::{max, min}, @@ -263,6 +264,12 @@ pub enum Color { Indexed(u8), } +impl Color { + pub fn from_hex(hex: &str) -> Result { + HexColor::parse_rgb(hex).map(|c| Self::Rgb(c.r, c.g, c.b)) + } +} + #[cfg(feature = "term")] impl From for crossterm::style::Color { fn from(color: Color) -> Self { From 2b0c425cc64a7cffd22d605725963225871db5e5 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:28:19 +0000 Subject: [PATCH 02/30] feat: larger boxess --- helix-term/src/ui/completion.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index 91b11534..255ae149 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -92,7 +92,7 @@ impl menu::Item for CompletionItem { None => None, }; maybe_hex_color.map_or(Span::raw("color"), |c| match Color::from_hex(c) { - Ok(l) => Span::styled("●", Style::default().fg(l)), + Ok(l) => Span::styled(" ", Style::default().bg(l)), Err(_) => Span::raw("color"), }) } From 565c98110727466848acabd63e9066f5002bf56e Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:50:36 +0000 Subject: [PATCH 03/30] refactor: no longer need so many `.into()` --- helix-term/src/ui/completion.rs | 92 +++++++++++++++++---------------- 1 file changed, 48 insertions(+), 44 deletions(-) diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index 255ae149..4d8d16c0 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -67,21 +67,21 @@ impl menu::Item for CompletionItem { let kind = match self { CompletionItem::Lsp(LspCompletionItem { item, .. }) => match item.kind { - Some(lsp::CompletionItemKind::TEXT) => "text".into(), - Some(lsp::CompletionItemKind::METHOD) => "method".into(), - Some(lsp::CompletionItemKind::FUNCTION) => "function".into(), - Some(lsp::CompletionItemKind::CONSTRUCTOR) => "constructor".into(), - Some(lsp::CompletionItemKind::FIELD) => "field".into(), - Some(lsp::CompletionItemKind::VARIABLE) => "variable".into(), - Some(lsp::CompletionItemKind::CLASS) => "class".into(), - Some(lsp::CompletionItemKind::INTERFACE) => "interface".into(), - Some(lsp::CompletionItemKind::MODULE) => "module".into(), - Some(lsp::CompletionItemKind::PROPERTY) => "property".into(), - Some(lsp::CompletionItemKind::UNIT) => "unit".into(), - Some(lsp::CompletionItemKind::VALUE) => "value".into(), - Some(lsp::CompletionItemKind::ENUM) => "enum".into(), - Some(lsp::CompletionItemKind::KEYWORD) => "keyword".into(), - Some(lsp::CompletionItemKind::SNIPPET) => "snippet".into(), + Some(lsp::CompletionItemKind::TEXT) => "text", + Some(lsp::CompletionItemKind::METHOD) => "method", + Some(lsp::CompletionItemKind::FUNCTION) => "function", + Some(lsp::CompletionItemKind::CONSTRUCTOR) => "constructor", + Some(lsp::CompletionItemKind::FIELD) => "field", + Some(lsp::CompletionItemKind::VARIABLE) => "variable", + Some(lsp::CompletionItemKind::CLASS) => "class", + Some(lsp::CompletionItemKind::INTERFACE) => "interface", + Some(lsp::CompletionItemKind::MODULE) => "module", + Some(lsp::CompletionItemKind::PROPERTY) => "property", + Some(lsp::CompletionItemKind::UNIT) => "unit", + Some(lsp::CompletionItemKind::VALUE) => "value", + Some(lsp::CompletionItemKind::ENUM) => "enum", + Some(lsp::CompletionItemKind::KEYWORD) => "keyword", + Some(lsp::CompletionItemKind::SNIPPET) => "snippet", Some(lsp::CompletionItemKind::COLOR) => { let doc = item.documentation.clone(); let maybe_hex_color = match &doc { @@ -91,42 +91,46 @@ impl menu::Item for CompletionItem { } None => None, }; - maybe_hex_color.map_or(Span::raw("color"), |c| match Color::from_hex(c) { - Ok(l) => Span::styled(" ", Style::default().bg(l)), - Err(_) => Span::raw("color"), - }) + return menu::Row::new([ + first_cell, + maybe_hex_color + .map_or(Span::raw("color"), |c| match Color::from_hex(c) { + Ok(l) => Span::styled(" ", Style::default().bg(l)), + Err(_) => Span::raw("color"), + }) + .into(), + ]); } - Some(lsp::CompletionItemKind::FILE) => "file".into(), - Some(lsp::CompletionItemKind::REFERENCE) => "reference".into(), - Some(lsp::CompletionItemKind::FOLDER) => "folder".into(), - Some(lsp::CompletionItemKind::ENUM_MEMBER) => "enum_member".into(), - Some(lsp::CompletionItemKind::CONSTANT) => "constant".into(), - Some(lsp::CompletionItemKind::STRUCT) => "struct".into(), - Some(lsp::CompletionItemKind::EVENT) => "event".into(), - Some(lsp::CompletionItemKind::OPERATOR) => "operator".into(), - Some(lsp::CompletionItemKind::TYPE_PARAMETER) => "type_param".into(), + Some(lsp::CompletionItemKind::FILE) => "file", + Some(lsp::CompletionItemKind::REFERENCE) => "reference", + Some(lsp::CompletionItemKind::FOLDER) => "folder", + Some(lsp::CompletionItemKind::ENUM_MEMBER) => "enum_member", + Some(lsp::CompletionItemKind::CONSTANT) => "constant", + Some(lsp::CompletionItemKind::STRUCT) => "struct", + Some(lsp::CompletionItemKind::EVENT) => "event", + Some(lsp::CompletionItemKind::OPERATOR) => "operator", + Some(lsp::CompletionItemKind::TYPE_PARAMETER) => "type_param", Some(kind) => { log::error!("Received unknown completion item kind: {:?}", kind); - "".into() + "" } - None => "".into(), + None => "", }, - CompletionItem::Other(core::CompletionItem { kind, .. }) => Span::raw(kind.to_string()), + CompletionItem::Other(core::CompletionItem { kind, .. }) => kind, }; - menu::Row::new([ - menu::Cell::from(Span::styled( - label, - if deprecated { - Style::default().add_modifier(Modifier::CROSSED_OUT) - } else if kind == "folder" { - *dir_style - } else { - Style::default() - }, - )), - menu::Cell::from(kind), - ]) + let first_cell = menu::Cell::from(Span::styled( + label, + if deprecated { + Style::default().add_modifier(Modifier::CROSSED_OUT) + } else if kind.stuff == "folder" { + *dir_style + } else { + Style::default() + }, + )); + + menu::Row::new([first_cell, menu::Cell::from(kind)]) } } From 22259e3a8c73a79c5d260e33f5681794db8b1847 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:53:34 +0000 Subject: [PATCH 04/30] refactor: better variable naming --- helix-term/src/ui/completion.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index 4d8d16c0..8e34c574 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -94,9 +94,11 @@ impl menu::Item for CompletionItem { return menu::Row::new([ first_cell, maybe_hex_color - .map_or(Span::raw("color"), |c| match Color::from_hex(c) { - Ok(l) => Span::styled(" ", Style::default().bg(l)), - Err(_) => Span::raw("color"), + .map_or(Span::raw("color"), |hex_color| { + match Color::from_hex(hex_color) { + Ok(l) => Span::styled(" ", Style::default().bg(l)), + Err(_) => Span::raw("color"), + } }) .into(), ]); From f1281b1634bc9a012c338b586de863d0f0300657 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:55:22 +0000 Subject: [PATCH 05/30] perf: do not use unnecessary `clone` --- helix-term/src/ui/completion.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index 8e34c574..ff4cbc9e 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -83,8 +83,7 @@ impl menu::Item for CompletionItem { Some(lsp::CompletionItemKind::KEYWORD) => "keyword", Some(lsp::CompletionItemKind::SNIPPET) => "snippet", Some(lsp::CompletionItemKind::COLOR) => { - let doc = item.documentation.clone(); - let maybe_hex_color = match &doc { + let maybe_hex_color = match &item.documentation { Some(Documentation::String(text)) => Some(text), Some(Documentation::MarkupContent(MarkupContent { value, .. })) => { Some(value) From b7f7e2528b17b3ba1bba7da1d87a7b12397ea130 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 16:08:27 +0000 Subject: [PATCH 06/30] feat: do not add unnecessary custom method --- Cargo.lock | 2 +- helix-term/Cargo.toml | 2 ++ helix-term/src/ui/completion.rs | 5 ++++- helix-view/Cargo.toml | 2 -- helix-view/src/graphics.rs | 7 ------- 5 files changed, 7 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 322d1d66..6897e953 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1387,6 +1387,7 @@ dependencies = [ "helix-tui", "helix-vcs", "helix-view", + "hex_color", "ignore", "indoc", "libc", @@ -1461,7 +1462,6 @@ dependencies = [ "helix-stdx", "helix-tui", "helix-vcs", - "hex_color", "libc", "log", "once_cell", diff --git a/helix-term/Cargo.toml b/helix-term/Cargo.toml index 5b46a261..a8810eed 100644 --- a/helix-term/Cargo.toml +++ b/helix-term/Cargo.toml @@ -49,6 +49,8 @@ fern = "0.7" chrono = { version = "0.4", default-features = false, features = ["clock"] } log = "0.4" +hex_color = "3.0" + # File picker nucleo.workspace = true ignore = "0.4" diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index ff4cbc9e..76ab1ad1 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -12,6 +12,7 @@ use helix_view::{ theme::{Color, Modifier, Style}, ViewId, }; +use hex_color::HexColor; use tui::{buffer::Buffer as Surface, text::Span}; use std::{borrow::Cow, sync::Arc}; @@ -94,7 +95,9 @@ impl menu::Item for CompletionItem { first_cell, maybe_hex_color .map_or(Span::raw("color"), |hex_color| { - match Color::from_hex(hex_color) { + match HexColor::parse_rgb(hex_color) + .map(|c| Color::Rgb(c.r, c.g, c.b)) + { Ok(l) => Span::styled(" ", Style::default().bg(l)), Err(_) => Span::raw("color"), } diff --git a/helix-view/Cargo.toml b/helix-view/Cargo.toml index 8247bab4..6f71fa05 100644 --- a/helix-view/Cargo.toml +++ b/helix-view/Cargo.toml @@ -44,8 +44,6 @@ slotmap = "1" chardetng = "0.1" -hex_color = "3.0" - serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" toml = "0.8" diff --git a/helix-view/src/graphics.rs b/helix-view/src/graphics.rs index 45d3d1a1..a26823b9 100644 --- a/helix-view/src/graphics.rs +++ b/helix-view/src/graphics.rs @@ -1,5 +1,4 @@ use bitflags::bitflags; -use hex_color::{HexColor, ParseHexColorError}; use serde::{Deserialize, Serialize}; use std::{ cmp::{max, min}, @@ -264,12 +263,6 @@ pub enum Color { Indexed(u8), } -impl Color { - pub fn from_hex(hex: &str) -> Result { - HexColor::parse_rgb(hex).map(|c| Self::Rgb(c.r, c.g, c.b)) - } -} - #[cfg(feature = "term")] impl From for crossterm::style::Color { fn from(color: Color) -> Self { From fbbb045d8785fc1ebc19567a4be7d30c43861455 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 16:37:31 +0000 Subject: [PATCH 07/30] refactor: do not use extra dependency --- helix-term/src/ui/completion.rs | 37 +++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index 76ab1ad1..a929a40b 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -91,19 +91,30 @@ impl menu::Item for CompletionItem { } None => None, }; - return menu::Row::new([ - first_cell, - maybe_hex_color - .map_or(Span::raw("color"), |hex_color| { - match HexColor::parse_rgb(hex_color) - .map(|c| Color::Rgb(c.r, c.g, c.b)) - { - Ok(l) => Span::styled(" ", Style::default().bg(l)), - Err(_) => Span::raw("color"), - } - }) - .into(), - ]); + + let content = maybe_hex_color.map_or(Span::raw("color"), |hex_color| { + let maybe_color = match ( + hex_color + .get(1..=2) + .and_then(|r| u8::from_str_radix(r, 16).ok()), + hex_color + .get(3..=4) + .and_then(|g| u8::from_str_radix(g, 16).ok()), + hex_color + .get(5..=6) + .and_then(|b| u8::from_str_radix(b, 16).ok()), + ) { + (Some(r), Some(g), Some(b)) => Some(Color::Rgb(r, g, b)), + _ => None, + }; + + match maybe_color { + Some(color) => Span::styled(" ", Style::default().bg(color)), + None => Span::raw("color"), + } + }); + + return menu::Row::new([first_cell, menu::Cell::from(content)]); } Some(lsp::CompletionItemKind::FILE) => "file", Some(lsp::CompletionItemKind::REFERENCE) => "reference", From 3097c7efd075b3de7b07da7affdead75c01decd5 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 16:38:19 +0000 Subject: [PATCH 08/30] feat: remove dependency --- Cargo.lock | 38 -------------------------------------- helix-term/Cargo.toml | 2 -- 2 files changed, 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6897e953..559e9eb8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -122,12 +122,6 @@ version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - [[package]] name = "bytes" version = "1.7.1" @@ -1387,7 +1381,6 @@ dependencies = [ "helix-tui", "helix-vcs", "helix-view", - "hex_color", "ignore", "indoc", "libc", @@ -1484,15 +1477,6 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" -[[package]] -name = "hex_color" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d37f101bf4c633f7ca2e4b5e136050314503dd198e78e325ea602c327c484ef0" -dependencies = [ - "rand", -] - [[package]] name = "home" version = "0.5.9" @@ -1994,15 +1978,6 @@ version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" -[[package]] -name = "ppv-lite86" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] - [[package]] name = "proc-macro2" version = "1.0.86" @@ -2057,18 +2032,6 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", "rand_core", ] @@ -3019,7 +2982,6 @@ version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ - "byteorder", "zerocopy-derive", ] diff --git a/helix-term/Cargo.toml b/helix-term/Cargo.toml index a8810eed..5b46a261 100644 --- a/helix-term/Cargo.toml +++ b/helix-term/Cargo.toml @@ -49,8 +49,6 @@ fern = "0.7" chrono = { version = "0.4", default-features = false, features = ["clock"] } log = "0.4" -hex_color = "3.0" - # File picker nucleo.workspace = true ignore = "0.4" From d9919798cce3d037867c9779c8eaa4b431e241eb Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 16:42:55 +0000 Subject: [PATCH 09/30] refactor: use an array of ranges --- helix-term/src/ui/completion.rs | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index a929a40b..88d74bae 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -93,18 +93,14 @@ impl menu::Item for CompletionItem { }; let content = maybe_hex_color.map_or(Span::raw("color"), |hex_color| { - let maybe_color = match ( - hex_color - .get(1..=2) - .and_then(|r| u8::from_str_radix(r, 16).ok()), - hex_color - .get(3..=4) - .and_then(|g| u8::from_str_radix(g, 16).ok()), - hex_color - .get(5..=6) - .and_then(|b| u8::from_str_radix(b, 16).ok()), - ) { - (Some(r), Some(g), Some(b)) => Some(Color::Rgb(r, g, b)), + let maybe_color = match { + [1..=2, 3..=4, 5..=6].map(|a| { + hex_color + .get(a) + .and_then(|c| u8::from_str_radix(c, 16).ok()) + }) + } { + [Some(r), Some(g), Some(b)] => Some(Color::Rgb(r, g, b)), _ => None, }; From 495adf7b6343dbb0faa3c34b5d34a86f3fe64271 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 16:52:28 +0000 Subject: [PATCH 10/30] refactor: extract into a `from_hex` method on Color --- helix-term/src/ui/completion.rs | 13 ++----------- helix-view/src/graphics.rs | 11 +++++++++++ 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index 88d74bae..939bd9cb 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -92,17 +92,8 @@ impl menu::Item for CompletionItem { None => None, }; - let content = maybe_hex_color.map_or(Span::raw("color"), |hex_color| { - let maybe_color = match { - [1..=2, 3..=4, 5..=6].map(|a| { - hex_color - .get(a) - .and_then(|c| u8::from_str_radix(c, 16).ok()) - }) - } { - [Some(r), Some(g), Some(b)] => Some(Color::Rgb(r, g, b)), - _ => None, - }; + let content = maybe_hex_color.map_or(Span::raw("color"), |hex| { + let maybe_color = Color::from_hex(hex); match maybe_color { Some(color) => Span::styled(" ", Style::default().bg(color)), diff --git a/helix-view/src/graphics.rs b/helix-view/src/graphics.rs index a26823b9..3ee7622f 100644 --- a/helix-view/src/graphics.rs +++ b/helix-view/src/graphics.rs @@ -263,6 +263,17 @@ pub enum Color { Indexed(u8), } +impl Color { + pub fn from_hex(hex: &str) -> Option { + match [1..=2, 3..=4, 5..=6] + .map(|range| hex.get(range).and_then(|c| u8::from_str_radix(c, 16).ok())) + { + [Some(r), Some(g), Some(b)] => Some(Self::Rgb(r, g, b)), + _ => None, + } + } +} + #[cfg(feature = "term")] impl From for crossterm::style::Color { fn from(color: Color) -> Self { From 73286a1497d5f2550d9883b0a4c7b645cc01a01d Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 16:56:30 +0000 Subject: [PATCH 11/30] refactor: do not return early --- helix-term/src/ui/completion.rs | 109 ++++++++++++++++---------------- 1 file changed, 54 insertions(+), 55 deletions(-) diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index 939bd9cb..0b713cec 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -66,61 +66,6 @@ impl menu::Item for CompletionItem { CompletionItem::Other(core::CompletionItem { label, .. }) => label, }; - let kind = match self { - CompletionItem::Lsp(LspCompletionItem { item, .. }) => match item.kind { - Some(lsp::CompletionItemKind::TEXT) => "text", - Some(lsp::CompletionItemKind::METHOD) => "method", - Some(lsp::CompletionItemKind::FUNCTION) => "function", - Some(lsp::CompletionItemKind::CONSTRUCTOR) => "constructor", - Some(lsp::CompletionItemKind::FIELD) => "field", - Some(lsp::CompletionItemKind::VARIABLE) => "variable", - Some(lsp::CompletionItemKind::CLASS) => "class", - Some(lsp::CompletionItemKind::INTERFACE) => "interface", - Some(lsp::CompletionItemKind::MODULE) => "module", - Some(lsp::CompletionItemKind::PROPERTY) => "property", - Some(lsp::CompletionItemKind::UNIT) => "unit", - Some(lsp::CompletionItemKind::VALUE) => "value", - Some(lsp::CompletionItemKind::ENUM) => "enum", - Some(lsp::CompletionItemKind::KEYWORD) => "keyword", - Some(lsp::CompletionItemKind::SNIPPET) => "snippet", - Some(lsp::CompletionItemKind::COLOR) => { - let maybe_hex_color = match &item.documentation { - Some(Documentation::String(text)) => Some(text), - Some(Documentation::MarkupContent(MarkupContent { value, .. })) => { - Some(value) - } - None => None, - }; - - let content = maybe_hex_color.map_or(Span::raw("color"), |hex| { - let maybe_color = Color::from_hex(hex); - - match maybe_color { - Some(color) => Span::styled(" ", Style::default().bg(color)), - None => Span::raw("color"), - } - }); - - return menu::Row::new([first_cell, menu::Cell::from(content)]); - } - Some(lsp::CompletionItemKind::FILE) => "file", - Some(lsp::CompletionItemKind::REFERENCE) => "reference", - Some(lsp::CompletionItemKind::FOLDER) => "folder", - Some(lsp::CompletionItemKind::ENUM_MEMBER) => "enum_member", - Some(lsp::CompletionItemKind::CONSTANT) => "constant", - Some(lsp::CompletionItemKind::STRUCT) => "struct", - Some(lsp::CompletionItemKind::EVENT) => "event", - Some(lsp::CompletionItemKind::OPERATOR) => "operator", - Some(lsp::CompletionItemKind::TYPE_PARAMETER) => "type_param", - Some(kind) => { - log::error!("Received unknown completion item kind: {:?}", kind); - "" - } - None => "", - }, - CompletionItem::Other(core::CompletionItem { kind, .. }) => kind, - }; - let first_cell = menu::Cell::from(Span::styled( label, if deprecated { @@ -133,6 +78,60 @@ impl menu::Item for CompletionItem { )); menu::Row::new([first_cell, menu::Cell::from(kind)]) + + + let kind = match self { + CompletionItem::Lsp(LspCompletionItem { item, .. }) => match item.kind { + Some(lsp::CompletionItemKind::TEXT) => "text".into(), + Some(lsp::CompletionItemKind::METHOD) => "method".into(), + Some(lsp::CompletionItemKind::FUNCTION) => "function".into(), + Some(lsp::CompletionItemKind::CONSTRUCTOR) => "constructor".into(), + Some(lsp::CompletionItemKind::FIELD) => "field".into(), + Some(lsp::CompletionItemKind::VARIABLE) => "variable".into(), + Some(lsp::CompletionItemKind::CLASS) => "class".into(), + Some(lsp::CompletionItemKind::INTERFACE) => "interface".into(), + Some(lsp::CompletionItemKind::MODULE) => "module".into(), + Some(lsp::CompletionItemKind::PROPERTY) => "property".into(), + Some(lsp::CompletionItemKind::UNIT) => "unit".into(), + Some(lsp::CompletionItemKind::VALUE) => "value".into(), + Some(lsp::CompletionItemKind::ENUM) => "enum".into(), + Some(lsp::CompletionItemKind::KEYWORD) => "keyword".into(), + Some(lsp::CompletionItemKind::SNIPPET) => "snippet".into(), + Some(lsp::CompletionItemKind::COLOR) => { + let maybe_hex_color = match &item.documentation { + Some(Documentation::String(text)) => Some(text), + Some(Documentation::MarkupContent(MarkupContent { value, .. })) => { + Some(value) + } + None => None, + }; + + maybe_hex_color.map_or(Span::raw("color"), |hex| { + let maybe_color = Color::from_hex(hex); + + match maybe_color { + Some(color) => Span::styled(" ", Style::default().bg(color)), + None => Span::raw("color"), + } + }) + } + Some(lsp::CompletionItemKind::FILE) => "file".into(), + Some(lsp::CompletionItemKind::REFERENCE) => "reference".into(), + Some(lsp::CompletionItemKind::FOLDER) => "folder".into(), + Some(lsp::CompletionItemKind::ENUM_MEMBER) => "enum_member".into(), + Some(lsp::CompletionItemKind::CONSTANT) => "constant".into(), + Some(lsp::CompletionItemKind::STRUCT) => "struct".into(), + Some(lsp::CompletionItemKind::EVENT) => "event".into(), + Some(lsp::CompletionItemKind::OPERATOR) => "operator".into(), + Some(lsp::CompletionItemKind::TYPE_PARAMETER) => "type_param".into(), + Some(kind) => { + log::error!("Received unknown completion item kind: {:?}", kind); + "".into() + } + None => "".into(), + }, + CompletionItem::Other(core::CompletionItem { kind, .. }) => Span::raw(kind.to_string()), + }; } } From 1a2b6166cd3b4b21be63a3dfce7849dffb272af8 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 17:07:40 +0000 Subject: [PATCH 12/30] feat: use "color" text for accessibility next to a small colored cube --- helix-term/src/ui/completion.rs | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index 0b713cec..1cef6fea 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -12,8 +12,10 @@ use helix_view::{ theme::{Color, Modifier, Style}, ViewId, }; -use hex_color::HexColor; -use tui::{buffer::Buffer as Surface, text::Span}; +use tui::{ + buffer::Buffer as Surface, + text::{Span, Spans}, +}; use std::{borrow::Cow, sync::Arc}; @@ -110,8 +112,8 @@ impl menu::Item for CompletionItem { let maybe_color = Color::from_hex(hex); match maybe_color { - Some(color) => Span::styled(" ", Style::default().bg(color)), - None => Span::raw("color"), + Some(color) => Span::styled("■", Style::default().fg(color)), + None => Span::raw(""), } }) } @@ -132,6 +134,21 @@ impl menu::Item for CompletionItem { }, CompletionItem::Other(core::CompletionItem { kind, .. }) => Span::raw(kind.to_string()), }; + menu::Row::new([ + menu::Cell::from(Span::styled( + label, + if deprecated { + Style::default().add_modifier(Modifier::CROSSED_OUT) + } else { + Style::default() + }, + )), + if kind.content == "■" { + menu::Cell::from(Spans::from(vec![Span::raw("color "), kind])) + } else { + menu::Cell::from(kind) + }, + ]) } } From 662b6d3e53930b9b7018b2a876afba6b56147da5 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 17:17:25 +0000 Subject: [PATCH 13/30] refactor: rename variable for consistency --- helix-term/src/ui/completion.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index 1cef6fea..12dbca19 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -101,7 +101,7 @@ impl menu::Item for CompletionItem { Some(lsp::CompletionItemKind::SNIPPET) => "snippet".into(), Some(lsp::CompletionItemKind::COLOR) => { let maybe_hex_color = match &item.documentation { - Some(Documentation::String(text)) => Some(text), + Some(Documentation::String(value)) => Some(value), Some(Documentation::MarkupContent(MarkupContent { value, .. })) => { Some(value) } From fc54f2e51a0a2100687ac246d073c4c1cf7b66ef Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 17:30:49 +0000 Subject: [PATCH 14/30] fix: "color" for items with documentation but a hex value which cannot be parsed --- helix-term/src/ui/completion.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index 12dbca19..8b341afb 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -113,7 +113,8 @@ impl menu::Item for CompletionItem { match maybe_color { Some(color) => Span::styled("■", Style::default().fg(color)), - None => Span::raw(""), + // there is documentation but it doesn't conform to the format to parse the hex color + None => Span::raw("color"), } }) } From aed0f8d1f83aaf4ed551b47bd05c9ac0f102d7a8 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 17:32:06 +0000 Subject: [PATCH 15/30] refactor: remove extra variable assignment --- helix-term/src/ui/completion.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index 8b341afb..e969ef1c 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -109,9 +109,7 @@ impl menu::Item for CompletionItem { }; maybe_hex_color.map_or(Span::raw("color"), |hex| { - let maybe_color = Color::from_hex(hex); - - match maybe_color { + match Color::from_hex(hex) { Some(color) => Span::styled("■", Style::default().fg(color)), // there is documentation but it doesn't conform to the format to parse the hex color None => Span::raw("color"), From 6617f1209c2921faefdf830cc6b49aecf67d7112 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 17:37:44 +0000 Subject: [PATCH 16/30] docs: add doc for from_hex --- helix-view/src/graphics.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/helix-view/src/graphics.rs b/helix-view/src/graphics.rs index 3ee7622f..fa0e078c 100644 --- a/helix-view/src/graphics.rs +++ b/helix-view/src/graphics.rs @@ -263,6 +263,16 @@ pub enum Color { Indexed(u8), } +/// Creates a `Color` from a hex string +/// +/// # Examples +/// +/// ```rust +/// let color1 = Color::from_hex("#c0ffee"); +/// let color2 = Color::Rgb(192, 255, 238); +/// +/// assert_eq!(color1, color2); +/// ``` impl Color { pub fn from_hex(hex: &str) -> Option { match [1..=2, 3..=4, 5..=6] From b00cac307adc901adfc69e985227342f13575e7f Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 17:39:44 +0000 Subject: [PATCH 17/30] docs: use `unwrap` in example to extract from Option --- helix-view/src/graphics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-view/src/graphics.rs b/helix-view/src/graphics.rs index fa0e078c..67160aed 100644 --- a/helix-view/src/graphics.rs +++ b/helix-view/src/graphics.rs @@ -268,7 +268,7 @@ pub enum Color { /// # Examples /// /// ```rust -/// let color1 = Color::from_hex("#c0ffee"); +/// let color1 = Color::from_hex("#c0ffee").unwrap(); /// let color2 = Color::Rgb(192, 255, 238); /// /// assert_eq!(color1, color2); From 0e7b3925c58b95c430f9bd58380b4b4a556ffbd1 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 17:41:03 +0000 Subject: [PATCH 18/30] docs: place in the correct position --- helix-view/src/graphics.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/helix-view/src/graphics.rs b/helix-view/src/graphics.rs index 67160aed..049dc534 100644 --- a/helix-view/src/graphics.rs +++ b/helix-view/src/graphics.rs @@ -263,17 +263,17 @@ pub enum Color { Indexed(u8), } -/// Creates a `Color` from a hex string -/// -/// # Examples -/// -/// ```rust -/// let color1 = Color::from_hex("#c0ffee").unwrap(); -/// let color2 = Color::Rgb(192, 255, 238); -/// -/// assert_eq!(color1, color2); -/// ``` impl Color { + /// Creates a `Color` from a hex string + /// + /// # Examples + /// + /// ```rust + /// let color1 = Color::from_hex("#c0ffee").unwrap(); + /// let color2 = Color::Rgb(192, 255, 238); + /// + /// assert_eq!(color1, color2); + /// ``` pub fn from_hex(hex: &str) -> Option { match [1..=2, 3..=4, 5..=6] .map(|range| hex.get(range).and_then(|c| u8::from_str_radix(c, 16).ok())) From 8e17b7424c332af2dd9e7daac730228827d44092 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 17:42:50 +0000 Subject: [PATCH 19/30] refactor: better variable naming --- helix-view/src/graphics.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/helix-view/src/graphics.rs b/helix-view/src/graphics.rs index 049dc534..58bcff2f 100644 --- a/helix-view/src/graphics.rs +++ b/helix-view/src/graphics.rs @@ -275,8 +275,7 @@ impl Color { /// assert_eq!(color1, color2); /// ``` pub fn from_hex(hex: &str) -> Option { - match [1..=2, 3..=4, 5..=6] - .map(|range| hex.get(range).and_then(|c| u8::from_str_radix(c, 16).ok())) + match [1..=2, 3..=4, 5..=6].map(|i| hex.get(i).and_then(|c| u8::from_str_radix(c, 16).ok())) { [Some(r), Some(g), Some(b)] => Some(Self::Rgb(r, g, b)), _ => None, From 1cc2235828529beaa29b632b0ff22aa857555e92 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 17:47:15 +0000 Subject: [PATCH 20/30] docs: use Color in doc test --- helix-view/src/graphics.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/helix-view/src/graphics.rs b/helix-view/src/graphics.rs index 58bcff2f..8fa40808 100644 --- a/helix-view/src/graphics.rs +++ b/helix-view/src/graphics.rs @@ -269,6 +269,8 @@ impl Color { /// # Examples /// /// ```rust + /// use helix_view::theme::Color + /// /// let color1 = Color::from_hex("#c0ffee").unwrap(); /// let color2 = Color::Rgb(192, 255, 238); /// From 530748db96c7aff75bc77856702b3f2f65e8a18c Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 17:49:02 +0000 Subject: [PATCH 21/30] docs: missing semicolon --- helix-view/src/graphics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-view/src/graphics.rs b/helix-view/src/graphics.rs index 8fa40808..6ecc8076 100644 --- a/helix-view/src/graphics.rs +++ b/helix-view/src/graphics.rs @@ -269,7 +269,7 @@ impl Color { /// # Examples /// /// ```rust - /// use helix_view::theme::Color + /// use helix_view::theme::Color; /// /// let color1 = Color::from_hex("#c0ffee").unwrap(); /// let color2 = Color::Rgb(192, 255, 238); From c2e24a44ac6cd5c85a7eb75be43b72c6acd11520 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 21:24:46 +0000 Subject: [PATCH 22/30] feat: reject a set of invalid inputs for Color::from_hex --- helix-view/src/graphics.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/helix-view/src/graphics.rs b/helix-view/src/graphics.rs index 6ecc8076..fcc037ed 100644 --- a/helix-view/src/graphics.rs +++ b/helix-view/src/graphics.rs @@ -277,6 +277,9 @@ impl Color { /// assert_eq!(color1, color2); /// ``` pub fn from_hex(hex: &str) -> Option { + if !(hex.starts_with('#') && hex.len() == 7) { + return None; + } match [1..=2, 3..=4, 5..=6].map(|i| hex.get(i).and_then(|c| u8::from_str_radix(c, 16).ok())) { [Some(r), Some(g), Some(b)] => Some(Self::Rgb(r, g, b)), From f29f336c4d65b15a80c7fecc4e258891d7ef7852 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 21:33:37 +0000 Subject: [PATCH 23/30] feat: resolve merge conflicts --- helix-term/src/ui/completion.rs | 35 ++++++++++++--------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index e969ef1c..f9b4330d 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -68,20 +68,6 @@ impl menu::Item for CompletionItem { CompletionItem::Other(core::CompletionItem { label, .. }) => label, }; - let first_cell = menu::Cell::from(Span::styled( - label, - if deprecated { - Style::default().add_modifier(Modifier::CROSSED_OUT) - } else if kind.stuff == "folder" { - *dir_style - } else { - Style::default() - }, - )); - - menu::Row::new([first_cell, menu::Cell::from(kind)]) - - let kind = match self { CompletionItem::Lsp(LspCompletionItem { item, .. }) => match item.kind { Some(lsp::CompletionItemKind::TEXT) => "text".into(), @@ -133,15 +119,20 @@ impl menu::Item for CompletionItem { }, CompletionItem::Other(core::CompletionItem { kind, .. }) => Span::raw(kind.to_string()), }; + + let first_cell = menu::Cell::from(Span::styled( + label, + if deprecated { + Style::default().add_modifier(Modifier::CROSSED_OUT) + } else if kind.content == "folder" { + *dir_style + } else { + Style::default() + }, + )); + menu::Row::new([ - menu::Cell::from(Span::styled( - label, - if deprecated { - Style::default().add_modifier(Modifier::CROSSED_OUT) - } else { - Style::default() - }, - )), + first_cell, if kind.content == "■" { menu::Cell::from(Spans::from(vec![Span::raw("color "), kind])) } else { From 3d8dc157a08cc3d1b94fb6e10d27047cd1268679 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 21:35:15 +0000 Subject: [PATCH 24/30] perf: avoid unnecessary string allocation --- helix-term/src/ui/completion.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index f9b4330d..0922b088 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -117,7 +117,7 @@ impl menu::Item for CompletionItem { } None => "".into(), }, - CompletionItem::Other(core::CompletionItem { kind, .. }) => Span::raw(kind.to_string()), + CompletionItem::Other(core::CompletionItem { kind, .. }) => kind.as_ref().into(), }; let first_cell = menu::Cell::from(Span::styled( From 52ce26ccecfe359668834c49476a7447a91eabff Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 21:46:11 +0000 Subject: [PATCH 25/30] refactor: `kind` is `Spans` --- helix-term/src/ui/completion.rs | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index 0922b088..60eb8b4d 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -94,11 +94,14 @@ impl menu::Item for CompletionItem { None => None, }; - maybe_hex_color.map_or(Span::raw("color"), |hex| { + maybe_hex_color.map_or(Span::raw("color").into(), |hex| { match Color::from_hex(hex) { - Some(color) => Span::styled("■", Style::default().fg(color)), - // there is documentation but it doesn't conform to the format to parse the hex color - None => Span::raw("color"), + Some(color) => Spans::from(vec![ + Span::raw("color "), + Span::styled("■", Style::default().fg(color)), + ]), + // there is documentation but it cannot be parsed as a color + None => "color".into(), } }) } @@ -120,25 +123,20 @@ impl menu::Item for CompletionItem { CompletionItem::Other(core::CompletionItem { kind, .. }) => kind.as_ref().into(), }; - let first_cell = menu::Cell::from(Span::styled( + log::error!("{:#?}", kind.0[0].content); + + let label = Span::styled( label, if deprecated { Style::default().add_modifier(Modifier::CROSSED_OUT) - } else if kind.content == "folder" { + } else if kind.0[0].content == "folder" { *dir_style } else { Style::default() }, - )); + ); - menu::Row::new([ - first_cell, - if kind.content == "■" { - menu::Cell::from(Spans::from(vec![Span::raw("color "), kind])) - } else { - menu::Cell::from(kind) - }, - ]) + menu::Row::new([menu::Cell::from(label), menu::Cell::from(kind)]) } } From 8bfff23bb96132314694a158adf2dd7e60d8892d Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 21:50:00 +0000 Subject: [PATCH 26/30] fix: remove unnecessary log statement --- helix-term/src/ui/completion.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index 60eb8b4d..e4aaa3be 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -123,8 +123,6 @@ impl menu::Item for CompletionItem { CompletionItem::Other(core::CompletionItem { kind, .. }) => kind.as_ref().into(), }; - log::error!("{:#?}", kind.0[0].content); - let label = Span::styled( label, if deprecated { From e55e8863c87188b2b068fa36a110c1fe72b129d4 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Thu, 19 Dec 2024 21:58:53 +0000 Subject: [PATCH 27/30] docs: distinction between "color" and "hex color" --- helix-term/src/ui/completion.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index e4aaa3be..c23ec958 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -100,7 +100,7 @@ impl menu::Item for CompletionItem { Span::raw("color "), Span::styled("■", Style::default().fg(color)), ]), - // there is documentation but it cannot be parsed as a color + // there is documentation but it cannot be parsed as a hex color None => "color".into(), } }) From 98e408f603941855a9e785c7ad07b936409deeb3 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Fri, 20 Dec 2024 06:58:31 +0000 Subject: [PATCH 28/30] refactor: use .into() instead of explicit Spans::raw --- helix-term/src/ui/completion.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index c23ec958..0d1f1595 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -94,7 +94,7 @@ impl menu::Item for CompletionItem { None => None, }; - maybe_hex_color.map_or(Span::raw("color").into(), |hex| { + maybe_hex_color.map_or("color".into(), |hex| { match Color::from_hex(hex) { Some(color) => Spans::from(vec![ Span::raw("color "), From cebdc599d6951a39084fd5b230c9d178fd9c7807 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Fri, 20 Dec 2024 11:07:49 -0500 Subject: [PATCH 29/30] style - simplify option handling --- helix-term/src/ui/completion.rs | 34 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index 0d1f1595..4004e5c4 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -85,26 +85,22 @@ impl menu::Item for CompletionItem { Some(lsp::CompletionItemKind::ENUM) => "enum".into(), Some(lsp::CompletionItemKind::KEYWORD) => "keyword".into(), Some(lsp::CompletionItemKind::SNIPPET) => "snippet".into(), - Some(lsp::CompletionItemKind::COLOR) => { - let maybe_hex_color = match &item.documentation { - Some(Documentation::String(value)) => Some(value), - Some(Documentation::MarkupContent(MarkupContent { value, .. })) => { - Some(value) - } - None => None, - }; - - maybe_hex_color.map_or("color".into(), |hex| { - match Color::from_hex(hex) { - Some(color) => Spans::from(vec![ - Span::raw("color "), - Span::styled("■", Style::default().fg(color)), - ]), - // there is documentation but it cannot be parsed as a hex color - None => "color".into(), - } + Some(lsp::CompletionItemKind::COLOR) => item + .documentation + .as_ref() + .and_then(|docs| { + let text = match docs { + Documentation::String(text) => text, + Documentation::MarkupContent(MarkupContent { value, .. }) => value, + }; + Color::from_hex(text) }) - } + .map_or("color".into(), |color| { + Spans::from(vec![ + Span::raw("color "), + Span::styled("■", Style::default().fg(color)), + ]) + }), Some(lsp::CompletionItemKind::FILE) => "file".into(), Some(lsp::CompletionItemKind::REFERENCE) => "reference".into(), Some(lsp::CompletionItemKind::FOLDER) => "folder".into(), From e25fcfc590695bb8d0fe815f163f09660b1e0eb7 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Fri, 20 Dec 2024 11:10:00 -0500 Subject: [PATCH 30/30] style - replace use with qualified path --- helix-term/src/ui/completion.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index 4004e5c4..adacfad3 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -28,10 +28,7 @@ use helix_view::{graphics::Rect, Document, Editor}; use crate::ui::{menu, Markdown, Menu, Popup, PromptEvent}; -use helix_lsp::{ - lsp::{self, Documentation, MarkupContent}, - util, OffsetEncoding, -}; +use helix_lsp::{lsp, util, OffsetEncoding}; impl menu::Item for CompletionItem { type Data = Style; @@ -90,8 +87,10 @@ impl menu::Item for CompletionItem { .as_ref() .and_then(|docs| { let text = match docs { - Documentation::String(text) => text, - Documentation::MarkupContent(MarkupContent { value, .. }) => value, + lsp::Documentation::String(text) => text, + lsp::Documentation::MarkupContent(lsp::MarkupContent { + value, .. + }) => value, }; Color::from_hex(text) })