feat: add markdown view component

This commit is contained in:
2026-11-06 17:04:56 +07:00
parent e8e1cb39e0
commit 310cad32be
9 changed files with 1957 additions and 13 deletions
+3
View File
@@ -8,6 +8,9 @@ pub mod code_view;
#[cfg(feature = "diff_view")]
pub mod diff_view;
#[cfg(feature = "markdown_view")]
pub mod markdown;
pub mod highlight;
mod utils;
File diff suppressed because it is too large Load Diff
+42 -3
View File
@@ -1,9 +1,11 @@
//! Shared helpers for the editor's views: gutter cells, role colors, change
//! washes and diff row building.
//! Shared helpers for the editor's views: gutter cells, role colors, code
//! line text, language mapping, change washes and diff row building.
#[cfg(feature = "diff_view")]
#[cfg(any(feature = "diff_view", feature = "markdown_view"))]
use std::ops::Range;
#[cfg(feature = "markdown_view")]
use gpui::StyledText;
use gpui::{App, HighlightStyle, Hsla, IntoElement, ParentElement as _, Styled as _, div};
use gpui_native_theme::{ActiveTheme as _, ColorTokens, Ramps};
#[cfg(feature = "diff_view")]
@@ -14,6 +16,8 @@ use crate::diff_view::{DiffRow, DiffRowKind};
#[cfg(feature = "diff_view")]
use crate::highlight::HighlightedCode;
use crate::highlight::Role;
#[cfg(feature = "markdown_view")]
use crate::highlight::{Language, Line};
/// Maps a highlight role to the theme's semantic palette.
pub(crate) fn role_color(role: Role, colors: ColorTokens, ramps: Ramps) -> Hsla {
@@ -136,3 +140,38 @@ pub(crate) fn wash_gutter(colors: &ColorTokens) -> Hsla {
..colors.muted
}
}
/// One highlighted code line as styled text, roles resolved from the theme.
#[cfg(feature = "markdown_view")]
pub(crate) fn code_line(line: &Line, colors: ColorTokens, ramps: Ramps) -> StyledText {
let mut text = String::new();
let mut highlights: Vec<(Range<usize>, HighlightStyle)> = Vec::new();
for span in &line.spans {
let start = text.len();
text.push_str(&span.text);
if span.role != Role::Text {
highlights.push((
start..text.len(),
HighlightStyle {
color: Some(role_color(span.role, colors, ramps)),
..Default::default()
},
));
}
}
StyledText::new(text).with_highlights(highlights)
}
/// Maps a fence info string to a bundled grammar.
#[cfg(feature = "markdown_view")]
pub(crate) fn grammar_language(info: &str) -> Option<Language> {
match info.to_ascii_lowercase().as_str() {
"rust" | "rs" => Some(Language::Rust),
"typescript" | "ts" => Some(Language::TypeScript),
"javascript" | "js" => Some(Language::JavaScript),
"python" | "py" => Some(Language::Python),
_ => None,
}
}