3aaca5a173da2155ad2ce16c990d149e55222d94
[scilab.git] / scilab / modules / console / src / c / windows / TermCompletion.c
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2008-2010 - DIGITEO - Allan CORNET
4 *
5 * This file must be used under the terms of the CeCILL.
6 * This source file is licensed as described in the file COPYING, which
7 * you should have received as part of this distribution.  The terms
8 * are also available at
9 * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
10 *
11 */
12
13 /*--------------------------------------------------------------------------*/
14 #include <string.h>
15 #include <stdlib.h>
16 #include "TermCompletion.h"
17 #include "sci_malloc.h"
18 #include "freeArrayOfString.h"
19 #include "localization.h"
20 #include "TermLine.h"
21 #include "TermConsole.h"
22 #include "getPartLine.h"
23 #include "getCommonPart.h"
24 #include "completion.h"
25 #include "scilines.h"
26 #include "os_string.h"
27 #include "completeLine.h"
28 /*--------------------------------------------------------------------------*/
29 static void displayCompletionDictionary(char **dictionary, int sizedictionary, char *namedictionary);
30 static char **concatenateStrings(int *sizearrayofstring, char *string1,
31                                  char *string2, char *string3,
32                                  char *string4, char *string5);
33 static void TermCompletionOnFiles(char **dictionaryFiles, int sizedictionaryFiles,
34                                   char *lineBeforeCaret, char *lineAfterCaret, char *filePattern, char *defaultPattern);
35 static void TermCompletionOnAll(char *lineBeforeCaret, char *lineAfterCaret, char *defaultPattern);
36 /*--------------------------------------------------------------------------*/
37 static void TermCompletionOnFiles(char **dictionaryFiles, int sizedictionaryFiles,
38                                   char *lineBeforeCaret, char *lineAfterCaret, char *filePattern, char *defaultPattern)
39 {
40     if (dictionaryFiles)
41     {
42         if (sizedictionaryFiles == 1)
43         {
44             char *newline = completeLine(lineBeforeCaret, dictionaryFiles[0], filePattern, defaultPattern, TRUE, lineAfterCaret);
45             if (newline)
46             {
47                 clearCurrentLine();
48                 copyLine(newline);
49                 FREE(newline);
50                 return;
51             }
52         }
53         else
54         {
55             char *common = getCommonPart(dictionaryFiles, sizedictionaryFiles);
56
57             displayCompletionDictionary(dictionaryFiles,
58                                         sizedictionaryFiles, gettext("File or Directory"));
59
60             displayPrompt();
61             newLine();
62
63             if (defaultPattern[0] == 0)
64             {
65                 int lennewline = (int)strlen(lineBeforeCaret) + (int)strlen(lineAfterCaret);
66                 char *newline = (char*)MALLOC(sizeof(char) * (lennewline + 1));
67
68                 clearCurrentLine();
69                 if (newline)
70                 {
71                     strcpy(newline, lineBeforeCaret);
72                     strcat(newline, lineAfterCaret);
73                     copyLine(newline);
74                     FREE(newline);
75                     newline = NULL;
76                 }
77             }
78             else if (common)
79             {
80                 char *newline = completeLine(lineBeforeCaret, common, filePattern, defaultPattern, TRUE, lineAfterCaret);
81                 if (newline)
82                 {
83                     clearCurrentLine();
84                     copyLine(newline);
85                     FREE(common);
86                     FREE(newline);
87                     return;
88                 }
89                 else
90                 {
91                     int lennewline = (int)strlen(lineBeforeCaret) + (int)strlen(lineAfterCaret);
92                     newline = (char*)MALLOC(sizeof(char) * (lennewline + 1));
93
94                     clearCurrentLine();
95                     if (newline)
96                     {
97                         strcpy(newline, lineBeforeCaret);
98                         strcat(newline, lineAfterCaret);
99                         copyLine(newline);
100                         FREE(newline);
101                         newline = NULL;
102                     }
103                 }
104                 FREE(common);
105                 common = NULL;
106             }
107         }
108     }
109 }
110 /*--------------------------------------------------------------------------*/
111 static void TermCompletionOnAll(char *lineBeforeCaret, char *lineAfterCaret, char *defaultPattern)
112 {
113     if (defaultPattern)
114     {
115         int numberWordFound = 0;
116         char **completionDictionaryFunctions = NULL;
117         int sizecompletionDictionaryFunctions = 0;
118
119         char **completionDictionaryCommandWords = NULL;
120         int sizecompletionDictionaryCommandWords = 0;
121
122         char **completionDictionaryMacros = NULL;
123         int sizecompletionDictionaryMacros = 0;
124
125         char **completionDictionaryVariables = NULL;
126         int sizecompletionDictionaryVariables = 0;
127
128         char **completionDictionaryHandleGraphicsProperties = NULL;
129         int sizecompletionDictionaryHandleGraphicsProperties = 0;
130
131         char **completionDictionaryFields = NULL;
132         int sizecompletionDictionaryFields = 0;
133
134         completionDictionaryFields = completionOnFields(lineBeforeCaret, defaultPattern, &sizecompletionDictionaryFields);
135
136         if ((completionDictionaryFields == NULL) && strcmp(defaultPattern, ""))
137         {
138             completionDictionaryFunctions = completionOnFunctions(defaultPattern, &sizecompletionDictionaryFunctions);
139             completionDictionaryCommandWords = completionOnCommandWords(defaultPattern, &sizecompletionDictionaryCommandWords);
140             completionDictionaryMacros = completionOnMacros(defaultPattern, &sizecompletionDictionaryMacros);
141             completionDictionaryVariables = completionOnVariablesWithoutMacros(defaultPattern, &sizecompletionDictionaryVariables);
142             completionDictionaryHandleGraphicsProperties = completionOnHandleGraphicsProperties(defaultPattern, &sizecompletionDictionaryHandleGraphicsProperties);
143         }
144         numberWordFound = sizecompletionDictionaryFunctions + sizecompletionDictionaryCommandWords +
145                           sizecompletionDictionaryMacros + sizecompletionDictionaryVariables +
146                           sizecompletionDictionaryHandleGraphicsProperties + sizecompletionDictionaryFields;
147
148         if (numberWordFound > 0)
149         {
150             if (numberWordFound == 1)
151             {
152                 char **completionDictionary = NULL;
153                 char *new_line = NULL;
154
155                 if (completionDictionaryFields)
156                 {
157                     completionDictionary = completionDictionaryFields;
158                 }
159                 if (completionDictionaryFunctions)
160                 {
161                     completionDictionary = completionDictionaryFunctions;
162                 }
163                 if (completionDictionaryCommandWords)
164                 {
165                     completionDictionary = completionDictionaryCommandWords;
166                 }
167                 if (completionDictionaryMacros)
168                 {
169                     completionDictionary = completionDictionaryMacros;
170                 }
171                 if (completionDictionaryVariables)
172                 {
173                     completionDictionary = completionDictionaryVariables;
174                 }
175                 if (completionDictionaryHandleGraphicsProperties)
176                 {
177                     completionDictionary = completionDictionaryHandleGraphicsProperties;
178                 }
179
180                 new_line = completeLine(lineBeforeCaret, completionDictionary[0], NULL, defaultPattern, FALSE, lineAfterCaret);
181                 if (new_line)
182                 {
183                     clearCurrentLine();
184                     copyLine(new_line);
185                     FREE(new_line);
186                 }
187             }
188             else
189             {
190                 char *commonAll = NULL;
191                 if (completionDictionaryFields)
192                 {
193                     commonAll = getCommonPart(completionDictionaryFields, sizecompletionDictionaryFields);
194                     displayCompletionDictionary(completionDictionaryFields, sizecompletionDictionaryFields, (char *)_("Scilab Fields"));
195                     freeArrayOfString(completionDictionaryFields, sizecompletionDictionaryFields);
196                 }
197                 else
198                 {
199                     char *commonFunctions = getCommonPart(completionDictionaryFunctions, sizecompletionDictionaryFunctions);
200                     char *commonCommandWords = getCommonPart(completionDictionaryCommandWords, sizecompletionDictionaryCommandWords);
201                     char *commonMacros = getCommonPart(completionDictionaryMacros, sizecompletionDictionaryMacros);
202                     char *commonVariables = getCommonPart(completionDictionaryVariables, sizecompletionDictionaryVariables);
203                     char *commonHandleGraphicsProperties = getCommonPart(completionDictionaryHandleGraphicsProperties, sizecompletionDictionaryHandleGraphicsProperties);
204
205                     int sizecommonsDictionary = 0;
206                     char **commonsDictionary = concatenateStrings(&sizecommonsDictionary, commonFunctions,
207                                                commonMacros, commonCommandWords, commonVariables, commonHandleGraphicsProperties);
208
209                     if (sizecommonsDictionary > 0)
210                     {
211                         if (sizecommonsDictionary == 1)
212                         {
213                             commonAll = os_strdup(commonsDictionary[0]);
214                         }
215                         else
216                         {
217                             commonAll = getCommonPart(commonsDictionary, sizecommonsDictionary);
218                         }
219                         freeArrayOfString(commonsDictionary, sizecommonsDictionary);
220                     }
221
222                     displayCompletionDictionary(completionDictionaryFunctions, sizecompletionDictionaryFunctions, (char *)_("Scilab Function"));
223                     displayCompletionDictionary(completionDictionaryCommandWords, sizecompletionDictionaryCommandWords, (char *)_("Scilab Command"));
224                     displayCompletionDictionary(completionDictionaryMacros, sizecompletionDictionaryMacros, (char *)_("Scilab Macro"));
225                     displayCompletionDictionary(completionDictionaryVariables, sizecompletionDictionaryVariables, (char *)_("Scilab Variable"));
226                     displayCompletionDictionary(completionDictionaryHandleGraphicsProperties, sizecompletionDictionaryHandleGraphicsProperties, (char *)_("Graphics handle field"));
227                     freeArrayOfString(completionDictionaryFunctions, sizecompletionDictionaryFunctions);
228                     freeArrayOfString(completionDictionaryCommandWords, sizecompletionDictionaryCommandWords);
229                     freeArrayOfString(completionDictionaryMacros, sizecompletionDictionaryMacros);
230                     freeArrayOfString(completionDictionaryVariables, sizecompletionDictionaryVariables);
231                     freeArrayOfString(completionDictionaryHandleGraphicsProperties, sizecompletionDictionaryHandleGraphicsProperties);
232                 }
233
234                 displayPrompt();
235                 newLine();
236
237                 if (commonAll)
238                 {
239                     char *newline = NULL;
240
241                     newline = completeLine(lineBeforeCaret, commonAll, NULL, defaultPattern, FALSE, lineAfterCaret);
242
243                     if (newline)
244                     {
245                         clearCurrentLine();
246                         copyLine(newline);
247                         FREE(newline);
248                     }
249                     FREE(commonAll);
250                     commonAll = NULL;
251                 }
252             }
253         }
254     }
255 }
256 /*--------------------------------------------------------------------------*/
257 void TermCompletion(void)
258 {
259     char *LineBeforeCaret = getLineBeforeCaret();
260     char *LineAfterCaret = getLineAfterCaret();
261     char *fileSearchedPattern = getFilePartLevel(LineBeforeCaret);
262     char *SearchedPattern = getPartLevel(LineBeforeCaret);
263
264
265     char **completionDictionaryFiles = NULL;
266     int sizecompletionDictionaryFiles = 0;
267
268     completionDictionaryFiles = completionOnFiles(fileSearchedPattern, &sizecompletionDictionaryFiles);
269     if (completionDictionaryFiles)
270     {
271         TermCompletionOnFiles(completionDictionaryFiles, sizecompletionDictionaryFiles,
272                               LineBeforeCaret, LineAfterCaret, fileSearchedPattern, SearchedPattern);
273
274         freeArrayOfString(completionDictionaryFiles, sizecompletionDictionaryFiles);
275     }
276     else
277     {
278         TermCompletionOnAll(LineBeforeCaret, LineAfterCaret, SearchedPattern);
279     }
280
281     if (LineBeforeCaret)
282     {
283         FREE(LineBeforeCaret);
284         LineBeforeCaret = NULL;
285     }
286     if (LineAfterCaret)
287     {
288         FREE(LineAfterCaret);
289         LineAfterCaret = NULL;
290     }
291     if (fileSearchedPattern)
292     {
293         FREE(fileSearchedPattern);
294         fileSearchedPattern = NULL;
295     }
296     if (SearchedPattern)
297     {
298         FREE(SearchedPattern);
299         SearchedPattern = NULL;
300     }
301 }
302 /*--------------------------------------------------------------------------*/
303 static void displayCompletionDictionary(char **dictionary, int sizedictionary, char *namedictionary)
304 {
305     if (dictionary)
306     {
307         int i = 0;
308         int lenCurrentLine = 0;
309
310         TerminalPrintf("\n");
311         TerminalPrintf(namedictionary);
312         TerminalPrintf(":");
313         TerminalPrintf("\n");
314
315         for (i = 0; i < sizedictionary; i++)
316         {
317             int newlenLine = lenCurrentLine + (int)strlen(dictionary[i]) + (int)strlen(" ");
318             if ( newlenLine >= (getColumnsSize() - 10) )
319             {
320                 TerminalPrintf("\n");
321                 lenCurrentLine = 0;
322             }
323             else
324             {
325                 lenCurrentLine = newlenLine;
326             }
327
328             TerminalPrintf(dictionary[i]);
329             TerminalPrintf(" ");
330         }
331         TerminalPrintf("\n");
332     }
333 }
334 /*--------------------------------------------------------------------------*/
335 static char **concatenateStrings(int *sizearrayofstring, char *string1,
336                                  char *string2, char *string3,
337                                  char *string4, char *string5)
338 {
339     int newsize = 0;
340     char **arrayOfString = NULL;
341     *sizearrayofstring = 0;
342
343     if (string1)
344     {
345         newsize++;
346     }
347     if (string2)
348     {
349         newsize++;
350     }
351     if (string3)
352     {
353         newsize++;
354     }
355     if (string4)
356     {
357         newsize++;
358     }
359     if (string5)
360     {
361         newsize++;
362     }
363
364     if (newsize > 0)
365     {
366         arrayOfString = (char**)MALLOC(sizeof(char*) * (newsize));
367         if (arrayOfString)
368         {
369             int i = 0;
370             if (string1)
371             {
372                 arrayOfString[i] = string1;
373                 i++;
374             }
375             if (string2)
376             {
377                 arrayOfString[i] = string2;
378                 i++;
379             }
380             if (string3)
381             {
382                 arrayOfString[i] = string3;
383                 i++;
384             }
385             if (string4)
386             {
387                 arrayOfString[i] = string4;
388                 i++;
389             }
390             if (string5)
391             {
392                 arrayOfString[i] = string5;
393                 i++;
394             }
395             *sizearrayofstring = i;
396         }
397         else
398         {
399             *sizearrayofstring = 0;
400         }
401     }
402     return arrayOfString;
403 }
404 /*--------------------------------------------------------------------------*/