mirror of
https://seed.radicle.dev/rad:z6cFWeWpnZNHh9rUW8phgA3b5yGt.git
synced 2026-10-30 16:30:49 +08:00
radicle-surf: remove syntax highlighting
Remove the syntax feature flag and any of the syntax highlighting logic. This is not required any more from the clients implementation and so we minimise this codebase in favour of any downstream dependent to define how they highlight the blob's content. Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com> X-Clacks-Overhead: GNU Terry Pratchett
This commit is contained in:
@@ -20,7 +20,6 @@ test = false
|
||||
doctest = false
|
||||
|
||||
[features]
|
||||
syntax = ["syntect", "lazy_static"]
|
||||
# NOTE: testing `test_submodule_failure` on GH actions
|
||||
# is painful since it uses this specific repo and expects
|
||||
# certain branches to be setup. So we use this feature flag
|
||||
@@ -43,10 +42,6 @@ version = "0.1.0"
|
||||
path = "../git-ref-format"
|
||||
features = ["macro", "serde"]
|
||||
|
||||
[dependencies.lazy_static]
|
||||
version = "1"
|
||||
optional = true
|
||||
|
||||
[dependencies.radicle-git-ext]
|
||||
version = "0.2.0"
|
||||
path = "../radicle-git-ext"
|
||||
@@ -61,10 +56,6 @@ version = "1"
|
||||
features = ["serde_derive"]
|
||||
optional = true
|
||||
|
||||
[dependencies.syntect]
|
||||
version = "5"
|
||||
optional = true
|
||||
|
||||
[build-dependencies]
|
||||
anyhow = "1.0"
|
||||
flate2 = "1"
|
||||
|
||||
@@ -21,8 +21,3 @@ pub use person::Person;
|
||||
|
||||
mod view;
|
||||
pub use view::{view, View};
|
||||
|
||||
#[cfg(feature = "syntax")]
|
||||
pub mod syntax;
|
||||
#[cfg(feature = "syntax")]
|
||||
pub use syntax::SYNTAX_SET;
|
||||
|
||||
@@ -89,12 +89,6 @@ impl Blob {
|
||||
pub fn is_binary(&self) -> bool {
|
||||
matches!(self.content, BlobContent::Binary(_))
|
||||
}
|
||||
|
||||
/// Indicates if the content of the [`Blob`] is HTML.
|
||||
#[must_use]
|
||||
pub const fn is_html(&self) -> bool {
|
||||
matches!(self.content, BlobContent::Html(_))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
@@ -103,10 +97,9 @@ impl Serialize for Blob {
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
const FIELDS: usize = 6;
|
||||
const FIELDS: usize = 5;
|
||||
let mut state = serializer.serialize_struct("Blob", FIELDS)?;
|
||||
state.serialize_field("binary", &self.is_binary())?;
|
||||
state.serialize_field("html", &self.is_html())?;
|
||||
state.serialize_field("content", &self.content)?;
|
||||
state.serialize_field("lastCommit", &self.commit)?;
|
||||
state.serialize_field("name", &self.file.name())?;
|
||||
@@ -120,12 +113,6 @@ impl Serialize for Blob {
|
||||
pub enum BlobContent {
|
||||
/// Content is plain text and can be passed as a string.
|
||||
Plain(String),
|
||||
/// Content is syntax-highlighted HTML.
|
||||
///
|
||||
/// Note that it is necessary to enable the `syntax` feature flag
|
||||
/// for this variant to be constructed. Use `Blob::highlighted`,
|
||||
/// instead of `Blob::new` to get highlighted content.
|
||||
Html(String),
|
||||
/// Content is binary and needs special treatment.
|
||||
Binary(Vec<u8>),
|
||||
}
|
||||
@@ -137,7 +124,7 @@ impl Serialize for BlobContent {
|
||||
S: Serializer,
|
||||
{
|
||||
match self {
|
||||
Self::Plain(content) | Self::Html(content) => serializer.serialize_str(content),
|
||||
Self::Plain(content) => serializer.serialize_str(content),
|
||||
Self::Binary(bytes) => {
|
||||
let encoded = base64::encode(bytes);
|
||||
serializer.serialize_str(&encoded)
|
||||
@@ -155,54 +142,3 @@ impl From<FileContent<'_>> for BlobContent {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "syntax")]
|
||||
pub mod highlighting {
|
||||
use crate::source::syntax;
|
||||
|
||||
use super::*;
|
||||
|
||||
impl Blob {
|
||||
/// Returns the [`Blob`] for a file at `revision` under `path`.
|
||||
///
|
||||
/// The content of the [`Blob`] will be highlighted, if possible.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Will return [`Error`] if the project doesn't exist or a surf
|
||||
/// interaction fails.
|
||||
pub fn highlighted<P, R>(
|
||||
browser: &Repository,
|
||||
revision: &R,
|
||||
path: &P,
|
||||
theme: Option<&str>,
|
||||
) -> Result<Blob, Error>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
R: git::Revision,
|
||||
{
|
||||
Self::make_blob(browser, revision, path, |contents| {
|
||||
content(path, &contents, theme)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a [`BlobContent`] given a file path, content and theme. Attempts
|
||||
/// to perform syntax highlighting when the theme is `Some`.
|
||||
fn content<P>(path: P, content: &FileContent, theme_name: Option<&str>) -> BlobContent
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let content = content.as_bytes();
|
||||
let content = match str::from_utf8(content) {
|
||||
Ok(content) => content,
|
||||
Err(_) => return BlobContent::Binary(content.to_owned()),
|
||||
};
|
||||
|
||||
match theme_name {
|
||||
None => BlobContent::Plain(content.to_owned()),
|
||||
Some(theme) => syntax::highlight(path, content, theme)
|
||||
.map_or_else(|| BlobContent::Plain(content.to_owned()), BlobContent::Html),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
// This file is part of radicle-surf
|
||||
// <https://github.com/radicle-dev/radicle-surf>
|
||||
//
|
||||
// Copyright (C) 2019-2020 The Radicle Team <dev@radicle.xyz>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 3 or
|
||||
// later as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use syntect::{
|
||||
easy::HighlightLines,
|
||||
highlighting::ThemeSet,
|
||||
parsing::SyntaxSet,
|
||||
util::LinesWithEndings,
|
||||
};
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
// The syntax set is slow to load (~30ms), so we make sure to only load it once.
|
||||
// It _will_ affect the latency of the first request that uses syntax highlighting,
|
||||
// but this is acceptable for now.
|
||||
pub static ref SYNTAX_SET: SyntaxSet = {
|
||||
let default_set = SyntaxSet::load_defaults_newlines();
|
||||
let mut builder = default_set.into_builder();
|
||||
|
||||
if cfg!(debug_assertions) {
|
||||
// In development assets are relative to the proxy source.
|
||||
// Don't crash if we aren't able to load additional syntaxes for some reason.
|
||||
builder.add_from_folder("./assets", true).ok();
|
||||
} else {
|
||||
// In production assets are relative to the proxy executable.
|
||||
let exe_path = std::env::current_exe().expect("Can't get current exe path");
|
||||
let root_path = exe_path
|
||||
.parent()
|
||||
.expect("Could not get parent path of current executable");
|
||||
let mut tmp = root_path.to_path_buf();
|
||||
tmp.push("assets");
|
||||
let asset_path = tmp.to_str().expect("Couldn't convert pathbuf to str");
|
||||
|
||||
// Don't crash if we aren't able to load additional syntaxes for some reason.
|
||||
match builder.add_from_folder(asset_path, true) {
|
||||
Ok(_) => (),
|
||||
Err(err) => log::warn!("Syntax builder error : {}", err),
|
||||
};
|
||||
}
|
||||
builder.build()
|
||||
};
|
||||
}
|
||||
|
||||
/// Return highlighted text given a file path, the original text, and
|
||||
/// a theme.
|
||||
pub fn highlight<P>(path: P, content: &str, theme_name: &str) -> Option<String>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let syntax = path
|
||||
.as_ref()
|
||||
.extension()
|
||||
.and_then(std::ffi::OsStr::to_str)
|
||||
.and_then(|ext| SYNTAX_SET.find_syntax_by_extension(ext));
|
||||
|
||||
let ts = ThemeSet::load_defaults();
|
||||
let theme = ts.themes.get(theme_name);
|
||||
|
||||
match (syntax, theme) {
|
||||
(Some(syntax), Some(theme)) => {
|
||||
let mut highlighter = HighlightLines::new(syntax, theme);
|
||||
let mut html = String::with_capacity(content.len());
|
||||
|
||||
for line in LinesWithEndings::from(content) {
|
||||
let regions = highlighter.highlight_line(line, &SYNTAX_SET).ok()?;
|
||||
syntect::html::append_highlighted_html_for_styled_line(
|
||||
®ions[..],
|
||||
syntect::html::IncludeBackground::No,
|
||||
&mut html,
|
||||
)
|
||||
.ok();
|
||||
}
|
||||
Some(html)
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ path = "../../radicle-git-ext"
|
||||
|
||||
[dev-dependencies.radicle-surf]
|
||||
path = ".."
|
||||
features = ["serde", "syntax"]
|
||||
features = ["serde"]
|
||||
|
||||
[dev-dependencies.test-helpers]
|
||||
path = "../../test/test-helpers"
|
||||
|
||||
Reference in New Issue
Block a user