* Add icons * Fix build break * Fix icon position in detailed mode * Various fixes * Provision for icon specific colors No icons with oldcolor. Small optimizatons * Update Makefiles Small refinement for other matchingmaster
@@ -19,6 +19,7 @@ O_NOMOUSE := 0 # no mouse support | |||||
O_NOBATCH := 0 # no built-in batch renamer | O_NOBATCH := 0 # no built-in batch renamer | ||||
O_NOFIFO := 0 # no FIFO previewer support | O_NOFIFO := 0 # no FIFO previewer support | ||||
O_CTX8 := 0 # enable 8 contexts | O_CTX8 := 0 # enable 8 contexts | ||||
O_ICONS := 0 # support icons | |||||
# convert targets to flags for backwards compatibility | # convert targets to flags for backwards compatibility | ||||
ifneq ($(filter debug,$(MAKECMDGOALS)),) | ifneq ($(filter debug,$(MAKECMDGOALS)),) | ||||
@@ -70,6 +71,10 @@ ifeq ($(O_CTX8),1) | |||||
CPPFLAGS += -DCTX8 | CPPFLAGS += -DCTX8 | ||||
endif | endif | ||||
ifeq ($(O_ICONS),1) | |||||
CPPFLAGS += -DICONS | |||||
endif | |||||
ifeq ($(shell $(PKG_CONFIG) ncursesw && echo 1),1) | ifeq ($(shell $(PKG_CONFIG) ncursesw && echo 1),1) | ||||
CFLAGS_CURSES ?= $(shell $(PKG_CONFIG) --cflags ncursesw) | CFLAGS_CURSES ?= $(shell $(PKG_CONFIG) --cflags ncursesw) | ||||
LDLIBS_CURSES ?= $(shell $(PKG_CONFIG) --libs ncursesw) | LDLIBS_CURSES ?= $(shell $(PKG_CONFIG) --libs ncursesw) | ||||
@@ -17,6 +17,7 @@ O_NOMOUSE := 0 # no mouse support | |||||
O_NOBATCH := 0 # no built-in batch renamer | O_NOBATCH := 0 # no built-in batch renamer | ||||
O_NOFIFO := 0 # no FIFO previewer support | O_NOFIFO := 0 # no FIFO previewer support | ||||
O_CTX8 := 0 # enable 8 contexts | O_CTX8 := 0 # enable 8 contexts | ||||
O_ICONS := 0 # support icons | |||||
# convert targets to flags for backwards compatibility | # convert targets to flags for backwards compatibility | ||||
ifneq ($(filter debug,$(MAKECMDGOALS)),) | ifneq ($(filter debug,$(MAKECMDGOALS)),) | ||||
@@ -69,6 +70,10 @@ ifeq ($(O_CTX8),1) | |||||
CPPFLAGS += -DCTX8 | CPPFLAGS += -DCTX8 | ||||
endif | endif | ||||
ifeq ($(O_ICONS),1) | |||||
CPPFLAGS += -DICONS | |||||
endif | |||||
ifeq ($(shell $(PKG_CONFIG) ncursesw && echo 1),1) | ifeq ($(shell $(PKG_CONFIG) ncursesw && echo 1),1) | ||||
CFLAGS_CURSES ?= $(shell $(PKG_CONFIG) --cflags ncursesw) | CFLAGS_CURSES ?= $(shell $(PKG_CONFIG) --cflags ncursesw) | ||||
LDLIBS_CURSES ?= $(shell $(PKG_CONFIG) --libs ncursesw) | LDLIBS_CURSES ?= $(shell $(PKG_CONFIG) --libs ncursesw) | ||||
@@ -0,0 +1,233 @@ | |||||
#include "icons-in-terminal.h" | |||||
struct icon_pair { | |||||
const char *match; | |||||
const char *icon; | |||||
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 "" | |||||
#define ICON_PADDING_RIGHT " " | |||||
/* | |||||
* 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. | |||||
*/ | |||||
static const struct icon_pair dir_icon = {"", FA_FOLDER, 0}; | |||||
static const struct icon_pair file_icon = {"", FA_FILE, 0}; | |||||
/* All entries are case-insensitive */ | |||||
static const struct icon_pair icons_name[] = { | |||||
{".git", FA_GITHUB_SQUARE, 0}, | |||||
{"Desktop", FA_HOME, 0}, | |||||
{"Documents", FA_LIST_ALT, 0}, | |||||
{"Downloads", FA_DOWNLOAD, 0}, | |||||
{"Music", FA_MUSIC, 0}, | |||||
{"node_modules", MFIZZ_NPM, 0}, | |||||
{"Pictures", FA_IMAGE, 0}, | |||||
{"Public", FA_INBOX, 0}, | |||||
{"Templates", FA_COG, 0}, | |||||
{"Videos", FA_FILM, 0}, | |||||
}; | |||||
/* | |||||
* New entries should bu 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[] = { | |||||
/* Numbers */ | |||||
{"7z", FA_FILE_ARCHIVE_O, 0}, | |||||
/* A */ | |||||
{"a", FILE_MANPAGE, 0}, | |||||
{"apk", FA_FILE_ARCHIVE_O, 0}, | |||||
{"asm", FILE_NASM, 0}, | |||||
{"aup", FA_FILE_AUDIO_O, 0}, | |||||
{"avi", FA_FILE_MOVIE_O, 0}, | |||||
/* B */ | |||||
{"bat", MFIZZ_SCRIPT, 0}, | |||||
{"bmp", FA_FILE_IMAGE_O, 0}, | |||||
{"bz2", FA_FILE_ARCHIVE_O, 0}, | |||||
/* C */ | |||||
{"c", MFIZZ_C, 0}, | |||||
{"c++", MFIZZ_CPLUSPLUS, 0}, | |||||
{"cab", FA_FILE_ARCHIVE_O, 0}, | |||||
{"cbr", FA_FILE_ARCHIVE_O, 0}, | |||||
{"cbz", FA_FILE_ARCHIVE_O, 0}, | |||||
{"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, 0}, | |||||
{"cpp", MFIZZ_CPLUSPLUS, 0}, | |||||
{"css", MFIZZ_CSS3, 0}, | |||||
{"cue", FA_FILE_AUDIO_O, 0}, | |||||
{"cvs", FA_COGS, 0}, | |||||
{"cxx", MFIZZ_CPLUSPLUS, 0}, | |||||
/* D */ | |||||
{"db", MFIZZ_DATABASE_ALT2, 0}, | |||||
{"deb", MFIZZ_DEBIAN, 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, 0}, | |||||
{"exe", FA_WINDOWS, 0}, | |||||
/* F */ | |||||
{"f#", DEV_FSHARP, 0}, | |||||
{"flac", FA_FILE_AUDIO_O, 0}, | |||||
{"flv", FA_FILE_MOVIE_O, 0}, | |||||
{"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, 0}, | |||||
{"go", MFIZZ_GO, 0}, | |||||
{"gz", FA_FILE_ARCHIVE_O, 0}, | |||||
{"gzip", FA_FILE_ARCHIVE_O, 0}, | |||||
/* 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, 0}, | |||||
{"img", FA_FILE_IMAGE_O, 0}, | |||||
{"ini", FA_COGS, 0}, | |||||
{"iso", LINEA_MUSIC_CD, 0}, | |||||
/* J */ | |||||
{"jar", MFIZZ_JAVA, 0}, | |||||
{"java", MFIZZ_JAVA, 0}, | |||||
{"jl", FA_COGS, 0}, | |||||
{"jpeg", FA_FILE_IMAGE_O, 0}, | |||||
{"jpg", FA_FILE_IMAGE_O, 0}, | |||||
{"js", DEV_JAVASCRIPT_BADGE, 0}, | |||||
{"json", MFIZZ_JAVASCRIPT, 0}, | |||||
{"jsx", FILE_JSX, 0}, | |||||
/* K */ | |||||
/* L */ | |||||
{"lha", FA_FILE_ARCHIVE_O, 0}, | |||||
{"log", FA_FILE_TEXT_O, 0}, | |||||
{"lua", FILE_LUA, 0}, | |||||
{"lzh", FA_FILE_ARCHIVE_O, 0}, | |||||
{"lzma", FA_FILE_ARCHIVE_O, 0}, | |||||
/* M */ | |||||
{"m4a", FA_FILE_AUDIO_O, 0}, | |||||
{"m4v", FA_FILE_MOVIE_O, 0}, | |||||
{"markdown", OCT_MARKDOWN, 0}, | |||||
{"md", OCT_MARKDOWN, 0}, | |||||
{"mkv", FA_FILE_MOVIE_O, 0}, | |||||
{"mov", FA_FILE_MOVIE_O, 0}, | |||||
{"mp3", FA_FILE_AUDIO_O, 0}, | |||||
{"mp4", FA_FILE_MOVIE_O, 0}, | |||||
{"mpeg", FA_FILE_MOVIE_O, 0}, | |||||
{"mpg", FA_FILE_MOVIE_O, 0}, | |||||
{"msi", FA_WINDOWS, 0}, | |||||
/* N */ | |||||
/* O */ | |||||
{"o", FILE_MANPAGE, 0}, | |||||
{"ogg", FA_FILE_AUDIO_O, 0}, | |||||
{"out", FA_LINUX, 0}, | |||||
/* P */ | |||||
{"pdf", FA_FILE_PDF_O, 0}, | |||||
{"php", MFIZZ_PHP, 0}, | |||||
{"png", FA_FILE_IMAGE_O, 0}, | |||||
{"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, 0}, | |||||
{"rc", FA_COGS, 0}, | |||||
{"rom", FA_LOCK, 0}, | |||||
{"rpm", FA_FILE_ARCHIVE_O, 0}, | |||||
{"rss", FA_RSS_SQUARE, 0}, | |||||
{"rtf", FA_FILE_PDF_O, 0}, | |||||
/* S */ | |||||
{"so", FILE_MANPAGE, 0}, | |||||
{"scala", MFIZZ_SCALA, 0}, | |||||
{"sh", MFIZZ_SCRIPT, 0}, | |||||
{"slim", FA_FILE_CODE_O, 0}, | |||||
{"sln", DEV_VISUALSTUDIO, 0}, | |||||
{"sql", MFIZZ_MYSQL, 0}, | |||||
{"svg", FA_FILE_IMAGE_O, 0}, | |||||
/* T */ | |||||
{"tar", FA_FILE_ARCHIVE_O, 0}, | |||||
{"tex", FILE_TEX, 0}, | |||||
{"tgz", FA_FILE_ARCHIVE_O, 0}, | |||||
{"ts", FILE_TS, 0}, | |||||
{"tsx", FILE_TSX, 0}, | |||||
{"txt", FA_FILE_TEXT_O, 0}, | |||||
/* U */ | |||||
/* V */ | |||||
{"vim", DEV_VIM, 0}, | |||||
{"vimrc", DEV_VIM, 0}, | |||||
/* W */ | |||||
{"wav", FA_FILE_AUDIO_O, 0}, | |||||
{"webm", FA_FILE_MOVIE_O, 0}, | |||||
/* X */ | |||||
{"xbps", FA_FILE_ARCHIVE_O, 0}, | |||||
{"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, 0}, | |||||
/* Y */ | |||||
{"yaml", FA_COGS, 0}, | |||||
{"yml", FA_COGS, 0}, | |||||
/* Z */ | |||||
{"zip", FA_FILE_ARCHIVE_O, 0} | |||||
/* Other */ | |||||
}; |
@@ -112,6 +112,10 @@ | |||||
#include "nnn.h" | #include "nnn.h" | ||||
#include "dbg.h" | #include "dbg.h" | ||||
#ifdef ICONS | |||||
#include "icons.h" | |||||
#endif | |||||
/* Macro definitions */ | /* Macro definitions */ | ||||
#define VERSION "3.3" | #define VERSION "3.3" | ||||
#define GENERAL_INFO "BSD 2-Clause\nhttps://github.com/jarun/nnn" | #define GENERAL_INFO "BSD 2-Clause\nhttps://github.com/jarun/nnn" | ||||
@@ -681,6 +685,11 @@ static const char * const patterns[] = { | |||||
#define C_SOC (C_PIP + 1) /* Socket: MediumOrchid1 */ | #define C_SOC (C_PIP + 1) /* Socket: MediumOrchid1 */ | ||||
#define C_UND (C_SOC + 1) /* Unknown OR 0B regular/exe file: Red1 */ | #define C_UND (C_SOC + 1) /* Unknown OR 0B regular/exe file: Red1 */ | ||||
#ifdef ICONS | |||||
/* NUMBERS, A-Z, OTHER = 28. */ | |||||
static ushort icon_positions[28]; | |||||
#endif | |||||
static char gcolors[] = "c1e2272e006033f7c6d6abc4"; | static char gcolors[] = "c1e2272e006033f7c6d6abc4"; | ||||
static uint fcolors[C_UND + 1] = {0}; | static uint fcolors[C_UND + 1] = {0}; | ||||
@@ -1713,6 +1722,27 @@ static bool initcurses(void *oldmask) | |||||
} | } | ||||
} | } | ||||
#ifdef ICONS | |||||
if (!g_state.oldcolor) { | |||||
memset(icon_positions, 0x7f, sizeof(icon_positions)); | |||||
if (icons_ext[0].match[0] >= '0' && icons_ext[0].match[0] <= '9') | |||||
icon_positions[0] = 0; | |||||
char c; | |||||
for (uint i = 0; i < sizeof(icons_ext)/sizeof(struct icon_pair); ++i) { | |||||
c = TOUPPER(icons_ext[i].match[0]); | |||||
if (c >= 'A' && c <= 'Z') { | |||||
if (icon_positions[c - 'A' + 1] == 0x7f7f) | |||||
icon_positions[c - 'A' + 1] = i; | |||||
} else if (!(c >= '0' && c <= '9')) { | |||||
if (icon_positions[27] == 0x7f7f) | |||||
icon_positions[27] = i; | |||||
} | |||||
} | |||||
} | |||||
#endif | |||||
settimeout(); /* One second */ | settimeout(); /* One second */ | ||||
set_escdelay(25); | set_escdelay(25); | ||||
return TRUE; | return TRUE; | ||||
@@ -3425,6 +3455,42 @@ static char *get_lsperms(mode_t mode) | |||||
return bits; | return bits; | ||||
} | } | ||||
#ifdef ICONS | |||||
static const char *get_icon(const struct entry *ent){ | |||||
ushort i, j; | |||||
char *tmp; | |||||
for (i = 0; i < sizeof(icons_name)/sizeof(struct icon_pair); ++i) | |||||
if (strcasecmp(ent->name, icons_name[i].match) == 0) | |||||
return icons_name[i].icon; | |||||
if (ent->flags & DIR_OR_LINK_TO_DIR) | |||||
return dir_icon.icon; | |||||
tmp = xextension(ent->name, ent->nlen); | |||||
if (!tmp) | |||||
return file_icon.icon; | |||||
/* Skip the . */ | |||||
++tmp; | |||||
if (*tmp >= '0' && *tmp <= '9') | |||||
i = 0; /* NUMBER */ | |||||
else if (TOUPPER(*tmp) >= 'A' && TOUPPER(*tmp) <= 'Z') | |||||
i = TOUPPER(*tmp) - 'A' + 1; /* LETTER A-Z */ | |||||
else | |||||
i = 27; /* OTHER */ | |||||
for (j = icon_positions[i]; j < sizeof(icons_ext)/sizeof(struct icon_pair) && | |||||
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].icon; | |||||
} | |||||
return file_icon.icon; | |||||
} | |||||
#endif | |||||
static void print_time(const time_t *timep) | static void print_time(const time_t *timep) | ||||
{ | { | ||||
struct tm *t = localtime(timep); | struct tm *t = localtime(timep); | ||||
@@ -3511,6 +3577,14 @@ static void printent(const struct entry *ent, uint namecols, bool sel) | |||||
if (attrs) | if (attrs) | ||||
attron(attrs); | attron(attrs); | ||||
#ifdef ICONS | |||||
if (!g_state.oldcolor) { | |||||
addstr(ICON_PADDING_LEFT); | |||||
addstr(get_icon(ent)); | |||||
addstr(ICON_PADDING_RIGHT); | |||||
} | |||||
#endif | |||||
#ifndef NOLOCALE | #ifndef NOLOCALE | ||||
addwstr(unescape(ent->name, namecols)); | addwstr(unescape(ent->name, namecols)); | ||||
#else | #else | ||||
@@ -3643,11 +3717,21 @@ static void printent_long(const struct entry *ent, uint namecols, bool sel) | |||||
attron(attrs); | attron(attrs); | ||||
} | } | ||||
} | } | ||||
#ifdef ICONS | |||||
if (!g_state.oldcolor) { | |||||
addstr(ICON_PADDING_LEFT); | |||||
addstr(get_icon(ent)); | |||||
addstr(ICON_PADDING_RIGHT); | |||||
} | |||||
#endif | |||||
#ifndef NOLOCALE | #ifndef NOLOCALE | ||||
addwstr(unescape(ent->name, namecols)); | addwstr(unescape(ent->name, namecols)); | ||||
#else | #else | ||||
addstr(unescape(ent->name, MIN(namecols, ent->nlen) + 1)); | addstr(unescape(ent->name, MIN(namecols, ent->nlen) + 1)); | ||||
#endif | #endif | ||||
if (attrs) | if (attrs) | ||||
attroff(attrs); | attroff(attrs); | ||||
if (ind2) | if (ind2) | ||||
@@ -5418,11 +5502,18 @@ static int adjust_cols(int ncols) | |||||
if (ncols < 36) { | if (ncols < 36) { | ||||
cfg.showdetail ^= 1; | cfg.showdetail ^= 1; | ||||
printptr = &printent; | printptr = &printent; | ||||
ncols -= 3; /* Preceding space, indicator, newline */ | |||||
} else | |||||
ncols -= 35; | |||||
} else | |||||
ncols -= 3; /* Preceding space, indicator, newline */ | |||||
} else { | |||||
/* 3 more accounted for below */ | |||||
ncols -= 32; | |||||
} | |||||
} | |||||
/* 3 = Preceding space, indicator, newline */ | |||||
#ifdef ICONS | |||||
ncols -= 3 + xstrlen(ICON_PADDING_LEFT) + xstrlen(ICON_PADDING_RIGHT) + 1; | |||||
#else | |||||
ncols -= 3; | |||||
#endif | |||||
return ncols; | return ncols; | ||||
} | } | ||||