From 9bdf677a5651b0e95beea59ee011d1632457f630 Mon Sep 17 00:00:00 2001 From: nova Date: Mon, 8 Jun 2026 22:05:40 +0200 Subject: [PATCH] implementation of copy_file and paste --- config.h | 9 ++++- defines.h | 8 ++-- interactions.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++-- interactions.h | 2 +- 4 files changed, 112 insertions(+), 12 deletions(-) diff --git a/config.h b/config.h index 9182073..d3f9152 100644 --- a/config.h +++ b/config.h @@ -18,6 +18,8 @@ static const char clipboard_cmd[] = "echo ^ | xsel -ib --trim"; /*used in yank_t static const char rename_cmd[] = "mv"; /* as used in rename_hovered, makedir and makefile */ static const char makefile_cmd[] = "touch"; /*as of now both only do ``rename_cmd new_name``*/ static const char makedir_cmd[] = "mkdir"; +static const char copy_cmd[] = "cp -r"; +static const char cut_cmd[] = "mv"; static const mimetype mimetype_default_cmd[] = { /* mimetype shell command @@ -74,8 +76,8 @@ static const binding key_binding[] = { * this means that it does not delete the hovered files if files are already selected */ { "yn", yank_file_name, NULL, "yank filename of hovered file" }, { "yp", yank_file_path, NULL, "yank path of hovered file" }, - { "yy", yank_file, "copy", "copy/yank file/directory" }, - { "dd", yank_file, "cut", "cut file/directory" }, + { "yy", copy_file, COPY_FILE, "copy/yank file/directory" }, + { "dd", copy_file, CUT_FILE, "cut file/directory" }, { "pp", paste, NULL, "paste" }, { "G", jump_bottom, NULL, "jump to last file in dir" }, @@ -150,5 +152,8 @@ static const char ui_makedir_text[]; static const char ui_makefile_text[]; static const char ui_rename_text[]; static const char ui_delete_text[]; +static const char copy_cmd[]; +static const char cut_cmd[]; + #endif /* }}} */ diff --git a/defines.h b/defines.h index 23d7276..5fd535d 100644 --- a/defines.h +++ b/defines.h @@ -59,9 +59,8 @@ #define FILE_TYPE_SYMLINK 64 #define FILE_TYPE_OPEN_FILE 128 /* this is only used in rgt_content to print a file preview, not the dir */ -#define YANK_IS_USED 1 -#define YANK_CUT 2 -#define YANK_COPY 4 +#define COPY_FILE (int*)0x0001 +#define CUT_FILE (int*)0x0002 #define BTM_WINDOW_HEIGHT_ON_STR_INTERACTION 5 #define INPUT_BUFFER_SIZE 255 @@ -101,8 +100,7 @@ typedef struct Binding { char* comment; } binding; typedef struct Yank { - char status; - char *path; + int *status; /*pointer to make blackmagic easier, should probably not deref lol*/ char **list; unsigned long count; } yank; diff --git a/interactions.c b/interactions.c index f9e1443..7af100e 100644 --- a/interactions.c +++ b/interactions.c @@ -444,11 +444,108 @@ void yank_file_path(){ } -void yank_file(unsigned long passes, int index){ - TODO; +void copy_file(unsigned long passes, int index){ + (void)passes; + + yank_files.status = key_binding[index].black_magic; + + unsigned long i; + unsigned long j = 0; + + char *path = malloc(strlen(global_path)+1); /* im at a loss for words, freeing this always segfaults if yank_files.count != 0 + if i use global_path directly or getcwd(NULL, 0), it will segfault at the next free on global_path. + what makes this wierder is, regardless of if the yank_files.count != 0 is true or false, both do the same things + so were going to just leak the size of the path */ + + memcpy(path, global_path, strlen(global_path)+1); + + if (yank_files.count != 0) { + for (i = 0; i < yank_files.count; i++) { + free(yank_files.list[i]); + } + free(yank_files.list); + yank_files.count = 0; + } + + for (i = 0; i < mid_dir.file_count; i++) { + if (mid_dir.file_list[i].status & FILE_STATUS_SELECTED) { + yank_files.count++; + } + } + if (yank_files.count != 0) { + yank_files.list = malloc(yank_files.count * sizeof(char*)); + + for (i = 0; j < yank_files.count; i++) { + if (mid_dir.file_list[i].status & FILE_STATUS_SELECTED) { + + char *str = malloc(strlen(path) + 1 + strlen(mid_dir.current_file->file_name)+1); + memcpy(str, path, strlen(path)); + memcpy(str+strlen(path)+1, mid_dir.file_list[i].file_name, strlen(mid_dir.file_list[i].file_name)+1); + str[strlen(path)] = '/'; + + yank_files.list[j] = str; + j++; + } + } + } else { + /*this path is achieved if no file is explicitly selected by the user, thus we assume the user wants the currently hovered file*/ + yank_files.list = malloc(1 * sizeof(char*)); + + char *str = malloc(strlen(path) + 1 + strlen(mid_dir.current_file->file_name)+1); + memcpy(str, path, strlen(path)); + memcpy(str+strlen(path)+1, mid_dir.current_file->file_name, strlen(mid_dir.current_file->file_name)+1); + str[strlen(path)] = '/'; + + *yank_files.list = str; + yank_files.count = 1; + } + + /*free(path);*/ + + + status |= (STATUS_RUN_BACKEND); } -void paste(){ - TODO; +void paste(unsigned long passes){ + + unsigned long i; + unsigned long j; + file tmp; + char *cmd; + + for (j = 0; j < passes; j++) { + for (i = 0; i < yank_files.count; i++) { + + char *file_name = strrchr(yank_files.list[i], '/')+1; + char *dest_file_name = malloc(strlen(file_name)+1); + memcpy(dest_file_name, file_name, strlen(file_name)+1); + + + tmp.file_name = yank_files.list[i]; + while(access(dest_file_name, F_OK) == 0) { + unsigned long len = strlen(dest_file_name); + dest_file_name = realloc(dest_file_name, len+2); + + dest_file_name[len] = '_'; + dest_file_name[len+1] = 0; + + } + if (yank_files.status == COPY_FILE) { + cmd = parse_cmd(copy_cmd, &tmp); + } else if (yank_files.status == CUT_FILE) { + cmd = parse_cmd(cut_cmd, &tmp); + } else { + free(dest_file_name); + continue; + } + tmp.file_name = dest_file_name; + cmd = parse_cmd(cmd, &tmp); + system(cmd); + free(cmd); + free(tmp.file_name); + } + } + + status |= (STATUS_RUN_BACKEND | STATUS_RELOAD_DIRECTORY); } void search(){ echo(); diff --git a/interactions.h b/interactions.h index 1967d10..908a940 100644 --- a/interactions.h +++ b/interactions.h @@ -28,7 +28,7 @@ void order_by(unsigned long passes, int index); void cmd_on_selected(unsigned long passes, int index); void yank_file_name(); void yank_file_path(); -void yank_file(unsigned long passes, int index); +void copy_file(); void paste(); void search(); void search_next();