completion-sorting.diff
changeset 51 5e5992999357
parent 50 1c5d368913c9
child 52 887f44e99aa1
equal deleted inserted replaced
50:1c5d368913c9 51:5e5992999357
     1 # HG changeset patch
     1 # HG changeset patch
     2 # Parent 3c7cebacae165329047f6859c26224e9c8a67807
     2 # Parent f8958ab545ac1af3e3fbc3b3b025de66fd1ffa51
     3 Make completion sorting order configurable
     3 Make completion sorting order configurable
     4 
     4 
     5   * Use allocated plain array for categories
     5   * Use allocated plain array for categories
     6   * Use callbacks for dynamic completions (private for now)
     6   * Use callbacks for dynamic completions (private for now)
     7   * Add compl_set_flags() to allow user to set completion order
     7   * Add compl_set_flags() to allow user to set completion order
     8   * [todo] Test ordering
     8   * [todo] Test ordering
     9   * [todo] Bump API (compatibly)
     9   * [todo] Bump API (compatibly)
    10   * [todo] Reallocate array, when need more completions
    10   * [todo] Reallocate array, when need more completions
    11   * [todo] Design and publish interface to dynamic completion cbs
    11   * [todo] Design and publish interface to dynamic completion cbs
    12 
    12 
    13 diff -r 3c7cebacae16 mcabber/mcabber/compl.c
    13 diff -r f8958ab545ac mcabber/mcabber/compl.c
    14 --- a/mcabber/mcabber/compl.c	Wed Oct 17 02:33:43 2012 +0300
    14 --- a/mcabber/mcabber/compl.c	Mon Oct 15 19:53:02 2012 +0200
    15 +++ b/mcabber/mcabber/compl.c	Wed Oct 17 03:00:30 2012 +0300
    15 +++ b/mcabber/mcabber/compl.c	Thu Oct 18 00:00:39 2012 +0300
    16 @@ -2,7 +2,7 @@
    16 @@ -2,7 +2,7 @@
    17   * compl.c      -- Completion system
    17   * compl.c      -- Completion system
    18   *
    18   *
    19   * Copyright (C) 2005-2010 Mikael Berthe <mikael@lilotux.net>
    19   * Copyright (C) 2005-2010 Mikael Berthe <mikael@lilotux.net>
    20 - * Copyright (C) 2009,2010 Myhailo Danylenko <isbear@ukrpost.net>
    20 - * Copyright (C) 2009,2010 Myhailo Danylenko <isbear@ukrpost.net>
    21 + * Copyright (C) 2009-2012 Myhailo Danylenko <isbear@ukrpost.net>
    21 + * Copyright (C) 2009-2012 Myhailo Danylenko <isbear@ukrpost.net>
    22   *
    22   *
    23   * This program is free software; you can redistribute it and/or modify
    23   * This program is free software; you can redistribute it and/or modify
    24   * it under the terms of the GNU General Public License as published by
    24   * it under the terms of the GNU General Public License as published by
    25 @@ -47,49 +47,96 @@
    25 @@ -47,49 +47,97 @@
    26    GSList *next;         // pointer to next completion to try
    26    GSList *next;         // pointer to next completion to try
    27  } compl;
    27  } compl;
    28  
    28  
    29 +typedef GSList *(*compl_handler_t) (void); // XXX userdata? *dynlist?
    29 +typedef GSList *(*compl_handler_t) (void); // XXX userdata? *dynlist?
    30 +
    30 +
    78 +  compl = g_slist_append(compl, g_strdup("list"));
    78 +  compl = g_slist_append(compl, g_strdup("list"));
    79 +  return compl;
    79 +  return compl;
    80 +}
    80 +}
    81 +  
    81 +  
    82 +static inline void register_builtin_cat(guint c, compl_handler_t dynamic) {
    82 +static inline void register_builtin_cat(guint c, compl_handler_t dynamic) {
    83 +  Categories[c-1].flags = COMPL_CAT_BUILTIN | COMPL_CAT_ACTIVE;
    83 +  Categories[c-1].flags   = COMPL_CAT_BUILTIN | COMPL_CAT_ACTIVE;
       
    84 +  Categories[c-1].words   = NULL;
       
    85 +  Categories[c-1].dynamic = dynamic;
    84 +  if (dynamic != NULL) {
    86 +  if (dynamic != NULL) {
    85 +    Categories[c-1].flags |= COMPL_CAT_DYNAMIC;
    87 +    Categories[c-1].flags |= COMPL_CAT_DYNAMIC;
    86 +    Categories[c-1].dynamic = dynamic;
       
    87 +  }
    88 +  }
    88  }
    89  }
    89  
    90  
    90  void compl_init_system(void)
    91  void compl_init_system(void)
    91  {
    92  {
    92 +#ifdef MODULES_ENABLE
    93 +#ifdef MODULES_ENABLE
    93 +  num_categories = 64; // XXX
    94 +  num_categories = 64; // XXX
    94 +#else
    95 +#else
    95 +  num_categories = COMPL_MODULE;
    96 +  num_categories = COMPL_MODULE;
    96 +#endif
    97 +#endif
    97 +  Categories = g_new0(category, num_categories);
    98 +  Categories = g_new(category, num_categories);
    98 +
    99 +
    99    // Builtin completion categories:
   100    // Builtin completion categories:
   100 -  register_builtin_cat(COMPL_CMD);
   101 -  register_builtin_cat(COMPL_CMD);
   101 -  register_builtin_cat(COMPL_JID);
   102 -  register_builtin_cat(COMPL_JID);
   102 -  register_builtin_cat(COMPL_URLJID);
   103 -  register_builtin_cat(COMPL_URLJID);
   145  
   146  
   146 +#ifdef MODULES_ENABLE
   147 +#ifdef MODULES_ENABLE
   147  //  compl_new_category()
   148  //  compl_new_category()
   148  // Reserves id for new completion category.
   149  // Reserves id for new completion category.
   149  // Returns 0, if no more categories can be allocated.
   150  // Returns 0, if no more categories can be allocated.
   150 @@ -97,32 +144,68 @@
   151 @@ -97,32 +145,87 @@
   151  // as it is likely to change in future.
   152  // as it is likely to change in future.
   152  guint compl_new_category(void)
   153  guint compl_new_category(void)
   153  {
   154  {
   154 -  const guint maxcat = 8 * sizeof (registered_cats);
   155 -  const guint maxcat = 8 * sizeof (registered_cats);
   155    guint i = 0;
   156    guint i = 0;
   166 +      Categories[i].flags = COMPL_CAT_ACTIVE;
   167 +      Categories[i].flags = COMPL_CAT_ACTIVE;
   167 +      Categories[i].words = NULL;
   168 +      Categories[i].words = NULL;
   168 +      return i+1;
   169 +      return i+1;
   169 +    }
   170 +    }
   170    }
   171    }
   171 +  // XXX realloc
   172 +  {
   172 +  scr_log_print(LPRINT_LOGNORM, "Warning: run out of completion categories!");
   173 +    guint new_num = num_categories + 16; // *2?
       
   174 +    category *new_categories = g_try_renew(category, Categories, new_num);
       
   175 +    if (new_categories) {
       
   176 +      Categories     = new_categories;
       
   177 +      num_categories = new_num;
       
   178 +      Categories[i].flags = COMPL_CAT_ACTIVE;
       
   179 +      Categories[i].words = NULL;
       
   180 +      return i+1;
       
   181 +    } else
       
   182 +      scr_log_print(LPRINT_LOGNORM, "Warning: Unable to reallocate "
       
   183 +                    "more memory for completion categories!");
       
   184 +  }
   173 +  return 0;
   185 +  return 0;
   174  }
   186  }
   175  
   187  
   176  //  compl_del_category(id)
   188  //  compl_del_category(id)
   177  // Frees reserved id for category.
   189  // Frees reserved id for category.
   179  // and specify exactly what you get from compl_new_category.
   191  // and specify exactly what you get from compl_new_category.
   180 -void compl_del_category(guint id)
   192 -void compl_del_category(guint id)
   181 +void compl_del_category(guint compl)
   193 +void compl_del_category(guint compl)
   182  {
   194  {
   183 -  if (!id) {
   195 -  if (!id) {
       
   196 -    scr_log_print(LPRINT_LOGNORM, "Error: compl_del_category() - "
       
   197 -                  "Invalid category.");
       
   198 +  GSList *wel;
       
   199 +
   184 +  if (!compl) {
   200 +  if (!compl) {
   185      scr_log_print(LPRINT_LOGNORM, "Error: compl_del_category() - "
   201 +    scr_log_print(LPRINT_DEBUG, "Error: compl_del_category() - "
   186 -                  "Invalid category.");
   202 +                                "Invalid category.");
   187 +                                  "Invalid category.");
       
   188      return;
   203      return;
   189    }
   204    }
   190 -  id--;
   205 -  id--;
   191 -  registered_cats &= ~(1<<id);
   206 -  registered_cats &= ~(1<<id);
       
   207 +
   192 +  compl--;
   208 +  compl--;
       
   209 +
   193 +  if ((compl >= num_categories) ||
   210 +  if ((compl >= num_categories) ||
   194 +      (Categories[compl].flags & COMPL_CAT_BUILTIN)) {
   211 +      (Categories[compl].flags & COMPL_CAT_BUILTIN)) {
   195 +    scr_log_print(LPRINT_DEBUG, "Error: compl_del_category() "
   212 +    scr_log_print(LPRINT_DEBUG, "Error: compl_del_category() "
   196 +                                "Invalid category.");
   213 +                                "Invalid category.");
   197 +    return;
   214 +    return;
   198 +  }
   215 +  }
   199 +
   216 +
   200 +  Categories[compl].flags = 0;
   217 +  Categories[compl].flags = 0;
   201 +  // XXX free words
   218 +  for (wel = Categories[compl].words; wel; wel = g_slist_next (wel))
   202 +}
   219 +    g_free (wel -> data);
   203 +
   220 +  g_slist_free (Categories[compl].words);
   204 +//  compl_set_sorting_order(category,order)
   221 +}
       
   222 +
       
   223 +//  compl_set_flags (category, flags)
   205 +// Sets sorting order for given category.
   224 +// Sets sorting order for given category.
   206 +// In future can be merged with new_category, set more flags,
   225 +// In future can be merged with new_category, set more flags,
   207 +// maybe even set dynamic callback.
   226 +// maybe even set dynamic callback.
   208 +void compl_set_flags(guint compl, guint new_flags)
   227 +void compl_set_flags(guint compl, guint new_flags)
   209 +{
   228 +{
   210 +  if (!compl) {
   229 +  if (!compl) {
   211 +    scr_log_print(LPRINT_LOGNORM, "Error: compl_set_flags() - "
   230 +    scr_log_print(LPRINT_DEBUG, "Error: compl_set_flags() - "
   212 +                                  "Invalid category.");
   231 +                                "Invalid category.");
   213 +    return;
   232 +    return;
   214 +  }
   233 +  }
       
   234 +
   215 +  compl--;
   235 +  compl--;
       
   236 +
   216 +  if (compl < num_categories) {
   237 +  if (compl < num_categories) {
   217 +    guint flags = Categories[compl].flags;
   238 +    guint flags = Categories[compl].flags;
   218 +    if (flags & COMPL_CAT_BUILTIN)
   239 +    if (flags & COMPL_CAT_BUILTIN)
   219 +      scr_log_print(LPRINT_DEBUG, "Error: compl_set_flags() - "
   240 +      scr_log_print(LPRINT_DEBUG, "Error: compl_set_flags() - "
   220 +                                  "Invalid category.");
   241 +                                  "Rejecting builtin category.");
   221 +    else if (!(flags & COMPL_CAT_ACTIVE))
   242 +    else if (!(flags & COMPL_CAT_ACTIVE))
   222 +      scr_log_print(LPRINT_DEBUG, "Error: compl_set_flags() - "
   243 +      scr_log_print(LPRINT_DEBUG, "Error: compl_set_flags() - "
   223 +                                  "Invalid category.");
   244 +                                  "Not existing category.");
   224 +    else
   245 +    else
   225 +      Categories[compl].flags = (flags & ~COMPL_CAT_USERFLAGS)
   246 +      Categories[compl].flags = (flags & ~COMPL_CAT_USERFLAGS)
   226 +        | ((new_flags << 2) & COMPL_CAT_USERFLAGS);
   247 +        | ((new_flags << 2) & COMPL_CAT_USERFLAGS);
   227 +  } else
   248 +  } else
   228 +    scr_log_print(LPRINT_DEBUG, "Error: compl_set_flags() - "
   249 +    scr_log_print(LPRINT_DEBUG, "Error: compl_set_flags() - "
   229 +                                "Invalid category.");
   250 +                                "Not existing category.");
   230  }
   251  }
   231  #endif
   252  #endif
   232  
   253  
   233 @@ -222,13 +305,30 @@
   254 @@ -136,12 +239,15 @@
       
   255  guint new_completion(const char *prefix, GSList *compl_cat, const gchar *suffix)
       
   256  {
       
   257    compl *c;
       
   258 +  guint  ret_len = 0;
       
   259    GSList *sl_cat;
       
   260    gint (*cmp)(const char *s1, const char *s2, size_t n);
       
   261    size_t len = strlen(prefix);
       
   262  
       
   263    if (InputCompl) { // This should not happen, but hey...
       
   264 -    cancel_completion();
       
   265 +    scr_log_print(LPRINT_DEBUG, "Warinng: new_completion() - "
       
   266 +                                "Previous completion exists!");
       
   267 +    done_completion();
       
   268    }
       
   269  
       
   270    if (settings_opt_get_int("completion_ignore_case"))
       
   271 @@ -160,14 +266,15 @@
       
   272            compval = g_strdup_printf("%s%s", word+len, suffix);
       
   273          else
       
   274            compval = g_strdup(word+len);
       
   275 -        c->list = g_slist_insert_sorted(c->list, compval,
       
   276 -                                        (GCompareFunc)g_ascii_strcasecmp);
       
   277 +        // for a bit of efficiency, will reverse order afterwards
       
   278 +        c->list = g_slist_prepend(c->list, compval);
       
   279 +        ret_len ++;
       
   280        }
       
   281      }
       
   282    }
       
   283 -  c->next = c->list;
       
   284 +  c->next = c->list = g_slist_reverse (c->list);
       
   285    InputCompl = c;
       
   286 -  return g_slist_length(c->list);
       
   287 +  return ret_len;
       
   288  }
       
   289  
       
   290  //  done_completion();
       
   291 @@ -222,35 +329,46 @@
   234  
   292  
   235  /* Categories functions */
   293  /* Categories functions */
   236  
   294  
   237 +static gint compl_sort_forward(gconstpointer a, gconstpointer b)
   295 +static gint compl_sort_forward(gconstpointer a, gconstpointer b)
   238 +{
   296 +{
   262 -  GSList *sl_cat;
   320 -  GSList *sl_cat;
   263 -  category *cat;
   321 -  category *cat;
   264    char *nword;
   322    char *nword;
   265  
   323  
   266    if (!categ) {
   324    if (!categ) {
   267 @@ -236,21 +336,15 @@
   325 -    scr_log_print(LPRINT_LOGNORM, "Error: compl_add_category_word() - "
       
   326 +    scr_log_print(LPRINT_DEBUG, "Error: compl_add_category_word() - "
   268                    "Invalid category.");
   327                    "Invalid category.");
   269      return;
   328      return;
   270    }
   329    }
   271 -
   330 -
   272 +  
   331 +  
   276 -  // Look for category
   335 -  // Look for category
   277 -  for (sl_cat=Categories; sl_cat; sl_cat = g_slist_next(sl_cat)) {
   336 -  for (sl_cat=Categories; sl_cat; sl_cat = g_slist_next(sl_cat)) {
   278 -    if (catv == ((category*)sl_cat->data)->flag)
   337 -    if (catv == ((category*)sl_cat->data)->flag)
   279 -      break;
   338 -      break;
   280 +  
   339 +  
   281 +  if ((categ > num_categories) ||
   340 +  if ((categ >= num_categories) ||
   282 +      !(Categories[categ].flags & COMPL_CAT_ACTIVE)) {
   341 +      !(Categories[categ].flags & COMPL_CAT_ACTIVE)) {
   283 +    scr_log_print(LPRINT_LOGNORM, "Error: compl_add_category_word() - "
   342 +    scr_log_print(LPRINT_DEBUG, "Error: compl_add_category_word() - "
   284 +                  "Invalid category.");
   343 +                  "Not existing category.");
   285 +    return;
   344 +    return;
   286    }
   345    }
   287 -  if (!sl_cat) {   // Category not found, let's create it
   346 -  if (!sl_cat) {   // Category not found, let's create it
   288 -    cat = g_new0(category, 1);
   347 -    cat = g_new0(category, 1);
   289 -    cat->flag = catv;
   348 -    cat->flag = catv;
   291 -  } else
   350 -  } else
   292 -    cat = (category*)sl_cat->data;
   351 -    cat = (category*)sl_cat->data;
   293  
   352  
   294    // If word is not space-terminated, we add one trailing space
   353    // If word is not space-terminated, we add one trailing space
   295    for (nword = (char*)word; *nword; nword++)
   354    for (nword = (char*)word; *nword; nword++)
   296 @@ -262,20 +356,28 @@
   355 @@ -262,59 +380,64 @@
   297      nword = g_strdup(word);
   356      nword = g_strdup(word);
   298    }
   357    }
   299  
   358  
   300 -  if (g_slist_find_custom(cat->words, nword, (GCompareFunc)g_strcmp0) != NULL)
   359 -  if (g_slist_find_custom(cat->words, nword, (GCompareFunc)g_strcmp0) != NULL)
   301 -    return;
   360 -    return;
   323  void compl_del_category_word(guint categ, const gchar *word)
   382  void compl_del_category_word(guint categ, const gchar *word)
   324  {
   383  {
   325 -  guint64 catv;
   384 -  guint64 catv;
   326 -  GSList *sl_cat, *sl_elt;
   385 -  GSList *sl_cat, *sl_elt;
   327 -  category *cat;
   386 -  category *cat;
   328 +  GSList *sl_elt;
   387 +  GSList *wel;
   329    char *nword;
   388    char *nword;
   330  
   389  
   331    if (!categ) {
   390    if (!categ) {
   332 @@ -285,16 +387,13 @@
   391 -    scr_log_print(LPRINT_LOGNORM, "Error: compl_del_category_word() - "
       
   392 +    scr_log_print(LPRINT_DEBUG, "Error: compl_del_category_word() - "
       
   393                    "Invalid category.");
       
   394      return;
   333    }
   395    }
   334  
   396  
   335    categ--;
   397    categ--;
   336 -  catv = 1UL << categ;
   398 -  catv = 1UL << categ;
   337  
   399  
   338 -  // Look for category
   400 -  // Look for category
   339 -  for (sl_cat=Categories; sl_cat; sl_cat = g_slist_next(sl_cat)) {
   401 -  for (sl_cat=Categories; sl_cat; sl_cat = g_slist_next(sl_cat)) {
   340 -    if (catv == ((category*)sl_cat->data)->flag)
   402 -    if (catv == ((category*)sl_cat->data)->flag)
   341 -      break;
   403 -      break;
   342 +  if ((categ > num_categories) ||
   404 +  if ((categ >= num_categories) ||
   343 +      !(Categories[categ].flags & COMPL_CAT_ACTIVE)) {
   405 +      !(Categories[categ].flags & COMPL_CAT_ACTIVE)) {
   344 +    scr_log_print(LPRINT_LOGNORM, "Error: compl_del_category_word() - "
   406 +    scr_log_print(LPRINT_DEBUG, "Error: compl_del_category_word() - "
   345 +                  "Invalid category.");
   407 +                  "Not existing category.");
   346 +    return;
   408 +    return;
   347    }
   409    }
   348 -  if (!sl_cat) return;   // Category not found, finished!
   410 -  if (!sl_cat) return;   // Category not found, finished!
   349 -
   411 -
   350 -  cat = (category*)sl_cat->data;
   412 -  cat = (category*)sl_cat->data;
   351  
   413  
   352    // If word is not space-terminated, we add one trailing space
   414    // If word is not space-terminated, we add one trailing space
   353    for (nword = (char*)word; *nword; nword++)
   415    for (nword = (char*)word; *nword; nword++)
   354 @@ -306,11 +405,12 @@
   416      ;
   355      nword = g_strdup(word);
   417    if (nword > word) nword--;
       
   418 -  if (*nword != ' ') {  // Add a space
       
   419 -    nword = g_strdup_printf("%s ", word);
       
   420 -  } else {              // word is fine
       
   421 -    nword = g_strdup(word);
       
   422 +  if (*nword != ' ')  // Add a space
       
   423 +    word = nword = g_strdup_printf("%s ", word);
       
   424 +  else
       
   425 +    nword = NULL;
       
   426 +
       
   427 +  for (wel = Categories[categ].words; wel; wel = g_slist_next (wel)) {
       
   428 +    if (!strcasecmp((char*)wel->data, word)) {
       
   429 +      g_free(wel->data);
       
   430 +      Categories[categ].words = g_slist_delete_link
       
   431 +                                (Categories[categ].words, wel);
       
   432 +      break; // Only remove first occurence
       
   433 +    }
   356    }
   434    }
   357  
   435  
   358 -  sl_elt = cat->words;
   436 -  sl_elt = cat->words;
   359 +  sl_elt = Categories[categ].words;
   437 -  while (sl_elt) {
   360    while (sl_elt) {
   438 -    if (!strcasecmp((char*)sl_elt->data, nword)) {
   361      if (!strcasecmp((char*)sl_elt->data, nword)) {
   439 -      g_free(sl_elt->data);
   362        g_free(sl_elt->data);
       
   363 -      cat->words = g_slist_delete_link(cat->words, sl_elt);
   440 -      cat->words = g_slist_delete_link(cat->words, sl_elt);
   364 +      Categories[categ].words = g_slist_delete_link
   441 -      break; // Only remove first occurence
   365 +                                             (Categories[categ].words, sl_elt);
   442 -    }
   366        break; // Only remove first occurence
   443 -    sl_elt = g_slist_next(sl_elt);
   367      }
   444 -  }
   368      sl_elt = g_slist_next(sl_elt);
   445 +  g_free (nword);
   369 @@ -323,48 +423,28 @@
   446  }
       
   447  
       
   448  //  compl_get_category_list()
       
   449 @@ -323,48 +446,28 @@
   370  // whole list after use.
   450  // whole list after use.
   371  GSList *compl_get_category_list(guint categ, guint *dynlist)
   451  GSList *compl_get_category_list(guint categ, guint *dynlist)
   372  {
   452  {
   373 -  guint64 cat_flags;
   453 -  guint64 cat_flags;
   374 -  GSList *sl_cat;
   454 -  GSList *sl_cat;
   375 -
   455 -
   376    if (!categ) {
   456    if (!categ) {
   377      scr_log_print(LPRINT_LOGNORM, "Error: compl_get_category_list() - "
   457 -    scr_log_print(LPRINT_LOGNORM, "Error: compl_get_category_list() - "
       
   458 +    scr_log_print(LPRINT_DEBUG, "Error: compl_get_category_list() - "
   378                    "Invalid category.");
   459                    "Invalid category.");
   379      return NULL;
   460      return NULL;
   380    }
   461    }
   381  
   462  
   382 -  *dynlist = FALSE;
   463 -  *dynlist = FALSE;
   409 -      cel->data = g_strdup(cel->data);
   490 -      cel->data = g_strdup(cel->data);
   410 -    compl = g_slist_append(compl, g_strdup("list"));
   491 -    compl = g_slist_append(compl, g_strdup("list"));
   411 -    return compl;
   492 -    return compl;
   412 +  if ((categ > num_categories) ||
   493 +  if ((categ > num_categories) ||
   413 +      !(Categories[categ].flags & COMPL_CAT_ACTIVE)) {
   494 +      !(Categories[categ].flags & COMPL_CAT_ACTIVE)) {
   414 +    scr_log_print(LPRINT_LOGNORM, "Error: compl_get_category_list() - "
   495 +    scr_log_print(LPRINT_DEBUG, "Error: compl_get_category_list() - "
   415 +                  "Invalid category.");
   496 +                  "Not existing category.");
   416 +    return NULL;
   497 +    return NULL;
   417    }
   498    }
   418  
   499  
   419 -  *dynlist = FALSE;
   500 -  *dynlist = FALSE;
   420 -  return NULL;
   501 -  return NULL;
   426 +    return Categories[categ].words;
   507 +    return Categories[categ].words;
   427 +  }
   508 +  }
   428  }
   509  }
   429  
   510  
   430  /* vim: set expandtab cindent cinoptions=>2\:2(0 sw=2 ts=2:  For Vim users... */
   511  /* vim: set expandtab cindent cinoptions=>2\:2(0 sw=2 ts=2:  For Vim users... */
   431 diff -r 3c7cebacae16 mcabber/mcabber/compl.h
   512 diff -r f8958ab545ac mcabber/mcabber/compl.h
   432 --- a/mcabber/mcabber/compl.h	Wed Oct 17 02:33:43 2012 +0300
   513 --- a/mcabber/mcabber/compl.h	Mon Oct 15 19:53:02 2012 +0200
   433 +++ b/mcabber/mcabber/compl.h	Wed Oct 17 03:00:30 2012 +0300
   514 +++ b/mcabber/mcabber/compl.h	Thu Oct 18 00:00:39 2012 +0300
   434 @@ -28,10 +28,17 @@
   515 @@ -28,10 +28,17 @@
   435  #define COMPL_OTRPOLICY   21
   516  #define COMPL_OTRPOLICY   21
   436  #define COMPL_MODULE      22
   517  #define COMPL_MODULE      22
   437  
   518  
   438 +void compl_init_system(void); /* private */
   519 +void compl_init_system(void); /* private */
   448  void  compl_del_category(guint id);
   529  void  compl_del_category(guint id);
   449 +void  compl_set_flags(guint id, guint flags);
   530 +void  compl_set_flags(guint id, guint flags);
   450  #endif
   531  #endif
   451  
   532  
   452  void    compl_add_category_word(guint categ, const gchar *command);
   533  void    compl_add_category_word(guint categ, const gchar *command);
   453 diff -r 3c7cebacae16 mcabber/mcabber/main.c
   534 diff -r f8958ab545ac mcabber/mcabber/main.c
   454 --- a/mcabber/mcabber/main.c	Wed Oct 17 02:33:43 2012 +0300
   535 --- a/mcabber/mcabber/main.c	Mon Oct 15 19:53:02 2012 +0200
   455 +++ b/mcabber/mcabber/main.c	Wed Oct 17 03:00:30 2012 +0300
   536 +++ b/mcabber/mcabber/main.c	Thu Oct 18 00:00:39 2012 +0300
   456 @@ -368,13 +368,13 @@
   537 @@ -364,13 +364,13 @@
   457    }
   538    }
   458  
   539  
   459    /* Initialize command system, roster and default key bindings */
   540    /* Initialize command system, roster and default key bindings */
   460 +  compl_init_system();
   541 +  compl_init_system();
   461    cmd_init();
   542    cmd_init();