make toggle file details work
This commit is contained in:
parent
10f4bef9da
commit
83d3eb64be
2 changed files with 101 additions and 30 deletions
107
ccc.c
107
ccc.c
|
@ -23,11 +23,13 @@ int mkdir_p(const char *destdir);
|
||||||
void populate_files(const char *path, int ftype);
|
void populate_files(const char *path, int ftype);
|
||||||
int get_directory_size(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf);
|
int get_directory_size(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf);
|
||||||
void add_file_stat(char *filepath, int ftype);
|
void add_file_stat(char *filepath, int ftype);
|
||||||
|
char *get_file_mode(mode_t mode);
|
||||||
void highlight_current_line();
|
void highlight_current_line();
|
||||||
void show_file_content();
|
void show_file_content();
|
||||||
void edit_file();
|
void edit_file();
|
||||||
|
void toggle_executable();
|
||||||
int write_last_d();
|
int write_last_d();
|
||||||
void wpprintw(const char *line);
|
void wpprintw(const char *fmt, ...);
|
||||||
void init_windows();
|
void init_windows();
|
||||||
void draw_border_title(WINDOW *window, bool active);
|
void draw_border_title(WINDOW *window, bool active);
|
||||||
|
|
||||||
|
@ -54,6 +56,13 @@ int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
if (argc > 1 && strcmp(argv[1], "-h") == 0)
|
if (argc > 1 && strcmp(argv[1], "-h") == 0)
|
||||||
die("Usage: ccc filename");
|
die("Usage: ccc filename");
|
||||||
|
if (argc == 2) {
|
||||||
|
struct stat st;
|
||||||
|
if (lstat(argv[1], &st) != 0) {
|
||||||
|
perror("ccc");
|
||||||
|
die("Error from lstat");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* check if it is interactive shell */
|
/* check if it is interactive shell */
|
||||||
if (!isatty(STDIN_FILENO))
|
if (!isatty(STDIN_FILENO))
|
||||||
|
@ -92,10 +101,14 @@ int main(int argc, char** argv)
|
||||||
marked = arraylist_init(100);
|
marked = arraylist_init(100);
|
||||||
|
|
||||||
cwd = memalloc(PATH_MAX * sizeof(char));
|
cwd = memalloc(PATH_MAX * sizeof(char));
|
||||||
p_cwd = memalloc(PATH_MAX * sizeof(char));
|
if (argc == 2) {
|
||||||
|
strcpy(cwd, argv[1]);
|
||||||
|
} else {
|
||||||
getcwd(cwd, PATH_MAX);
|
getcwd(cwd, PATH_MAX);
|
||||||
populate_files(cwd, 0);
|
}
|
||||||
|
p_cwd = memalloc(PATH_MAX * sizeof(char));
|
||||||
start_ccc();
|
start_ccc();
|
||||||
|
populate_files(cwd, 0);
|
||||||
|
|
||||||
int ch, ch2;
|
int ch, ch2;
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -268,6 +281,11 @@ int main(int argc, char** argv)
|
||||||
case 'i':
|
case 'i':
|
||||||
file_details = !file_details;
|
file_details = !file_details;
|
||||||
change_dir(cwd, 0, 0);
|
change_dir(cwd, 0, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'X':
|
||||||
|
toggle_executable();
|
||||||
|
break;
|
||||||
|
|
||||||
/* mark one file */
|
/* mark one file */
|
||||||
case SPACE:
|
case SPACE:
|
||||||
|
@ -328,6 +346,7 @@ int main(int argc, char** argv)
|
||||||
delwin(panel);
|
delwin(panel);
|
||||||
endwin();
|
endwin();
|
||||||
start_ccc();
|
start_ccc();
|
||||||
|
highlight_current_line();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -343,7 +362,7 @@ void show_help()
|
||||||
{
|
{
|
||||||
wclear(directory_content);
|
wclear(directory_content);
|
||||||
wclear(preview_content);
|
wclear(preview_content);
|
||||||
wprintw(directory_content,"h: go to parent dir\nj: scroll down\nk: scroll up\nl: go to child dir\n\nleft: go to parent dir\ndown: scroll down\nup: scroll up\nright: go to child dir\n\nenter: go to child dir/open file\nbackspace: go to parent dir\n\ngg: go to top\nG: go to bottom\n\nctrl+u: jump up\nctrl+d: jump down\n\nt: go to trash dir\n~: go to home dir\n-: go to previous dir\nz: refresh current dir\n\nA: show directory disk usage/block size\nspace: mark file\na: mark all files in directory\n\n?: show help\nq: exit with last dir written to file\nctrl+c exit without writing last dir");
|
wprintw(directory_content,"h: go to parent dir\nj: scroll down\nk: scroll up\nl: go to child dir\n\nleft: go to parent dir\ndown: scroll down\nup: scroll up\nright: go to child dir\n\nenter: go to child dir/open file\nbackspace: go to parent dir\n\ngg: go to top\nG: go to bottom\n\nctrl+u: jump up\nctrl+d: jump down\n\nt: go to trash dir\n~: go to home dir\n-: go to previous dir\nz: refresh current dir\n\nA: show directory disk usage/block size\nX: toggle executable\nspace: mark file\na: mark all files in directory\n\n?: show help\nq: exit with last dir written to file\nctrl+c exit without writing last dir");
|
||||||
wpprintw("Visit https://github.com/piotr-marendowski/ccc or use 'man ccc' for help");
|
wpprintw("Visit https://github.com/piotr-marendowski/ccc or use 'man ccc' for help");
|
||||||
wrefresh(directory_content);
|
wrefresh(directory_content);
|
||||||
wrefresh(preview_content);
|
wrefresh(preview_content);
|
||||||
|
@ -353,7 +372,6 @@ void start_ccc()
|
||||||
{
|
{
|
||||||
half_width = COLS / 2;
|
half_width = COLS / 2;
|
||||||
init_windows();
|
init_windows();
|
||||||
highlight_current_line();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -373,9 +391,8 @@ void change_dir(const char *buf, int selection, int ftype)
|
||||||
strcpy(cwd, buf_dup);
|
strcpy(cwd, buf_dup);
|
||||||
arraylist_free(files);
|
arraylist_free(files);
|
||||||
files = arraylist_init(100);
|
files = arraylist_init(100);
|
||||||
populate_files(cwd, ftype);
|
|
||||||
current_selection = selection;
|
current_selection = selection;
|
||||||
highlight_current_line();
|
populate_files(cwd, ftype);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -461,12 +478,10 @@ void populate_files(const char *path, int ftype)
|
||||||
}
|
}
|
||||||
closedir(dp);
|
closedir(dp);
|
||||||
wrefresh(directory_content);
|
wrefresh(directory_content);
|
||||||
|
highlight_current_line();
|
||||||
} else {
|
} else {
|
||||||
perror("ccc");
|
wpprintw("stat failed: %s\n", strerror(errno));
|
||||||
}
|
}
|
||||||
#if DRAW_BORDERS
|
|
||||||
draw_border_title(directory_border, true);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_directory_size(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
|
int get_directory_size(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
|
||||||
|
@ -555,8 +570,11 @@ void add_file_stat(char *filepath, int ftype)
|
||||||
/* display sizes */
|
/* display sizes */
|
||||||
sprintf(size, "%.3g%s", bytes, units[unit]);
|
sprintf(size, "%.3g%s", bytes, units[unit]);
|
||||||
|
|
||||||
char *total_stat = memalloc(45 * sizeof(char));
|
/* get file mode string */
|
||||||
snprintf(total_stat, 45, "%-18s %-8s", time, size);
|
char *mode_str = get_file_mode(file_stat.st_mode);
|
||||||
|
|
||||||
|
char *total_stat = memalloc(56 * sizeof(char));
|
||||||
|
snprintf(total_stat, 56, "%s %s %-8s", mode_str, time, size);
|
||||||
total_stat[strlen(total_stat)] = '\0';
|
total_stat[strlen(total_stat)] = '\0';
|
||||||
|
|
||||||
arraylist_add(files, filepath, total_stat, type, color, false, false);
|
arraylist_add(files, filepath, total_stat, type, color, false, false);
|
||||||
|
@ -565,14 +583,39 @@ void add_file_stat(char *filepath, int ftype)
|
||||||
free(size);
|
free(size);
|
||||||
free(total_stat);
|
free(total_stat);
|
||||||
free(type);
|
free(type);
|
||||||
|
free(mode_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get file mode string from stat mode
|
||||||
|
* eg: drwxr-sr-x
|
||||||
|
*/
|
||||||
|
char *get_file_mode(mode_t mode)
|
||||||
|
{
|
||||||
|
char *mode_str = memalloc(sizeof(char) * 11);
|
||||||
|
mode_str[0] = S_ISDIR(mode) ? 'd' : '-'; // Check if it's a directory
|
||||||
|
mode_str[1] = (mode & S_IRUSR) ? 'r' : '-';
|
||||||
|
mode_str[2] = (mode & S_IWUSR) ? 'w' : '-';
|
||||||
|
mode_str[3] = (mode & S_IXUSR) ? 'x' : '-';
|
||||||
|
mode_str[4] = (mode & S_IRGRP) ? 'r' : '-';
|
||||||
|
mode_str[5] = (mode & S_IWGRP) ? 'w' : '-';
|
||||||
|
mode_str[6] = (mode & S_IXGRP) ? 'x' : '-';
|
||||||
|
mode_str[7] = (mode & S_IROTH) ? 'r' : '-';
|
||||||
|
mode_str[8] = (mode & S_IWOTH) ? 'w' : '-';
|
||||||
|
mode_str[9] = (mode & S_IXOTH) ? 'x' : '-';
|
||||||
|
mode_str[10] = '\0'; // Null terminator
|
||||||
|
return mode_str;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Highlight current line by reversing the color
|
* Highlight current line by reversing the color
|
||||||
*/
|
*/
|
||||||
void highlight_current_line()
|
void highlight_current_line()
|
||||||
{
|
{
|
||||||
|
#if DRAW_BORDERS
|
||||||
|
draw_border_title(directory_border, true);
|
||||||
|
#endif
|
||||||
|
|
||||||
long overflow = 0;
|
long overflow = 0;
|
||||||
if (current_selection > LINES - 4) {
|
if (current_selection > LINES - 4) {
|
||||||
/* overflown */
|
/* overflown */
|
||||||
|
@ -582,7 +625,7 @@ void highlight_current_line()
|
||||||
/* calculate range of files to show */
|
/* calculate range of files to show */
|
||||||
long range = files->length;
|
long range = files->length;
|
||||||
/* not highlight if no files in directory */
|
/* not highlight if no files in directory */
|
||||||
if (range == 0) {
|
if (range == 0 && errno == 0) {
|
||||||
#if DRAW_PREVIEW
|
#if DRAW_PREVIEW
|
||||||
wprintw(preview_content, "empty directory");
|
wprintw(preview_content, "empty directory");
|
||||||
wrefresh(preview_content);
|
wrefresh(preview_content);
|
||||||
|
@ -603,9 +646,6 @@ void highlight_current_line()
|
||||||
if ((overflow == 0 && i == current_selection) || (overflow != 0 && i == current_selection)) {
|
if ((overflow == 0 && i == current_selection) || (overflow != 0 && i == current_selection)) {
|
||||||
wattron(directory_content, A_REVERSE);
|
wattron(directory_content, A_REVERSE);
|
||||||
|
|
||||||
/* update the panel */
|
|
||||||
wclear(panel);
|
|
||||||
|
|
||||||
/* check for marked files */
|
/* check for marked files */
|
||||||
long num_marked = marked->length;
|
long num_marked = marked->length;
|
||||||
if (num_marked > 0) {
|
if (num_marked > 0) {
|
||||||
|
@ -614,9 +654,9 @@ void highlight_current_line()
|
||||||
char *selected = memalloc((m_len + 1) * sizeof(char));
|
char *selected = memalloc((m_len + 1) * sizeof(char));
|
||||||
|
|
||||||
snprintf(selected, m_len + 1, "[%ld] selected", num_marked);
|
snprintf(selected, m_len + 1, "[%ld] selected", num_marked);
|
||||||
wprintw(panel, "(%ld/%ld) %s %s", current_selection + 1, files->length, selected, cwd);
|
wpprintw("(%ld/%ld) %s %s", current_selection + 1, files->length, selected, cwd);
|
||||||
} else {
|
} else {
|
||||||
wprintw(panel, "(%ld/%ld) %s", current_selection + 1, files->length, cwd);
|
wpprintw("(%ld/%ld) %s", current_selection + 1, files->length, cwd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* print the actual filename and stats */
|
/* print the actual filename and stats */
|
||||||
|
@ -655,6 +695,9 @@ void highlight_current_line()
|
||||||
show_file_content();
|
show_file_content();
|
||||||
#endif
|
#endif
|
||||||
wrefresh(preview_content);
|
wrefresh(preview_content);
|
||||||
|
#if DRAW_BORDERS
|
||||||
|
draw_border_title(preview_border, true);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -673,9 +716,6 @@ void show_file_content()
|
||||||
mvwprintw(preview_content, 0, 0, "Unable to read %s", current_file.path);
|
mvwprintw(preview_content, 0, 0, "Unable to read %s", current_file.path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#if DRAW_BORDERS
|
|
||||||
draw_border_title(preview_border, true);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int c;
|
int c;
|
||||||
/* check if its binary */
|
/* check if its binary */
|
||||||
|
@ -732,6 +772,22 @@ void edit_file()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void toggle_executable()
|
||||||
|
{
|
||||||
|
file current_file = files->items[current_selection];
|
||||||
|
struct stat st;
|
||||||
|
if (stat(current_file.path, &st) == -1) {
|
||||||
|
wpprintw("stat failed: %s\n", strerror(errno));
|
||||||
|
}
|
||||||
|
if (strncmp(current_file.type, "DIR", 3) == 0)
|
||||||
|
return;
|
||||||
|
/* chmod by xor executable bits */
|
||||||
|
if (chmod(current_file.path, st.st_mode ^ (S_IXUSR | S_IXGRP | S_IXOTH)) == -1) {
|
||||||
|
wpprintw("Error toggling executable: %s", strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int write_last_d()
|
int write_last_d()
|
||||||
{
|
{
|
||||||
#ifdef LAST_D
|
#ifdef LAST_D
|
||||||
|
@ -772,10 +828,13 @@ int write_last_d()
|
||||||
/*
|
/*
|
||||||
* Print line to the panel
|
* Print line to the panel
|
||||||
*/
|
*/
|
||||||
void wpprintw(const char *line)
|
void wpprintw(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
wclear(panel);
|
wclear(panel);
|
||||||
wprintw(panel, "%s", line);
|
vw_printw(panel, fmt, args);
|
||||||
|
va_end(args);
|
||||||
wrefresh(panel);
|
wrefresh(panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
20
file.c
20
file.c
|
@ -132,15 +132,27 @@ char *get_line(ArrayList *list, long index, bool detail)
|
||||||
{
|
{
|
||||||
file file = list->items[index];
|
file file = list->items[index];
|
||||||
char *name = strdup(file.path);
|
char *name = strdup(file.path);
|
||||||
char *stats = strdup(file.stats);
|
char *stats = NULL;
|
||||||
size_t length = strlen(name) + strlen(stats) + 2; /* one for space and one for null */
|
size_t length;
|
||||||
|
if (detail) {
|
||||||
|
stats = strdup(file.stats);
|
||||||
|
length = strlen(name) + strlen(stats) + 2; /* one for space and one for null */
|
||||||
|
if (stats == NULL) {
|
||||||
|
perror("ccc");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
length = strlen(name) + 2; /* one for space and one for null */
|
||||||
|
}
|
||||||
char *line = memalloc(length * sizeof(char));
|
char *line = memalloc(length * sizeof(char));
|
||||||
|
|
||||||
name = basename(name);
|
name = basename(name);
|
||||||
if (name == NULL || stats == NULL)
|
if (name == NULL)
|
||||||
perror("ccc");
|
perror("ccc");
|
||||||
|
if (detail) {
|
||||||
snprintf(line, length, "%s %s", stats, name);
|
snprintf(line, length, "%s %s", stats, name);
|
||||||
|
} else {
|
||||||
|
snprintf(line, length, "%s", name);
|
||||||
|
}
|
||||||
|
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue