diff options
Diffstat (limited to 'src/AutoComplete.cpp')
-rwxr-xr-x | src/AutoComplete.cpp | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/src/AutoComplete.cpp b/src/AutoComplete.cpp new file mode 100755 index 0000000..753adca --- /dev/null +++ b/src/AutoComplete.cpp @@ -0,0 +1,174 @@ +// Scintilla source code edit control +/** @file AutoComplete.cxx + ** Defines the auto completion list box. + **/ +// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org> +// The License.txt file describes the conditions under which this software may be distributed. + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#include "Platform.h" + +#include "PropSet.h" +#include "AutoComplete.h" + +AutoComplete::AutoComplete() : + active(false), + separator(' '), + typesep('?'), + ignoreCase(false), + chooseSingle(false), + lb(0), + posStart(0), + startLen(0), + cancelAtStartPos(true), + autoHide(true), + dropRestOfWord(false) { + lb = ListBox::Allocate(); + stopChars[0] = '\0'; + fillUpChars[0] = '\0'; +} + +AutoComplete::~AutoComplete() { + if (lb) { + lb->Destroy(); + delete lb; + lb = 0; + } +} + +bool AutoComplete::Active() { + return active; +} + +void AutoComplete::Start(Window &parent, int ctrlID, + int position, Point location, int startLen_, + int lineHeight, bool unicodeMode) { + if (active) { + Cancel(); + } + lb->Create(parent, ctrlID, location, lineHeight, unicodeMode); + lb->Clear(); + active = true; + startLen = startLen_; + posStart = position; +} + +void AutoComplete::SetStopChars(const char *stopChars_) { + strncpy(stopChars, stopChars_, sizeof(stopChars)); + stopChars[sizeof(stopChars) - 1] = '\0'; +} + +bool AutoComplete::IsStopChar(char ch) { + return ch && strchr(stopChars, ch); +} + +void AutoComplete::SetFillUpChars(const char *fillUpChars_) { + strncpy(fillUpChars, fillUpChars_, sizeof(fillUpChars)); + fillUpChars[sizeof(fillUpChars) - 1] = '\0'; +} + +bool AutoComplete::IsFillUpChar(char ch) { + return ch && strchr(fillUpChars, ch); +} + +void AutoComplete::SetSeparator(char separator_) { + separator = separator_; +} + +char AutoComplete::GetSeparator() { + return separator; +} + +void AutoComplete::SetTypesep(char separator_) { + typesep = separator_; +} + +char AutoComplete::GetTypesep() { + return typesep; +} + +void AutoComplete::SetList(const char *list) { + lb->SetList(list, separator, typesep); +} + +void AutoComplete::Show(bool show) { + lb->Show(show); + if (show) + lb->Select(0); +} + +void AutoComplete::Cancel() { + if (lb->Created()) { + lb->Clear(); + lb->Destroy(); + active = false; + } +} + + +void AutoComplete::Move(int delta) { + int count = lb->Length(); + int current = lb->GetSelection(); + current += delta; + if (current >= count) + current = count - 1; + if (current < 0) + current = 0; + lb->Select(current); +} + +void AutoComplete::Select(const char *word) { + size_t lenWord = strlen(word); + int location = -1; + const int maxItemLen=1000; + char item[maxItemLen]; + int start = 0; // lower bound of the api array block to search + int end = lb->Length() - 1; // upper bound of the api array block to search + while ((start <= end) && (location == -1)) { // Binary searching loop + int pivot = (start + end) / 2; + lb->GetValue(pivot, item, maxItemLen); + int cond; + if (ignoreCase) + cond = CompareNCaseInsensitive(word, item, lenWord); + else + cond = strncmp(word, item, lenWord); + if (!cond) { + // Find first match + while (pivot > start) { + lb->GetValue(pivot-1, item, maxItemLen); + if (ignoreCase) + cond = CompareNCaseInsensitive(word, item, lenWord); + else + cond = strncmp(word, item, lenWord); + if (0 != cond) + break; + --pivot; + } + location = pivot; + if (ignoreCase) { + // Check for exact-case match + for (; pivot <= end; pivot++) { + lb->GetValue(pivot, item, maxItemLen); + if (!strncmp(word, item, lenWord)) { + location = pivot; + break; + } + if (CompareNCaseInsensitive(word, item, lenWord)) + break; + } + } + } else if (cond < 0) { + end = pivot - 1; + } else if (cond > 0) { + start = pivot + 1; + } + } + if (location == -1 && autoHide) + Cancel(); + else + lb->Select(location); +} + |