DiffViewer: prose files (Markdown, plain text) read plain, not as code
This commit is contained in:
2 files changed
+45
-6
No files matched your search
+39
-3
@@ -78,10 +78,29 @@ pub(super) fn washes(kind: LineKind, colors: &Palette) -> (Option<Hsla>, Hsla) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A line's code, colored as code, its changed words washed.
|
/// Extensions of prose and plain text.
|
||||||
pub(super) fn code(line: &DiffLine, colors: &Palette, cx: &App) -> StyledText {
|
const PROSE: [&str; 13] = [
|
||||||
|
"md", "markdown", "mdown", "mkd", "txt", "text", "rst", "adoc", "asciidoc", "org", "csv",
|
||||||
|
"tsv", "log",
|
||||||
|
];
|
||||||
|
|
||||||
|
/// Whether `path` holds prose, read plain rather than as code.
|
||||||
|
pub(super) fn prose(path: &str) -> bool {
|
||||||
|
let name = path.rsplit_once('/').map_or(path, |(_, name)| name);
|
||||||
|
match name.rsplit_once('.') {
|
||||||
|
Some((stem, ext)) if !stem.is_empty() => PROSE.contains(&ext.to_ascii_lowercase().as_str()),
|
||||||
|
_ => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A line's text, colored as code unless prose, changed words washed.
|
||||||
|
pub(super) fn code(line: &DiffLine, colors: &Palette, prose: bool, cx: &App) -> StyledText {
|
||||||
let (_, word) = washes(line.kind, colors);
|
let (_, word) = washes(line.kind, colors);
|
||||||
let mut styles: Vec<(Range<usize>, HighlightStyle)> = code_colors(&line.text, cx);
|
let mut styles: Vec<(Range<usize>, HighlightStyle)> = if prose {
|
||||||
|
Vec::new()
|
||||||
|
} else {
|
||||||
|
code_colors(&line.text, cx)
|
||||||
|
};
|
||||||
styles.extend(line.words.iter().map(|range| {
|
styles.extend(line.words.iter().map(|range| {
|
||||||
(
|
(
|
||||||
range.clone(),
|
range.clone(),
|
||||||
@@ -108,6 +127,23 @@ pub(super) fn spoken(line: &DiffLine) -> SharedString {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
#[test]
|
||||||
|
fn prose_reads_plain_and_code_reads_as_code() {
|
||||||
|
for path in [
|
||||||
|
"docs/README.md",
|
||||||
|
"notes.MARKDOWN",
|
||||||
|
"LICENSE",
|
||||||
|
".gitignore",
|
||||||
|
"a/b.txt",
|
||||||
|
"data.csv",
|
||||||
|
] {
|
||||||
|
assert!(super::prose(path), "{path}");
|
||||||
|
}
|
||||||
|
for path in ["src/main.rs", "web/app.js", "a.md/b.py", "Cargo.toml"] {
|
||||||
|
assert!(!super::prose(path), "{path}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn a_line_speaks_its_number_change_and_text() {
|
fn a_line_speaks_its_number_change_and_text() {
|
||||||
let stretches = super::super::diff::diff("a\nb\n", "a\nc\n", 1);
|
let stretches = super::super::diff::diff("a\nb\n", "a\nc\n", 1);
|
||||||
|
|||||||
+6
-3
@@ -9,7 +9,7 @@ use gpui::{
|
|||||||
use super::{
|
use super::{
|
||||||
badges::DiffStat,
|
badges::DiffStat,
|
||||||
diff::{DiffLine, LineKind, Stretch, diff, side_numbers},
|
diff::{DiffLine, LineKind, Stretch, diff, side_numbers},
|
||||||
rows::{Place, Shown, code, shown, spoken, washes},
|
rows::{Place, Shown, code, prose, shown, spoken, washes},
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
buttons::{Button, ButtonVariant, SegmentedControl},
|
buttons::{Button, ButtonVariant, SegmentedControl},
|
||||||
@@ -194,6 +194,7 @@ impl RenderOnce for DiffViewer {
|
|||||||
.len()
|
.len()
|
||||||
.max(2);
|
.max(2);
|
||||||
let (id, on_open) = (self.id.clone(), self.on_open.clone());
|
let (id, on_open) = (self.id.clone(), self.on_open.clone());
|
||||||
|
let prose = prose(&self.path);
|
||||||
let (button, button_height) = (
|
let (button, button_height) = (
|
||||||
self.hunk_action.is_some(),
|
self.hunk_action.is_some(),
|
||||||
theme.control_height(ControlSize::Sm),
|
theme.control_height(ControlSize::Sm),
|
||||||
@@ -269,7 +270,9 @@ impl RenderOnce for DiffViewer {
|
|||||||
.when_some(wash, |side, wash| side.bg(wash))
|
.when_some(wash, |side, wash| side.bg(wash))
|
||||||
.child(number(shown))
|
.child(number(shown))
|
||||||
.children(line.map(|(_, line)| {
|
.children(line.map(|(_, line)| {
|
||||||
div().whitespace_nowrap().child(code(line, &colors, cx))
|
div()
|
||||||
|
.whitespace_nowrap()
|
||||||
|
.child(code(line, &colors, prose, cx))
|
||||||
}));
|
}));
|
||||||
match line {
|
match line {
|
||||||
Some((place, line)) => {
|
Some((place, line)) => {
|
||||||
@@ -328,7 +331,7 @@ impl RenderOnce for DiffViewer {
|
|||||||
.flex_1()
|
.flex_1()
|
||||||
.min_w_0()
|
.min_w_0()
|
||||||
.overflow_hidden()
|
.overflow_hidden()
|
||||||
.child(code(line, &colors, cx)),
|
.child(code(line, &colors, prose, cx)),
|
||||||
)
|
)
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user