41 typedef struct { |
41 typedef struct { |
42 GList *list; // list of matches |
42 GList *list; // list of matches |
43 guint len_prefix; // length of text already typed by the user |
43 guint len_prefix; // length of text already typed by the user |
44 guint len_compl; // length of the last completion |
44 guint len_compl; // length of the last completion |
45 GList *next; // pointer to next completion to try |
45 GList *next; // pointer to next completion to try |
46 } compl; |
46 } compl_t; |
47 |
47 |
48 typedef GSList *(*compl_handler_t) (void); // XXX userdata? *dynlist? |
48 typedef GSList *(*compl_handler_t) (void); // XXX userdata? *dynlist? |
49 |
49 |
50 // Category structure |
50 // Category structure |
51 typedef struct { |
51 typedef struct { |
52 guint flags; |
52 guint flags; |
53 GSList *words; |
53 GSList *words; |
54 compl_handler_t dynamic; |
54 compl_handler_t dynamic; |
55 } category; |
55 } category_t; |
56 |
56 |
57 #define COMPL_CAT_BUILTIN 0x01 |
57 #define COMPL_CAT_BUILTIN 0x01 |
58 #define COMPL_CAT_ACTIVE 0x02 |
58 #define COMPL_CAT_ACTIVE 0x02 |
59 #define COMPL_CAT_DYNAMIC 0x04 |
59 #define COMPL_CAT_DYNAMIC 0x04 |
60 #define COMPL_CAT_REVERSE 0x10 |
60 #define COMPL_CAT_REVERSE 0x10 |
61 #define COMPL_CAT_NOSORT 0x20 |
61 #define COMPL_CAT_NOSORT 0x20 |
62 |
62 |
63 #define COMPL_CAT_USERFLAGS 0x30 |
63 #define COMPL_CAT_USERFLAGS 0x30 |
64 |
64 |
65 static compl *InputCompl; |
65 static compl_t *InputCompl; |
66 static category *Categories; |
66 static category_t *Categories; |
67 static guint num_categories; |
67 static guint num_categories; |
68 |
68 |
69 // Dynamic completions callbacks |
69 // Dynamic completions callbacks |
70 static GSList *compl_dyn_group (void) |
70 static GSList *compl_dyn_group (void) |
71 { |
71 { |
105 { |
105 { |
106 num_categories = COMPL_MAX_ID; |
106 num_categories = COMPL_MAX_ID; |
107 #ifdef MODULES_ENABLE |
107 #ifdef MODULES_ENABLE |
108 num_categories = ((num_categories / 16) + 1) * 16; |
108 num_categories = ((num_categories / 16) + 1) * 16; |
109 #endif |
109 #endif |
110 Categories = g_new0(category, num_categories); |
110 Categories = g_new0(category_t, num_categories); |
111 |
111 |
112 // Builtin completion categories: |
112 // Builtin completion categories: |
113 register_builtin_cat(COMPL_CMD, NULL); |
113 register_builtin_cat(COMPL_CMD, NULL); |
114 register_builtin_cat(COMPL_JID, compl_dyn_user); |
114 register_builtin_cat(COMPL_JID, compl_dyn_user); |
115 register_builtin_cat(COMPL_URLJID, NULL); |
115 register_builtin_cat(COMPL_URLJID, NULL); |
152 scr_log_print(LPRINT_LOGNORM, "Warning: Too many " |
152 scr_log_print(LPRINT_LOGNORM, "Warning: Too many " |
153 "completion categories!"); |
153 "completion categories!"); |
154 return 0; |
154 return 0; |
155 } |
155 } |
156 num_categories += 16; |
156 num_categories += 16; |
157 Categories = g_renew(category, Categories, num_categories); |
157 Categories = g_renew(category_t, Categories, num_categories); |
158 for (j = i+1; j < num_categories; j++) |
158 for (j = i+1; j < num_categories; j++) |
159 Categories[j].flags = 0; |
159 Categories[j].flags = 0; |
160 } |
160 } |
161 Categories[i].flags = COMPL_CAT_ACTIVE | (flags & COMPL_CAT_USERFLAGS); |
161 Categories[i].flags = COMPL_CAT_ACTIVE | (flags & COMPL_CAT_USERFLAGS); |
162 Categories[i].words = NULL; |
162 Categories[i].words = NULL; |
200 // Set the InputCompl pointer to an allocated compl structure. |
200 // Set the InputCompl pointer to an allocated compl structure. |
201 // done_completion() must be called when finished. |
201 // done_completion() must be called when finished. |
202 // Returns the number of possible completions. |
202 // Returns the number of possible completions. |
203 guint new_completion(const char *prefix, GSList *compl_cat, const gchar *suffix) |
203 guint new_completion(const char *prefix, GSList *compl_cat, const gchar *suffix) |
204 { |
204 { |
205 compl *c; |
205 compl_t *c; |
206 guint ret_len = 0; |
206 guint ret_len = 0; |
207 GSList *sl_cat; |
207 GSList *sl_cat; |
208 gint (*cmp)(const char *s1, const char *s2, size_t n); |
208 gint (*cmp)(const char *s1, const char *s2, size_t n); |
209 size_t len = strlen(prefix); |
209 size_t len = strlen(prefix); |
210 |
210 |
217 if (settings_opt_get_int("completion_ignore_case")) |
217 if (settings_opt_get_int("completion_ignore_case")) |
218 cmp = &strncasecmp; |
218 cmp = &strncasecmp; |
219 else |
219 else |
220 cmp = &strncmp; |
220 cmp = &strncmp; |
221 |
221 |
222 c = g_new0(compl, 1); |
222 c = g_new0(compl_t, 1); |
223 // Build the list of matches |
223 // Build the list of matches |
224 for (sl_cat = compl_cat; sl_cat; sl_cat = g_slist_next(sl_cat)) { |
224 for (sl_cat = compl_cat; sl_cat; sl_cat = g_slist_next(sl_cat)) { |
225 char *word = sl_cat->data; |
225 char *word = sl_cat->data; |
226 if (!cmp(prefix, word, len)) { |
226 if (!cmp(prefix, word, len)) { |
227 if (strlen(word) != len) { |
227 if (strlen(word) != len) { |