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_draw(struct view
*view
, struct line
*line
, unsigned int lineno
)
31 if (draw_lineno(view
, lineno
))
34 if (line
->wrapped
&& draw_text(view
, LINE_DELIMITER
, "+"))
37 draw_text(view
, line
->type
, line
->data
);
42 add_describe_ref(char *buf
, size_t *bufpos
, const char *commit_id
, const char *sep
)
44 const char *describe_argv
[] = { "git", "describe", commit_id
, NULL
};
47 if (!io_run_buf(describe_argv
, ref
, sizeof(ref
)) || !*ref
)
50 /* This is the only fatal call, since it can "corrupt" the buffer. */
51 if (!string_nformat(buf
, SIZEOF_STR
, bufpos
, "%s%s", sep
, ref
))
58 add_pager_refs(struct view
*view
, const char *commit_id
)
61 struct ref_list
*list
;
63 const char *sep
= "Refs: ";
66 list
= get_ref_list(commit_id
);
68 if (view_has_flags(view
, VIEW_ADD_DESCRIBE_REF
))
69 goto try_add_describe_ref
;
73 for (i
= 0; i
< list
->size
; i
++) {
74 struct ref
*ref
= list
->refs
[i
];
75 const struct ref_format
*fmt
= get_ref_format(ref
);
77 if (!string_format_from(buf
, &bufpos
, "%s%s%s%s", sep
,
78 fmt
->start
, ref
->name
, fmt
->end
))
85 if (!is_tag
&& view_has_flags(view
, VIEW_ADD_DESCRIBE_REF
)) {
87 /* Add <tag>-g<commit_id> "fake" reference. */
88 if (!add_describe_ref(buf
, &bufpos
, commit_id
, sep
))
95 add_line_text(view
, buf
, LINE_PP_REFS
);
99 pager_wrap_line(struct view
*view
, const char *data
, enum line_type type
)
101 size_t first_line
= 0;
102 bool has_first_line
= FALSE
;
103 size_t datalen
= strlen(data
);
106 while (datalen
> 0 || !has_first_line
) {
107 bool wrapped
= !!first_line
;
108 size_t linelen
= string_expanded_length(data
, datalen
, opt_tab_size
, view
->width
- !!wrapped
);
112 line
= add_line(view
, NULL
, type
, linelen
+ 1, wrapped
);
115 if (!has_first_line
) {
116 first_line
= view
->lines
- 1;
117 has_first_line
= TRUE
;
121 lineno
= line
->lineno
;
123 line
->wrapped
= wrapped
;
124 line
->lineno
= lineno
;
127 strncpy(text
, data
, linelen
);
134 return has_first_line
? &view
->line
[first_line
] : NULL
;
138 pager_common_read(struct view
*view
, const char *data
, enum line_type type
)
145 if (opt_wrap_lines
) {
146 line
= pager_wrap_line(view
, data
, type
);
148 line
= add_line_text(view
, data
, type
);
154 if (line
->type
== LINE_COMMIT
&& view_has_flags(view
, VIEW_ADD_PAGER_REFS
))
155 add_pager_refs(view
, data
+ STRING_SIZE("commit "));
161 pager_read(struct view
*view
, char *data
)
166 return pager_common_read(view
, data
, get_line_type(data
));
170 pager_request(struct view
*view
, enum request request
, struct line
*line
)
174 if (request
!= REQ_ENTER
)
177 if (line
->type
== LINE_COMMIT
&& view_has_flags(view
, VIEW_OPEN_DIFF
)) {
178 open_diff_view(view
, OPEN_SPLIT
);
182 /* Always scroll the view even if it was split. That way
183 * you can use Enter to scroll through the log view and
184 * split open each commit diff. */
185 scroll_view(view
, REQ_SCROLL_LINE_DOWN
);
187 /* FIXME: A minor workaround. Scrolling the view will call report_clear()
188 * but if we are scrolling a non-current view this won't properly
189 * update the view title. */
191 update_view_title(view
);
197 pager_grep(struct view
*view
, struct line
*line
)
199 const char *text
[] = { line
->data
, NULL
};
201 return grep_text(view
, text
);
205 pager_select(struct view
*view
, struct line
*line
)
207 if (line
->type
== LINE_COMMIT
) {
208 string_copy_rev_from_commit_line(view
->env
->commit
, line
->data
);
209 if (!view_has_flags(view
, VIEW_NO_REF
))
210 string_copy_rev(view
->ref
, view
->env
->commit
);
215 pager_open(struct view
*view
, enum open_flags flags
)
217 if (!open_from_stdin(flags
) && !view
->lines
&& !(flags
& OPEN_PREPARED
)) {
218 report("No pager content, press %s to run command from prompt",
219 get_view_key(view
, REQ_PROMPT
));
223 return begin_update(view
, NULL
, NULL
, flags
);
226 static struct view_ops pager_ops
= {
229 VIEW_OPEN_DIFF
| VIEW_NO_REF
| VIEW_NO_GIT_DIR
,
241 /* vim: set ts=8 sw=8 noexpandtab: */