comparison mcabber/mcabber/compl.c @ 2143:2f294c2b6778

Add a backward completion (Oleg) When we skip some needed item with tab, we can back with shift+tab.
author Mikael Berthe <mikael@lilotux.net>
date Sun, 06 Jul 2014 14:51:17 +0200
parents fc7a758ebbde
children f5402d705f67
comparison
equal deleted inserted replaced
2142:0e8a25503ee1 2143:2f294c2b6778
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;