From 63f61dca043ace4daae9fa1e3fbca941f2a7541e Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Thu, 14 Aug 2025 18:02:27 +0800 Subject: [PATCH] chore: Avoid built-in tree-sitter languages in default. (#1135) With a `tree-sitter-languages` feature to enable it (Default not enable). Changed this for reduce the application size (From 52 MB to 22MB), Ref #1132 Now default only includes `tree-sitter-json`, if you want more: ```toml [dependencies] gpui-component = { features = ["tree-sitter-languages"] } ``` --- ``` cargo bloat -p hello_world --release -n 10 Finished `release` profile [optimized] target(s) in 0.27s Analyzing target/release/hello_world File .text Size Crate Name 0.4% 1.4% 88.5KiB simple_minify_html simple_minify_html::code_gen::attrs::ATTRS::{{closure}} 0.3% 1.0% 62.1KiB taffy taffy::compute::grid::track_sizing::resolve_intrinsic_track_sizes 0.1% 0.5% 32.6KiB gpui_component gpui_component::theme::theme_color::ThemeColor::dark 0.1% 0.5% 30.0KiB gpui_component gpui_component::theme::theme_color::ThemeColor::light 0.1% 0.5% 29.9KiB html5ever html5ever::tree_builder::TreeBuilder::step 0.1% 0.4% 27.2KiB gpui taffy::compute::flexbox::compute_flexbox_layout 0.1% 0.4% 23.3KiB usvg usvg::text::layout::layout_text 0.1% 0.4% 22.5KiB resvg resvg::filter::apply_inner 0.1% 0.3% 21.4KiB gpui jpeg_decoder::decoder::Decoder::decode_internal 0.1% 0.3% 21.2KiB image_webp image_webp::lossless::LosslessDecoder::decode_image_stream 25.3% 94.3% 5.7MiB And 14091 smaller methods. Use -n N to show more. 26.8% 100.0% 6.0MiB .text section size, the file size is 22.4MiB ``` --- Cargo.lock | 9 ++ Cargo.toml | 1 + crates/hello_world/Cargo.toml | 14 +++ .../src/main.rs} | 0 crates/story/Cargo.toml | 2 +- crates/ui/Cargo.toml | 87 +++++++++++++------ crates/ui/src/highlighter/languages.rs | 64 +++++++------- crates/ui/src/highlighter/registry.rs | 33 ++++++- 8 files changed, 149 insertions(+), 61 deletions(-) create mode 100644 crates/hello_world/Cargo.toml rename crates/{story/examples/hello_world.rs => hello_world/src/main.rs} (100%) diff --git a/Cargo.lock b/Cargo.lock index f36fb7c3..5fa9aaa0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3363,6 +3363,15 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hello_world" +version = "0.1.0" +dependencies = [ + "anyhow", + "gpui", + "gpui-component", +] + [[package]] name = "hermit-abi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index b06f9f55..8119ccbc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] members = [ "crates/macros", + "crates/hello_world", "crates/story", "crates/ui", "crates/wef", diff --git a/crates/hello_world/Cargo.toml b/crates/hello_world/Cargo.toml new file mode 100644 index 00000000..f5ec8a90 --- /dev/null +++ b/crates/hello_world/Cargo.toml @@ -0,0 +1,14 @@ +[package] +edition = "2021" +name = "hello_world" +description = "A minimal example of application development with GPUI Component." +publish = false +version = "0.1.0" + +[dependencies] +anyhow.workspace = true +gpui.workspace = true +gpui-component = { workspace = true } + +[lints] +workspace = true diff --git a/crates/story/examples/hello_world.rs b/crates/hello_world/src/main.rs similarity index 100% rename from crates/story/examples/hello_world.rs rename to crates/hello_world/src/main.rs diff --git a/crates/story/Cargo.toml b/crates/story/Cargo.toml index bbb215df..8b43324c 100644 --- a/crates/story/Cargo.toml +++ b/crates/story/Cargo.toml @@ -7,7 +7,7 @@ version = "0.1.0" [dependencies] anyhow.workspace = true gpui.workspace = true -gpui-component = { workspace = true, features = ["webview"] } +gpui-component = { workspace = true, features = ["webview", "tree-sitter-languages"] } chrono = "0.4" fake = { version = "2.10.0", features = ["dummy"] } diff --git a/crates/ui/Cargo.toml b/crates/ui/Cargo.toml index 56994222..b23a9d6f 100644 --- a/crates/ui/Cargo.toml +++ b/crates/ui/Cargo.toml @@ -15,6 +15,37 @@ doctest = false decimal = ["dep:rust_decimal"] inspector = [] webview = ["dep:wry"] +# For syntax highlighting in Markdown and CodeEditor. +tree-sitter-languages = [ + "dep:tree-sitter-bash", + "dep:tree-sitter-c", + "dep:tree-sitter-c-sharp", + "dep:tree-sitter-cmake", + "dep:tree-sitter-cpp", + "dep:tree-sitter-css", + "dep:tree-sitter-diff", + "dep:tree-sitter-elixir", + "dep:tree-sitter-embedded-template", + "dep:tree-sitter-go", + "dep:tree-sitter-graphql", + "dep:tree-sitter-html", + "dep:tree-sitter-java", + "dep:tree-sitter-javascript", + "dep:tree-sitter-jsdoc", + "dep:tree-sitter-make", + "dep:tree-sitter-md", + "dep:tree-sitter-proto", + "dep:tree-sitter-python", + "dep:tree-sitter-ruby", + "dep:tree-sitter-rust", + "dep:tree-sitter-scala", + "dep:tree-sitter-sequel", + "dep:tree-sitter-swift", + "dep:tree-sitter-toml-ng", + "dep:tree-sitter-typescript", + "dep:tree-sitter-yaml", + "dep:tree-sitter-zig" +] [dependencies] gpui.workspace = true @@ -61,35 +92,35 @@ chrono = "0.4.38" # Code Editor indexset = "0.12.2" tree-sitter = "0.25.4" -tree-sitter-bash = "0.23.3" -tree-sitter-c = "0.24.1" -tree-sitter-c-sharp = "0.23.1" -tree-sitter-cmake = "0.7.1" -tree-sitter-cpp = "0.23.4" -tree-sitter-css = "0.23.2" -tree-sitter-diff = "0.1.0" -tree-sitter-elixir = "0.3" -tree-sitter-embedded-template = "0.23.0" -tree-sitter-go = "0.23.4" -tree-sitter-graphql = "0.1.0" -tree-sitter-html = "0.23.2" -tree-sitter-java = "0.23.5" -tree-sitter-javascript = "0.23.1" -tree-sitter-jsdoc = "0.23.2" tree-sitter-json = "0.24.8" -tree-sitter-make = "1.1.1" -tree-sitter-md = { git = "https://github.com/tree-sitter-grammars/tree-sitter-markdown", tag = "v0.5.0" } -tree-sitter-proto = "0.2.0" -tree-sitter-python = "0.23.6" -tree-sitter-ruby = "0.23.1" -tree-sitter-rust = "0.24.0" -tree-sitter-scala = "0.23.4" -tree-sitter-sequel = "0.3.8" -tree-sitter-swift = "0.7.0" -tree-sitter-toml-ng = "0.7.0" -tree-sitter-typescript = "0.23.2" -tree-sitter-yaml = "0.7.1" -tree-sitter-zig = "1.1.2" +tree-sitter-bash = { version = "0.23.3", optional = true } +tree-sitter-c = { version = "0.24.1", optional = true } +tree-sitter-c-sharp = { version = "0.23.1", optional = true } +tree-sitter-cmake = { version = "0.7.1", optional = true } +tree-sitter-cpp = { version = "0.23.4", optional = true } +tree-sitter-css = { version = "0.23.2", optional = true } +tree-sitter-diff = { version = "0.1.0", optional = true } +tree-sitter-elixir = { version = "0.3", optional = true } +tree-sitter-embedded-template = { version = "0.23.0", optional = true } +tree-sitter-go = { version = "0.23.4", optional = true } +tree-sitter-graphql = { version = "0.1.0", optional = true } +tree-sitter-html = { version = "0.23.2", optional = true } +tree-sitter-java = { version = "0.23.5", optional = true } +tree-sitter-javascript = { version = "0.23.1", optional = true } +tree-sitter-jsdoc = { version = "0.23.2", optional = true } +tree-sitter-make = { version = "1.1.1", optional = true } +tree-sitter-md = { git = "https://github.com/tree-sitter-grammars/tree-sitter-markdown", tag = "v0.5.0", optional = true } +tree-sitter-proto = { version = "0.2.0", optional = true } +tree-sitter-python = { version = "0.23.6", optional = true } +tree-sitter-ruby = { version = "0.23.1", optional = true } +tree-sitter-rust = { version = "0.24.0", optional = true } +tree-sitter-scala = { version = "0.23.4", optional = true } +tree-sitter-sequel = { version = "0.3.8", optional = true } +tree-sitter-swift = { version = "0.7.0", optional = true } +tree-sitter-toml-ng = { version = "0.7.0", optional = true } +tree-sitter-typescript = { version = "0.23.2", optional = true } +tree-sitter-yaml = { version = "0.7.1", optional = true } +tree-sitter-zig = { version = "1.1.2", optional = true } [dev-dependencies] indoc = "2" diff --git a/crates/ui/src/highlighter/languages.rs b/crates/ui/src/highlighter/languages.rs index f44b2686..697c801c 100644 --- a/crates/ui/src/highlighter/languages.rs +++ b/crates/ui/src/highlighter/languages.rs @@ -1,7 +1,17 @@ use gpui::SharedString; +use crate::highlighter::LanguageConfig; + +#[cfg(not(feature = "tree-sitter-languages"))] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, enum_iterator::Sequence)] pub enum Language { + Json, +} + +#[cfg(feature = "tree-sitter-languages")] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, enum_iterator::Sequence)] +pub enum Language { + Json, Plain, Bash, C, @@ -19,7 +29,6 @@ pub enum Language { Java, JavaScript, JsDoc, - Json, Make, Markdown, MarkdownInline, @@ -37,35 +46,6 @@ pub enum Language { Zig, } -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct LanguageConfig { - pub name: SharedString, - pub language: tree_sitter::Language, - pub injection_languages: Vec, - pub highlights: SharedString, - pub injections: SharedString, - pub locals: SharedString, -} - -impl LanguageConfig { - pub fn new( - name: impl Into, - language: tree_sitter::Language, - injection_languages: Vec, - highlights: &str, - injections: &str, - locals: &str, - ) -> Self { - Self { - name: name.into(), - language, - injection_languages, - highlights: SharedString::from(highlights.to_string()), - injections: SharedString::from(injections.to_string()), - locals: SharedString::from(locals.to_string()), - } - } -} impl From for SharedString { fn from(language: Language) -> Self { language.name().into() @@ -78,6 +58,10 @@ impl Language { } pub fn name(&self) -> &'static str { + #[cfg(not(feature = "tree-sitter-languages"))] + return "json"; + + #[cfg(feature = "tree-sitter-languages")] match self { Self::Plain => "text", Self::Bash => "bash", @@ -115,7 +99,12 @@ impl Language { } } + #[allow(unused)] pub fn from_str(s: &str) -> Self { + #[cfg(not(feature = "tree-sitter-languages"))] + return Self::Json; + + #[cfg(feature = "tree-sitter-languages")] match s { "bash" | "sh" => Self::Bash, "c" => Self::C, @@ -155,6 +144,10 @@ impl Language { #[allow(unused)] pub(super) fn injection_languages(&self) -> Vec { + #[cfg(not(feature = "tree-sitter-languages"))] + return vec![]; + + #[cfg(feature = "tree-sitter-languages")] match self { Self::Markdown => vec!["markdown-inline", "html", "toml", "yaml"], Self::MarkdownInline => vec![], @@ -183,6 +176,17 @@ impl Language { /// /// (language, query, injection, locals) pub(super) fn config(&self) -> LanguageConfig { + #[cfg(not(feature = "tree-sitter-languages"))] + let (language, query, injection, locals) = match self { + Self::Json => ( + tree_sitter_json::LANGUAGE, + include_str!("languages/json/highlights.scm"), + "", + "", + ), + }; + + #[cfg(feature = "tree-sitter-languages")] let (language, query, injection, locals) = match self { Self::Plain => (tree_sitter_json::LANGUAGE, "", "", ""), Self::Json => ( diff --git a/crates/ui/src/highlighter/registry.rs b/crates/ui/src/highlighter/registry.rs index 931e7009..08501f8c 100644 --- a/crates/ui/src/highlighter/registry.rs +++ b/crates/ui/src/highlighter/registry.rs @@ -1,10 +1,9 @@ -use gpui::{App, FontWeight, HighlightStyle, Hsla}; +use gpui::{App, FontWeight, HighlightStyle, Hsla, SharedString}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; use std::{collections::HashMap, ops::Deref, sync::LazyLock}; -use super::LanguageConfig; use crate::{ highlighter::{languages, Language}, ActiveTheme, Colorize, ThemeMode, @@ -68,6 +67,36 @@ const DEFAULT_LIGHT: LazyLock = LazyLock::new(|| { serde_json::from_str(json).unwrap() }); +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct LanguageConfig { + pub name: SharedString, + pub language: tree_sitter::Language, + pub injection_languages: Vec, + pub highlights: SharedString, + pub injections: SharedString, + pub locals: SharedString, +} + +impl LanguageConfig { + pub fn new( + name: impl Into, + language: tree_sitter::Language, + injection_languages: Vec, + highlights: &str, + injections: &str, + locals: &str, + ) -> Self { + Self { + name: name.into(), + language, + injection_languages, + highlights: SharedString::from(highlights.to_string()), + injections: SharedString::from(injections.to_string()), + locals: SharedString::from(locals.to_string()), + } + } +} + /// Theme for Tree-sitter Highlight /// /// https://docs.rs/tree-sitter-highlight/0.25.4/tree_sitter_highlight/