mirror of
https://seed.radicle.dev/rad:z6cFWeWpnZNHh9rUW8phgA3b5yGt.git
synced 2026-10-30 16:30:49 +08:00
Initially, radicle-source was envisioned to be another layer on top of radicle-surf, however, it ended up duplicating a lot of concepts. We consolidate them by merging radicle-source into radicle-surf. This meant removing modules branch.rs, tag.rs, oid.rs and error.rs.
88 lines
3.4 KiB
Rust
88 lines
3.4 KiB
Rust
// 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;
|
|
|
|
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 a [`BlobContent`] given a file path, content and theme. Attempts to
|
|
/// perform syntax highlighting when the theme is `Some`.
|
|
pub fn highlight(path: &str, content: &str, theme_name: &str) -> Option<String> {
|
|
let syntax = path::Path::new(path)
|
|
.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, &SYNTAX_SET);
|
|
syntect::html::append_highlighted_html_for_styled_line(
|
|
®ions[..],
|
|
syntect::html::IncludeBackground::No,
|
|
&mut html,
|
|
);
|
|
}
|
|
Some(html)
|
|
},
|
|
_ => None,
|
|
}
|
|
}
|