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/refdb.h"
15 #include "tig/display.h"
19 #include "tig/pager.h"
22 /* Used for tracking when we need to recalculate the previous
23 * commit, for example when the user scrolls up or uses the page
24 * up/down in the log view. */
27 enum line_type last_type
;
28 bool commit_title_read
;
29 bool after_commit_header
;
30 bool reading_diff_stat
;
34 log_copy_rev(struct view
*view
, struct line
*line
)
36 const char *text
= line
->data
;
37 size_t offset
= get_graph_indent(text
);
39 string_copy_rev_from_commit_line(view
->ref
, text
+ offset
);
43 log_select(struct view
*view
, struct line
*line
)
45 struct log_state
*state
= view
->private;
46 int last_lineno
= state
->last_lineno
;
48 if (!last_lineno
|| abs(last_lineno
- line
->lineno
) > 1
49 || (state
->last_type
== LINE_COMMIT
&& last_lineno
> line
->lineno
)) {
50 struct line
*commit_line
= find_prev_line_by_type(view
, line
, LINE_COMMIT
);
53 log_copy_rev(view
, commit_line
);
56 if (line
->type
== LINE_COMMIT
&& !view_has_flags(view
, VIEW_NO_REF
))
57 log_copy_rev(view
, line
);
58 string_copy_rev(view
->env
->commit
, view
->ref
);
59 state
->last_lineno
= line
->lineno
;
60 state
->last_type
= line
->type
;
64 log_open(struct view
*view
, enum open_flags flags
)
66 const char *log_argv
[] = {
67 "git", "log", encoding_arg
, commit_order_arg(), "--cc",
68 "--stat", "%(cmdlineargs)", "%(revargs)", "--no-color",
69 "--", "%(fileargs)", NULL
72 return begin_update(view
, NULL
, log_argv
, flags
);
76 log_request(struct view
*view
, enum request request
, struct line
*line
)
85 if (!display
[1] || strcmp(display
[1]->vid
, view
->ref
))
86 open_diff_view(view
, OPEN_SPLIT
);
95 log_read(struct view
*view
, struct buffer
*buf
)
97 struct line
*line
= NULL
;
99 struct log_state
*state
= view
->private;
108 commit
= strstr(data
, "commit ");
109 if (commit
&& get_graph_indent(data
) == commit
- data
)
110 state
->graph_indent
= commit
- data
;
112 type
= get_line_type(data
+ state
->graph_indent
);
113 len
= strlen(data
+ state
->graph_indent
);
115 if (type
== LINE_COMMIT
)
116 state
->commit_title_read
= TRUE
;
117 else if (state
->commit_title_read
&& len
< 1) {
118 state
->commit_title_read
= FALSE
;
119 state
->after_commit_header
= TRUE
;
120 } else if (state
->after_commit_header
&& len
< 1) {
121 state
->after_commit_header
= FALSE
;
122 state
->reading_diff_stat
= TRUE
;
123 } else if (state
->reading_diff_stat
) {
124 line
= diff_common_add_diff_stat(view
, data
, state
->graph_indent
);
126 if (state
->graph_indent
)
127 line
->graph_indent
= 1;
130 state
->reading_diff_stat
= FALSE
;
133 if (!pager_common_read(view
, data
, type
, &line
))
135 if (line
&& state
->graph_indent
)
136 line
->graph_indent
= 1;
140 static struct view_ops log_ops
= {
143 VIEW_ADD_PAGER_REFS
| VIEW_OPEN_DIFF
| VIEW_SEND_CHILD_ENTER
| VIEW_LOG_LIKE
| VIEW_REFRESH
,
144 sizeof(struct log_state
),
152 view_column_bit(LINE_NUMBER
) | view_column_bit(TEXT
),
153 pager_get_column_data
,
158 /* vim: set ts=8 sw=8 noexpandtab: */