LINE(CURSOR, "", COLOR_WHITE, COLOR_GREEN, A_BOLD), \
LINE(STATUS, "", COLOR_GREEN, COLOR_DEFAULT, 0), \
LINE(DELIMITER, "", COLOR_MAGENTA, COLOR_DEFAULT, 0), \
+LINE(LINE_NUMBER, "", COLOR_CYAN, COLOR_DEFAULT, 0), \
LINE(TITLE_BLUR, "", COLOR_WHITE, COLOR_BLUE, 0), \
LINE(TITLE_FOCUS, "", COLOR_WHITE, COLOR_BLUE, A_BOLD), \
LINE(MAIN_DATE, "", COLOR_BLUE, COLOR_DEFAULT, 0), \
LINE(BLAME_DATE, "", COLOR_BLUE, COLOR_DEFAULT, 0), \
LINE(BLAME_AUTHOR, "", COLOR_GREEN, COLOR_DEFAULT, 0), \
LINE(BLAME_COMMIT, "", COLOR_DEFAULT, COLOR_DEFAULT, 0), \
-LINE(BLAME_ID, "", COLOR_MAGENTA, COLOR_DEFAULT, 0), \
-LINE(BLAME_LINENO, "", COLOR_CYAN, COLOR_DEFAULT, 0)
+LINE(BLAME_ID, "", COLOR_MAGENTA, COLOR_DEFAULT, 0)
enum line_type {
#define LINE(type, line, fg, bg, attr) \
if (max < max_number)
max_number = max;
+ if (!selected)
+ wattrset(view->win, get_line_attr(LINE_LINE_NUMBER));
col = draw_text(view, number, max_number, showtrimmed, selected);
if (col < max) {
if (!selected)
OPEN_SPLIT = 1, /* Split current view. */
OPEN_BACKGROUNDED = 2, /* Backgrounded. */
OPEN_RELOAD = 4, /* Reload view even if it is the current. */
+ OPEN_NOMAXIMIZE = 8, /* Do not maximize the current view. */
};
static void
bool backgrounded = !!(flags & OPEN_BACKGROUNDED);
bool split = !!(flags & OPEN_SPLIT);
bool reload = !!(flags & OPEN_RELOAD);
+ bool nomaximize = !!(flags & OPEN_NOMAXIMIZE);
struct view *view = VIEW(request);
int nviews = displayed_views();
struct view *base_view = display[0];
display[1] = view;
if (!backgrounded)
current_view = 1;
- } else {
+ } else if (!nomaximize) {
/* Maximize the current view. */
memset(display, 0, sizeof(display));
current_view = 0;
if (view->pipe && view->lines == 0) {
/* Clear the old view and let the incremental updating refill
* the screen. */
- wclear(view->win);
+ werase(view->win);
report("");
} else {
redraw_view(view);
if (request > REQ_NONE) {
open_run_request(request);
- return TRUE;
+ /* FIXME: When all views can refresh always do this. */
+ if (view == VIEW(REQ_VIEW_STATUS) ||
+ view == VIEW(REQ_VIEW_STAGE))
+ request = REQ_REFRESH;
+ else
+ return TRUE;
}
if (view && view->lines) {
case REQ_TOGGLE_LINENO:
opt_line_number = !opt_line_number;
- redraw_display();
+ redraw_view(view);
break;
case REQ_TOGGLE_DATE:
opt_date = !opt_date;
- redraw_display();
+ redraw_view(view);
break;
case REQ_TOGGLE_AUTHOR:
opt_author = !opt_author;
- redraw_display();
+ redraw_view(view);
break;
case REQ_TOGGLE_REV_GRAPH:
opt_rev_graph = !opt_rev_graph;
- redraw_display();
+ redraw_view(view);
break;
case REQ_TOGGLE_REFS:
opt_show_refs = !opt_show_refs;
- redraw_display();
+ redraw_view(view);
break;
case REQ_PROMPT:
}
{
- if (!selected)
- wattrset(view->win, get_line_attr(LINE_BLAME_LINENO));
col += draw_lineno(view, lineno, view->width - col, selected);
if (col >= view->width)
return TRUE;
return REQ_NONE;
}
+static bool
+status_exists(struct status *status, enum line_type type)
+{
+ struct view *view = VIEW(REQ_VIEW_STATUS);
+ struct line *line;
+
+ for (line = view->line; line < view->line + view->lines; line++) {
+ struct status *pos = line->data;
+
+ if (line->type == type && pos &&
+ !strcmp(status->new.name, pos->new.name))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static FILE *
status_update_prepare(enum line_type type)
return written == bufsize;
}
-static struct line *
-stage_diff_hdr(struct view *view, struct line *line)
+static bool
+stage_diff_write(FILE *pipe, struct line *line, struct line *end)
{
- int diff_hdr_dir = line->type == LINE_DIFF_CHUNK ? -1 : 1;
- struct line *diff_hdr;
-
- if (line->type == LINE_DIFF_CHUNK)
- diff_hdr = line - 1;
- else
- diff_hdr = view->line + 1;
+ while (line < end) {
+ if (!stage_diff_line(pipe, line++))
+ return FALSE;
+ if (line->type == LINE_DIFF_CHUNK ||
+ line->type == LINE_DIFF_HEADER)
+ break;
+ }
- while (diff_hdr > view->line && diff_hdr < view->line + view->lines) {
- if (diff_hdr->type == LINE_DIFF_HEADER)
- return diff_hdr;
+ return TRUE;
+}
- diff_hdr += diff_hdr_dir;
- }
+static struct line *
+stage_diff_find(struct view *view, struct line *line, enum line_type type)
+{
+ for (; view->line < line; line--)
+ if (line->type == type)
+ return line;
return NULL;
}
static bool
-stage_update_chunk(struct view *view, struct line *line)
+stage_update_chunk(struct view *view, struct line *chunk)
{
char cmd[SIZEOF_STR];
size_t cmdsize = 0;
- struct line *diff_hdr, *diff_chunk, *diff_end;
+ struct line *diff_hdr;
FILE *pipe;
- diff_hdr = stage_diff_hdr(view, line);
+ diff_hdr = stage_diff_find(view, chunk, LINE_DIFF_HEADER);
if (!diff_hdr)
return FALSE;
if (!pipe)
return FALSE;
- diff_end = view->line + view->lines;
- if (line->type != LINE_DIFF_CHUNK) {
- diff_chunk = diff_hdr;
-
- } else {
- for (diff_chunk = line + 1; diff_chunk < diff_end; diff_chunk++)
- if (diff_chunk->type == LINE_DIFF_CHUNK ||
- diff_chunk->type == LINE_DIFF_HEADER)
- diff_end = diff_chunk;
-
- diff_chunk = line;
-
- while (diff_hdr->type != LINE_DIFF_CHUNK) {
- switch (diff_hdr->type) {
- case LINE_DIFF_HEADER:
- case LINE_DIFF_INDEX:
- case LINE_DIFF_ADD:
- case LINE_DIFF_DEL:
- break;
-
- default:
- diff_hdr++;
- continue;
- }
-
- if (!stage_diff_line(pipe, diff_hdr++)) {
- pclose(pipe);
- return FALSE;
- }
- }
- }
-
- while (diff_chunk < diff_end && stage_diff_line(pipe, diff_chunk))
- diff_chunk++;
+ if (!stage_diff_write(pipe, diff_hdr, chunk) ||
+ !stage_diff_write(pipe, chunk, view->line + view->lines))
+ chunk = NULL;
pclose(pipe);
- if (diff_chunk != diff_end)
- return FALSE;
-
- return TRUE;
+ return chunk ? TRUE : FALSE;
}
-static void
+static bool
stage_update(struct view *view, struct line *line)
{
- if (!opt_no_head && stage_line_type != LINE_STAT_UNTRACKED &&
- (line->type == LINE_DIFF_CHUNK || !stage_status.status)) {
- if (!stage_update_chunk(view, line)) {
+ struct line *chunk = NULL;
+
+ if (!opt_no_head && stage_line_type != LINE_STAT_UNTRACKED)
+ chunk = stage_diff_find(view, line, LINE_DIFF_CHUNK);
+
+ if (chunk) {
+ if (!stage_update_chunk(view, chunk)) {
report("Failed to apply chunk");
- return;
+ return FALSE;
}
} else if (!status_update_file(&stage_status, stage_line_type)) {
report("Failed to update file");
- return;
+ return FALSE;
}
- open_view(view, REQ_VIEW_STATUS, OPEN_RELOAD);
-
- view = VIEW(REQ_VIEW_STATUS);
- if (view_is_displayed(view))
- status_enter(view, &view->line[view->lineno]);
+ return TRUE;
}
static enum request
open_editor(stage_status.status != '?', stage_status.new.name);
break;
+ case REQ_REFRESH:
+ /* Reload everything ... */
+ break;
+
case REQ_VIEW_BLAME:
if (stage_status.new.name[0]) {
string_copy(opt_file, stage_status.new.name);
return request;
case REQ_ENTER:
- pager_request(view, request, line);
- break;
+ return pager_request(view, request, line);
default:
return request;
}
+ open_view(view, REQ_VIEW_STATUS, OPEN_RELOAD | OPEN_NOMAXIMIZE);
+
+ /* Check whether the staged entry still exists, and close the
+ * stage view if it doesn't. */
+ if (!status_exists(&stage_status, stage_line_type))
+ return REQ_VIEW_CLOSE;
+
+ if (stage_line_type == LINE_STAT_UNTRACKED)
+ opt_pipe = fopen(stage_status.new.name, "r");
+ else
+ string_copy(opt_cmd, view->cmd);
+ open_view(view, REQ_VIEW_STAGE, OPEN_RELOAD | OPEN_NOMAXIMIZE);
+
return REQ_NONE;
}
}
static int
-load_repo_config(void)
+load_git_config(void)
{
return read_properties(popen(GIT_CONFIG " --list", "r"),
"=", read_repo_config_option);
if (load_options() == ERR)
die("Failed to load user config.");
- /* Load the repo config file so options can be overwritten from
- * the command line. */
- if (load_repo_config() == ERR)
+ if (load_git_config() == ERR)
die("Failed to load repo config.");
if (!parse_options(argc, argv))