From 3b7dd6a3ad6a1914cfa711316be89b4c7b12fd25 Mon Sep 17 00:00:00 2001 From: The Mist Date: Fri, 26 Apr 2024 01:01:17 +0800 Subject: [PATCH] [Feat] support line number & remove unused module (#91) --- generator/src/code.rs | 1 + generator/src/components.rs | 2 + generator/src/components/code_block.rs | 29 ++++++++ generator/src/components/editor/code.rs | 12 +-- generator/src/components/line_number.rs | 99 +++++++++++++++++++++++++ generator/src/config.rs | 1 + generator/src/snapshot.rs | 7 +- lua/codesnap/client.lua | 61 --------------- lua/codesnap/config.lua | 2 + lua/codesnap/init.lua | 1 + lua/codesnap/static.lua | 1 + lua/codesnap/utils/logger.lua | 11 --- lua/codesnap/utils/visual.lua | 5 +- 13 files changed, 149 insertions(+), 83 deletions(-) create mode 100644 generator/src/components/code_block.rs create mode 100644 generator/src/components/line_number.rs delete mode 100644 lua/codesnap/client.lua delete mode 100644 lua/codesnap/utils/logger.lua diff --git a/generator/src/code.rs b/generator/src/code.rs index da95bee..2b0849a 100644 --- a/generator/src/code.rs +++ b/generator/src/code.rs @@ -2,6 +2,7 @@ use cached::proc_macro::cached; use regex::Regex; const MIN_WIDTH: f32 = 100.; +pub const CHAR_WIDTH: f32 = 9.05; fn min_width(width: f32) -> f32 { if width < MIN_WIDTH { diff --git a/generator/src/components.rs b/generator/src/components.rs index c14e6db..530c222 100644 --- a/generator/src/components.rs +++ b/generator/src/components.rs @@ -1,7 +1,9 @@ pub mod background; pub mod breadcrumbs; +pub mod code_block; pub mod container; pub mod editor; pub mod interface; +pub mod line_number; pub mod rect; pub mod watermark; diff --git a/generator/src/components/code_block.rs b/generator/src/components/code_block.rs new file mode 100644 index 0000000..d103ba8 --- /dev/null +++ b/generator/src/components/code_block.rs @@ -0,0 +1,29 @@ +use crate::edges::margin::Margin; + +use super::interface::{ + component::Component, + style::{RawComponentStyle, Style}, +}; + +pub struct CodeBlock { + children: Vec>, +} + +impl Component for CodeBlock { + fn children(&self) -> &Vec> { + &self.children + } + + fn style(&self) -> RawComponentStyle { + Style::default().margin(Margin { + top: 10., + ..Margin::default() + }) + } +} + +impl CodeBlock { + pub fn from_children(children: Vec>) -> CodeBlock { + CodeBlock { children } + } +} diff --git a/generator/src/components/editor/code.rs b/generator/src/components/editor/code.rs index 40f8c06..c875e4a 100644 --- a/generator/src/components/editor/code.rs +++ b/generator/src/components/editor/code.rs @@ -1,11 +1,10 @@ use crate::{ - code::{calc_wh, prepare_code}, + code::{calc_wh, prepare_code, CHAR_WIDTH}, components::interface::{ component::{Component, ComponentContext, RenderParams}, render_error, style::{ComponentStyle, RawComponentStyle, Size, Style}, }, - edges::margin::Margin, highlight::Highlight, text::FontRenderer, }; @@ -23,14 +22,9 @@ impl Component for Code { } fn style(&self) -> RawComponentStyle { - let (w, h) = calc_wh(&self.value, 9.05, self.line_height); + let (w, h) = calc_wh(&self.value, CHAR_WIDTH, self.line_height); - Style::default() - .size(Size::Num(w), Size::Num(h)) - .margin(Margin { - top: 10., - ..Margin::default() - }) + Style::default().size(Size::Num(w), Size::Num(h)) } fn draw_self( diff --git a/generator/src/components/line_number.rs b/generator/src/components/line_number.rs new file mode 100644 index 0000000..5412dac --- /dev/null +++ b/generator/src/components/line_number.rs @@ -0,0 +1,99 @@ +use super::interface::{ + component::{Component, ComponentContext, RenderParams}, + render_error, + style::{ComponentStyle, RawComponentStyle, Size, Style}, +}; +use crate::{code::CHAR_WIDTH, edges::margin::Margin, text::FontRenderer}; +use cosmic_text::{Attrs, Color, Family}; + +const FONT_SIZE: f32 = 14.; + +#[derive(Default)] +pub struct LineNumber { + children: Vec>, + line_height: f32, + render_condition: bool, + line_number_content: Vec, + number_of_digit: usize, +} + +impl Component for LineNumber { + fn render_condition(&self) -> bool { + return self.render_condition; + } + + fn children(&self) -> &Vec> { + &self.children + } + + fn style(&self) -> RawComponentStyle { + Style::default() + .size( + Size::Num(CHAR_WIDTH * self.number_of_digit as f32), + Size::Num(self.line_number_content.len() as f32 * self.line_height), + ) + .margin(Margin { + right: 10., + ..Margin::default() + }) + } + + fn draw_self( + &self, + pixmap: &mut tiny_skia::Pixmap, + context: &ComponentContext, + render_params: &RenderParams, + style: &ComponentStyle, + ) -> render_error::Result<()> { + FontRenderer::new( + FONT_SIZE, + self.line_height, + context.scale_factor, + &context.take_snapshot_params.fonts_folder, + ) + .draw_text( + render_params.x, + render_params.y, + style.width, + style.height, + vec![( + &self.line_number_content.join("\n"), + Attrs::new() + .color(Color::rgb(73, 81, 98)) + .family(Family::Name(&context.take_snapshot_params.code_font_family)), + )], + pixmap, + ); + + Ok(()) + } +} + +impl LineNumber { + pub fn new(content: &str, start_line_number: Option, line_height: f32) -> LineNumber { + match start_line_number { + None => LineNumber::default(), + Some(start_line_number) => { + let lines = content.split("\n").collect::>(); + let max_line_number = lines.len() + start_line_number; + let number_of_digit = (max_line_number - 1).to_string().len(); + + LineNumber { + line_number_content: (start_line_number..max_line_number) + .map(|line_number| { + format!( + "{:>width$}", + line_number.to_string(), + width = number_of_digit + ) + }) + .collect::>(), + number_of_digit, + children: vec![], + render_condition: true, + line_height, + } + } + } + } +} diff --git a/generator/src/config.rs b/generator/src/config.rs index c1e955a..4bc84dd 100644 --- a/generator/src/config.rs +++ b/generator/src/config.rs @@ -26,6 +26,7 @@ pub struct TakeSnapshotParams { pub file_path: String, pub breadcrumbs_separator: String, pub has_breadcrumbs: bool, + pub start_line_number: Option, } impl FromObject for TakeSnapshotParams { diff --git a/generator/src/snapshot.rs b/generator/src/snapshot.rs index daeb410..1b608a6 100644 --- a/generator/src/snapshot.rs +++ b/generator/src/snapshot.rs @@ -4,11 +4,13 @@ use tiny_skia::Pixmap; use crate::components::background::Background; use crate::components::breadcrumbs::Breadcrumbs; +use crate::components::code_block::CodeBlock; use crate::components::container::Container; use crate::components::editor::code::Code; use crate::components::editor::mac_title_bar::MacTitleBar; use crate::components::interface::component::ComponentContext; use crate::components::interface::render_error; +use crate::components::line_number::LineNumber; use crate::components::rect::Rect; use crate::components::watermark::Watermark; use crate::config::TakeSnapshotParams; @@ -33,7 +35,10 @@ pub fn take_snapshot(params: TakeSnapshotParams) -> render_error::Result params.breadcrumbs_separator, params.has_breadcrumbs, )), - Box::new(Code::new(params.code, 20., 15.)), + Box::new(CodeBlock::from_children(vec![ + Box::new(LineNumber::new(¶ms.code, params.start_line_number, 20.)), + Box::new(Code::new(params.code, 20., 15.)), + ])), ], )), Box::new(Watermark::new(params.watermark)), diff --git a/lua/codesnap/client.lua b/lua/codesnap/client.lua deleted file mode 100644 index c0ec413..0000000 --- a/lua/codesnap/client.lua +++ /dev/null @@ -1,61 +0,0 @@ -local logger = require("codesnap.utils.logger") -local static = require("codesnap.static") - -local client = { - job_id = 0, -} - -local cwd = static.cwd .. "/snap-server" - -function client:connect() - return vim.fn.jobstart({ - cwd .. "/target/release/snap-server", - }, { - cwd = cwd, - stderr_buffered = true, - rpc = true, - on_stderr = function(_, err) - vim.fn.jobstop(self.job_id) - logger.error(err) - end, - on_exit = function() - vim.fn.chanclose(self.job_id) - self.job_id = 0 - end, - }) -end - -function client:init() - return self.job_id == 0 and client:connect() or self.job_id -end - -function client:start() - self.job_id = client:init() - - if self.job_id == 0 then - logger.error("cannot start rpc process") - return - end - - if self.job_id == -1 then - logger.error("rpc process is not executable") - vim.fn.jobstop(self.job_id) - return - end - - return self -end - -function client:send(event, message) - vim.fn.rpcnotify(self.job_id, event, message) -end - -function client:stop() - if self.job_id == 0 or self.job_id == -1 then - return - end - - vim.fn.jobstop(self.job_id) -end - -return client diff --git a/lua/codesnap/config.lua b/lua/codesnap/config.lua index 0d7cded..d2ba1b8 100644 --- a/lua/codesnap/config.lua +++ b/lua/codesnap/config.lua @@ -27,6 +27,7 @@ end function config_module.get_config(extension) local code = visual_utils.get_selected_text() + local start_line_number = visual_utils.get_start_line_number() if string_utils.is_str_empty(code) then error("No code is selected", 0) @@ -41,6 +42,7 @@ function config_module.get_config(extension) themes_folder = assets_folder .. "/themes", theme = "base16-onedark", file_path = static.config.has_breadcrumbs and path_utils.get_relative_path() or "", + start_line_number = static.config.has_line_number and start_line_number or nil, }, static.config) config.save_path = parse_save_path(config.save_path) diff --git a/lua/codesnap/init.lua b/lua/codesnap/init.lua index 8340208..2a47c8e 100644 --- a/lua/codesnap/init.lua +++ b/lua/codesnap/init.lua @@ -36,6 +36,7 @@ function main.save_snapshot(extension) require("generator").save_snapshot(config) vim.cmd("delmarks <>") + ---@diagnostic disable-next-line: need-check-nil vim.notify("Save snapshot in " .. config.save_path .. " successfully") end diff --git a/lua/codesnap/static.lua b/lua/codesnap/static.lua index 518158e..1bec55f 100644 --- a/lua/codesnap/static.lua +++ b/lua/codesnap/static.lua @@ -10,6 +10,7 @@ return { bg_theme = "default", breadcrumbs_separator = "/", has_breadcrumbs = false, + has_line_number = false, }, cwd = path_utils.back(path_utils.back(debug.getinfo(1, "S").source:sub(2):match("(.*[/\\])"))), preview_switch = true, diff --git a/lua/codesnap/utils/logger.lua b/lua/codesnap/utils/logger.lua deleted file mode 100644 index 168de3a..0000000 --- a/lua/codesnap/utils/logger.lua +++ /dev/null @@ -1,11 +0,0 @@ -local logger = {} - -function logger.log(level, message) - vim.api.nvim_notify("[" .. level .. "] CodeSnap: " .. tostring(vim.inspect(message)), vim.log.levels[level], {}) -end - -function logger.error(message) - logger.log("ERROR", message) -end - -return logger diff --git a/lua/codesnap/utils/visual.lua b/lua/codesnap/utils/visual.lua index f834ec4..a586cbe 100644 --- a/lua/codesnap/utils/visual.lua +++ b/lua/codesnap/utils/visual.lua @@ -2,7 +2,6 @@ local visual_utils = {} -- Get all the lines from "from" to "to" and return them as a single string -- If "from" and "to" are the same, return the line at "from" - local function get_whole_lines(from, to) local lines = {} if from == to then @@ -15,6 +14,10 @@ local function get_whole_lines(from, to) return table.concat(lines, "\n") end +function visual_utils.get_start_line_number() + return vim.fn.line("'<") +end + function visual_utils.get_selected_text() local selected_text = vim.fn.getline("'<", "'>")