Merge pull request #16 from piotr-marendowski/feature

Feature
This commit is contained in:
Night Kaly 2024-03-16 19:39:26 +00:00 committed by GitHub
commit 5f6c4ee903
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 193 additions and 45 deletions

View file

@ -1,26 +1,30 @@
.POSIX: .POSIX:
.SUFFIXES: .SUFFIXES:
CC = cc
VERSION = 1.0
TARGET = ccc TARGET = ccc
MANPAGE = ccc.1 MANPAGE = ccc.1
SRC = ccc.c util.c file.c config.h CONF = config.h
PREFIX ?= /usr/local
BINDIR = $(PREFIX)/bin
MANDIR = $(PREFIX)/share/man/man1
# Flags # Flags
LDFLAGS = $(shell pkg-config --libs ncurses) LDFLAGS = $(shell pkg-config --libs ncurses)
CFLAGS = -march=native -mtune=native -O3 -pipe -s -std=c99 -pedantic $(shell pkg-config --cflags ncurses) -Wall # -Wextra -Werror CFLAGS = -march=native -mtune=native -O3 -pipe -s -std=c99 -pedantic $(shell pkg-config --cflags ncurses) -Wall # -Wextra -Werror
CC=cc
PREFIX ?= /usr/local
CONF = config.h
BINDIR = $(PREFIX)/bin SRC = ccc.c util.c file.c $(CONF)
MANDIR = $(PREFIX)/share/man/man1
.PHONY: all install uninstall clean
$(TARGET): $(SRC) $(TARGET): $(SRC)
$(CC) $(CFLAGS) $(LDFLAGS) $(SRC) -o $@ $(CC) $(CFLAGS) $(LDFLAGS) $(SRC) -o $@
all: $(TARGET) dist:
mkdir -p $(TARGET)-$(VERSION)
cp -R README.md $(MANPAGE) $(TARGET) $(TARGET)-$(VERSION)
tar -cf $(TARGET)-$(VERSION).tar $(TARGET)-$(VERSION)
gzip $(TARGET)-$(VERSION).tar
rm -rf $(TARGET)-$(VERSION)
install: $(TARGET) install: $(TARGET)
mkdir -p $(DESTDIR)$(BINDIR) mkdir -p $(DESTDIR)$(BINDIR)
@ -36,3 +40,7 @@ uninstall:
clean: clean:
$(RM) $(TARGET) $(RM) $(TARGET)
all: $(TARGET)
.PHONY: all dist install uninstall clean

114
ccc.c
View file

