index 9250cd7013e7c26b8187ce09c2ead6233bc61f87..a7dd9154dd5f609da7f65e44746230d73197f199 100644 (file)
--- a/tig.c
+++ b/tig.c
static const char **opt_diff_argv = NULL;
static const char **opt_rev_argv = NULL;
static const char **opt_file_argv = NULL;
+static const char **opt_blame_argv = NULL;
#define is_initial_commit() (!get_ref_head())
#define is_head_commit(rev) (!strcmp((rev), "HEAD") || (get_ref_head() && !strcmp(rev, get_ref_head()->id)))
OPT_ERR_(NO_OPTION_VALUE, "No option value"), \
OPT_ERR_(NO_VALUE_ASSIGNED, "No value assigned"), \
OPT_ERR_(OBSOLETE_REQUEST_NAME, "Obsolete request name"), \
+ OPT_ERR_(OUT_OF_MEMORY, "Out of memory"), \
OPT_ERR_(TOO_MANY_OPTION_ARGUMENTS, "Too many option arguments"), \
OPT_ERR_(UNKNOWN_ATTRIBUTE, "Unknown attribute"), \
OPT_ERR_(UNKNOWN_COLOR, "Unknown color"), \
}
}
+static enum option_code
+parse_args(const char ***args, const char *argv[])
+{
+ if (*args == NULL && !argv_copy(args, argv))
+ return OPT_ERR_OUT_OF_MEMORY;
+ return OPT_OK;
+}
+
/* Wants: name = value */
static enum option_code
option_set_command(int argc, const char *argv[])
{
- if (argc != 3)
+ if (argc < 3)
return OPT_ERR_WRONG_NUMBER_OF_ARGUMENTS;
if (strcmp(argv[1], "="))
return OPT_ERR_NO_VALUE_ASSIGNED;
+ if (!strcmp(argv[0], "blame-options"))
+ return parse_args(&opt_blame_argv, argv + 2);
+
+ if (argc != 3)
+ return OPT_ERR_WRONG_NUMBER_OF_ARGUMENTS;
+
if (!strcmp(argv[0], "show-author"))
return parse_enum(&opt_author, argv[2], author_map);
struct view {
enum view_type type; /* View type */
const char *name; /* View name */
- const char *cmd_env; /* Command line set via environment */
const char *id; /* Points to either of ref_{head,commit,blob} */
struct view_ops *ops; /* View operations */
static struct view_ops tree_ops;
static struct view_ops branch_ops;
-#define VIEW_STR(type, name, env, ref, ops, map, git) \
- { type, name, #env, ref, ops, map, git }
+#define VIEW_STR(type, name, ref, ops, map, git) \
+ { type, name, ref, ops, map, git }
#define VIEW_(id, name, ops, git, ref) \
- VIEW_STR(VIEW_##id, name, TIG_##id##_CMD, ref, ops, KEYMAP_##id, git)
+ VIEW_STR(VIEW_##id, name, ref, ops, KEYMAP_##id, git)
static struct view views[] = {
VIEW_(MAIN, "main", &main_ops, TRUE, ref_head),
}
}
+#define VIEW_MAX_LEN(view) ((view)->width + (view)->yoffset - (view)->col)
+
static int
draw_chars(struct view *view, enum line_type type, const char *string,
int max_len, bool use_tilde)
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, TRUE);
+ view->col += draw_chars(view, type, text, VIEW_MAX_LEN(view), TRUE);
string += pos;
- } while (*string && view->width + view->yoffset > view->col);
+ } while (*string && VIEW_MAX_LEN(view) > 0);
- return view->width + view->yoffset <= view->col;
+ return VIEW_MAX_LEN(view) <= 0;
}
static bool
draw_graphic(struct view *view, enum line_type type, const chtype graphic[], size_t size, bool separator)
{
size_t skip = view->yoffset > view->col ? view->yoffset - view->col : 0;
- int max = view->width + view->yoffset - view->col;
+ int max = VIEW_MAX_LEN(view);
int i;
if (max < size)
@@ -1599,13 +1616,13 @@ draw_graphic(struct view *view, enum line_type type, const chtype graphic[], siz
view->col++;
}
- return view->width + view->yoffset <= view->col;
+ return VIEW_MAX_LEN(view) <= 0;
}
static bool
draw_field(struct view *view, enum line_type type, const char *text, int len, bool trim)
{
- int max = MIN(view->width + view->yoffset - view->col, len);
+ int max = MIN(VIEW_MAX_LEN(view), len);
int col;
if (text)
@@ -1615,7 +1632,7 @@ draw_field(struct view *view, enum line_type type, const char *text, int len, bo
view->col += col;
view->col += draw_space(view, LINE_DEFAULT, max - col, max - col);
- return view->width + view->yoffset <= view->col;
+ return VIEW_MAX_LEN(view) <= 0;
}
static bool
{
char number[10];
int digits3 = view->digits < 3 ? 3 : view->digits;
- int max = MIN(view->width + view->yoffset - view->col, digits3);
+ int max = MIN(VIEW_MAX_LEN(view), digits3);
char *text = NULL;
chtype separator = opt_line_graphics ? ACS_VLINE : '|';
@@ -2383,6 +2400,11 @@ format_argv(const char ***dst_argv, const char *src_argv[], bool replace, bool f
break;
continue;
+ } else if (!strcmp(arg, "%(blameargs)")) {
+ if (!argv_append_array(dst_argv, opt_blame_argv))
+ break;
+ continue;
+
} else if (!strcmp(arg, "%(revargs)") ||
(first && !strcmp(arg, "%(commit)"))) {
if (!argv_append_array(dst_argv, opt_rev_argv))
{
if (!line) {
const char *blame_argv[] = {
- "git", "blame", "--incremental",
+ "git", "blame", "%(blameargs)", "--incremental",
*opt_ref ? opt_ref : "--incremental", "--", opt_file, NULL
};
"\n"
"Usage: tig [options] [revs] [--] [paths]\n"
" or: tig show [options] [revs] [--] [paths]\n"
-" or: tig blame [rev] path\n"
+" or: tig blame [options] [rev] [--] path\n"
" or: tig status\n"
" or: tig < [git command output]\n"
"\n"
return REQ_VIEW_STATUS;
} else if (!strcmp(subcommand, "blame")) {
- if (argc <= 2 || argc > 4)
+ filter_rev_parse(&opt_file_argv, "--no-revs", "--no-flags", argv + 2);
+ filter_rev_parse(&opt_blame_argv, "--no-revs", "--flags", argv + 2);
+ filter_rev_parse(&opt_rev_argv, "--symbolic", "--revs-only", argv + 2);
+
+ if (!opt_file_argv || opt_file_argv[1] || (opt_rev_argv && opt_rev_argv[1]))
die("invalid number of options to blame\n\n%s", usage);
- i = 2;
- if (argc == 4) {
- string_ncopy(opt_ref, argv[i], strlen(argv[i]));
- i++;
+ if (opt_rev_argv) {
+ string_ncopy(opt_ref, opt_rev_argv[0], strlen(opt_rev_argv[0]));
}
- string_ncopy(opt_file, argv[i], strlen(argv[i]));
+ string_ncopy(opt_file, opt_file_argv[0], strlen(opt_file_argv[0]));
return REQ_VIEW_BLAME;
} else if (!strcmp(subcommand, "show")) {
const char *codeset = "UTF-8";
enum request request = parse_options(argc, argv);
struct view *view;
- size_t i;
signal(SIGINT, quit);
signal(SIGPIPE, SIG_IGN);
if (load_refs() == ERR)
die("Failed to load refs.");
- foreach_view (view, i) {
- if (getenv(view->cmd_env))
- warn("Use of the %s environment variable is deprecated,"
- " use options or TIG_DIFF_ARGS instead",
- view->cmd_env);
- if (!argv_from_env(view->ops->argv, view->cmd_env))
- die("Too many arguments in the `%s` environment variable",
- view->cmd_env);
- }
-
init_display();
while (view_driver(display[current_view], request)) {