Change test scripts to always wait for previous command to finish
[tig.git] / src / refs.c
blobc30d363738425ad0f5921d60696ad64d1cf76fd7
1 /* Copyright (c) 2006-2014 Jonas Fonseca <jonas.fonseca@gmail.com>
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU General Public License as
5 * published by the Free Software Foundation; either version 2 of
6 * the License, or (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
14 #include "tig/io.h"
15 #include "tig/options.h"
16 #include "tig/parse.h"
17 #include "tig/display.h"
18 #include "tig/view.h"
19 #include "tig/draw.h"
20 #include "tig/git.h"
21 #include "tig/main.h"
24 * Branch backend
27 struct reference {
28 const struct ident *author; /* Author of the last commit. */
29 struct time time; /* Date of the last activity. */
30 char title[128]; /* First line of the commit message. */
31 const struct ref *ref; /* Name and commit ID information. */
34 static const struct ref *refs_all;
35 #define REFS_ALL_NAME "All references"
36 #define refs_is_all(reference) ((reference)->ref == refs_all)
38 static bool
39 refs_get_column_data(struct view *view, const struct line *line, struct view_column_data *column_data)
41 const struct reference *reference = line->data;
43 column_data->author = reference->author;
44 column_data->date = &reference->time;
45 column_data->id = reference->ref->id;
46 column_data->ref = reference->ref;
47 column_data->commit_title = reference->title;
49 return TRUE;
52 static enum request
53 refs_request(struct view *view, enum request request, struct line *line)
55 struct reference *reference = line->data;
57 switch (request) {
58 case REQ_REFRESH:
59 load_refs(TRUE);
60 refresh_view(view);
61 return REQ_NONE;
63 case REQ_ENTER:
65 const struct ref *ref = reference->ref;
66 const char *all_references_argv[] = {
67 GIT_MAIN_LOG_CUSTOM(encoding_arg, commit_order_arg(), "",
68 refs_is_all(reference) ? "--all" : ref->name, "")
71 open_argv(view, &main_view, all_references_argv, NULL, OPEN_SPLIT);
72 return REQ_NONE;
74 default:
75 return request;
79 static bool
80 refs_read(struct view *view, struct buffer *buf)
82 struct reference template = {};
83 char *author;
84 char *title;
85 size_t i;
87 if (!buf)
88 return TRUE;
90 if (!*buf->data)
91 return FALSE;
93 author = io_memchr(buf, buf->data, 0);
94 title = io_memchr(buf, author, 0);
96 if (author)
97 parse_author_line(author, &template.author, &template.time);
99 for (i = 0; i < view->lines; i++) {
100 struct reference *reference = view->line[i].data;
102 if (strcmp(reference->ref->id, buf->data))
103 continue;
105 reference->author = template.author;
106 reference->time = template.time;
108 if (title)
109 string_expand(reference->title, sizeof(reference->title), title, 1);
111 view->line[i].dirty = TRUE;
112 view_column_info_update(view, &view->line[i]);
115 return TRUE;
118 static bool
119 refs_open_visitor(void *data, const struct ref *ref)
121 struct view *view = data;
122 struct reference *reference;
123 bool is_all = ref == refs_all;
124 struct line *line;
126 line = add_line_alloc(view, &reference, LINE_DEFAULT, 0, is_all);
127 if (!line)
128 return FALSE;
130 reference->ref = ref;
131 view_column_info_update(view, line);
133 return TRUE;
136 static bool
137 refs_open(struct view *view, enum open_flags flags)
139 const char *refs_log[] = {
140 "git", "log", encoding_arg, "--no-color", "--date=raw",
141 "--pretty=format:%H%x00%an <%ae> %ad%x00%s",
142 "--all", "--simplify-by-decoration", NULL
145 if (!refs_all) {
146 struct ref *ref = calloc(1, sizeof(*refs_all) + strlen(REFS_ALL_NAME));
148 if (ref) {
149 strncpy(ref->name, REFS_ALL_NAME, strlen(REFS_ALL_NAME));
150 refs_all = ref;
154 if (!refs_all || !begin_update(view, NULL, refs_log, OPEN_RELOAD)) {
155 report("Failed to load reference data");
156 return FALSE;
159 refs_open_visitor(view, refs_all);
160 foreach_ref(refs_open_visitor, view);
162 watch_register(&view->watch, WATCH_HEAD | WATCH_REFS);
164 return TRUE;
167 static void
168 refs_select(struct view *view, struct line *line)
170 struct reference *reference = line->data;
172 if (refs_is_all(reference)) {
173 string_copy(view->ref, REFS_ALL_NAME);
174 return;
176 string_copy_rev(view->ref, reference->ref->id);
177 string_copy_rev(view->env->head, reference->ref->id);
178 string_ncopy(view->env->ref, reference->ref->name, strlen(reference->ref->name));
179 ref_update_env(view->env, reference->ref, TRUE);
182 static struct view_ops refs_ops = {
183 "reference",
184 argv_env.head,
185 VIEW_REFRESH | VIEW_SORTABLE,
187 refs_open,
188 refs_read,
189 view_column_draw,
190 refs_request,
191 view_column_grep,
192 refs_select,
193 NULL,
194 view_column_bit(AUTHOR) | view_column_bit(COMMIT_TITLE) |
195 view_column_bit(DATE) | view_column_bit(ID) |
196 view_column_bit(LINE_NUMBER) | view_column_bit(REF),
197 refs_get_column_data,
200 DEFINE_VIEW(refs);
202 /* vim: set ts=8 sw=8 noexpandtab: */