use std::path::Path;
pub fn link_icon() -> char {
'\u{f0c1}' }
pub fn task_icon(checked: bool) -> char {
if checked {
'\u{f046}' } else {
'\u{f096}' }
}
pub fn branch_icon() -> char {
'\u{2387}'
}
pub fn base_icon() -> char {
'\u{2316}'
}
pub fn branch_marker(icons: bool) -> &'static str {
if icons {
"\u{2387}"
} else {
"br:"
}
}
pub fn base_marker(icons: bool) -> &'static str {
if icons {
"\u{2316}"
} else {
"base:"
}
}
pub fn dir_icon(expanded: bool) -> char {
if expanded {
'\u{f07c}' } else {
'\u{f07b}' }
}
pub fn file_icon(path: &Path) -> char {
let name = path.file_name().and_then(|n| n.to_str()).unwrap_or("");
match name.to_ascii_lowercase().as_str() {
".gitignore" | ".gitattributes" | ".gitmodules" => return '\u{e702}', "license" | "license.md" | "license.txt" | "copying" => return '\u{f0f6}', _ => {}
}
let ext = path
.extension()
.and_then(|e| e.to_str())
.unwrap_or("")
.to_ascii_lowercase();
match ext.as_str() {
"rs" => '\u{e7a8}', "md" | "markdown" | "mmd" | "mermaid" => '\u{e73e}', "toml" | "yaml" | "yml" | "ini" | "cfg" | "conf" => '\u{e615}', "json" => '\u{e60b}', "js" | "mjs" | "cjs" => '\u{e74e}', "ts" | "tsx" => '\u{e628}', "py" => '\u{e73c}', "go" => '\u{e627}', "c" | "h" => '\u{e61e}', "cpp" | "cc" | "cxx" | "hpp" => '\u{e61d}', "sh" | "bash" | "zsh" | "fish" => '\u{f489}', "png" | "jpg" | "jpeg" | "gif" | "webp" | "bmp" | "ico" | "svg" => '\u{f1c5}', "mp4" | "mov" | "mkv" | "webm" | "avi" => '\u{f03d}', "lock" => '\u{f023}', "txt" | "log" => '\u{f15c}', _ => '\u{f016}', }
}
#[cfg_attr(not(feature = "git"), allow(dead_code))]
pub fn node_glyph(kind: crate::git::NodeKind, vcs: crate::vcs::VcsKind) -> char {
use crate::git::NodeKind as K;
#[cfg(feature = "git")]
if vcs == crate::vcs::VcsKind::Jj {
return match kind {
K::WorkingCopy => '@',
K::Normal | K::Merge => '\u{25cb}', K::Immutable => '\u{25c6}', K::Conflict => '\u{00d7}', };
}
let _ = vcs;
match kind {
K::Normal | K::WorkingCopy => '\u{25cf}', K::Merge | K::Immutable => '\u{25c6}', K::Conflict => '\u{00d7}', }
}
#[cfg_attr(not(feature = "git"), allow(dead_code))]
pub fn chip_marker(vcs: crate::vcs::VcsKind, icons: bool) -> &'static str {
match vcs {
crate::vcs::VcsKind::Git => branch_marker(icons),
#[cfg(feature = "git")]
crate::vcs::VcsKind::Jj => "",
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::git::NodeKind;
use crate::vcs::VcsKind;
#[test]
fn node_glyph_git_all_five_kinds() {
assert_eq!(
node_glyph(NodeKind::Normal, VcsKind::Git),
'\u{25cf}',
"git の通常コミットは ●"
);
assert_eq!(
node_glyph(NodeKind::Merge, VcsKind::Git),
'\u{25c6}',
"git のマージは ◆"
);
assert_eq!(
node_glyph(NodeKind::WorkingCopy, VcsKind::Git),
'\u{25cf}',
"git に作業コピー専用の字は無く、Normal と同じ ●(擬似行は色で後から塗り分ける)"
);
assert_eq!(
node_glyph(NodeKind::Immutable, VcsKind::Git),
'\u{25c6}',
"git に Immutable の概念は無く、Merge と同じ ◆ に落ちる"
);
assert_eq!(
node_glyph(NodeKind::Conflict, VcsKind::Git),
'\u{00d7}',
"衝突は ×"
);
}
#[cfg(feature = "git")]
#[test]
fn node_glyph_jj_all_five_kinds() {
assert_eq!(
node_glyph(NodeKind::WorkingCopy, VcsKind::Jj),
'@',
"jj の作業コピーは @"
);
assert_eq!(
node_glyph(NodeKind::Normal, VcsKind::Jj),
'\u{25cb}',
"jj の通常コミットは ○"
);
assert_eq!(
node_glyph(NodeKind::Merge, VcsKind::Jj),
'\u{25cb}',
"jj はマージを通常コミットと同じ ○ に畳む(git と違い ◆ にはしない)"
);
assert_eq!(
node_glyph(NodeKind::Immutable, VcsKind::Jj),
'\u{25c6}',
"jj の不変コミットは ◆"
);
assert_eq!(
node_glyph(NodeKind::Conflict, VcsKind::Jj),
'\u{00d7}',
"衝突は ×"
);
}
#[cfg(feature = "git")]
#[test]
fn git_and_jj_fold_different_kind_pairs_into_the_same_glyph() {
assert_eq!(
node_glyph(NodeKind::Merge, VcsKind::Git),
node_glyph(NodeKind::Immutable, VcsKind::Git),
"git: Merge と Immutable は同じ字のはず"
);
assert_ne!(
node_glyph(NodeKind::Merge, VcsKind::Jj),
node_glyph(NodeKind::Immutable, VcsKind::Jj),
"jj: Merge と Immutable は別の字でなければならない"
);
assert_eq!(
node_glyph(NodeKind::Normal, VcsKind::Jj),
node_glyph(NodeKind::Merge, VcsKind::Jj),
"jj: Normal と Merge は同じ字のはず"
);
assert_ne!(
node_glyph(NodeKind::Normal, VcsKind::Git),
node_glyph(NodeKind::Merge, VcsKind::Git),
"git: Normal と Merge は別の字でなければならない"
);
}
#[test]
fn chip_marker_git_both_icon_settings() {
assert_eq!(
chip_marker(VcsKind::Git, true),
"\u{2387}",
"git+icons=true は ⎇"
);
assert_eq!(
chip_marker(VcsKind::Git, false),
"br:",
"git+icons=false は ASCII ラベル br:"
);
}
#[cfg(feature = "git")]
#[test]
fn chip_marker_jj_is_always_empty() {
assert_eq!(
chip_marker(VcsKind::Jj, true),
"",
"jj+icons=true はチップ記号を足さない(ラベルが既に @ で始まる)"
);
assert_eq!(chip_marker(VcsKind::Jj, false), "", "jj+icons=false も同様");
}
}