mirror of
https://github.com/jarun/nnn.git
synced 2024-12-01 02:49:44 +00:00
Fix #36: uneven splitting of codepoints
Check if the number of columns needed to print name exceeds the number of cols. If it does, split the name str at the max number of columns available for name. Conversion to wide char ensures the split is done at a valid codepoint. The current patch adds some optimization as well: - No more copying to an intermediate (global) string. - If the name is shortened, escape chars are replaced only till the terminator.
This commit is contained in:
parent
2e33c577b1
commit
1e5a0b8c5b
77
nnn.c
77
nnn.c
|
@ -1160,19 +1160,28 @@ readinput(void)
|
|||
|
||||
/*
|
||||
* Replace escape characters in a string with '?'
|
||||
* Adjust string length to maxcols if > 0;
|
||||
*/
|
||||
static char *
|
||||
unescape(const char *str)
|
||||
unescape(const char *str, uint maxcols)
|
||||
{
|
||||
static char buffer[PATH_MAX];
|
||||
static wchar_t wbuf[PATH_MAX];
|
||||
static wchar_t *buf;
|
||||
static size_t len, width;
|
||||
|
||||
buffer[0] = '\0';
|
||||
buf = wbuf;
|
||||
|
||||
/* Convert multi-byte to wide char */
|
||||
mbstowcs(wbuf, str, PATH_MAX);
|
||||
len = mbstowcs(wbuf, str, PATH_MAX);
|
||||
|
||||
if (maxcols) {
|
||||
width = wcswidth(wbuf, len);
|
||||
|
||||
if (width > maxcols)
|
||||
wbuf[maxcols] = 0;
|
||||
}
|
||||
|
||||
while (*buf) {
|
||||
if (*buf <= '\x1f' || *buf == '\x7f')
|
||||
|
@ -1190,32 +1199,33 @@ static void
|
|||
printent(struct entry *ent, int sel)
|
||||
{
|
||||
static int ncols;
|
||||
static char *pname;
|
||||
|
||||
if (PATH_MAX + 16 < COLS)
|
||||
ncols = PATH_MAX + 16;
|
||||
else
|
||||
ncols = COLS;
|
||||
|
||||
pname = unescape(ent->name, ncols - 5);
|
||||
|
||||
if (S_ISDIR(ent->mode))
|
||||
snprintf(g_buf, ncols, "%s%s/", CURSYM(sel), unescape(ent->name));
|
||||
printw("%s%s/\n", CURSYM(sel), pname);
|
||||
else if (S_ISLNK(ent->mode))
|
||||
snprintf(g_buf, ncols, "%s%s@", CURSYM(sel), unescape(ent->name));
|
||||
printw("%s%s@\n", CURSYM(sel), pname);
|
||||
else if (S_ISSOCK(ent->mode))
|
||||
snprintf(g_buf, ncols, "%s%s=", CURSYM(sel), unescape(ent->name));
|
||||
printw("%s%s=\n", CURSYM(sel), pname);
|
||||
else if (S_ISFIFO(ent->mode))
|
||||
snprintf(g_buf, ncols, "%s%s|", CURSYM(sel), unescape(ent->name));
|
||||
printw("%s%s|\n", CURSYM(sel), pname);
|
||||
else if (ent->mode & 0100)
|
||||
snprintf(g_buf, ncols, "%s%s*", CURSYM(sel), unescape(ent->name));
|
||||
printw("%s%s*\n", CURSYM(sel), pname);
|
||||
else
|
||||
snprintf(g_buf, ncols, "%s%s", CURSYM(sel), unescape(ent->name));
|
||||
printw("%s%s\n", CURSYM(sel), pname);
|
||||
|
||||
/* Dirs are always shown on top */
|
||||
if (cfg.dircolor && !S_ISDIR(ent->mode)) {
|
||||
attroff(COLOR_PAIR(1) | A_BOLD);
|
||||
cfg.dircolor = 0;
|
||||
}
|
||||
|
||||
printw("%s\n", g_buf);
|
||||
}
|
||||
|
||||
static char *
|
||||
|
@ -1246,7 +1256,7 @@ static void
|
|||
printent_long(struct entry *ent, int sel)
|
||||
{
|
||||
static int ncols;
|
||||
static char buf[18];
|
||||
static char buf[18], *pname;
|
||||
|
||||
if (PATH_MAX + 32 < COLS)
|
||||
ncols = PATH_MAX + 32;
|
||||
|
@ -1254,44 +1264,45 @@ printent_long(struct entry *ent, int sel)
|
|||
ncols = COLS;
|
||||
|
||||
strftime(buf, 18, "%d-%m-%Y %H:%M", localtime(&ent->t));
|
||||
pname = unescape(ent->name, ncols - 32);
|
||||
|
||||
if (sel)
|
||||
attron(A_REVERSE);
|
||||
|
||||
if (!cfg.blkorder) {
|
||||
if (S_ISDIR(ent->mode))
|
||||
snprintf(g_buf, ncols, "%s%-16.16s / %s/", CURSYM(sel), buf, unescape(ent->name));
|
||||
printw("%s%-16.16s / %s/\n", CURSYM(sel), buf, pname);
|
||||
else if (S_ISLNK(ent->mode))
|
||||
snprintf(g_buf, ncols, "%s%-16.16s @ %s@", CURSYM(sel), buf, unescape(ent->name));
|
||||
printw("%s%-16.16s @ %s@\n", CURSYM(sel), buf, pname);
|
||||
else if (S_ISSOCK(ent->mode))
|
||||
snprintf(g_buf, ncols, "%s%-16.16s = %s=", CURSYM(sel), buf, unescape(ent->name));
|
||||
printf("%s%-16.16s = %s=\n", CURSYM(sel), buf, pname);
|
||||
else if (S_ISFIFO(ent->mode))
|
||||
snprintf(g_buf, ncols, "%s%-16.16s | %s|", CURSYM(sel), buf, unescape(ent->name));
|
||||
printw("%s%-16.16s | %s|\n", CURSYM(sel), buf, pname);
|
||||
else if (S_ISBLK(ent->mode))
|
||||
snprintf(g_buf, ncols, "%s%-16.16s b %s", CURSYM(sel), buf, unescape(ent->name));
|
||||
printw("%s%-16.16s b %s\n", CURSYM(sel), buf, pname);
|
||||
else if (S_ISCHR(ent->mode))
|
||||
snprintf(g_buf, ncols, "%s%-16.16s c %s", CURSYM(sel), buf, unescape(ent->name));
|
||||
printw("%s%-16.16s c %s\n", CURSYM(sel), buf, pname);
|
||||
else if (ent->mode & 0100)
|
||||
snprintf(g_buf, ncols, "%s%-16.16s %8.8s* %s*", CURSYM(sel), buf, coolsize(ent->size), unescape(ent->name));
|
||||
printw("%s%-16.16s %8.8s* %s*\n", CURSYM(sel), buf, coolsize(ent->size), pname);
|
||||
else
|
||||
snprintf(g_buf, ncols, "%s%-16.16s %8.8s %s", CURSYM(sel), buf, coolsize(ent->size), unescape(ent->name));
|
||||
printw("%s%-16.16s %8.8s %s\n", CURSYM(sel), buf, coolsize(ent->size), pname);
|
||||
} else {
|
||||
if (S_ISDIR(ent->mode))
|
||||
snprintf(g_buf, ncols, "%s%-16.16s %8.8s/ %s/", CURSYM(sel), buf, coolsize(ent->blocks << 9), unescape(ent->name));
|
||||
printw("%s%-16.16s %8.8s/ %s/\n", CURSYM(sel), buf, coolsize(ent->blocks << 9), pname);
|
||||
else if (S_ISLNK(ent->mode))
|
||||
snprintf(g_buf, ncols, "%s%-16.16s @ %s@", CURSYM(sel), buf, unescape(ent->name));
|
||||
printw("%s%-16.16s @ %s@\n", CURSYM(sel), buf, pname);
|
||||
else if (S_ISSOCK(ent->mode))
|
||||
snprintf(g_buf, ncols, "%s%-16.16s = %s=", CURSYM(sel), buf, unescape(ent->name));
|
||||
printw("%s%-16.16s = %s=\n", CURSYM(sel), buf, pname);
|
||||
else if (S_ISFIFO(ent->mode))
|
||||
snprintf(g_buf, ncols, "%s%-16.16s | %s|", CURSYM(sel), buf, unescape(ent->name));
|
||||
printw("%s%-16.16s | %s|\n", CURSYM(sel), buf, pname);
|
||||
else if (S_ISBLK(ent->mode))
|
||||
snprintf(g_buf, ncols, "%s%-16.16s b %s", CURSYM(sel), buf, unescape(ent->name));
|
||||
printw("%s%-16.16s b %s\n", CURSYM(sel), buf, pname);
|
||||
else if (S_ISCHR(ent->mode))
|
||||
snprintf(g_buf, ncols, "%s%-16.16s c %s", CURSYM(sel), buf, unescape(ent->name));
|
||||
printw("%s%-16.16s c %s\n", CURSYM(sel), buf, pname);
|
||||
else if (ent->mode & 0100)
|
||||
snprintf(g_buf, ncols, "%s%-16.16s %8.8s* %s*", CURSYM(sel), buf, coolsize(ent->blocks << 9), unescape(ent->name));
|
||||
printw("%s%-16.16s %8.8s* %s*\n", CURSYM(sel), buf, coolsize(ent->blocks << 9), pname);
|
||||
else
|
||||
snprintf(g_buf, ncols, "%s%-16.16s %8.8s %s", CURSYM(sel), buf, coolsize(ent->blocks << 9), unescape(ent->name));
|
||||
printw("%s%-16.16s %8.8s %s\n", CURSYM(sel), buf, coolsize(ent->blocks << 9), pname);
|
||||
}
|
||||
|
||||
/* Dirs are always shown on top */
|
||||
|
@ -1300,8 +1311,6 @@ printent_long(struct entry *ent, int sel)
|
|||
cfg.dircolor = 0;
|
||||
}
|
||||
|
||||
printw("%s\n", g_buf);
|
||||
|
||||
if (sel)
|
||||
attroff(A_REVERSE);
|
||||
}
|
||||
|
@ -1473,12 +1482,12 @@ show_stats(char *fpath, char *fname, struct stat *sb)
|
|||
|
||||
if (len != -1) {
|
||||
g_buf[len] = '\0';
|
||||
dprintf(fd, " File: '%s' -> ", unescape(fname));
|
||||
dprintf(fd, "'%s'", unescape(g_buf));
|
||||
dprintf(fd, " File: '%s' -> ", unescape(fname, 0));
|
||||
dprintf(fd, "'%s'", unescape(g_buf, 0));
|
||||
xstrlcpy(g_buf, "symbolic link", MAX_CMD_LEN);
|
||||
}
|
||||
} else
|
||||
dprintf(fd, " File: '%s'", unescape(fname));
|
||||
dprintf(fd, " File: '%s'", unescape(fname, 0));
|
||||
|
||||
/* Show size, blocks, file type */
|
||||
#ifdef __APPLE__
|
||||
|
@ -2007,10 +2016,10 @@ redraw(char *path)
|
|||
* be truncated in directory listing
|
||||
*/
|
||||
if (!cfg.blkorder)
|
||||
sprintf(g_buf, "total %d %s[%s%s]", ndents, sort, unescape(dents[cur].name), ind);
|
||||
sprintf(g_buf, "total %d %s[%s%s]", ndents, sort, unescape(dents[cur].name, 0), ind);
|
||||
else {
|
||||
i = sprintf(g_buf, "du: %s (%lu files) ", coolsize(dir_blocks << 9), num_files);
|
||||
sprintf(g_buf + i, "vol: %s free [%s%s]", coolsize(get_fs_free(path)), unescape(dents[cur].name), ind);
|
||||
sprintf(g_buf + i, "vol: %s free [%s%s]", coolsize(get_fs_free(path)), unescape(dents[cur].name, 0), ind);
|
||||
}
|
||||
|
||||
printmsg(g_buf);
|
||||
|
|
Loading…
Reference in a new issue