[Feat] add breadcrumbs to display file path
parent
38ee8c463d
commit
272e89ff8e
|
@ -1,3 +1,5 @@
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
const MIN_WIDTH: f32 = 100.;
|
const MIN_WIDTH: f32 = 100.;
|
||||||
|
|
||||||
fn min_width(width: f32) -> f32 {
|
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) {
|
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| {
|
let max_length_line = lines.clone().into_iter().fold("", |max_length_line, cur| {
|
||||||
if cur.len() > max_length_line.len() {
|
if cur.len() > max_length_line.len() {
|
||||||
cur
|
cur
|
||||||
|
@ -22,3 +25,25 @@ pub fn calc_wh(text: &str, char_wdith: f32, line_height: f32) -> (f32, f32) {
|
||||||
|
|
||||||
(min_width(width), height)
|
(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 background;
|
||||||
|
pub mod breadcrumbs;
|
||||||
pub mod container;
|
pub mod container;
|
||||||
pub mod editor;
|
pub mod editor;
|
||||||
pub mod interface;
|
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::{
|
use crate::{
|
||||||
code::calc_wh,
|
code::{calc_wh, trim_space},
|
||||||
components::interface::{
|
components::interface::{
|
||||||
component::{Component, ComponentContext, RenderParams},
|
component::{Component, ComponentContext, RenderParams},
|
||||||
render_error,
|
render_error,
|
||||||
|
@ -42,7 +42,7 @@ impl Component for Code {
|
||||||
) -> render_error::Result<()> {
|
) -> render_error::Result<()> {
|
||||||
let params = &context.take_snapshot_params;
|
let params = &context.take_snapshot_params;
|
||||||
let highlight = Highlight::new(
|
let highlight = Highlight::new(
|
||||||
params.code.clone(),
|
self.value.clone(),
|
||||||
params.code_font_family.clone(),
|
params.code_font_family.clone(),
|
||||||
params.language.clone(),
|
params.language.clone(),
|
||||||
params.extension.clone(),
|
params.extension.clone(),
|
||||||
|
@ -71,7 +71,7 @@ impl Component for Code {
|
||||||
impl Code {
|
impl Code {
|
||||||
pub fn new(value: String, line_height: f32, font_size: f32) -> Code {
|
pub fn new(value: String, line_height: f32, font_size: f32) -> Code {
|
||||||
Code {
|
Code {
|
||||||
value,
|
value: trim_space(&value),
|
||||||
line_height,
|
line_height,
|
||||||
font_size,
|
font_size,
|
||||||
children: vec![],
|
children: vec![],
|
||||||
|
|
|
@ -19,6 +19,9 @@ 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>,
|
||||||
|
pub file_path: String,
|
||||||
|
pub breadcrumbs_separator: String,
|
||||||
|
pub has_breadcrumbs: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromObject for TakeSnapshotParams {
|
impl FromObject for TakeSnapshotParams {
|
||||||
|
|
|
@ -3,6 +3,7 @@ use std::sync::Arc;
|
||||||
use tiny_skia::Pixmap;
|
use tiny_skia::Pixmap;
|
||||||
|
|
||||||
use crate::components::background::Background;
|
use crate::components::background::Background;
|
||||||
|
use crate::components::breadcrumbs::Breadcrumbs;
|
||||||
use crate::components::container::Container;
|
use crate::components::container::Container;
|
||||||
use crate::components::editor::code::Code;
|
use crate::components::editor::code::Code;
|
||||||
use crate::components::editor::mac_title_bar::MacTitleBar;
|
use crate::components::editor::mac_title_bar::MacTitleBar;
|
||||||
|
@ -26,6 +27,12 @@ pub fn take_snapshot(params: TakeSnapshotParams) -> render_error::Result<Pixmap>
|
||||||
16.,
|
16.,
|
||||||
vec![
|
vec![
|
||||||
Box::new(MacTitleBar::from_radius(8.)),
|
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.)),
|
Box::new(Code::new(params.code, 20., 15.)),
|
||||||
],
|
],
|
||||||
)),
|
)),
|
||||||
|
|
|
@ -3,6 +3,7 @@ local table_utils = require("codesnap.utils.table")
|
||||||
local generator = require("generator")
|
local generator = require("generator")
|
||||||
local string_utils = require("codesnap.utils.string")
|
local string_utils = require("codesnap.utils.string")
|
||||||
local visual_utils = require("codesnap.utils.visual")
|
local visual_utils = require("codesnap.utils.visual")
|
||||||
|
local path_utils = require("codesnap.utils.path")
|
||||||
|
|
||||||
local assets_folder = static.cwd .. "/assets"
|
local assets_folder = static.cwd .. "/assets"
|
||||||
|
|
||||||
|
@ -40,6 +41,7 @@ local function get_config()
|
||||||
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",
|
||||||
|
file_path = static.config.has_breadcrumbs and path_utils.get_relative_path() or "",
|
||||||
}, static.config)
|
}, static.config)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@ return {
|
||||||
watermark_font_family = "Pacifico",
|
watermark_font_family = "Pacifico",
|
||||||
watermark = "CodeSnap.nvim",
|
watermark = "CodeSnap.nvim",
|
||||||
bg_theme = "default",
|
bg_theme = "default",
|
||||||
|
breadcrumbs_separator = "/",
|
||||||
|
has_breadcrumbs = false,
|
||||||
},
|
},
|
||||||
cwd = path_utils.back(path_utils.back(debug.getinfo(1, "S").source:sub(2):match("(.*[/\\])"))),
|
cwd = path_utils.back(path_utils.back(debug.getinfo(1, "S").source:sub(2):match("(.*[/\\])"))),
|
||||||
preview_switch = true,
|
preview_switch = true,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
local string_utils = require("codesnap.utils.string")
|
||||||
local path_utils = {}
|
local path_utils = {}
|
||||||
|
|
||||||
function path_utils.back(path)
|
function path_utils.back(path)
|
||||||
|
@ -6,4 +7,11 @@ function path_utils.back(path)
|
||||||
return parsed_path
|
return parsed_path
|
||||||
end
|
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
|
return path_utils
|
||||||
|
|
Loading…
Reference in New Issue