codesnap.nvim/generator/src/highlight.rs
Mist 08f0b24cf4
[Release] v1.0.0 (#43)
* [Update] apply template

* [Feat] update assets files (#35)

* [Update] README add packer install config

* [Feat] take snapshot via skia engine

* [Feat] title component

* [Feat] add watermark

* [Feat] update padding of code panel

* [Remove] pack ci script

* [Release] v1.0.0

* [Update] apply template

* [Chore] remove unused code

* [Update] readme

* [Release] v1.0.1

* [Update] apply template

* [Update] readme

* Update README.md

* [Feat] compile nvim-0.9 FFI

* [Release] v1.0.2

* [Update] apply template

* [Update] README.md

* [Feat] add multi platform support

* [Feat] add workflow for build target binary package

* [Update] files based on generated files by template generator

* [Update] files based on generated files by template generator

* [Update] files based on generated files by template generator

* [Update] files based on generated files by template generator

* [Update] files based on generated files by template generator

* [Update] files based on generated files by template generator

* [Update] files based on generated files by template generator

* [Feat] build plugin after released

* [Delete] build.yml

* [Update] README

* [Release] v1.0.3

* [Update] README

* [Refactor] editor frame size calculation logic

* [Refactor] update margin of watermark

* [Feat] preset font family

* [Refactor] update component interface

* [Update] change theme to onedark

* [Refactor] redefine render_error and throw it to lua scope

* [Perf] build script

* [Refactor] abstract component concept & implement it for all widgets

* [Update] README.md

---------

Co-authored-by: mistricky <mistricky@users.noreply.github.com>
2024-03-17 01:07:12 +08:00

76 lines
2.5 KiB
Rust

use cosmic_text::{Attrs, Family, Style, Weight};
use syntect::{
easy::HighlightLines,
highlighting::{FontStyle, ThemeSet},
parsing::SyntaxSet,
util::LinesWithEndings,
};
use crate::components::interface::render_error::RenderError;
pub struct Highlight {
content: String,
language: Option<String>,
extension: Option<String>,
font_family: String,
}
pub type HighlightResult<'a> = Vec<(&'a str, Attrs<'a>)>;
impl Highlight {
pub fn new(
content: String,
font_family: String,
language: Option<String>,
extension: Option<String>,
) -> Highlight {
Highlight {
content,
language,
extension,
font_family,
}
}
pub fn parse(
&self,
theme_folder: &str,
theme: &str,
) -> Result<Vec<(&str, Attrs)>, RenderError> {
let syntax_set = SyntaxSet::load_defaults_newlines();
let theme_set = ThemeSet::load_from_folder(theme_folder)
.map_err(|_| RenderError::HighlightThemeLoadFailed)?;
let syntax = match &self.extension {
Some(extension) => syntax_set
.find_syntax_by_extension(extension)
.ok_or(RenderError::HighlightCodeFailed(extension.to_owned())),
None => {
let language = &self.language.clone().unwrap_or("Rust".to_string());
syntax_set
.find_syntax_by_name(language)
.ok_or(RenderError::HighlightCodeFailed(language.to_owned()))
}
}?;
let mut highlight = HighlightLines::new(syntax, &theme_set.themes[theme]);
let attrs = Attrs::new().family(Family::Name(self.font_family.as_ref()));
Ok(LinesWithEndings::from(&self.content)
.map(|line| highlight.highlight_line(line, &syntax_set).unwrap())
.fold(vec![], |acc, cur| [acc, cur].concat())
.into_iter()
.map(move |(style, str)| {
let syntect::highlighting::Color { r, g, b, a: _ } = style.foreground;
let attrs = match style.font_style {
FontStyle::BOLD => attrs.weight(Weight::BOLD),
FontStyle::ITALIC => attrs.style(Style::Italic),
FontStyle::UNDERLINE => attrs.style(Style::Normal),
_ => attrs,
};
(str, attrs.color(cosmic_text::Color::rgb(r, g, b)))
})
.collect::<HighlightResult>())
}
}