[Refactor] change the detect filetype strategy (#78)

This commit is contained in:
The Mist 2024-04-07 17:24:43 +08:00 committed by GitHub
parent 69ecdace3b
commit 72d6a69ace
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 34 additions and 49 deletions

View file

@ -44,7 +44,7 @@ impl Component for Code {
let highlight = Highlight::new( let highlight = Highlight::new(
self.value.clone(), self.value.clone(),
params.code_font_family.clone(), params.code_font_family.clone(),
params.language.clone(), params.code_file_path.clone(),
params.extension.clone(), params.extension.clone(),
); );
let highlight_result = highlight.parse(&params.themes_folder, &params.theme)?; let highlight_result = highlight.parse(&params.themes_folder, &params.theme)?;

View file

@ -16,6 +16,9 @@ pub enum RenderError {
#[error("Invalid hex color {0}")] #[error("Invalid hex color {0}")]
InvalidHexColor(String), InvalidHexColor(String),
#[error("No such file {0}")]
NoSuchFile(String),
} }
impl From<RenderError> for nvim_oxi::Error { impl From<RenderError> for nvim_oxi::Error {

View file

@ -5,13 +5,16 @@ use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Clone)] #[derive(Serialize, Deserialize, Clone)]
pub struct TakeSnapshotParams { pub struct TakeSnapshotParams {
// Whether to display the MacOS style title bar
pub mac_window_bar: bool, pub mac_window_bar: bool,
// Wartermark of the code snapshot
pub watermark: String, pub watermark: String,
// Editor title
pub title: Option<String>, pub title: Option<String>,
pub code_font_family: String, pub code_font_family: String,
pub watermark_font_family: String, pub watermark_font_family: String,
pub code: String, pub code: String,
pub language: Option<String>, pub code_file_path: String,
pub extension: Option<String>, pub extension: Option<String>,
pub save_path: Option<String>, pub save_path: Option<String>,
pub themes_folder: String, pub themes_folder: String,
@ -19,6 +22,7 @@ pub struct TakeSnapshotParams {
pub theme: String, pub theme: String,
pub bg_theme: String, pub bg_theme: String,
pub bg_color: Option<String>, pub bg_color: Option<String>,
// Breadcrumbs path
pub file_path: String, pub file_path: String,
pub breadcrumbs_separator: String, pub breadcrumbs_separator: String,
pub has_breadcrumbs: bool, pub has_breadcrumbs: bool,

View file

@ -2,6 +2,7 @@ use cosmic_text::{Attrs, Family, Style, Weight};
use syntect::{ use syntect::{
easy::HighlightLines, easy::HighlightLines,
highlighting::{FontStyle, ThemeSet}, highlighting::{FontStyle, ThemeSet},
parsing::{SyntaxReference, SyntaxSet},
util::LinesWithEndings, util::LinesWithEndings,
}; };
@ -9,7 +10,7 @@ use crate::components::interface::render_error::RenderError;
pub struct Highlight { pub struct Highlight {
content: String, content: String,
language: Option<String>, code_file_path: String,
extension: Option<String>, extension: Option<String>,
font_family: String, font_family: String,
} }
@ -20,17 +21,35 @@ impl Highlight {
pub fn new( pub fn new(
content: String, content: String,
font_family: String, font_family: String,
language: Option<String>, code_file_path: String,
extension: Option<String>, extension: Option<String>,
) -> Highlight { ) -> Highlight {
Highlight { Highlight {
content, content,
language, code_file_path,
extension, extension,
font_family, font_family,
} }
} }
fn guess_syntax(&self, syntax_set: &SyntaxSet) -> Result<SyntaxReference, RenderError> {
// The extension exist only when users specified explicitly
// By default, using filepath to detect what syntax should use
let syntax = match &self.extension {
Some(extension) => syntax_set
.find_syntax_by_extension(&extension)
.ok_or(RenderError::HighlightCodeFailed(extension.to_string()))?,
None => syntax_set
.find_syntax_for_file(&self.code_file_path)
.map_err(|_| RenderError::NoSuchFile(self.code_file_path.to_string()))?
.ok_or(RenderError::HighlightCodeFailed(
self.code_file_path.to_string(),
))?,
};
Ok(syntax.to_owned())
}
pub fn parse( pub fn parse(
&self, &self,
theme_folder: &str, theme_folder: &str,
@ -39,19 +58,7 @@ impl Highlight {
let syntax_set = two_face::syntax::extra_newlines(); let syntax_set = two_face::syntax::extra_newlines();
let theme_set = ThemeSet::load_from_folder(theme_folder) let theme_set = ThemeSet::load_from_folder(theme_folder)
.map_err(|_| RenderError::HighlightThemeLoadFailed)?; .map_err(|_| RenderError::HighlightThemeLoadFailed)?;
let syntax = match &self.extension { let syntax = &self.guess_syntax(&syntax_set)?;
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 mut highlight = HighlightLines::new(syntax, &theme_set.themes[theme]);
let attrs = Attrs::new().family(Family::Name(self.font_family.as_ref())); let attrs = Attrs::new().family(Family::Name(self.font_family.as_ref()));

View file

@ -7,31 +7,6 @@ local config_module = {}
local assets_folder = static.cwd .. "/assets" local assets_folder = static.cwd .. "/assets"
-- Get extension of cureent file
local function get_file_info()
local file_path = vim.fn.expand("%:p")
local filename, extension = string.match(file_path, "([^\\/%.]+)%.?([^\\/%.]*)$")
return string_utils.convert_empty_to_nil(filename), string_utils.convert_empty_to_nil(extension)
end
-- Some files have no extension, but they still need to highlighting correctly,
-- in this case, use filename instead of extension to highlighting code
-- e.g. Dockerfile, Pipefile
local function parse_file_extension_by_highlighting_file_presets(filename, extension)
local lowercase_filename = string.lower(filename)
return extension or lowercase_filename
end
local function parse_extension(specify_extension)
local filename, file_extension = get_file_info()
return specify_extension
or file_extension
or parse_file_extension_by_highlighting_file_presets(filename, file_extension)
end
-- Auto generated codesnap filename based on the following rule: -- Auto generated codesnap filename based on the following rule:
-- CodeSnap_y-m-d_at_h:m:s -- CodeSnap_y-m-d_at_h:m:s
local function auto_generate_snap_filename() local function auto_generate_snap_filename()
@ -50,22 +25,18 @@ local function parse_save_path(save_path)
return parsed_save_path .. auto_generate_snap_filename() return parsed_save_path .. auto_generate_snap_filename()
end end
function config_module.get_config(specify_extension) function config_module.get_config(extension)
local code = visual_utils.get_selected_text() local code = visual_utils.get_selected_text()
local extension = specify_extension or parse_extension(specify_extension)
if string_utils.is_str_empty(code) then if string_utils.is_str_empty(code) then
error("No code is selected", 0) error("No code is selected", 0)
return return
end end
if string_utils.is_str_empty(extension) then
error("Cannot detect current filetype", 0)
end
local config = table_utils.merge({ local config = table_utils.merge({
code = code, code = code,
extension = extension, extension = extension,
code_file_path = vim.fn.expand("%:p"),
fonts_folder = assets_folder .. "/fonts", fonts_folder = assets_folder .. "/fonts",
themes_folder = assets_folder .. "/themes", themes_folder = assets_folder .. "/themes",
theme = "base16-onedark", theme = "base16-onedark",