-string_ncopy(char *dst, const char *src, int dstlen)
+string_ncopy_do(char *dst, size_t dstlen, const char *src, size_t srclen)
- string_ncopy(dst, src, sizeof(dst))
+ string_ncopy_do(dst, sizeof(dst), src, sizeof(dst))
+
+#define string_ncopy(dst, src, srclen) \
+ string_ncopy_do(dst, sizeof(dst), src, srclen)
-string_nformat(char *buf, size_t bufsize, int *bufpos, const char *fmt, ...)
+string_nformat(char *buf, size_t bufsize, size_t *bufpos, const char *fmt, ...)
va_start(args, fmt);
pos += vsnprintf(buf + pos, bufsize - pos, fmt, args);
va_start(args, fmt);
pos += vsnprintf(buf + pos, bufsize - pos, fmt, args);
LINE(AUTHOR, "author ", COLOR_CYAN, COLOR_DEFAULT, 0), \
LINE(COMMITTER, "committer ", COLOR_MAGENTA, COLOR_DEFAULT, 0), \
LINE(SIGNOFF, " Signed-off-by", COLOR_YELLOW, COLOR_DEFAULT, 0), \
LINE(AUTHOR, "author ", COLOR_CYAN, COLOR_DEFAULT, 0), \
LINE(COMMITTER, "committer ", COLOR_MAGENTA, COLOR_DEFAULT, 0), \
LINE(SIGNOFF, " Signed-off-by", COLOR_YELLOW, COLOR_DEFAULT, 0), \
LINE(DEFAULT, "", COLOR_DEFAULT, COLOR_DEFAULT, A_NORMAL), \
LINE(CURSOR, "", COLOR_WHITE, COLOR_GREEN, A_BOLD), \
LINE(STATUS, "", COLOR_GREEN, COLOR_DEFAULT, 0), \
LINE(DEFAULT, "", COLOR_DEFAULT, COLOR_DEFAULT, A_NORMAL), \
LINE(CURSOR, "", COLOR_WHITE, COLOR_GREEN, A_BOLD), \
LINE(STATUS, "", COLOR_GREEN, COLOR_DEFAULT, 0), \
{ 'z', REQ_STOP_LOADING },
{ 'v', REQ_SHOW_VERSION },
{ 'r', REQ_SCREEN_REDRAW },
{ 'z', REQ_STOP_LOADING },
{ 'v', REQ_SHOW_VERSION },
{ 'r', REQ_SCREEN_REDRAW },
for (i = 0; i < ARRAY_SIZE(display) && (view = display[i]); i++)
#define displayed_views() (display[1] != NULL ? 2 : 1)
for (i = 0; i < ARRAY_SIZE(display) && (view = display[i]); i++)
#define displayed_views() (display[1] != NULL ? 2 : 1)
/* If non-NULL, points to the view that opened this view. If this view
* is closed tig will switch back to the parent view. */
/* If non-NULL, points to the view that opened this view. If this view
* is closed tig will switch back to the parent view. */
/* What type of content being displayed. Used in the title bar. */
const char *type;
/* Draw one line; @lineno must be < view->height. */
/* What type of content being displayed. Used in the title bar. */
const char *type;
/* Draw one line; @lineno must be < view->height. */
- bool (*draw)(struct view *view, struct line *line, unsigned int lineno);
+ bool (*draw)(struct view *view, struct line *line, unsigned int lineno, bool selected);
/* Read one line; updates view->line. */
bool (*read)(struct view *view, char *data);
/* Depending on view, change display based on current line. */
bool (*enter)(struct view *view, struct line *line);
/* Search for regex in a line. */
bool (*grep)(struct view *view, struct line *line);
/* Read one line; updates view->line. */
bool (*read)(struct view *view, char *data);
/* Depending on view, change display based on current line. */
bool (*enter)(struct view *view, struct line *line);
/* Search for regex in a line. */
bool (*grep)(struct view *view, struct line *line);
+#define foreach_view(view, i) \
+ for (i = 0; i < ARRAY_SIZE(views) && (view = &views[i]); i++)
+
+#define view_is_displayed(view) \
+ (view == display[0] || view == display[1])
- return view->ops->draw(view, &view->line[view->offset + lineno], lineno);
+ line = &view->line[view->offset + lineno];
+
+ if (selected) {
+ line->selected = TRUE;
+ view->ops->select(view, line);
+ } else if (line->selected) {
+ line->selected = FALSE;
+ wmove(view->win, lineno, 0);
+ wclrtoeol(view->win);
+ }
+
+ return view->ops->draw(view, line, lineno, selected);
if (view == display[current_view])
wbkgdset(view->title, get_line_attr(LINE_TITLE_FOCUS));
else
if (view == display[current_view])
wbkgdset(view->title, get_line_attr(LINE_TITLE_FOCUS));
else
if (!view->win) {
view->win = newwin(view->height, 0, offset, 0);
if (!view->win)
if (!view->win) {
view->win = newwin(view->height, 0, offset, 0);
if (!view->win)
+ /* Move current line into the view. */
+ if (view->lineno < view->offset) {
+ view->lineno = view->offset;
+ redraw_current_line = TRUE;
+ } else if (view->lineno >= view->offset + view->height) {
+ view->lineno = view->offset + view->height - 1;
+ redraw_current_line = TRUE;
+ }
+
+ assert(view->offset <= view->lineno && view->lineno < view->lines);
+
- }
-
- /* Move current line into the view. */
- if (view->lineno < view->offset) {
- view->lineno = view->offset;
- draw_view_line(view, 0);
- } else if (view->lineno >= view->offset + view->height) {
- if (view->lineno == view->offset + view->height) {
- /* Clear the hidden line so it doesn't show if the view
- * is scrolled up. */
- wmove(view->win, view->height, 0);
- wclrtoeol(view->win);
- }
- view->lineno = view->offset + view->height - 1;
- draw_view_line(view, view->lineno - view->offset);
+ if (redraw_current_line)
+ draw_view_line(view, view->lineno - view->offset);
- /* Repaint the old "current" line if we be scrolling */
- if (ABS(steps) < view->height) {
- int prev_lineno = view->lineno - steps - view->offset;
-
- wmove(view->win, prev_lineno, 0);
- wclrtoeol(view->win);
- draw_view_line(view, prev_lineno);
- }
-
/* Check whether the view needs to be scrolled */
if (view->lineno < view->offset ||
view->lineno >= view->offset + view->height) {
/* Check whether the view needs to be scrolled */
if (view->lineno < view->offset ||
view->lineno >= view->offset + view->height) {
- steps = view->lines - view->offset - 1;
- if (steps >= view->height)
- steps -= view->height - 1;
+ scroll_steps = view->lines - view->offset - 1;
+ if (scroll_steps >= view->height)
+ scroll_steps -= view->height - 1;
- do_scroll_view(view, steps, redraw);
+ if (!view_is_displayed(view)) {
+ view->offset += steps;
+ view->ops->select(view, &view->line[view->lineno]);
- /* Draw the current line */
- draw_view_line(view, view->lineno - view->offset);
+ /* Repaint the old "current" line if we be scrolling */
+ if (ABS(steps) < view->height)
+ draw_view_line(view, view->lineno - steps - view->offset);
draw_view_line(view, old_lineno);
draw_view_line(view, view->lineno - view->offset);
draw_view_line(view, old_lineno);
draw_view_line(view, view->lineno - view->offset);
- regerror(regex_err, &view->regex, buf, sizeof(buf));
- report("Search failed: %s", buf);;
+ regerror(regex_err, view->regex, buf, sizeof(buf));
+ report("Search failed: %s", buf);
- if (snprintf(view->cmd, sizeof(view->cmd), format, id, opt_path)
- >= sizeof(view->cmd))
+ if (!string_format(view->cmd, format, id, opt_path))
if (view == VIEW(REQ_VIEW_TREE)) {
/* Clear the view and redraw everything since the tree sorting
* might have rearranged things. */
if (view == VIEW(REQ_VIEW_TREE)) {
/* Clear the view and redraw everything since the tree sorting
* might have rearranged things. */
if (ferror(view->pipe)) {
report("Failed to read: %s", strerror(errno));
goto end;
if (ferror(view->pipe)) {
report("Failed to read: %s", strerror(errno));
goto end;
view->parent == VIEW(REQ_VIEW_MAIN)) ||
(view == VIEW(REQ_VIEW_BLOB) &&
view->parent == VIEW(REQ_VIEW_TREE))) {
view->parent == VIEW(REQ_VIEW_MAIN)) ||
(view == VIEW(REQ_VIEW_BLOB) &&
view->parent == VIEW(REQ_VIEW_TREE))) {
-pager_draw(struct view *view, struct line *line, unsigned int lineno)
+pager_draw(struct view *view, struct line *line, unsigned int lineno, bool selected)
- if (view->offset + lineno == view->lineno) {
- if (type == LINE_COMMIT) {
- string_copy(view->ref, text + 7);
- string_copy(ref_commit, view->ref);
-
- } else if (type == LINE_TREE_DIR || type == LINE_TREE_FILE) {
- strncpy(view->ref, text + STRING_SIZE("100644 blob "), 41);
- view->ref[40] = 0;
- string_copy(ref_blob, view->ref);
- }
-
type = LINE_CURSOR;
wchgat(view->win, -1, 0, type, NULL);
}
type = LINE_CURSOR;
wchgat(view->win, -1, 0, type, NULL);
}
-add_describe_ref(char *buf, int *bufpos, char *commit_id, const char *sep)
+add_describe_ref(char *buf, size_t *bufpos, char *commit_id, const char *sep)
if (!add_describe_ref(buf, &bufpos, commit_id, sep))
return;
}
if (!add_describe_ref(buf, &bufpos, commit_id, sep))
return;
}
- if (regexec(&view->regex, text, 1, &pmatch, 0) == REG_NOMATCH)
+ if (regexec(view->regex, text, 1, &pmatch, 0) == REG_NOMATCH)
+static void
+pager_select(struct view *view, struct line *line)
+{
+ if (line->type == LINE_COMMIT) {
+ char *text = line->data;
+
+ string_copy(view->ref, text + STRING_SIZE("commit "));
+ string_copy(ref_commit, view->ref);
+ }
+}
+
*
* 100644 blob fb0e31ea6cc679b7379631188190e975f5789c26 Makefile
* 100644 blob 5304ca4260aaddaee6498f9630e7d471b8591ea6 README
*
* 100644 blob fb0e31ea6cc679b7379631188190e975f5789c26 Makefile
* 100644 blob 5304ca4260aaddaee6498f9630e7d471b8591ea6 README
- if (snprintf(buf, sizeof(buf), "Directory path /%s", opt_path) < sizeof(buf) &&
+ if (string_format(buf, "Directory path /%s", opt_path) &&
realloc_lines(view, view->line_size + 1) &&
pager_read(view, buf))
view->line[view->lines - 1].type = LINE_DEFAULT;
realloc_lines(view, view->line_size + 1) &&
pager_read(view, buf))
view->line[view->lines - 1].type = LINE_DEFAULT;
- snprintf(buf, sizeof(buf), TREE_UP_FORMAT, view->ref) < sizeof(buf) &&
+ string_format(buf, TREE_UP_FORMAT, view->ref) &&
realloc_lines(view, view->line_size + 1) &&
pager_read(view, buf))
view->line[view->lines - 1].type = LINE_TREE_DIR;
realloc_lines(view, view->line_size + 1) &&
pager_read(view, buf))
view->line[view->lines - 1].type = LINE_TREE_DIR;
- string_format_from(opt_path, &pathlen, "%s/", basename);
+ if (!string_format_from(opt_path, &pathlen, "%s/", basename)) {
+ opt_path[origlen] = 0;
+ return TRUE;
+ }
- if (!VIEW(request)->pipe)
- return TRUE;
+ return TRUE;
+}
+
+static void
+tree_select(struct view *view, struct line *line)
+{
+ char *text = line->data;
+
+ text += STRING_SIZE("100644 blob ");
- /* For tree views insert the path to the parent as the first line. */
- if (request == REQ_VIEW_BLOB) {
- /* Mirror what is showed in the title bar. */
- string_ncopy(ref_blob, data + STRING_SIZE("100644 blob "), 40);
+ if (line->type == LINE_TREE_FILE) {
+ string_ncopy(ref_blob, text, 40);
+ /* Also update the blob view's ref, since all there must always
+ * be in sync. */
-main_draw(struct view *view, struct line *line, unsigned int lineno)
+main_draw(struct view *view, struct line *line, unsigned int lineno, bool selected)
type = LINE_CURSOR;
wattrset(view->win, get_line_attr(type));
wchgat(view->win, -1, 0, type, NULL);
type = LINE_CURSOR;
wattrset(view->win, get_line_attr(type));
wchgat(view->win, -1, 0, type, NULL);
- if (regexec(&view->regex, text, 1, &pmatch, 0) != REG_NOMATCH)
+ if (regexec(view->regex, text, 1, &pmatch, 0) != REG_NOMATCH)
+static void
+main_select(struct view *view, struct line *line)
+{
+ struct commit *commit = line->data;
+
+ string_copy(view->ref, commit->id);
+ string_copy(ref_commit, view->ref);
+}
+
if (*opt_codeset && strcmp(opt_codeset, opt_encoding)) {
opt_iconv = iconv_open(opt_codeset, opt_encoding);
if (*opt_codeset && strcmp(opt_codeset, opt_encoding)) {
opt_iconv = iconv_open(opt_codeset, opt_encoding);