summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 87f9b5b)
raw | patch | inline | side by side (parent: 87f9b5b)
author | Jonas Fonseca <fonseca@diku.dk> | |
Sat, 21 Feb 2009 01:33:47 +0000 (02:33 +0100) | ||
committer | Jonas Fonseca <fonseca@diku.dk> | |
Sat, 21 Feb 2009 12:05:02 +0000 (13:05 +0100) |
NEWS | patch | blob | history | |
tig.c | patch | blob | history |
index 086bb79ff34e61ff939e18d01f1c9e86b95b4908..15d898b9037a04918f24c368928404f0ad6762d0 100644 (file)
--- a/NEWS
+++ b/NEWS
- Add branch view for choosing which branch to display in the main
view. Bound to 'H' by default.
+ - Tree view: sort entries by name, date or author. Toggling is bound to
+ 'i' by default, with 'I' controlling whether or not to sort in
+ ascending order.
Bug fixes:
index 13d1c45038042edbd391230f9f0b53b69cae65fd..a4eae7d01e624b3a65d5e81da1934b6026899134 100644 (file)
--- a/tig.c
+++ b/tig.c
REQ_(TOGGLE_AUTHOR, "Toggle author display"), \
REQ_(TOGGLE_REV_GRAPH, "Toggle revision graph visualization"), \
REQ_(TOGGLE_REFS, "Toggle reference display (tags/branches)"), \
+ REQ_(TOGGLE_SORT_ORDER, "Toggle ascending/descending sort order"), \
+ REQ_(TOGGLE_SORT_FIELD, "Toggle field to sort by"), \
\
REQ_GROUP("Misc") \
REQ_(PROMPT, "Bring up the prompt"), \
{ 'A', REQ_TOGGLE_AUTHOR },
{ 'g', REQ_TOGGLE_REV_GRAPH },
{ 'F', REQ_TOGGLE_REFS },
+ { 'I', REQ_TOGGLE_SORT_ORDER },
+ { 'i', REQ_TOGGLE_SORT_FIELD },
{ ':', REQ_PROMPT },
{ 'u', REQ_STATUS_UPDATE },
{ '!', REQ_STATUS_REVERT },
toggle_view_option(&opt_show_refs, "reference display");
break;
+ case REQ_TOGGLE_SORT_FIELD:
+ case REQ_TOGGLE_SORT_ORDER:
+ report("Sorting is not yet supported for the %s view", view->name);
+ break;
+
case REQ_SEARCH:
case REQ_SEARCH_BACK:
search_view(view, request);
* View backend utilities
*/
+enum sort_field {
+ ORDERBY_NAME,
+ ORDERBY_DATE,
+ ORDERBY_AUTHOR,
+};
+
+struct sort_state {
+ const enum sort_field *fields;
+ size_t size, current;
+ bool reverse;
+};
+
+#define SORT_STATE(fields) { fields, ARRAY_SIZE(fields), 0 }
+#define get_sort_field(state) ((state).fields[(state).current])
+#define sort_order(state, result) ((state).reverse ? -(result) : (result))
+
+static void
+sort_view(struct view *view, enum request request, struct sort_state *state,
+ int (*compare)(const void *, const void *))
+{
+ switch (request) {
+ case REQ_TOGGLE_SORT_FIELD:
+ state->current = (state->current + 1) % state->size;
+ break;
+
+ case REQ_TOGGLE_SORT_ORDER:
+ state->reverse = !state->reverse;
+ break;
+ default:
+ die("Not a sort request");
+ }
+
+ qsort(view->line, view->lines, sizeof(*view->line), compare);
+ redraw_view(view);
+}
+
DEFINE_ALLOCATOR(realloc_authors, const char *, 256)
/* Small author cache to reduce memory consumption. It uses binary
};
static const char *
-tree_path(struct line *line)
+tree_path(const struct line *line)
{
return ((struct tree_entry *) line->data)->name;
}
-
static int
-tree_compare_entry(struct line *line1, struct line *line2)
+tree_compare_entry(const struct line *line1, const struct line *line2)
{
if (line1->type != line2->type)
return line1->type == LINE_TREE_DIR ? -1 : 1;
return strcmp(tree_path(line1), tree_path(line2));
}
+static const enum sort_field tree_sort_fields[] = {
+ ORDERBY_NAME, ORDERBY_DATE, ORDERBY_AUTHOR
+};
+static struct sort_state tree_sort_state = SORT_STATE(tree_sort_fields);
+
+static int
+tree_compare(const void *l1, const void *l2)
+{
+ const struct line *line1 = (const struct line *) l1;
+ const struct line *line2 = (const struct line *) l2;
+ const struct tree_entry *entry1 = ((const struct line *) l1)->data;
+ const struct tree_entry *entry2 = ((const struct line *) l2)->data;
+
+ if (line1->type == LINE_TREE_HEAD)
+ return -1;
+ if (line2->type == LINE_TREE_HEAD)
+ return 1;
+
+ switch (get_sort_field(tree_sort_state)) {
+ case ORDERBY_DATE:
+ return sort_order(tree_sort_state, entry1->time - entry2->time);
+
+ case ORDERBY_AUTHOR:
+ return sort_order(tree_sort_state, strcmp(entry1->author, entry2->author));
+
+ case ORDERBY_NAME:
+ default:
+ return sort_order(tree_sort_state, tree_compare_entry(line1, line2));
+ }
+}
+
+
static struct line *
tree_entry(struct view *view, enum line_type type, const char *path,
const char *mode, const char *id)
}
return REQ_NONE;
+ case REQ_TOGGLE_SORT_FIELD:
+ case REQ_TOGGLE_SORT_ORDER:
+ sort_view(view, request, &tree_sort_state, tree_compare);
+ return REQ_NONE;
+
case REQ_PARENT:
if (!*opt_path) {
/* quit view if at top of tree */