diff --git a/generator/src/components/editor/code.rs b/generator/src/components/editor/code.rs index ea1ca9a..40f8c06 100644 --- a/generator/src/components/editor/code.rs +++ b/generator/src/components/editor/code.rs @@ -44,7 +44,7 @@ impl Component for Code { let highlight = Highlight::new( self.value.clone(), params.code_font_family.clone(), - params.language.clone(), + params.code_file_path.clone(), params.extension.clone(), ); let highlight_result = highlight.parse(¶ms.themes_folder, ¶ms.theme)?; diff --git a/generator/src/components/interface/render_error.rs b/generator/src/components/interface/render_error.rs index 28b4420..5aa0e2f 100644 --- a/generator/src/components/interface/render_error.rs +++ b/generator/src/components/interface/render_error.rs @@ -16,6 +16,9 @@ pub enum RenderError { #[error("Invalid hex color {0}")] InvalidHexColor(String), + + #[error("No such file {0}")] + NoSuchFile(String), } impl From for nvim_oxi::Error { diff --git a/generator/src/config.rs b/generator/src/config.rs index 82c0048..c1e955a 100644 --- a/generator/src/config.rs +++ b/generator/src/config.rs @@ -5,13 +5,16 @@ use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Clone)] pub struct TakeSnapshotParams { + // Whether to display the MacOS style title bar pub mac_window_bar: bool, + // Wartermark of the code snapshot pub watermark: String, + // Editor title pub title: Option, pub code_font_family: String, pub watermark_font_family: String, pub code: String, - pub language: Option, + pub code_file_path: String, pub extension: Option, pub save_path: Option, pub themes_folder: String, @@ -19,6 +22,7 @@ pub struct TakeSnapshotParams { pub theme: String, pub bg_theme: String, pub bg_color: Option, + // Breadcrumbs path pub file_path: String, pub breadcrumbs_separator: String, pub has_breadcrumbs: bool, diff --git a/generator/src/highlight.rs b/generator/src/highlight.rs index 935cd89..88c3e00 100644 --- a/generator/src/highlight.rs +++ b/generator/src/highlight.rs @@ -2,6 +2,7 @@ use cosmic_text::{Attrs, Family, Style, Weight}; use syntect::{ easy::HighlightLines, highlighting::{FontStyle, ThemeSet}, + parsing::{SyntaxReference, SyntaxSet}, util::LinesWithEndings, }; @@ -9,7 +10,7 @@ use crate::components::interface::render_error::RenderError; pub struct Highlight { content: String, - language: Option, + code_file_path: String, extension: Option, font_family: String, } @@ -20,17 +21,35 @@ impl Highlight { pub fn new( content: String, font_family: String, - language: Option, + code_file_path: String, extension: Option, ) -> Highlight { Highlight { content, - language, + code_file_path, extension, font_family, } } + fn guess_syntax(&self, syntax_set: &SyntaxSet) -> Result { + // 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( &self, theme_folder: &str, @@ -39,19 +58,7 @@ impl Highlight { let syntax_set = two_face::syntax::extra_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 syntax = &self.guess_syntax(&syntax_set)?; let mut highlight = HighlightLines::new(syntax, &theme_set.themes[theme]); let attrs = Attrs::new().family(Family::Name(self.font_family.as_ref())); diff --git a/lua/codesnap/config.lua b/lua/codesnap/config.lua index 7c9dd6b..0d7cded 100644 --- a/lua/codesnap/config.lua +++ b/lua/codesnap/config.lua @@ -7,31 +7,6 @@ local config_module = {} 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: -- CodeSnap_y-m-d_at_h:m:s 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() end -function config_module.get_config(specify_extension) +function config_module.get_config(extension) local code = visual_utils.get_selected_text() - local extension = specify_extension or parse_extension(specify_extension) if string_utils.is_str_empty(code) then error("No code is selected", 0) return end - if string_utils.is_str_empty(extension) then - error("Cannot detect current filetype", 0) - end - local config = table_utils.merge({ code = code, extension = extension, + code_file_path = vim.fn.expand("%:p"), fonts_folder = assets_folder .. "/fonts", themes_folder = assets_folder .. "/themes", theme = "base16-onedark",