[Feat] add breadcrumbs to display file path
parent
38ee8c463d
commit
272e89ff8e
|
@ -1,3 +1,5 @@
|
|||
use regex::Regex;
|
||||
|
||||
const MIN_WIDTH: f32 = 100.;
|
||||
|
||||
fn min_width(width: f32) -> f32 {
|
||||
|
@ -9,7 +11,8 @@ fn min_width(width: f32) -> f32 {
|
|||
}
|
||||
|
||||
pub fn calc_wh(text: &str, char_wdith: f32, line_height: f32) -> (f32, f32) {
|
||||
let lines = text.lines();
|
||||
let trimmed_text = trim_space(text);
|
||||
let lines = trimmed_text.lines();
|
||||
let max_length_line = lines.clone().into_iter().fold("", |max_length_line, cur| {
|
||||
if cur.len() > max_length_line.len() {
|
||||
cur
|
||||
|
@ -22,3 +25,25 @@ pub fn calc_wh(text: &str, char_wdith: f32, line_height: f32) -> (f32, f32) {
|
|||
|
||||
(min_width(width), height)
|
||||
}
|
||||
|
||||
pub fn trim_space(text: &str) -> String {
|
||||
let lines = text.split("\n").collect::<Vec<&str>>();
|
||||
let first_line = lines.first().unwrap();
|
||||
let head_spaces = Regex::new(r"^(\s*)").unwrap().find(first_line);
|
||||
|
||||
match head_spaces {
|
||||
Some(head_spaces) => {
|
||||
return lines
|
||||
.into_iter()
|
||||
.map(|line| {
|
||||
Regex::new(format!("^{}", head_spaces.as_str()).as_ref())
|
||||
.unwrap()
|
||||
.replace(line, "")
|
||||
.to_string()
|
||||
})
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n");
|
||||
}
|
||||
None => text.to_string(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
pub mod background;
|
||||
pub mod breadcrumbs;
|
||||
pub mod container;
|
||||
pub mod editor;
|
||||
pub mod interface;
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
use cosmic_text::{Attrs, Color, Family};
|
||||
use regex::Regex;
|
||||
|
||||
use crate::{code::calc_wh, edges::margin::Margin, text::FontRenderer};
|
||||
|
||||
use super::interface::{
|
||||
component::Component,
|
||||
style::{RawComponentStyle, Size},
|
||||
};
|
||||
|
||||
pub struct Breadcrumbs {
|
||||
children: Vec<Box<dyn Component>>,
|
||||
path: String,
|
||||
line_height: f32,
|
||||
has_breadcrumbs: bool,
|
||||
}
|
||||
|
||||
impl Component for Breadcrumbs {
|
||||
fn children(&self) -> &Vec<Box<dyn Component>> {
|
||||
&self.children
|
||||
}
|
||||
|
||||
fn style(&self) -> RawComponentStyle {
|
||||
let style = RawComponentStyle::default();
|
||||
|
||||
if self.has_breadcrumbs {
|
||||
let (w, h) = calc_wh(&self.path, 8., self.line_height);
|
||||
|
||||
style.size(Size::Num(w), Size::Num(h)).margin(Margin {
|
||||
top: 5.,
|
||||
..Margin::default()
|
||||
})
|
||||
} else {
|
||||
style
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_self(
|
||||
&self,
|
||||
pixmap: &mut tiny_skia::Pixmap,
|
||||
context: &super::interface::component::ComponentContext,
|
||||
render_params: &super::interface::component::RenderParams,
|
||||
style: &super::interface::style::ComponentStyle,
|
||||
) -> super::interface::render_error::Result<()> {
|
||||
if self.has_breadcrumbs {
|
||||
let attrs = Attrs::new()
|
||||
.color(Color::rgb(128, 132, 139))
|
||||
.family(Family::Name(&context.take_snapshot_params.code_font_family));
|
||||
|
||||
FontRenderer::new(
|
||||
12.,
|
||||
self.line_height,
|
||||
context.scale_factor,
|
||||
&context.take_snapshot_params.fonts_folder,
|
||||
)
|
||||
.draw_text(
|
||||
render_params.x,
|
||||
render_params.y,
|
||||
style.width,
|
||||
self.line_height,
|
||||
vec![(&self.path, attrs)],
|
||||
pixmap,
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Breadcrumbs {
|
||||
pub fn from_path(
|
||||
path: String,
|
||||
line_height: f32,
|
||||
separator: String,
|
||||
has_breadcrumbs: bool,
|
||||
) -> Breadcrumbs {
|
||||
let path = Regex::new("/")
|
||||
.unwrap()
|
||||
.replace_all(&path, separator)
|
||||
.to_string();
|
||||
|
||||
Breadcrumbs {
|
||||
children: vec![],
|
||||
path,
|
||||
line_height,
|
||||
has_breadcrumbs,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{
|
||||
code::calc_wh,
|
||||
code::{calc_wh, trim_space},
|
||||
components::interface::{
|
||||
component::{Component, ComponentContext, RenderParams},
|
||||
render_error,
|
||||
|
@ -42,7 +42,7 @@ impl Component for Code {
|
|||
) -> render_error::Result<()> {
|
||||
let params = &context.take_snapshot_params;
|
||||
let highlight = Highlight::new(
|
||||
params.code.clone(),
|
||||
self.value.clone(),
|
||||
params.code_font_family.clone(),
|
||||
params.language.clone(),
|
||||
params.extension.clone(),
|
||||
|
@ -71,7 +71,7 @@ impl Component for Code {
|
|||
impl Code {
|
||||
pub fn new(value: String, line_height: f32, font_size: f32) -> Code {
|
||||
Code {
|
||||
value,
|
||||
value: trim_space(&value),
|
||||
line_height,
|
||||
font_size,
|
||||
children: vec![],
|
||||
|
|
|
@ -19,6 +19,9 @@ pub struct TakeSnapshotParams {
|
|||
pub theme: String,
|
||||
pub bg_theme: String,
|
||||
pub bg_color: Option<String>,
|
||||
pub file_path: String,
|
||||
pub breadcrumbs_separator: String,
|
||||
pub has_breadcrumbs: bool,
|
||||
}
|
||||
|
||||
impl FromObject for TakeSnapshotParams {
|
||||
|
|
|
@ -3,6 +3,7 @@ use std::sync::Arc;
|
|||
use tiny_skia::Pixmap;
|
||||
|
||||
use crate::components::background::Background;
|
||||
use crate::components::breadcrumbs::Breadcrumbs;
|
||||
use crate::components::container::Container;
|
||||
use crate::components::editor::code::Code;
|
||||
use crate::components::editor::mac_title_bar::MacTitleBar;
|
||||
|
@ -26,6 +27,12 @@ pub fn take_snapshot(params: TakeSnapshotParams) -> render_error::Result<Pixmap>
|
|||
16.,
|
||||
vec![
|
||||
Box::new(MacTitleBar::from_radius(8.)),
|
||||
Box::new(Breadcrumbs::from_path(
|
||||
params.file_path,
|
||||
15.,
|
||||
params.breadcrumbs_separator,
|
||||
params.has_breadcrumbs,
|
||||
)),
|
||||
Box::new(Code::new(params.code, 20., 15.)),
|
||||
],
|
||||
)),
|
||||
|
|
|
@ -3,6 +3,7 @@ local table_utils = require("codesnap.utils.table")
|
|||
local generator = require("generator")
|
||||
local string_utils = require("codesnap.utils.string")
|
||||
local visual_utils = require("codesnap.utils.visual")
|
||||
local path_utils = require("codesnap.utils.path")
|
||||
|
||||
local assets_folder = static.cwd .. "/assets"
|
||||
|
||||
|
@ -40,6 +41,7 @@ local function get_config()
|
|||
fonts_folder = assets_folder .. "/fonts",
|
||||
themes_folder = assets_folder .. "/themes",
|
||||
theme = "base16-onedark",
|
||||
file_path = static.config.has_breadcrumbs and path_utils.get_relative_path() or "",
|
||||
}, static.config)
|
||||
end
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@ return {
|
|||
watermark_font_family = "Pacifico",
|
||||
watermark = "CodeSnap.nvim",
|
||||
bg_theme = "default",
|
||||
breadcrumbs_separator = "/",
|
||||
has_breadcrumbs = false,
|
||||
},
|
||||
cwd = path_utils.back(path_utils.back(debug.getinfo(1, "S").source:sub(2):match("(.*[/\\])"))),
|
||||
preview_switch = true,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
local string_utils = require("codesnap.utils.string")
|
||||
local path_utils = {}
|
||||
|
||||
function path_utils.back(path)
|
||||
|
@ -6,4 +7,11 @@ function path_utils.back(path)
|
|||
return parsed_path
|
||||
end
|
||||
|
||||
function path_utils.get_relative_path()
|
||||
local full_file_path = vim.fn.expand("%:p")
|
||||
local cwd = vim.fn.getcwd()
|
||||
|
||||
return full_file_path:gsub(string_utils.escape(cwd), ""):sub(2)
|
||||
end
|
||||
|
||||
return path_utils
|
||||
|
|
Loading…
Reference in New Issue