pass on to the right sub-makefile target
[notion/jeffpc.git] / mod_query / complete.c
blobdb7426bd398857cb877e67000f000668ef445801
1 /*
2 * ion/mod_query/complete.c
4 * Copyright (c) Tuomo Valkonen 1999-2009.
6 * See the included file LICENSE for details.
7 */
9 #include <string.h>
10 #include <ctype.h>
11 #include <string.h>
12 #include <limits.h>
14 #include <libtu/objp.h>
15 #include <ioncore/common.h>
16 #include "complete.h"
17 #include "edln.h"
18 #include "wedln.h"
21 /*{{{ Completion list processing */
24 static int str_common_part_l(const char *p1, const char *p2)
26 int i=0;
28 while(1){
29 if(*p1=='\0' || *p1!=*p2)
30 break;
31 p1++; p2++; i++;
34 return i;
38 /* Get length of part common to all completions
39 * and remove duplicates
41 static int get_common_part_rmdup(char **completions, int *ncomp)
43 int i, j, c=INT_MAX, c2;
45 for(i=0, j=1; j<*ncomp; j++){
46 c2=str_common_part_l(completions[i], completions[j]);
47 if(c2<c)
48 c=c2;
50 if(completions[i][c2]=='\0' && completions[j][c2]=='\0'){
51 free(completions[j]);
52 completions[j]=NULL;
53 continue;
55 i++;
56 if(i!=j){
57 completions[i]=completions[j];
58 completions[j]=NULL;
61 *ncomp=i+1;
63 return c;
67 static int compare(const void *p1, const void *p2)
69 const char **v1, **v2;
71 v1=(const char **)p1;
72 v2=(const char **)p2;
73 return strcoll(*v1, *v2);
77 static void edln_reset(Edln *edln)
79 assert(edln->palloced>=1);
81 edln->p[0]='\0';
82 edln->psize=0;
83 edln->point=0;
84 edln->mark=-1;
85 edln->histent=-1;
89 static void edln_do_set_completion(Edln *edln, const char *comp, int len,
90 const char *beg, const char *end)
92 edln_reset(edln);
94 if(beg!=NULL)
95 edln_insstr_n(edln, beg, strlen(beg), FALSE, TRUE);
97 if(len>0)
98 edln_insstr_n(edln, comp, len, FALSE, TRUE);
100 if(end!=NULL)
101 edln_insstr_n(edln, end, strlen(end), FALSE, FALSE);
103 if(edln->ui_update!=NULL){
104 edln->ui_update(edln->uiptr, 0,
105 EDLN_UPDATE_MOVED|EDLN_UPDATE_CHANGED|
106 EDLN_UPDATE_NEW);
112 void edln_set_completion(Edln *edln, const char *comp,
113 const char *beg, const char *end)
115 edln_do_set_completion(edln, comp, strlen(comp), beg, end);
119 int edln_do_completions(Edln *edln, char **completions, int ncomp,
120 const char *beg, const char *end, bool setcommon,
121 bool nosort)
123 int len;
124 int i;
126 if(ncomp==0){
127 return 0;
128 }else if(ncomp==1){
129 len=strlen(completions[0]);
130 }else{
131 if(!nosort)
132 qsort(completions, ncomp, sizeof(char**), compare);
133 len=get_common_part_rmdup(completions, &ncomp);
136 if(setcommon)
137 edln_do_set_completion(edln, completions[0], len, beg, end);
139 return ncomp;
143 /*}}}*/
146 /*{{{ WComplProxy */
149 bool complproxy_init(WComplProxy *proxy, WEdln *wedln, int id, int cycle)
151 watch_init(&(proxy->wedln_watch));
152 if(!watch_setup(&(proxy->wedln_watch), (Obj*)wedln, NULL))
153 return FALSE;
155 proxy->id=id;
156 proxy->cycle=cycle;
158 return TRUE;
162 WComplProxy *create_complproxy(WEdln *wedln, int id, int cycle)
164 CREATEOBJ_IMPL(WComplProxy, complproxy, (p, wedln, id, cycle));
168 void complproxy_deinit(WComplProxy *proxy)
170 watch_reset(&(proxy->wedln_watch));
174 /*EXTL_DOC
175 * Set completion list of the \type{WEdln} that \var{proxy} refers to to
176 * \var{compls}, if it is still waiting for this completion run. The
177 * numerical indexes of \var{compls} list the found completions. If the
178 * entry \var{common_beg} (\var{common_end}) exists, it gives an extra
179 * common prefix (suffix) of all found completions.
181 EXTL_EXPORT_MEMBER
182 bool complproxy_set_completions(WComplProxy *proxy, ExtlTab compls)
184 WEdln *wedln=(WEdln*)proxy->wedln_watch.obj;
186 if(wedln!=NULL){
187 if(wedln->compl_waiting_id==proxy->id){
188 wedln_set_completions(wedln, compls, proxy->cycle);
189 wedln->compl_current_id=proxy->id;
190 return TRUE;
194 return FALSE;
198 EXTL_EXPORT
199 IMPLCLASS(WComplProxy, Obj, complproxy_deinit, NULL);
202 /*}}}*/