From df01136d5ab9226f42c2c8cb78a5cf1be598616b Mon Sep 17 00:00:00 2001 From: night0721 <night@night0721.xyz> Date: Tue, 4 Feb 2025 21:20:29 +0000 Subject: [PATCH] Bulk rename, symlink, copy, move files and tick ported features --- README.md | 10 ++--- ccc.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 123 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 80b1ff2..473e369 100644 --- a/README.md +++ b/README.md @@ -12,14 +12,14 @@ Consider this project incomplete and WIP! | Advanced movement (jumps) | X | | | File details | X | | | File icons! | X | | -| Searching for files | | | +| Searching for files | | X | | Sorting | X | | -| Marking and marking operations | | | +| Marking and marking operations | X | | | Image previews | X | | | Help | X | | -| History | | | -| Bookmarks | | | -| Bulk rename | | | +| History | X | | +| Bookmarks | X | | +| Bulk rename | X | | ## Features added that are not in fff: - File preview diff --git a/ccc.c b/ccc.c index 4264354..5a6445b 100644 --- a/ccc.c +++ b/ccc.c @@ -1294,22 +1294,138 @@ void delete_files(const Arg *arg) void move_files(const Arg *arg) { + if (marked->length) { + char *input = get_panel_string("Move to: "); + if (!input) { + return; + } + for (int i = 0; i < marked->length; i++) { + char new_path[PATH_MAX]; + snprintf(new_path, PATH_MAX, "%s/%s", input, marked->items[i].name); + if (rename(marked->items[i].path, new_path)) { + wpprintw("move failed: %s", strerror(errno)); + } + } + change_dir(cwd, 0, 0); + for (int i = 0; i < marked->length; i++) { + arraylist_remove(marked, 0); + } + free(input); + } +} +int copy_file(const char *src, const char *dest) +{ + int src_fd = open(src, O_RDONLY); + if (src_fd == -1) { + return 1; + } + int dest_fd = open(dest, O_WRONLY | O_CREAT, 0644); + if (dest_fd == -1) { + close(src_fd); + return 1; + } + char buffer[4096]; + ssize_t bytes; + while ((bytes = read(src_fd, buffer, sizeof(buffer))) > 0) { + if (write(dest_fd, buffer, bytes) != bytes) { + close(src_fd); + close(dest_fd); + return 1; + } + } + close(src_fd); + close(dest_fd); + return 0; } void copy_files(const Arg *arg) { - + if (marked->length) { + char *input = get_panel_string("Copy to: "); + if (!input) { + return; + } + for (int i = 0; i < marked->length; i++) { + char new_path[PATH_MAX]; + snprintf(new_path, PATH_MAX, "%s/%s", input, marked->items[i].name); + if (copy_file(marked->items[i].path, new_path)) { + wpprintw("copy failed: %s", strerror(errno)); + } + } + change_dir(cwd, 0, 0); + free(input); + } } void symbolic_link(const Arg *arg) { - + if (marked->length) { + char *input = get_panel_string("Link to: "); + if (!input) { + return; + } + for (int i = 0; i < marked->length; i++) { + if (symlink(marked->items[i].path, input)) { + wpprintw("link failed: %s", strerror(errno)); + } + } + change_dir(cwd, 0, 0); + free(input); + } } void bulk_rename(const Arg *arg) { + if (!marked->length) { + return; + } + /* + * # Bulk rename files using '$EDITOR'. + */ + char rename_file[PATH_MAX]; + strcpy(rename_file, "~/.cache/ccc/bulk_rename"); + replace_home(rename_file); + FILE *marked_files = fopen(rename_file, "w"); + if (!marked_files) { + wpprintw("Cannot open rename file (Press any key to continue)"); + readch(); + return; + } + for (int i = 0; i < marked->length; i++) { + fprintf(marked_files, "%s\n", marked->items[i].path); + } + fclose(marked_files); + pid_t pid = fork(); + if (pid == 0) { + /* Child process */ + execlp(editor, editor, rename_file, NULL); + _exit(1); /* Exit if exec fails */ + } else if (pid > 0) { + /* Parent process */ + waitpid(pid, NULL, 0); + } else { + /* Fork failed */ + wpprintw("fork failed: %s", strerror(errno)); + } + + FILE *rename_file_fp = fopen(rename_file, "r"); + if (!rename_file_fp) { + wpprintw("Cannot open rename file (Press any key to continue)"); + readch(); + return; + } + char buffer[PATH_MAX]; + while (fgets(buffer, sizeof(buffer), rename_file_fp)) { + buffer[strcspn(buffer, "\n")] = 0; + char new_path[PATH_MAX]; + snprintf(new_path, PATH_MAX, "%s", buffer); + if (rename(buffer, new_path)) { + wpprintw("rename failed: %s", strerror(errno)); + } + } + fclose(rename_file_fp); } /*