#include #include #include #include #include #include #include "file_previews.h" #include "backend.h" #include "defines.h" #include "config.h" #include "dir.h" extern pthread_mutex_t mutex_mid; extern pthread_mutex_t mutex_render; extern WINDOW *win_b; extern WINDOW *win_m; extern dir mid_dir; extern unsigned int terminal_height; extern unsigned int terminal_width; extern unsigned int status; extern char *start_path; extern char *global_path; extern char *input; extern time_t seed; char search_buffer[INPUT_BUFFER_SIZE]; unsigned int input_pass; unsigned long parsed_input_number; yank yank_files = { 0 }; #define TODO noraw(); \ endwin();\ curs_set(1);\ echo();\ printf("TODO: %s at %d in %s \n", __func__, __LINE__, __FILE__);\ exit(1); void FAIL(char *function, char *str){ printf("ERROR in function %s: %s", function, str); } void user_interactions() { char ch; unsigned long i; unsigned long binding_matches = 0; ch = getch(); if(ch != ERR) { input[input_pass] = ch; input_pass++; if (ch == 27) { /* esc key */ memset(input, 0, INPUT_BUFFER_SIZE); input_pass = 0; } } void (*func_ptr)(int, int); unsigned long number_length = 0; parsed_input_number = 0; while((*input >= '0') && (*input <= '9')) { parsed_input_number = (parsed_input_number * 10) + (*input - '0'); input++; number_length++; } if (parsed_input_number == 0) { parsed_input_number = 1; } input -= number_length; char cmp_len = strlen(input); if(strlen(input) < 1) { cmp_len = 1; } for (i = 0; i < binding_count; i++) { if (strncmp(input + number_length, key_binding[i].key, cmp_len) == 0) { if (strcmp(input + number_length, key_binding[i].key) == 0) { pthread_mutex_lock(&mutex_mid); func_ptr = key_binding[i].func; func_ptr(parsed_input_number, i); pthread_mutex_unlock(&mutex_mid); timeout(SETTINGS_CURSES_TIMEOUT); /* blocking timeout of getch() */ } else { binding_matches++; mvwprintw(stdscr, terminal_height-binding_matches-1, 0, "\t\t\t"); mvwprintw(stdscr, terminal_height-binding_matches-1, 0, "%s\t%s", key_binding[i].key, key_binding[i].comment); status |= STATUS_INPUT_MATCH; } } } if (status & STATUS_INPUT_MATCH) { attron(A_UNDERLINE); mvwprintw(stdscr, terminal_height-binding_matches-2, 0, "input\tcommand\t\t"); attroff(A_UNDERLINE); status &= ~STATUS_INPUT_MATCH; } else if (number_length != strlen(input)) { memset(input, 0, INPUT_BUFFER_SIZE); input_pass = 0; number_length = 0; binding_matches = 0; } } int read_string(WINDOW *win, int y, int x, char *str){ curs_set(1); timeout(-1); /* negative numbers block until enter is pressed */ unsigned int pass = 0; char ch; char err = 0; wmove(win, y, x); while(1) { /*ch = mvwgetch(win, y, x + pass);*/ ch = wgetch(win); if (ch == '\n') { err = 0; break; } else if (ch == '\t') { /* tab */ memcpy(str + pass, mid_dir.current_file->file_name, strlen(mid_dir.current_file->file_name)); mvwaddstr(win, y, x + pass, mid_dir.current_file->file_name); pass += strlen(mid_dir.current_file->file_name); } else if (ch == 127) { /* backspace */ if (pass > 0) { pass--; mvwdelch(win, y, x + pass); } } else if (ch == 27) { /* esc key */ err = 1; break; } else { mvwaddch(win, y, x + pass, ch); str[pass] = ch; pass++; } } str[pass] = '\0'; curs_set(0); return err; } void quit_program(){ status = STATUS_QUIT_PROGRAM; } void update(){ status |= (STATUS_RUN_BACKEND | STATUS_UPDATE_SCREEN_MASK | STATUS_RELOAD_DIRECTORY ); } void select_all(){ unsigned long i; for (i = 0; i < mid_dir.file_count; i++) { mid_dir.file_list[i].status ^= FILE_STATUS_SELECTED; } status |= (STATUS_RUN_BACKEND); } void move_down(unsigned long passes){ mid_dir.current_file += passes; if (mid_dir.current_file > mid_dir.file_list + mid_dir.file_count - 1) { mid_dir.current_file = mid_dir.file_list + mid_dir.file_count - 1; } status |= (STATUS_RUN_BACKEND); } void move_up(unsigned long passes){ mid_dir.current_file -= passes; if (mid_dir.current_file < mid_dir.file_list) { mid_dir.current_file = mid_dir.file_list; } status |= (STATUS_RUN_BACKEND); } void move_left(unsigned long passes){ unsigned long i; for (i = 0; i < passes; i++) { change_dir(".."); } status |= (STATUS_RUN_BACKEND | STATUS_RELOAD_DIRECTORY); } void move_right(){ if (mid_dir.current_file->file_type & FILE_TYPE_DIR) { change_dir(mid_dir.current_file->file_name); } else if (mid_dir.current_file->file_type & FILE_TYPE_EXEC) { char *cmd = parse_cmd("./"SETTINGS_COMMAND_REPLACE_STR,mid_dir.current_file); if (system(cmd)) { } } else { char *mime = get_mimetype(mid_dir.current_file); char *extension = mid_dir.current_file->file_name; char *cmd = NULL; while (extension <= mid_dir.current_file->file_name + strlen(mid_dir.current_file->file_name)) { if (*extension == '.') { break; } extension++; } unsigned long i; if (extension <= mid_dir.current_file->file_name + strlen(mid_dir.current_file->file_name)) { for (i = 0; i < file_extension_default_count; i++) { if (strcmp(extension, file_extension_default_cmd[i].file_extension) == 0) { if (file_extension_default_cmd[i].command[0] == SETTINGS_COMMAND_FORK) { cmd = parse_cmd(file_extension_default_cmd[i].command + 1, mid_dir.current_file); pid_t pid = fork(); if (pid == 0 && setsid()) { system(cmd); status = STATUS_QUIT_PROGRAM; exit(1); } } else { cmd = parse_cmd(file_extension_default_cmd[i].command, mid_dir.current_file); if (system(cmd)) { } } status |= STATUS_MOVE_RIGHT_MATCH; update(); break; } } } if (!(status & STATUS_MOVE_RIGHT_MATCH)) { for (i = 0; i < mimetype_default_count; i++) { if (strstr(mime, mimetype_default_cmd[i].mimetype)) { if (mimetype_default_cmd[i].command[0] == SETTINGS_COMMAND_FORK) { cmd = parse_cmd(mimetype_default_cmd[i].command + 1, mid_dir.current_file); pid_t pid = fork(); if (pid == 0 && setsid()) { system(cmd); status = STATUS_QUIT_PROGRAM; exit(1); } } else { cmd = parse_cmd(mimetype_default_cmd[i].command, mid_dir.current_file); if (system(cmd)) { } } status |= STATUS_MOVE_RIGHT_MATCH; update(); break; } } } status &= ~STATUS_MOVE_RIGHT_MATCH; free(cmd); free(mime); } status |= (STATUS_RUN_BACKEND | STATUS_RELOAD_DIRECTORY); } void toggle_hidden_files(){ file_modifiers ^= FILE_MODIFIERS_HIDDEN_FILES; status |= (STATUS_RUN_BACKEND | STATUS_RELOAD_DIRECTORY); } void toggle_selection(unsigned long passes){ unsigned long i; for (i = 0; i < passes; i++) { mid_dir.current_file->status ^= FILE_STATUS_SELECTED; move_down(1); } status |= (STATUS_RUN_BACKEND); } void jump_bottom(){ mid_dir.current_file = mid_dir.file_list + mid_dir.file_count - 1; status |= (STATUS_RUN_BACKEND); } void jump_top(){ mid_dir.current_file = mid_dir.file_list; status |= (STATUS_RUN_BACKEND); } void open_with(){ wclear(win_b); char *cmd; char *str = malloc(INPUT_BUFFER_SIZE); char *parsed_ui_text = parse_cmd(ui_open_with_text, mid_dir.current_file); mvwprintw(win_b, 0, 0, parsed_ui_text); if (read_string(win_b, 0, strlen(parsed_ui_text)+1, str) == 0) { if (str[0] == SETTINGS_COMMAND_FORK) { cmd = parse_cmd(str+1, mid_dir.current_file); pid_t pid = fork(); if (pid == 0 && setsid()) { system(cmd); status = STATUS_QUIT_PROGRAM; exit(1); } } else { cmd = parse_cmd(str, mid_dir.current_file); if (system(cmd)) { } } free(cmd); } free(parsed_ui_text); free(str); status |= (STATUS_RUN_BACKEND | STATUS_RELOAD_DIRECTORY | STATUS_UPDATE_SCREEN_CLEAR); } void rename_hovered(){ wclear(win_b); file tmp; tmp.file_name = malloc(INPUT_BUFFER_SIZE); char *parsed_ui_text = parse_cmd(ui_rename_text, mid_dir.current_file); mvwprintw(win_b, 0, 0, parsed_ui_text); if (read_string(win_b, 0, strlen(parsed_ui_text)+1, tmp.file_name) == 0) { char *cmd0 = parse_cmd(rename_cmd, mid_dir.current_file); char *cmd1 = parse_cmd(cmd0, &tmp); system(cmd1); free(cmd0); free(cmd1); } free(parsed_ui_text); free(tmp.file_name); status |= (STATUS_RUN_BACKEND | STATUS_RELOAD_DIRECTORY); } void delete(){ TODO; } void makedir(){ wclear(win_b); file tmp; tmp.file_name = malloc(INPUT_BUFFER_SIZE); mvwprintw(win_b, 0, 0, ui_makedir_text); if (read_string(win_b, 0, strlen(ui_makedir_text)+1, tmp.file_name) == 0) { char *cmd = parse_cmd(makedir_cmd, &tmp); system(cmd); free(cmd); } free(tmp.file_name); status |= (STATUS_RUN_BACKEND | STATUS_RELOAD_DIRECTORY); } void makefile(){ wclear(win_b); file tmp; tmp.file_name = malloc(INPUT_BUFFER_SIZE); mvwprintw(win_b, 0, 0, ui_makefile_text); if (read_string(win_b, 0, strlen(ui_makefile_text)+1, tmp.file_name) == 0) { char *cmd = parse_cmd(makefile_cmd, &tmp); system(cmd); free(cmd); } free(tmp.file_name); status |= (STATUS_RUN_BACKEND | STATUS_RELOAD_DIRECTORY); } void enter_shell(unsigned long passes, int index){ (void)passes; /*remove compiler warning*/ endwin();\ echo();\ curs_set(1);\ if (system(key_binding[index].black_magic)) { } initscr(); /* start ncurses */ noecho(); /* hide keyboard input */ curs_set(0); status |= (STATUS_RUN_BACKEND | STATUS_RELOAD_DIRECTORY); } void not_implemented(unsigned long passes, int index){ (void)passes; mvaddstr(terminal_height-1, 0, key_binding[index].comment); mvaddstr(terminal_height-1, strlen(key_binding[index].comment), "\t"); mvaddstr(terminal_height-1, strlen(key_binding[index].comment) + strlen("\t"), "is not yet implemented"); TODO; } void jump_to_dir(unsigned long passes, int index){ (void)passes; unsigned long len; char *c = strchr(key_binding[index].black_magic, '/'); if (c) { len = c - (char*)key_binding[index].black_magic; } else { len = strlen(key_binding[index].black_magic); } char *to_env = malloc(len + 1); memcpy(to_env, key_binding[index].black_magic, len); to_env[len] = '\0'; char *env = getenv(to_env + 1); /*+1 to remove the '$' prefix, freeing env always segfaults*/ if (env) { char *path = malloc(strlen(key_binding[index].black_magic) + strlen(env) + 1); memcpy(path, env, strlen(env)); memcpy(path + strlen(env), key_binding[index].black_magic + len, strlen(key_binding[index].black_magic)+1); change_dir(path); free(path); } else { change_dir(key_binding[index].black_magic); } free(to_env); status |= (STATUS_RUN_BACKEND | STATUS_UPDATE_SCREEN_MASK | STATUS_RELOAD_DIRECTORY ); } void order_by(unsigned long passes, int index){ (void)passes; seed = time(NULL); order_func = key_binding[index].black_magic; status |= (STATUS_RUN_BACKEND | STATUS_RELOAD_DIRECTORY); } void cmd_on_selected(unsigned long passes, int index){ TODO; } void yank_file_name(){ char *cmd = parse_cmd(clipboard_cmd, mid_dir.current_file); system(cmd); free(cmd); status |= (STATUS_RUN_BACKEND); } void yank_file_path(){ file *tmp = malloc(sizeof(file)); tmp->file_name = malloc(strlen(global_path)+1+strlen(mid_dir.current_file->file_name)+1); memcpy(tmp->file_name, global_path, strlen(global_path)); memcpy(tmp->file_name+strlen(global_path)+1, mid_dir.current_file->file_name, strlen(mid_dir.current_file->file_name)+1); tmp->file_name[strlen(global_path)] = '/'; /*no +1 is needed*/ char *cmd = parse_cmd(clipboard_cmd, tmp); system(cmd); free(cmd); free(tmp->file_name); free(tmp); status |= (STATUS_RUN_BACKEND); } void yank_file(unsigned long passes, int index){ TODO; } void paste(){ TODO; } void search(){ echo(); unsigned long i; for (i = 0; i < terminal_width -1; i++) { mvwaddch(win_b, 0, i, ' '); } mvwaddch(win_b, 0, 0, '/'); memset(search_buffer, 0, INPUT_BUFFER_SIZE); curs_set(1); echo(); timeout(-1); /* negative numbers block until enter is pressed */ unsigned int pass = 0; char ch; char err = 0; wmove(win_b, 0, 1); while(1) { ch = wgetch(win_b); if (ch == '\n') { err = 0; break; } else if (ch == '\t') { /* tab */ memcpy(search_buffer + pass, mid_dir.current_file->file_name, strlen(mid_dir.current_file->file_name)); mvwaddstr(win_b, 0, pass+1, mid_dir.current_file->file_name); pass += strlen(mid_dir.current_file->file_name); } else if (ch == 127) { /* backspace */ if (pass > 0) { pass--; mvwdelch(win_b, 0, pass+1); } } else if (ch == 27) { /* esc key */ err = 1; break; } if (ch) { mvwaddch(win_b, 0, pass+1, ch); search_buffer[pass] = ch; pass++; unsigned long index = (mid_dir.current_file - mid_dir.file_list); unsigned long x = getmaxx(win_b); for (; &mid_dir.file_list[index] < mid_dir.file_list + mid_dir.file_count; index++) { if (smartstrcasestr(mid_dir.file_list[index].file_name, search_buffer)) { mid_dir.current_file = &mid_dir.file_list[index]; /* re-render current dir */ pthread_mutex_lock(&mutex_render); werase(win_m); print_dir(win_m, 1, &mid_dir); wnoutrefresh(win_m); pthread_mutex_unlock(&mutex_render); break; } } } } search_buffer[pass] = '\0'; noecho(); curs_set(0); status |= (STATUS_RUN_BACKEND); } void search_next(){ long index = (mid_dir.current_file - mid_dir.file_list) + 1; for (; &mid_dir.file_list[index] < mid_dir.file_list + mid_dir.file_count; index++) { if (smartstrcasestr(mid_dir.file_list[index].file_name, search_buffer)) { mid_dir.current_file = &mid_dir.file_list[index]; break; } } status |= (STATUS_RUN_BACKEND); } void search_previous(){ long index = (mid_dir.current_file - mid_dir.file_list) - 1; for (; &mid_dir.file_list[index] >= mid_dir.file_list; index--) { if (smartstrcasestr(mid_dir.file_list[index].file_name, search_buffer)) { mid_dir.current_file = &mid_dir.file_list[index]; break; } } status |= (STATUS_RUN_BACKEND); } void jmp_file_index(){ TODO; }