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_HELP_KEYMAP
) {
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
), 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_HELP_KEYMAP
) {
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
), 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_HELP_KEYMAP
) ||
156 iterator
->keymap
->hidden
)
160 if (iterator
->group
!= group
) {
161 iterator
->group
= group
;
162 if (!add_help_line(iterator
->view
, &help
, iterator
->keymap
, LINE_HELP_GROUP
))
164 help
->data
.text
= group
;
171 help_open_keymap(void *data
, const struct request_info
*req_info
, const char *group
)
173 struct help_request_iterator
*iterator
= data
;
174 struct help_state
*state
= iterator
->view
->private;
175 struct keymap
*keymap
= iterator
->keymap
;
176 const char *key
= get_keys(keymap
, req_info
->request
, TRUE
);
179 if (req_info
->request
== REQ_NONE
|| !key
|| !*key
)
182 if (!add_help_headers(iterator
, group
) ||
183 !add_help_line(iterator
->view
, &help
, iterator
->keymap
, LINE_DEFAULT
))
186 state
->keys_width
= MAX(state
->keys_width
, strlen(key
));
187 state
->name_width
= MAX(state
->name_width
, strlen(enum_name(*req_info
)));
189 help
->data
.req_info
= req_info
;
190 help
->request
= req_info
->request
;
196 help_open_keymap_run_requests(struct help_request_iterator
*iterator
, bool internal
)
198 struct view
*view
= iterator
->view
;
199 struct help_state
*state
= view
->private;
200 struct keymap
*keymap
= iterator
->keymap
;
201 const char *group
= internal
? "Internal commands: " : "External commands:";
202 enum request request
= REQ_RUN_REQUESTS
+ 1;
205 for (; TRUE
; request
++) {
206 struct run_request
*req
= get_run_request(request
);
212 if (req
->flags
.internal
!= !!internal
||
213 req
->keymap
!= keymap
||
214 !*(key
= get_keys(keymap
, request
, TRUE
)))
217 if (!add_help_headers(iterator
, group
) ||
218 !add_help_line(view
, &help
, keymap
, LINE_DEFAULT
))
221 state
->keys_width
= MAX(state
->keys_width
, strlen(key
));
223 help
->request
= request
;
228 help_open(struct view
*view
, enum open_flags flags
)
230 struct keymap
*keymap
;
236 if (!add_help_line(view
, &help
, NULL
, LINE_DEFAULT
))
238 help
->data
.text
= "Quick reference for tig keybindings:";
240 if (!add_help_line(view
, &help
, NULL
, LINE_DEFAULT
))
242 help
->data
.text
= "";
244 for (i
= 0; (keymap
= get_keymap_by_index(i
)); i
++) {
245 struct help_request_iterator iterator
= { view
, keymap
, TRUE
};
247 if (foreach_request(help_open_keymap
, &iterator
)) {
248 help_open_keymap_run_requests(&iterator
, TRUE
);
249 help_open_keymap_run_requests(&iterator
, FALSE
);
257 help_request(struct view
*view
, enum request request
, struct line
*line
)
259 struct help
*help
= line
->data
;
263 if (line
->type
== LINE_HELP_KEYMAP
) {
264 struct keymap
*keymap
= help
->keymap
;
266 keymap
->hidden
= !keymap
->hidden
;
281 help_select(struct view
*view
, struct line
*line
)
285 static struct view_ops help_ops
= {
289 sizeof(struct help_state
),
301 /* vim: set ts=8 sw=8 noexpandtab: */