@ -39,6 +39,7 @@ void draw_border_title(WINDOW *window, bool active);
/* global variables */ /* global variables */
unsigned int focus = 0; unsigned int focus = 0;
long current_selection = 0; long current_selection = 0;
bool dir_mode = BLOCK_SIZE;
char *cwd; char *cwd;
int half_width; int half_width;
WIN_STRUCT windows[5]; WIN_STRUCT windows[5];
@ -84,7 +85,7 @@ int main(int argc, char** argv)
init_pair(4, COLOR_YELLOW, -1); /* BLK */ init_pair(4, COLOR_YELLOW, -1); /* BLK */
init_pair(5, COLOR_BLUE, -1); /* DIR */ init_pair(5, COLOR_BLUE, -1); /* DIR */
init_pair(6, COLOR_MAGENTA, -1); /* */ init_pair(6, COLOR_MAGENTA, -1); /* */
init_pair(7, COLOR_CYAN, -1); /* */ init_pair(7, COLOR_CYAN, -1); /* MARKED FILES */
init_pair(8, COLOR_WHITE, -1); /* REG */ init_pair(8, COLOR_WHITE, -1); /* REG */
half_width = COLS / 2; half_width = COLS / 2;
@ -238,8 +239,16 @@ int main(int argc, char** argv)
} }
break; break;
/* a to toggle between DISK_USAGE and BLOCK SIZE */
case 'a':
dir_mode = !dir_mode;
clear_files();
populate_files(cwd);
highlight_current_line();
break;
/* mark files by space */ /* mark files by space */
case SPACE: case SPACE:;
add_file_stat(get_filepath(current_selection), 1); add_file_stat(get_filepath(current_selection), 1);
highlight_current_line(); highlight_current_line();
break; break;
@ -392,11 +401,15 @@ long add_file_stat(char *filepath, int ftype)
/* get file size */ /* get file size */
double bytes = file_stat.st_size; double bytes = file_stat.st_size;
if (S_ISDIR(file_stat.st_mode)) {
/* at most 15 fd opened */ if (!dir_mode) {
total_dir_size = 0; /* dir_mode is 0, so disk usage mode, calculate disk usage */
nftw(filepath, &get_directory_size, 15, FTW_PHYS); if (S_ISDIR(file_stat.st_mode)) {
bytes = total_dir_size; /* at most 15 fd opened */
total_dir_size = 0;
nftw(filepath, &get_directory_size, 15, FTW_PHYS);
bytes = total_dir_size;
}
} }
/* 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(25 * sizeof(char));
@ -443,7 +456,14 @@ long add_file_stat(char *filepath, int ftype)
free(type); free(type);
free(size); free(size);
free(time); free(time);
return index; if (index != -1) {
/* just marked */
return index;
}
/* already marked */
return -1;
/* -1 does nothing, just function required to return something */
} }
char *total_stat = memalloc(45 * sizeof(char)); char *total_stat = memalloc(45 * sizeof(char));
snprintf(total_stat, 45, "%-18s %-10s", time, size); snprintf(total_stat, 45, "%-18s %-10s", time, size);
@ -495,6 +515,15 @@ void highlight_current_line()
/* update the panel */ /* update the panel */
wclear(panel); wclear(panel);
/* showing dir_mode requires 26 characters */
char *dir_mode_line = memalloc(27 * sizeof(char));
if (dir_mode)
strncpy(dir_mode_line, "Directory Mode: Block Size", 27);
else
strncpy(dir_mode_line, "Directory Mode: Disk Usage", 27);
/* check for marked files */
long num_marked = marked_len(); long num_marked = marked_len();
if (num_marked > 0) { if (num_marked > 0) {
/* Determine length of formatted string */ /* Determine length of formatted string */
@ -502,24 +531,36 @@ 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_len(), selected, cwd); wprintw(panel, "(%ld/%ld) %s %s %s", current_selection + 1, files_len(), selected, cwd, dir_mode_line);
} else { } else {
wprintw(panel, "(%ld/%ld) %s", current_selection + 1, files_len(), cwd); wprintw(panel, "(%ld/%ld) %s %s", current_selection + 1, files_len(), cwd, dir_mode_line);
} }
} }
/* print the actual filename and stats */ /* print the actual filename and stats */
char *line = get_line(i); char *line = get_line(i);
int color = get_color(i); int color = get_color(i);
/* check is file marked for action */
bool marked = in_marked(get_filepath(i));
if (marked) {
/* show file is selected */
wattron(directory_content, COLOR_PAIR(7));
} else {
/* print the whole directory with default colors */
wattron(directory_content, COLOR_PAIR(color));
}
/* print the whole directory with colors */
wattron(directory_content, COLOR_PAIR(color));
if (overflow > 0) if (overflow > 0)
mvwprintw(directory_content, line_count, 0, "%s", line); mvwprintw(directory_content, line_count, 0, "%s", line);
else else
mvwprintw(directory_content, i, 0, "%s", line); mvwprintw(directory_content, i, 0, "%s", line);
if (marked) {
wattroff(directory_content, COLOR_PAIR(7));
} else {
wattroff(directory_content, COLOR_PAIR(color));
}
wattroff(directory_content, A_REVERSE); wattroff(directory_content, A_REVERSE);
wattroff(directory_content, COLOR_PAIR(color));
free(line); free(line);
line_count++; line_count++;
} }
@ -539,23 +580,36 @@ void show_file_content()
wclear(preview_content); wclear(preview_content);
file *current_file = get_file((long) current_selection); file *current_file = get_file((long) current_selection);
if (strncmp(current_file->type, "DIR", 3) == 0) return; if (strncmp(current_file->type, "DIR", 3) == 0) return;
FILE *file = fopen(current_file->path, "rb"); FILE *file = fopen(current_file->path, "r");
if (file) { if (file == NULL) {
draw_border_title(preview_border, true); mvwprintw(preview_content, 0, 0, "Unable to read %s", current_file->path);
fseek(file, 0, SEEK_END); return;
long length = ftell(file);
/* check if file isn't empty */
if (length != 0 && length < 4096) {
fseek(file, 0, SEEK_SET); /* set cursor back to start of file */
char *buffer = memalloc(length * sizeof(char));
fread(buffer, 1, length, file);
mvwprintw(preview_content, 0, 0, "%s", buffer);
free(buffer);
} else {
wclear(preview_content);
}
fclose(file);
} }
draw_border_title(preview_border, true);
int c;
/* check binary */
while ((c=fgetc(file)) != EOF) {
if (c == '\0') {
mvwprintw(preview_content, 0, 0, "binary");
return;
}
}
fseek(file, 0, SEEK_END);
long length = ftell(file);
/* check if file isn't empty */
if (length != 0) {
fseek(file, 0, SEEK_SET); /* set cursor back to start of file */
int max_length = (LINES - 3) * (COLS / 2 - 2);
char *buffer = memalloc(max_length * sizeof(char));
fread(buffer, 1, max_length, file);
mvwprintw(preview_content, 0, 0, "%s", buffer);
free(buffer);
} else {
wclear(preview_content);
}
fclose(file);
} }
/* /*
@ -611,7 +665,7 @@ void init_windows()
/* draw border around windows */ /* draw border around windows */
draw_border_title(directory_border, true); draw_border_title(directory_border, true);
draw_border_title(preview_border, false); draw_border_title(preview_border, true);
scrollok(directory_content, true); scrollok(directory_content, true);
/* window location y, x */ /* window location y, x */

