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.
15 #include "tig/options.h"
16 #include "tig/request.h"
19 #include "tig/display.h"
29 pager_get_column_data(struct view
*view
, const struct line
*line
, struct view_column_data
*column_data
)
31 column_data
->text
= line
->data
;
36 add_describe_ref(char *buf
, size_t *bufpos
, const char *commit_id
, const char *sep
)
38 const char *describe_argv
[] = { "git", "describe", commit_id
, NULL
};
41 if (!io_run_buf(describe_argv
, ref
, sizeof(ref
)) || !*ref
)
44 /* This is the only fatal call, since it can "corrupt" the buffer. */
45 if (!string_nformat(buf
, SIZEOF_STR
, bufpos
, "%s%s", sep
, ref
))
52 add_pager_refs(struct view
*view
, const char *commit_id
)
55 struct ref_list
*list
;
57 const char *sep
= "Refs: ";
60 list
= get_ref_list(commit_id
);
62 if (view_has_flags(view
, VIEW_ADD_DESCRIBE_REF
))
63 goto try_add_describe_ref
;
67 for (i
= 0; i
< list
->size
; i
++) {
68 struct ref
*ref
= list
->refs
[i
];
69 const struct ref_format
*fmt
= get_ref_format(ref
);
71 if (!string_format_from(buf
, &bufpos
, "%s%s%s%s", sep
,
72 fmt
->start
, ref
->name
, fmt
->end
))
79 if (!is_tag
&& view_has_flags(view
, VIEW_ADD_DESCRIBE_REF
)) {
81 /* Add <tag>-g<commit_id> "fake" reference. */
82 if (!add_describe_ref(buf
, &bufpos
, commit_id
, sep
))
89 add_line_text(view
, buf
, LINE_PP_REFS
);
93 pager_wrap_line(struct view
*view
, const char *data
, enum line_type type
)
95 size_t first_line
= 0;
96 bool has_first_line
= FALSE
;
97 size_t datalen
= strlen(data
);
100 while (datalen
> 0 || !has_first_line
) {
101 bool wrapped
= !!first_line
;
102 size_t linelen
= string_expanded_length(data
, datalen
, opt_tab_size
, view
->width
- !!wrapped
);
106 line
= add_line(view
, NULL
, type
, linelen
+ 1, wrapped
);
109 if (!has_first_line
) {
110 first_line
= view
->lines
- 1;
111 has_first_line
= TRUE
;
115 lineno
= line
->lineno
;
117 line
->wrapped
= wrapped
;
118 line
->lineno
= lineno
;
121 strncpy(text
, data
, linelen
);
128 return has_first_line
? &view
->line
[first_line
] : NULL
;
132 pager_common_read(struct view
*view
, const char *data
, enum line_type type
, struct line
**line_ptr
)
139 if (opt_wrap_lines
) {
140 line
= pager_wrap_line(view
, data
, type
);
142 line
= add_line_text(view
, data
, type
);
151 if (line
->type
== LINE_COMMIT
&& view_has_flags(view
, VIEW_ADD_PAGER_REFS
))
152 add_pager_refs(view
, data
+ STRING_SIZE("commit "));
158 pager_read(struct view
*view
, char *data
)
163 return pager_common_read(view
, data
, get_line_type(data
), NULL
);
167 pager_request(struct view
*view
, enum request request
, struct line
*line
)
171 if (request
!= REQ_ENTER
)
174 if (line
->type
== LINE_COMMIT
&& view_has_flags(view
, VIEW_OPEN_DIFF
)) {
175 open_diff_view(view
, OPEN_SPLIT
);
179 /* Always scroll the view even if it was split. That way
180 * you can use Enter to scroll through the log view and
181 * split open each commit diff. */
182 scroll_view(view
, REQ_SCROLL_LINE_DOWN
);
184 /* FIXME: A minor workaround. Scrolling the view will call report_clear()
185 * but if we are scrolling a non-current view this won't properly
186 * update the view title. */
188 update_view_title(view
);
194 pager_select(struct view
*view
, struct line
*line
)
196 if (line
->type
== LINE_COMMIT
) {
197 string_copy_rev_from_commit_line(view
->env
->commit
, line
->data
);
198 if (!view_has_flags(view
, VIEW_NO_REF
))
199 string_copy_rev(view
->ref
, view
->env
->commit
);
204 pager_open(struct view
*view
, enum open_flags flags
)
206 if (!open_from_stdin(flags
) && !view
->lines
&& !(flags
& OPEN_PREPARED
)) {
207 report("No pager content, press %s to run command from prompt",
208 get_view_key(view
, REQ_PROMPT
));
212 return begin_update(view
, NULL
, NULL
, flags
);
215 static struct view_ops pager_ops
= {
218 VIEW_OPEN_DIFF
| VIEW_NO_REF
| VIEW_NO_GIT_DIR
,
227 view_column_bit(LINE_NUMBER
) | view_column_bit(TEXT
),
228 pager_get_column_data
,
233 /* vim: set ts=8 sw=8 noexpandtab: */