]> Sergey Matveev's repositories - nnn.git/commitdiff
Revise and optimize icons handling
authorNRK <nrk@disroot.org>
Wed, 20 Jul 2022 09:57:05 +0000 (15:57 +0600)
committerNRK <nrk@disroot.org>
Fri, 22 Jul 2022 11:08:42 +0000 (17:08 +0600)
This pretty much reworks the entire icon system. Some notable changes:

* The extensions are put into a statically generated hash-table instead
  of a sorted array. We use Robin-Hood insertion to reduce the max probe
  length. Currently we need to probe only 2 slots for `O_EMOJI` and only
  3 for `O_NERD`/`O_ICONS`.
* I've opted not to use a perfect-hash since the perfect hashes
  generated by [`gperf`](https://www.gnu.org/software/gperf) used some
  huge lookup table. The hash function also wasn't as minimal as I'd
  like.
* Colors are now using X-Macros. This should speed up startup since we
  don't have to search `icons_ext` linearly to find unique colors.
* The hash-table generator outputs a more space optimized `struct
  icon_pair` using a char array instead of char pointer. This brings
  down the binary size from `145KiB` when using `O_NERD` down to
  `137KiB`.
* Some unnecessary duplication and indirection has been reduced by using
  the `ICON_STR()` macro.

.gitignore
Makefile
src/icons-emoji.h [deleted file]
src/icons-hash.c [new file with mode: 0644]
src/icons-nerdfont.h [deleted file]
src/icons.h
src/nnn.c

index a023af708e8ab5b7ed5259af2d1e3ac9a9261e4b..5a584b3308138697e8b0b4f0cd50b04ecd998534 100644 (file)
@@ -1,3 +1,5 @@
 *.o
 *.dSYM
 nnn
+src/icons-generated.h
+src/icons-hash-gen
index 3eaa28b78fae7574cc6c7e2cb698fbc8c8d30201..2294b18fcdec42280f0ffb30020f9cc6f728939f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -95,7 +95,7 @@ ifeq ($(strip $(O_CTX8)),1)
 endif
 
 ifeq ($(strip $(O_ICONS)),1)
-       CPPFLAGS += -DICONS
+       CPPFLAGS += -DICONS_IN_TERM
 endif
 
 ifeq ($(strip $(O_NERD)),1)
@@ -187,17 +187,17 @@ endif
 ifeq ($(strip $(O_DEBUG)),1)
        HEADERS += src/dbg.h
 endif
+ifeq ($(strip $(O_QSORT)),1)
+       HEADERS += src/qsort.h
+endif
 ifeq ($(strip $(O_EMOJI)),1)
-       HEADERS += src/icons.h src/icons-emoji.h
+       HEADERS += src/icons.h src/icons-generated.h
 endif
 ifeq ($(strip $(O_NERD)),1)
-       HEADERS += src/icons.h src/icons-nerdfont.h
+       HEADERS += src/icons.h src/icons-generated.h
 endif
 ifeq ($(strip $(O_ICONS)),1)
-       HEADERS += src/icons.h src/icons-in-terminal.h
-endif
-ifeq ($(strip $(O_QSORT)),1)
-       HEADERS += src/qsort.h
+       HEADERS += src/icons.h src/icons-generated.h src/icons-in-terminal.h
 endif
 
 all: $(BIN)
@@ -207,6 +207,11 @@ $(BIN): $(SRC) $(HEADERS) Makefile
        $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $(GETTIME_C) $< $(LDLIBS)
        @$(MAKE) --silent postpatch
 
+src/icons-generated.h: src/icons-hash-gen
+       @./$< > $@
+src/icons-hash-gen: src/icons-hash.c src/nnn.c src/icons.h src/nnn.h
+       $(CC) $(CPPFLAGS) -DICONS_GENERATE -o $@ src/icons-hash.c
+
 # targets for backwards compatibility
 debug: $(BIN)
 norl: $(BIN)
@@ -313,7 +318,7 @@ upload-local: sign static musl
            --upload-file $(BIN)-musl-static-$(VERSION).x86_64.tar.gz
 
 clean:
-       $(RM) -f $(BIN) nnn-$(VERSION).tar.gz *.sig $(BIN)-static $(BIN)-static-$(VERSION).x86_64.tar.gz $(BIN)-icons-static $(BIN)-icons-static-$(VERSION).x86_64.tar.gz $(BIN)-nerd-static $(BIN)-nerd-static-$(VERSION).x86_64.tar.gz $(BIN)-emoji-static $(BIN)-emoji-static-$(VERSION).x86_64.tar.gz $(BIN)-musl-static $(BIN)-musl-static-$(VERSION).x86_64.tar.gz
+       $(RM) -f $(BIN) nnn-$(VERSION).tar.gz *.sig $(BIN)-static $(BIN)-static-$(VERSION).x86_64.tar.gz $(BIN)-icons-static $(BIN)-icons-static-$(VERSION).x86_64.tar.gz $(BIN)-nerd-static $(BIN)-nerd-static-$(VERSION).x86_64.tar.gz $(BIN)-emoji-static $(BIN)-emoji-static-$(VERSION).x86_64.tar.gz $(BIN)-musl-static $(BIN)-musl-static-$(VERSION).x86_64.tar.gz src/icons-hash-gen src/icons-generated.h
 
 checkpatches:
        ./patches/check-patches.sh
diff --git a/src/icons-emoji.h b/src/icons-emoji.h
deleted file mode 100644 (file)
index fc07b25..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-#ifndef ICONS_EMOJI
-#define ICONS_EMOJI
-
-// You can find a list of emoji here:
-// https://unicode.org/Public/emoji/5.0/emoji-test.txt
-
-// Note: As some emoji are stored as two characters, all of these strings must
-// be of width 2. Therefore, right pad single-width emoji with a space.
-
-#define MD_ARROW_UPWARD    "⬆"
-#define MD_ARROW_FORWARD   "➑"
-#define MD_ARROW_DOWNWARD  "⬇"
-
-#define EMOJI_ARCHIVE "πŸ“¦"
-#define EMOJI_AUDIO "🎧"
-#define EMOJI_BINARY "πŸ““"
-#define EMOJI_BRIEFCASE "πŸ’Ό"
-#define EMOJI_C "πŸ‡¨ "
-#define EMOJI_CHANGELOG "πŸ”Ί"
-#define EMOJI_CONF "πŸ”§"
-#define EMOJI_CPP EMOJI_C
-#define EMOJI_DATABASE "πŸ—ƒοΈ "
-#define EMOJI_DESKTOP "πŸ–₯️ "
-#define EMOJI_DIFF "πŸ“‹"
-#define EMOJI_DISK "πŸ’Ώ"
-#define EMOJI_DOWNLOAD "πŸ“₯"
-#define EMOJI_ENCRYPTED "πŸ”’"
-#define EMOJI_EXEC "βš™οΈ "
-#define EMOJI_FILE "πŸ“ƒ"
-#define EMOJI_FOLDER "πŸ“‚"
-#define EMOJI_GIT "🌱"
-#define EMOJI_IMAGE "🎨"
-#define EMOJI_INFO "ℹ️ "
-#define EMOJI_JAVA "β˜•"
-#define EMOJI_JAVASCRIPT EMOJI_SCRIPT
-#define EMOJI_LICENSE "βš–οΈ "
-#define EMOJI_LINUX "🐧"
-#define EMOJI_LOCK "πŸ”’"
-#define EMOJI_LUA "🌘"
-#define EMOJI_MAKE "πŸ›  "
-#define EMOJI_MANUAL "❓"
-#define EMOJI_MOVIE "🎞 "
-#define EMOJI_MUSIC EMOJI_AUDIO
-#define EMOJI_NOTE "πŸ“"
-#define EMOJI_PATCH "🩹"
-#define EMOJI_PDF "πŸ“•"
-#define EMOJI_PHOTO "πŸ“Έ"
-#define EMOJI_PICTURE EMOJI_IMAGE
-#define EMOJI_PRESENTATION "πŸ“Š"
-#define EMOJI_PUBLIC "πŸ‘€"
-#define EMOJI_PYTHON "🐍"
-#define EMOJI_RSS "πŸ“‘"
-#define EMOJI_RUBY "πŸ’Ž"
-#define EMOJI_SCRIPT "πŸ“œ"
-#define EMOJI_STATS "πŸ“Š"
-#define EMOJI_STYLESHEET "πŸ¦‹"
-#define EMOJI_SUBTITLES "πŸ’¬"
-#define EMOJI_TABLE "πŸ“—"
-#define EMOJI_TEMPLATE "πŸ“Ž"
-#define EMOJI_TEXT "πŸ—’ "
-#define EMOJI_UNI "πŸ›οΈ "
-#define EMOJI_VECTOR "πŸ—ΊοΈ "
-#define EMOJI_WEB "🌐"
-#define EMOJI_WINDOWS "πŸͺŸ"
-#define EMOJI_WORD "πŸ“˜"
-#define EMOJI_WORK EMOJI_UNI
-
-#endif // ICONS_EMOJI
diff --git a/src/icons-hash.c b/src/icons-hash.c
new file mode 100644 (file)
index 0000000..70a5d1c
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * simple program which outputs a hash-table of `icons_ext` with low collusion.
+ * the hash function is case-insensitive, it also doesn't hash beyond the
+ * length of the longest extension.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define GOLDEN_RATIO_16 40503u /* golden ratio for 16bits: (2^16) / 1.61803 */
+#define ICONS_TABLE_SIZE 8 /* size in bits. 8 = 256 */
+
+#ifdef ICONS_GENERATE
+
+#define ICONS_PROBE_MAX_ALLOWED 6
+#define ICONS_MATCH_MAX ((size_t)-1)
+
+#ifdef NDEBUG
+       #error "NDEBUG"
+#endif
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include "icons.h"
+
+#define ASSERT(X) assert(X)
+#define ARRLEN(X) (sizeof(X) / sizeof((X)[0]))
+#define MAX(A, B) ((A) > (B) ? (A) : (B))
+#define HGEN_ITERARATION (1ul << 14)
+#if 0 /* enable for debugging */
+       #define log(...)  fprintf(stderr, "[INFO]: " __VA_ARGS__)
+#else
+       #define log(...) ((void)0)
+#endif
+
+static uint16_t icon_ext_hash(const char *s);
+
+/* change ICONS_TABLE_SIZE to increase the size of the table */
+static struct icon_pair table[1u << ICONS_TABLE_SIZE];
+static uint16_t seen[ARRLEN(table)];
+static uint16_t hash_start = 7; /* arbitrarily picked. change if needed. but ensure it's above 1 */
+static uint16_t hash_mul = 251; /* same as above ^ */
+
+/*
+ * use robin-hood insertion to reduce the max probe length
+ */
+static void
+rh_insert(const struct icon_pair item, uint32_t idx, uint32_t n)
+{
+       assert(n != 0);
+       for (uint32_t tries = 0; tries < ARRLEN(table); ++tries, ++n) {
+               if (seen[idx] < n) {
+                       struct icon_pair tmp_item = table[idx];
+                       uint32_t tmp_n = seen[idx];
+
+                       table[idx] = item;
+                       seen[idx] = n;
+
+                       if (tmp_n != 0) /* the slot we inserted to wasn't empty */
+                               rh_insert(tmp_item, idx, tmp_n);
+                       return;
+               }
+               idx = (idx + 1) % ARRLEN(table);
+       }
+       assert(0); /* unreachable */
+}
+
+static unsigned int
+table_populate(void)
+{
+       memset(seen, 0x0, sizeof seen);
+       memset(table, 0x0, sizeof table);
+       for (size_t i = 0; i < ARRLEN(icons_ext); ++i) {
+               if (icons_ext[i].icon[0] == '\0') continue;
+               uint32_t h = icon_ext_hash(icons_ext[i].match);
+               rh_insert(icons_ext[i], h, 1);
+       }
+
+       unsigned int max_try = 0;
+       for (size_t i = 0; i < ARRLEN(seen); ++i) {
+               if (seen[i] > max_try) max_try = seen[i];
+       }
+       return max_try;
+}
+
+int
+main(void)
+{
+       assert(ARRLEN(icons_ext) <= ARRLEN(table));
+       assert(ICONS_TABLE_SIZE < 16); /* the hash function only supports upto 16 bits */
+       assert(1u << ICONS_TABLE_SIZE == ARRLEN(table));
+       assert((GOLDEN_RATIO_16 & 1) == 1); /* must be odd */
+       assert(hash_start > 1); assert(hash_mul > 1);
+       /* ensure power of 2 hashtable size which allows compiler to optimize
+        * away mod (`%`) operations
+        */
+       assert((ARRLEN(table) & (ARRLEN(table) - 1)) == 0);
+
+       unsigned int max_probe = (unsigned)-1;
+       uint16_t best_hash_start, best_hash_mul;
+
+       for (size_t i = 0; i < HGEN_ITERARATION; ++i) {
+               unsigned z = table_populate();
+               if (z < max_probe) {
+                       max_probe = z;
+                       best_hash_start = hash_start;
+                       best_hash_mul = hash_mul;
+               }
+               hash_start *= GOLDEN_RATIO_16;
+               hash_mul *= GOLDEN_RATIO_16;
+       }
+       assert(max_probe < ICONS_PROBE_MAX_ALLOWED);
+       hash_start = best_hash_start;
+       hash_mul = best_hash_mul;
+       {
+               unsigned tmp = table_populate();
+               assert(tmp == max_probe);
+       }
+
+       /* sanity check */
+       for (size_t i = 0; i < ARRLEN(icons_ext); ++i) {
+               if (icons_ext[i].icon[0] == 0) continue;
+               uint16_t found = 0, h = icon_ext_hash(icons_ext[i].match);
+               for (uint16_t k = 0; k < max_probe; ++k) {
+                       uint16_t z = (h + k) % ARRLEN(table);
+                       if (table[z].match && strcmp(icons_ext[i].match, table[z].match) == 0) {
+                               found = 1;
+                       }
+               }
+               assert(found);
+       }
+
+       log("hash_start: %u\n", (unsigned)hash_start);
+       log("hash_mul  : %u\n", (unsigned)hash_mul);
+       log("max_probe : %u\n", max_probe);
+
+       printf("#ifndef INCLUDE_ICONS_GENERATED\n");
+       printf("#define INCLUDE_ICONS_GENERATED\n\n");
+
+       printf("/*\n * NOTE: This file is automatically generated.\n");
+       printf(" * DO NOT EDIT THIS FILE DIRECTLY.\n");
+       printf(" * Use `icons.h` to customize icons\n */\n\n");
+
+       printf("#define hash_start %uu\n", hash_start);
+       printf("#define hash_mul   %uu\n\n", hash_mul);
+
+       size_t match_max = 0, icon_max = 0;
+       for (size_t i = 0; i < ARRLEN(icons_name); ++i) {
+               match_max = MAX(match_max, strlen(icons_name[i].match) + 1);
+               icon_max = MAX(icon_max, strlen(icons_name[i].icon) + 1);
+       }
+       for (size_t i = 0; i < ARRLEN(icons_ext); ++i) {
+               match_max = MAX(match_max, strlen(icons_ext[i].match) + 1);
+               icon_max = MAX(icon_max, strlen(icons_ext[i].icon) + 1);
+       }
+       icon_max = MAX(icon_max, strlen(dir_icon.icon) + 1);
+       icon_max = MAX(icon_max, strlen(exec_icon.icon) + 1);
+       icon_max = MAX(icon_max, strlen(file_icon.icon) + 1);
+
+       printf("#define ICONS_PROBE_MAX %u\n", max_probe);
+       printf("#define ICONS_MATCH_MAX %zuu\n\n", match_max);
+
+       printf("struct icon_pair { const char match[%zu]; const char icon[%zu]; unsigned char color; };\n\n",
+              match_max, icon_max);
+
+       printf("static const struct icon_pair icons_ext[%zu] = {\n", ARRLEN(table));
+       for (size_t i = 0; i < ARRLEN(table); ++i) {
+               if (table[i].icon == NULL || table[i].icon[0] == '\0') /* skip empty entries */
+                       continue;
+               printf("\t[%u] = {\"%s\", \"%s\", %d },\n",
+                      (unsigned)i, table[i].match, table[i].icon,
+                      (unsigned)table[i].color);
+       }
+       printf("};\n\n");
+
+       printf("#endif /* INCLUDE_ICONS_GENERATED */\n");
+}
+
+#else
+       #define ASSERT(X) ((void)0)
+#endif /* ICONS_GENERATE */
+
+#ifndef TOUPPER
+       #define TOUPPER(ch)     (((ch) >= 'a' && (ch) <= 'z') ? ((ch) - 'a' + 'A') : (ch))
+#endif
+
+static uint16_t
+icon_ext_hash(const char *str)
+{
+       const unsigned int z = 16 - ICONS_TABLE_SIZE; /* 16 == size of `hash` in bits */
+       uint16_t hash = hash_start;
+       for (size_t i = 0; i < ICONS_MATCH_MAX && str[i] != '\0'; ++i) {
+               hash ^= TOUPPER((unsigned char)str[i]) + (i << 3);
+               hash *= hash_mul;
+       }
+       hash = (hash >> z) ^ hash;
+       hash *= GOLDEN_RATIO_16;
+       hash >>= z;
+       ASSERT(hash < ARRLEN(table));
+       return hash;
+}
diff --git a/src/icons-nerdfont.h b/src/icons-nerdfont.h
deleted file mode 100644 (file)
index 53077b4..0000000
+++ /dev/null
@@ -1,276 +0,0 @@
-#ifndef ICONS_NERDFONT
-#define ICONS_NERDFONT
-
-// You can find hex codes for nerd fonts here
-// https://www.nerdfonts.com/cheat-sheet
-
-// Arrows
-#define MD_ARROW_UPWARD    "\uf55c"
-#define MD_ARROW_FORWARD   "\uf553"
-#define MD_ARROW_DOWNWARD  "\uf544"
-
-// Generics
-#define ICON_DIRECTORY     "\ue5ff"
-#define ICON_FILE          "\uf713"
-#define ICON_EXEC          "\uf144"
-#define ICON_MANUAL        "\uf5bd"
-
-// Top level and common icons
-#define ICON_ARCHIVE       "\uf53b"
-#define ICON_BRIEFCASE     "\uf5d5"
-#define ICON_C             "\ue61e"
-#define ICON_CHANGELOG     "\uf7d9"
-#define ICON_CHESS         "\uf639"
-#define ICON_CLOJURE       "\ue76a"
-#define ICON_CONFIGURE     "\uf423"
-#define ICON_CPLUSPLUS     "\ue61d"
-#define ICON_DATABASE      "\uf6b7"
-#define ICON_DESKTOP       "\ufcbe"
-#define ICON_DOCUMENT      "\uf718"
-#define ICON_DOWNLOADS     "\uf5d7"
-#define ICON_ENCRYPT       "\uf805"
-#define ICON_FSHARP        "\ue7a7"
-#define ICON_GIT           "\ue5fb"
-#define ICON_HASKELL       "\ue777"
-#define ICON_HTML          "\uf72d"
-#define ICON_JAVA          "\ue738"
-#define ICON_JAVASCRIPT    "\uf81d"
-#define ICON_LICENSE       "\uf718"
-#define ICON_LINUX         "\uf83c"
-#define ICON_MAKEFILE      "\uf68c"
-#define ICON_MUSIC         "\uf832"
-#define ICON_MUSICFILE     "\uf886"
-#define ICON_OPTICALDISK   "\ue271"
-#define ICON_PICTUREFILE   "\uf71e"
-#define ICON_PICTURES      "\uf753"
-#define ICON_PLAYLIST      "\uf910"
-#define ICON_PUBLIC        "\ue5ff"
-#define ICON_PYTHON        "\ue235"
-#define ICON_REACT         "\ue625"
-#define ICON_RUBY          "\ue23e"
-#define ICON_SCRIPT        "\ue795"
-#define ICON_TEMPLATES     "\ufac6"
-#define ICON_TEX           "\ufb68"
-#define ICON_VIDEOFILE     "\uf72a"
-#define ICON_VIDEOS        "\uf72f"
-#define ICON_WORDDOC       "\uf72b"
-
-
-/* Numbers */
-#define ICON_EXT_1         ICON_MANUAL
-#define ICON_EXT_7Z        ICON_ARCHIVE
-
-/* A */
-#define ICON_EXT_A         ICON_MANUAL
-#define ICON_EXT_APK       ICON_ARCHIVE
-#define ICON_EXT_ASM       ICON_FILE
-#define ICON_EXT_AUP       ICON_MUSICFILE
-#define ICON_EXT_AVI       ICON_VIDEOFILE
-
-/* B */
-#define ICON_EXT_BAT       ICON_SCRIPT
-#define ICON_EXT_BIB       ICON_TEX
-#define ICON_EXT_BIN       "\uf471"
-#define ICON_EXT_BMP       ICON_PICTUREFILE
-#define ICON_EXT_BZ2       ICON_ARCHIVE
-
-/* C */
-#define ICON_EXT_C         ICON_C
-#define ICON_EXT_CPLUSPLUS ICON_CPLUSPLUS
-#define ICON_EXT_CAB       ICON_ARCHIVE
-#define ICON_EXT_CABAL     ICON_HASKELL
-#define ICON_EXT_CBR       ICON_ARCHIVE
-#define ICON_EXT_CBZ       ICON_ARCHIVE
-#define ICON_EXT_CC        ICON_CPLUSPLUS
-#define ICON_EXT_CLASS     ICON_JAVA
-#define ICON_EXT_CLJ       ICON_CLOJURE
-#define ICON_EXT_CLJC      ICON_CLOJURE
-#define ICON_EXT_CLJS      ICON_CLOJURE
-#define ICON_EXT_CLS       ICON_TEX
-#define ICON_EXT_CMAKE     ICON_MAKEFILE
-#define ICON_EXT_COFFEE    "\ue751"
-#define ICON_EXT_CONF      ICON_CONFIGURE
-#define ICON_EXT_CPIO      ICON_ARCHIVE
-#define ICON_EXT_CPP       ICON_CPLUSPLUS
-#define ICON_EXT_CSS       "\ue749"
-#define ICON_EXT_CUE       ICON_PLAYLIST
-#define ICON_EXT_CVS       ICON_CONFIGURE
-#define ICON_EXT_CXX       ICON_CPLUSPLUS
-
-/* D */
-#define ICON_EXT_DB        ICON_DATABASE
-#define ICON_EXT_DEB       "\ue77d"
-#define ICON_EXT_DIFF      "\uf440"
-#define ICON_EXT_DLL       ICON_SCRIPT
-#define ICON_EXT_DOC       ICON_WORDDOC
-#define ICON_EXT_DOCX      ICON_WORDDOC
-
-/* E */
-#define ICON_EXT_EJS       ICON_JAVASCRIPT
-#define ICON_EXT_ELF       ICON_LINUX
-#define ICON_EXT_EPUB      ICON_MANUAL
-#define ICON_EXT_EXE       ICON_EXEC
-
-/* F */
-#define ICON_EXT_FEN       ICON_CHESS
-#define ICON_EXT_FSHARP    ICON_FSHARP
-#define ICON_EXT_FLAC      ICON_MUSICFILE
-#define ICON_EXT_FLV       ICON_VIDEOFILE
-#define ICON_EXT_FS        ICON_FSHARP
-#define ICON_EXT_FSI       ICON_FSHARP
-#define ICON_EXT_FSSCRIPT  ICON_FSHARP
-#define ICON_EXT_FSX       ICON_FSHARP
-
-/* G */
-#define ICON_EXT_GEM       ICON_RUBY
-#define ICON_EXT_GIF       ICON_PICTUREFILE
-#define ICON_EXT_GO        "\ufcd1"
-#define ICON_EXT_GPG       ICON_ENCRYPT
-#define ICON_EXT_GZ        ICON_ARCHIVE
-#define ICON_EXT_GZIP      ICON_ARCHIVE
-
-/* H */
-#define ICON_EXT_H         ICON_C
-#define ICON_EXT_HH        ICON_CPLUSPLUS
-#define ICON_EXT_HPP       ICON_CPLUSPLUS
-#define ICON_EXT_HS        ICON_HASKELL
-#define ICON_EXT_HTACCESS  ICON_CONFIGURE
-#define ICON_EXT_HTPASSWD  ICON_CONFIGURE
-#define ICON_EXT_HTM       ICON_HTML
-#define ICON_EXT_HTML      ICON_HTML
-#define ICON_EXT_HXX       ICON_CPLUSPLUS
-
-/* I */
-#define ICON_EXT_ICO       ICON_PICTUREFILE
-#define ICON_EXT_IMG       ICON_OPTICALDISK
-#define ICON_EXT_INI       ICON_CONFIGURE
-#define ICON_EXT_ISO       ICON_OPTICALDISK
-
-/* J */
-#define ICON_EXT_JAR       ICON_JAVA
-#define ICON_EXT_JAVA      ICON_JAVA
-#define ICON_EXT_JL        ICON_CONFIGURE
-#define ICON_EXT_JPEG      ICON_PICTUREFILE
-#define ICON_EXT_JPG       ICON_PICTUREFILE
-#define ICON_EXT_JS        ICON_JAVASCRIPT
-#define ICON_EXT_JSON      "\ufb25"
-#define ICON_EXT_JSX       ICON_REACT
-
-/* K */
-
-/* L */
-#define ICON_EXT_LHA       ICON_ARCHIVE
-#define ICON_EXT_LHS       ICON_HASKELL
-#define ICON_EXT_LOG       ICON_DOCUMENT
-#define ICON_EXT_LUA       "\ue620"
-#define ICON_EXT_LZH       ICON_ARCHIVE
-#define ICON_EXT_LZMA      ICON_ARCHIVE
-
-/* M */
-#define ICON_EXT_M4A       ICON_MUSICFILE
-#define ICON_EXT_M4V       ICON_VIDEOFILE
-#define ICON_EXT_M         "\ufd1c"
-#define ICON_EXT_MAT       "\uf0ce"
-#define ICON_EXT_MD        "\ue609"
-#define ICON_EXT_MK        ICON_MAKEFILE
-#define ICON_EXT_MKV       ICON_VIDEOFILE
-#define ICON_EXT_MOV       ICON_VIDEOFILE
-#define ICON_EXT_MP3       ICON_MUSICFILE
-#define ICON_EXT_MP4       ICON_VIDEOFILE
-#define ICON_EXT_MPEG      ICON_VIDEOFILE
-#define ICON_EXT_MPG       ICON_VIDEOFILE
-#define ICON_EXT_MSI       "\uf871"
-
-/* N */
-#define ICON_EXT_NIX       "\uf313"
-
-/* O */
-#define ICON_EXT_O         ICON_MANUAL
-#define ICON_EXT_OGG       ICON_MUSICFILE
-#define ICON_EXT_OPUS      ICON_MUSICFILE
-#define ICON_EXT_ODOWNLOAD ICON_DOWNLOADS
-#define ICON_EXT_OUT       ICON_LINUX
-
-/* P */
-#define ICON_EXT_PART      ICON_DOWNLOADS
-#define ICON_EXT_PATCH     "\uf440"
-#define ICON_EXT_PDF       "\uf724"
-#define ICON_EXT_PGN       ICON_CHESS
-#define ICON_EXT_PHP       "\ue73d"
-#define ICON_EXT_PNG       ICON_PICTUREFILE
-#define ICON_EXT_PPT       "\uf726"
-#define ICON_EXT_PPTX      "\uf726"
-#define ICON_EXT_PSB       "\ue7b8"
-#define ICON_EXT_PSD       "\ue7b8"
-#define ICON_EXT_PY        ICON_PYTHON
-#define ICON_EXT_PYC       ICON_PYTHON
-#define ICON_EXT_PYD       ICON_PYTHON
-#define ICON_EXT_PYO       ICON_PYTHON
-
-/* Q */
-
-/* R */
-#define ICON_EXT_RAR       ICON_ARCHIVE
-#define ICON_EXT_RC        ICON_CONFIGURE
-#define ICON_EXT_ROM       "\uf795"
-#define ICON_EXT_RPM       ICON_ARCHIVE
-#define ICON_EXT_RSS       "\uf96b"
-#define ICON_EXT_RTF       "\uf724"
-#define ICON_EXT_RB        ICON_RUBY
-
-/* S */
-#define ICON_EXT_SASS      "\ue603"
-#define ICON_EXT_SCSS      "\ue603"
-#define ICON_EXT_SO        ICON_MANUAL
-#define ICON_EXT_SCALA     "\ue737"
-#define ICON_EXT_SH        ICON_SCRIPT
-#define ICON_EXT_SLIM      ICON_SCRIPT
-#define ICON_EXT_SLN       "\ue70c"
-#define ICON_EXT_SQL       ICON_DATABASE
-#define ICON_EXT_SRT       "\uf679"
-#define ICON_EXT_STY       ICON_TEX
-#define ICON_EXT_SUB       "\uf679"
-#define ICON_EXT_SVG       ICON_PICTUREFILE
-
-/* T */
-#define ICON_EXT_TAR       ICON_ARCHIVE
-#define ICON_EXT_TEX       ICON_TEX
-#define ICON_EXT_TGZ       ICON_ARCHIVE
-#define ICON_EXT_TS        "\ue628"
-#define ICON_EXT_TSX       ICON_REACT
-#define ICON_EXT_TXT       ICON_DOCUMENT
-#define ICON_EXT_TXZ       ICON_ARCHIVE
-
-/* U */
-
-/* V */
-#define ICON_EXT_VID       ICON_VIDEOFILE
-#define ICON_EXT_VIM       "\ue62b"
-#define ICON_EXT_VIMRC     "\ue62b"
-
-/* W */
-#define ICON_EXT_WAV       ICON_MUSICFILE
-#define ICON_EXT_WEBM      ICON_VIDEOFILE
-#define ICON_EXT_WEBP      ICON_PICTUREFILE
-#define ICON_EXT_WMA       ICON_VIDEOFILE
-#define ICON_EXT_WMV       ICON_VIDEOFILE
-
-/* X */
-#define ICON_EXT_XBPS      ICON_ARCHIVE
-#define ICON_EXT_XCF       ICON_PICTUREFILE
-#define ICON_EXT_XHTML     ICON_HTML
-#define ICON_EXT_XLS       "\uf71a"
-#define ICON_EXT_XLSX      "\uf71a"
-#define ICON_EXT_XML       ICON_HTML
-#define ICON_EXT_XZ        ICON_ARCHIVE
-
-/* Y */
-#define ICON_EXT_YAML      ICON_CONFIGURE
-#define ICON_EXT_YML       ICON_CONFIGURE
-
-/* Z */
-#define ICON_EXT_ZIP       ICON_ARCHIVE
-#define ICON_EXT_ZSH       ICON_SCRIPT
-#define ICON_EXT_ZST       ICON_ARCHIVE
-
-#endif // ICONS_NERDFONT
index 4cadc4dcd515928b7dd5cabb75f2350382958fff..293ce9aadfb8d46415d3dd7b345f857f3540ae06 100644 (file)
-#pragma once
+#ifndef INCLUDE_ICONS_H
+#define INCLUDE_ICONS_H
 
-#if defined(ICONS)
-#include "icons-in-terminal.h"
+/*
+ * 1st arg = ICONS_IN_TERM
+ *
+ * 2nd arg = NERD ICONS
+ * You can find hex codes for nerd fonts here: https://www.nerdfonts.com/cheat-sheet
+ *
+ * 3rd arg = EMOJIS
+ * You can find a list of emoji here: https://unicode.org/Public/emoji/5.0/emoji-test.txt
+ *
+ * Any entry with empty icon gets removed by the hash-table generator
+ */
+#if defined(ICONS_IN_TERM)
+       #define ICON_STR(I, N, E) I
+       #include "icons-in-terminal.h"
 #elif defined(NERD)
-#include "icons-nerdfont.h"
+       #define ICON_STR(I, N, E) N
 #elif defined(EMOJI)
-#include "icons-emoji.h"
+       #define ICON_STR(I, N, E) E
 #endif
 
-struct icon_pair {
-       const char *match;
-       const char *icon;
-       /*
-        * Hex xterm 256 color code, 0 to follow file specific (if any)
-        * Codes: https://jonasjacek.github.io/colors/
-        * Spectrum sorted: https://upload.wikimedia.org/wikipedia/commons/1/15/Xterm_256color_chart.svg
-        */
-       const unsigned char color;
-};
-
 /*
  * Define a string to be printed before and after the icon
  * Adjust if the icons are not printed properly
  */
-
-#define ICON_PADDING_LEFT  ""
 #if defined(EMOJI)
-#define ICON_PADDING_RIGHT " "
+       /*
+        * NOTE: As some emojis take up two cells, all of the emoji icons must
+        * be of width 2. Therefore, right pad single-width emoji with a space.
+        */
+       #define ICON_SIZE 2
+       #define ICON_PADDING_RIGHT " "
 #else
-#define ICON_PADDING_RIGHT "  "
+       #define ICON_SIZE 1
+       #define ICON_PADDING_RIGHT "  "
 #endif
-#define ICON_PADDING_LEFT_LEN  (sizeof ICON_PADDING_LEFT - 1)
+#define ICON_PADDING_LEFT  ""
+#define ICON_PADDING_LEFT_LEN  (sizeof ICON_PADDING_LEFT  - 1)
 #define ICON_PADDING_RIGHT_LEN (sizeof ICON_PADDING_RIGHT - 1)
 
-#if defined(EMOJI) /* emojies take up 2 cells */
-#define ICON_SIZE 2
-#else
-#define ICON_SIZE 1
-#endif
-
-/* For color names, refer to: https://www.ditig.com/256-colors-cheat-sheet */
-#define COLOR_VIDEO        45  /* Turquoise2 */
-#define COLOR_VIDEO1       226 /* Yellow1 */
-#define COLOR_AUDIO        220 /* Gold1 */
-#define COLOR_AUDIO1       205 /* HotPink */
-#define COLOR_IMAGE        82  /* Chartreuse2 */
-#define COLOR_DOCS         202 /* OrangeRed1 */
-#define COLOR_ARCHIVE      209 /* Salmon1 */
-#define COLOR_C            81  /* SteelBlue1 */
-#define COLOR_JAVA         32  /* DeepSkyBlue3 */
-#define COLOR_JAVASCRIPT   47  /* SpringGreen2 */
-#define COLOR_REACT        39  /* DeepSkyBlue1 */
-#define COLOR_CSS          199 /* DeepPink1 */
-#define COLOR_PYTHON       227 /* LightGoldenrod1 */
-#define COLOR_LUA          19  /* Blue3 */
-#define COLOR_DOCUMENT     15  /* White */
-#define COLOR_FSHARP       31  /* DeepSkyBlue3 */
-#define COLOR_RUBY         160 /* Red3 */
-#define COLOR_SCALA        196 /* Red1 */
-#define COLOR_SHELL        47  /* SpringGreen2 */
-#define COLOR_VIM          28  /* Green4 */
+/* ARROWS */
+#define ICON_ARROW_UP      ICON_STR(MD_ARROW_UPWARD, "\uf55c", "⬆")
+#define ICON_ARROW_FORWARD ICON_STR(MD_ARROW_FORWARD, "\uf553", "➑")
+#define ICON_ARROW_DOWN    ICON_STR(MD_ARROW_DOWNWARD, "\uf544", "⬇")
+
+/* GENERIC */
+#define ICON_DIRECTORY     ICON_STR(FA_FOLDER, "\ue5ff", "πŸ“‚")
+#define ICON_FILE          ICON_STR(FA_FILE, "\uf713", "πŸ“ƒ")
+#define ICON_EXEC          ICON_STR(FA_COG, "\uf144", "βš™οΈ ")
+
+/* Top level and common icons */
+#define ICON_ARCHIVE       ICON_STR(FA_FILE_ARCHIVE_O, "\uf53b", "πŸ“¦")
+#define ICON_BRIEFCASE     ICON_STR(FA_BRIEFCASE, "\uf5d5", "πŸ’Ό")
+#define ICON_C             ICON_STR(MFIZZ_C, "\ue61e", "πŸ‡¨ ")
+#define ICON_CHANGELOG     ICON_STR(FA_HISTORY, "\uf7d9", "πŸ”Ί")
+#define ICON_CHESS         ICON_STR("", "\uf639", "")
+#define ICON_CLOJURE       ICON_STR(MFIZZ_CLOJURE, "\ue76a", "")
+#define ICON_CONFIGURE     ICON_STR(FILE_CONFIG, "\uf423", "πŸ”§")
+#define ICON_CPLUSPLUS     ICON_STR(MFIZZ_CPLUSPLUS, "\ue61d", ICON_C)
+#define ICON_DATABASE      ICON_STR(MFIZZ_DATABASE_ALT2, "\uf6b7", "πŸ—ƒοΈ ")
+#define ICON_DESKTOP       ICON_STR(FA_DESKTOP, "\ufcbe", "πŸ–₯️ ")
+#define ICON_DOCUMENT      ICON_STR(FA_FILE_TEXT_O, "\uf718", "πŸ—’ ")
+#define ICON_DOWNLOADS     ICON_STR(FA_DOWNLOAD, "\uf5d7", "πŸ“₯")
+#define ICON_ENCRYPT       ICON_STR("", "\uf805", "πŸ”’")
+#define ICON_FSHARP        ICON_STR(DEV_FSHARP, "\ue7a7", "")
+#define ICON_GIT           ICON_STR(FA_GIT, "\ue5fb", "🌱")
+#define ICON_HASKELL       ICON_STR("", "\ue777", "")
+#define ICON_HTML          ICON_STR(FA_FILE_CODE_O, "\uf72d", "")
+#define ICON_JAVA          ICON_STR(MFIZZ_JAVA, "\ue738", "β˜•")
+#define ICON_JAVASCRIPT    ICON_STR(FA_FILE_CODE_O, "\uf81d", "")
+#define ICON_LICENSE       ICON_STR(FA_COPYRIGHT, "\uf718", "βš–οΈ ")
+#define ICON_LINUX         ICON_STR(FA_LINUX, "\uf83c", "🐧")
+#define ICON_MAKEFILE      ICON_STR(FILE_CMAKE, "\uf68c", "πŸ›  ")
+#define ICON_MANUAL        ICON_STR(FILE_MANPAGE, "\uf5bd", "❓")
+#define ICON_MS_EXCEL      ICON_STR(FILE_EXCEL, "\uf71a", ICON_WORDDOC)
+#define ICON_MUSIC         ICON_STR(FA_MUSIC, "\uf832", "🎧")
+#define ICON_MUSICFILE     ICON_STR(FA_FILE_AUDIO_O, "\uf886", ICON_MUSIC)
+#define ICON_OPTICALDISK   ICON_STR(LINEA_MUSIC_CD, "\ue271", "πŸ’Ώ")
+#define ICON_PDF           ICON_STR(FA_FILE_PDF_O, "\uf724", "πŸ“•")
+#define ICON_PHOTOSHOP     ICON_STR(DEV_PHOTOSHOP, "\ue7b8", ICON_PICTUREFILE)
+#define ICON_PICTUREFILE   ICON_STR(FA_FILE_IMAGE_O, "\uf71e", ICON_PICTURES)
+#define ICON_PICTURES      ICON_STR(MD_CAMERA_ALT, "\uf753", "🎨")
+#define ICON_PLAYLIST      ICON_STR(ICON_MUSICFILE, "\uf910", "")
+#define ICON_POWERPOINT    ICON_STR(FILE_POWERPOINT, "\uf726", "πŸ“Š")
+#define ICON_PUBLIC        ICON_STR(FA_INBOX, "\ue5ff", "πŸ‘€")
+#define ICON_PYTHON        ICON_STR(MFIZZ_PYTHON, "\ue235", "🐍")
+#define ICON_REACT         ICON_STR(FILE_JSX, "\ue625", ICON_JAVASCRIPT)
+#define ICON_RUBY          ICON_STR(MFIZZ_RUBY, "\ue23e", "πŸ’Ž")
+#define ICON_SASS          ICON_STR("", "\ue603", "")
+#define ICON_SCRIPT        ICON_STR(MFIZZ_SCRIPT, "\ue795", "πŸ“œ")
+#define ICON_SUBTITLE      ICON_STR(FA_COMMENTS_O, "\uf679", "πŸ’¬")
+#define ICON_TEMPLATES     ICON_STR(FA_PAPERCLIP, "\ufac6", "πŸ“Ž")
+#define ICON_TEX           ICON_STR(FILE_TEX, "\ufb68", ICON_DOCUMENT)
+#define ICON_VIDEOFILE     ICON_STR(FA_FILE_MOVIE_O, "\uf72a", ICON_VIDEOS)
+#define ICON_VIDEOS        ICON_STR(FA_FILM, "\uf72f", "🎞 ")
+#define ICON_VIM           ICON_STR(DEV_VIM, "\ue62b", "")
+#define ICON_WORDDOC       ICON_STR(FILE_WORD, "\uf72b", "πŸ“˜")
+
+#define ICON_EXT_ASM       ICON_STR(FILE_NASM, "", "")
+#define ICON_EXT_BIN       ICON_STR(OCT_FILE_BINARY, "\uf471", "πŸ““")
+#define ICON_EXT_COFFEE    ICON_STR(MFIZZ_COFFEE_BEAN, "\ue751", "")
+#define ICON_EXT_CSS       ICON_STR(MFIZZ_CSS3, "\ue749", "πŸ¦‹")
+#define ICON_EXT_DEB       ICON_STR(MFIZZ_DEBIAN, "\ue77d", ICON_LINUX)
+#define ICON_EXT_DIFF      ICON_STR(FILE_DIFF, "\uf440", "πŸ“‹")
+#define ICON_EXT_GO        ICON_STR(MFIZZ_GO, "\ufcd1", "")
+#define ICON_EXT_JSON      ICON_STR(ICON_JAVASCRIPT, "\ufb25", ICON_JAVASCRIPT)
+#define ICON_EXT_LUA       ICON_STR(FILE_LUA, "\ue620", "🌘")
+#define ICON_EXT_M         ICON_STR("", "\ufd1c", "πŸ“Š")
+#define ICON_EXT_MAT       ICON_STR("", "\uf0ce", "")
+#define ICON_EXT_MD        ICON_STR(DEV_MARKDOWN, "\ue609", "πŸ“")
+#define ICON_EXT_MSI       ICON_STR(FA_WINDOWS, "\uf871", "πŸͺŸ")
+#define ICON_EXT_NIX       ICON_STR("", "\uf313", "")
+#define ICON_EXT_PATCH     ICON_STR(FILE_PATCH, "\uf440", "🩹")
+#define ICON_EXT_PHP       ICON_STR(MFIZZ_PHP, "\ue73d", "🌐")
+#define ICON_EXT_ROM       ICON_STR(FA_LOCK, "\uf795", "")
+#define ICON_EXT_RSS       ICON_STR(FA_RSS_SQUARE, "\uf96b", "πŸ“‘")
+#define ICON_EXT_RTF       ICON_STR(ICON_PDF, "\uf724", ICON_PDF)
+#define ICON_EXT_SCALA     ICON_STR(MFIZZ_SCALA, "\ue737", "")
+#define ICON_EXT_SLN       ICON_STR(DEV_VISUALSTUDIO, "\ue70c", "")
+#define ICON_EXT_TS        ICON_STR(FILE_TS, "\ue628", "")
 
 /*
- * Using symbols defined in icons-in-terminal.h, or even using icons-in-terminal is not necessary.
- * You can use whatever pathched font you like. You just have to put the desired icon as a string.
- * If you are using icons-in-terminal the creator recommends that you do use the symbols in the generated header.
+ * Hex xterm 256 color code, 0 to follow file specific (if any)
+ * Codes: https://jonasjacek.github.io/colors/
+ * Spectrum sorted: https://upload.wikimedia.org/wikipedia/commons/1/15/Xterm_256color_chart.svg
+ * Color names: https://www.ditig.com/256-colors-cheat-sheet
  */
-
-#if defined(ICONS)
-static const struct icon_pair dir_icon  = {"", FA_FOLDER, 0};
-static const struct icon_pair file_icon = {"", FA_FILE_O, 0};
-static const struct icon_pair exec_icon = {"", FA_COG,    0};
-#elif defined(NERD)
-static const struct icon_pair dir_icon  = {"", ICON_DIRECTORY, 0};
-static const struct icon_pair file_icon = {"", ICON_FILE,      0};
-static const struct icon_pair exec_icon = {"", ICON_EXEC,      0};
-#elif defined(EMOJI)
-static const struct icon_pair dir_icon  = {"", EMOJI_FOLDER, 0};
-static const struct icon_pair file_icon = {"", EMOJI_FILE,   0};
-static const struct icon_pair exec_icon = {"", EMOJI_EXEC,   0};
+#define COLOR_LIST \
+       COLOR_X(COLOR_VIDEO,         45)  /* Turquoise2 */ \
+       COLOR_X(COLOR_VIDEO1,       226)  /* Yellow1 */ \
+       COLOR_X(COLOR_AUDIO,        220)  /* Gold1 */ \
+       COLOR_X(COLOR_AUDIO1,       205)  /* HotPink */ \
+       COLOR_X(COLOR_IMAGE,         82)  /* Chartreuse2 */ \
+       COLOR_X(COLOR_DOCS,         202)  /* OrangeRed1 */ \
+       COLOR_X(COLOR_ARCHIVE,      209)  /* Salmon1 */ \
+       COLOR_X(COLOR_C,             81)  /* SteelBlue1 */ \
+       COLOR_X(COLOR_JAVA,          32)  /* DeepSkyBlue3 */ \
+       COLOR_X(COLOR_JAVASCRIPT,    47)  /* SpringGreen2 */ \
+       COLOR_X(COLOR_REACT,         39)  /* DeepSkyBlue1 */ \
+       COLOR_X(COLOR_CSS,          199)  /* DeepPink1 */ \
+       COLOR_X(COLOR_PYTHON,       227)  /* LightGoldenrod1 */ \
+       COLOR_X(COLOR_LUA,           19)  /* Blue3 */ \
+       COLOR_X(COLOR_DOCUMENT,      15)  /* White */ \
+       COLOR_X(COLOR_FSHARP,        31)  /* DeepSkyBlue3 */ \
+       COLOR_X(COLOR_RUBY,         160)  /* Red3 */ \
+       COLOR_X(COLOR_SCALA,        196)  /* Red1 */ \
+       COLOR_X(COLOR_SHELL,         47)  /* SpringGreen2 */ \
+       COLOR_X(COLOR_VIM,           28)  /* Green4 */ \
+
+/* X-Macro: https://en.wikipedia.org/wiki/X_Macro */
+#define COLOR_X(N, V) N = V,
+enum { COLOR_LIST };
+#undef COLOR_X
+#define COLOR_X(N, V) N,
+static const unsigned char init_colors[] = { COLOR_LIST };
+#undef COLOR_X
+
+#ifdef ICONS_GENERATE
+       /* temporary struct using `char *`. the hash-table generator will
+        * output a more optimized version which uses `char[]` instead reducing
+        * indirection and the total binary size.
+        */
+       struct icon_pair { const char *match; const char *icon; unsigned char color; };
 #endif
 
-/* All entries are case-insensitive */
+static const struct icon_pair dir_icon  = {"", ICON_DIRECTORY, 0};
+static const struct icon_pair file_icon = {"", ICON_FILE, 0};
+static const struct icon_pair exec_icon = {"", ICON_EXEC, 0};
 
 static const struct icon_pair icons_name[] = {
-#if defined(ICONS)
-       {".git",         FA_GIT,        0},
-       {"Desktop",      FA_DESKTOP,    0},
-       {"Documents",    FA_BRIEFCASE,  0},
-       {"Downloads",    FA_DOWNLOAD,   0},
-       {"Music",        FA_MUSIC,      0},
-       {"Pictures",     MD_CAMERA_ALT, 0},
-       {"Public",       FA_INBOX,      0},
-       {"Templates",    FA_PAPERCLIP,  0},
-       {"Videos",       FA_FILM,       0},
-       {"CHANGELOG",    FA_HISTORY,    COLOR_DOCS},
-       {"configure",    FILE_CONFIG,   0},
-       {"License",      FA_COPYRIGHT,  COLOR_DOCS},
-       {"Makefile",     FILE_CMAKE,    0},
-#elif defined(NERD)
-       {".git",         ICON_GIT,       0},
-       {"Desktop",      ICON_DESKTOP,   0},
-       {"Documents",    ICON_BRIEFCASE, 0},
-       {"Downloads",    ICON_DOWNLOADS, 0},
-       {"Music",        ICON_MUSIC,     0},
-       {"Pictures",     ICON_PICTURES,  0},
-       {"Public",       ICON_PUBLIC,    0},
-       {"Templates",    ICON_TEMPLATES, 0},
-       {"Videos",       ICON_VIDEOS,    0},
-       {"CHANGELOG",    ICON_CHANGELOG, COLOR_DOCS},
-       {"configure",    ICON_CONFIGURE, 0},
-       {"License",      ICON_LICENSE,   COLOR_DOCS},
-       {"Makefile",     ICON_MAKEFILE,  0},
-#elif defined(EMOJI)
-       {".git",         EMOJI_GIT,        0},
-       {"Desktop",      EMOJI_DESKTOP,    0},
-       {"Documents",    EMOJI_BRIEFCASE,  0},
-       {"Downloads",    EMOJI_DOWNLOAD,   0},
-       {"Music",        EMOJI_MUSIC,      0},
-       {"Pictures",     EMOJI_PICTURE,    0},
-       {"Public",       EMOJI_PUBLIC,     0},
-       {"Templates",    EMOJI_TEMPLATE,   0},
-       {"Videos",       EMOJI_MOVIE,      0},
-       {"CHANGELOG",    EMOJI_CHANGELOG,  COLOR_DOCS},
-       {"configure",    EMOJI_CONF,       0},
-       {"License",      EMOJI_LICENSE,    COLOR_DOCS},
-       {"Makefile",     EMOJI_MAKE,       0},
-#endif
+       {".git",        ICON_GIT,       0},
+       {"Desktop",     ICON_DESKTOP,   0},
+       {"Documents",   ICON_BRIEFCASE, 0},
+       {"Downloads",   ICON_DOWNLOADS, 0},
+       {"Music",       ICON_MUSIC,     0},
+       {"Pictures",    ICON_PICTURES,  0},
+       {"Public",      ICON_PUBLIC,    0},
+       {"Templates",   ICON_TEMPLATES, 0},
+       {"Videos",      ICON_VIDEOS,    0},
+       {"CHANGELOG",   ICON_CHANGELOG, COLOR_DOCS},
+       {"configure",   ICON_CONFIGURE, 0},
+       {"License",     ICON_LICENSE,   COLOR_DOCS},
+       {"Makefile",    ICON_MAKEFILE,  0},
 };
 
+#ifdef ICONS_GENERATE
 /*
- * New entries should be added such that the first character of the extension is in the correct group .
- * This is done for performance reason so that the correct icon can be found faster.
  * All entries are case-insensitive
  */
-
 static const struct icon_pair icons_ext[] = {
-#if defined(ICONS)
        /* Numbers */
-       {"1",        FILE_MANPAGE,         COLOR_DOCS},
-       {"7z",       FA_FILE_ARCHIVE_O,    COLOR_ARCHIVE},
+       {"1",          ICON_MANUAL,         COLOR_DOCS},
+       {"7z",         ICON_ARCHIVE,        COLOR_ARCHIVE},
 
        /* A */
-       {"a",        FILE_MANPAGE,         0},
-       {"apk",      FA_FILE_ARCHIVE_O,    COLOR_ARCHIVE},
-       {"asm",      FILE_NASM,            0},
-       {"aup",      FA_FILE_AUDIO_O,      COLOR_AUDIO},
-       {"avi",      FA_FILE_MOVIE_O,      COLOR_VIDEO},
+       {"a",          ICON_MANUAL,         0},
+       {"apk",        ICON_ARCHIVE,        COLOR_ARCHIVE},
+       {"asm",        ICON_EXT_ASM,        0},
+       {"aup",        ICON_MUSICFILE,      COLOR_AUDIO},
+       {"avi",        ICON_VIDEOFILE,      COLOR_VIDEO},
 
        /* B */
-       {"bat",      MFIZZ_SCRIPT,         0},
-       {"bin",      OCT_FILE_BINARY,      0},
-       {"bmp",      FA_FILE_IMAGE_O,      COLOR_IMAGE},
-       {"bz2",      FA_FILE_ARCHIVE_O,    COLOR_ARCHIVE},
-
-        /* C */
-       {"c",        MFIZZ_C,              0},
-       {"c++",      MFIZZ_CPLUSPLUS,      0},
-       {"cab",      FA_FILE_ARCHIVE_O,    COLOR_ARCHIVE},
-       {"cbr",      FA_FILE_ARCHIVE_O,    COLOR_ARCHIVE},
-       {"cbz",      FA_FILE_ARCHIVE_O,    COLOR_ARCHIVE},
-       {"cc",       MFIZZ_CPLUSPLUS,      0},
-       {"class",    MFIZZ_JAVA,           0},
-       {"clj",      MFIZZ_CLOJURE,        0},
-       {"cljc",     MFIZZ_CLOJURE,        0},
-       {"cljs",     MFIZZ_CLOJURE,        0},
-       {"cmake",    FILE_CMAKE,           0},
-       {"coffee",   MFIZZ_COFFEE_BEAN,    0},
-       {"conf",     FA_COGS,              0},
-       {"cpio",     FA_FILE_ARCHIVE_O,    COLOR_ARCHIVE},
-       {"cpp",      MFIZZ_CPLUSPLUS,      0},
-       {"css",      MFIZZ_CSS3,           0},
-       {"cue",      FA_FILE_AUDIO_O,      COLOR_AUDIO},
-       {"cvs",      FA_COGS,              0},
-       {"cxx",      MFIZZ_CPLUSPLUS,      0},
-
-       /* D */
-       {"db",       MFIZZ_DATABASE_ALT2,  0},
-       {"deb",      MFIZZ_DEBIAN,         COLOR_ARCHIVE},
-       {"diff",     FILE_DIFF,            0},
-       {"dll",      FILE_MANPAGE,         0},
-       {"doc",      FILE_WORD,            0},
-       {"docx",     FILE_WORD,            0},
-
-        /* E */
-       {"ejs",      FA_FILE_CODE_O,       0},
-       {"elf",      FA_LINUX,             0},
-       {"epub",     FA_FILE_PDF_O,        COLOR_DOCS},
-       {"exe",      FA_WINDOWS,           0},
-
-       /* F */
-       {"f#",       DEV_FSHARP,           0},
-       {"flac",     FA_FILE_AUDIO_O,      COLOR_AUDIO1},
-       {"flv",      FA_FILE_MOVIE_O,      COLOR_VIDEO},
-       {"fs",       DEV_FSHARP,           0},
-       {"fsi",      DEV_FSHARP,           0},
-       {"fsscript", DEV_FSHARP,           0},
-       {"fsx",      DEV_FSHARP,           0},
-
-       /* G */
-       {"gem",      FA_FILE_ARCHIVE_O,    0},
-       {"gif",      FA_FILE_IMAGE_O,      COLOR_IMAGE},
-       {"go",       MFIZZ_GO,             0},
-       {"gz",       FA_FILE_ARCHIVE_O,    COLOR_ARCHIVE},
-       {"gzip",     FA_FILE_ARCHIVE_O,    COLOR_ARCHIVE},
-
-       /* H */
-       {"h",        MFIZZ_C,              0},
-       {"hh",       MFIZZ_CPLUSPLUS,      0},
-       {"htaccess", FA_COGS,              0},
-       {"htpasswd", FA_COGS,              0},
-       {"htm",      FA_FILE_CODE_O,       0},
-       {"html",     FA_FILE_CODE_O,       0},
-       {"hxx",      MFIZZ_CPLUSPLUS,      0},
-
-       /* I */
-       {"ico",      FA_FILE_IMAGE_O,      COLOR_IMAGE},
-       {"img",      LINEA_MUSIC_CD,       COLOR_ARCHIVE},
-       {"ini",      FA_COGS,              0},
-       {"iso",      LINEA_MUSIC_CD,       COLOR_ARCHIVE},
-
-       /* J */
-       {"jar",      MFIZZ_JAVA,           0},
-       {"java",     MFIZZ_JAVA,           0},
-       {"jl",       FA_COGS,              0},
-       {"jpeg",     FA_FILE_IMAGE_O,      COLOR_IMAGE},
-       {"jpg",      FA_FILE_IMAGE_O,      COLOR_IMAGE},
-       {"js",       DEV_JAVASCRIPT_BADGE, 0},
-       {"json",     MFIZZ_JAVASCRIPT,     0},
-       {"jsx",      FILE_JSX,             0},
-
-       /* K */
-       {"kdb", FA_LOCK, 0},
-       {"kdb2", FA_LOCK, 0},
-       {"kdbx", FA_LOCK, 0},
-
-       /* L */
-       {"lha",      FA_FILE_ARCHIVE_O,    COLOR_ARCHIVE},
-       {"log",      FA_FILE_TEXT_O,       0},
-       {"lua",      FILE_LUA,             COLOR_LUA},
-       {"lzh",      FA_FILE_ARCHIVE_O,    COLOR_ARCHIVE},
-       {"lzma",     FA_FILE_ARCHIVE_O,    COLOR_ARCHIVE},
-
-       /* M */
-       {"m4a",      FA_FILE_AUDIO_O,      COLOR_AUDIO},
-       {"m4v",      FA_FILE_MOVIE_O,      COLOR_VIDEO},
-       {"markdown", DEV_MARKDOWN,         COLOR_DOCS},
-       {"md",       DEV_MARKDOWN,         COLOR_DOCS},
-       {"mk",       FILE_CMAKE,           0},
-       {"mkv",      FA_FILE_MOVIE_O,      COLOR_VIDEO},
-       {"mov",      FA_FILE_MOVIE_O,      COLOR_VIDEO},
-       {"mp3",      FA_FILE_AUDIO_O,      COLOR_AUDIO},
-       {"mp4",      FA_FILE_MOVIE_O,      COLOR_VIDEO1},
-       {"mpeg",     FA_FILE_MOVIE_O,      COLOR_VIDEO},
-       {"mpg",      FA_FILE_MOVIE_O,      COLOR_VIDEO},
-       {"msi",      FA_WINDOWS,           0},
-
-       /* N */
-
-       /* O */
-       {"o",          FILE_MANPAGE,       0},
-       {"ogg",        FA_FILE_AUDIO_O,    COLOR_AUDIO},
-       {"opus",       FA_FILE_AUDIO_O,    COLOR_AUDIO},
-       {"opdownload", FA_DOWNLOAD,        0},
-       {"out",        FA_LINUX,           0},
-
-       /* P */
-       {"part",     FA_DOWNLOAD,          0},
-       {"patch",    FILE_PATCH,           0},
-       {"pdf",      FA_FILE_PDF_O,        COLOR_DOCS},
-       {"php",      MFIZZ_PHP,            0},
-       {"png",      FA_FILE_IMAGE_O,      COLOR_IMAGE},
-       {"ppt",      FILE_POWERPOINT,      0},
-       {"pptx",     FILE_POWERPOINT,      0},
-       {"psb",      DEV_PHOTOSHOP,        0},
-       {"psd",      DEV_PHOTOSHOP,        0},
-       {"py",       MFIZZ_PYTHON,         0},
-       {"pyc",      MFIZZ_PYTHON,         0},
-       {"pyd",      MFIZZ_PYTHON,         0},
-       {"pyo",      MFIZZ_PYTHON,         0},
-
-       /* Q */
-
-       /* R */
-       {"rar",      FA_FILE_ARCHIVE_O,    COLOR_ARCHIVE},
-       {"rb",       MFIZZ_RUBY,           COLOR_RUBY},
-       {"rc",       FA_COGS,              0},
-       {"rom",      FA_LOCK,              0},
-       {"rpm",      FA_FILE_ARCHIVE_O,    COLOR_ARCHIVE},
-       {"rss",      FA_RSS_SQUARE,        0},
-       {"rtf",      FA_FILE_PDF_O,        0},
-
-       /* S */
-       {"so",       FILE_MANPAGE,         0},
-       {"scala",    MFIZZ_SCALA,          0},
-       {"sh",       MFIZZ_SCRIPT,         COLOR_SHELL},
-       {"slim",     FA_FILE_CODE_O,       0},
-       {"sln",      DEV_VISUALSTUDIO,     0},
-       {"sql",      MFIZZ_MYSQL,          0},
-       {"srt",      FA_COMMENTS_O,        0},
-       {"sub",      FA_COMMENTS_O,        0},
-       {"svg",      FA_FILE_IMAGE_O,      COLOR_IMAGE},
-
-       /* T */
-       {"tar",      FA_FILE_ARCHIVE_O,    COLOR_ARCHIVE},
-       {"tex",      FILE_TEX,             0},
-       {"tgz",      FA_FILE_ARCHIVE_O,    COLOR_ARCHIVE},
-       {"ts",       FILE_TS,              0},
-       {"tsx",      FILE_TSX,             0},
-       {"txt",      FA_FILE_TEXT_O,       0},
-       {"txz",      FA_FILE_ARCHIVE_O,    COLOR_ARCHIVE},
-
-       /* U */
-
-       /* V */
-       {"vid",      FA_FILE_MOVIE_O,      COLOR_VIDEO},
-       {"vim",      DEV_VIM,              0},
-       {"vimrc",    DEV_VIM,              0},
-       {"vtt",      FA_COMMENTS_O,        0},
-
-       /* W */
-       {"wav",      FA_FILE_AUDIO_O,      COLOR_AUDIO},
-       {"webm",     FA_FILE_MOVIE_O,      COLOR_VIDEO},
-       {"webp",     FA_FILE_IMAGE_O,      COLOR_IMAGE},
-       {"wma",      FA_FILE_AUDIO_O,      COLOR_AUDIO},
-       {"wmv",      FA_FILE_MOVIE_O,      COLOR_VIDEO},
-
-       /* X */
-       {"xbps",     FA_FILE_ARCHIVE_O,    COLOR_ARCHIVE},
-       {"xcf",      FA_FILE_IMAGE_O,      COLOR_IMAGE},
-       {"xhtml",    FA_FILE_CODE_O,       0},
-       {"xls",      FILE_EXCEL,           0},
-       {"xlsx",     FILE_EXCEL,           0},
-       {"xml",      FA_FILE_CODE_O,       0},
-       {"xz",       FA_FILE_ARCHIVE_O,    COLOR_ARCHIVE},
-
-       /* Y */
-       {"yaml",     FA_COGS,              0},
-       {"yml",      FA_COGS,              0},
-
-       /* Z */
-       {"zip",      FA_FILE_ARCHIVE_O,    COLOR_ARCHIVE},
-
-       /* Other */
-#elif defined(NERD)
-       /* Numbers */
-       {"1",          ICON_EXT_1,         COLOR_DOCS},
-       {"7z",         ICON_EXT_7Z,        COLOR_ARCHIVE},
-
-       /* A */
-       {"a",          ICON_EXT_A,         0},
-       {"apk",        ICON_EXT_APK,       COLOR_ARCHIVE},
-       {"asm",        ICON_EXT_ASM,       0},
-       {"aup",        ICON_EXT_AUP,       COLOR_AUDIO},
-       {"avi",        ICON_EXT_AVI,       COLOR_VIDEO},
-
-       /* B */
-       {"bat",        ICON_EXT_BAT,       0},
-       {"bib",        ICON_EXT_BIB,       0},
-       {"bin",        ICON_EXT_BIN,       0},
-       {"bmp",        ICON_EXT_BMP,       COLOR_IMAGE},
-       {"bz2",        ICON_EXT_BZ2,       COLOR_ARCHIVE},
-
-        /* C */
-       {"c",          ICON_EXT_C,         COLOR_C},
-       {"c++",        ICON_EXT_CPLUSPLUS, COLOR_C},
-       {"cabal",      ICON_EXT_CABAL,     COLOR_VIDEO},
-       {"cab",        ICON_EXT_CAB,       COLOR_ARCHIVE},
-       {"cbr",        ICON_EXT_CBR,       COLOR_ARCHIVE},
-       {"cbz",        ICON_EXT_CBZ,       COLOR_ARCHIVE},
-       {"cc",         ICON_EXT_CC,        COLOR_C},
-       {"class",      ICON_EXT_CLASS,     COLOR_JAVA},
-       {"clj",        ICON_EXT_CLJ,       0},
-       {"cljc",       ICON_EXT_CLJC,      0},
-       {"cljs",       ICON_EXT_CLJS,      0},
-       {"cls",        ICON_EXT_CLS,       0},
-       {"cmake",      ICON_EXT_CMAKE,     0},
-       {"coffee",     ICON_EXT_COFFEE,    0},
-       {"conf",       ICON_EXT_CONF,      0},
-       {"cpio",       ICON_EXT_CPIO,      COLOR_ARCHIVE},
-       {"cpp",        ICON_EXT_CPP,       COLOR_C},
-       {"css",        ICON_EXT_CSS,       COLOR_CSS},
-       {"cue",        ICON_EXT_CUE,       COLOR_AUDIO},
-       {"cvs",        ICON_EXT_CVS,       0},
-       {"cxx",        ICON_EXT_CXX,       COLOR_C},
-
-       /* D */
-       {"db",         ICON_EXT_DB,        0},
-       {"deb",        ICON_EXT_DEB,       COLOR_ARCHIVE},
-       {"diff",       ICON_EXT_DIFF,      0},
-       {"dll",        ICON_EXT_DLL,       0},
-       {"doc",        ICON_EXT_DOC,       COLOR_DOCUMENT},
-       {"docx",       ICON_EXT_DOCX,      COLOR_DOCUMENT},
-
-        /* E */
-       {"ejs",        ICON_EXT_EJS,       COLOR_JAVASCRIPT},
-       {"elf",        ICON_EXT_ELF,       0},
-       {"epub",       ICON_EXT_EPUB,      COLOR_DOCS},
-       {"exe",        ICON_EXT_EXE,       0},
-
-       /* F */
-       {"f#",         ICON_EXT_FSHARP,    COLOR_FSHARP},
-       {"fen",        ICON_EXT_FEN,       0},
-       {"flac",       ICON_EXT_FLAC,      COLOR_AUDIO1},
-       {"flv",        ICON_EXT_FLV,       COLOR_VIDEO},
-       {"fs",         ICON_EXT_FS,        COLOR_FSHARP},
-       {"fsi",        ICON_EXT_FSI,       COLOR_FSHARP},
-       {"fsscript",   ICON_EXT_FSSCRIPT,  COLOR_FSHARP},
-       {"fsx",        ICON_EXT_FSX,       COLOR_FSHARP},
-
-       /* G */
-       {"gem",        ICON_EXT_GEM,       COLOR_RUBY},
-       {"gif",        ICON_EXT_GIF,       COLOR_IMAGE},
-       {"go",         ICON_EXT_GO,        0},
-       {"gpg",        ICON_EXT_GPG,       COLOR_ARCHIVE},
-       {"gz",         ICON_EXT_GZ,        COLOR_ARCHIVE},
-       {"gzip",       ICON_EXT_GZIP,      COLOR_ARCHIVE},
-
-       /* H */
-       {"h",          ICON_EXT_H,         COLOR_C},
-       {"hh",         ICON_EXT_HH,        COLOR_C},
-       {"hpp",        ICON_EXT_HPP,       COLOR_C},
-       {"hs",         ICON_EXT_HS,        COLOR_VIM},
-       {"htaccess",   ICON_EXT_HTACCESS,  0},
-       {"htpasswd",   ICON_EXT_HTPASSWD,  0},
-       {"htm",        ICON_EXT_HTM,       0},
-       {"html",       ICON_EXT_HTML,      0},
-       {"hxx",        ICON_EXT_HXX,       COLOR_C},
-
-       /* I */
-       {"ico",        ICON_EXT_ICO,       COLOR_IMAGE},
-       {"img",        ICON_EXT_IMG,       COLOR_ARCHIVE},
-       {"ini",        ICON_EXT_INI,       0},
-       {"iso",        ICON_EXT_ISO,       COLOR_ARCHIVE},
-
-       /* J */
-       {"jar",        ICON_EXT_JAR,       COLOR_JAVA},
-       {"java",       ICON_EXT_JAVA,      COLOR_JAVA},
-       {"jl",         ICON_EXT_JL,        0},
-       {"jpeg",       ICON_EXT_JPEG,      COLOR_IMAGE},
-       {"jpg",        ICON_EXT_JPG,       COLOR_IMAGE},
-       {"js",         ICON_EXT_JS,        COLOR_JAVASCRIPT},
-       {"json",       ICON_EXT_JSON,      COLOR_JAVASCRIPT},
-       {"jsx",        ICON_EXT_JSX,       COLOR_REACT},
-
-       /* K */
-
-       /* L */
-       {"lha",        ICON_EXT_LHA,       COLOR_ARCHIVE},
-       {"lhs",        ICON_EXT_LHS,       COLOR_VIM},
-       {"log",        ICON_EXT_LOG,       0},
-       {"lua",        ICON_EXT_LUA,       COLOR_LUA},
-       {"lzh",        ICON_EXT_LZH,       COLOR_ARCHIVE},
-       {"lzma",       ICON_EXT_LZMA,      COLOR_ARCHIVE},
-
-       /* M */
-       {"m",          ICON_EXT_M,         COLOR_C},
-       {"m4a",        ICON_EXT_M4A,       COLOR_AUDIO},
-       {"m4v",        ICON_EXT_M4V,       COLOR_VIDEO},
-       {"markdown",   ICON_EXT_MD,        COLOR_DOCS},
-       {"mat",        ICON_EXT_MAT,       COLOR_C},
-       {"md",         ICON_EXT_MD,        COLOR_DOCS},
-       {"mk",         ICON_EXT_MK,        0},
-       {"mkv",        ICON_EXT_MKV,       COLOR_VIDEO},
-       {"mov",        ICON_EXT_MOV,       COLOR_VIDEO},
-       {"mp3",        ICON_EXT_MP3,       COLOR_AUDIO},
-       {"mp4",        ICON_EXT_MP4,       COLOR_VIDEO1},
-       {"mpeg",       ICON_EXT_MPEG,      COLOR_VIDEO},
-       {"mpg",        ICON_EXT_MPG,       COLOR_VIDEO},
-       {"msi",        ICON_EXT_MSI,       0},
-
-       /* N */
-       {"nix",        ICON_EXT_NIX,       COLOR_FSHARP},
-
-       /* O */
-       {"o",          ICON_EXT_O,         0},
-       {"ogg",        ICON_EXT_OGG,       COLOR_AUDIO},
-       {"opus",       ICON_EXT_OPUS,      COLOR_AUDIO},
-       {"opdownload", ICON_EXT_ODOWNLOAD, 0},
-       {"out",        ICON_EXT_OUT,       0},
-
-       /* P */
-       {"part",       ICON_EXT_PART,      0},
-       {"patch",      ICON_EXT_PATCH,     0},
-       {"pdf",        ICON_EXT_PDF,       COLOR_DOCS},
-       {"pgn",        ICON_EXT_PGN,       0},
-       {"php",        ICON_EXT_PHP,       0},
-       {"png",        ICON_EXT_PNG,       COLOR_IMAGE},
-       {"ppt",        ICON_EXT_PPT,       0},
-       {"pptx",       ICON_EXT_PPTX,      0},
-       {"psb",        ICON_EXT_PSB,       0},
-       {"psd",        ICON_EXT_PSD,       0},
-       {"py",         ICON_EXT_PY,        COLOR_PYTHON},
-       {"pyc",        ICON_EXT_PYC,       COLOR_PYTHON},
-       {"pyd",        ICON_EXT_PYD,       COLOR_PYTHON},
-       {"pyo",        ICON_EXT_PYO,       COLOR_PYTHON},
-
-       /* Q */
-
-       /* R */
-       {"rar",        ICON_EXT_RAR,       COLOR_ARCHIVE},
-       {"rb",         ICON_EXT_RB,        COLOR_RUBY},
-       {"rc",         ICON_EXT_RC,        0},
-       {"rom",        ICON_EXT_ROM,       0},
-       {"rpm",        ICON_EXT_RPM,       COLOR_ARCHIVE},
-       {"rss",        ICON_EXT_RSS,       0},
-       {"rtf",        ICON_EXT_RTF,       0},
-
-       /* S */
-       {"sass",       ICON_EXT_SASS,      COLOR_CSS},
-       {"scss",       ICON_EXT_SCSS,      COLOR_CSS},
-       {"so",         ICON_EXT_SO,        0},
-       {"scala",      ICON_EXT_SCALA,     COLOR_SCALA},
-       {"sh",         ICON_EXT_SH,        COLOR_SHELL},
-       {"slim",       ICON_EXT_SLIM,      COLOR_DOCUMENT},
-       {"sln",        ICON_EXT_SLN,       0},
-       {"sql",        ICON_EXT_SQL,       0},
-       {"srt",        ICON_EXT_SRT,       0},
-       {"sty",        ICON_EXT_STY,       0},
-       {"sub",        ICON_EXT_SUB,       0},
-       {"svg",        ICON_EXT_SVG,       COLOR_IMAGE},
-
-       /* T */
-       {"tar",        ICON_EXT_TAR,       COLOR_ARCHIVE},
-       {"tex",        ICON_EXT_TEX,       0},
-       {"tgz",        ICON_EXT_TGZ,       COLOR_ARCHIVE},
-       {"ts",         ICON_EXT_TS,        COLOR_JAVASCRIPT},
-       {"tsx",        ICON_EXT_TSX,       COLOR_REACT},
-       {"txt",        ICON_EXT_TXT,       COLOR_DOCUMENT},
-       {"txz",        ICON_EXT_TXZ,       COLOR_ARCHIVE},
-
-       /* U */
-
-       /* V */
-       {"vid",        ICON_EXT_VID,       COLOR_VIDEO},
-       {"vim",        ICON_EXT_VIM,       COLOR_VIM},
-       {"vimrc",      ICON_EXT_VIMRC,     COLOR_VIM},
-       {"vtt",        ICON_EXT_SRT,       0},
-
-       /* W */
-       {"wav",        ICON_EXT_WAV,       COLOR_AUDIO},
-       {"webm",       ICON_EXT_WEBM,      COLOR_VIDEO},
-       {"webp",       ICON_EXT_WEBP,      COLOR_IMAGE},
-       {"wma",        ICON_EXT_WMA,       COLOR_AUDIO},
-       {"wmv",        ICON_EXT_WMV,       COLOR_VIDEO},
-
-       /* X */
-       {"xbps",       ICON_EXT_XBPS,      COLOR_ARCHIVE},
-       {"xcf",        ICON_EXT_XCF,       COLOR_IMAGE},
-       {"xhtml",      ICON_EXT_XHTML,     0},
-       {"xls",        ICON_EXT_XLS,       0},
-       {"xlsx",       ICON_EXT_XLSX,      0},
-       {"xml",        ICON_EXT_XML,       0},
-       {"xz",         ICON_EXT_XZ,        COLOR_ARCHIVE},
-
-       /* Y */
-       {"yaml",       ICON_EXT_YAML,      COLOR_DOCUMENT},
-       {"yml",        ICON_EXT_YML,       COLOR_DOCUMENT},
-
-       /* Z */
-       {"zip",        ICON_EXT_ZIP,       COLOR_ARCHIVE},
-       {"zsh",        ICON_EXT_ZSH,       COLOR_SHELL},
-       {"zst",        ICON_EXT_ZST,       COLOR_ARCHIVE},
-
-       /* Other */
-#elif defined(EMOJI)
-       /* Numbers */
-       {"1", EMOJI_MANUAL, COLOR_DOCS},
-       {"7z", EMOJI_ARCHIVE, COLOR_ARCHIVE},
-
-       /* A */
-       {"a", EMOJI_MANUAL, 0},
-       {"apk", EMOJI_ARCHIVE, COLOR_ARCHIVE},
-       {"aup", EMOJI_AUDIO, COLOR_AUDIO},
-       {"avi", EMOJI_MOVIE, COLOR_VIDEO},
-
-       /* B */
-       {"bat", EMOJI_SCRIPT, 0},
-       {"bin", EMOJI_BINARY, 0},
-       {"bmp", EMOJI_IMAGE, COLOR_IMAGE},
-       {"bz2", EMOJI_ARCHIVE, COLOR_ARCHIVE},
+       {"bat",        ICON_SCRIPT,         0},
+       {"bib",        ICON_TEX,            0},
+       {"bin",        ICON_EXT_BIN,        0},
+       {"bmp",        ICON_PICTUREFILE,    COLOR_IMAGE},
+       {"bz2",        ICON_ARCHIVE,        COLOR_ARCHIVE},
 
        /* C */
-       {"c", EMOJI_C, 0},
-       {"c++", EMOJI_CPP, 0},
-       {"cab", EMOJI_ARCHIVE, COLOR_ARCHIVE},
-       {"cbr", EMOJI_ARCHIVE, COLOR_ARCHIVE},
-       {"cbz", EMOJI_ARCHIVE, COLOR_ARCHIVE},
-       {"cc", EMOJI_CPP, 0},
-       {"class", EMOJI_JAVA, 0},
-       {"cmake", EMOJI_MAKE, 0},
-       {"conf", EMOJI_CONF, 0},
-       {"cpio", EMOJI_ARCHIVE, COLOR_ARCHIVE},
-       {"cpp", EMOJI_CPP, 0},
-       {"css", EMOJI_STYLESHEET, 0},
-       {"cue", EMOJI_AUDIO, COLOR_AUDIO},
-       {"cvs", EMOJI_CONF, 0},
-       {"csv", EMOJI_TABLE, 0},
-       {"cxx", EMOJI_CPP, 0},
+       {"c",          ICON_C,              COLOR_C},
+       {"c++",        ICON_CPLUSPLUS,      COLOR_C},
+       {"cabal",      ICON_HASKELL,        COLOR_VIDEO},
+       {"cab",        ICON_ARCHIVE,        COLOR_ARCHIVE},
+       {"cbr",        ICON_ARCHIVE,        COLOR_ARCHIVE},
+       {"cbz",        ICON_ARCHIVE,        COLOR_ARCHIVE},
+       {"cc",         ICON_CPLUSPLUS,      COLOR_C},
+       {"class",      ICON_JAVA,           COLOR_JAVA},
+       {"clj",        ICON_CLOJURE,        0},
+       {"cljc",       ICON_CLOJURE,        0},
+       {"cljs",       ICON_CLOJURE,        0},
+       {"cls",        ICON_TEX,            0},
+       {"cmake",      ICON_MAKEFILE,       0},
+       {"coffee",     ICON_EXT_COFFEE,     0},
+       {"conf",       ICON_CONFIGURE,      0},
+       {"cpio",       ICON_ARCHIVE,        COLOR_ARCHIVE},
+       {"cpp",        ICON_CPLUSPLUS,      COLOR_C},
+       {"css",        ICON_EXT_CSS,        COLOR_CSS},
+       {"cue",        ICON_PLAYLIST,       COLOR_AUDIO},
+       {"cvs",        ICON_CONFIGURE,      0},
+       {"cxx",        ICON_CPLUSPLUS,      COLOR_C},
 
        /* D */
-       {"db", EMOJI_DATABASE, 0},
-       {"deb", EMOJI_LINUX, COLOR_ARCHIVE},
-       {"diff", EMOJI_DIFF, 0},
-       {"djvu", EMOJI_PDF, COLOR_DOCS},
-       {"dll", EMOJI_MANUAL, 0},
-       {"doc", EMOJI_WORD, 0},
-       {"docx", EMOJI_WORD, 0},
+       {"db",         ICON_DATABASE,       0},
+       {"deb",        ICON_EXT_DEB,        COLOR_ARCHIVE},
+       {"diff",       ICON_EXT_DIFF,       0},
+       {"dll",        ICON_SCRIPT,         0},
+       {"doc",        ICON_WORDDOC,        COLOR_DOCUMENT},
+       {"docx",       ICON_WORDDOC,        COLOR_DOCUMENT},
 
        /* E */
-       {"elf", EMOJI_LINUX, 0},
-       {"epub", EMOJI_PDF, COLOR_DOCS},
-       {"exe", EMOJI_WINDOWS, 0},
+       {"ejs",        ICON_JAVASCRIPT,     COLOR_JAVASCRIPT},
+       {"elf",        ICON_LINUX,          0},
+       {"epub",       ICON_PDF,            COLOR_DOCS},
+       {"exe",        ICON_EXEC,           0},
 
        /* F */
-       {"flac", EMOJI_AUDIO, COLOR_AUDIO1},
-       {"flv", EMOJI_MOVIE, COLOR_VIDEO},
+       {"f#",         ICON_FSHARP,         COLOR_FSHARP},
+       {"fen",        ICON_CHESS,          0},
+       {"flac",       ICON_MUSICFILE,      COLOR_AUDIO1},
+       {"flv",        ICON_VIDEOFILE,      COLOR_VIDEO},
+       {"fs",         ICON_FSHARP,         COLOR_FSHARP},
+       {"fsi",        ICON_FSHARP,         COLOR_FSHARP},
+       {"fsscript",   ICON_FSHARP,         COLOR_FSHARP},
+       {"fsx",        ICON_FSHARP,         COLOR_FSHARP},
 
        /* G */
-       {"gem", EMOJI_ARCHIVE, 0},
-       {"gif", EMOJI_IMAGE, COLOR_IMAGE},
-       {"gpg", EMOJI_ENCRYPTED, COLOR_IMAGE},
-       {"gz", EMOJI_ARCHIVE, COLOR_ARCHIVE},
-       {"gzip", EMOJI_ARCHIVE, COLOR_ARCHIVE},
+       {"gem",        ICON_RUBY,           COLOR_RUBY},
+       {"gif",        ICON_PICTUREFILE,    COLOR_IMAGE},
+       {"go",         ICON_EXT_GO,         0},
+       {"gpg",        ICON_ENCRYPT,        COLOR_ARCHIVE},
+       {"gz",         ICON_ARCHIVE,        COLOR_ARCHIVE},
+       {"gzip",       ICON_ARCHIVE,        COLOR_ARCHIVE},
 
        /* H */
-       {"h", EMOJI_C, 0},
-       {"hh", EMOJI_CPP, 0},
-       {"htaccess", EMOJI_CONF, 0},
-       {"htpasswd", EMOJI_CONF, 0},
-       {"htm", EMOJI_WEB, 0},
-       {"html", EMOJI_WEB, 0},
-       {"hxx", EMOJI_CPP, 0},
+       {"h",          ICON_C,              COLOR_C},
+       {"hh",         ICON_CPLUSPLUS,      COLOR_C},
+       {"hpp",        ICON_CPLUSPLUS,      COLOR_C},
+       {"hs",         ICON_HASKELL,        COLOR_VIM},
+       {"htaccess",   ICON_CONFIGURE,      0},
+       {"htpasswd",   ICON_CONFIGURE,      0},
+       {"htm",        ICON_HTML,           0},
+       {"html",       ICON_HTML,           0},
+       {"hxx",        ICON_CPLUSPLUS,      COLOR_C},
 
        /* I */
-       {"ico", EMOJI_IMAGE, COLOR_IMAGE},
-       {"img", EMOJI_DISK, COLOR_ARCHIVE},
-       {"ini", EMOJI_CONF, 0},
-       {"info", EMOJI_INFO, 0},
-       {"iso", EMOJI_DISK, COLOR_ARCHIVE},
+       {"ico",        ICON_PICTUREFILE,    COLOR_IMAGE},
+       {"ini",        ICON_CONFIGURE,      0},
+       {"img",        ICON_OPTICALDISK,    COLOR_ARCHIVE},
+       {"iso",        ICON_OPTICALDISK,    COLOR_ARCHIVE},
 
        /* J */
-       {"jar", EMOJI_JAVA, 0},
-       {"java", EMOJI_JAVA, 0},
-       {"jl", EMOJI_CONF, 0},
-       {"jpeg", EMOJI_IMAGE, COLOR_IMAGE},
-       {"jpe", EMOJI_IMAGE, COLOR_IMAGE},
-       {"jpg", EMOJI_IMAGE, COLOR_IMAGE},
-       {"js", EMOJI_JAVASCRIPT, 0},
-       {"json", EMOJI_JAVASCRIPT, 0},
-       {"jsx", EMOJI_JAVASCRIPT, 0},
+       {"jar",        ICON_JAVA,           COLOR_JAVA},
+       {"java",       ICON_JAVA,           COLOR_JAVA},
+       {"jl",         ICON_CONFIGURE,      0},
+       {"jpeg",       ICON_PICTUREFILE,    COLOR_IMAGE},
+       {"jpg",        ICON_PICTUREFILE,    COLOR_IMAGE},
+       {"js",         ICON_JAVASCRIPT,     COLOR_JAVASCRIPT},
+       {"json",       ICON_EXT_JSON,       COLOR_JAVASCRIPT},
+       {"jsx",        ICON_REACT,          COLOR_REACT},
 
        /* K */
-       {"kdb", EMOJI_LOCK, 0},
-       {"kdb2", EMOJI_LOCK, 0},
-       {"kdbx", EMOJI_LOCK, 0},
 
        /* L */
-       {"lha", EMOJI_ARCHIVE, COLOR_ARCHIVE},
-       {"log", EMOJI_TEXT, 0},
-       {"lua", EMOJI_LUA, COLOR_LUA},
-       {"lzh", EMOJI_ARCHIVE, COLOR_ARCHIVE},
-       {"lzma", EMOJI_ARCHIVE, COLOR_ARCHIVE},
+       {"lha",        ICON_ARCHIVE,        COLOR_ARCHIVE},
+       {"lhs",        ICON_HASKELL,        COLOR_VIM},
+       {"log",        ICON_DOCUMENT,       0},
+       {"lua",        ICON_EXT_LUA,        COLOR_LUA},
+       {"lzh",        ICON_ARCHIVE,        COLOR_ARCHIVE},
+       {"lzma",       ICON_ARCHIVE,        COLOR_ARCHIVE},
 
        /* M */
-       {"m", EMOJI_STATS, 0},
-       {"m4a", EMOJI_AUDIO, COLOR_AUDIO},
-       {"m4v", EMOJI_MOVIE, COLOR_VIDEO},
-       {"markdown", EMOJI_NOTE, COLOR_DOCS},
-       {"md", EMOJI_NOTE, COLOR_DOCS},
-       {"me", EMOJI_NOTE, COLOR_DOCS},
-       {"mk", EMOJI_MAKE, 0},
-       {"mkv", EMOJI_MOVIE, COLOR_VIDEO},
-       {"mom", EMOJI_NOTE, COLOR_DOCS},
-       {"mov", EMOJI_MOVIE, COLOR_VIDEO},
-       {"mp3", EMOJI_AUDIO, COLOR_AUDIO},
-       {"mp4", EMOJI_MOVIE, COLOR_VIDEO1},
-       {"mpeg", EMOJI_MOVIE, COLOR_VIDEO},
-       {"mpg", EMOJI_MOVIE, COLOR_VIDEO},
-       {"ms", EMOJI_NOTE, COLOR_DOCS},
-       {"msi", EMOJI_WINDOWS, 0},
+       {"m",          ICON_EXT_M,          COLOR_C},
+       {"m4a",        ICON_MUSICFILE,      COLOR_AUDIO},
+       {"m4v",        ICON_VIDEOFILE,      COLOR_VIDEO},
+       {"markdown",   ICON_EXT_MD,         COLOR_DOCS},
+       {"mat",        ICON_EXT_MAT,        COLOR_C},
+       {"md",         ICON_EXT_MD,         COLOR_DOCS},
+       {"mk",         ICON_MAKEFILE,       0},
+       {"mkv",        ICON_VIDEOFILE,      COLOR_VIDEO},
+       {"mov",        ICON_VIDEOFILE,      COLOR_VIDEO},
+       {"mp3",        ICON_MUSICFILE,      COLOR_AUDIO},
+       {"mp4",        ICON_VIDEOFILE,      COLOR_VIDEO1},
+       {"mpeg",       ICON_VIDEOFILE,      COLOR_VIDEO},
+       {"mpg",        ICON_VIDEOFILE,      COLOR_VIDEO},
+       {"msi",        ICON_EXT_MSI,        0},
 
        /* N */
-       {"nfo", EMOJI_INFO, 0},
+       {"nix",        ICON_EXT_NIX,        COLOR_FSHARP},
 
        /* O */
-       {"o", EMOJI_MANUAL, 0},
-       {"odp", EMOJI_PRESENTATION, 0},
-       {"ods", EMOJI_TABLE, 0},
-       {"odt", EMOJI_WORD, 0},
-       {"ogg", EMOJI_AUDIO, COLOR_AUDIO},
-       {"opdownload", EMOJI_DOWNLOAD, 0},
-       {"opus", EMOJI_AUDIO, COLOR_AUDIO},
-       {"out", EMOJI_LINUX, 0},
+       {"o",          ICON_MANUAL,         0},
+       {"ogg",        ICON_MUSICFILE,      COLOR_AUDIO},
+       {"opus",       ICON_MUSICFILE,      COLOR_AUDIO},
+       {"opdownload", ICON_DOWNLOADS,      0},
+       {"out",        ICON_LINUX,          0},
 
        /* P */
-       {"part", EMOJI_DOWNLOAD, 0},
-       {"patch", EMOJI_PATCH, 0},
-       {"pdf", EMOJI_PDF, COLOR_DOCS},
-       {"php", EMOJI_WEB, 0},
-       {"png", EMOJI_IMAGE, COLOR_IMAGE},
-       {"ppt", EMOJI_PRESENTATION, 0},
-       {"pptx", EMOJI_PRESENTATION, 0},
-       {"psb", EMOJI_IMAGE, 0},
-       {"psd", EMOJI_IMAGE, 0},
-       {"py", EMOJI_PYTHON, 0},
-       {"pyc", EMOJI_PYTHON, 0},
-       {"pyd", EMOJI_PYTHON, 0},
-       {"pyo", EMOJI_PYTHON, 0},
+       {"part",       ICON_DOWNLOADS,      0},
+       {"patch",      ICON_EXT_PATCH,      0},
+       {"pdf",        ICON_PDF,            COLOR_DOCS},
+       {"pgn",        ICON_CHESS,          0},
+       {"php",        ICON_EXT_PHP,        0},
+       {"png",        ICON_PICTUREFILE,    COLOR_IMAGE},
+       {"ppt",        ICON_POWERPOINT,     0},
+       {"pptx",       ICON_POWERPOINT,     0},
+       {"psb",        ICON_PHOTOSHOP,      0},
+       {"psd",        ICON_PHOTOSHOP,      0},
+       {"py",         ICON_PYTHON,        COLOR_PYTHON},
+       {"pyc",        ICON_PYTHON,        COLOR_PYTHON},
+       {"pyd",        ICON_PYTHON,        COLOR_PYTHON},
+       {"pyo",        ICON_PYTHON,        COLOR_PYTHON},
 
        /* Q */
 
        /* R */
-       {"r", EMOJI_STATS, 0},
-       {"rar", EMOJI_ARCHIVE, COLOR_ARCHIVE},
-       {"rb", EMOJI_RUBY, COLOR_RUBY},
-       {"rc", EMOJI_CONF, 0},
-       {"rmd", EMOJI_STATS, 0},
-       {"rpm", EMOJI_ARCHIVE, COLOR_ARCHIVE},
-       {"rss", EMOJI_RSS, 0},
-       {"rtf", EMOJI_PDF, 0},
+       {"rar",        ICON_ARCHIVE,        COLOR_ARCHIVE},
+       {"rb",         ICON_RUBY,           COLOR_RUBY},
+       {"rc",         ICON_CONFIGURE,      0},
+       {"rom",        ICON_EXT_ROM,        0},
+       {"rpm",        ICON_ARCHIVE,        COLOR_ARCHIVE},
+       {"rss",        ICON_EXT_RSS,        0},
+       {"rtf",        ICON_EXT_RTF,        0},
 
        /* S */
-       {"sh", EMOJI_SCRIPT, COLOR_SHELL},
-       {"so", EMOJI_MANUAL, 0},
-       {"sql", EMOJI_DATABASE, 0},
-       {"srt", EMOJI_SUBTITLES, 0},
-       {"sub", EMOJI_SUBTITLES, 0},
-       {"svg", EMOJI_VECTOR, COLOR_IMAGE},
+       {"sass",       ICON_SASS,           COLOR_CSS},
+       {"scss",       ICON_SASS,           COLOR_CSS},
+       {"so",         ICON_MANUAL,         0},
+       {"scala",      ICON_EXT_SCALA,      COLOR_SCALA},
+       {"sh",         ICON_SCRIPT,         COLOR_SHELL},
+       {"slim",       ICON_SCRIPT,         COLOR_DOCUMENT},
+       {"sln",        ICON_EXT_SLN,        0},
+       {"sql",        ICON_DATABASE,       0},
+       {"srt",        ICON_SUBTITLE,       0},
+       {"sty",        ICON_TEX,            0},
+       {"sub",        ICON_SUBTITLE,       0},
+       {"svg",        ICON_PICTUREFILE,    COLOR_IMAGE},
 
        /* T */
-       {"tar", EMOJI_ARCHIVE, COLOR_ARCHIVE},
-       {"tex", EMOJI_TEXT, 0},
-       {"tgz", EMOJI_ARCHIVE, COLOR_ARCHIVE},
-       {"tif", EMOJI_IMAGE, COLOR_IMAGE},
-       {"tiff", EMOJI_IMAGE, COLOR_IMAGE},
-       {"torrent", EMOJI_DOWNLOAD, 0},
-       {"txt", EMOJI_TEXT, 0},
-       {"txz", EMOJI_ARCHIVE, COLOR_ARCHIVE},
+       {"tar",        ICON_ARCHIVE,        COLOR_ARCHIVE},
+       {"tex",        ICON_TEX,            0},
+       {"tgz",        ICON_ARCHIVE,        COLOR_ARCHIVE},
+       {"ts",         ICON_EXT_TS,        COLOR_JAVASCRIPT},
+       {"tsx",        ICON_REACT,          COLOR_REACT},
+       {"txt",        ICON_DOCUMENT,       COLOR_DOCUMENT},
+       {"txz",        ICON_ARCHIVE,        COLOR_ARCHIVE},
 
        /* U */
 
        /* V */
-       {"vid", EMOJI_MOVIE, COLOR_VIDEO},
-       {"vim", EMOJI_CONF, 0},
-       {"vimrc", EMOJI_CONF, 0},
-       {"vtt", EMOJI_SUBTITLES, 0},
+       {"vid",        ICON_VIDEOFILE,      COLOR_VIDEO},
+       {"vim",        ICON_VIM,            COLOR_VIM},
+       {"vimrc",      ICON_VIM,            COLOR_VIM},
+       {"vtt",        ICON_SUBTITLE,       0},
 
        /* W */
-       {"wav", EMOJI_AUDIO, COLOR_AUDIO},
-       {"webm", EMOJI_MOVIE, COLOR_VIDEO},
-       {"webp", EMOJI_IMAGE, COLOR_IMAGE},
-       {"wma", EMOJI_AUDIO, COLOR_AUDIO},
-       {"wmv", EMOJI_MOVIE, COLOR_VIDEO},
+       {"wav",        ICON_MUSICFILE,      COLOR_AUDIO},
+       {"webm",       ICON_VIDEOFILE,      COLOR_VIDEO},
+       {"webp",       ICON_PICTUREFILE,    COLOR_IMAGE},
+       {"wma",        ICON_VIDEOFILE,      COLOR_AUDIO},
+       {"wmv",        ICON_VIDEOFILE,      COLOR_VIDEO},
 
        /* X */
-       {"xbps", EMOJI_ARCHIVE, COLOR_ARCHIVE},
-       {"xcf", EMOJI_IMAGE, COLOR_IMAGE},
-       {"xhtml", EMOJI_WEB, 0},
-       {"xls", EMOJI_TABLE, 0},
-       {"xlsx", EMOJI_TABLE, 0},
-       {"xml", EMOJI_WEB, 0},
-       {"xz", EMOJI_ARCHIVE, COLOR_ARCHIVE},
+       {"xbps",       ICON_ARCHIVE,        COLOR_ARCHIVE},
+       {"xcf",        ICON_PICTUREFILE,    COLOR_IMAGE},
+       {"xhtml",      ICON_HTML,           0},
+       {"xls",        ICON_MS_EXCEL,       0},
+       {"xlsx",       ICON_MS_EXCEL,       0},
+       {"xml",        ICON_HTML,           0},
+       {"xz",         ICON_ARCHIVE,        COLOR_ARCHIVE},
 
        /* Y */
-       {"yaml", EMOJI_CONF, 0},
-       {"yml", EMOJI_CONF, 0},
+       {"yaml",       ICON_CONFIGURE,      COLOR_DOCUMENT},
+       {"yml",        ICON_CONFIGURE,      COLOR_DOCUMENT},
 
        /* Z */
-       {"zip", EMOJI_ARCHIVE, COLOR_ARCHIVE},
+       {"zip",        ICON_ARCHIVE,        COLOR_ARCHIVE},
+       {"zsh",        ICON_SCRIPT,         COLOR_SHELL},
+       {"zst",        ICON_ARCHIVE,        COLOR_ARCHIVE},
 
        /* Other */
-#endif
 };
+#endif
+
+#endif /* INCLUDE_ICONS_H */
index 1e41d0f3459a1a45da29495bf6bcada79c610f90..9e8c8aa081fdcbae9b4f88f570f4d1d37801800d 100644 (file)
--- a/src/nnn.c
+++ b/src/nnn.c
 #include "nnn.h"
 #include "dbg.h"
 
-#if defined(ICONS) || defined(NERD) || defined(EMOJI)
-#include "icons.h"
+#if defined(ICONS_IN_TERM) || defined(NERD) || defined(EMOJI)
 #define ICONS_ENABLED
+#include "icons-generated.h"
+#include "icons-hash.c"
+#include "icons.h"
 #endif
 
 #ifdef TOURBIN_QSORT
@@ -771,11 +773,6 @@ static const char * const patterns[] = {
 #define C_SOC (C_PIP + 1)   /* Socket: MediumOrchid1 */
 #define C_UND (C_SOC + 1)   /* Unknown OR 0B regular/exe file: Red1 */
 
-#ifdef ICONS_ENABLED
-/* 0-9, A-Z, OTHER = 36. */
-static ushort_t icon_positions[37];
-#endif
-
 static char gcolors[] = "c1e2272e006033f7c6d6abc4";
 static uint_t fcolors[C_UND + 1] = {0};
 
@@ -2164,30 +2161,10 @@ static bool initcurses(void *oldmask)
                        init_pair(i + 1, *pcode, -1);
                }
        }
