2 * ion/mod_query/complete.c
4 * Copyright (c) Tuomo Valkonen 1999-2007.
6 * Ion is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
17 #include <libtu/objp.h>
18 #include <ioncore/common.h>
24 /*{{{ Completion list processing */
27 static int str_common_part_l(const char *p1, const char *p2)
32 if(*p1=='\0' || *p1!=*p2)
41 /* Get length of part common to all completions
42 * and remove duplicates
44 static int get_common_part_rmdup(char **completions, int *ncomp)
46 int i, j, c=INT_MAX, c2;
48 for(i=0, j=1; j<*ncomp; j++){
49 c2=str_common_part_l(completions[i], completions[j]);
53 if(completions[i][c2]=='\0' && completions[j][c2]=='\0'){
60 completions[i]=completions[j];
70 static int compare(const void *p1, const void *p2)
72 const char **v1, **v2;
76 return strcoll(*v1, *v2);
80 static void edln_reset(Edln *edln)
82 assert(edln->palloced>=1);
92 static void edln_do_set_completion(Edln *edln, const char *comp, int len,
93 const char *beg, const char *end)
98 edln_insstr_n(edln, beg, strlen(beg), FALSE, TRUE);
101 edln_insstr_n(edln, comp, len, FALSE, TRUE);
104 edln_insstr_n(edln, end, strlen(end), FALSE, FALSE);
106 if(edln->ui_update!=NULL){
107 edln->ui_update(edln->uiptr, 0,
108 EDLN_UPDATE_MOVED|EDLN_UPDATE_CHANGED|
115 void edln_set_completion(Edln *edln, const char *comp,
116 const char *beg, const char *end)
118 edln_do_set_completion(edln, comp, strlen(comp), beg, end);
122 int edln_do_completions(Edln *edln, char **completions, int ncomp,
123 const char *beg, const char *end, bool setcommon,
132 len=strlen(completions[0]);
135 qsort(completions, ncomp, sizeof(char**), compare);
136 len=get_common_part_rmdup(completions, &ncomp);
140 edln_do_set_completion(edln, completions[0], len, beg, end);
152 bool complproxy_init(WComplProxy *proxy, WEdln *wedln, int id, int cycle)
154 watch_init(&(proxy->wedln_watch));
155 if(!watch_setup(&(proxy->wedln_watch), (Obj*)wedln, NULL))
165 WComplProxy *create_complproxy(WEdln *wedln, int id, int cycle)
167 CREATEOBJ_IMPL(WComplProxy, complproxy, (p, wedln, id, cycle));
171 void complproxy_deinit(WComplProxy *proxy)
173 watch_reset(&(proxy->wedln_watch));
178 * Set completion list of the \type{WEdln} that \var{proxy} refers to to
179 * \var{compls}, if it is still waiting for this completion run. The
180 * numerical indexes of \var{compls} list the found completions. If the
181 * entry \var{common_beg} (\var{common_end}) exists, it gives an extra
182 * common prefix (suffix) of all found completions.
185 bool complproxy_set_completions(WComplProxy *proxy, ExtlTab compls)
187 WEdln *wedln=(WEdln*)proxy->wedln_watch.obj;
190 if(wedln->compl_waiting_id==proxy->id){
191 wedln_set_completions(wedln, compls, proxy->cycle);
192 wedln->compl_current_id=proxy->id;
202 IMPLCLASS(WComplProxy, Obj, complproxy_deinit, NULL);