Mercurial > ~mikael > mcabber > hg
comparison mcabber/mcabber/compl.c @ 1922:4ba68ad737bc
Increase the number of available categories for completions
author | Mikael Berthe <mikael@lilotux.net> |
---|---|
date | Wed, 10 Nov 2010 14:08:24 +0100 |
parents | 057b514b1f12 |
children | 924f4552996c |
comparison
equal
deleted
inserted
replaced
1921:7d72b7d2d93a | 1922:4ba68ad737bc |
---|---|
34 | 34 |
35 #include "compl.h" | 35 #include "compl.h" |
36 #include "utf8.h" | 36 #include "utf8.h" |
37 #include "roster.h" | 37 #include "roster.h" |
38 #include "events.h" | 38 #include "events.h" |
39 #include "logprint.h" | |
39 | 40 |
40 // Completion structure | 41 // Completion structure |
41 typedef struct { | 42 typedef struct { |
42 GSList *list; // list of matches | 43 GSList *list; // list of matches |
43 guint len_prefix; // length of text already typed by the user | 44 guint len_prefix; // length of text already typed by the user |
45 GSList *next; // pointer to next completion to try | 46 GSList *next; // pointer to next completion to try |
46 } compl; | 47 } compl; |
47 | 48 |
48 // Category structure | 49 // Category structure |
49 typedef struct { | 50 typedef struct { |
50 guint flag; | 51 guint64 flag; |
51 GSList *words; | 52 GSList *words; |
52 } category; | 53 } category; |
53 | 54 |
54 static GSList *Categories; | 55 static GSList *Categories; |
55 static compl *InputCompl; | 56 static compl *InputCompl; |
56 | 57 |
57 #ifdef MODULES_ENABLE | 58 #ifdef MODULES_ENABLE |
58 guint registered_cats = COMPL_CMD|COMPL_JID|COMPL_URLJID|COMPL_NAME| \ | 59 static guint64 registered_cats; |
59 COMPL_STATUS|COMPL_FILENAME|COMPL_ROSTER|COMPL_BUFFER| \ | 60 |
60 COMPL_GROUP|COMPL_GROUPNAME|COMPL_MULTILINE|COMPL_ROOM| \ | 61 static inline void register_builtin_cat(guint c) { |
61 COMPL_RESOURCE|COMPL_AUTH|COMPL_REQUEST|COMPL_EVENTS| \ | 62 registered_cats |= 1UL << (c-1); |
62 COMPL_EVENTSID|COMPL_PGP|COMPL_COLOR| \ | 63 } |
63 COMPL_OTR|COMPL_OTRPOLICY| \ | 64 |
64 0; | 65 void compl_init_system(void) |
66 { | |
67 // Builtin completion categories: | |
68 register_builtin_cat(COMPL_CMD); | |
69 register_builtin_cat(COMPL_JID); | |
70 register_builtin_cat(COMPL_URLJID); | |
71 register_builtin_cat(COMPL_NAME); | |
72 register_builtin_cat(COMPL_STATUS); | |
73 register_builtin_cat(COMPL_FILENAME); | |
74 register_builtin_cat(COMPL_ROSTER); | |
75 register_builtin_cat(COMPL_BUFFER); | |
76 register_builtin_cat(COMPL_GROUP); | |
77 register_builtin_cat(COMPL_GROUPNAME); | |
78 register_builtin_cat(COMPL_MULTILINE); | |
79 register_builtin_cat(COMPL_ROOM); | |
80 register_builtin_cat(COMPL_RESOURCE); | |
81 register_builtin_cat(COMPL_AUTH); | |
82 register_builtin_cat(COMPL_REQUEST); | |
83 register_builtin_cat(COMPL_EVENTS); | |
84 register_builtin_cat(COMPL_EVENTSID); | |
85 register_builtin_cat(COMPL_PGP); | |
86 register_builtin_cat(COMPL_COLOR); | |
87 register_builtin_cat(COMPL_OTR); | |
88 register_builtin_cat(COMPL_OTRPOLICY); | |
89 } | |
65 | 90 |
66 // compl_new_category() | 91 // compl_new_category() |
67 // Reserves id for new completion category. | 92 // Reserves id for new completion category. |
68 // Returns 0, if no more categories can be allocated. | 93 // Returns 0, if no more categories can be allocated. |
69 // Note, that user should not make any assumptions about id nature, | 94 // Note, that user should not make any assumptions about id nature, |
71 guint compl_new_category(void) | 96 guint compl_new_category(void) |
72 { | 97 { |
73 guint i = 0; | 98 guint i = 0; |
74 while ((registered_cats >> i) & 1) | 99 while ((registered_cats >> i) & 1) |
75 i++; | 100 i++; |
76 if (i >= 8 * sizeof (guint)) | 101 if (i >= 8 * sizeof (registered_cats)) |
77 return 0; | 102 return 0; |
78 else { | 103 else { |
79 guint id = 1 << i; | 104 guint64 id = 1 << i; |
80 registered_cats |= id; | 105 registered_cats |= id; |
81 return id; | 106 return i+1; |
82 } | 107 } |
83 } | 108 } |
84 | 109 |
85 // compl_del_category(id) | 110 // compl_del_category(id) |
86 // Frees reserved id for category. | 111 // Frees reserved id for category. |
87 // Note, that for now it not validates its input, so, be careful | 112 // Note, that for now it not validates its input, so, be careful |
88 // and specify exactly what you get from compl_new_category. | 113 // and specify exactly what you get from compl_new_category. |
89 void compl_del_category(guint id) | 114 void compl_del_category(guint id) |
90 { | 115 { |
91 registered_cats &= ~id; | 116 if (!id) { |
117 scr_log_print(LPRINT_LOGNORM, "Error: compl_del_category() - " | |
118 "Invalid category."); | |
119 return; | |
120 } | |
121 id--; | |
122 registered_cats &= ~(1<<id); | |
92 } | 123 } |
93 #endif | 124 #endif |
94 | 125 |
95 // new_completion(prefix, compl_cat, suffix) | 126 // new_completion(prefix, compl_cat, suffix) |
96 // . prefix = beginning of the word, typed by the user | 127 // . prefix = beginning of the word, typed by the user |
184 | 215 |
185 // compl_add_category_word(categ, command) | 216 // compl_add_category_word(categ, command) |
186 // Adds a keyword as a possible completion in category categ. | 217 // Adds a keyword as a possible completion in category categ. |
187 void compl_add_category_word(guint categ, const gchar *word) | 218 void compl_add_category_word(guint categ, const gchar *word) |
188 { | 219 { |
220 guint64 catv; | |
189 GSList *sl_cat; | 221 GSList *sl_cat; |
190 category *cat; | 222 category *cat; |
191 char *nword; | 223 char *nword; |
224 | |
225 if (!categ) { | |
226 scr_log_print(LPRINT_LOGNORM, "Error: compl_add_category_word() - " | |
227 "Invalid category."); | |
228 return; | |
229 } | |
230 | |
231 categ--; | |
232 catv = 1UL << categ; | |
233 | |
192 // Look for category | 234 // Look for category |
193 for (sl_cat=Categories; sl_cat; sl_cat = g_slist_next(sl_cat)) { | 235 for (sl_cat=Categories; sl_cat; sl_cat = g_slist_next(sl_cat)) { |
194 if (categ == ((category*)sl_cat->data)->flag) | 236 if (catv == ((category*)sl_cat->data)->flag) |
195 break; | 237 break; |
196 } | 238 } |
197 if (!sl_cat) { // Category not found, let's create it | 239 if (!sl_cat) { // Category not found, let's create it |
198 cat = g_new0(category, 1); | 240 cat = g_new0(category, 1); |
199 cat->flag = categ; | 241 cat->flag = catv; |
200 Categories = g_slist_append(Categories, cat); | 242 Categories = g_slist_append(Categories, cat); |
201 } else | 243 } else |
202 cat = (category*)sl_cat->data; | 244 cat = (category*)sl_cat->data; |
203 | 245 |
204 // If word is not space-terminated, we add one trailing space | 246 // If word is not space-terminated, we add one trailing space |
220 | 262 |
221 // compl_del_category_word(categ, command) | 263 // compl_del_category_word(categ, command) |
222 // Removes a keyword from category categ in completion list. | 264 // Removes a keyword from category categ in completion list. |
223 void compl_del_category_word(guint categ, const gchar *word) | 265 void compl_del_category_word(guint categ, const gchar *word) |
224 { | 266 { |
267 guint64 catv; | |
225 GSList *sl_cat, *sl_elt; | 268 GSList *sl_cat, *sl_elt; |
226 category *cat; | 269 category *cat; |
227 char *nword; | 270 char *nword; |
271 | |
272 if (!categ) { | |
273 scr_log_print(LPRINT_LOGNORM, "Error: compl_del_category_word() - " | |
274 "Invalid category."); | |
275 return; | |
276 } | |
277 | |
278 categ--; | |
279 catv = 1UL << categ; | |
280 | |
228 // Look for category | 281 // Look for category |
229 for (sl_cat=Categories; sl_cat; sl_cat = g_slist_next(sl_cat)) { | 282 for (sl_cat=Categories; sl_cat; sl_cat = g_slist_next(sl_cat)) { |
230 if (categ == ((category*)sl_cat->data)->flag) | 283 if (catv == ((category*)sl_cat->data)->flag) |
231 break; | 284 break; |
232 } | 285 } |
233 if (!sl_cat) return; // Category not found, finished! | 286 if (!sl_cat) return; // Category not found, finished! |
234 | 287 |
235 cat = (category*)sl_cat->data; | 288 cat = (category*)sl_cat->data; |
254 sl_elt = g_slist_next(sl_elt); | 307 sl_elt = g_slist_next(sl_elt); |
255 } | 308 } |
256 } | 309 } |
257 | 310 |
258 // compl_get_category_list() | 311 // compl_get_category_list() |
259 // Returns a slist of all words in the categories specified by the given flags | 312 // Returns a slist of all words in the specified categorie. |
260 // Iff this function sets *dynlist to TRUE, then the caller must free the | 313 // Iff this function sets *dynlist to TRUE, then the caller must free the |
261 // whole list after use. | 314 // whole list after use. |
262 GSList *compl_get_category_list(guint cat_flags, guint *dynlist) | 315 GSList *compl_get_category_list(guint categ, guint *dynlist) |
263 { | 316 { |
317 guint64 cat_flags; | |
264 GSList *sl_cat; | 318 GSList *sl_cat; |
265 | 319 |
320 if (!categ) { | |
321 scr_log_print(LPRINT_LOGNORM, "Error: compl_get_category_list() - " | |
322 "Invalid category."); | |
323 return NULL; | |
324 } | |
325 | |
266 *dynlist = FALSE; | 326 *dynlist = FALSE; |
267 | 327 cat_flags = 1UL << (categ - 1); |
268 // Look for category | 328 |
269 // XXX Actually that's not that simple... cat_flags can be a combination | 329 // Look for the category |
270 // of several flags! | |
271 for (sl_cat=Categories; sl_cat; sl_cat = g_slist_next(sl_cat)) { | 330 for (sl_cat=Categories; sl_cat; sl_cat = g_slist_next(sl_cat)) { |
272 if (cat_flags == ((category*)sl_cat->data)->flag) | 331 if (cat_flags == ((category*)sl_cat->data)->flag) |
273 break; | 332 break; |
274 } | 333 } |
275 if (sl_cat) // Category was found, easy... | 334 if (sl_cat) // Category was found, easy... |
276 return ((category*)sl_cat->data)->words; | 335 return ((category*)sl_cat->data)->words; |
277 | 336 |
278 // Handle dynamic SLists | 337 // Handle dynamic SLists |
279 *dynlist = TRUE; | 338 *dynlist = TRUE; |
280 if (cat_flags == COMPL_GROUPNAME) { | 339 if (categ == COMPL_GROUPNAME) { |
281 return compl_list(ROSTER_TYPE_GROUP); | 340 return compl_list(ROSTER_TYPE_GROUP); |
282 } | 341 } |
283 if (cat_flags == COMPL_JID) { | 342 if (categ == COMPL_JID) { |
284 return compl_list(ROSTER_TYPE_USER); | 343 return compl_list(ROSTER_TYPE_USER); |
285 } | 344 } |
286 if (cat_flags == COMPL_RESOURCE) { | 345 if (categ == COMPL_RESOURCE) { |
287 return buddy_getresources_locale(NULL); | 346 return buddy_getresources_locale(NULL); |
288 } | 347 } |
289 if (cat_flags == COMPL_EVENTSID) { | 348 if (categ == COMPL_EVENTSID) { |
290 GSList *compl = evs_geteventslist(); | 349 GSList *compl = evs_geteventslist(); |
291 GSList *cel; | 350 GSList *cel; |
292 for (cel = compl; cel; cel = cel->next) | 351 for (cel = compl; cel; cel = cel->next) |
293 cel->data = g_strdup(cel->data); | 352 cel->data = g_strdup(cel->data); |
294 compl = g_slist_append(compl, g_strdup("list")); | 353 compl = g_slist_append(compl, g_strdup("list")); |