-
 #ifdef ICONS_ENABLED
        if (!g_state.oldcolor) {
-               uchar_t icolors[COLOR_256] = {0};
-               char c;
-
-               memset(icon_positions, 0x7f, sizeof(icon_positions));
-
-               for (uint_t i = 0; i < ELEMENTS(icons_ext); ++i) {
-                       c = TOUPPER(icons_ext[i].match[0]);
-                       if (c >= 'A' && c <= 'Z') {
-                               if (icon_positions[c - 'A' + 10] == 0x7f7f)
-                                       icon_positions[c - 'A' + 10] = i;
-                       } else if (c >= '0' && c <= '9') {
-                               if (icon_positions[c - '0'] == 0x7f7f)
-                                       icon_positions[c - '0'] = i;
-                       } else if (icon_positions[36] == 0x7f7f)
-                               icon_positions[36] = i;
-
-                       if (icons_ext[i].color && !icolors[icons_ext[i].color]) {
-                               init_pair(C_UND + 1 + icons_ext[i].color, icons_ext[i].color, -1);
-                               icolors[icons_ext[i].color] = 1;
-                       }
-               }
+               for (uint_t i = 0; i < ELEMENTS(init_colors); ++i)
+                       init_pair(C_UND + 1 + init_colors[i], init_colors[i], -1);
        }
 #endif
 
