updated Scintilla to 2.29
[TortoiseGit.git] / ext / scintilla / src / AutoComplete.cxx
blobdbab3562a36d5fc824466bdf088ee512ddacad67
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"
18 #ifdef SCI_NAMESPACE
19 using namespace Scintilla;
20 #endif
22 AutoComplete::AutoComplete() :
23 active(false),
24 separator(' '),
25 typesep('?'),
26 ignoreCase(false),
27 chooseSingle(false),
28 lb(0),
29 posStart(0),
30 startLen(0),
31 cancelAtStartPos(true),
32 autoHide(true),
33 dropRestOfWord(false) {
34 lb = ListBox::Allocate();
35 stopChars[0] = '\0';
36 fillUpChars[0] = '\0';
39 AutoComplete::~AutoComplete() {
40 if (lb) {
41 lb->Destroy();
42 delete lb;
43 lb = 0;
47 bool AutoComplete::Active() const {
48 return active;
51 void AutoComplete::Start(Window &parent, int ctrlID,
52 int position, Point location, int startLen_,
53 int lineHeight, bool unicodeMode) {
54 if (active) {
55 Cancel();
57 lb->Create(parent, ctrlID, location, lineHeight, unicodeMode);
58 lb->Clear();
59 active = true;
60 startLen = startLen_;
61 posStart = position;
64 void AutoComplete::SetStopChars(const char *stopChars_) {
65 strncpy(stopChars, stopChars_, sizeof(stopChars));
66 stopChars[sizeof(stopChars) - 1] = '\0';
69 bool AutoComplete::IsStopChar(char ch) {
70 return ch && strchr(stopChars, ch);
73 void AutoComplete::SetFillUpChars(const char *fillUpChars_) {
74 strncpy(fillUpChars, fillUpChars_, sizeof(fillUpChars));
75 fillUpChars[sizeof(fillUpChars) - 1] = '\0';
78 bool AutoComplete::IsFillUpChar(char ch) {
79 return ch && strchr(fillUpChars, ch);
82 void AutoComplete::SetSeparator(char separator_) {
83 separator = separator_;
86 char AutoComplete::GetSeparator() const {
87 return separator;
90 void AutoComplete::SetTypesep(char separator_) {
91 typesep = separator_;
94 char AutoComplete::GetTypesep() const {
95 return typesep;
98 void AutoComplete::SetList(const char *list) {
99 lb->SetList(list, separator, typesep);
102 void AutoComplete::Show(bool show) {
103 lb->Show(show);
104 if (show)
105 lb->Select(0);
108 void AutoComplete::Cancel() {
109 if (lb->Created()) {
110 lb->Clear();
111 lb->Destroy();
112 active = false;
117 void AutoComplete::Move(int delta) {
118 int count = lb->Length();
119 int current = lb->GetSelection();
120 current += delta;
121 if (current >= count)
122 current = count - 1;
123 if (current < 0)
124 current = 0;
125 lb->Select(current);
128 void AutoComplete::Select(const char *word) {
129 size_t lenWord = strlen(word);
130 int location = -1;
131 const int maxItemLen=1000;
132 int start = 0; // lower bound of the api array block to search
133 int end = lb->Length() - 1; // upper bound of the api array block to search
134 while ((start <= end) && (location == -1)) { // Binary searching loop
135 int pivot = (start + end) / 2;
136 char item[maxItemLen];
137 lb->GetValue(pivot, item, maxItemLen);
138 int cond;
139 if (ignoreCase)
140 cond = CompareNCaseInsensitive(word, item, lenWord);
141 else
142 cond = strncmp(word, item, lenWord);
143 if (!cond) {
144 // Find first match
145 while (pivot > start) {
146 lb->GetValue(pivot-1, item, maxItemLen);
147 if (ignoreCase)
148 cond = CompareNCaseInsensitive(word, item, lenWord);
149 else
150 cond = strncmp(word, item, lenWord);
151 if (0 != cond)
152 break;
153 --pivot;
155 location = pivot;
156 if (ignoreCase) {
157 // Check for exact-case match
158 for (; pivot <= end; pivot++) {
159 lb->GetValue(pivot, item, maxItemLen);
160 if (!strncmp(word, item, lenWord)) {
161 location = pivot;
162 break;
164 if (CompareNCaseInsensitive(word, item, lenWord))
165 break;
168 } else if (cond < 0) {
169 end = pivot - 1;
170 } else if (cond > 0) {
171 start = pivot + 1;
174 if (location == -1 && autoHide)
175 Cancel();
176 else
177 lb->Select(location);