index 199eb34b7cfc434e915bf9026114dafb68ca280d..f562218376a5f17edc4722ce7e2fb25b4b985ec5 100644 (file)
--- a/tig.c
+++ b/tig.c
OPEN_RELOAD = 4, /* Reload view even if it is the current. */
OPEN_REFRESH = 16, /* Refresh view using previous command. */
OPEN_PREPARED = 32, /* Open already prepared command. */
+ OPEN_EXTRA = 64, /* Open extra data from command. */
};
struct view_ops {
}
static void
-maximize_view(struct view *view)
+maximize_view(struct view *view, bool redraw)
{
memset(display, 0, sizeof(display));
current_view = 0;
display[current_view] = view;
resize_display();
- redraw_display(FALSE);
- report("");
+ if (redraw) {
+ redraw_display(FALSE);
+ report("");
+ }
}
}
static bool
-format_argv(const char ***dst_argv, const char *src_argv[], bool replace, bool first)
+format_argv(const char ***dst_argv, const char *src_argv[], bool first)
{
char buf[SIZEOF_STR];
int argc;
@@ -2426,7 +2429,7 @@ format_argv(const char ***dst_argv, const char *src_argv[], bool replace, bool f
int len = next - arg;
const char *value;
- if (!next || !replace) {
+ if (!next) {
len = strlen(arg);
value = "";
@@ -2441,7 +2444,7 @@ format_argv(const char ***dst_argv, const char *src_argv[], bool replace, bool f
if (!string_format_from(buf, &bufpos, "%.*s%s", len, arg, value))
return FALSE;
- arg = next && replace ? strchr(next, ')') + 1 : NULL;
+ arg = next ? strchr(next, ')') + 1 : NULL;
}
if (!argv_append(dst_argv, buf))
}
static bool
-prepare_io(struct view *view, const char *dir, const char *argv[], bool replace)
+prepare_update(struct view *view, const char *dir, const char *argv[])
{
+ if (view->pipe)
+ io_done(view->pipe);
view->dir = dir;
- return format_argv(&view->argv, argv, replace, !view->prev);
+ return argv_copy(&view->argv, argv);
}
static bool
start_update(struct view *view, const char **argv, const char *dir)
{
- if (view->pipe)
- io_done(view->pipe);
- return prepare_io(view, dir, argv, FALSE) &&
+ return prepare_update(view, dir, argv) &&
io_run(&view->io, IO_RD, dir, view->argv);
}
static bool
begin_update(struct view *view, const char *dir, const char **argv, enum open_flags flags)
{
- bool reload = !!(flags & (OPEN_RELOAD | OPEN_REFRESH | OPEN_PREPARED));
+ bool extra = !!(flags & (OPEN_EXTRA));
+ bool reload = !!(flags & (OPEN_RELOAD | OPEN_REFRESH | OPEN_PREPARED | OPEN_EXTRA));
bool refresh = flags & (OPEN_REFRESH | OPEN_PREPARED);
if (!reload && !strcmp(view->vid, view->id))
return TRUE;
- if (view->pipe)
- end_update(view, TRUE);
+ if (view->pipe) {
+ if (extra)
+ io_done(view->pipe);
+ else
+ end_update(view, TRUE);
+ }
if (!refresh) {
- if (!prepare_io(view, dir, argv, TRUE))
+ view->dir = dir;
+ if (!format_argv(&view->argv, argv, !view->prev))
return FALSE;
/* Put the current ref_* value to the view title ref
@@ -2539,11 +2548,9 @@ begin_update(struct view *view, const char *dir, const char **argv, enum open_fl
if (view->argv && view->argv[0] &&
!io_run(&view->io, IO_RD, view->dir, view->argv))
return FALSE;
- else if (view->argv && !strcmp(view->argv[0], opt_cdup) &&
- !io_open(&view->io, "%s%s", opt_cdup, view->argv[1]))
- return FALSE;
- setup_update(view, view->id);
+ if (!extra)
+ setup_update(view, view->id);
return TRUE;
}
@@ -2690,15 +2697,63 @@ add_line_format(struct view *view, enum line_type type, const char *fmt, ...)
* View opening
*/
+static void
+load_view(struct view *view, enum open_flags flags)
+{
+ if (view->pipe)
+ end_update(view, TRUE);
+ if (!view->ops->open(view, flags)) {
+ report("Failed to load %s view", view->name);
+ return;
+ }
+ restore_view_position(view);
+
+ if (view->pipe && view->lines == 0) {
+ /* Clear the old view and let the incremental updating refill
+ * the screen. */
+ werase(view->win);
+ view->p_restore = flags & (OPEN_RELOAD | OPEN_REFRESH);
+ report("");
+ } else if (view_is_displayed(view)) {
+ redraw_view(view);
+ report("");
+ }
+}
+
+#define refresh_view(view) load_view(view, OPEN_REFRESH)
+
+static void
+split_view(struct view *prev, struct view *view)
+{
+ display[1] = view;
+ current_view = 1;
+ view->parent = prev;
+ resize_display();
+
+ if (prev->lineno - prev->offset >= prev->height) {
+ /* Take the title line into account. */
+ int lines = prev->lineno - prev->offset - prev->height + 1;
+
+ /* Scroll the view that was split if the current line is
+ * outside the new limited view. */
+ do_scroll_view(prev, lines);
+ }
+
+ if (view != prev && view_is_displayed(prev)) {
+ /* "Blur" the previous view. */
+ update_view_title(prev);
+ }
+}
+
static void
open_view(struct view *prev, enum request request, enum open_flags flags)
{
bool split = !!(flags & OPEN_SPLIT);
- bool reload = !!(flags & (OPEN_RELOAD | OPEN_REFRESH | OPEN_PREPARED));
- bool nomaximize = !!(flags & OPEN_REFRESH);
+ bool reload = !!(flags & (OPEN_RELOAD | OPEN_PREPARED));
struct view *view = VIEW(request);
int nviews = displayed_views();
- struct view *base_view = display[0];
+
+ assert(flags ^ OPEN_REFRESH);
if (view == prev && nviews == 1 && !reload) {
report("Already in %s view", view->name);
}
if (split) {
- display[1] = view;
- current_view = 1;
- view->parent = prev;
- } else if (!nomaximize) {
- /* Maximize the current view. */
- memset(display, 0, sizeof(display));
- current_view = 0;
- display[current_view] = view;
+ split_view(prev, view);
+ } else {
+ maximize_view(view, FALSE);
}
/* No prev signals that this is the first loaded view. */
view->prev = prev;
}
- /* Resize the view when switching between split- and full-screen,
- * or when switching between two different full-screen views. */
- if (nviews != displayed_views() ||
- (nviews == 1 && base_view != display[0]))
- resize_display();
-
- if (view->ops->open) {
- if (view->pipe)
- end_update(view, TRUE);
- if (!view->ops->open(view, flags)) {
- report("Failed to load %s view", view->name);
- return;
- }
- restore_view_position(view);
- }
-
- if (split && prev->lineno - prev->offset >= prev->height) {
- /* Take the title line into account. */
- int lines = prev->lineno - prev->offset - prev->height + 1;
-
- /* Scroll the view that was split if the current line is
- * outside the new limited view. */
- do_scroll_view(prev, lines);
- }
-
- if (prev && view != prev && split && view_is_displayed(prev)) {
- /* "Blur" the previous view. */
- update_view_title(prev);
- }
-
- if (view->pipe && view->lines == 0) {
- /* Clear the old view and let the incremental updating refill
- * the screen. */
- werase(view->win);
- view->p_restore = flags & (OPEN_RELOAD | OPEN_REFRESH);
- report("");
- } else if (view_is_displayed(view)) {
- redraw_view(view);
- report("");
- }
+ load_view(view, flags);
}
static void
@@ -2773,9 +2784,7 @@ open_argv(struct view *prev, struct view *view, const char *argv[], const char *
{
enum request request = view - views + REQ_OFFSET + 1;
- if (view->pipe)
- end_update(view, TRUE);
- if (!prepare_io(view, dir, argv, FALSE)) {
+ if (!prepare_update(view, dir, argv)) {
report("Failed to open %s view: %s", view->name, io_strerror(&view->io));
} else {
open_view(prev, request, flags | OPEN_PREPARED);
@@ -2790,6 +2799,7 @@ open_file(struct view *prev, struct view *view, const char *file, enum open_flag
if (view->pipe)
end_update(view, TRUE);
+ view->dir = opt_cdup;
if (!argv_copy(&view->argv, file_argv)) {
report("Failed to load %s: out of memory", file);
} else {
return;
}
- if (format_argv(&argv, req->argv, TRUE, FALSE))
+ if (format_argv(&argv, req->argv, FALSE))
open_external_viewer(argv, NULL);
if (argv)
argv_free(argv);
case REQ_MAXIMIZE:
if (displayed_views() == 2)
- maximize_view(view);
+ maximize_view(view, TRUE);
break;
case REQ_OPTIONS:
* view itself. Parents to closed view should never be
* followed. */
if (view->prev && view->prev != view) {
- maximize_view(view->prev);
+ maximize_view(view->prev, TRUE);
view->prev = view;
break;
}
switch (request) {
case REQ_REFRESH:
load_refs();
- open_view(view, REQ_VIEW_LOG, OPEN_REFRESH);
+ refresh_view(view);
return REQ_NONE;
default:
return pager_request(view, request, line);
if (line->type == LINE_HELP_KEYMAP) {
help_keymap_hidden[line->other] =
!help_keymap_hidden[line->other];
- view->p_restore = TRUE;
- open_view(view, REQ_VIEW_HELP, OPEN_REFRESH);
+ refresh_view(view);
}
return REQ_NONE;
static bool
blame_open(struct view *view, enum open_flags flags)
{
+ const char *file_argv[] = { opt_cdup, opt_file , NULL };
char path[SIZEOF_STR];
size_t i;
return FALSE;
}
- if (*opt_ref || !io_open(&view->io, "%s%s", opt_cdup, opt_file)) {
+ if (*opt_ref || !begin_update(view, opt_cdup, file_argv, flags)) {
const char *blame_cat_file_argv[] = {
"git", "cat-file", "blob", path, NULL
};
if (!string_format(path, "%s:%s", opt_ref, opt_file) ||
- !start_update(view, blame_cat_file_argv, opt_cdup))
+ !begin_update(view, opt_cdup, blame_cat_file_argv, flags))
return FALSE;
}
free(blame->commit);
}
- setup_update(view, opt_file);
+ string_format(view->vid, "%s:%s", opt_ref, opt_file);
string_format(view->ref, "%s ...", opt_file);
return TRUE;
if (view->lines == 0 && !view->prev)
die("No blame exist for %s", view->vid);
- if (view->lines == 0 || !start_update(view, blame_argv, opt_cdup)) {
+ if (view->lines == 0 || !begin_update(view, opt_cdup, blame_argv, OPEN_EXTRA)) {
report("Failed to load blame data");
return TRUE;
}
string_copy(opt_file, blame->commit->filename);
if (blame->lineno)
view->lineno = blame->lineno;
- open_view(view, REQ_VIEW_BLAME, OPEN_REFRESH);
+ refresh_view(view);
}
break;
string_copy_rev(opt_ref, blame->commit->parent_id);
string_copy(opt_file, blame->commit->parent_filename);
setup_blame_parent_line(view, blame);
- open_view(view, REQ_VIEW_BLAME, OPEN_REFRESH);
+ refresh_view(view);
}
break;
switch (request) {
case REQ_REFRESH:
load_refs();
- open_view(view, REQ_VIEW_BRANCH, OPEN_REFRESH);
+ refresh_view(view);
return REQ_NONE;
case REQ_TOGGLE_SORT_FIELD:
return request;
}
- open_view(view, REQ_VIEW_STATUS, OPEN_RELOAD);
+ refresh_view(view);
return REQ_NONE;
}
return request;
}
- VIEW(REQ_VIEW_STATUS)->p_restore = TRUE;
- open_view(view, REQ_VIEW_STATUS, OPEN_REFRESH);
+ refresh_view(view->parent);
/* Check whether the staged entry still exists, and close the
* stage view if it doesn't. */
return REQ_VIEW_CLOSE;
}
- open_view(view, REQ_VIEW_STAGE, OPEN_REFRESH);
+ refresh_view(view);
return REQ_NONE;
}
switch (request) {
case REQ_ENTER:
if (view_is_displayed(view) && display[0] != view)
- maximize_view(view);
+ maximize_view(view, TRUE);
open_view(view, REQ_VIEW_DIFF, flags);
break;
case REQ_REFRESH:
load_refs();
- open_view(view, REQ_VIEW_MAIN, OPEN_REFRESH);
+ refresh_view(view);
break;
default:
return request;