Skip to content

Commit

Permalink
Add struct box for structured pager text
Browse files Browse the repository at this point in the history
  • Loading branch information
jonas committed Jun 20, 2015
1 parent eecfbda commit 178c45c
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 35 deletions.
23 changes: 23 additions & 0 deletions include/tig/view.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@

struct view_ops;

struct box_cell {
enum line_type type;
size_t offset;
};

struct box {
const char *text;
size_t cells;
struct box_cell cell[1];
};

struct line {
enum line_type type;
unsigned int lineno:24;
Expand Down Expand Up @@ -189,6 +200,7 @@ struct view_column_data {
const struct ref *refs;
const char *status;
const char *text;
const struct box *box;
};

#define view_column_bit(id) (1 << VIEW_COLUMN_##id)
Expand Down Expand Up @@ -341,6 +353,16 @@ void update_view_title(struct view *view);
* Line utilities.
*/

static inline const char *
box_text(const struct line *line)
{
const struct box *box = line->data;

return box->text;
}

void box_text_copy(struct box *box, size_t cells, const char *src, size_t srclen);

struct line *add_line_at(struct view *view, unsigned long pos, const void *data, enum line_type type, size_t data_size, bool custom);
struct line *add_line(struct view *view, const void *data, enum line_type type, size_t data_size, bool custom);
struct line *add_line_alloc_(struct view *view, void **ptr, enum line_type type, size_t data_size, bool custom);
Expand All @@ -350,6 +372,7 @@ struct line *add_line_alloc_(struct view *view, void **ptr, enum line_type type,

struct line *add_line_nodata(struct view *view, enum line_type type);
struct line *add_line_text(struct view *view, const char *text, enum line_type type);
struct line *add_line_text_at(struct view *view, unsigned long pos, const char *text, enum line_type type, size_t cells);
struct line * PRINTF_LIKE(3, 4) add_line_format(struct view *view, enum line_type type, const char *fmt, ...);
bool append_line_format(struct view *view, struct line *line, const char *fmt, ...);

Expand Down
10 changes: 5 additions & 5 deletions src/diff.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ diff_read_describe(struct view *view, struct buffer *buffer, struct diff_state *

if (line && buffer) {
const char *ref = chomp_string(buffer->data);
const char *sep = !strcmp("Refs: ", line->data) ? "" : ", ";
const char *sep = !strcmp("Refs: ", box_text(line)) ? "" : ", ";

if (*ref && !append_line_format(view, line, "%s%s", sep, ref))
return false;
Expand Down Expand Up @@ -351,7 +351,7 @@ diff_get_lineno(struct view *view, struct line *line)
* following line, in the new version of the file. We increment this
* number for each non-deletion line, until the given line position.
*/
if (!parse_chunk_header(&chunk_header, chunk->data))
if (!parse_chunk_header(&chunk_header, box_text(chunk)))
return 0;

lineno = chunk_header.new.position;
Expand Down Expand Up @@ -383,7 +383,7 @@ diff_trace_origin(struct view *view, struct line *line)
}

for (; diff < line && !file; diff++) {
const char *data = diff->data;
const char *data = box_text(diff);

if (!prefixcmp(data, "--- a/")) {
file = data + STRING_SIZE("--- a/");
Expand All @@ -396,7 +396,7 @@ diff_trace_origin(struct view *view, struct line *line)
return REQ_NONE;
}

chunk_data = chunk->data;
chunk_data = box_text(chunk);

if (!parse_chunk_lineno(&lineno, chunk_data, chunk_marker)) {
report("Failed to read the line number");
Expand Down Expand Up @@ -455,7 +455,7 @@ diff_get_pathname(struct view *view, struct line *line)
return NULL;

for (i = 0; i < ARRAY_SIZE(prefixes) && !dst; i++)
dst = strstr(header->data, prefixes[i]);
dst = strstr(box_text(header), prefixes[i]);

return dst ? dst + strlen(prefixes[--i]) : NULL;
}
Expand Down
2 changes: 1 addition & 1 deletion src/grep.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ grep_get_line(const struct line *line)
if (line->type == LINE_DEFAULT)
return line->data;

grep_line.file = line->type == LINE_DELIMITER ? "" : get_path(line->data);
grep_line.file = line->type == LINE_DELIMITER ? "" : get_path(box_text(line));
return &grep_line;
}

Expand Down
2 changes: 1 addition & 1 deletion src/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ struct log_state {
static inline void
log_copy_rev(struct view *view, struct line *line)
{
const char *text = line->data;
const char *text = box_text(line);
size_t offset = get_graph_indent(text);

string_copy_rev_from_commit_line(view->ref, text + offset);
Expand Down
14 changes: 6 additions & 8 deletions src/pager.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
bool
pager_get_column_data(struct view *view, const struct line *line, struct view_column_data *column_data)
{
column_data->text = line->data;
column_data->text = box_text(line);
column_data->box = line->data;
return true;
}

Expand Down Expand Up @@ -75,9 +76,9 @@ pager_wrap_line(struct view *view, const char *data, enum line_type type)
bool wrapped = !!first_line;
size_t linelen = string_expanded_length(data, datalen, opt_tab_size, view->width - !!wrapped);
struct line *line;
char *text;
struct box *box;

line = add_line(view, NULL, type, linelen + 1, wrapped);
line = add_line_alloc(view, &box, type, linelen + 1, wrapped);
if (!line)
break;
if (!has_first_line) {
Expand All @@ -90,10 +91,7 @@ pager_wrap_line(struct view *view, const char *data, enum line_type type)

line->wrapped = wrapped;
line->lineno = lineno;
text = line->data;
if (linelen)
strncpy(text, data, linelen);
text[linelen] = 0;
box_text_copy(box, 1, data, linelen);

datalen -= linelen;
data += linelen;
Expand Down Expand Up @@ -168,7 +166,7 @@ void
pager_select(struct view *view, struct line *line)
{
if (line->type == LINE_COMMIT) {
string_copy_rev_from_commit_line(view->env->commit, line->data);
string_copy_rev_from_commit_line(view->env->commit, box_text(line));
if (!view_has_flags(view, VIEW_NO_REF))
string_copy_rev(view->ref, view->env->commit);
}
Expand Down
23 changes: 12 additions & 11 deletions src/stage.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ static bool
stage_diff_write(struct io *io, struct line *line, struct line *end)
{
while (line < end) {
if (!io_write(io, line->data, strlen(line->data)) ||
const char *text = box_text(line);

if (!io_write(io, text, strlen(text)) ||
!io_write(io, "\n", 1))
return false;
line++;
Expand All @@ -79,7 +81,7 @@ stage_diff_single_write(struct io *io, bool staged,

while (line < end) {
const char *prefix = "";
const char *data = line->data;
const char *data = box_text(line);

if (line == single) {
/* Write the complete line. */
Expand Down Expand Up @@ -110,7 +112,7 @@ stage_apply_line(struct io *io, struct line *diff_hdr, struct line *chunk, struc
bool staged = stage_line_type == LINE_STAT_STAGED;
int diff = single->type == LINE_DIFF_DEL ? -1 : 1;

if (!parse_chunk_header(&header, chunk->data))
if (!parse_chunk_header(&header, box_text(chunk)))
return false;

if (staged)
Expand Down Expand Up @@ -242,7 +244,7 @@ stage_insert_chunk(struct view *view, struct chunk_header *header,
struct line *from, struct line *to, struct line *last_unchanged_line)
{
char buf[SIZEOF_STR];
char *chunk_line;
struct box *box;
unsigned long from_lineno = last_unchanged_line - view->line;
unsigned long to_lineno = to - view->line;
unsigned long after_lineno = to_lineno;
Expand All @@ -252,23 +254,22 @@ stage_insert_chunk(struct view *view, struct chunk_header *header,
header->new.position, header->new.lines))
return NULL;

chunk_line = strdup(buf);
if (!chunk_line)
box = from->data;
box_text_copy(box, box->cells, "", 0);
if (!append_line_format(view, from, "%s", buf))
return NULL;

free(from->data);
from->data = chunk_line;

if (!to)
return from;

if (!add_line_at(view, after_lineno++, buf, LINE_DIFF_CHUNK, strlen(buf) + 1, false))
if (!add_line_text_at(view, after_lineno++, buf, LINE_DIFF_CHUNK, 1))
return NULL;

while (from_lineno < to_lineno) {
struct line *line = &view->line[from_lineno++];
const char *text = box_text(line);

if (!add_line_at(view, after_lineno++, line->data, line->type, strlen(line->data) + 1, false))
if (!add_line_text_at(view, after_lineno++, text, line->type, 1))
return false;
}

Expand Down
54 changes: 45 additions & 9 deletions src/view.c
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,9 @@ compare_view_column(enum view_column_type column, bool use_file_mode,
return apply_comparator(number_compare, column_data1->status, column_data2->status);

case VIEW_COLUMN_TEXT:
if (column_data1->box && column_data2->box)
return apply_comparator(strcmp, column_data1->box->text,
column_data2->box->text);
return apply_comparator(strcmp, column_data1->text, column_data2->text);
}

Expand Down Expand Up @@ -1450,6 +1453,21 @@ find_line_by_type(struct view *view, struct line *line, enum line_type type, int

DEFINE_ALLOCATOR(realloc_lines, struct line, 256)

static inline char *
box_text_offset(struct box *box, size_t cells)
{
return (char *) &box->cell[cells];
}

void
box_text_copy(struct box *box, size_t cells, const char *src, size_t srclen)
{
char *dst = box_text_offset(box, cells);

box->text = dst;
strncpy(dst, src, srclen);
}

struct line *
add_line_at(struct view *view, unsigned long pos, const void *data, enum line_type type, size_t data_size, bool custom)
{
Expand Down Expand Up @@ -1521,15 +1539,30 @@ add_line_nodata(struct view *view, enum line_type type)
}

struct line *
add_line_text(struct view *view, const char *text, enum line_type type)
add_line_text_at(struct view *view, unsigned long pos, const char *text, enum line_type type, size_t cells)
{
struct line *line = add_line(view, text, type, strlen(text) + 1, false);
struct box *box;
size_t extra_cells = cells > 1 ? sizeof(box->cell) * (cells - 1) : 0;
struct line *line = add_line_at(view, pos, NULL, type, sizeof(*box) + extra_cells + strlen(text) + 1, false);

if (line && view->ops->column_bits)
if (!line)
return NULL;

box = line->data;
box->cell[box->cells++].type = type;
box_text_copy(box, cells, text, strlen(text));

if (view->ops->column_bits)
view_column_info_update(view, line);
return line;
}

struct line *
add_line_text(struct view *view, const char *text, enum line_type type)
{
return add_line_text_at(view, view->lines, text, type, 1);
}

struct line * PRINTF_LIKE(3, 4)
add_line_format(struct view *view, enum line_type type, const char *fmt, ...)
{
Expand All @@ -1543,10 +1576,11 @@ add_line_format(struct view *view, enum line_type type, const char *fmt, ...)
bool
append_line_format(struct view *view, struct line *line, const char *fmt, ...)
{
char *text = NULL;
struct box *box;
size_t textlen = 0;
int fmtlen, retval;
va_list args;
char *text;

va_start(args, fmt);
fmtlen = vsnprintf(NULL, 0, fmt, args);
Expand All @@ -1555,18 +1589,20 @@ append_line_format(struct view *view, struct line *line, const char *fmt, ...)
if (fmtlen <= 0)
return false;

text = line->data;
textlen = strlen(text);
box = line->data;
textlen = strlen(box->text);

text = realloc(text, textlen + fmtlen + 1);
if (!text)
box = realloc(box, sizeof(*box) + textlen + fmtlen + 1);
if (!box)
return false;

box->text = text = box_text_offset(box, box->cells);
FORMAT_BUFFER(text + textlen, fmtlen + 1, fmt, retval, false);
if (retval < 0)
text[textlen] = 0;

line->data = text;
box->cell[box->cells - 1].length += fmtlen;
line->data = box;
line->dirty = true;

if (view->ops->column_bits)
Expand Down

0 comments on commit 178c45c

Please sign in to comment.