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.
28 struct keymap
*keymap
;
32 const struct request_info
*req_info
;
37 help_draw(struct view
*view
, struct line
*line
, unsigned int lineno
)
39 struct help
*help
= line
->data
;
40 struct keymap
*keymap
= help
->keymap
;
41 struct help_state
*state
= view
->private;
43 if (line
->type
== LINE_SECTION
) {
44 draw_formatted(view
, line
->type
, "[%c] %s bindings",
45 keymap
->hidden
? '+' : '-', keymap
->name
);
47 } else if (line
->type
== LINE_HELP_GROUP
|| !keymap
) {
48 draw_text(view
, line
->type
, help
->data
.text
);
50 } else if (help
->request
> REQ_RUN_REQUESTS
) {
51 struct run_request
*req
= get_run_request(help
->request
);
52 const char *key
= get_keys(keymap
, help
->request
, TRUE
);
53 char flags
[8] = { req
->flags
.internal
? ':' : '!', 0 };
54 const char *sep
= flags
;
55 int flagspos
= req
->flags
.internal
? 1 : 0;
58 if (draw_field(view
, LINE_DEFAULT
, key
, state
->keys_width
+ 2, ALIGN_RIGHT
, FALSE
))
61 if (req
->flags
.silent
)
62 flags
[flagspos
++] = '@';
63 if (req
->flags
.confirm
)
64 flags
[flagspos
++] = '?';
66 flags
[flagspos
++] = '<';
68 flags
[flagspos
++] = 0;
70 for (i
= 0; req
->argv
[i
]; i
++) {
71 if (draw_formatted(view
, LINE_HELP_ACTION
, "%s%s", sep
, req
->argv
[i
]))
77 const struct request_info
*req_info
= help
->data
.req_info
;
78 const char *key
= get_keys(keymap
, req_info
->request
, TRUE
);
80 if (draw_field(view
, LINE_DEFAULT
, key
, state
->keys_width
+ 2, ALIGN_RIGHT
, FALSE
))
83 if (draw_field(view
, LINE_HELP_ACTION
, enum_name(req_info
->name
), state
->name_width
, ALIGN_LEFT
, FALSE
))
86 draw_text(view
, LINE_DEFAULT
, req_info
->help
);
93 help_grep(struct view
*view
, struct line
*line
)
95 struct help
*help
= line
->data
;
96 struct keymap
*keymap
= help
->keymap
;
98 if (line
->type
== LINE_SECTION
) {
99 const char *text
[] = { keymap
->name
, NULL
};
101 return grep_text(view
, text
);
103 } else if (line
->type
== LINE_HELP_GROUP
|| !keymap
) {
104 const char *text
[] = { help
->data
.text
, NULL
};
106 return grep_text(view
, text
);
108 } else if (help
->request
> REQ_RUN_REQUESTS
) {
109 struct run_request
*req
= get_run_request(help
->request
);
110 const char *key
= get_keys(keymap
, help
->request
, TRUE
);
111 char buf
[SIZEOF_STR
] = "";
112 const char *text
[] = { key
, buf
, NULL
};
114 if (!argv_to_string(req
->argv
, buf
, sizeof(buf
), " "))
117 return grep_text(view
, text
);
120 const struct request_info
*req_info
= help
->data
.req_info
;
121 const char *key
= get_keys(keymap
, req_info
->request
, TRUE
);
122 const char *text
[] = { key
, enum_name(req_info
->name
), req_info
->help
, NULL
};
124 return grep_text(view
, text
);
128 struct help_request_iterator
{
130 struct keymap
*keymap
;
136 add_help_line(struct view
*view
, struct help
**help_ptr
, struct keymap
*keymap
, enum line_type type
)
140 if (!add_line_alloc(view
, &help
, type
, 0, FALSE
))
142 help
->keymap
= keymap
;
149 add_help_headers(struct help_request_iterator
*iterator
, const char *group
)
153 if (iterator
->add_title
) {
154 iterator
->add_title
= FALSE
;
155 if (!add_help_line(iterator
->view
, &help
, iterator
->keymap
, LINE_SECTION
))
159 if (iterator
->keymap
->hidden
)
162 if (iterator
->group
!= group
) {
163 iterator
->group
= group
;
164 if (!add_help_line(iterator
->view
, &help
, iterator
->keymap
, LINE_HELP_GROUP
))
166 help
->data
.text
= group
;
173 help_open_keymap(void *data
, const struct request_info
*req_info
, const char *group
)
175 struct help_request_iterator
*iterator
= data
;
176 struct help_state
*state
= iterator
->view
->private;
177 struct keymap
*keymap
= iterator
->keymap
;
178 const char *key
= get_keys(keymap
, req_info
->request
, TRUE
);
181 if (req_info
->request
== REQ_NONE
|| !key
|| !*key
)
184 if (!add_help_headers(iterator
, group
) ||
185 !add_help_line(iterator
->view
, &help
, iterator
->keymap
, LINE_DEFAULT
))
188 state
->keys_width
= MAX(state
->keys_width
, strlen(key
));
189 state
->name_width
= MAX(state
->name_width
, strlen(enum_name(req_info
->name
)));
191 help
->data
.req_info
= req_info
;
192 help
->request
= req_info
->request
;
198 help_open_keymap_run_requests(struct help_request_iterator
*iterator
, bool internal
, bool toggles
)
200 struct view
*view
= iterator
->view
;
201 struct help_state
*state
= view
->private;
202 struct keymap
*keymap
= iterator
->keymap
;
203 const char *group
= !internal
? "External commands:" :
204 toggles
? "Option toggling:" :
205 "Internal commands:";
206 enum request request
= REQ_RUN_REQUESTS
+ 1;
209 for (; TRUE
; request
++) {
210 struct run_request
*req
= get_run_request(request
);
216 if (req
->flags
.internal
!= !!internal
||
217 req
->keymap
!= keymap
||
218 !*(key
= get_keys(keymap
, request
, TRUE
)))
221 if (toggles
!= !strcmp(req
->argv
[0], "toggle"))
224 if (!add_help_headers(iterator
, group
) ||
225 !add_help_line(view
, &help
, keymap
, LINE_DEFAULT
))
228 state
->keys_width
= MAX(state
->keys_width
, strlen(key
));
230 help
->request
= request
;
235 help_open(struct view
*view
, enum open_flags flags
)
237 struct keymap
*keymap
;
243 if (!add_help_line(view
, &help
, NULL
, LINE_HEADER
))
245 help
->data
.text
= "Quick reference for tig keybindings:";
247 if (!add_help_line(view
, &help
, NULL
, LINE_DEFAULT
))
249 help
->data
.text
= "";
251 for (i
= 0; (keymap
= get_keymap_by_index(i
)); i
++) {
252 struct help_request_iterator iterator
= { view
, keymap
, TRUE
};
254 if (foreach_request(help_open_keymap
, &iterator
)) {
255 help_open_keymap_run_requests(&iterator
, TRUE
, TRUE
);
256 help_open_keymap_run_requests(&iterator
, TRUE
, FALSE
);
257 help_open_keymap_run_requests(&iterator
, FALSE
, FALSE
);
265 help_request(struct view
*view
, enum request request
, struct line
*line
)
267 struct help
*help
= line
->data
;
271 if (line
->type
== LINE_SECTION
) {
272 struct keymap
*keymap
= help
->keymap
;
274 keymap
->hidden
= !keymap
->hidden
;
289 help_select(struct view
*view
, struct line
*line
)
293 static struct view_ops help_ops
= {
296 VIEW_NO_GIT_DIR
| VIEW_REFRESH
,
297 sizeof(struct help_state
),
309 /* vim: set ts=8 sw=8 noexpandtab: */