commit c71d4135f19f596d4b3a1160284e8a94f3cbc831 from: Omar Polo date: Wed Dec 01 08:33:23 2021 UTC starting to rewrite the input loop commit - ae787901f8ec87bffa70c871326d1faaeac1ec91 commit + c71d4135f19f596d4b3a1160284e8a94f3cbc831 blob - 581d910c8bd5007ef9c17132139bc2578c54f812 blob + bae5608fa11859f9709db8b6ce80fe993f8db480 --- fm.c +++ fm.c @@ -128,6 +128,7 @@ static struct state { #define MIN(A, B) ((A) < (B) ? (A) : (B)) #define MAX(A, B) ((A) > (B) ? (A) : (B)) #define ISDIR(E) (strchr((E), '/') != NULL) +#define CTRL(x) ((x) & 0x1f) /* Line Editing Macros. */ #define EDIT_FULL(E) ((E).left == (E).right) @@ -1132,6 +1133,44 @@ update_input(const char *prompt, enum color c) move(LINES - 1, plen + fm.edit.left - fm.edit_scroll); } +static void +loop(void) +{ + int ch; + + for (;;) { + ch = fm_getch(); + clear_message(); + switch (ch) { + case 'j': + case 'n': + case CTRL('n'): + if (!fm.nfiles) + continue; + ESEL = MIN(ESEL + 1, fm.nfiles - 1); + update_view(); + break; + + case 'k': + case 'p': + case CTRL('p'): + if (!fm.nfiles) + continue; + ESEL = MAX(ESEL - 1, 0); + update_view(); + break; + + case 'q': + return; + + default: + message(RED, "%s is undefined", keyname(ch)); + refresh(); + break; + } + } +} + int main(int argc, char *argv[]) { @@ -1198,437 +1237,9 @@ main(int argc, char *argv[]) strcpy(CLIPBOARD, CWD); if (fm.nfiles > 0) strcat(CLIPBOARD, ENAME(ESEL)); - while (1) { - ch = fm_getch(); - key = keyname(ch); - clear_message(); - if (!strcmp(key, RVK_QUIT)) - break; - else if (ch >= '0' && ch <= '9') { - fm.tab = ch - '0'; - cd(0); - } else if (!strcmp(key, RVK_HELP)) { - spawn((char *[]) { "man", "fm", NULL }); - } else if (!strcmp(key, RVK_DOWN)) { - if (!fm.nfiles) - continue; - ESEL = MIN(ESEL + 1, fm.nfiles - 1); - update_view(); - } else if (!strcmp(key, RVK_UP)) { - if (!fm.nfiles) - continue; - ESEL = MAX(ESEL - 1, 0); - update_view(); - } else if (!strcmp(key, RVK_JUMP_DOWN)) { - if (!fm.nfiles) - continue; - ESEL = MIN(ESEL + RV_JUMP, fm.nfiles - 1); - if (fm.nfiles > HEIGHT) - SCROLL = MIN(SCROLL + RV_JUMP, - fm.nfiles - HEIGHT); - update_view(); - } else if (!strcmp(key, RVK_JUMP_UP)) { - if (!fm.nfiles) - continue; - ESEL = MAX(ESEL - RV_JUMP, 0); - SCROLL = MAX(SCROLL - RV_JUMP, 0); - update_view(); - } else if (!strcmp(key, RVK_JUMP_TOP)) { - if (!fm.nfiles) - continue; - ESEL = 0; - update_view(); - } else if (!strcmp(key, RVK_JUMP_BOTTOM)) { - if (!fm.nfiles) - continue; - ESEL = fm.nfiles - 1; - update_view(); - } else if (!strcmp(key, RVK_CD_DOWN)) { - if (!fm.nfiles || !S_ISDIR(EMODE(ESEL))) - continue; - if (chdir(ENAME(ESEL)) == -1) { - message(RED, "Cannot access \"%s\".", - ENAME(ESEL)); - continue; - } - strcat(CWD, ENAME(ESEL)); - cd(1); - } else if (!strcmp(key, RVK_CD_UP)) { - char *dirname, first; - if (!strcmp(CWD, "/")) - continue; - CWD[strlen(CWD) - 1] = '\0'; - dirname = strrchr(CWD, '/') + 1; - first = dirname[0]; - dirname[0] = '\0'; - cd(1); - dirname[0] = first; - dirname[strlen(dirname)] = '/'; - try_to_sel(dirname); - dirname[0] = '\0'; - if (fm.nfiles > HEIGHT) - SCROLL = ESEL - HEIGHT / 2; - update_view(); - } else if (!strcmp(key, RVK_HOME)) { - strcpy(CWD, getenv("HOME")); - if (CWD[strlen(CWD) - 1] != '/') - strcat(CWD, "/"); - cd(1); - } else if (!strcmp(key, RVK_TARGET)) { - char *bname, first; - int is_dir = S_ISDIR(EMODE(ESEL)); - ssize_t len = readlink(ENAME(ESEL), BUF1, BUFLEN - 1); - if (len == -1) - continue; - BUF1[len] = '\0'; - if (access(BUF1, F_OK) == -1) { - char *msg; - switch (errno) { - case EACCES: - msg = "Cannot access \"%s\"."; - break; - case ENOENT: - msg = "\"%s\" does not exist."; - break; - default: - msg = "Cannot navigate to \"%s\"."; - } - strcpy(BUF2, BUF1); /* message() uses BUF1. */ - message(RED, msg, BUF2); - continue; - } - realpath(BUF1, CWD); - len = strlen(CWD); - if (CWD[len - 1] == '/') - CWD[len - 1] = '\0'; - bname = strrchr(CWD, '/') + 1; - first = *bname; - *bname = '\0'; - cd(1); - *bname = first; - if (is_dir) - strcat(CWD, "/"); - try_to_sel(bname); - *bname = '\0'; - update_view(); - } else if (!strcmp(key, RVK_COPY_PATH)) { - clip_path = getenv("CLIP"); - if (!clip_path) - goto copy_path_fail; - clip_file = fopen(clip_path, "w"); - if (!clip_file) - goto copy_path_fail; - fprintf(clip_file, "%s%s\n", CWD, ENAME(ESEL)); - fclose(clip_file); - goto copy_path_done; - copy_path_fail: - strcpy(CLIPBOARD, CWD); - strcat(CLIPBOARD, ENAME(ESEL)); - copy_path_done: - ; - } else if (!strcmp(key, RVK_PASTE_PATH)) { - clip_path = getenv("CLIP"); - if (!clip_path) - goto paste_path_fail; - clip_file = fopen(clip_path, "r"); - if (!clip_file) - goto paste_path_fail; - fscanf(clip_file, "%s\n", CLIPBOARD); - fclose(clip_file); - paste_path_fail: - strcpy(BUF1, CLIPBOARD); - strcpy(CWD, dirname(BUF1)); - if (strcmp(CWD, "/")) - strcat(CWD, "/"); - cd(1); - strcpy(BUF1, CLIPBOARD); - try_to_sel(strstr(CLIPBOARD, basename(BUF1))); - update_view(); - } else if (!strcmp(key, RVK_REFRESH)) { - reload(); - } else if (!strcmp(key, RVK_SHELL)) { - program = user_shell; - if (program) { -#ifdef RV_SHELL - spawn((char *[]) { RV_SHELL, "-c", program, - NULL}); -#else - spawn((char *[]) { program, NULL }); -#endif - reload(); - } - } else if (!strcmp(key, RVK_VIEW)) { - if (!fm.nfiles || S_ISDIR(EMODE(ESEL))) - continue; - if (open_with_env(user_pager, ENAME(ESEL))) - cd(0); - } else if (!strcmp(key, RVK_EDIT)) { - if (!fm.nfiles || S_ISDIR(EMODE(ESEL))) - continue; - if (open_with_env(user_editor, ENAME(ESEL))) - cd(0); - } else if (!strcmp(key, RVK_OPEN)) { - if (!fm.nfiles || S_ISDIR(EMODE(ESEL))) - continue; - if (open_with_env(user_open, ENAME(ESEL))) - cd(0); - } else if (!strcmp(key, RVK_SEARCH)) { - int oldsel, oldscroll, length; - if (!fm.nfiles) - continue; - oldsel = ESEL; - oldscroll = SCROLL; - start_line_edit(""); - update_input(RVP_SEARCH, RED); - while ((edit_stat = get_line_edit()) == CONTINUE) { - int sel; - enum color c = RED; - length = strlen(INPUT); - if (length) { - for (sel = 0; sel < fm.nfiles; sel++) - if (!strncmp(ENAME(sel), INPUT, - length)) - break; - if (sel < fm.nfiles) { - c = GREEN; - ESEL = sel; - if (fm.nfiles > HEIGHT) { - if (sel < 3) - SCROLL = 0; - else if (sel - 3 > - fm.nfiles - - HEIGHT) - SCROLL = fm.nfiles - - HEIGHT; - else - SCROLL = sel - - 3; - } - } - } else { - ESEL = oldsel; - SCROLL = oldscroll; - } - update_view(); - update_input(RVP_SEARCH, c); - } - if (edit_stat == CANCEL) { - ESEL = oldsel; - SCROLL = oldscroll; - } - clear_message(); - update_view(); - } else if (!strcmp(key, RVK_TG_FILES)) { - FLAGS ^= SHOW_FILES; - reload(); - } else if (!strcmp(key, RVK_TG_DIRS)) { - FLAGS ^= SHOW_DIRS; - reload(); - } else if (!strcmp(key, RVK_TG_HIDDEN)) { - FLAGS ^= SHOW_HIDDEN; - reload(); - } else if (!strcmp(key, RVK_NEW_FILE)) { - int ok = 0; - start_line_edit(""); - update_input(RVP_NEW_FILE, RED); - while ((edit_stat = get_line_edit()) == CONTINUE) { - int length = strlen(INPUT); - ok = length; - for (i = 0; i < fm.nfiles; i++) { - if ( - !strncmp(ENAME(i), INPUT, length) && - (!strcmp(ENAME(i) + length, "") || - !strcmp(ENAME(i) + length, "/")) - ) { - ok = 0; - break; - } - } - update_input(RVP_NEW_FILE, ok ? GREEN : RED); - } - clear_message(); - if (edit_stat == CONFIRM) { - if (ok) { - if (addfile(INPUT) == 0) { - cd(1); - try_to_sel(INPUT); - update_view(); - } else - message(RED, - "Could not create \"%s\".", - INPUT); - } else - message(RED, "\"%s\" already exists.", - INPUT); - } - } else if (!strcmp(key, RVK_NEW_DIR)) { - int ok = 0; - start_line_edit(""); - update_input(RVP_NEW_DIR, RED); - while ((edit_stat = get_line_edit()) == CONTINUE) { - int length = strlen(INPUT); - ok = length; - for (i = 0; i < fm.nfiles; i++) { - if ( - !strncmp(ENAME(i), INPUT, length) && - (!strcmp(ENAME(i) + length, "") || - !strcmp(ENAME(i) + length, "/")) - ) { - ok = 0; - break; - } - } - update_input(RVP_NEW_DIR, ok ? GREEN : RED); - } - clear_message(); - if (edit_stat == CONFIRM) { - if (ok) { - if (adddir(INPUT) == 0) { - cd(1); - strcat(INPUT, "/"); - try_to_sel(INPUT); - update_view(); - } else - message(RED, - "Could not create \"%s/\".", - INPUT); - } else - message(RED, "\"%s\" already exists.", - INPUT); - } - } else if (!strcmp(key, RVK_RENAME)) { - int ok = 0; - char *last; - int isdir; - strcpy(INPUT, ENAME(ESEL)); - last = INPUT + strlen(INPUT) - 1; - if ((isdir = *last == '/')) - *last = '\0'; - start_line_edit(INPUT); - update_input(RVP_RENAME, RED); - while ((edit_stat = get_line_edit()) == CONTINUE) { - int length = strlen(INPUT); - ok = length; - for (i = 0; i < fm.nfiles; i++) - if ( - !strncmp(ENAME(i), INPUT, length) && - (!strcmp(ENAME(i) + length, "") || - !strcmp(ENAME(i) + length, "/")) - ) { - ok = 0; - break; - } - update_input(RVP_RENAME, ok ? GREEN : RED); - } - clear_message(); - if (edit_stat == CONFIRM) { - if (isdir) - strcat(INPUT, "/"); - if (ok) { - if (!rename(ENAME(ESEL), INPUT) && - MARKED(ESEL)) { - del_mark(&fm.marks, - ENAME(ESEL)); - add_mark(&fm.marks, CWD, - INPUT); - } - cd(1); - try_to_sel(INPUT); - update_view(); - } else - message(RED, "\"%s\" already exists.", - INPUT); - } - } else if (!strcmp(key, RVK_TG_EXEC)) { - if (!fm.nfiles || S_ISDIR(EMODE(ESEL))) - continue; - if (S_IXUSR & EMODE(ESEL)) - EMODE(ESEL) &= ~(S_IXUSR | S_IXGRP | S_IXOTH); - else - EMODE(ESEL) |= S_IXUSR | S_IXGRP | S_IXOTH; - if (chmod(ENAME(ESEL), EMODE(ESEL))) { - message(RED, - "Failed to change mode of \"%s\".", - ENAME(ESEL)); - } else { - message(GREEN, "Changed mode of \"%s\".", - ENAME(ESEL)); - update_view(); - } - } else if (!strcmp(key, RVK_DELETE)) { - if (fm.nfiles) { - message(YELLOW, "Delete \"%s\"? (Y/n)", - ENAME(ESEL)); - if (fm_getch() == 'Y') { - const char *name = ENAME(ESEL); - int ret = ISDIR(ENAME(ESEL)) ? - deldir(name) : delfile(name); - reload(); - if (ret) - message(RED, - "Could not delete \"%s\".", - ENAME(ESEL)); - } else - clear_message(); - } else - message(RED, "No entry selected for deletion."); - } else if (!strcmp(key, RVK_TG_MARK)) { - if (MARKED(ESEL)) - del_mark(&fm.marks, ENAME(ESEL)); - else - add_mark(&fm.marks, CWD, ENAME(ESEL)); - MARKED(ESEL) = !MARKED(ESEL); - ESEL = (ESEL + 1) % fm.nfiles; - update_view(); - } else if (!strcmp(key, RVK_INVMARK)) { - for (i = 0; i < fm.nfiles; i++) { - if (MARKED(i)) - del_mark(&fm.marks, ENAME(i)); - else - add_mark(&fm.marks, CWD, ENAME(i)); - MARKED(i) = !MARKED(i); - } - update_view(); - } else if (!strcmp(key, RVK_MARKALL)) { - for (i = 0; i < fm.nfiles; i++) - if (!MARKED(i)) { - add_mark(&fm.marks, CWD, ENAME(i)); - MARKED(i) = 1; - } - update_view(); - } else if (!strcmp(key, RVK_MARK_DELETE)) { - if (fm.marks.nentries) { - message(YELLOW, - "Delete all marked entries? (Y/n)"); - if (fm_getch() == 'Y') - process_marked(NULL, delfile, deldir, - "Deleting", "Deleted"); - else - clear_message(); - } else - message(RED, "No entries marked for deletion."); - } else if (!strcmp(key, RVK_MARK_COPY)) { - if (fm.marks.nentries) { - if (strcmp(CWD, fm.marks.dirpath)) - process_marked(adddir, cpyfile, NULL, - "Copying", "Copied"); - else - message(RED, - "Cannot copy to the same path."); - } else - message(RED, "No entries marked for copying."); - } else if (!strcmp(key, RVK_MARK_MOVE)) { - if (fm.marks.nentries) { - if (strcmp(CWD, fm.marks.dirpath)) - process_marked(adddir, movfile, deldir, - "Moving", "Moved"); - else - message(RED, - "Cannot move to the same path."); - } else - message(RED, "No entries marked for moving."); - } - } + + loop(); + if (fm.nfiles) free_rows(&fm.rows, fm.nfiles); delwin(fm.window);