index dd155e35e23a6b11fd3aedc9e5883085372ebdb7..5f4c2635c3a719c5ea06d01bc08be62b042802a5 100644 (file)
--- a/tig.c
+++ b/tig.c
#define string_add(dst, from, src) \
string_ncopy_do(dst + (from), sizeof(dst) - (from), src, sizeof(src))
-static void
+static size_t
string_expand(char *dst, size_t dstlen, const char *src, int tabsize)
{
size_t size, pos;
}
dst[size] = 0;
+ return pos;
}
static char *
argv[0] = NULL;
}
+static size_t
+argv_size(const char **argv)
+{
+ int argc = 0;
+
+ while (argv && argv[argc])
+ argc++;
+
+ return argc;
+}
+
DEFINE_ALLOCATOR(argv_realloc, const char *, SIZEOF_ARG)
static bool
argv_append(const char ***argv, const char *arg)
{
- int argc = 0;
-
- while (*argv && (*argv)[argc])
- argc++;
+ size_t argc = argv_size(*argv);
if (!argv_realloc(argv, argc, 2))
return FALSE;
const char *home = getenv("HOME");
const char *tigrc_user = getenv("TIGRC_USER");
const char *tigrc_system = getenv("TIGRC_SYSTEM");
+ const char *tig_diff_opts = getenv("TIG_DIFF_OPTS");
char buf[SIZEOF_STR];
if (!tigrc_system)
* that conflict with keybindings. */
add_builtin_run_requests();
+ if (!opt_diff_args && tig_diff_opts && *tig_diff_opts) {
+ static const char *diff_opts[SIZEOF_ARG] = { NULL };
+ int argc = 0;
+
+ if (!string_format(buf, "%s", tig_diff_opts) ||
+ !argv_from_string(diff_opts, &argc, buf))
+ die("TIG_DIFF_OPTS contains too many arguments");
+ else if (!argv_copy(&opt_diff_args, diff_opts))
+ die("Failed to format TIG_DIFF_OPTS arguments");
+ }
+
return OK;
}
static bool
draw_text(struct view *view, enum line_type type, const char *string, bool trim)
{
- view->col += draw_chars(view, type, string, view->width + view->yoffset - view->col, trim);
+ char text[SIZEOF_STR];
+
+ do {
+ size_t pos = string_expand(text, sizeof(text), string, opt_tab_size);
+
+ view->col += draw_chars(view, type, text, view->width + view->yoffset - view->col, trim);
+ string += pos;
+ } while (*string && view->width + view->yoffset > view->col);
+
return view->width + view->yoffset <= view->col;
}
const char *arg = src_argv[argc];
size_t bufpos = 0;
- if (!strcmp(arg, "%(file-args)")) {
+ if (!strcmp(arg, "%(fileargs)")) {
if (!argv_append_array(dst_argv, opt_file_args))
break;
continue;
- } else if (!strcmp(arg, "%(diff-args)")) {
+ } else if (!strcmp(arg, "%(diffargs)")) {
if (!argv_append_array(dst_argv, opt_diff_args))
break;
continue;
- } else if (!strcmp(arg, "%(rev-args)")) {
+ } else if (!strcmp(arg, "%(revargs)")) {
if (!argv_append_array(dst_argv, opt_rev_args))
break;
continue;
static bool
pager_draw(struct view *view, struct line *line, unsigned int lineno)
{
- char text[SIZEOF_STR];
-
if (opt_line_number && draw_lineno(view, lineno))
return TRUE;
- string_expand(text, sizeof(text), line->data, opt_tab_size);
- draw_text(view, line->type, text, TRUE);
+ draw_text(view, line->type, line->data, TRUE);
return TRUE;
}
static const char *diff_argv[SIZEOF_ARG] = {
"git", "show", "--pretty=fuller", "--no-color", "--root",
"--patch-with-stat", "--find-copies-harder", "-C",
- "%(diff-args)", "%(commit)", "--", "%(file-args)", NULL
+ "%(diffargs)", "%(commit)", "--", "%(fileargs)", NULL
};
+static bool
+diff_read(struct view *view, char *data)
+{
+ if (!data) {
+ /* Fall back to retry if no diff will be shown. */
+ if (view->lines == 0 && opt_file_args) {
+ int pos = argv_size(view->argv)
+ - argv_size(opt_file_args) - 1;
+
+ if (pos > 0 && !strcmp(view->argv[pos], "--")) {
+ for (; view->argv[pos]; pos++) {
+ free((void *) view->argv[pos]);
+ view->argv[pos] = NULL;
+ }
+
+ if (view->pipe)
+ io_done(view->pipe);
+ if (io_run(&view->io, IO_RD, view->dir, view->argv))
+ return FALSE;
+ }
+ }
+ return TRUE;
+ }
+
+ return pager_read(view, data);
+}
+
static struct view_ops diff_ops = {
"line",
diff_argv,
NULL,
- pager_read,
+ diff_read,
pager_draw,
pager_request,
pager_grep,
struct blame *blame = line->data;
struct time *time = NULL;
const char *id = NULL, *author = NULL;
- char text[SIZEOF_STR];
if (blame->commit && *blame->commit->filename) {
id = blame->commit->id;
if (draw_lineno(view, lineno))
return TRUE;
- string_expand(text, sizeof(text), blame->text, opt_tab_size);
- draw_text(view, LINE_DEFAULT, text, TRUE);
+ draw_text(view, LINE_DEFAULT, blame->text, TRUE);
return TRUE;
}
static const char *main_argv[SIZEOF_ARG] = {
"git", "log", "--no-color", "--pretty=raw", "--parents",
- "--topo-order", "%(diff-args)", "%(rev-args)",
- "--", "%(file-args)", NULL
+ "--topo-order", "%(diffargs)", "%(revargs)",
+ "--", "%(fileargs)", NULL
};
static bool