@@ -3997,28 +3974,15 @@ static const struct icon_pair *get_icon(const struct entry *ent)
 
        char *tmp = xextension(ent->name, ent->nlen);
 
-       if (!tmp) {
-               if (ent->mode & 0100)
-                       return &exec_icon;
-
-               return &file_icon;
+       if (tmp) {
+               uint16_t z, k, h = icon_ext_hash(++tmp); /* ++tmp to skip '.' */
+               for (k = 0; k < ICONS_PROBE_MAX; ++k) {
+                       z = (h + k) % ELEMENTS(icons_ext);
+                       if (strcasecmp(tmp, icons_ext[z].match) == 0)
+                               return &icons_ext[z];
+               }
        }
 
-       /* Skip the . */
-       ++tmp;
-
-       if (*tmp >= '0' && *tmp <= '9')
-               i = *tmp - '0'; /* NUMBER 0-9 */
-       else if (TOUPPER(*tmp) >= 'A' && TOUPPER(*tmp) <= 'Z')
-               i = TOUPPER(*tmp) - 'A' + 10; /* LETTER A-Z */
-       else
-               i = 36; /* OTHER */
-
-       for (ushort_t j = icon_positions[i]; j < ELEMENTS(icons_ext) &&
-                       icons_ext[j].match[0] == icons_ext[icon_positions[i]].match[0]; ++j)
-               if (strcasecmp(tmp, icons_ext[j].match) == 0)
-                       return &icons_ext[j];
-
        /* If there's no match and the file is executable, icon that */
        if (ent->mode & 0100)
                return &exec_icon;
@@ -6509,7 +6473,7 @@ static void redraw(char *path)
        if (curscroll > 0) {
                move(1, 0);
 #ifdef ICONS_ENABLED
-               addstr(MD_ARROW_UPWARD);
+               addstr(ICON_ARROW_UP);
 #else
                addch('^');
 #endif
@@ -6546,7 +6510,7 @@ static void redraw(char *path)
        if (onscreen < ndents) {
                move(xlines - 2, 0);
 #ifdef ICONS_ENABLED
-               addstr(MD_ARROW_DOWNWARD);
+               addstr(ICON_ARROW_DOWN);
 #else
                addch('v');
 #endif