index 8a55aab9288ab2c3ea861c619649324937f27a9e..fb6231f256fbbfbcbb1545dc7caaa6d0a69dd3c1 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 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)
{
* Navigation
*/
+static bool
+goto_view_line(struct view *view, unsigned long offset, unsigned long lineno)
+{
+ if (lineno >= view->lines)
+ lineno = view->lines > 0 ? view->lines - 1 : 0;
+
+ if (offset > lineno || offset + view->height <= lineno) {
+ unsigned long half = view->height / 2;
+
+ if (lineno > half)
+ offset = lineno - half;
+ else
+ offset = 0;
+ }
+
+ if (offset != view->offset || lineno != view->lineno) {
+ view->offset = offset;
+ view->lineno = lineno;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
/* Scrolling backend */
static void
do_scroll_view(struct view *view, int lines)
static void
select_view_line(struct view *view, unsigned long lineno)
{
- if (lineno - view->offset >= view->height) {
- view->offset = lineno;
- view->lineno = lineno;
- if (view_is_displayed(view))
- redraw_view(view);
+ unsigned long old_lineno = view->lineno;
+ unsigned long old_offset = view->offset;
- } else {
- unsigned long old_lineno = view->lineno - view->offset;
-
- view->lineno = lineno;
+ if (goto_view_line(view, view->offset, lineno)) {
if (view_is_displayed(view)) {
- draw_view_line(view, old_lineno);
- draw_view_line(view, view->lineno - view->offset);
- wnoutrefresh(view->win);
+ if (old_offset != view->offset) {
+ redraw_view(view);
+ } else {
+ draw_view_line(view, old_lineno - view->offset);
+ draw_view_line(view, view->lineno - view->offset);
+ wnoutrefresh(view->win);
+ }
} else {
view->ops->select(view, &view->line[view->lineno]);
}
return FALSE;
}
- if (view->p_lineno >= view->lines) {
- view->p_lineno = view->lines > 0 ? view->lines - 1 : 0;
- if (view->p_offset >= view->p_lineno) {
- unsigned long half = view->height / 2;
-
- if (view->p_lineno > half)
- view->p_offset = view->p_lineno - half;
- else
- view->p_offset = 0;
- }
- }
-
- if (view_is_displayed(view) &&
- view->offset != view->p_offset &&
- view->lineno != view->p_lineno)
+ if (goto_view_line(view, view->p_offset, view->p_lineno) &&
+ view_is_displayed(view))
werase(view->win);
- view->offset = view->p_offset;
view->yoffset = view->p_yoffset;
- view->lineno = view->p_lineno;
view->p_restore = FALSE;
return TRUE;
struct blame {
struct blame_commit *commit;
+ unsigned long lineno;
char text[1];
};
{
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;
blame = line->data;
blame->commit = commit;
+ blame->lineno = orig_lineno + group - 1;
line->dirty = 1;
}
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;
}
}
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;
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;
}
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;