build.rs 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780
  1. /// The version string isnโ€™t the simplest: we want to show the version,
  2. /// current Git hash, and compilation date when building *debug* versions, but
  3. /// just the version for *release* versions so the builds are reproducible.
  4. ///
  5. /// This script generates the string from the environment variables that Cargo
  6. /// adds (http://doc.crates.io/environment-variables.html) and runs `git` to
  7. /// get the SHA1 hash. It then writes the string into a file, which exa then
  8. /// includes at build-time.
  9. ///
  10. /// - https://stackoverflow.com/q/43753491/3484614
  11. /// - https://crates.io/crates/vergen
  12. use std::env;
  13. use std::fs::File;
  14. use std::io::{self, Write};
  15. use std::path::PathBuf;
  16. use datetime::{LocalDateTime, ISO};
  17. /// The build script entry point.
  18. fn main() -> io::Result<()> {
  19. create_version_string_file()?;
  20. create_file_typing_hash_file()?;
  21. create_file_icon_hash_file()
  22. }
  23. /// Create the version_string.txt file
  24. fn create_version_string_file() -> io::Result<()> {
  25. #![allow(clippy::write_with_newline)]
  26. let tagline = "eza - A modern, maintained replacement for ls";
  27. let url = "https://github.com/eza-community/eza";
  28. let ver =
  29. if is_debug_build() {
  30. format!("{}\nv{} \\1;31m(pre-release debug build!)\\0m\n\\1;4;34m{}\\0m", tagline, version_string(), url)
  31. }
  32. else if is_development_version() {
  33. format!("{}\nv{} [{}] built on {} \\1;31m(pre-release!)\\0m\n\\1;4;34m{}\\0m", tagline, version_string(), git_hash(), build_date(), url)
  34. }
  35. else {
  36. format!("{}\nv{}\n\\1;4;34m{}\\0m", tagline, version_string(), url)
  37. };
  38. // We need to create these files in the Cargo output directory.
  39. let out = PathBuf::from(env::var("OUT_DIR").unwrap());
  40. let path = &out.join("version_string.txt");
  41. // Bland version text
  42. let mut f = File::create(path).unwrap_or_else(|_| { panic!("{}", path.to_string_lossy().to_string()) });
  43. writeln!(f, "{}", strip_codes(&ver))
  44. }
  45. /// Removes escape codes from a string.
  46. fn strip_codes(input: &str) -> String {
  47. input.replace("\\0m", "")
  48. .replace("\\1;31m", "")
  49. .replace("\\1;4;34m", "")
  50. }
  51. /// Retrieve the projectโ€™s current Git hash, as a string.
  52. fn git_hash() -> String {
  53. use std::process::Command;
  54. String::from_utf8_lossy(
  55. &Command::new("git")
  56. .args(["rev-parse", "--short", "HEAD"])
  57. .output().unwrap()
  58. .stdout).trim().to_string()
  59. }
  60. /// Whether we should show pre-release info in the version string.
  61. ///
  62. /// Both weekly releases and actual releases are --release releases,
  63. /// but actual releases will have a proper version number.
  64. fn is_development_version() -> bool {
  65. cargo_version().ends_with("-pre") || env::var("PROFILE").unwrap() == "debug"
  66. }
  67. /// Whether we are building in debug mode.
  68. fn is_debug_build() -> bool {
  69. env::var("PROFILE").unwrap() == "debug"
  70. }
  71. /// Retrieves the [package] version in Cargo.toml as a string.
  72. fn cargo_version() -> String {
  73. env::var("CARGO_PKG_VERSION").unwrap()
  74. }
  75. /// Returns the version and build parameters string.
  76. fn version_string() -> String {
  77. let mut ver = cargo_version();
  78. let feats = nonstandard_features_string();
  79. if ! feats.is_empty() {
  80. ver.push_str(&format!(" [{}]", &feats));
  81. }
  82. ver
  83. }
  84. /// Finds whether a feature is enabled by examining the Cargo variable.
  85. fn feature_enabled(name: &str) -> bool {
  86. env::var(format!("CARGO_FEATURE_{}", name))
  87. .map(|e| ! e.is_empty())
  88. .unwrap_or(false)
  89. }
  90. /// A comma-separated list of non-standard feature choices.
  91. fn nonstandard_features_string() -> String {
  92. let mut s = Vec::new();
  93. if feature_enabled("GIT") {
  94. s.push("+git");
  95. }
  96. else {
  97. s.push("-git");
  98. }
  99. s.join(", ")
  100. }
  101. /// Formats the current date as an ISO 8601 string.
  102. fn build_date() -> String {
  103. let now = LocalDateTime::now();
  104. format!("{}", now.date().iso())
  105. }
  106. /// Create the perfect hashing for file typing
  107. fn create_file_typing_hash_file() -> io::Result<()> {
  108. let path = &PathBuf::from(env::var("OUT_DIR").unwrap()).join("filetype_maps.rs");
  109. let mut file = io::BufWriter::new(File::create(path).unwrap_or_else(|_| {
  110. panic!("{}", path.to_string_lossy().to_string())
  111. }));
  112. generate_filename_type_map(file.get_mut())?;
  113. generate_extension_type_map(file.get_mut())?;
  114. file.flush()
  115. }
  116. /// Create the perfect hashing for file icons
  117. fn create_file_icon_hash_file() -> io::Result<()> {
  118. let path = &PathBuf::from(env::var("OUT_DIR").unwrap()).join("icon_maps.rs");
  119. let mut file = io::BufWriter::new(File::create(path).unwrap_or_else(|_| {
  120. panic!("{}", path.to_string_lossy().to_string());
  121. }));
  122. generate_filename_icon_map(file.get_mut())?;
  123. generate_extension_icon_map(file.get_mut())?;
  124. file.flush()
  125. }
  126. /// Generate mapping from full filenames to file type. For file types see info/filetype.rs
  127. fn generate_filename_type_map(file: &mut File) -> io::Result<()> {
  128. writeln!(file, "static FILENAME_TYPES: phf::Map<&'static str, FileType> = {};\n",
  129. phf_codegen::Map::new()
  130. /* Immediate file - kick off the build of a project */
  131. .entry("Brewfile", "FileType::Immediate")
  132. .entry("bsconfig.json", "FileType::Immediate")
  133. .entry("BUILD", "FileType::Immediate")
  134. .entry("BUILD.bazel", "FileType::Immediate")
  135. .entry("build.gradle", "FileType::Immediate")
  136. .entry("build.sbt", "FileType::Immediate")
  137. .entry("build.xml", "FileType::Immediate")
  138. .entry("Cargo.lock", "FileType::Immediate")
  139. .entry("Cargo.toml", "FileType::Immediate")
  140. .entry("CMakeLists.txt", "FileType::Immediate")
  141. .entry("composer.json", "FileType::Immediate")
  142. .entry("configure.ac", "FileType::Immediate")
  143. .entry("Configure.ac", "FileType::Immediate")
  144. .entry("Containerfile", "FileType::Immediate")
  145. .entry("Dockerfile", "FileType::Immediate")
  146. .entry("Earthfile", "FileType::Immediate")
  147. .entry("flake.lock", "FileType::Immediate")
  148. .entry("flake.nix", "FileType::Immediate")
  149. .entry("Gemfile", "FileType::Immediate")
  150. .entry("GNUmakefile", "FileType::Immediate")
  151. .entry("Gruntfile.coffee", "FileType::Immediate")
  152. .entry("Gruntfile.js", "FileType::Immediate")
  153. .entry("Justfile", "FileType::Immediate")
  154. .entry("justfile", "FileType::Immediate")
  155. .entry("Makefile", "FileType::Immediate")
  156. .entry("makefile", "FileType::Immediate")
  157. .entry("Makefile.in", "FileType::Immediate")
  158. .entry("makefile.in", "FileType::Immediate")
  159. .entry("meson.build", "FileType::Immediate")
  160. .entry("mix.exs", "FileType::Immediate")
  161. .entry("package.json", "FileType::Immediate")
  162. .entry("Pipfile", "FileType::Immediate")
  163. .entry("PKGBUILD", "FileType::Immediate")
  164. .entry("Podfile", "FileType::Immediate")
  165. .entry("pom.xml", "FileType::Immediate")
  166. .entry("Procfile", "FileType::Immediate")
  167. .entry("Rakefile", "FileType::Immediate")
  168. .entry("RoboFile.php", "FileType::Immediate")
  169. .entry("SConstruct", "FileType::Immediate")
  170. .entry("tsconfig.json", "FileType::Immediate")
  171. .entry("Vagrantfile", "FileType::Immediate")
  172. .entry("webpack.config.cjs","FileType::Immediate")
  173. .entry("webpack.config.js", "FileType::Immediate")
  174. .entry("WORKSPACE", "FileType::Immediate")
  175. .build()
  176. )
  177. }
  178. /// Generate mapping from lowercase file extension to file type. If an image, video, music, or
  179. /// lossless extension is added also update the extension icon map. For file types see
  180. /// info/filetype.rs
  181. fn generate_extension_type_map(file: &mut File) -> io::Result<()> {
  182. // Extension are converted to lower case for comparison
  183. writeln!(file, "static EXTENSION_TYPES: phf::Map<&'static str, FileType> = {};\n",
  184. phf_codegen::Map::new()
  185. /* Immediate file - kick off the build of a project */
  186. .entry("ninja", "FileType::Immediate")
  187. /* Image files */
  188. .entry("arw", "FileType::Image")
  189. .entry("avif", "FileType::Image")
  190. .entry("bmp", "FileType::Image")
  191. .entry("cbr", "FileType::Image")
  192. .entry("cbz", "FileType::Image")
  193. .entry("cr2", "FileType::Image")
  194. .entry("dvi", "FileType::Image")
  195. .entry("eps", "FileType::Image")
  196. .entry("gif", "FileType::Image")
  197. .entry("heif", "FileType::Image")
  198. .entry("ico", "FileType::Image")
  199. .entry("j2c", "FileType::Image")
  200. .entry("j2k", "FileType::Image")
  201. .entry("jfi", "FileType::Image")
  202. .entry("jfif", "FileType::Image")
  203. .entry("jif", "FileType::Image")
  204. .entry("jp2", "FileType::Image")
  205. .entry("jpe", "FileType::Image")
  206. .entry("jpeg", "FileType::Image")
  207. .entry("jpf", "FileType::Image")
  208. .entry("jpg", "FileType::Image")
  209. .entry("jpx", "FileType::Image")
  210. .entry("jxl", "FileType::Image")
  211. .entry("nef", "FileType::Image")
  212. .entry("orf", "FileType::Image")
  213. .entry("pbm", "FileType::Image")
  214. .entry("pgm", "FileType::Image")
  215. .entry("png", "FileType::Image")
  216. .entry("pnm", "FileType::Image")
  217. .entry("ppm", "FileType::Image")
  218. .entry("ps", "FileType::Image")
  219. .entry("pxm", "FileType::Image")
  220. .entry("raw", "FileType::Image")
  221. .entry("stl", "FileType::Image")
  222. .entry("svg", "FileType::Image")
  223. .entry("tif", "FileType::Image")
  224. .entry("tiff", "FileType::Image")
  225. .entry("webp", "FileType::Image")
  226. .entry("xpm", "FileType::Image")
  227. /* Video files */
  228. .entry("avi", "FileType::Video")
  229. .entry("flv", "FileType::Video")
  230. .entry("heic", "FileType::Video")
  231. .entry("m2ts", "FileType::Video")
  232. .entry("m2v", "FileType::Video")
  233. .entry("m4v", "FileType::Video")
  234. .entry("mkv", "FileType::Video")
  235. .entry("mov", "FileType::Video")
  236. .entry("mp4", "FileType::Video")
  237. .entry("mpeg", "FileType::Video")
  238. .entry("mpg", "FileType::Video")
  239. .entry("ogm", "FileType::Video")
  240. .entry("ogv", "FileType::Video")
  241. .entry("vob", "FileType::Video")
  242. .entry("webm", "FileType::Video")
  243. .entry("wmv", "FileType::Video")
  244. /* Music files */
  245. .entry("aac", "FileType::Music")
  246. .entry("m4a", "FileType::Music")
  247. .entry("mka", "FileType::Music")
  248. .entry("mp2", "FileType::Music")
  249. .entry("mp3", "FileType::Music")
  250. .entry("ogg", "FileType::Music")
  251. .entry("opus", "FileType::Music")
  252. .entry("wma", "FileType::Music")
  253. /* Lossless music, rather than any other kind of data... */
  254. .entry("alac", "FileType::Lossless")
  255. .entry("ape", "FileType::Lossless")
  256. .entry("flac", "FileType::Lossless")
  257. .entry("wav", "FileType::Lossless")
  258. /* Cryptology files */
  259. .entry("asc", "FileType::Crypto")
  260. .entry("enc", "FileType::Crypto")
  261. .entry("gpg", "FileType::Crypto")
  262. .entry("p12", "FileType::Crypto")
  263. .entry("pfx", "FileType::Crypto")
  264. .entry("pgp", "FileType::Crypto")
  265. .entry("sig", "FileType::Crypto")
  266. .entry("signature", "FileType::Crypto")
  267. /* Document files */
  268. .entry("djvu", "FileType::Document")
  269. .entry("doc", "FileType::Document")
  270. .entry("docx", "FileType::Document")
  271. // .entry("dvi", "FileType::Document") // already an image format
  272. .entry("eml", "FileType::Document")
  273. // .entry("eps", "FileType::Document") // already an image format
  274. .entry("fotd", "FileType::Document")
  275. .entry("key", "FileType::Document")
  276. .entry("keynote", "FileType::Document")
  277. .entry("numbers", "FileType::Document")
  278. .entry("odp", "FileType::Document")
  279. .entry("odt", "FileType::Document")
  280. .entry("pages", "FileType::Document")
  281. .entry("pdf", "FileType::Document")
  282. .entry("ppt", "FileType::Document")
  283. .entry("pptx", "FileType::Document")
  284. .entry("rtf", "FileType::Document")
  285. .entry("xls", "FileType::Document")
  286. .entry("xlsx", "FileType::Document")
  287. /* Compressed/archive files */
  288. .entry("7z", "FileType::Compressed")
  289. .entry("a", "FileType::Compressed")
  290. .entry("ar", "FileType::Compressed")
  291. .entry("bz", "FileType::Compressed")
  292. .entry("bz2", "FileType::Compressed")
  293. .entry("cpio", "FileType::Compressed")
  294. .entry("deb", "FileType::Compressed")
  295. .entry("dmg", "FileType::Compressed")
  296. .entry("gz", "FileType::Compressed")
  297. .entry("iso", "FileType::Compressed")
  298. .entry("lz", "FileType::Compressed")
  299. .entry("lz4", "FileType::Compressed")
  300. .entry("lzh", "FileType::Compressed")
  301. .entry("lzma", "FileType::Compressed")
  302. .entry("lzo", "FileType::Compressed")
  303. .entry("par", "FileType::Compressed")
  304. .entry("rar", "FileType::Compressed")
  305. .entry("rpm", "FileType::Compressed")
  306. .entry("tar", "FileType::Compressed")
  307. .entry("taz", "FileType::Compressed")
  308. .entry("tbz", "FileType::Compressed")
  309. .entry("tbz2", "FileType::Compressed")
  310. .entry("tc", "FileType::Compressed")
  311. .entry("tgz", "FileType::Compressed")
  312. .entry("tlz", "FileType::Compressed")
  313. .entry("txz", "FileType::Compressed")
  314. .entry("tz", "FileType::Compressed")
  315. .entry("tzo", "FileType::Compressed")
  316. .entry("xz", "FileType::Compressed")
  317. .entry("z", "FileType::Compressed")
  318. .entry("zip", "FileType::Compressed")
  319. .entry("zst", "FileType::Compressed")
  320. /* Temporary files */
  321. .entry("bak", "FileType::Temp")
  322. .entry("bk", "FileType::Temp")
  323. .entry("bkp", "FileType::Temp")
  324. .entry("swn", "FileType::Temp")
  325. .entry("swo", "FileType::Temp")
  326. .entry("swp", "FileType::Temp")
  327. .entry("tmp", "FileType::Temp")
  328. /* Compiler output files */
  329. .entry("class", "FileType::Compiled")
  330. .entry("elc", "FileType::Compiled")
  331. .entry("hi", "FileType::Compiled")
  332. .entry("ko", "FileType::Compiled")
  333. .entry("o", "FileType::Compiled")
  334. .entry("pyc", "FileType::Compiled")
  335. .entry("zwc", "FileType::Compiled")
  336. .build()
  337. )
  338. }
  339. /// Generate mapping from full filenames to file type. This mapping should also contain all the
  340. /// "dot" directories that have a custom icon. See output/render/icons.rs for a partial list of
  341. /// icon constants.
  342. fn generate_filename_icon_map(file: &mut File) -> io::Result<()> {
  343. writeln!(file, "static FILENAME_ICONS: phf::Map<&'static str, char> = {};\n",
  344. phf_codegen::Map::new()
  345. .entry(".atom", "'\u{e764}'") // ๎ค
  346. .entry(".bashprofile", "'\u{e615}'") // ๎˜•
  347. .entry(".bashrc", "'\u{f489}'") // ๏’‰
  348. .entry(".emacs", "'\u{e632}'") // ๎˜ฒ
  349. .entry(".git", "'\u{f1d3}'") // ๏‡“
  350. .entry(".gitattributes", "'\u{f1d3}'") // ๏‡“
  351. .entry(".gitconfig", "'\u{f1d3}'") // ๏‡“
  352. .entry(".github", "'\u{f408}'") // ๏ˆ
  353. .entry(".gitignore", "'\u{f1d3}'") // ๏‡“
  354. .entry(".gitignore_global", "'\u{f1d3}'") // ๏‡“
  355. .entry(".gitmodules", "'\u{f1d3}'") // ๏‡“
  356. .entry(".idea", "'\u{e7b5}'") // ๎žต
  357. .entry(".rvm", "'\u{e21e}'") // ๎ˆž
  358. .entry(".Trash", "'\u{f1f8}'") // ๏‡ธ
  359. .entry(".vimrc", "'\u{e7c5}'") // ๎Ÿ…
  360. .entry(".vscode", "'\u{e70c}'") // ๎œŒ
  361. .entry(".zshrc", "'\u{f489}'") // ๏’‰
  362. .entry("bin", "'\u{e5fc}'") // ๎—ผ
  363. .entry("Cargo.lock", "'\u{e7a8}'") // ๎žจ
  364. .entry("config", "'\u{e5fc}'") // ๎—ผ
  365. .entry("docker-compose.yml", "'\u{f308}'") // ๏Œˆ
  366. .entry("Dockerfile", "'\u{f308}'") // ๏Œˆ
  367. .entry("ds_store", "'\u{f179}'") // ๏…น
  368. .entry("Earthfile", "'\u{f0ac}'") // ๏‚ฌ
  369. .entry("gitignore_global", "'\u{f1d3}'") // ๏‡“
  370. .entry("gitlab-ci.yml", "'\u{f296}'") // ๏Š–
  371. .entry("go.mod", "'\u{e626}'") // ๎˜ฆ
  372. .entry("go.sum", "'\u{e626}'") // ๎˜ฆ
  373. .entry("gradle", "'\u{e256}'") // ๎‰–
  374. .entry("gruntfile.coffee", "'\u{e611}'") // ๎˜‘
  375. .entry("gruntfile.js", "'\u{e611}'") // ๎˜‘
  376. .entry("gruntfile.ls", "'\u{e611}'") // ๎˜‘
  377. .entry("gulpfile.coffee", "'\u{e610}'") // ๎˜
  378. .entry("gulpfile.js", "'\u{e610}'") // ๎˜
  379. .entry("gulpfile.ls", "'\u{e610}'") // ๎˜
  380. .entry("hidden", "'\u{f023}'") // ๏€ฃ
  381. .entry("include", "'\u{e5fc}'") // ๎—ผ
  382. .entry("lib", "'\u{f121}'") // ๏„ก
  383. .entry("LICENSE", "'\u{f02d}'") // ๏€ญ
  384. .entry("localized", "'\u{f179}'") // ๏…น
  385. .entry("Makefile", "'\u{f489}'") // ๏’‰
  386. .entry("node_modules", "'\u{e718}'") // ๎œ˜
  387. .entry("npmignore", "'\u{e71e}'") // ๎œž
  388. .entry("PKGBUILD", "'\u{f303}'") // ๏Œƒ
  389. .entry("rubydoc", "'\u{e73b}'") // ๎œป
  390. .entry("Vagrantfile", "'\u{2371}'") // โฑ
  391. .entry("yarn.lock", "'\u{e718}'") // ๎œ˜
  392. .build()
  393. )
  394. }
  395. /// Generate mapping from lowercase file extension to icons. If an image, video, or audio
  396. /// extension is add also update the extension filetype map. See output/render/icons.rs for
  397. /// a partial list of icon constants.
  398. fn generate_extension_icon_map(file: &mut File) -> io::Result<()> {
  399. writeln!(file, "static EXTENSION_ICONS: phf::Map<&'static str, char> = {};\n",
  400. phf_codegen::Map::new()
  401. .entry("7z", "'\u{f410}'") // ๏
  402. .entry("a", "'\u{f17c}'") // ๏…ผ
  403. .entry("acc", "'\u{f001}'") // ๏€
  404. .entry("acf", "'\u{f1b6}'") // ๏†ถ
  405. .entry("ai", "'\u{e7b4}'") // ๎žด
  406. .entry("alac", "'\u{f001}'") // ๏€
  407. .entry("android", "'\u{e70e}'") // ๎œŽ
  408. .entry("ape", "'\u{f001}'") // ๏€
  409. .entry("apk", "'\u{e70e}'") // ๎œŽ
  410. .entry("apple", "'\u{f179}'") // ๏…น
  411. .entry("ar", "'\u{f410}'") // ๏
  412. .entry("arw", "'\u{f1c5}'") // ๏‡…
  413. .entry("asm", "'\u{e637}'") // ๎˜ท
  414. .entry("avi", "'\u{f03d}'") // ๏€ฝ
  415. .entry("avif", "'\u{f1c5}'") // ๏‡…
  416. .entry("avro", "'\u{e60b}'") // ๎˜‹
  417. .entry("awk", "'\u{f489}'") // ๏’‰
  418. .entry("bash", "'\u{f489}'") // ๏’‰
  419. .entry("bashrc", "'\u{f489}'") // ๏’‰
  420. .entry("bash_history", "'\u{f489}'") // ๏’‰
  421. .entry("bash_profile", "'\u{f489}'") // ๏’‰
  422. .entry("bat", "'\u{ebc4}'") // ๎ฏ„
  423. .entry("bats", "'\u{f489}'") // ๏’‰
  424. .entry("bib", "'\u{e69b}'") // ๎š›
  425. .entry("bin", "'\u{eae8}'") // ๎ซจ
  426. .entry("bmp", "'\u{f1c5}'") // ๏‡…
  427. .entry("bst", "'\u{e69b}'") // ๎š›
  428. .entry("bz", "'\u{f410}'") // ๏
  429. .entry("bz2", "'\u{f410}'") // ๏
  430. .entry("c", "'\u{e61e}'") // ๎˜ž
  431. .entry("c++", "'\u{e61d}'") // ๎˜
  432. .entry("cab", "'\u{e70f}'") // ๎œ
  433. .entry("cbr", "'\u{f1c5}'") // ๏‡…
  434. .entry("cbz", "'\u{f1c5}'") // ๏‡…
  435. .entry("cc", "'\u{e61d}'") // ๎˜
  436. .entry("cert", "'\u{eafa}'") // ๎ซบ
  437. .entry("cfg", "'\u{e615}'") // ๎˜•
  438. .entry("cjs", "'\u{e74e}'") // ๎Ž
  439. .entry("class", "'\u{e256}'") // ๎‰–
  440. .entry("clj", "'\u{e768}'") // ๎จ
  441. .entry("cljs", "'\u{e76a}'") // ๎ช
  442. .entry("cls", "'\u{e69b}'") // ๎š›
  443. .entry("cmd", "'\u{e70f}'") // ๎œ
  444. .entry("coffee", "'\u{f0f4}'") // ๏ƒด
  445. .entry("conf", "'\u{e615}'") // ๎˜•
  446. .entry("config", "'\u{e615}'") // ๎˜•
  447. .entry("cp", "'\u{e61d}'") // ๎˜
  448. .entry("cpio", "'\u{f410}'") // ๏
  449. .entry("cpp", "'\u{e61d}'") // ๎˜
  450. .entry("cr2", "'\u{f1c5}'") // ๏‡…
  451. .entry("crt", "'\u{eafa}'") // ๎ซบ
  452. .entry("cs", "'\u{f031b}'") // ๓ฐŒ›
  453. .entry("csh", "'\u{f489}'") // ๏’‰
  454. .entry("cshtml", "'\u{f1fa}'") // ๏‡บ
  455. .entry("csproj", "'\u{f031b}'") // ๓ฐŒ›
  456. .entry("css", "'\u{e749}'") // ๎‰
  457. .entry("csv", "'\u{f1c3}'") // ๏‡ƒ
  458. .entry("csx", "'\u{f031b}'") // ๓ฐŒ›
  459. .entry("cts", "'\u{e628}'") // ๎˜จ
  460. .entry("cu", "'\u{e64b}'") // ๎™‹
  461. .entry("cxx", "'\u{e61d}'") // ๎˜
  462. .entry("d", "'\u{e7af}'") // ๎žฏ
  463. .entry("dart", "'\u{e798}'") // ๎ž˜
  464. .entry("db", "'\u{f1c0}'") // ๏‡€
  465. .entry("deb", "'\u{e77d}'") // ๎ฝ
  466. .entry("desktop", "'\u{ebd1}'") // ๎ฏ‘
  467. .entry("diff", "'\u{f440}'") // ๏‘€
  468. .entry("djvu", "'\u{f02d}'") // ๏€ญ
  469. .entry("dll", "'\u{e70f}'") // ๎œ
  470. .entry("dmg", "'\u{e271}'") // ๎‰ฑ
  471. .entry("doc", "'\u{f1c2}'") // ๏‡‚
  472. .entry("docx", "'\u{f1c2}'") // ๏‡‚
  473. .entry("drawio", "'\u{ebba}'") // ๎ฎบ
  474. .entry("ds_store", "'\u{f179}'") // ๏…น
  475. .entry("dump", "'\u{f1c0}'") // ๎œ†
  476. .entry("dvi", "'\u{f1c5}'") // ๏‡…
  477. .entry("ebook", "'\u{e28b}'") // ๎Š‹
  478. .entry("ebuild", "'\u{f30d}'") // ๏Œ
  479. .entry("editorconfig", "'\u{e615}'") // ๎˜•
  480. .entry("ejs", "'\u{e618}'") // ๎˜˜
  481. .entry("el", "'\u{e632}'") // ๎˜ฒ
  482. .entry("elm", "'\u{e62c}'") // ๎˜ฌ
  483. .entry("eml", "'\u{f003}'") // ๏€ƒ
  484. .entry("env", "'\u{f462}'") // ๏‘ข
  485. .entry("eot", "'\u{f031}'") // ๏€ฑ
  486. .entry("eps", "'\u{f1c5}'") // ๏‡…
  487. .entry("epub", "'\u{e28a}'") // ๎ŠŠ
  488. .entry("erb", "'\u{e73b}'") // ๎œป
  489. .entry("erl", "'\u{e7b1}'") // ๎žฑ
  490. .entry("ex", "'\u{e62d}'") // ๎˜ญ
  491. .entry("exe", "'\u{f17a}'") // ๏…บ
  492. .entry("exs", "'\u{e62d}'") // ๎˜ญ
  493. .entry("fish", "'\u{f489}'") // ๏’‰
  494. .entry("flac", "'\u{f001}'") // ๏€
  495. .entry("flv", "'\u{f03d}'") // ๏€ฝ
  496. .entry("font", "'\u{f031}'") // ๏€ฑ
  497. .entry("fs", "'\u{e7a7}'") // ๎žง
  498. .entry("fsi", "'\u{e7a7}'") // ๎žง
  499. .entry("fsx", "'\u{e7a7}'") // ๎žง
  500. .entry("gdoc", "'\u{f1c2}'") // ๏‡‚
  501. .entry("gem", "'\u{e21e}'") // ๎ˆž
  502. .entry("gemfile", "'\u{e21e}'") // ๎ˆž
  503. .entry("gemspec", "'\u{e21e}'") // ๎ˆž
  504. .entry("gform", "'\u{f298}'") // ๏Š˜
  505. .entry("gif", "'\u{f1c5}'") // ๏‡…
  506. .entry("git", "'\u{f1d3}'") // ๏‡“
  507. .entry("gitattributes", "'\u{f1d3}'") // ๏‡“
  508. .entry("gitignore", "'\u{f1d3}'") // ๏‡“
  509. .entry("gitmodules", "'\u{f1d3}'") // ๏‡“
  510. .entry("go", "'\u{e626}'") // ๎˜ฆ
  511. .entry("gpg", "'\u{e60a}'") // ๎˜Š
  512. .entry("gradle", "'\u{e256}'") // ๎‰–
  513. .entry("groovy", "'\u{e775}'") // ๎ต
  514. .entry("gsheet", "'\u{f1c3}'") // ๏‡ƒ
  515. .entry("gslides", "'\u{f1c4}'") // ๏‡„
  516. .entry("guardfile", "'\u{e21e}'") // ๎ˆž
  517. .entry("gz", "'\u{f410}'") // ๏
  518. .entry("h", "'\u{f0fd}'") // ๏ƒฝ
  519. .entry("hbs", "'\u{e60f}'") // ๎˜
  520. .entry("heic", "'\u{f03d}'") // ๏€ฝ
  521. .entry("heif", "'\u{f1c5}'") // ๏‡…
  522. .entry("hpp", "'\u{f0fd}'") // ๏ƒฝ
  523. .entry("hs", "'\u{e777}'") // ๎ท
  524. .entry("htm", "'\u{f13b}'") // ๏„ป
  525. .entry("html", "'\u{f13b}'") // ๏„ป
  526. .entry("hxx", "'\u{f0fd}'") // ๏ƒฝ
  527. .entry("ical", "'\u{eab0}'") // ๏ณ
  528. .entry("icalendar", "'\u{eab0}'") // ๏ณ
  529. .entry("ico", "'\u{f1c5}'") // ๏‡…
  530. .entry("ics", "'\u{eab0}'") // ๏ณ
  531. .entry("ifb", "'\u{eab0}'") // ๏ณ
  532. .entry("image", "'\u{f1c5}'") // ๏‡…
  533. .entry("img", "'\u{e271}'") // ๎‰ฑ
  534. .entry("iml", "'\u{e7b5}'") // ๎žต
  535. .entry("ini", "'\u{f17a}'") // ๏…บ
  536. .entry("ipynb", "'\u{e678}'") // ๎™ธ
  537. .entry("iso", "'\u{e271}'") // ๎‰ฑ
  538. .entry("j2c", "'\u{f1c5}'") // ๏‡…
  539. .entry("j2k", "'\u{f1c5}'") // ๏‡…
  540. .entry("jad", "'\u{e256}'") // ๎‰–
  541. .entry("jar", "'\u{e256}'") // ๎‰–
  542. .entry("java", "'\u{e256}'") // ๎‰–
  543. .entry("jfi", "'\u{f1c5}'") // ๏‡…
  544. .entry("jfif", "'\u{f1c5}'") // ๏‡…
  545. .entry("jif", "'\u{f1c5}'") // ๏‡…
  546. .entry("jl", "'\u{e624}'") // ๎˜ค
  547. .entry("jmd", "'\u{f48a}'") // ๏’Š
  548. .entry("jp2", "'\u{f1c5}'") // ๏‡…
  549. .entry("jpe", "'\u{f1c5}'") // ๏‡…
  550. .entry("jpeg", "'\u{f1c5}'") // ๏‡…
  551. .entry("jpf", "'\u{f1c5}'") // ๏‡…
  552. .entry("jpg", "'\u{f1c5}'") // ๏‡…
  553. .entry("jpx", "'\u{f1c5}'") // ๏‡…
  554. .entry("js", "'\u{e74e}'") // ๎Ž
  555. .entry("json", "'\u{e60b}'") // ๎˜‹
  556. .entry("jsx", "'\u{e7ba}'") // ๎žบ
  557. .entry("jxl", "'\u{f1c5}'") // ๏‡…
  558. .entry("kdb", "'\u{f23e}'") // ๏ˆพ
  559. .entry("kdbx", "'\u{f23e}'") // ๏ˆพ
  560. .entry("key", "'\u{eb11}'") // ๎ฌ‘
  561. .entry("ko", "'\u{f17c}'") // ๏…ผ
  562. .entry("ksh", "'\u{f489}'") // ๏’‰
  563. .entry("latex", "'\u{e69b}'") // ๎š›
  564. .entry("less", "'\u{e758}'") // ๎˜
  565. .entry("lhs", "'\u{e777}'") // ๎ท
  566. .entry("license", "'\u{f02d}'") // ๏€ญ
  567. .entry("localized", "'\u{f179}'") // ๏…น
  568. .entry("lock", "'\u{f023}'") // ๏€ฃ
  569. .entry("log", "'\u{f18d}'") // ๏†
  570. .entry("lua", "'\u{e620}'") // ๎˜ 
  571. .entry("lz", "'\u{f410}'") // ๏
  572. .entry("lz4", "'\u{f410}'") // ๏
  573. .entry("lzh", "'\u{f410}'") // ๏
  574. .entry("lzma", "'\u{f410}'") // ๏
  575. .entry("lzo", "'\u{f410}'") // ๏
  576. .entry("m", "'\u{e61e}'") // ๎˜ž
  577. .entry("m2ts", "'\u{f03d}'") // ๏€ฝ
  578. .entry("m2v", "'\u{f03d}'") // ๏€ฝ
  579. .entry("m4a", "'\u{f001}'") // ๏€
  580. .entry("m4v", "'\u{f03d}'") // ๏€ฝ
  581. .entry("magnet", "'\u{f076}'") // ๏ถ
  582. .entry("markdown", "'\u{f48a}'") // ๏’Š
  583. .entry("md", "'\u{f48a}'") // ๏’Š
  584. .entry("mjs", "'\u{e74e}'") // ๎Ž
  585. .entry("mk", "'\u{f489}'") // ๏’‰
  586. .entry("mka", "'\u{f001}'") // ๏€
  587. .entry("mkd", "'\u{f48a}'") // ๏’Š
  588. .entry("mkv", "'\u{f03d}'") // ๏€ฝ
  589. .entry("ml", "'\u{e67a}'") // ๎™บ
  590. .entry("mli", "'\u{e67a}'") // ๎™บ
  591. .entry("mll", "'\u{e67a}'") // ๎™บ
  592. .entry("mly", "'\u{e67a}'") // ๎™บ
  593. .entry("mm", "'\u{e61d}'") // ๎˜
  594. .entry("mobi", "'\u{e28b}'") // ๎Š‹
  595. .entry("mov", "'\u{f03d}'") // ๏€ฝ
  596. .entry("mp2", "'\u{f001}'") // ๏€
  597. .entry("mp3", "'\u{f001}'") // ๏€
  598. .entry("mp4", "'\u{f03d}'") // ๏€ฝ
  599. .entry("mpeg", "'\u{f03d}'") // ๏€ฝ
  600. .entry("mpg", "'\u{f03d}'") // ๏€ฝ
  601. .entry("msi", "'\u{e70f}'") // ๎œ
  602. .entry("mts", "'\u{e628}'") // ๎˜จ
  603. .entry("mustache", "'\u{e60f}'") // ๎˜
  604. .entry("nef", "'\u{f1c5}'") // ๏‡…
  605. .entry("ninja", "'\u{f0774}'") // ๓ฐด
  606. .entry("nix", "'\u{f313}'") // ๏Œ“
  607. .entry("node", "'\u{f0399}'") // ๓ฐŽ™
  608. .entry("npmignore", "'\u{e71e}'") // ๎œž
  609. .entry("o", "'\u{eae8}'") // ๎ซจ
  610. .entry("odp", "'\u{f1c4}'") // ๏‡„
  611. .entry("ods", "'\u{f1c3}'") // ๏‡ƒ
  612. .entry("odt", "'\u{f1c2}'") // ๏‡‚
  613. .entry("ogg", "'\u{f001}'") // ๏€
  614. .entry("ogm", "'\u{f03d}'") // ๏€ฝ
  615. .entry("ogv", "'\u{f03d}'") // ๏€ฝ
  616. .entry("opus", "'\u{f001}'") // ๏€
  617. .entry("orf", "'\u{f1c5}'") // ๏‡…
  618. .entry("org", "'\u{e633}'") // ๎˜ณ
  619. .entry("otf", "'\u{f031}'") // ๏€ฑ
  620. .entry("out", "'\u{eb2c}'") // ๎ฌฌ
  621. .entry("par", "'\u{f410}'") // ๏
  622. .entry("part", "'\u{f43a}'") // ๏บ
  623. .entry("patch", "'\u{f440}'") // ๏‘€
  624. .entry("pbm", "'\u{f1c5}'") // ๏‡…
  625. .entry("pdf", "'\u{f1c1}'") // ๏‡
  626. .entry("pem", "'\u{eb11}'") // ๎ฌ‘
  627. .entry("pgm", "'\u{f1c5}'") // ๏‡…
  628. .entry("php", "'\u{e73d}'") // ๎œฝ
  629. .entry("pl", "'\u{e769}'") // ๎ฉ
  630. .entry("plx", "'\u{e769}'") // ๎ฉ
  631. .entry("pm", "'\u{e769}'") // ๎ฉ
  632. .entry("png", "'\u{f1c5}'") // ๏‡…
  633. .entry("pnm", "'\u{f1c5}'") // ๏‡…
  634. .entry("pod", "'\u{e769}'") // ๎ฉ
  635. .entry("ppm", "'\u{f1c5}'") // ๏‡…
  636. .entry("ppt", "'\u{f1c4}'") // ๏‡„
  637. .entry("pptx", "'\u{f1c4}'") // ๏‡„
  638. .entry("procfile", "'\u{e21e}'") // ๎ˆž
  639. .entry("properties", "'\u{e60b}'") // ๎˜‹
  640. .entry("ps", "'\u{f1c5}'") // ๏‡…
  641. .entry("ps1", "'\u{ebc7}'") // ๎ฏ‡
  642. .entry("psd", "'\u{e7b8}'") // ๎žธ
  643. .entry("psd1", "'\u{ebc7}'") // ๎ฏ‡
  644. .entry("psm1", "'\u{ebc7}'") // ๎ฏ‡
  645. .entry("pxm", "'\u{f1c5}'") // ๏‡…
  646. .entry("py", "'\u{e606}'") // ๎˜†
  647. .entry("pyc", "'\u{e606}'") // ๎˜†
  648. .entry("qcow2", "'\u{e271}'") // ๎‰ฑ
  649. .entry("r", "'\u{f25d}'") // ๏‰
  650. .entry("rakefile", "'\u{e21e}'") // ๎ˆž
  651. .entry("rar", "'\u{f410}'") // ๏
  652. .entry("raw", "'\u{f1c5}'") // ๏‡…
  653. .entry("razor", "'\u{f1fa}'") // ๏‡บ
  654. .entry("rb", "'\u{e21e}'") // ๎ˆž
  655. .entry("rdata", "'\u{f25d}'") // ๏‰
  656. .entry("rdb", "'\u{e76d}'") // ๎ญ
  657. .entry("rdoc", "'\u{f48a}'") // ๏’Š
  658. .entry("rds", "'\u{f25d}'") // ๏‰
  659. .entry("readme", "'\u{f48a}'") // ๏’Š
  660. .entry("rlib", "'\u{e7a8}'") // ๎žจ
  661. .entry("rmd", "'\u{f48a}'") // ๏’Š
  662. .entry("rmeta", "'\u{e7a8}'") // ๎žจ
  663. .entry("rpm", "'\u{e7bb}'") // ๎žป
  664. .entry("rs", "'\u{e7a8}'") // ๎žจ
  665. .entry("rspec", "'\u{e21e}'") // ๎ˆž
  666. .entry("rspec_parallel","'\u{e21e}'") // ๎ˆž
  667. .entry("rspec_status", "'\u{e21e}'") // ๎ˆž
  668. .entry("rss", "'\u{f09e}'") // ๏‚ž
  669. .entry("rst", "'\u{f15c}'") // ๏…œ
  670. .entry("rtf", "'\u{f0219}'") // ๓ฐˆ™
  671. .entry("ru", "'\u{e21e}'") // ๎ˆž
  672. .entry("rubydoc", "'\u{e73b}'") // ๎œป
  673. .entry("s", "'\u{e637}'") // ๎˜ท
  674. .entry("sass", "'\u{e603}'") // ๎˜ƒ
  675. .entry("scala", "'\u{e737}'") // ๎œท
  676. .entry("scss", "'\u{e749}'") // ๎‰
  677. .entry("service", "'\u{eba2}'") // ๎ฎข
  678. .entry("sh", "'\u{f489}'") // ๏’‰
  679. .entry("shell", "'\u{f489}'") // ๏’‰
  680. .entry("slim", "'\u{e73b}'") // ๎œป
  681. .entry("sln", "'\u{e70c}'") // ๎œŒ
  682. .entry("so", "'\u{f17c}'") // ๏…ผ
  683. .entry("sql", "'\u{f1c0}'") // ๎œ†
  684. .entry("sqlite3", "'\u{e7c4}'") // ๎Ÿ„
  685. .entry("stl", "'\u{f1c5}'") // ๏‡…
  686. .entry("sty", "'\u{e69b}'") // ๎š›
  687. .entry("styl", "'\u{e600}'") // ๎˜€
  688. .entry("stylus", "'\u{e600}'") // ๎˜€
  689. .entry("svelte", "'\u{e697}'") // ๎š—
  690. .entry("svg", "'\u{f1c5}'") // ๏‡…
  691. .entry("swift", "'\u{e755}'") // ๎•
  692. .entry("t", "'\u{e769}'") // ๎ฉ
  693. .entry("tar", "'\u{f410}'") // ๏
  694. .entry("taz", "'\u{f410}'") // ๏
  695. .entry("tbz", "'\u{f410}'") // ๏
  696. .entry("tbz2", "'\u{f410}'") // ๏
  697. .entry("tc", "'\u{f410}'") // ๏
  698. .entry("tex", "'\u{e69b}'") // ๎š›
  699. .entry("tgz", "'\u{f410}'") // ๏
  700. .entry("tif", "'\u{f1c5}'") // ๏‡…
  701. .entry("tiff", "'\u{f1c5}'") // ๏‡…
  702. .entry("tlz", "'\u{f410}'") // ๏
  703. .entry("toml", "'\u{e615}'") // ๎˜•
  704. .entry("torrent", "'\u{e275}'") // ๎‰ต
  705. .entry("ts", "'\u{e628}'") // ๎˜จ
  706. .entry("tsv", "'\u{f1c3}'") // ๏‡ƒ
  707. .entry("tsx", "'\u{e7ba}'") // ๎žบ
  708. .entry("ttf", "'\u{f031}'") // ๏€ฑ
  709. .entry("twig", "'\u{e61c}'") // ๎˜œ
  710. .entry("txt", "'\u{f15c}'") // ๏…œ
  711. .entry("txz", "'\u{f410}'") // ๏
  712. .entry("tz", "'\u{f410}'") // ๏
  713. .entry("tzo", "'\u{f410}'") // ๏
  714. .entry("unity", "'\u{e721}'") // ๎œก
  715. .entry("unity3d", "'\u{e721}'") // ๎œก
  716. .entry("vdi", "'\u{e271}'") // ๎‰ฑ
  717. .entry("vhd", "'\u{e271}'") // ๎‰ฑ
  718. .entry("video", "'\u{f03d}'") // ๏€ฝ
  719. .entry("vim", "'\u{e7c5}'") // ๎Ÿ…
  720. .entry("vmdk", "'\u{e271}'") // ๎‰ฑ
  721. .entry("vob", "'\u{f03d}'") // ๏€ฝ
  722. .entry("vue", "'\u{f0844}'") // ๓ฐก„
  723. .entry("war", "'\u{e256}'") // ๎‰–
  724. .entry("wav", "'\u{f001}'") // ๏€
  725. .entry("webm", "'\u{f03d}'") // ๏€ฝ
  726. .entry("webp", "'\u{f1c5}'") // ๏‡…
  727. .entry("windows", "'\u{f17a}'") // ๏…บ
  728. .entry("wma", "'\u{f001}'") // ๏€
  729. .entry("wmv", "'\u{f03d}'") // ๏€ฝ
  730. .entry("woff", "'\u{f031}'") // ๏€ฑ
  731. .entry("woff2", "'\u{f031}'") // ๏€ฑ
  732. .entry("xhtml", "'\u{f13b}'") // ๏„ป
  733. .entry("xls", "'\u{f1c3}'") // ๏‡ƒ
  734. .entry("xlsm", "'\u{f1c3}'") // ๏‡ƒ
  735. .entry("xlsx", "'\u{f1c3}'") // ๏‡ƒ
  736. .entry("xml", "'\u{f05c0}'") // ๓ฐ—€
  737. .entry("xpm", "'\u{f1c5}'") // ๏‡…
  738. .entry("xul", "'\u{f05c0}'") // ๓ฐ—€
  739. .entry("xz", "'\u{f410}'") // ๏
  740. .entry("yaml", "'\u{f481}'") // ๏’
  741. .entry("yml", "'\u{f481}'") // ๏’
  742. .entry("z", "'\u{f410}'") // ๏
  743. .entry("zig", "'\u{21af}'") // โ†ฏ
  744. .entry("zip", "'\u{f410}'") // ๏
  745. .entry("zsh", "'\u{f489}'") // ๏’‰
  746. .entry("zsh-theme", "'\u{f489}'") // ๏’‰
  747. .entry("zshrc", "'\u{f489}'") // ๏’‰
  748. .entry("zst", "'\u{f410}'") // ๏
  749. .build()
  750. )
  751. }