fm/modes/fs/
icon.rs

1use crate::{
2    common::DIR_ICON,
3    modes::{extract_extension, FileInfo, FileKind},
4};
5
6/// Associate something to a nerdfont icon.
7///
8/// Those methods require nerdfont to be installed.
9pub trait Icon {
10    fn icon(&self) -> &'static str;
11}
12
13impl Icon for str {
14    /// Associate an extension to a nerdfont icon.
15    /// Adapted from [ranger_devicons](https://github.com/alexanderjeurissen/ranger_devicons)
16    #[inline]
17    fn icon(&self) -> &'static str {
18        match self {
19            "7z" => " ",
20            "a" => " ",
21            "ai" => " ",
22            "apk" => " ",
23            "asm" => " ",
24            "asp" => " ",
25            "aup" => " ",
26            "avi" => " ",
27            "awk" => " ",
28            "bash" => " ",
29            "bat" => " ",
30            "bmp" => " ",
31            "bz2" => " ",
32            "c" => " ",
33            "c++" => " ",
34            "cab" => " ",
35            "cbr" => " ",
36            "cbz" => " ",
37            "cc" => " ",
38            "class" => " ",
39            "clj" => " ",
40            "cljc" => " ",
41            "cljs" => " ",
42            "cmake" => " ",
43            "coffee" => " ",
44            "conf" => " ",
45            "cp" => " ",
46            "cpio" => " ",
47            "cpp" => " ",
48            "cs" => "󰌛 ",
49            "csh" => " ",
50            "css" => " ",
51            "cue" => " ",
52            "cvs" => " ",
53            "cxx" => " ",
54            "d" => " ",
55            "dart" => " ",
56            "db" => " ",
57            "deb" => " ",
58            "diff" => " ",
59            "dll" => " ",
60            "wps" => " ",
61            "wpt" => " ",
62            "doc" => " ",
63            "docx" => " ",
64            "docm" => " ",
65            "dotx" => " ",
66            "dotm" => " ",
67            "dump" => " ",
68            "edn" => " ",
69            "eex" => " ",
70            "efi" => " ",
71            "ejs" => " ",
72            "elf" => " ",
73            "elm" => " ",
74            "epub" => " ",
75            "erl" => " ",
76            "ex" => " ",
77            "exe" => " ",
78            "exs" => " ",
79            "f#" => " ",
80            "fifo" => "󰟥 ",
81            "fish" => " ",
82            "flac" => " ",
83            "flv" => " ",
84            "fs" => " ",
85            "fsi" => " ",
86            "fsscript" => " ",
87            "fsx" => " ",
88            "gem" => " ",
89            "gemspec" => " ",
90            "gif" => " ",
91            "go" => " ",
92            "gz" => " ",
93            "gzip" => " ",
94            "h" => " ",
95            "haml" => " ",
96            "hbs" => " ",
97            "hh" => " ",
98            "hpp" => " ",
99            "hrl" => " ",
100            "hs" => " ",
101            "htaccess" => " ",
102            "htm" => " ",
103            "html" => " ",
104            "htpasswd" => " ",
105            "hxx" => " ",
106            "ico" => " ",
107            "img" => " ",
108            "ini" => " ",
109            "ipynb" => " ",
110            "iso" => " ",
111            "jar" => " ",
112            "java" => " ",
113            "jl" => " ",
114            "jpeg" => " ",
115            "jpg" => " ",
116            "js" => " ",
117            "json" => " ",
118            "jsonc" => " ",
119            "jsx" => " ",
120            "key" => " ",
121            "ksh" => " ",
122            "leex" => " ",
123            "less" => " ",
124            "lha" => " ",
125            "lhs" => " ",
126            "log" => " ",
127            "lua" => " ",
128            "lz" => " ",
129            "lzh" => " ",
130            "lzma" => " ",
131            "m4a" => " ",
132            "m4v" => " ",
133            "markdown" => " ",
134            "md" => " ",
135            "mdx" => " ",
136            "mjs" => " ",
137            "mka" => " ",
138            "mkv" => " ",
139            "ml" => "λ ",
140            "mli" => "λ ",
141            "mov" => " ",
142            "mp3" => " ",
143            "mp4" => " ",
144            "mpeg" => " ",
145            "mpg" => " ",
146            "msi" => " ",
147            "mustache" => " ",
148            "nix" => " ",
149            "o" => " ",
150            "ogg" => " ",
151            "opus" => " ",
152            "part" => " ",
153            "pdf" => " ",
154            "php" => " ",
155            "pl" => " ",
156            "pm" => " ",
157            "png" => " ",
158            "pp" => " ",
159            "dps" => " ",
160            "dpt" => " ",
161            "ppt" => " ",
162            "pptx" => " ",
163            "pptm" => " ",
164            "pot" => " ",
165            "potx" => " ",
166            "potm" => " ",
167            "pps" => " ",
168            "ppsx" => " ",
169            "ppsm" => " ",
170            "ps1" => " ",
171            "psb" => " ",
172            "psd" => " ",
173            "pub" => " ",
174            "py" => " ",
175            "pyc" => " ",
176            "pyd" => " ",
177            "pyo" => " ",
178            "r" => "󰟔 ",
179            "rake" => " ",
180            "rar" => " ",
181            "rb" => " ",
182            "rc" => " ",
183            "rlib" => " ",
184            "rmd" => " ",
185            "rom" => " ",
186            "rpm" => " ",
187            "rproj" => "󰗆 ",
188            "rs" => " ",
189            "rss" => " ",
190            "rtf" => " ",
191            "s" => " ",
192            "sass" => " ",
193            "scala" => " ",
194            "scss" => " ",
195            "sh" => " ",
196            "slim" => " ",
197            "sln" => " ",
198            "so" => " ",
199            "sql" => " ",
200            "styl" => " ",
201            "suo" => " ",
202            "svelte" => " ",
203            "swift" => " ",
204            "t" => " ",
205            "tar" => " ",
206            "tex" => "󰙩 ",
207            "tgz" => " ",
208            "toml" => " ",
209            "torrent" => " ",
210            "ts" => " ",
211            "tsx" => " ",
212            "twig" => " ",
213            "vim" => " ",
214            "vimrc" => " ",
215            "vue" => "󰡄 ",
216            "wav" => " ",
217            "webm" => " ",
218            "webmanifest" => " ",
219            "webp" => " ",
220            "xbps" => " ",
221            "xcplayground" => " ",
222            "xhtml" => " ",
223            "et" => "󰈛 ",
224            "ett" => "󰈛 ",
225            "xls" => "󰈛 ",
226            "xlt" => "󰈛 ",
227            "xlsx" => "󰈛 ",
228            "xlsm" => "󰈛 ",
229            "xlsb" => "󰈛 ",
230            "xltx" => "󰈛 ",
231            "xltm" => "󰈛 ",
232            "xla" => "󰈛 ",
233            "xlam" => "󰈛 ",
234            "xml" => " ",
235            "xul" => " ",
236            "xz" => " ",
237            "yaml" => " ",
238            "yml" => " ",
239            "zip" => " ",
240            "zsh" => " ",
241            _ => "󰈔 ",
242        }
243    }
244}
245
246impl Icon for std::path::Path {
247    /// Icon from a path.
248    /// Should only be used in tree display.
249    /// Requires metadata and is quite heavy.
250    fn icon(&self) -> &'static str {
251        let Ok(metadata) = self.symlink_metadata() else {
252            return DIR_ICON;
253        };
254        let file_kind = FileKind::new(&metadata, self);
255        match file_kind {
256            FileKind::NormalFile => extract_extension(self).icon(),
257            _ => file_kind.icon(),
258        }
259    }
260}
261
262impl Icon for FileKind<bool> {
263    /// Icon per file kind.
264    /// Shouldn't be called for normal files, use extension.icon() directly.
265    fn icon(&self) -> &'static str {
266        match self {
267            Self::Fifo => " ",
268            Self::Socket => "󰟩 ",
269            Self::Directory => DIR_ICON,
270            Self::NormalFile => "",
271            Self::CharDevice => " ",
272            Self::BlockDevice => " ",
273            Self::SymbolicLink(_) => " ",
274        }
275    }
276}
277
278impl Icon for FileInfo {
279    /// Icon for a file given by its fileinfo.
280    fn icon(&self) -> &'static str {
281        match self.file_kind {
282            FileKind::NormalFile => self.extension.icon(),
283            _ => self.file_kind.icon(),
284        }
285    }
286}