diff --git a/Makefile b/Makefile index 11e21eb1..0916948f 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,7 @@ O_NOFIFO := 0 # no FIFO previewer support O_CTX8 := 0 # enable 8 contexts O_ICONS := 0 # support icons-in-terminal O_NERD := 0 # support icons-nerdfont +O_EMOJI := 0 # support emoji O_QSORT := 0 # use Alexey Tourbin's QSORT implementation O_BENCH := 0 # benchmark mode (stops at first user input) O_NOSSN := 0 # disable session support @@ -69,6 +70,8 @@ ifeq ($(strip $(O_NOLC)),1) $(info *** Ignoring O_NOLC since O_ICONS is set ***) else ifeq ($(strip $(O_NERD)),1) $(info *** Ignoring O_NOLC since O_NERD is set ***) + else ifeq ($(strip $(O_EMOJI)),1) +$(info *** Ignoring O_NOLC since O_EMOJI is set ***) else CPPFLAGS += -DNOLC endif @@ -98,6 +101,10 @@ ifeq ($(strip $(O_NERD)),1) CPPFLAGS += -DNERD endif +ifeq ($(strip $(O_EMOJI)),1) + CPPFLAGS += -DEMOJI +endif + ifeq ($(strip $(O_QSORT)),1) CPPFLAGS += -DTOURBIN_QSORT endif @@ -227,6 +234,9 @@ static: # static binary with patched nerd font support make O_STATIC=1 O_NERD=1 strip mv $(BIN) $(BIN)-nerd-static + # static binary with emoji support + make O_STATIC=1 O_EMOJI=1 strip + mv $(BIN) $(BIN)-emoji-static musl: cp misc/musl/musl-static-ubuntu.sh . @@ -254,6 +264,7 @@ upload-local: sign static musl upx -qqq $(BIN)-static upx -qqq $(BIN)-icons-static upx -qqq $(BIN)-nerd-static + upx -qqq $(BIN)-emoji-static # upload static binary tar -zcf $(BIN)-static-$(VERSION).x86_64.tar.gz $(BIN)-static curl -XPOST 'https://uploads.github.com/repos/jarun/nnn/releases/$(ID)/assets?name=$(BIN)-static-$(VERSION).x86_64.tar.gz' \ @@ -269,6 +280,11 @@ upload-local: sign static musl curl -XPOST 'https://uploads.github.com/repos/jarun/nnn/releases/$(ID)/assets?name=$(BIN)-nerd-static-$(VERSION).x86_64.tar.gz' \ -H 'Authorization: token $(NNN_SIG_UPLOAD_TOKEN)' -H 'Content-Type: application/x-sharedlib' \ --upload-file $(BIN)-nerd-static-$(VERSION).x86_64.tar.gz + # upload emoji compiled static binary + tar -zcf $(BIN)-emoji-static-$(VERSION).x86_64.tar.gz $(BIN)-icons-static + curl -XPOST 'https://uploads.github.com/repos/jarun/nnn/releases/$(ID)/assets?name=$(BIN)-emoji-static-$(VERSION).x86_64.tar.gz' \ + -H 'Authorization: token $(NNN_SIG_UPLOAD_TOKEN)' -H 'Content-Type: application/x-sharedlib' \ + --upload-file $(BIN)-emoji-static-$(VERSION).x86_64.tar.gz # upload musl static binary tar -zcf $(BIN)-musl-static-$(VERSION).x86_64.tar.gz $(BIN)-musl-static curl -XPOST 'https://uploads.github.com/repos/jarun/nnn/releases/$(ID)/assets?name=$(BIN)-musl-static-$(VERSION).x86_64.tar.gz' \ @@ -276,7 +292,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)-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 prepatch: ifeq ($(strip $(O_NAMEFIRST)),1) diff --git a/README.md b/README.md index 6da41206..f108d882 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ Runs on the Pi, [Termux](https://www.youtube.com/embed/AbaauM7gUJw) (Android), L - Preview hovered files in FIFO-based previewer - Open with desktop opener or specify a custom opener - File-specific colors (or minimal _dirs in context color_) - - Icons (customize and compile-in) + - Icons or Emojis support (customize and compile-in) - Plugin for image, video and audio thumbnails - Create, list, extract (to), mount (FUSE based) archives - Option to open all text files in `$EDITOR` diff --git a/src/icons-emoji.h b/src/icons-emoji.h new file mode 100644 index 00000000..3b256226 --- /dev/null +++ b/src/icons-emoji.h @@ -0,0 +1,72 @@ +#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_BOOKS "📚" +#define EMOJI_BRIEFCASE "💼" +#define EMOJI_C "📑" +#define EMOJI_CHANGELOG "🔖" +#define EMOJI_CLOUD "☁️ " +#define EMOJI_CODE "🧮" +#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_GAME "🧩" +#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_LUA "🌘" +#define EMOJI_MAKE "🚧" +#define EMOJI_MANUAL "📔" +#define EMOJI_MOVIE "🎬" +#define EMOJI_MUSIC EMOJI_AUDIO +#define EMOJI_NOTE "📝" +#define EMOJI_NOTES "📓" +#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.h b/src/icons.h index 35d3252a..5e2d14ec 100644 --- a/src/icons.h +++ b/src/icons.h @@ -4,6 +4,8 @@ #include "icons-in-terminal.h" #elif defined(NERD) #include "icons-nerdfont.h" +#elif defined(EMOJI) +#include "icons-emoji.h" #endif struct icon_pair { @@ -23,9 +25,19 @@ struct icon_pair { */ #define ICON_PADDING_LEFT "" -#define ICON_PADDING_LEFT_LEN (0) +#if defined(EMOJI) +#define ICON_PADDING_RIGHT " " +#else #define ICON_PADDING_RIGHT " " -#define ICON_PADDING_RIGHT_LEN (2) +#endif +#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 #define COLOR_VIDEO 93 /* Purple */ #define COLOR_AUDIO 220 /* Gold1 */ @@ -60,6 +72,10 @@ static const struct icon_pair exec_icon = {"", FA_COG, 0}; 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}; #endif /* All entries are case-insensitive */ @@ -93,6 +109,25 @@ static const struct icon_pair icons_name[] = { {"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}, + {"Cloud", EMOJI_CLOUD, 0}, + {"Code", EMOJI_CODE, 0}, + {"Games", EMOJI_GAME, 0}, + {"Literature", EMOJI_BOOKS, 0}, + {"Notes", EMOJI_NOTES, 0}, + {"CHANGELOG", EMOJI_CHANGELOG, COLOR_DOCS}, + {"configure", EMOJI_CONF, 0}, + {"License", EMOJI_LICENSE, COLOR_DOCS}, + {"Makefile", EMOJI_MAKE, 0}, #endif }; @@ -528,5 +563,216 @@ static const struct icon_pair icons_ext[] = { {"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}, + {"bib", EMOJI_BOOKS, 0}, + {"bmp", EMOJI_IMAGE, COLOR_IMAGE}, + {"bz2", EMOJI_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}, + + /* 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}, + + /* E */ + {"elf", EMOJI_LINUX, 0}, + {"epub", EMOJI_PDF, COLOR_DOCS}, + {"exe", EMOJI_WINDOWS, 0}, + + /* F */ + {"flac", EMOJI_AUDIO, COLOR_AUDIO}, + {"flv", EMOJI_MOVIE, COLOR_VIDEO}, + + /* G */ + {"gba", EMOJI_GAME, 0}, + {"gdi", EMOJI_GAME, 0}, + {"gem", EMOJI_ARCHIVE, 0}, + {"gif", EMOJI_IMAGE, COLOR_IMAGE}, + {"gpg", EMOJI_ENCRYPTED, COLOR_IMAGE}, + {"gz", EMOJI_ARCHIVE, COLOR_ARCHIVE}, + {"gzip", EMOJI_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}, + + /* I */ + {"ico", EMOJI_IMAGE, COLOR_IMAGE}, + {"img", EMOJI_DISK, COLOR_ARCHIVE}, + {"ini", EMOJI_CONF, 0}, + {"info", EMOJI_INFO, 0}, + {"iso", EMOJI_DISK, COLOR_ARCHIVE}, + + /* J */ + {"jar", EMOJI_JAVA, 0}, + {"java", EMOJI_JAVA, 0}, + {"jl", EMOJI_CONF, 0}, + {"jpeg", EMOJI_PHOTO, COLOR_IMAGE}, + {"jpe", EMOJI_PHOTO, COLOR_IMAGE}, + {"jpg", EMOJI_PHOTO, COLOR_IMAGE}, + {"js", EMOJI_JAVASCRIPT, 0}, + {"json", EMOJI_JAVASCRIPT, 0}, + {"jsx", EMOJI_JAVASCRIPT, 0}, + + /* K */ + + /* 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}, + + /* 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_VIDEO}, + {"mpeg", EMOJI_MOVIE, COLOR_VIDEO}, + {"mpg", EMOJI_MOVIE, COLOR_VIDEO}, + {"ms", EMOJI_NOTE, COLOR_DOCS}, + {"msi", EMOJI_WINDOWS, 0}, + + /* N */ + {"n64", EMOJI_GAME, 0}, + {"nes", EMOJI_GAME, 0}, + {"nfo", EMOJI_INFO, 0}, + + /* 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}, + + /* 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}, + + /* 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}, + + /* 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}, + + /* 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}, + + /* U */ + + /* V */ + {"v64", EMOJI_GAME, 0}, + {"vid", EMOJI_MOVIE, COLOR_VIDEO}, + {"vim", EMOJI_CONF, 0}, + {"vimrc", EMOJI_CONF, 0}, + {"vtt", EMOJI_SUBTITLES, 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}, + + /* 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}, + + /* Y */ + {"yaml", EMOJI_CONF, 0}, + {"yml", EMOJI_CONF, 0}, + + /* Z */ + {"z64", EMOJI_GAME, 0}, + {"zip", EMOJI_ARCHIVE, COLOR_ARCHIVE}, + + /* Other */ #endif }; diff --git a/src/nnn.c b/src/nnn.c index 46daf974..f6c5b5ed 100644 --- a/src/nnn.c +++ b/src/nnn.c @@ -124,7 +124,7 @@ #include "nnn.h" #include "dbg.h" -#if defined(ICONS) || defined(NERD) +#if defined(ICONS) || defined(NERD) || defined(EMOJI) #include "icons.h" #define ICONS_ENABLED #endif @@ -6371,7 +6371,7 @@ static int adjust_cols(int n) { /* Calculate the number of cols available to print entry name */ #ifdef ICONS_ENABLED - n -= (g_state.oldcolor ? 0 : 1 + ICON_PADDING_LEFT_LEN + ICON_PADDING_RIGHT_LEN); + n -= (g_state.oldcolor ? 0 : ICON_SIZE + ICON_PADDING_LEFT_LEN + ICON_PADDING_RIGHT_LEN); #endif if (cfg.showdetail) { /* Fallback to light mode if less than 35 columns */