Code

Use file and line number information when loading blame for commit
[tig.git] / tig.c
diff --git a/tig.c b/tig.c
index fba03c9ca1c0ef6a6114490f8300f09518b9bd7d..fb6231f256fbbfbcbb1545dc7caaa6d0a69dd3c1 100644 (file)
--- a/tig.c
+++ b/tig.c
@@ -188,20 +188,6 @@ string_ncopy_do(char *dst, size_t dstlen, const char *src, size_t srclen)
 #define string_add(dst, from, src) \
        string_ncopy_do(dst + (from), sizeof(dst) - (from), src, sizeof(src))
 
-static size_t
-string_expand_length(const char *line, int tabsize)
-{
-       size_t size, pos;
-
-       for (size = pos = 0; line[pos]; pos++) {
-               if (line[pos] == '\t' && tabsize > 0)
-                       size += tabsize - (size % tabsize);
-               else
-                       size++;
-       }
-       return size;
-}
-
 static void
 string_expand(char *dst, size_t dstlen, const char *src, int tabsize)
 {
@@ -4191,6 +4177,7 @@ struct blame_commit {
 
 struct blame {
        struct blame_commit *commit;
+       unsigned long lineno;
        char text[1];
 };
 
@@ -4254,14 +4241,16 @@ parse_blame_commit(struct view *view, const char *text, int *blamed)
 {
        struct blame_commit *commit;
        struct blame *blame;
-       const char *pos = text + SIZEOF_REV - 1;
+       const char *pos = text + SIZEOF_REV - 2;
+       size_t orig_lineno = 0;
        size_t lineno;
        size_t group;
 
-       if (strlen(text) <= SIZEOF_REV || *pos != ' ')
+       if (strlen(text) <= SIZEOF_REV || pos[1] != ' ')
                return NULL;
 
-       if (!parse_number(&pos, &lineno, 1, view->lines) ||
+       if (!parse_number(&pos, &orig_lineno, 1, 9999999) ||
+           !parse_number(&pos, &lineno, 1, view->lines) ||
            !parse_number(&pos, &group, 1, view->lines - lineno + 1))
                return NULL;
 
@@ -4275,6 +4264,7 @@ parse_blame_commit(struct view *view, const char *text, int *blamed)
 
                blame = line->data;
                blame->commit = commit;
+               blame->lineno = orig_lineno + group - 1;
                line->dirty = 1;
        }
 
@@ -4302,14 +4292,15 @@ blame_read_file(struct view *view, const char *line, bool *read_file)
                return FALSE;
 
        } else {
-               size_t linelen = string_expand_length(line, opt_tab_size);
+               size_t linelen = strlen(line);
                struct blame *blame = malloc(sizeof(*blame) + linelen);
 
                if (!blame)
                        return FALSE;
 
                blame->commit = NULL;
-               string_expand(blame->text, linelen + 1, line, opt_tab_size);
+               strncpy(blame->text, line, linelen);
+               blame->text[linelen] = 0;
                return add_line_data(view, blame, LINE_BLAME_ID) != NULL;
        }
 }
@@ -4385,6 +4376,7 @@ blame_draw(struct view *view, struct line *line, unsigned int lineno)
        struct blame *blame = line->data;
        struct tm *time = NULL;
        const char *id = NULL, *author = NULL;
+       char text[SIZEOF_STR];
 
        if (blame->commit && *blame->commit->filename) {
                id = blame->commit->id;
@@ -4404,7 +4396,8 @@ blame_draw(struct view *view, struct line *line, unsigned int lineno)
        if (draw_lineno(view, lineno))
                return TRUE;
 
-       draw_text(view, LINE_DEFAULT, blame->text, TRUE);
+       string_expand(text, sizeof(text), blame->text, opt_tab_size);
+       draw_text(view, LINE_DEFAULT, text, TRUE);
        return TRUE;
 }
 
@@ -4430,6 +4423,9 @@ blame_request(struct view *view, enum request request, struct line *line)
        case REQ_VIEW_BLAME:
                if (check_blame_commit(blame)) {
                        string_copy(opt_ref, blame->commit->id);
+                       string_copy(opt_file, blame->commit->filename);
+                       if (blame->lineno)
+                               view->lineno = blame->lineno;
                        open_view(view, REQ_VIEW_BLAME, OPEN_REFRESH);
                }
                break;