commit - 0ce35b66957ca0c2d19ae9833da0a3e607425d94
commit + ccda2f4db6c3f1c5132eefc87f1fc2dbd5298cc4
blob - 1900350b9104586937723169cc85667e743543ad
blob + 285021accb225e5cc858097d09e1a68d4b32e1ca
--- tog/tog.c
+++ tog/tog.c
return NULL;
}
-/* Format a line for display, ensuring that it won't overflow a width limit. */
-static const struct got_error *
-format_line(wchar_t **wlinep, int *widthp, const char *line, int wlimit,
- int col_tab_align, int expand)
+/*
+ * Skip leading nscroll columns of a wide character string.
+ * Returns the index to the first character of the scrolled string.
+ */
+static const struct got_error *
+scroll_wline(int *scrollx , wchar_t *wline, int nscroll,
+ int col_tab_align)
{
+ int cols = 0;
+ size_t wlen = wcslen(wline);
+ int i = 0;
+
+ *scrollx = 0;
+
+ while (i < wlen && cols < nscroll) {
+ int width = wcwidth(wline[i]);
+
+ if (width == 0) {
+ i++;
+ continue;
+ }
+
+ if (width == 1 || width == 2) {
+ if (cols + width > nscroll)
+ break;
+ cols += width;
+ i++;
+ } else if (width == -1) {
+ if (wline[i] == L'\t') {
+ width = TABSIZE -
+ ((cols + col_tab_align) % TABSIZE);
+ } else {
+ width = 1;
+ wline[i] = L'.';
+ }
+ if (cols + width > nscroll)
+ break;
+ cols += width;
+ i++;
+ } else
+ return got_error_from_errno("wcwidth");
+ }
+
+ *scrollx = i;
+ return NULL;
+}
+
+/*
+ * Format a line for display, ensuring that it won't overflow a width limit.
+ * With scrolling, the width returned refers to the scrolled version of the
+ * line, which starts at (*wlinep)[*scrollxp]. The caller must free *wlinep.
+ */
+static const struct got_error *
+format_line(wchar_t **wlinep, int *widthp, int *scrollxp,
+ const char *line, int nscroll, int wlimit, int col_tab_align, int expand)
+{
const struct got_error *err = NULL;
int cols = 0;
wchar_t *wline = NULL;
char *exstr = NULL;
size_t wlen;
- int i;
+ int i, scrollx = 0;
*wlinep = NULL;
*widthp = 0;
if (err)
return err;
+ err = scroll_wline(&scrollx, wline, nscroll, col_tab_align);
+ if (err)
+ goto done;
+
if (wlen > 0 && wline[wlen - 1] == L'\n') {
wline[wlen - 1] = L'\0';
wlen--;
wlen--;
}
- i = 0;
+ i = scrollx;
while (i < wlen) {
int width = wcwidth(wline[i]);
wline[i] = L'\0';
if (widthp)
*widthp = cols;
+ if (scrollxp)
+ *scrollxp = scrollx;
done:
if (err)
free(wline);
else
*wlinep = wline;
return err;
-}
-
-/* Skip the leading nscroll columns of a wide character string. */
-const struct got_error *
-scroll_wline(wchar_t **wlinep, wchar_t *wline, int nscroll,
- int col_tab_align)
-{
- int cols = 0;
- size_t wlen = wcslen(wline);
- int i = 0, j = 0;
-
- *wlinep = wline;
-
- while (i < wlen && cols < nscroll) {
- int width = wcwidth(wline[i]);
-
- if (width == 0) {
- i++;
- continue;
- }
-
- if (width == 1 || width == 2) {
- if (cols + width > nscroll)
- break;
- cols += width;
- i++;
- } else if (width == -1) {
- if (wline[i] == L'\t') {
- width = TABSIZE -
- ((cols + col_tab_align) % TABSIZE);
- } else {
- width = 1;
- wline[i] = L'.';
- }
- if (cols + width > nscroll)
- break;
- cols += width;
- i++;
- } else
- return got_error_from_errno("wcwidth");
- j++;
- }
-
- *wlinep = &wline[j];
- return NULL;
}
static const struct got_error*
if (smallerthan && smallerthan[1] != '\0')
author = smallerthan + 1;
author[strcspn(author, "@>")] = '\0';
- return format_line(wauthor, author_width, author, limit, col_tab_align,
- 0);
+ return format_line(wauthor, author_width, NULL, author, 0, limit,
+ col_tab_align, 0);
}
static const struct got_error *
char datebuf[12]; /* YYYY-MM-DD + SPACE + NUL */
char *logmsg0 = NULL, *logmsg = NULL;
char *author = NULL;
- wchar_t *wlogmsg = NULL, *wauthor = NULL, *scrolled_wline;
+ wchar_t *wlogmsg = NULL, *wauthor = NULL;
int author_width, logmsg_width;
char *newline, *line = NULL;
- int col, limit;
+ int col, limit, scrollx;
const int avail = view->ncols;
struct tm tm;
time_t committer_time;
newline = strchr(logmsg, '\n');
if (newline)
*newline = '\0';
- limit = view->x + avail - col;
- err = format_line(&wlogmsg, &logmsg_width, logmsg, limit, col, 1);
- if (err)
- goto done;
- err = scroll_wline(&scrolled_wline, wlogmsg, view->x, col);
+ limit = avail - col;
+ err = format_line(&wlogmsg, &logmsg_width, &scrollx, logmsg, view->x,
+ limit, col, 1);
if (err)
goto done;
- waddwstr(view->window, scrolled_wline);
- logmsg_width = wcswidth(scrolled_wline, wcslen(scrolled_wline));
+ waddwstr(view->window, &wlogmsg[scrollx]);
col += MAX(logmsg_width, 0);
while (col < avail) {
waddch(view->window, ' ');
header = NULL;
goto done;
}
- err = format_line(&wline, &width, header, view->ncols, 0, 0);
+ err = format_line(&wline, &width, NULL, header, 0, view->ncols, 0, 0);
if (err)
goto done;
++msg;
if ((eol = strchr(msg, '\n')))
*eol = '\0';
- err = format_line(&wmsg, &width, msg, INT_MAX,
+ err = format_line(&wmsg, &width, NULL, msg, 0, INT_MAX,
date_display_cols + author_cols, 0);
if (err)
goto done;
rms = regmatch->rm_so;
rme = regmatch->rm_eo;
- err = format_line(&wline, &width, line, wlimit + skip,
+ err = format_line(&wline, &width, NULL, line, 0, wlimit + skip,
col_tab_align, 1);
if (err)
return err;
s->first_displayed_line - 1 + s->selected_line, nlines,
header) == -1)
return got_error_from_errno("asprintf");
- err = format_line(&wline, &width, line, view->ncols, 0, 0);
+ err = format_line(&wline, &width, NULL, line, 0, view->ncols,
+ 0, 0);
free(line);
if (err)
return err;
return err;
}
} else {
- err = format_line(&wline, &width, line,
+ err = format_line(&wline, &width, NULL, line, 0,
view->x + view->ncols, 0, view->x ? 1 : 0);
if (err) {
free(line);
nprinted++;
}
- err = format_line(&wline, &width, TOG_EOF_STRING, view->ncols,
- 0, 0);
+ err = format_line(&wline, &width, NULL, TOG_EOF_STRING, 0,
+ view->ncols, 0, 0);
if (err) {
return err;
}
return err;
}
- err = format_line(&wline, &width, line, view->ncols, 0, 0);
+ err = format_line(&wline, &width, NULL, line, 0, view->ncols, 0, 0);
free(line);
line = NULL;
if (err)
return got_error_from_errno("asprintf");
}
free(id_str);
- err = format_line(&wline, &width, line, view->ncols, 0, 0);
+ err = format_line(&wline, &width, NULL, line, 0, view->ncols, 0, 0);
free(line);
line = NULL;
if (err)
}
width += 9;
} else {
- err = format_line(&wline, &width, line,
+ err = format_line(&wline, &width, NULL, line, 0,
view->x + view->ncols - 9, 9, 1);
if (err) {
free(line);
if (limit == 0)
return NULL;
- err = format_line(&wline, &width, s->tree_label, view->ncols, 0, 0);
+ err = format_line(&wline, &width, NULL, s->tree_label, 0, view->ncols,
+ 0, 0);
if (err)
return err;
if (view_needs_focus_indication(view))
waddch(view->window, '\n');
if (--limit <= 0)
return NULL;
- err = format_line(&wline, &width, parent_path, view->ncols, 0, 0);
+ err = format_line(&wline, &width, NULL, parent_path, 0, view->ncols,
+ 0, 0);
if (err)
return err;
waddwstr(view->window, wline);
}
free(id_str);
free(link_target);
- err = format_line(&wline, &width, line, view->ncols, 0, 0);
+ err = format_line(&wline, &width, NULL, line, 0, view->ncols,
+ 0, 0);
if (err) {
free(line);
break;
s->nrefs) == -1)
return got_error_from_errno("asprintf");
- err = format_line(&wline, &width, line, view->ncols, 0, 0);
+ err = format_line(&wline, &width, NULL, line, 0, view->ncols, 0, 0);
if (err) {
free(line);
return err;
got_ref_get_name(re->ref)) == -1)
return got_error_from_errno("asprintf");
- err = format_line(&wline, &width, line, view->ncols, 0, 0);
+ err = format_line(&wline, &width, NULL, line, 0, view->ncols,
+ 0, 0);
if (err) {
free(line);
return err;