View file

@ -1,7 +1,7 @@
#define CTRLD 0x04 #define CTRLD 0x04
#define ENTER 0xA #define ENTER 0xA
#define CTRLU 0x15 #define CTRLU 0x15
#define ESC 0x1B /* \e or \033 */ #define ESC 0x1B
#define SPACE 0x20 #define SPACE 0x20
#define TILDE 0x7E #define TILDE 0x7E
#define DOWN 0x102 #define DOWN 0x102
@ -11,3 +11,7 @@
#define BACKSPACE 0x107 #define BACKSPACE 0x107
#define PH 1 /* panel height */ #define PH 1 /* panel height */
#define JUMP_NUM 14 /* how long ctrl + u/d jump are */ #define JUMP_NUM 14 /* how long ctrl + u/d jump are */
#define BLOCK_SIZE true
#define DISK_USAGE false
static const char *editor = "nvim"; /* default text editor */

84
file.c
View file

@ -1,5 +1,6 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h>
#include <libgen.h> #include <libgen.h>
#include "util.h" #include "util.h"
@ -45,13 +46,24 @@ long marked_len()
} }
void free_file(file *toremove)
{
if (toremove->type != NULL)
free(toremove->type);
if (toremove->path != NULL)
free(toremove->path);
if (toremove->stats != NULL)
free(toremove->stats);
free(toremove);
}
void clear_files() void clear_files()
{ {
file *tmp; file *tmp;
while (files != NULL) { while (files != NULL) {
tmp = files; tmp = files;
files = files->next; files = files->next;
free(tmp); free_file(tmp);
} }
} }
@ -61,7 +73,7 @@ void clear_marked()
while (marked != NULL) { while (marked != NULL) {
tmp = marked; tmp = marked;
files = marked->next; files = marked->next;
free(tmp); free_file(tmp);
} }
} }
@ -96,6 +108,29 @@ long add_file(char *filepath, char *stats, char *type, int color)
return index; return index;
} }
void remove_marked(file *marked_file)
{
/* If the head node itself is marked for removal */
if (marked == marked_file) {
marked = marked->next;
free_file(marked_file);
return;
}
/* Search for the marked file node in the list */
file* temp = marked;
while (temp != NULL && temp->next != marked_file) {
temp = temp->next;
}
/* If the marked file node is found, remove it from the list */
if (temp != NULL) {
temp->next = marked_file->next;
free_file(marked_file);
}
}
long add_marked(char *filepath, char *type) long add_marked(char *filepath, char *type)
{ {
file *current = marked; file *current = marked;
@ -107,20 +142,63 @@ long add_marked(char *filepath, char *type)
} }
new_file->path = buf; new_file->path = buf;
new_file->type = buf2; new_file->type = buf2;
new_file->stats = NULL;
new_file->color = 0;
new_file->next = NULL; new_file->next = NULL;
if (current == NULL) { if (current == NULL) {
marked = new_file; marked = new_file;
return 0; return 0;
} }
long index = 1; long index = 1;
while (current->next != NULL) { while (current->next != NULL) {
if (strcmp(current->path, new_file->path) == 0) {
remove_marked(current);
free_file(new_file);
return -1;
}
current = current->next; current = current->next;
index++; index++;
} }
if (strcmp(current->path, new_file->path) == 0){
remove_marked(current);
free_file(new_file);
return -1;
}
current->next = new_file; current->next = new_file;
return index; return index;
} }
file *get_marked(long index)
{
file *current = marked;
if (index == 0) {
return current;
}
if (index > files_len()) {
return NULL;
}
for (long i = 0; i < index; i++) {
current = current->next;
}
return current;
}
bool in_marked(char *path)
{
file *tmp = marked;
if (tmp == NULL)
return false;
while (tmp != NULL) {
if (strcmp(path, tmp->path) == 0) {
return true;
}
tmp = tmp->next;
}
return false;
}
file *get_file(long index) file *get_file(long index)
{ {
file *current = files; file *current = files;
@ -160,7 +238,7 @@ int get_color(long index)
} }
return color; return color;
} else { } else {
return 8; /* white */ return 8; /* white */
} }
} }

4
file.h
View file

@ -11,10 +11,14 @@ typedef struct file {
long files_len(); long files_len();
long marked_len(); long marked_len();
void free_file(file *toremove);
void clear_files(); void clear_files();
void clear_marked(); void clear_marked();
long add_file(char *filepath, char *stats, char *type, int color); long add_file(char *filepath, char *stats, char *type, int color);
void remove_marked(file *marked_file);
long add_marked(char *filepath, char *type); long add_marked(char *filepath, char *type);
file *get_marked(long index);
bool in_marked(char *path);
file *get_file(long index); file *get_file(long index);
char *get_filepath(long index); char *get_filepath(long index);
int get_color(long index); int get_color(long index);