Correct column width for tab completion and ls
This commit is contained in:
parent
58c708af23
commit
4d00129d0f
196
coreutils/ls.c
196
coreutils/ls.c
@ -43,11 +43,9 @@
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
TERMINAL_WIDTH = 80, /* use 79 if terminal has linefold bug */
|
TERMINAL_WIDTH = 80, /* use 79 if terminal has linefold bug */
|
||||||
COLUMN_WIDTH = 14, /* default if AUTOWIDTH not defined */
|
|
||||||
COLUMN_GAP = 2, /* includes the file type char */
|
COLUMN_GAP = 2, /* includes the file type char */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -167,7 +165,7 @@ struct dnode { /* the basic node */
|
|||||||
};
|
};
|
||||||
typedef struct dnode dnode_t;
|
typedef struct dnode dnode_t;
|
||||||
|
|
||||||
static struct dnode **list_dir(char *);
|
static struct dnode **list_dir(const char *);
|
||||||
static struct dnode **dnalloc(int);
|
static struct dnode **dnalloc(int);
|
||||||
static int list_single(struct dnode *);
|
static int list_single(struct dnode *);
|
||||||
|
|
||||||
@ -186,14 +184,12 @@ static unsigned int time_fmt;
|
|||||||
static unsigned int follow_links = FALSE;
|
static unsigned int follow_links = FALSE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static unsigned short column = 0;
|
|
||||||
|
|
||||||
#ifdef CONFIG_FEATURE_AUTOWIDTH
|
#ifdef CONFIG_FEATURE_AUTOWIDTH
|
||||||
static unsigned short terminal_width = TERMINAL_WIDTH;
|
static unsigned short terminal_width = TERMINAL_WIDTH;
|
||||||
static unsigned short column_width = COLUMN_WIDTH;
|
|
||||||
static unsigned short tabstops = COLUMN_GAP;
|
static unsigned short tabstops = COLUMN_GAP;
|
||||||
#else
|
#else
|
||||||
static unsigned short column_width = COLUMN_WIDTH;
|
#define tabstops COLUMN_GAP
|
||||||
|
#define terminal_width TERMINAL_WIDTH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int status = EXIT_SUCCESS;
|
static int status = EXIT_SUCCESS;
|
||||||
@ -202,35 +198,31 @@ static int status = EXIT_SUCCESS;
|
|||||||
static unsigned long ls_disp_hr = 0;
|
static unsigned long ls_disp_hr = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int my_stat(struct dnode *cur)
|
static struct dnode *my_stat(char *fullname, char *name)
|
||||||
{
|
{
|
||||||
|
struct stat dstat;
|
||||||
|
struct dnode *cur;
|
||||||
|
|
||||||
#ifdef CONFIG_FEATURE_LS_FOLLOWLINKS
|
#ifdef CONFIG_FEATURE_LS_FOLLOWLINKS
|
||||||
if (follow_links) {
|
if (follow_links) {
|
||||||
if (stat(cur->fullname, &cur->dstat)) {
|
if (stat(fullname, &dstat)) {
|
||||||
perror_msg("%s", cur->fullname);
|
perror_msg("%s", fullname);
|
||||||
status = EXIT_FAILURE;
|
status = EXIT_FAILURE;
|
||||||
free(cur->fullname);
|
return 0;
|
||||||
free(cur);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
if (lstat(cur->fullname, &cur->dstat)) {
|
if (lstat(fullname, &dstat)) {
|
||||||
perror_msg("%s", cur->fullname);
|
perror_msg("%s", fullname);
|
||||||
status = EXIT_FAILURE;
|
status = EXIT_FAILURE;
|
||||||
free(cur->fullname);
|
|
||||||
free(cur);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
static void newline(void)
|
|
||||||
{
|
|
||||||
if (column > 0) {
|
|
||||||
putchar('\n');
|
|
||||||
column = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cur = (struct dnode *) xmalloc(sizeof(struct dnode));
|
||||||
|
cur->fullname = fullname;
|
||||||
|
cur->name = name;
|
||||||
|
cur->dstat = dstat;
|
||||||
|
return cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
@ -239,7 +231,6 @@ static char fgcolor(mode_t mode)
|
|||||||
{
|
{
|
||||||
/* Check wheter the file is existing (if so, color it red!) */
|
/* Check wheter the file is existing (if so, color it red!) */
|
||||||
if (errno == ENOENT) {
|
if (errno == ENOENT) {
|
||||||
errno = 0;
|
|
||||||
return '\037';
|
return '\037';
|
||||||
}
|
}
|
||||||
if (LIST_EXEC && S_ISREG(mode)
|
if (LIST_EXEC && S_ISREG(mode)
|
||||||
@ -271,24 +262,6 @@ static char append_char(mode_t mode)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
|
||||||
static void nexttabstop(void)
|
|
||||||
{
|
|
||||||
static short nexttab = 0;
|
|
||||||
int n = 0;
|
|
||||||
|
|
||||||
if (column > 0) {
|
|
||||||
n = nexttab - column;
|
|
||||||
if (n < 1)
|
|
||||||
n = 1;
|
|
||||||
while (n--) {
|
|
||||||
putchar(' ');
|
|
||||||
column++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nexttab = column + column_width + COLUMN_GAP;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
static int is_subdir(struct dnode *dn)
|
static int is_subdir(struct dnode *dn)
|
||||||
{
|
{
|
||||||
@ -437,7 +410,11 @@ static int sortcmp(struct dnode *d1, struct dnode *d2)
|
|||||||
cmp = 1;
|
cmp = 1;
|
||||||
if (dif == 0) {
|
if (dif == 0) {
|
||||||
/* sort by name- may be a tie_breaker for time or size cmp */
|
/* sort by name- may be a tie_breaker for time or size cmp */
|
||||||
|
#ifdef CONFIG_LOCALE_SUPPORT
|
||||||
|
dif = strcoll(d1->name, d2->name);
|
||||||
|
#else
|
||||||
dif = strcmp(d1->name, d2->name);
|
dif = strcmp(d1->name, d2->name);
|
||||||
|
#endif
|
||||||
if (dif > 0)
|
if (dif > 0)
|
||||||
cmp = 1;
|
cmp = 1;
|
||||||
if (dif < 0)
|
if (dif < 0)
|
||||||
@ -479,46 +456,40 @@ static void shellsort(struct dnode **dn, int size)
|
|||||||
static void showfiles(struct dnode **dn, int nfiles)
|
static void showfiles(struct dnode **dn, int nfiles)
|
||||||
{
|
{
|
||||||
int i, ncols, nrows, row, nc;
|
int i, ncols, nrows, row, nc;
|
||||||
|
int column = 0;
|
||||||
#ifdef CONFIG_FEATURE_AUTOWIDTH
|
int nexttab = 0;
|
||||||
int len;
|
int column_width = 0; /* for STYLE_LONG and STYLE_SINGLE not used */
|
||||||
#endif
|
|
||||||
|
|
||||||
if (dn == NULL || nfiles < 1)
|
if (dn == NULL || nfiles < 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#ifdef CONFIG_FEATURE_AUTOWIDTH
|
switch (style_fmt) {
|
||||||
|
case STYLE_LONG: /* one record per line, extended info */
|
||||||
|
case STYLE_SINGLE: /* one record per line */
|
||||||
|
ncols = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
/* find the longest file name- use that as the column width */
|
/* find the longest file name- use that as the column width */
|
||||||
column_width = 0;
|
|
||||||
for (i = 0; i < nfiles; i++) {
|
for (i = 0; i < nfiles; i++) {
|
||||||
len = strlen(dn[i]->name) +
|
int len = strlen(dn[i]->name) +
|
||||||
((list_fmt & LIST_INO) ? 8 : 0) +
|
((list_fmt & LIST_INO) ? 8 : 0) +
|
||||||
((list_fmt & LIST_BLOCKS) ? 5 : 0);
|
((list_fmt & LIST_BLOCKS) ? 5 : 0);
|
||||||
if (column_width < len)
|
if (column_width < len)
|
||||||
column_width = len;
|
column_width = len;
|
||||||
}
|
}
|
||||||
ncols = (int) (terminal_width / (column_width + COLUMN_GAP));
|
column_width += tabstops;
|
||||||
#else
|
ncols = (int) (terminal_width / column_width);
|
||||||
ncols = TERMINAL_WIDTH;
|
|
||||||
#endif
|
|
||||||
switch (style_fmt) {
|
|
||||||
case STYLE_LONG: /* one record per line, extended info */
|
|
||||||
case STYLE_SINGLE: /* one record per line */
|
|
||||||
ncols = 1;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ncols > 1) {
|
if (ncols > 1) {
|
||||||
nrows = nfiles / ncols;
|
nrows = nfiles / ncols;
|
||||||
|
if ((nrows * ncols) < nfiles)
|
||||||
|
nrows++; /* round up fractionals */
|
||||||
} else {
|
} else {
|
||||||
nrows = nfiles;
|
nrows = nfiles;
|
||||||
ncols = 1;
|
ncols = 1;
|
||||||
}
|
}
|
||||||
if ((nrows * ncols) < nfiles)
|
|
||||||
nrows++; /* round up fractionals */
|
|
||||||
|
|
||||||
if (nrows > nfiles)
|
|
||||||
nrows = nfiles;
|
|
||||||
for (row = 0; row < nrows; row++) {
|
for (row = 0; row < nrows; row++) {
|
||||||
for (nc = 0; nc < ncols; nc++) {
|
for (nc = 0; nc < ncols; nc++) {
|
||||||
/* reach into the array based on the column and row */
|
/* reach into the array based on the column and row */
|
||||||
@ -526,11 +497,19 @@ static void showfiles(struct dnode **dn, int nfiles)
|
|||||||
if (disp_opts & DISP_ROWS)
|
if (disp_opts & DISP_ROWS)
|
||||||
i = (row * ncols) + nc; /* display across row */
|
i = (row * ncols) + nc; /* display across row */
|
||||||
if (i < nfiles) {
|
if (i < nfiles) {
|
||||||
nexttabstop();
|
if (column > 0) {
|
||||||
list_single(dn[i]);
|
nexttab -= column;
|
||||||
|
while (nexttab--) {
|
||||||
|
putchar(' ');
|
||||||
|
column++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
nexttab = column + column_width;
|
||||||
|
column += list_single(dn[i]);
|
||||||
}
|
}
|
||||||
newline();
|
}
|
||||||
|
putchar('\n');
|
||||||
|
column = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -580,7 +559,7 @@ static void showdirs(struct dnode **dn, int ndirs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
static struct dnode **list_dir(char *path)
|
static struct dnode **list_dir(const char *path)
|
||||||
{
|
{
|
||||||
struct dnode *dn, *cur, **dnp;
|
struct dnode *dn, *cur, **dnp;
|
||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
@ -599,18 +578,21 @@ static struct dnode **list_dir(char *path)
|
|||||||
return (NULL); /* could not open the dir */
|
return (NULL); /* could not open the dir */
|
||||||
}
|
}
|
||||||
while ((entry = readdir(dir)) != NULL) {
|
while ((entry = readdir(dir)) != NULL) {
|
||||||
|
char *fullname;
|
||||||
|
|
||||||
/* are we going to list the file- it may be . or .. or a hidden file */
|
/* are we going to list the file- it may be . or .. or a hidden file */
|
||||||
if ((strcmp(entry->d_name, ".") == 0) && !(disp_opts & DISP_DOT))
|
if (entry->d_name[0] == '.') {
|
||||||
|
if ((entry->d_name[1] == 0 || (
|
||||||
|
entry->d_name[1] == '.'
|
||||||
|
&& entry->d_name[2] == 0))
|
||||||
|
&& !(disp_opts & DISP_DOT))
|
||||||
continue;
|
continue;
|
||||||
if ((strcmp(entry->d_name, "..") == 0) && !(disp_opts & DISP_DOT))
|
if (!(disp_opts & DISP_HIDDEN))
|
||||||
continue;
|
continue;
|
||||||
if ((entry->d_name[0] == '.') && !(disp_opts & DISP_HIDDEN))
|
}
|
||||||
continue;
|
fullname = concat_path_file(path, entry->d_name);
|
||||||
cur = (struct dnode *) xmalloc(sizeof(struct dnode));
|
cur = my_stat(fullname, strrchr(fullname, '/') + 1);
|
||||||
cur->fullname = concat_path_file(path, entry->d_name);
|
if (!cur)
|
||||||
cur->name = cur->fullname +
|
|
||||||
(strlen(cur->fullname) - strlen(entry->d_name));
|
|
||||||
if (my_stat(cur))
|
|
||||||
continue;
|
continue;
|
||||||
cur->next = dn;
|
cur->next = dn;
|
||||||
dn = cur;
|
dn = cur;
|
||||||
@ -621,7 +603,7 @@ static struct dnode **list_dir(char *path)
|
|||||||
/* now that we know how many files there are
|
/* now that we know how many files there are
|
||||||
** allocate memory for an array to hold dnode pointers
|
** allocate memory for an array to hold dnode pointers
|
||||||
*/
|
*/
|
||||||
if (nfiles < 1)
|
if (dn == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
dnp = dnalloc(nfiles);
|
dnp = dnalloc(nfiles);
|
||||||
for (i = 0, cur = dn; i < nfiles; i++) {
|
for (i = 0, cur = dn; i < nfiles; i++) {
|
||||||
@ -635,10 +617,10 @@ static struct dnode **list_dir(char *path)
|
|||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
static int list_single(struct dnode *dn)
|
static int list_single(struct dnode *dn)
|
||||||
{
|
{
|
||||||
int i;
|
int i, column = 0;
|
||||||
|
|
||||||
#ifdef CONFIG_FEATURE_LS_USERNAME
|
#ifdef CONFIG_FEATURE_LS_USERNAME
|
||||||
char scratch[BUFSIZ + 1];
|
char scratch[16];
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_FEATURE_LS_TIMESTAMPS
|
#ifdef CONFIG_FEATURE_LS_TIMESTAMPS
|
||||||
char *filetime;
|
char *filetime;
|
||||||
@ -649,7 +631,7 @@ static int list_single(struct dnode *dn)
|
|||||||
char append;
|
char append;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (dn == NULL || dn->fullname == NULL)
|
if (dn->fullname == NULL)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
#ifdef CONFIG_FEATURE_LS_TIMESTAMPS
|
#ifdef CONFIG_FEATURE_LS_TIMESTAMPS
|
||||||
@ -667,29 +649,20 @@ static int list_single(struct dnode *dn)
|
|||||||
for (i = 0; i <= 31; i++) {
|
for (i = 0; i <= 31; i++) {
|
||||||
switch (list_fmt & (1 << i)) {
|
switch (list_fmt & (1 << i)) {
|
||||||
case LIST_INO:
|
case LIST_INO:
|
||||||
printf("%7ld ", (long int) dn->dstat.st_ino);
|
column += printf("%7ld ", (long int) dn->dstat.st_ino);
|
||||||
column += 8;
|
|
||||||
break;
|
break;
|
||||||
case LIST_BLOCKS:
|
case LIST_BLOCKS:
|
||||||
#ifdef CONFIG_FEATURE_HUMAN_READABLE
|
|
||||||
printf("%6s ", make_human_readable_str(dn->dstat.st_blocks >> 1,
|
|
||||||
KILOBYTE, (ls_disp_hr == TRUE) ? 0 : KILOBYTE));
|
|
||||||
#else
|
|
||||||
#if _FILE_OFFSET_BITS == 64
|
#if _FILE_OFFSET_BITS == 64
|
||||||
printf("%4lld ", dn->dstat.st_blocks >> 1);
|
column += printf("%4lld ", dn->dstat.st_blocks >> 1);
|
||||||
#else
|
#else
|
||||||
printf("%4ld ", dn->dstat.st_blocks >> 1);
|
column += printf("%4ld ", dn->dstat.st_blocks >> 1);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
column += 5;
|
|
||||||
break;
|
break;
|
||||||
case LIST_MODEBITS:
|
case LIST_MODEBITS:
|
||||||
printf("%-10s ", (char *) mode_string(dn->dstat.st_mode));
|
column += printf("%-10s ", (char *) mode_string(dn->dstat.st_mode));
|
||||||
column += 10;
|
|
||||||
break;
|
break;
|
||||||
case LIST_NLINKS:
|
case LIST_NLINKS:
|
||||||
printf("%4ld ", (long) dn->dstat.st_nlink);
|
column += printf("%4ld ", (long) dn->dstat.st_nlink);
|
||||||
column += 10;
|
|
||||||
break;
|
break;
|
||||||
case LIST_ID_NAME:
|
case LIST_ID_NAME:
|
||||||
#ifdef CONFIG_FEATURE_LS_USERNAME
|
#ifdef CONFIG_FEATURE_LS_USERNAME
|
||||||
@ -701,29 +674,28 @@ static int list_single(struct dnode *dn)
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case LIST_ID_NUMERIC:
|
case LIST_ID_NUMERIC:
|
||||||
printf("%-8d %-8d", dn->dstat.st_uid, dn->dstat.st_gid);
|
column += printf("%-8d %-8d", dn->dstat.st_uid, dn->dstat.st_gid);
|
||||||
column += 17;
|
|
||||||
break;
|
break;
|
||||||
case LIST_SIZE:
|
case LIST_SIZE:
|
||||||
case LIST_DEV:
|
case LIST_DEV:
|
||||||
if (S_ISBLK(dn->dstat.st_mode) || S_ISCHR(dn->dstat.st_mode)) {
|
if (S_ISBLK(dn->dstat.st_mode) || S_ISCHR(dn->dstat.st_mode)) {
|
||||||
printf("%4d, %3d ", (int) MAJOR(dn->dstat.st_rdev),
|
column += printf("%4d, %3d ", (int) MAJOR(dn->dstat.st_rdev),
|
||||||
(int) MINOR(dn->dstat.st_rdev));
|
(int) MINOR(dn->dstat.st_rdev));
|
||||||
} else {
|
} else {
|
||||||
#ifdef CONFIG_FEATURE_HUMAN_READABLE
|
#ifdef CONFIG_FEATURE_HUMAN_READABLE
|
||||||
if (ls_disp_hr == TRUE) {
|
if (ls_disp_hr == TRUE) {
|
||||||
printf("%8s ", make_human_readable_str(dn->dstat.st_size, 1, 0));
|
column += printf("%9s ",
|
||||||
|
make_human_readable_str(dn->dstat.st_size, 1, 0));
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#if _FILE_OFFSET_BITS == 64
|
#if _FILE_OFFSET_BITS == 64
|
||||||
printf("%9lld ", (long long) dn->dstat.st_size);
|
column += printf("%9lld ", (long long) dn->dstat.st_size);
|
||||||
#else
|
#else
|
||||||
printf("%9ld ", dn->dstat.st_size);
|
column += printf("%9ld ", dn->dstat.st_size);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
column += 10;
|
|
||||||
break;
|
break;
|
||||||
#ifdef CONFIG_FEATURE_LS_TIMESTAMPS
|
#ifdef CONFIG_FEATURE_LS_TIMESTAMPS
|
||||||
case LIST_FULLTIME:
|
case LIST_FULLTIME:
|
||||||
@ -752,13 +724,12 @@ static int list_single(struct dnode *dn)
|
|||||||
fgcolor(info.st_mode));
|
fgcolor(info.st_mode));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
printf("%s", dn->name);
|
column += printf("%s", dn->name);
|
||||||
#ifdef CONFIG_FEATURE_LS_COLOR
|
#ifdef CONFIG_FEATURE_LS_COLOR
|
||||||
if (show_color) {
|
if (show_color) {
|
||||||
printf("\033[0m");
|
printf("\033[0m");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
column += strlen(dn->name);
|
|
||||||
break;
|
break;
|
||||||
case LIST_SYMLINK:
|
case LIST_SYMLINK:
|
||||||
if (S_ISLNK(dn->dstat.st_mode)) {
|
if (S_ISLNK(dn->dstat.st_mode)) {
|
||||||
@ -778,13 +749,12 @@ static int list_single(struct dnode *dn)
|
|||||||
fgcolor(info.st_mode));
|
fgcolor(info.st_mode));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
printf("%s", lpath);
|
column += printf("%s", lpath) + 4;
|
||||||
#ifdef CONFIG_FEATURE_LS_COLOR
|
#ifdef CONFIG_FEATURE_LS_COLOR
|
||||||
if (show_color) {
|
if (show_color) {
|
||||||
printf("\033[0m");
|
printf("\033[0m");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
column += strlen(lpath) + 4;
|
|
||||||
free(lpath);
|
free(lpath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -800,7 +770,7 @@ static int list_single(struct dnode *dn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (0);
|
return column;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
@ -830,8 +800,6 @@ extern int ls_main(int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_FEATURE_AUTOWIDTH
|
#ifdef CONFIG_FEATURE_AUTOWIDTH
|
||||||
ioctl(fileno(stdout), TIOCGWINSZ, &win);
|
ioctl(fileno(stdout), TIOCGWINSZ, &win);
|
||||||
if (win.ws_row > 4)
|
|
||||||
column_width = win.ws_row - 2;
|
|
||||||
if (win.ws_col > 0)
|
if (win.ws_col > 0)
|
||||||
terminal_width = win.ws_col - 1;
|
terminal_width = win.ws_col - 1;
|
||||||
#endif
|
#endif
|
||||||
@ -1025,10 +993,10 @@ extern int ls_main(int argc, char **argv)
|
|||||||
/* stuff the command line file names into an dnode array */
|
/* stuff the command line file names into an dnode array */
|
||||||
dn = NULL;
|
dn = NULL;
|
||||||
for (oi = 0; oi < ac; oi++) {
|
for (oi = 0; oi < ac; oi++) {
|
||||||
cur = (struct dnode *) xmalloc(sizeof(struct dnode));
|
char *fullname = xstrdup(av[oi]);
|
||||||
cur->fullname = xstrdup(av[oi]);
|
|
||||||
cur->name = cur->fullname;
|
cur = my_stat(fullname, fullname);
|
||||||
if (my_stat(cur))
|
if (!cur)
|
||||||
continue;
|
continue;
|
||||||
cur->next = dn;
|
cur->next = dn;
|
||||||
dn = cur;
|
dn = cur;
|
||||||
|
@ -951,6 +951,44 @@ static int find_match(char *matchBuf, int *len_with_quotes)
|
|||||||
return command_mode;
|
return command_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
display by column original ideas from ls applet,
|
||||||
|
very optimize by my :)
|
||||||
|
*/
|
||||||
|
static void showfiles(char **matches, int nfiles)
|
||||||
|
{
|
||||||
|
int ncols, row;
|
||||||
|
int column_width = 0;
|
||||||
|
int nrows = nfiles;
|
||||||
|
|
||||||
|
/* find the longest file name- use that as the column width */
|
||||||
|
for (row = 0; row < nrows; row++) {
|
||||||
|
int l = strlen(matches[row]);
|
||||||
|
|
||||||
|
if (column_width < l)
|
||||||
|
column_width = l;
|
||||||
|
}
|
||||||
|
column_width += 2; /* min space for columns */
|
||||||
|
ncols = cmdedit_termw / column_width;
|
||||||
|
|
||||||
|
if (ncols > 1) {
|
||||||
|
nrows /= ncols;
|
||||||
|
if(nfiles % ncols)
|
||||||
|
nrows++; /* round up fractionals */
|
||||||
|
column_width = -column_width; /* for printf("%-Ns", ...); */
|
||||||
|
} else {
|
||||||
|
ncols = 1;
|
||||||
|
}
|
||||||
|
for (row = 0; row < nrows; row++) {
|
||||||
|
int n = row;
|
||||||
|
int nc;
|
||||||
|
|
||||||
|
for(nc = 1; nc < ncols && n+nrows < nfiles; n += nrows, nc++)
|
||||||
|
printf("%*s", column_width, matches[n]);
|
||||||
|
printf("%s\n", matches[n]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void input_tab(int *lastWasTab)
|
static void input_tab(int *lastWasTab)
|
||||||
{
|
{
|
||||||
@ -1078,29 +1116,11 @@ static void input_tab(int *lastWasTab)
|
|||||||
* just hit TAB again, print a list of all the
|
* just hit TAB again, print a list of all the
|
||||||
* available choices... */
|
* available choices... */
|
||||||
if (matches && num_matches > 0) {
|
if (matches && num_matches > 0) {
|
||||||
int i, col, l;
|
|
||||||
int sav_cursor = cursor; /* change goto_new_line() */
|
int sav_cursor = cursor; /* change goto_new_line() */
|
||||||
|
|
||||||
/* Go to the next line */
|
/* Go to the next line */
|
||||||
goto_new_line();
|
goto_new_line();
|
||||||
for (i = 0, col = 0; i < num_matches; i++) {
|
showfiles(matches, num_matches);
|
||||||
l = strlen(matches[i]);
|
|
||||||
if (l < 14)
|
|
||||||
l = 14;
|
|
||||||
printf("%-14s ", matches[i]);
|
|
||||||
col+=l;
|
|
||||||
if ((l += 2) > 16)
|
|
||||||
while (l % 16) {
|
|
||||||
putchar(' ');
|
|
||||||
l++;
|
|
||||||
}
|
|
||||||
if (col > (cmdedit_termw-l-l) && matches[i + 1] != NULL) {
|
|
||||||
putchar('\n');
|
|
||||||
col = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Go to the next line and rewrite */
|
|
||||||
putchar('\n');
|
|
||||||
redraw(0, len - sav_cursor);
|
redraw(0, len - sav_cursor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user