Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat] support for take code snapshot in ASCII art format ^ ^ #114

Merged
merged 4 commits into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions generator/src/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@ fn min_width(width: f32) -> f32 {
}
}

// Because the code block is input by users, we need to calculate the width and height
// to make sure render the width and height of the "editor" shape correctly
#[cached(key = "String", convert = r#"{ format!("{}", text) }"#)]
pub fn calc_max_line_number_length(code_length: usize, start_line_number: usize) -> usize {
let max_line_number = code_length + start_line_number;

// If code length is 1, the max_line_number will equal to start_line_number
(max_line_number - 1).to_string().len()
}

pub fn calc_wh(text: &str, char_wdith: f32, line_height: f32) -> (f32, f32) {
let trimmed_text = prepare_code(text);
let lines = trimmed_text.lines();
Expand All @@ -28,6 +32,15 @@ pub fn calc_wh(text: &str, char_wdith: f32, line_height: f32) -> (f32, f32) {
let width = max_length_line.len() as f32 * char_wdith;
let height = lines.collect::<Vec<&str>>().len() as f32 * line_height;

(width, height)
}

// Because the code block is input by users, we need to calculate the width and height
// to make sure render the width and height of the "editor" shape correctly
#[cached(key = "String", convert = r#"{ format!("{}", text) }"#)]
pub fn calc_wh_with_min_width(text: &str, char_wdith: f32, line_height: f32) -> (f32, f32) {
let (width, height) = calc_wh(text, char_wdith, line_height);

(min_width(width), height)
}

Expand Down
4 changes: 2 additions & 2 deletions generator/src/components/breadcrumbs.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use cosmic_text::{Attrs, Color, Family};
use regex::Regex;

use crate::{code::calc_wh, edges::margin::Margin, text::FontRenderer};
use crate::{code::calc_wh_with_min_width, edges::margin::Margin, text::FontRenderer};

use super::interface::{
component::Component,
Expand All @@ -24,7 +24,7 @@ impl Component for Breadcrumbs {
let style = RawComponentStyle::default();

if self.has_breadcrumbs {
let (w, h) = calc_wh(&self.path, 8., self.line_height);
let (w, h) = calc_wh_with_min_width(&self.path, 8., self.line_height);

style.size(Size::Num(w), Size::Num(h)).margin(Margin {
top: 5.,
Expand Down
4 changes: 2 additions & 2 deletions generator/src/components/editor/code.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{
code::{calc_wh, prepare_code, CHAR_WIDTH},
code::{calc_wh_with_min_width, prepare_code, CHAR_WIDTH},
components::interface::{
component::{Component, ComponentContext, RenderParams},
render_error,
Expand All @@ -22,7 +22,7 @@ impl Component for Code {
}

fn style(&self) -> RawComponentStyle {
let (w, h) = calc_wh(&self.value, CHAR_WIDTH, self.line_height);
let (w, h) = calc_wh_with_min_width(&self.value, CHAR_WIDTH, self.line_height);

Style::default().size(Size::Num(w), Size::Num(h))
}
Expand Down
65 changes: 65 additions & 0 deletions generator/src/copy_ascii.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use std::cmp::max;

use crate::{
code::{calc_max_line_number_length, calc_wh},
config::TakeSnapshotParams,
};
use arboard::Clipboard;
use nvim_oxi::Result;

const SPACE_BOTH_SIDE: usize = 2;

fn optional(component: String, is_view: bool) -> String {
if is_view {
component
} else {
"".to_string()
}
}

#[allow(dead_code)]
pub fn copy_ascii(params: TakeSnapshotParams) -> Result<()> {
let (width, height) = calc_wh(&params.code, 1., 1.);
let calc_line_number_width =
|start_line_number: usize| calc_max_line_number_length(height as usize, start_line_number);
let frame_width = max(width as usize, params.file_path.len()) + SPACE_BOTH_SIDE;
let frame_width = match params.start_line_number {
Some(start_line_number) => {
frame_width + SPACE_BOTH_SIDE + calc_line_number_width(start_line_number)
}
None => frame_width,
};
let line = format!("│{}│\n", "─".repeat(frame_width));
let frame_width_with_content = frame_width - 1;
let top_frame = format!("╭{}╮\n", "─".repeat(frame_width));
let bottom_frame = format!("╰{}╯", "─".repeat(frame_width));
let code = params
.code
.lines()
.enumerate()
.map(|(i, line)| {
format!(
"│ {:1$} │\n",
match params.start_line_number {
Some(start_line_number) => format!(
"{:1$} {line}",
start_line_number + i,
calc_line_number_width(start_line_number),
),
None => line.to_string(),
},
frame_width_with_content - 1
)
})
.collect::<String>();
let text_line = |text: &str| format!("│ {:1$}│\n", text, frame_width_with_content);
let breadcrumbs = optional(
format!("{}{line}", text_line(&params.file_path)),
params.has_breadcrumbs,
);
let ascii_snapshot = format!("{top_frame}{breadcrumbs}{code}{bottom_frame}");

Clipboard::new().unwrap().set_text(ascii_snapshot).unwrap();

Ok(())
}
3 changes: 3 additions & 0 deletions generator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ mod color;
mod components;
mod config;
mod copy;
mod copy_ascii;
mod edges;
mod highlight;
mod path;
Expand All @@ -11,6 +12,7 @@ mod snapshot;
mod text;

use copy::copy_into_clipboard;
use copy_ascii::copy_ascii;
use nvim_oxi::{Dictionary, Function, Result};
use save::save_snapshot;

Expand All @@ -22,5 +24,6 @@ fn generator() -> Result<Dictionary> {
Function::from_fn(copy_into_clipboard),
),
("save_snapshot", Function::from_fn(save_snapshot)),
("copy_ascii", Function::from_fn(copy_ascii)),
]))
}
7 changes: 7 additions & 0 deletions lua/codesnap/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ function main.copy_into_clipboard_with_config(config)
vim.notify("Save snapshot into clipboard successfully")
end

-- Take ASCII code snapshot into clipboard
function main.copy_ascii_snapshot(extension)
require("generator").copy_ascii(config_module.get_config(extension))
vim.cmd("delmarks <>")
vim.notify("Save snapshot into clipboard successfully")
end

function main.save_snapshot_with_config(config)
if string_utils.is_str_empty(static.config.save_path) then
error(
Expand Down
6 changes: 6 additions & 0 deletions plugin/codesnap.lua
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ vim.api.nvim_create_user_command("CodeSnap", take_snapshot(codesnap.copy_into_cl

vim.api.nvim_create_user_command("CodeSnapSave", take_snapshot(codesnap.save_snapshot), { nargs = "*", range = "%" })

vim.api.nvim_create_user_command(
"CodeSnapASCII",
take_snapshot(codesnap.copy_ascii_snapshot),
{ nargs = "*", range = "%" }
)

vim.api.nvim_create_user_command(
"CodeSnapHighlight",
take_snapshot(codesnap.highlight_mode_copy_into_clipboard),
Expand Down
Loading