39 #include "settings.h" |
39 #include "settings.h" |
40 #include "logprint.h" |
40 #include "logprint.h" |
41 |
41 |
42 // Completion structure |
42 // Completion structure |
43 typedef struct { |
43 typedef struct { |
44 GSList *list; // list of matches |
44 GList *list; // list of matches |
45 guint len_prefix; // length of text already typed by the user |
45 guint len_prefix; // length of text already typed by the user |
46 guint len_compl; // length of the last completion |
46 guint len_compl; // length of the last completion |
47 GSList *next; // pointer to next completion to try |
47 GList *next; // pointer to next completion to try |
48 } compl; |
48 } compl; |
49 |
49 |
50 typedef GSList *(*compl_handler_t) (void); // XXX userdata? *dynlist? |
50 typedef GSList *(*compl_handler_t) (void); // XXX userdata? *dynlist? |
51 |
51 |
52 // Category structure |
52 // Category structure |
231 if (suffix) |
231 if (suffix) |
232 compval = g_strdup_printf("%s%s", word+len, suffix); |
232 compval = g_strdup_printf("%s%s", word+len, suffix); |
233 else |
233 else |
234 compval = g_strdup(word+len); |
234 compval = g_strdup(word+len); |
235 // for a bit of efficiency, will reverse order afterwards |
235 // for a bit of efficiency, will reverse order afterwards |
236 c->list = g_slist_prepend(c->list, compval); |
236 c->list = g_list_prepend(c->list, compval); |
237 ret_len ++; |
237 ret_len ++; |
238 } |
238 } |
239 } |
239 } |
240 } |
240 } |
241 c->next = c->list = g_slist_reverse (c->list); |
241 c->list = g_list_reverse(c->list); |
|
242 c->next = NULL; |
242 InputCompl = c; |
243 InputCompl = c; |
243 return ret_len; |
244 return ret_len; |
244 } |
245 } |
245 |
246 |
246 // done_completion(); |
247 // done_completion(); |
247 void done_completion(void) |
248 void done_completion(void) |
248 { |
249 { |
249 GSList *clp; |
250 GList *clp; |
250 |
251 |
251 if (!InputCompl) return; |
252 if (!InputCompl) return; |
252 |
253 |
253 // Free the current completion list |
254 // Free the current completion list |
254 for (clp = InputCompl->list; clp; clp = g_slist_next(clp)) |
255 for (clp = InputCompl->list; clp; clp = g_list_next(clp)) |
255 g_free(clp->data); |
256 g_free(clp->data); |
256 g_slist_free(InputCompl->list); |
257 g_list_free(InputCompl->list); |
257 g_free(InputCompl); |
258 g_free(InputCompl); |
258 InputCompl = NULL; |
259 InputCompl = NULL; |
259 } |
260 } |
260 |
261 |
261 // cancel_completion() |
262 // cancel_completion() |
265 if (!InputCompl) return 0; |
266 if (!InputCompl) return 0; |
266 return InputCompl->len_compl; |
267 return InputCompl->len_compl; |
267 } |
268 } |
268 |
269 |
269 // Returns pointer to text to insert, NULL if no completion. |
270 // Returns pointer to text to insert, NULL if no completion. |
270 const char *complete() |
271 const char *complete(gboolean fwd) |
271 { |
272 { |
272 compl* c = InputCompl; |
273 compl* c = InputCompl; |
273 char *r; |
274 char *r; |
274 |
275 |
275 if (!InputCompl) return NULL; |
276 if (!InputCompl) return NULL; |
276 |
277 |
277 if (!c->next) { |
278 if (!c->next) { |
278 c->next = c->list; // back to the beginning |
279 if (fwd) |
|
280 c->next = c->list; // back to the beginning |
|
281 else |
|
282 c->next = g_list_last(c->list); // back to the ending |
|
283 } else { |
|
284 if (fwd) |
|
285 c->next = g_list_next(c->next); |
|
286 else |
|
287 c->next = g_list_previous(c->next); |
|
288 } |
|
289 |
|
290 if (!c->next) { |
|
291 c->next = NULL; |
279 c->len_compl = 0; |
292 c->len_compl = 0; |
280 return NULL; |
293 return NULL; |
281 } |
294 } |
|
295 |
282 r = (char*)c->next->data; |
296 r = (char*)c->next->data; |
283 c->next = g_slist_next(c->next); |
297 |
284 if (!utf8_mode) { |
298 if (!utf8_mode) { |
285 c->len_compl = strlen(r); |
299 c->len_compl = strlen(r); |
286 } else { |
300 } else { |
287 char *wc; |
301 char *wc; |
288 c->len_compl = 0; |
302 c->len_compl = 0; |