static bool blame_read(struct view *view, char *line) { struct blame_state *state = view->private; if (!state->done_reading) return blame_read_file(view, line, state); if (!line) { state->auto_filename_display = blame_detect_filename_display(view); string_format(view->ref, "%s", view->vid); if (view_is_displayed(view)) { update_view_title(view); redraw_view_from(view, 0); } return TRUE; } if (!state->commit) { state->commit = read_blame_commit(view, line, state); string_format(view->ref, "%s %2zd%%", view->vid, view->lines ? state->blamed * 100 / view->lines : 0); } else if (parse_blame_info(state->commit, line)) { if (!state->commit->filename) return FALSE; state->commit = NULL; } return TRUE; }
enum request pager_request(struct view *view, enum request request, struct line *line) { int split = 0; if (request != REQ_ENTER) return request; if (line->type == LINE_COMMIT && view_has_flags(view, VIEW_OPEN_DIFF)) { open_view(view, REQ_VIEW_DIFF, OPEN_SPLIT); split = 1; } /* Always scroll the view even if it was split. That way * you can use Enter to scroll through the log view and * split open each commit diff. */ scroll_view(view, REQ_SCROLL_LINE_DOWN); /* FIXME: A minor workaround. Scrolling the view will call report_clear() * but if we are scrolling a non-current view this won't properly * update the view title. */ if (split) update_view_title(view); return REQ_NONE; }
void redraw_display(bool clear) { struct view *view; int i; foreach_displayed_view (view, i) { if (clear) wclear(view->win); redraw_view(view); update_view_title(view); } redraw_display_separator(clear); }
void report_clear(void) { struct view *view = display[current_view]; if (!view) return; if (!input_mode && !status_empty) { werase(status_win); doupdate(); } status_empty = true; update_view_title(view); }
void report(const char *msg, ...) { struct view *view = display[current_view]; va_list args; if (!view) { char buf[SIZEOF_STR]; int retval; FORMAT_BUFFER(buf, sizeof(buf), msg, retval, TRUE); die("%s", buf); } va_start(args, msg); if (update_status_window(view, msg, args)) wnoutrefresh(status_win); va_end(args); update_view_title(view); }
/* Update status and title window. */ void report(const char *msg, ...) { struct view *view = display[current_view]; if (input_mode) return; if (!view) { char buf[SIZEOF_STR]; int retval; FORMAT_BUFFER(buf, sizeof(buf), msg, retval, TRUE); die("%s", buf); } if (!status_empty || *msg) { va_list args; va_start(args, msg); wmove(status_win, 0, 0); if (view->has_scrolled && use_scroll_status_wclear) wclear(status_win); if (*msg) { vwprintw(status_win, msg, args); status_empty = FALSE; } else { status_empty = TRUE; } wclrtoeol(status_win); wnoutrefresh(status_win); va_end(args); } update_view_title(view); }
static bool view_driver(struct view *view, enum request request) { int i; if (request == REQ_NONE) return true; if (request >= REQ_RUN_REQUESTS) { request = open_run_request(view, request); // exit quickly rather than going through view_request and back if (request == REQ_QUIT) return false; } request = view_request(view, request); if (request == REQ_NONE) return true; switch (request) { case REQ_MOVE_UP: case REQ_MOVE_DOWN: case REQ_MOVE_PAGE_UP: case REQ_MOVE_PAGE_DOWN: case REQ_MOVE_HALF_PAGE_UP: case REQ_MOVE_HALF_PAGE_DOWN: case REQ_MOVE_FIRST_LINE: case REQ_MOVE_LAST_LINE: move_view(view, request); break; case REQ_SCROLL_FIRST_COL: case REQ_SCROLL_LEFT: case REQ_SCROLL_RIGHT: case REQ_SCROLL_LINE_DOWN: case REQ_SCROLL_LINE_UP: case REQ_SCROLL_PAGE_DOWN: case REQ_SCROLL_PAGE_UP: case REQ_SCROLL_WHEEL_DOWN: case REQ_SCROLL_WHEEL_UP: scroll_view(view, request); break; case REQ_VIEW_GREP: open_grep_view(view); break; case REQ_VIEW_MAIN: open_main_view(view, OPEN_DEFAULT); break; case REQ_VIEW_DIFF: open_diff_view(view, OPEN_DEFAULT); break; case REQ_VIEW_LOG: open_log_view(view, OPEN_DEFAULT); break; case REQ_VIEW_TREE: open_tree_view(view, OPEN_DEFAULT); break; case REQ_VIEW_HELP: open_help_view(view, OPEN_DEFAULT); break; case REQ_VIEW_REFS: open_refs_view(view, OPEN_DEFAULT); break; case REQ_VIEW_BLAME: open_blame_view(view, OPEN_DEFAULT); break; case REQ_VIEW_BLOB: open_blob_view(view, OPEN_DEFAULT); break; case REQ_VIEW_STATUS: open_status_view(view, OPEN_DEFAULT); break; case REQ_VIEW_STAGE: open_stage_view(view, NULL, 0, OPEN_DEFAULT); break; case REQ_VIEW_PAGER: open_pager_view(view, OPEN_DEFAULT); break; case REQ_VIEW_STASH: open_stash_view(view, OPEN_DEFAULT); break; case REQ_NEXT: case REQ_PREVIOUS: if (view->parent) { int line; view = view->parent; line = view->pos.lineno; view_request(view, request); move_view(view, request); if (view_is_displayed(view)) update_view_title(view); if (line != view->pos.lineno) view_request(view, REQ_ENTER); } else { move_view(view, request); } break; case REQ_VIEW_NEXT: { int nviews = displayed_views(); int next_view = nviews ? (current_view + 1) % nviews : current_view; if (next_view == current_view) { report("Only one view is displayed"); break; } current_view = next_view; /* Blur out the title of the previous view. */ update_view_title(view); report_clear(); break; } case REQ_REFRESH: report("Refreshing is not supported by the %s view", view->name); break; case REQ_PARENT: report("Moving to parent is not supported by the %s view", view->name); break; case REQ_BACK: report("Going back is not supported by the %s view", view->name); break; case REQ_MAXIMIZE: if (displayed_views() == 2) maximize_view(view, true); break; case REQ_OPTIONS: toggle_option(view); break; case REQ_SEARCH: case REQ_SEARCH_BACK: search_view(view, request); break; case REQ_FIND_NEXT: case REQ_FIND_PREV: find_next(view, request); break; case REQ_MOVE_NEXT_MERGE: case REQ_MOVE_PREV_MERGE: report("Moving between merge commits is not supported by the %s view", view->name); break; case REQ_STOP_LOADING: foreach_view(view, i) { if (view->pipe) report("Stopped loading the %s view", view->name), end_update(view, true); } break; case REQ_SHOW_VERSION: report("tig-%s (built %s)", TIG_VERSION, __DATE__); return true; case REQ_SCREEN_REDRAW: redraw_display(true); break; case REQ_EDIT: report("Nothing to edit"); break; case REQ_ENTER: report("Nothing to enter"); break; case REQ_VIEW_CLOSE: /* XXX: Mark closed views by letting view->prev point to the * view itself. Parents to closed view should never be * followed. */ if (view->prev && view->prev != view) { maximize_view(view->prev, true); view->prev = view; watch_unregister(&view->watch); view->parent = NULL; break; } /* Fall-through */ case REQ_QUIT: return false; default: report("Unknown key, press %s for help", get_view_key(view, REQ_VIEW_HELP)); return true; } return true; }
static int view_driver(struct view *view, enum request request) { int i; if (request == REQ_NONE) return TRUE; if (request >= REQ_RUN_REQUESTS) { request = open_run_request(view, request); // exit quickly rather than going through view_request and back if (request == REQ_QUIT) return FALSE; } request = view_request(view, request); if (request == REQ_NONE) return TRUE; switch (request) { case REQ_MOVE_UP: case REQ_MOVE_DOWN: case REQ_MOVE_PAGE_UP: case REQ_MOVE_PAGE_DOWN: case REQ_MOVE_FIRST_LINE: case REQ_MOVE_LAST_LINE: move_view(view, request); break; case REQ_SCROLL_FIRST_COL: case REQ_SCROLL_LEFT: case REQ_SCROLL_RIGHT: case REQ_SCROLL_LINE_DOWN: case REQ_SCROLL_LINE_UP: case REQ_SCROLL_PAGE_DOWN: case REQ_SCROLL_PAGE_UP: case REQ_SCROLL_WHEEL_DOWN: case REQ_SCROLL_WHEEL_UP: scroll_view(view, request); break; case REQ_VIEW_GREP: open_grep_view(view); break; case REQ_VIEW_MAIN: case REQ_VIEW_DIFF: case REQ_VIEW_LOG: case REQ_VIEW_TREE: case REQ_VIEW_HELP: case REQ_VIEW_BRANCH: case REQ_VIEW_BLAME: case REQ_VIEW_BLOB: case REQ_VIEW_STATUS: case REQ_VIEW_STAGE: case REQ_VIEW_PAGER: case REQ_VIEW_STASH: open_view(view, request, OPEN_DEFAULT); break; case REQ_NEXT: case REQ_PREVIOUS: if (view->parent) { int line; view = view->parent; line = view->pos.lineno; view_request(view, request); move_view(view, request); if (view_is_displayed(view)) update_view_title(view); if (line != view->pos.lineno) view_request(view, REQ_ENTER); } else { move_view(view, request); } break; case REQ_VIEW_NEXT: { int nviews = displayed_views(); int next_view = (current_view + 1) % nviews; if (next_view == current_view) { report("Only one view is displayed"); break; } current_view = next_view; /* Blur out the title of the previous view. */ update_view_title(view); report_clear(); break; } case REQ_REFRESH: report("Refreshing is not supported by the %s view", view->name); break; case REQ_PARENT: report("Moving to parent is not supported by the the %s view", view->name); break; case REQ_BACK: report("Going back is not supported for by %s view", view->name); break; case REQ_MAXIMIZE: if (displayed_views() == 2) maximize_view(view, TRUE); break; case REQ_OPTIONS: case REQ_TOGGLE_LINENO: case REQ_TOGGLE_DATE: case REQ_TOGGLE_AUTHOR: case REQ_TOGGLE_FILENAME: case REQ_TOGGLE_GRAPHIC: case REQ_TOGGLE_REV_GRAPH: case REQ_TOGGLE_REFS: case REQ_TOGGLE_CHANGES: case REQ_TOGGLE_IGNORE_SPACE: case REQ_TOGGLE_ID: case REQ_TOGGLE_FILES: case REQ_TOGGLE_TITLE_OVERFLOW: case REQ_TOGGLE_FILE_SIZE: case REQ_TOGGLE_UNTRACKED_DIRS: case REQ_TOGGLE_VERTICAL_SPLIT: { char action[SIZEOF_STR] = ""; enum view_flag flags = toggle_option(view, request, action); if (flags == VIEW_FLAG_RESET_DISPLAY) { resize_display(); redraw_display(TRUE); } else { foreach_displayed_view(view, i) { if (view_has_flags(view, flags) && !view->unrefreshable) reload_view(view); else redraw_view(view); } } if (*action) report("%s", action); } break; case REQ_TOGGLE_SORT_FIELD: case REQ_TOGGLE_SORT_ORDER: report("Sorting is not yet supported for the %s view", view->name); break; case REQ_DIFF_CONTEXT_UP: case REQ_DIFF_CONTEXT_DOWN: report("Changing the diff context is not yet supported for the %s view", view->name); break; case REQ_SEARCH: case REQ_SEARCH_BACK: search_view(view, request); break; case REQ_FIND_NEXT: case REQ_FIND_PREV: find_next(view, request); break; case REQ_STOP_LOADING: foreach_view(view, i) { if (view->pipe) report("Stopped loading the %s view", view->name), end_update(view, TRUE); } break; case REQ_SHOW_VERSION: report("tig-%s (built %s)", TIG_VERSION, __DATE__); return TRUE; case REQ_SCREEN_REDRAW: redraw_display(TRUE); break; case REQ_EDIT: report("Nothing to edit"); break; case REQ_ENTER: report("Nothing to enter"); break; case REQ_VIEW_CLOSE: /* XXX: Mark closed views by letting view->prev point to the * view itself. Parents to closed view should never be * followed. */ if (view->prev && view->prev != view) { maximize_view(view->prev, TRUE); view->prev = view; break; } /* Fall-through */ case REQ_QUIT: return FALSE; default: report("Unknown key, press %s for help", get_view_key(view, REQ_VIEW_HELP)); return TRUE; } return TRUE; }
void read_info_file(int reread) { /* TODO: refactor this function read_info_file() */ FILE *fp; char info_file[PATH_MAX]; char *line = NULL, *line2 = NULL, *line3 = NULL, *line4 = NULL; snprintf(info_file, sizeof(info_file), "%s/vifminfo", cfg.config_dir); if((fp = fopen(info_file, "r")) == NULL) return; while((line = read_vifminfo_line(fp, line)) != NULL) { const char type = line[0]; const char *const line_val = line + 1; if(type == LINE_TYPE_COMMENT || type == '\0') continue; if(type == LINE_TYPE_OPTION) { if(line_val[0] == '[' || line_val[0] == ']') { FileView *v = curr_view; curr_view = (line_val[0] == '[') ? &lwin : &rwin; process_set_args(line_val + 1); curr_view = v; } else { process_set_args(line_val); } } else if(type == LINE_TYPE_FILETYPE) { if((line2 = read_vifminfo_line(fp, line2)) != NULL) { /* This is to prevent old builtin fake associations to be loaded. */ if(!ends_with(line2, "}" VIFM_PSEUDO_CMD)) { set_programs(line_val, line2, 0, curr_stats.env_type == ENVTYPE_EMULATOR_WITH_X); } } } else if(type == LINE_TYPE_XFILETYPE) { if((line2 = read_vifminfo_line(fp, line2)) != NULL) { set_programs(line_val, line2, 1, curr_stats.env_type == ENVTYPE_EMULATOR_WITH_X); } } else if(type == LINE_TYPE_FILEVIEWER) { if((line2 = read_vifminfo_line(fp, line2)) != NULL) { set_fileviewer(line_val, line2); } } else if(type == LINE_TYPE_COMMAND) { if((line2 = read_vifminfo_line(fp, line2)) != NULL) { char *cmdadd_cmd; if((cmdadd_cmd = format_str("command %s %s", line_val, line2)) != NULL) { exec_commands(cmdadd_cmd, curr_view, GET_COMMAND); free(cmdadd_cmd); } } } else if(type == LINE_TYPE_BOOKMARK) { if((line2 = read_vifminfo_line(fp, line2)) != NULL) { if((line3 = read_vifminfo_line(fp, line3)) != NULL) { add_bookmark(line_val[0], line2, line3); } } } else if(type == LINE_TYPE_ACTIVE_VIEW) { /* don't change active view on :restart command */ if(line_val[0] == 'r' && !reread) { update_view_title(&lwin); update_view_title(&rwin); curr_view = &rwin; other_view = &lwin; } } else if(type == LINE_TYPE_QUICK_VIEW_STATE) { const int i = atoi(line_val); curr_stats.view = (i == 1); } else if(type == LINE_TYPE_WIN_COUNT) { const int i = atoi(line_val); cfg.show_one_window = (i == 1); curr_stats.number_of_windows = (i == 1) ? 1 : 2; } else if(type == LINE_TYPE_SPLIT_ORIENTATION) { curr_stats.split = (line_val[0] == 'v') ? VSPLIT : HSPLIT; } else if(type == LINE_TYPE_SPLIT_POSITION) { curr_stats.splitter_pos = atof(line_val); } else if(type == LINE_TYPE_LWIN_SORT) { get_sort_info(&lwin, line_val); } else if(type == LINE_TYPE_RWIN_SORT) { get_sort_info(&rwin, line_val); } else if(type == LINE_TYPE_LWIN_HIST) { int pos; if(line_val[0] == '\0') { if(reread) continue; if(lwin.history_num > 0) strcpy(lwin.curr_dir, lwin.history[lwin.history_pos].dir); continue; } if((line2 = read_vifminfo_line(fp, line2)) == NULL) continue; pos = read_possible_possible_pos(fp); get_history(&lwin, reread, line_val, line2, pos); } else if(type == LINE_TYPE_RWIN_HIST) { int pos; if(line_val[0] == '\0') { if(reread) continue; if(rwin.history_num > 0) strcpy(rwin.curr_dir, rwin.history[rwin.history_pos].dir); continue; } if((line2 = read_vifminfo_line(fp, line2)) == NULL) continue; pos = read_possible_possible_pos(fp); get_history(&rwin, reread, line_val, line2, pos); } else if(type == LINE_TYPE_CMDLINE_HIST) { inc_history(&cfg.cmd_history, &cfg.cmd_history_num, &cfg.history_len); save_command_history(line_val); } else if(type == LINE_TYPE_SEARCH_HIST) { inc_history(&cfg.search_history, &cfg.search_history_num, &cfg.history_len); save_search_history(line_val); } else if(type == LINE_TYPE_PROMPT_HIST) { inc_history(&cfg.prompt_history, &cfg.prompt_history_num, &cfg.history_len); save_prompt_history(line_val); } else if(type == LINE_TYPE_DIR_STACK) { if((line2 = read_vifminfo_line(fp, line2)) != NULL) { if((line3 = read_vifminfo_line(fp, line3)) != NULL) { if((line4 = read_vifminfo_line(fp, line4)) != NULL) { push_to_dirstack(line_val, line2, line3 + 1, line4); } } } } else if(type == LINE_TYPE_TRASH) { if((line2 = read_vifminfo_line(fp, line2)) != NULL) { if(!path_exists_at(cfg.trash_dir, line_val)) continue; add_to_trash(line2, line_val); } } else if(type == LINE_TYPE_REG) { append_to_register(line_val[0], line_val + 1); } else if(type == LINE_TYPE_LWIN_FILT) { (void)replace_string(&lwin.prev_filter, line_val); set_filename_filter(&lwin, line_val); } else if(type == LINE_TYPE_RWIN_FILT) { (void)replace_string(&rwin.prev_filter, line_val); set_filename_filter(&rwin, line_val); } else if(type == LINE_TYPE_LWIN_FILT_INV) { const int i = atoi(line_val); lwin.invert = (i != 0); } else if(type == LINE_TYPE_RWIN_FILT_INV) { const int i = atoi(line_val); rwin.invert = (i != 0); } else if(type == LINE_TYPE_USE_SCREEN) { const int i = atoi(line_val); set_use_screen(i != 0); } else if(type == LINE_TYPE_COLORSCHEME) { strcpy(curr_stats.color_scheme, line_val); } else if(type == LINE_TYPE_LWIN_SPECIFIC || type == LINE_TYPE_RWIN_SPECIFIC) { FileView *view = (type == LINE_TYPE_LWIN_SPECIFIC) ? &lwin : &rwin; set_view_property(view, line_val[0], line_val + 1); } } free(line); free(line2); free(line3); free(line4); fclose(fp); }