mainline.diff (6913B)
1 # Description: Prints filenames first in the detail view. Prints user/group 2 # columns when a directory contains different users/groups. 3 # 4 # Author: Luuk van Baal 5 6 diff --git a/src/nnn.c b/src/nnn.c 7 index 88263beb..55f32e73 100644 8 --- a/src/nnn.c 9 +++ b/src/nnn.c 10 @@ -390,6 +390,10 @@ typedef struct { 11 } session_header_t; 12 #endif 13 14 +static struct { 15 + ushort_t maxnameln, maxsizeln, maxuidln, maxgidln, maxentln, uidln, gidln, printguid; 16 +} dtls; 17 + 18 /* GLOBALS */ 19 20 /* Configuration, contexts */ 21 @@ -1083,10 +1087,12 @@ static char *getpwname(uid_t uid) 22 static char *namecache; 23 24 if (uidcache != uid) { 25 + if (dtls.maxuidln && !dtls.printguid) dtls.printguid = 1; 26 struct passwd *pw = getpwuid(uid); 27 28 uidcache = uid; 29 namecache = pw ? pw->pw_name : NULL; 30 + dtls.uidln = xstrlen(namecache ? namecache : xitoa(uid)); 31 } 32 33 return namecache ? namecache : xitoa(uid); 34 @@ -1098,10 +1104,12 @@ static char *getgrname(gid_t gid) 35 static char *grpcache; 36 37 if (gidcache != gid) { 38 + if (dtls.maxgidln && !dtls.printguid) dtls.printguid = 1; 39 struct group *gr = getgrgid(gid); 40 41 gidcache = gid; 42 grpcache = gr ? gr->gr_name : NULL; 43 + dtls.gidln = xstrlen(grpcache ? grpcache : xitoa(gid)); 44 } 45 46 return grpcache ? grpcache : xitoa(gid); 47 @@ -3829,14 +3837,13 @@ static void resetdircolor(int flags) 48 * Max supported str length: NAME_MAX; 49 */ 50 #ifdef NOLC 51 -static char *unescape(const char *str, uint_t maxcols) 52 +static size_t unescape(const char *str, uint_t maxcols) 53 { 54 char * const wbuf = g_buf; 55 char *buf = wbuf; 56 - 57 - xstrsncpy(wbuf, str, maxcols); 58 + size_t len = xstrsncpy(wbuf, str, maxcols); 59 #else 60 -static wchar_t *unescape(const char *str, uint_t maxcols) 61 +static size_t unescape(const char *str, uint_t maxcols) 62 { 63 wchar_t * const wbuf = (wchar_t *)g_buf; 64 wchar_t *buf = wbuf; 65 @@ -3861,7 +3868,7 @@ static wchar_t *unescape(const char *str, uint_t maxcols) 66 ++buf; 67 } 68 69 - return wbuf; 70 + return len; 71 } 72 73 static off_t get_size(off_t size, off_t *pval, int comp) 74 @@ -4122,33 +4129,7 @@ static uchar_t get_color_pair_name_ind(const struct entry *ent, char *pind, int 75 static void printent(const struct entry *ent, uint_t namecols, bool sel) 76 { 77 char ind = '\0'; 78 - int attrs; 79 - 80 - if (cfg.showdetail) { 81 - int type = ent->mode & S_IFMT; 82 - char perms[6] = {' ', ' ', (char)('0' + ((ent->mode >> 6) & 7)), 83 - (char)('0' + ((ent->mode >> 3) & 7)), 84 - (char)('0' + (ent->mode & 7)), '\0'}; 85 - 86 - addch(' '); 87 - attrs = g_state.oldcolor ? (resetdircolor(ent->flags), A_DIM) 88 - : (fcolors[C_MIS] ? COLOR_PAIR(C_MIS) : 0); 89 - if (attrs) 90 - attron(attrs); 91 - 92 - /* Print details */ 93 - print_time(&ent->sec); 94 - 95 - printw("%s%9s ", perms, (type == S_IFREG || type == S_IFDIR) 96 - ? coolsize(cfg.blkorder ? (blkcnt_t)ent->blocks << blk_shift : ent->size) 97 - : (type = (uchar_t)get_detail_ind(ent->mode), (char *)&type)); 98 - 99 - if (attrs) 100 - attroff(attrs); 101 - } 102 - 103 - attrs = 0; 104 - 105 + int attrs = 0, namelen; 106 uchar_t color_pair = get_color_pair_name_ind(ent, &ind, &attrs); 107 108 addch((ent->flags & FILE_SELECTED) ? '+' | A_REVERSE | A_BOLD : ' '); 109 @@ -4173,15 +4154,40 @@ static void printent(const struct entry *ent, uint_t namecols, bool sel) 110 ++namecols; 111 112 #ifndef NOLC 113 - addwstr(unescape(ent->name, namecols)); 114 + addwstr((namelen = unescape(ent->name, namecols), (wchar_t *)g_buf)); 115 #else 116 - addstr(unescape(ent->name, MIN(namecols, ent->nlen) + 1)); 117 + addstr((namelen = unescape(ent->name, MIN(namecols, ent->nlen) + 1), (char *)g_buf)); 118 #endif 119 120 - if (attrs) 121 + if (!sel && attrs) 122 attroff(attrs); 123 if (ind) 124 addch(ind); 125 + if (cfg.showdetail) { 126 + int type = ent->mode & S_IFMT; 127 + char perms[6] = {(char)('0' + ((ent->mode >> 6) & 7)), 128 + (char)('0' + ((ent->mode >> 3) & 7)), 129 + (char)('0' + (ent->mode & 7)), ' ', ' ', '\0'}, *size = NULL; 130 + 131 + if (attrs) 132 + attron(attrs); 133 + if (!g_state.oldcolor && (type == S_IFDIR || (type == S_IFLNK && ent->flags & DIR_OR_DIRLNK))) 134 + attroff(A_BOLD); 135 + size_t sizelen = (type == S_IFREG || type == S_IFDIR) ? xstrlen(size = coolsize(cfg.blkorder ? ent->blocks << blk_shift : ent->size)) : 1; 136 + printw("%*c%*s%s%s", 1 + MIN(namecols, dtls.maxnameln + (size_t)(ind ? 0 : 1)) - namelen, ' ', 137 + dtls.maxsizeln - sizelen, "", size ? size : (type = (uchar_t)get_detail_ind(ent->mode), (char *)&type), " "); 138 +#ifndef NOUG 139 + if (g_state.uidgid && dtls.printguid) { 140 + addstr(getpwname(ent->uid)); 141 + printw("%*c%s", dtls.maxuidln + 1 - dtls.uidln, ' ', getgrname(ent->gid)); 142 + printw("%*c", dtls.maxgidln + 2 - dtls.gidln, ' '); 143 + } 144 +#endif 145 + addstr(perms); 146 + print_time(&ent->sec); 147 + } 148 + if (attrs) 149 + attroff(attrs); 150 } 151 152 static void savecurctx(char *path, char *curname, int nextctx) 153 @@ -6250,18 +6256,6 @@ static void statusbar(char *path) 154 tocursor(); 155 } 156 157 -static inline void markhovered(void) 158 -{ 159 - if (cfg.showdetail && ndents) { /* Reversed block for hovered entry */ 160 - tocursor(); 161 -#ifdef ICONS_ENABLED 162 - addstr(MD_ARROW_FORWARD); 163 -#else 164 - addch(' ' | A_REVERSE); 165 -#endif 166 - } 167 -} 168 - 169 static int adjust_cols(int n) 170 { 171 /* Calculate the number of cols available to print entry name */ 172 @@ -6269,11 +6263,10 @@ static int adjust_cols(int n) 173 n -= (g_state.oldcolor ? 0 : 1 + xstrlen(ICON_PADDING_LEFT) + xstrlen(ICON_PADDING_RIGHT)); 174 #endif 175 if (cfg.showdetail) { 176 - /* Fallback to light mode if less than 35 columns */ 177 - if (n < 36) 178 + if (n < (dtls.maxentln + 1 - dtls.maxnameln)) 179 cfg.showdetail ^= 1; 180 else /* 2 more accounted for below */ 181 - n -= 32; 182 + n -= (dtls.maxentln - 2 - dtls.maxnameln); 183 } 184 185 /* 2 columns for preceding space and indicator */ 186 @@ -6310,8 +6303,6 @@ static void draw_line(int ncols) 187 /* Must reset e.g. no files in dir */ 188 if (dir) 189 attroff(COLOR_PAIR(cfg.curctx + 1) | A_BOLD); 190 - 191 - markhovered(); 192 } 193 194 static void redraw(char *path) 195 @@ -6419,6 +6410,21 @@ static void redraw(char *path) 196 197 onscreen = MIN(onscreen + curscroll, ndents); 198 199 + if (cfg.showdetail) { 200 + ushort_t lenbuf = dtls.maxnameln = dtls.maxsizeln = dtls.maxuidln = dtls.maxgidln = dtls.printguid = 0; 201 + for (i = curscroll; i < onscreen; ++i) { 202 + if ((lenbuf = pdents[i].nlen - 1) > dtls.maxnameln) dtls.maxnameln = lenbuf; 203 + if ((lenbuf = xstrlen(coolsize(cfg.blkorder ? pdents[i].blocks << blk_shift : pdents[i].size))) > dtls.maxsizeln) dtls.maxsizeln = lenbuf; 204 +#ifndef NOUG 205 + if (g_state.uidgid) { 206 + if ((getpwname(pdents[i].uid), dtls.uidln) > dtls.maxuidln) dtls.maxuidln = dtls.uidln; 207 + if ((getgrname(pdents[i].gid), dtls.gidln) > dtls.maxgidln) dtls.maxgidln = dtls.gidln; 208 + } 209 +#endif 210 + } 211 + dtls.maxentln = dtls.maxnameln + dtls.maxsizeln + (dtls.printguid ? (dtls.maxuidln + dtls.maxgidln + 29) : 26); 212 + } 213 + 214 ncols = adjust_cols(ncols); 215 216 int len = scanselforpath(path, FALSE); 217 @@ -6449,7 +6455,7 @@ static void redraw(char *path) 218 #endif 219 } 220 221 - markhovered(); 222 + statusbar(path); 223 } 224 225 static bool cdprep(char *lastdir, char *lastname, char *path, char *newpath)