Thumbnail

rani/cscroll.git

Clone URL: https://git.buni.party/rani/cscroll.git

commit e91500ee97289974b5073859eb44d3fa70f17b97 Author: Raniconduh <clagv.randomgames@gmail.com> Date: Sat Dec 04 09:08:05 2021 +0000 added '!' command diff --git a/README.md b/README.md index f2d696c..28657b6 100644 --- a/README.md +++ b/README.md @@ -426 +427 @@ Files that are executable but have another identifier will keep the identifier b  * `p`: Paste all cut files into the current directory. Pasting in the same directory where the cut originated will cancel the cut  * `:`: Open a commands prompt ([see 'Command Prompt' section](#command-prompt))  * `/`: Search for a file in the current directory using a POSIX regex +* `!`: Run a shell command ([see shell commands](#shell-commands))  * `q`: Quit    #### Options Prompt @@ -606 +6110 @@ The command prompt will show up upon pressing `:` and the prompt itself is prefi    The `r` command will show a prompt (similar to a command prompt but without a prefix) where the new file name is to be expected. A file may only be renamed within the same directory. E.g. if the directory cscroll is in is `/home/user/downloads` and the file `image.png` is renamed to `/home/user/image.png`, it will fail. The file can only be renamed to something like `my_image.png`. (Attempting to move a file across directories is not possible with the rename function.) Mass renaming is not possible.   +#### Shell Commands + +Pressing `!` will open a prompt prefixed with `!` which will run the shell command entered into it. Entering %f will format the command entered with the name of the file the cursor is currently on. To escape this format (i.e. to not have it be replaced with the file name), enter `%%f`. The output will be literally `%f`. E.g. `vim %f` will format to `vim FILE` where `FILE` is the name of the file the cursor is on. `echo %%f`, however, will format to `echo %f` and the output of the command will literally be `%f`. +  ## Installation    The cscroll binary has one dependency to run: ncurses. To compile cscroll you must install `libncurses`. However, compilation through the makefile requires `pkg-config` as well. diff --git a/include/commands.h b/include/commands.h index 12c038d..3ffd386 100644 --- a/include/commands.h +++ b/include/commands.h @@ -66 +67 @@ long search_file(long, char *);  void create_cuts(char *, char **);  void free_cuts(void);  void paste_cuts(char *); +void run_cmd(char *);    extern bool cutting;  extern char * cut_start_dir; diff --git a/src/commands.c b/src/commands.c index ed65671..ff3c10b 100644 --- a/src/commands.c +++ b/src/commands.c @@ -146 +149 @@ char * cut_start_dir = NULL;  char ** cuts = NULL;    void ext_open(char * file) { + clear(); + refresh(); +   char * f = malloc(strlen(cwd) + strlen(file) + 2);   sprintf(f, "%s/%s", cwd, file);   @@ -257 +287 @@ void ext_open(char * file) {   wait(NULL);   free(f);   - erase(); + clear();   refresh();  }   @@ -1123 +11522 @@ void paste_cuts(char * path) {   rename(old_path, new_path);   }  } + + +void run_cmd(char * cmd) { + clear(); + refresh(); + + if (!fork()) { + execvp("sh", (char*[]){"sh", "-c", cmd, NULL}); + exit(0); + } + wait(NULL); + + addstr("\nPress enter to contine\n"); + refresh(); + while (getch() != '\n'); + + clear(); + refresh(); +} diff --git a/src/main.c b/src/main.c index adf28dc..2d3e9bc 100644 --- a/src/main.c +++ b/src/main.c @@ -2666 +26643 @@ int main(int argc, char ** argv) {   last_f = n_dir_entries - cursor > (unsigned)LINES - 6 ? cursor + LINES - 6 : n_dir_entries;   first_f = cursor > (unsigned)LINES - 6 ? last_f - LINES + 6 : 0;   break; + case '!':; + char * cmd = curses_getline("!"); + if (!cmd[0]) break; + // file name & length to sub + char * f = dir_entries[cursor - 1]->name; + size_t flen = strlen(f); + + char * cmdp = cmd; // tmp ptr to cmd + char * f_sep; // where %f is found + size_t moves = 0; // no. of times %f is found + // replace '%f' with file name cursor is on + while ((f_sep = strstr(cmdp, "%f"))) { + // escape '%f' if '%%f' is found + if (f_sep[-1] == '%') { + size_t seplen = strlen(f_sep); + memcpy(f_sep - 1, f_sep, seplen); + f_sep[seplen - 1] = 0; + cmdp = f_sep + 2; + continue; + } + ++moves; + // store position of f_sep to be restored + // after reallocating cmd + ptrdiff_t t = f_sep - cmd; + cmd = realloc(cmd, strlen(cmd) + flen * moves + 1); + f_sep = cmd + t; + cmdp = f_sep + 2; + // make room for file name + memmove(f_sep + flen, f_sep + 2, strlen(f_sep) - 2); + // replace '%f' with file name + for (size_t i = 0; i < flen; i++) + *f_sep++ = f[i]; + } + + run_cmd(cmd); + free(cmd); + break;   case 'q':   goto done;   default: