icons and fix goto trash dir and fix preview
This commit is contained in:
parent
eab8013601
commit
b470b7b286
7 changed files with 275 additions and 84 deletions
|
@ -13,6 +13,7 @@ Consider this project incomplete and WIP!
|
||||||
| Standard movement | X | |
|
| Standard movement | X | |
|
||||||
| Advanced movement (jumps) | X | |
|
| Advanced movement (jumps) | X | |
|
||||||
| File details | X | |
|
| File details | X | |
|
||||||
|
| File icons! | X | |
|
||||||
| Searching for files | | |
|
| Searching for files | | |
|
||||||
| Sorting | | |
|
| Sorting | | |
|
||||||
| Marking and marking operations | | |
|
| Marking and marking operations | | |
|
||||||
|
@ -32,9 +33,10 @@ Consider this project incomplete and WIP!
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
|
||||||
- gcc
|
- gcc
|
||||||
- ncurses
|
- ncursesw
|
||||||
- make
|
- make
|
||||||
- pkg-config
|
- pkg-config
|
||||||
|
- Any [Nerd Font](https://www.nerdfonts.com/) for file icons (optional, but turned on by default)
|
||||||
|
|
||||||
### Building
|
### Building
|
||||||
|
|
||||||
|
|
129
ccc.c
129
ccc.c
|
@ -10,6 +10,8 @@
|
||||||
#include <ftw.h>
|
#include <ftw.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <ncurses.h>
|
#include <ncurses.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
@ -18,8 +20,9 @@
|
||||||
/* functions' definitions */
|
/* functions' definitions */
|
||||||
void show_help();
|
void show_help();
|
||||||
void start_ccc();
|
void start_ccc();
|
||||||
|
char *check_trash_dir();
|
||||||
void change_dir(const char *buf, int selection, int ftype);
|
void change_dir(const char *buf, int selection, int ftype);
|
||||||
int mkdir_p(const char *destdir);
|
void 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);
|
||||||
|
@ -41,6 +44,7 @@ bool show_hidden = SHOW_HIDDEN;
|
||||||
bool file_details = SHOW_DETAILS;
|
bool file_details = SHOW_DETAILS;
|
||||||
char *cwd;
|
char *cwd;
|
||||||
char *p_cwd; /* previous cwd */
|
char *p_cwd; /* previous cwd */
|
||||||
|
char *trash_dir;
|
||||||
int half_width;
|
int half_width;
|
||||||
ArrayList *files;
|
ArrayList *files;
|
||||||
ArrayList *marked;
|
ArrayList *marked;
|
||||||
|
@ -71,6 +75,7 @@ int main(int argc, char** argv)
|
||||||
/* initialize screen, don't print special chars,
|
/* initialize screen, don't print special chars,
|
||||||
* make ctrl + c work, don't show cursor
|
* make ctrl + c work, don't show cursor
|
||||||
* enable arrow keys */
|
* enable arrow keys */
|
||||||
|
setlocale(LC_ALL, "");
|
||||||
initscr();
|
initscr();
|
||||||
noecho();
|
noecho();
|
||||||
cbreak();
|
cbreak();
|
||||||
|
@ -234,26 +239,10 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
/* go to the trash dir */
|
/* go to the trash dir */
|
||||||
case 't':;
|
case 't':;
|
||||||
#ifdef TRASH_DIR
|
char *trash_dir = check_trash_dir();
|
||||||
char *trash_dir = TRASH_DIR;
|
if (trash_dir != NULL)
|
||||||
#else
|
|
||||||
char *trash_dir = getenv("CCC_TRASH");
|
|
||||||
#endif
|
|
||||||
if (trash_dir == NULL) {
|
|
||||||
wpprintw("$CCC_TRASH is not defined");
|
|
||||||
} else {
|
|
||||||
if (access(trash_dir, F_OK) != 0) {
|
|
||||||
/* create the directory with 755 perm if it doesn't exit */
|
|
||||||
if (mkdir_p(trash_dir) == -1) {
|
|
||||||
switch (errno) {
|
|
||||||
case EACCES:
|
|
||||||
wpprintw("Parent directory does not allow write permission or one of directories does not allow search access");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
change_dir(trash_dir, 0, 0);
|
change_dir(trash_dir, 0, 0);
|
||||||
}
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
/* show directories' sizes */
|
/* show directories' sizes */
|
||||||
case 'A':
|
case 'A':
|
||||||
|
@ -302,7 +291,11 @@ int main(int argc, char** argv)
|
||||||
/* delete */
|
/* delete */
|
||||||
case 'd':;
|
case 'd':;
|
||||||
if (marked->length) {
|
if (marked->length) {
|
||||||
;
|
char *trash_dir = check_trash_dir();
|
||||||
|
if (trash_dir != NULL) {
|
||||||
|
;
|
||||||
|
/* do your magic here */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -374,6 +367,44 @@ void start_ccc()
|
||||||
init_windows();
|
init_windows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Checks if trash directory is set and returns it */
|
||||||
|
char *check_trash_dir()
|
||||||
|
{
|
||||||
|
char *path = memalloc(PATH_MAX * sizeof(char));
|
||||||
|
|
||||||
|
#ifdef TRASH_DIR
|
||||||
|
trash_dir = TRASH_DIR;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* check if there is trash_dir */
|
||||||
|
if (trash_dir == NULL) {
|
||||||
|
wpprintw("No trash directory defined");
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
/* if trash_dir has ~ then make it $HOME */
|
||||||
|
/* use path as trash_dir */
|
||||||
|
if (trash_dir[0] == '~') {
|
||||||
|
char *home = getenv("HOME");
|
||||||
|
if (home == NULL) {
|
||||||
|
wpprintw("$HOME is not defined, can't read the trash directory");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/* replace ~ with home */
|
||||||
|
snprintf(path, PATH_MAX, "%s%s", home, trash_dir + 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
strcpy(path, trash_dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if has access to trash_dir */
|
||||||
|
if (access(path, F_OK) != 0) {
|
||||||
|
/* create the directory with 755 perm if it doesn't exit */
|
||||||
|
mkdir_p(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Change directory in window with selection
|
* Change directory in window with selection
|
||||||
*/
|
*/
|
||||||
|
@ -399,7 +430,7 @@ void change_dir(const char *buf, int selection, int ftype)
|
||||||
* Recursively create directory by creating each subdirectory
|
* Recursively create directory by creating each subdirectory
|
||||||
* like mkdir -p
|
* like mkdir -p
|
||||||
*/
|
*/
|
||||||
int mkdir_p(const char *destdir)
|
void mkdir_p(const char *destdir)
|
||||||
{
|
{
|
||||||
char *path = memalloc(PATH_MAX * sizeof(char));
|
char *path = memalloc(PATH_MAX * sizeof(char));
|
||||||
char dir_path[PATH_MAX] = "";
|
char dir_path[PATH_MAX] = "";
|
||||||
|
@ -408,7 +439,7 @@ int mkdir_p(const char *destdir)
|
||||||
char *home = getenv("HOME");
|
char *home = getenv("HOME");
|
||||||
if (home == NULL) {
|
if (home == NULL) {
|
||||||
wpprintw("$HOME is not defined");
|
wpprintw("$HOME is not defined");
|
||||||
return -1;
|
return;
|
||||||
}
|
}
|
||||||
/* replace ~ with home */
|
/* replace ~ with home */
|
||||||
snprintf(path, PATH_MAX, "%s%s", home, destdir + 1);
|
snprintf(path, PATH_MAX, "%s%s", home, destdir + 1);
|
||||||
|
@ -433,15 +464,15 @@ int mkdir_p(const char *destdir)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
perror("ccc");
|
wpprintw("mkdir failed: %s\n", strerror(errno));
|
||||||
free(path);
|
free(path);
|
||||||
return -1;
|
return;
|
||||||
}
|
}
|
||||||
token = strtok(NULL, "/");
|
token = strtok(NULL, "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
free(path);
|
free(path);
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -493,7 +524,7 @@ int get_directory_size(const char *fpath, const struct stat *sb, int typeflag, s
|
||||||
/*
|
/*
|
||||||
* Get file's last modified time, size, type
|
* Get file's last modified time, size, type
|
||||||
* Add that file into list
|
* Add that file into list
|
||||||
* ftype: normal file = 0, normal marked = 1, marking ALL = 2
|
* ftype: normal file = 0, normal marked = 1, marked ALL = 2
|
||||||
*/
|
*/
|
||||||
void add_file_stat(char *filepath, int ftype)
|
void add_file_stat(char *filepath, int ftype)
|
||||||
{
|
{
|
||||||
|
@ -501,32 +532,35 @@ void add_file_stat(char *filepath, int ftype)
|
||||||
if (stat(filepath, &file_stat) == -1) {
|
if (stat(filepath, &file_stat) == -1) {
|
||||||
/* can't be triggered? */
|
/* can't be triggered? */
|
||||||
if (errno == EACCES)
|
if (errno == EACCES)
|
||||||
arraylist_add(files, filepath, "", "", 8, false, false);
|
arraylist_add(files, filepath, "", "", "", 8, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get file type and color, 4 chars for the type */
|
/* get file type and color, 4 chars for the type and icon */
|
||||||
char *type = memalloc(4 * sizeof(char));
|
char *type = memalloc(4 * sizeof(char));
|
||||||
|
wchar_t *icon = memalloc(2 * sizeof(wchar_t));
|
||||||
|
wcsncpy(icon, L"", 2);
|
||||||
int color;
|
int color;
|
||||||
|
|
||||||
if (S_ISDIR(file_stat.st_mode)) {
|
if (S_ISDIR(file_stat.st_mode)) {
|
||||||
strcpy(type, "DIR"); /* directory type */
|
strncpy(type, "DIR", 4); /* directory type */
|
||||||
color = 5; /* blue color */
|
color = 5; /* blue color */
|
||||||
} else if (S_ISREG(file_stat.st_mode)) {
|
} else if (S_ISREG(file_stat.st_mode)) {
|
||||||
strcpy(type, "REG"); /* regular file */
|
strncpy(type, "REG", 4); /* regular file */
|
||||||
color = 8; /* white color */
|
color = 8; /* white color */
|
||||||
} else if (S_ISLNK(file_stat.st_mode)) {
|
} else if (S_ISLNK(file_stat.st_mode)) {
|
||||||
strcpy(type, "LNK"); /* symbolic link */
|
strncpy(type, "LNK", 4); /* symbolic link */
|
||||||
color = 3; /* green color */
|
color = 3; /* green color */
|
||||||
} else if (S_ISCHR(file_stat.st_mode)) {
|
} else if (S_ISCHR(file_stat.st_mode)) {
|
||||||
strcpy(type, "CHR"); /* character device */
|
strncpy(type, "CHR", 4); /* character device */
|
||||||
color = 8; /* white color */
|
color = 8; /* white color */
|
||||||
} else if (S_ISSOCK(file_stat.st_mode)) {
|
} else if (S_ISSOCK(file_stat.st_mode)) {
|
||||||
strcpy(type, "SOC"); /* socket */
|
strncpy(type, "SOC", 4); /* socket */
|
||||||
color = 8; /* white color */
|
color = 8; /* white color */
|
||||||
} else if (S_ISBLK(file_stat.st_mode)) {
|
} else if (S_ISBLK(file_stat.st_mode)) {
|
||||||
strcpy(type, "BLK"); /* block device */
|
strncpy(type, "BLK", 4); /* block device */
|
||||||
color = 4; /* yellow color */
|
color = 4; /* yellow color */
|
||||||
} else if (S_ISFIFO(file_stat.st_mode)) {
|
} else if (S_ISFIFO(file_stat.st_mode)) {
|
||||||
strcpy(type, "FIF"); /* FIFO */
|
strncpy(type, "FIF", 4); /* FIFO */
|
||||||
color = 8; /* white color */
|
color = 8; /* white color */
|
||||||
} else {
|
} else {
|
||||||
color = 8; /* white color */
|
color = 8; /* white color */
|
||||||
|
@ -536,16 +570,16 @@ void add_file_stat(char *filepath, int ftype)
|
||||||
if (ftype == 1 || ftype == 2) {
|
if (ftype == 1 || ftype == 2) {
|
||||||
/* force if user is marking all files */
|
/* force if user is marking all files */
|
||||||
bool force = ftype == 2 ? true : false;
|
bool force = ftype == 2 ? true : false;
|
||||||
arraylist_add(marked, filepath, NULL, type, 8, true, force);
|
arraylist_add(marked, filepath, NULL, type, icon, 8, true, force);
|
||||||
/* free type and return without allocating more stuff */
|
/* free type and return without allocating more stuff */
|
||||||
free(type);
|
free(type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get last modified time */
|
/* get last modified time */
|
||||||
char *time = memalloc(20 * sizeof(char));
|
char *time = memalloc(17 * sizeof(char));
|
||||||
/* format last modified time to a string */
|
/* format last modified time to a string */
|
||||||
strftime(time, 20, "%Y-%m-%d %H:%M", localtime(&file_stat.st_mtime));
|
strftime(time, 17, "%Y-%m-%d %H:%M", localtime(&file_stat.st_mtime));
|
||||||
|
|
||||||
/* get file size */
|
/* get file size */
|
||||||
double bytes = file_stat.st_size;
|
double bytes = file_stat.st_size;
|
||||||
|
@ -560,7 +594,7 @@ void add_file_stat(char *filepath, int ftype)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* max 25 chars due to long, space, suffix and null */
|
/* max 25 chars due to long, space, suffix and null */
|
||||||
char *size = memalloc(25 * sizeof(char));
|
char *size = memalloc(8 * sizeof(char));
|
||||||
int unit = 0;
|
int unit = 0;
|
||||||
const char* units[] = {"B", "KiB", "MiB", "GiB", "TiB", "PiB"};
|
const char* units[] = {"B", "KiB", "MiB", "GiB", "TiB", "PiB"};
|
||||||
while (bytes > 1024) {
|
while (bytes > 1024) {
|
||||||
|
@ -573,17 +607,18 @@ void add_file_stat(char *filepath, int ftype)
|
||||||
/* get file mode string */
|
/* get file mode string */
|
||||||
char *mode_str = get_file_mode(file_stat.st_mode);
|
char *mode_str = get_file_mode(file_stat.st_mode);
|
||||||
|
|
||||||
char *total_stat = memalloc(56 * sizeof(char));
|
/* 11 + 17 + 8 + 1 for null */
|
||||||
snprintf(total_stat, 56, "%s %s %-8s", mode_str, time, size);
|
char *total_stat = memalloc(37 * sizeof(char));
|
||||||
total_stat[strlen(total_stat)] = '\0';
|
snprintf(total_stat, 37, "%s %s %-8s", mode_str, time, size);
|
||||||
|
|
||||||
arraylist_add(files, filepath, total_stat, type, color, false, false);
|
arraylist_add(files, filepath, total_stat, type, icon, color, false, false);
|
||||||
|
|
||||||
free(time);
|
free(time);
|
||||||
free(size);
|
free(size);
|
||||||
free(total_stat);
|
free(total_stat);
|
||||||
free(type);
|
free(type);
|
||||||
free(mode_str);
|
free(mode_str);
|
||||||
|
free(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -593,7 +628,7 @@ void add_file_stat(char *filepath, int ftype)
|
||||||
char *get_file_mode(mode_t mode)
|
char *get_file_mode(mode_t mode)
|
||||||
{
|
{
|
||||||
char *mode_str = memalloc(sizeof(char) * 11);
|
char *mode_str = memalloc(sizeof(char) * 11);
|
||||||
mode_str[0] = S_ISDIR(mode) ? 'd' : '-'; // Check if it's a directory
|
mode_str[0] = S_ISDIR(mode) ? 'd' : '-'; /* Check if it's a directory */
|
||||||
mode_str[1] = (mode & S_IRUSR) ? 'r' : '-';
|
mode_str[1] = (mode & S_IRUSR) ? 'r' : '-';
|
||||||
mode_str[2] = (mode & S_IWUSR) ? 'w' : '-';
|
mode_str[2] = (mode & S_IWUSR) ? 'w' : '-';
|
||||||
mode_str[3] = (mode & S_IXUSR) ? 'x' : '-';
|
mode_str[3] = (mode & S_IXUSR) ? 'x' : '-';
|
||||||
|
@ -603,7 +638,7 @@ char *get_file_mode(mode_t mode)
|
||||||
mode_str[7] = (mode & S_IROTH) ? 'r' : '-';
|
mode_str[7] = (mode & S_IROTH) ? 'r' : '-';
|
||||||
mode_str[8] = (mode & S_IWOTH) ? 'w' : '-';
|
mode_str[8] = (mode & S_IWOTH) ? 'w' : '-';
|
||||||
mode_str[9] = (mode & S_IXOTH) ? 'x' : '-';
|
mode_str[9] = (mode & S_IXOTH) ? 'x' : '-';
|
||||||
mode_str[10] = '\0'; // Null terminator
|
mode_str[10] = '\0';
|
||||||
return mode_str;
|
return mode_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -694,10 +729,10 @@ void highlight_current_line()
|
||||||
#if DRAW_PREVIEW
|
#if DRAW_PREVIEW
|
||||||
show_file_content();
|
show_file_content();
|
||||||
#endif
|
#endif
|
||||||
wrefresh(preview_content);
|
|
||||||
#if DRAW_BORDERS
|
#if DRAW_BORDERS
|
||||||
draw_border_title(preview_border, true);
|
draw_border_title(preview_border, true);
|
||||||
#endif
|
#endif
|
||||||
|
wrefresh(preview_content);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
6
config.h
6
config.h
|
@ -9,7 +9,8 @@
|
||||||
#define DRAW_BORDERS true /* Draw borders around windows? */
|
#define DRAW_BORDERS true /* Draw borders around windows? */
|
||||||
#define DRAW_PREVIEW true /* Draw file preview? */
|
#define DRAW_PREVIEW true /* Draw file preview? */
|
||||||
#define SHOW_HIDDEN true /* show hidden files/dotfiles in preview */
|
#define SHOW_HIDDEN true /* show hidden files/dotfiles in preview */
|
||||||
#define SHOW_DETAILS true /* show file details */
|
#define SHOW_DETAILS true /* show file details */
|
||||||
|
#define SHOW_ICONS true /* show file icons */
|
||||||
|
|
||||||
/* set width offset for windows:
|
/* set width offset for windows:
|
||||||
+-------------%-------------+
|
+-------------%-------------+
|
||||||
|
@ -31,6 +32,9 @@ In COLS:
|
||||||
/* File location to write last directory */
|
/* File location to write last directory */
|
||||||
#define LAST_D "~/.cache/ccc/.ccc_d"
|
#define LAST_D "~/.cache/ccc/.ccc_d"
|
||||||
|
|
||||||
|
/* will create this directory if doesn't exist! */
|
||||||
|
#define TRASH_DIR "~/.cache/ccc/trash/"
|
||||||
|
|
||||||
/* Keybindings */
|
/* Keybindings */
|
||||||
#define CTRLD 0x04
|
#define CTRLD 0x04
|
||||||
#define ENTER 0xA
|
#define ENTER 0xA
|
||||||
|
|
69
file.c
69
file.c
|
@ -2,21 +2,10 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "file.h"
|
||||||
typedef struct file {
|
|
||||||
char *path;
|
|
||||||
char *stats;
|
|
||||||
char *type;
|
|
||||||
int color;
|
|
||||||
} file;
|
|
||||||
|
|
||||||
typedef struct ArrayList {
|
|
||||||
size_t length;
|
|
||||||
size_t capacity;
|
|
||||||
file *items;
|
|
||||||
} ArrayList;
|
|
||||||
|
|
||||||
ArrayList *arraylist_init(size_t capacity)
|
ArrayList *arraylist_init(size_t capacity)
|
||||||
{
|
{
|
||||||
|
@ -24,6 +13,7 @@ ArrayList *arraylist_init(size_t capacity)
|
||||||
list->length = 0;
|
list->length = 0;
|
||||||
list->capacity = capacity;
|
list->capacity = capacity;
|
||||||
list->items = memalloc(capacity * sizeof(file));
|
list->items = memalloc(capacity * sizeof(file));
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +26,10 @@ void arraylist_free(ArrayList *list)
|
||||||
free(list->items[i].path);
|
free(list->items[i].path);
|
||||||
if (list->items[i].stats != NULL)
|
if (list->items[i].stats != NULL)
|
||||||
free(list->items[i].stats);
|
free(list->items[i].stats);
|
||||||
|
/*if (list->items[i].icon != NULL)
|
||||||
|
free(list->items[i].icon);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
free(list->items);
|
free(list->items);
|
||||||
list->length = 0;
|
list->length = 0;
|
||||||
}
|
}
|
||||||
|
@ -48,63 +41,66 @@ bool arraylist_includes(ArrayList *list, char *path)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void arraylist_remove(ArrayList *list, long index)
|
void arraylist_remove(ArrayList *list, long index)
|
||||||
{
|
{
|
||||||
if (index >= list->length) {
|
if (index >= list->length)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
free(list->items[index].path);
|
free(list->items[index].path);
|
||||||
free(list->items[index].stats);
|
free(list->items[index].stats);
|
||||||
free(list->items[index].type);
|
free(list->items[index].type);
|
||||||
|
free(list->items[index].icon);
|
||||||
|
|
||||||
for (long i = index; i < list->length - 1; i++) {
|
for (long i = index; i < list->length - 1; i++)
|
||||||
list->items[i] = list->items[i + 1];
|
list->items[i] = list->items[i + 1];
|
||||||
}
|
|
||||||
|
|
||||||
list->length--;
|
list->length--;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* force will not remove duplicate marked files, instead it just skip adding
|
* Force will not remove duplicate marked files, instead it just skip adding
|
||||||
*/
|
*/
|
||||||
void arraylist_add(ArrayList *list, char *filepath, char *stats, char *type, int color, bool marked, bool force)
|
void arraylist_add(ArrayList *list, char *filepath, char *stats, char *type, wchar_t *icon, int color, bool marked, bool force)
|
||||||
{
|
{
|
||||||
char *filepath_cp = NULL;
|
char *filepath_cp = NULL;
|
||||||
char *stats_cp = NULL;
|
char *stats_cp = NULL;
|
||||||
char *type_cp = NULL;
|
char *type_cp = NULL;
|
||||||
|
wchar_t *icon_cp = NULL;
|
||||||
|
|
||||||
if (filepath != NULL) {
|
if (filepath != NULL) {
|
||||||
filepath_cp = strdup(filepath);
|
filepath_cp = strdup(filepath);
|
||||||
if (filepath_cp == NULL) {
|
if (filepath_cp == NULL)
|
||||||
perror("ccc");
|
perror("ccc");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (stats != NULL) {
|
if (stats != NULL) {
|
||||||
stats_cp = strdup(stats);
|
stats_cp = strdup(stats);
|
||||||
if (stats_cp == NULL) {
|
if (stats_cp == NULL)
|
||||||
perror("ccc");
|
perror("ccc");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (type != NULL) {
|
if (type != NULL) {
|
||||||
type_cp = strdup(type);
|
type_cp = strdup(type);
|
||||||
if (type_cp == NULL) {
|
if (type_cp == NULL)
|
||||||
|
perror("ccc");
|
||||||
|
}
|
||||||
|
if (icon != NULL) {
|
||||||
|
icon_cp = wcsdup(icon);
|
||||||
|
if (icon_cp == NULL)
|
||||||
perror("ccc");
|
perror("ccc");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* path, stats, type, color */
|
/* path, stats, type, icon, color */
|
||||||
file new_file = { filepath_cp, stats_cp, type_cp, color };
|
file new_file = { filepath_cp, stats_cp, type_cp, icon_cp, color };
|
||||||
|
|
||||||
if (list->capacity != list->length) {
|
if (list->capacity != list->length) {
|
||||||
if (marked) {
|
if (marked) {
|
||||||
for (int i = 0; i < list->length; i++) {
|
for (int i = 0; i < list->length; i++) {
|
||||||
if (strcmp(list->items[i].path, new_file.path) == 0) {
|
if (strcmp(list->items[i].path, new_file.path) == 0) {
|
||||||
if (!force) {
|
if (!force)
|
||||||
arraylist_remove(list, i);
|
arraylist_remove(list, i);
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,9 +112,10 @@ void arraylist_add(ArrayList *list, char *filepath, char *stats, char *type, int
|
||||||
file *old_items = list->items;
|
file *old_items = list->items;
|
||||||
list->capacity = new_cap;
|
list->capacity = new_cap;
|
||||||
list->items = new_items;
|
list->items = new_items;
|
||||||
for (int i = 0; i < list->length; i++) {
|
|
||||||
|
for (int i = 0; i < list->length; i++)
|
||||||
new_items[i] = old_items[i];
|
new_items[i] = old_items[i];
|
||||||
}
|
|
||||||
free(old_items);
|
free(old_items);
|
||||||
list->items[list->length] = new_file;
|
list->items[list->length] = new_file;
|
||||||
}
|
}
|
||||||
|
@ -132,6 +129,7 @@ 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);
|
||||||
|
wchar_t *icon = wcsdup(file.icon);
|
||||||
char *stats = NULL;
|
char *stats = NULL;
|
||||||
size_t length;
|
size_t length;
|
||||||
if (detail) {
|
if (detail) {
|
||||||
|
@ -148,10 +146,13 @@ char *get_line(ArrayList *list, long index, bool detail)
|
||||||
name = basename(name);
|
name = basename(name);
|
||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
perror("ccc");
|
perror("ccc");
|
||||||
|
|
||||||
|
/*printf("%ls", icon);*/
|
||||||
|
|
||||||
if (detail) {
|
if (detail) {
|
||||||
snprintf(line, length, "%s %s", stats, name);
|
snprintf(line, length, "%s %ls %s", stats, icon, name);
|
||||||
} else {
|
} else {
|
||||||
snprintf(line, length, "%s", name);
|
snprintf(line, length, "%ls %s", icon, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return line;
|
return line;
|
||||||
|
|
3
file.h
3
file.h
|
@ -7,6 +7,7 @@ typedef struct file {
|
||||||
char *path;
|
char *path;
|
||||||
char *stats;
|
char *stats;
|
||||||
char *type;
|
char *type;
|
||||||
|
wchar_t *icon;
|
||||||
int color;
|
int color;
|
||||||
} file;
|
} file;
|
||||||
|
|
||||||
|
@ -20,7 +21,7 @@ ArrayList *arraylist_init(size_t capacity);
|
||||||
void arraylist_free(ArrayList *list);
|
void arraylist_free(ArrayList *list);
|
||||||
bool arraylist_includes(ArrayList *list, char *path);
|
bool arraylist_includes(ArrayList *list, char *path);
|
||||||
void arraylist_remove(ArrayList *list, long index);
|
void arraylist_remove(ArrayList *list, long index);
|
||||||
void arraylist_add(ArrayList *list, char *filepath, char *stats, char *type, int color, bool marked, bool force);
|
void arraylist_add(ArrayList *list, char *filepath, char *stats, char *type, wchar_t *icon, int color, bool marked, bool force);
|
||||||
char *get_line(ArrayList *list, long index, bool detail);
|
char *get_line(ArrayList *list, long index, bool detail);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
130
icons.c
Normal file
130
icons.c
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#define MAX_NAME 30
|
||||||
|
#define TABLE_SIZE 20
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char name[MAX_NAME];
|
||||||
|
char *icon;
|
||||||
|
} icon;
|
||||||
|
|
||||||
|
icon *hash_table[TABLE_SIZE];
|
||||||
|
|
||||||
|
/* Hashes every name with: name and TABLE_SIZE */
|
||||||
|
unsigned int hash(char *name)
|
||||||
|
{
|
||||||
|
int length = strnlen(name, MAX_NAME), i = 0;
|
||||||
|
unsigned int hash_value = 0;
|
||||||
|
|
||||||
|
for (; i < length; i++) {
|
||||||
|
hash_value += name[i];
|
||||||
|
hash_value = (hash_value * name[i]) % TABLE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_hash_table()
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for (; i < TABLE_SIZE; i++)
|
||||||
|
hash_table[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_table()
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for (; i < TABLE_SIZE; i++) {
|
||||||
|
if (hash_table[i] == NULL) {
|
||||||
|
printf("%i. ---\n", i);
|
||||||
|
} else {
|
||||||
|
printf("%i. %s %s\n", i, hash_table[i]->name, hash_table[i]->icon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Gets hashed name and tries to store the icon struct in that place */
|
||||||
|
bool add_icon(icon *p)
|
||||||
|
{
|
||||||
|
if (p == NULL) return false;
|
||||||
|
|
||||||
|
int index = hash(p->name);
|
||||||
|
int i = 0, try;
|
||||||
|
|
||||||
|
try = (i + index) % TABLE_SIZE;
|
||||||
|
if (hash_table[try] == NULL) {
|
||||||
|
hash_table[try] = p;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rehashes the name and then looks in this spot, if found returns icon */
|
||||||
|
icon *icon_search(char *name)
|
||||||
|
{
|
||||||
|
int index = hash(name), i = 0;
|
||||||
|
|
||||||
|
// this handles icons with the same hash values
|
||||||
|
// or use linked lists in structs
|
||||||
|
// for (; i < TABLE_SIZE; i++) {
|
||||||
|
// int try = (index + i) % TABLE_SIZE;
|
||||||
|
//
|
||||||
|
// for (; i < TABLE_SIZE; i++) {
|
||||||
|
// try = (i + index) % TABLE_SIZE;
|
||||||
|
//
|
||||||
|
// if (hash_table[try] == NULL)
|
||||||
|
// return false;
|
||||||
|
//
|
||||||
|
// if (strncmp(hash_table[try]->name, name, TABLE_SIZE) == 0)
|
||||||
|
// return hash_table[try];
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return NULL;
|
||||||
|
|
||||||
|
if (hash_table[index] == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (strncmp(hash_table[index]->name, name, MAX_NAME) == 0)
|
||||||
|
return hash_table[index];
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
init_hash_table();
|
||||||
|
|
||||||
|
/* name reference name icon */
|
||||||
|
icon c = { .name="c", .icon="" };
|
||||||
|
icon h = { .name="h", .icon="" };
|
||||||
|
icon cpp = { .name="cpp", .icon="" };
|
||||||
|
icon hpp = { .name="hpp", .icon="" };
|
||||||
|
icon md = { .name="md", .icon="" };
|
||||||
|
|
||||||
|
add_icon(&c);
|
||||||
|
add_icon(&h);
|
||||||
|
add_icon(&cpp);
|
||||||
|
add_icon(&hpp);
|
||||||
|
add_icon(&md);
|
||||||
|
|
||||||
|
print_table();
|
||||||
|
|
||||||
|
icon *tmp = icon_search("hpp");
|
||||||
|
|
||||||
|
if (tmp == NULL)
|
||||||
|
printf("null\n");
|
||||||
|
|
||||||
|
printf("%s", tmp->icon);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
18
icons.h
Normal file
18
icons.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#ifndef FILE_H_
|
||||||
|
#define FILE_H_
|
||||||
|
|
||||||
|
#define MAX_NAME 30
|
||||||
|
#define TABLE_SIZE 20
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char name[MAX_NAME];
|
||||||
|
char icon[4];
|
||||||
|
} icon;
|
||||||
|
|
||||||
|
unsigned int hash(char *name);
|
||||||
|
void init_hash_table();
|
||||||
|
void print_table();
|
||||||
|
bool add_icon(icon *p);
|
||||||
|
icon *icon_search(char *name);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue