upgraded to scintilla 3.2.0
[TortoiseGit.git] / ext / scintilla / src / AutoComplete.cxx
blobbb50b21572c22d0391d919ca657e88a238038679
1 // Scintilla source code edit control
2 /** @file AutoComplete.cxx
3 ** Defines the auto completion list box.
4 **/
5 // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
6 // The License.txt file describes the conditions under which this software may be distributed.
8 #include <stdlib.h>
9 #include <string.h>
10 #include <stdio.h>
11 #include <assert.h>
13 #include "Platform.h"
15 #include "CharacterSet.h"
16 #include "AutoComplete.h"
17 #include "Scintilla.h"
19 #ifdef SCI_NAMESPACE
20 using namespace Scintilla;
21 #endif
23 AutoComplete::AutoComplete() :
24 active(false),
25 separator(' '),
26 typesep('?'),
27 ignoreCase(false),
28 chooseSingle(false),
29 lb(0),
30 posStart(0),
31 startLen(0),
32 cancelAtStartPos(true),
33 autoHide(true),
34 dropRestOfWord(false),
35 ignoreCaseBehaviour(SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE) {
36 lb = ListBox::Allocate();
37 stopChars[0] = '\0';
38 fillUpChars[0] = '\0';
41 AutoComplete::~AutoComplete() {
42 if (lb) {
43 lb->Destroy();
44 delete lb;
45 lb = 0;
49 bool AutoComplete::Active() const {
50 return active;
53 void AutoComplete::Start(Window &parent, int ctrlID,
54 int position, Point location, int startLen_,
55 int lineHeight, bool unicodeMode, int technology) {
56 if (active) {
57 Cancel();
59 lb->Create(parent, ctrlID, location, lineHeight, unicodeMode, technology);
60 lb->Clear();
61 active = true;
62 startLen = startLen_;
63 posStart = position;
66 void AutoComplete::SetStopChars(const char *stopChars_) {
67 strncpy(stopChars, stopChars_, sizeof(stopChars));
68 stopChars[sizeof(stopChars) - 1] = '\0';
71 bool AutoComplete::IsStopChar(char ch) {
72 return ch && strchr(stopChars, ch);
75 void AutoComplete::SetFillUpChars(const char *fillUpChars_) {
76 strncpy(fillUpChars, fillUpChars_, sizeof(fillUpChars));
77 fillUpChars[sizeof(fillUpChars) - 1] = '\0';
80 bool AutoComplete::IsFillUpChar(char ch) {
81 return ch && strchr(fillUpChars, ch);
84 void AutoComplete::SetSeparator(char separator_) {
85 separator = separator_;
88 char AutoComplete::GetSeparator() const {
89 return separator;
92 void AutoComplete::SetTypesep(char separator_) {
93 typesep = separator_;
96 char AutoComplete::GetTypesep() const {
97 return typesep;
100 void AutoComplete::SetList(const char *list) {
101 lb->SetList(list, separator, typesep);
104 void AutoComplete::Show(bool show) {
105 lb->Show(show);
106 if (show)
107 lb->Select(0);
110 void AutoComplete::Cancel() {
111 if (lb->Created()) {
112 lb->Clear();
113 lb->Destroy();
114 active = false;
119 void AutoComplete::Move(int delta) {
120 int count = lb->Length();
121 int current = lb->GetSelection();
122 current += delta;
123 if (current >= count)
124 current = count - 1;
125 if (current < 0)
126 current = 0;
127 lb->Select(current);
130 void AutoComplete::Select(const char *word) {
131 size_t lenWord = strlen(word);
132 int location = -1;
133 const int maxItemLen=1000;
134 int start = 0; // lower bound of the api array block to search
135 int end = lb->Length() - 1; // upper bound of the api array block to search
136 while ((start <= end) && (location == -1)) { // Binary searching loop
137 int pivot = (start + end) / 2;
138 char item[maxItemLen];
139 lb->GetValue(pivot, item, maxItemLen);
140 int cond;
141 if (ignoreCase)
142 cond = CompareNCaseInsensitive(word, item, lenWord);
143 else
144 cond = strncmp(word, item, lenWord);
145 if (!cond) {
146 // Find first match
147 while (pivot > start) {
148 lb->GetValue(pivot-1, item, maxItemLen);
149 if (ignoreCase)
150 cond = CompareNCaseInsensitive(word, item, lenWord);
151 else
152 cond = strncmp(word, item, lenWord);
153 if (0 != cond)
154 break;
155 --pivot;
157 location = pivot;
158 if (ignoreCase
159 && ignoreCaseBehaviour == SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE) {
160 // Check for exact-case match
161 for (; pivot <= end; pivot++) {
162 lb->GetValue(pivot, item, maxItemLen);
163 if (!strncmp(word, item, lenWord)) {
164 location = pivot;
165 break;
167 if (CompareNCaseInsensitive(word, item, lenWord))
168 break;
171 } else if (cond < 0) {
172 end = pivot - 1;
173 } else if (cond > 0) {
174 start = pivot + 1;
177 if (location == -1 && autoHide)
178 Cancel();
179 else
180 lb->Select(location);