Code

Add VIEW_MAX_LEN macro to aid when drawing
[tig.git] / tig.c
diff --git a/tig.c b/tig.c
index 9250cd7013e7c26b8187ce09c2ead6233bc61f87..a7dd9154dd5f609da7f65e44746230d73197f199 100644 (file)
--- a/tig.c
+++ b/tig.c
@@ -365,6 +365,7 @@ static FILE *opt_tty                        = NULL;
 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)))
@@ -933,6 +934,7 @@ add_builtin_run_requests(void)
        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"), \
@@ -1110,16 +1112,30 @@ parse_string(char *opt, const char *arg, size_t optsize)
        }
 }
 
+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);
 
@@ -1362,7 +1378,6 @@ enum view_type {
 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 */
@@ -1447,11 +1462,11 @@ static struct view_ops status_ops;
 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),
@@ -1498,6 +1513,8 @@ set_view_attr(struct view *view, enum line_type type)
        }
 }
 
+#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)
@@ -1569,18 +1586,18 @@ draw_text(struct view *view, enum line_type type, const char *string)
        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
@@ -1665,7 +1682,7 @@ draw_lineno(struct view *view, unsigned int lineno)
 {
        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))
@@ -4181,7 +4203,7 @@ blame_read_file(struct view *view, const char *line, bool *read_file)
 {
        if (!line) {
                const char *blame_argv[] = {
-                       "git", "blame", "--incremental",
+                       "git", "blame", "%(blameargs)", "--incremental",
                                *opt_ref ? opt_ref : "--incremental", "--", opt_file, NULL
                };
 
@@ -6695,7 +6717,7 @@ static const char usage[] =
 "\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"
@@ -6792,16 +6814,18 @@ parse_options(int argc, const char *argv[])
                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")) {
@@ -6851,7 +6875,6 @@ main(int argc, const char *argv[])
        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);
@@ -6888,16 +6911,6 @@ main(int argc, const char *argv[])
        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)) {