From a02611fba11abd0b3610c7ab50e10880485dabc5 Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Wed, 14 May 2014 18:43:01 +0200 Subject: [PATCH] case-insensitive completion --- lib/V8/V8LineEditor.cpp | 130 ++++++++++++++++++++++------------------ 1 file changed, 71 insertions(+), 59 deletions(-) diff --git a/lib/V8/V8LineEditor.cpp b/lib/V8/V8LineEditor.cpp index 1338a0c4fe..382db2d8a6 100644 --- a/lib/V8/V8LineEditor.cpp +++ b/lib/V8/V8LineEditor.cpp @@ -198,95 +198,107 @@ static char* CompletionGenerator (char const* text, int state) { static void LinenoiseCompletionGenerator (char const* text, linenoiseCompletions * lc) { vector completions; - // locate global object or sub-object - v8::Handle current = v8::Context::GetCurrent()->Global(); - string path; - char* prefix; - if (*text != '\0') { - TRI_vector_string_t splitted = TRI_SplitString(text, '.'); + // locate global object or sub-object + v8::Handle current = v8::Context::GetCurrent()->Global(); + string path; + char* prefix; - if (1 < splitted._length) { - for (size_t i = 0; i < splitted._length - 1; ++i) { - v8::Handle name = v8::String::New(splitted._buffer[i]); + if (*text != '\0') { + TRI_vector_string_t splitted = TRI_SplitString(text, '.'); - if (! current->Has(name)) { - TRI_DestroyVectorString(&splitted); - return; - } + if (1 < splitted._length) { + for (size_t i = 0; i < splitted._length - 1; ++i) { + v8::Handle name = v8::String::New(splitted._buffer[i]); - v8::Handle val = current->Get(name); - - if (! val->IsObject()) { - TRI_DestroyVectorString(&splitted); - return; - } - - current = val->ToObject(); - path = path + splitted._buffer[i] + "."; + if (! current->Has(name)) { + TRI_DestroyVectorString(&splitted); + return; } - prefix = TRI_DuplicateString(splitted._buffer[splitted._length - 1]); - } - else { - prefix = TRI_DuplicateString(text); + v8::Handle val = current->Get(name); + + if (! val->IsObject()) { + TRI_DestroyVectorString(&splitted); + return; + } + + current = val->ToObject(); + path = path + splitted._buffer[i] + "."; } - TRI_DestroyVectorString(&splitted); + prefix = TRI_DuplicateString(splitted._buffer[splitted._length - 1]); } else { prefix = TRI_DuplicateString(text); } - v8::HandleScope scope; + TRI_DestroyVectorString(&splitted); + } + else { + prefix = TRI_DuplicateString(text); + } - // compute all possible completions - v8::Handle properties; - v8::Handle cpl = v8::String::New("_COMPLETIONS"); + v8::HandleScope scope; - if (current->HasOwnProperty(cpl)) { - v8::Handle funcVal = current->Get(cpl); + // compute all possible completions + v8::Handle properties; + v8::Handle cpl = v8::String::New("_COMPLETIONS"); - if (funcVal->IsFunction()) { - v8::Handle func = v8::Handle::Cast(funcVal); - v8::Handle args; - v8::Handle cpls = func->Call(current, 0, &args); + if (current->HasOwnProperty(cpl)) { + v8::Handle funcVal = current->Get(cpl); - if (cpls->IsArray()) { - properties = v8::Handle::Cast(cpls); - } + if (funcVal->IsFunction()) { + v8::Handle func = v8::Handle::Cast(funcVal); + v8::Handle args; + v8::Handle cpls = func->Call(current, 0, &args); + + if (cpls->IsArray()) { + properties = v8::Handle::Cast(cpls); } } - else { - properties = current->GetPropertyNames(); - } + } + else { + properties = current->GetPropertyNames(); + } - // locate - if (! properties.IsEmpty()) { - const uint32_t n = properties->Length(); + // locate + if (! properties.IsEmpty()) { + const uint32_t n = properties->Length(); - for (uint32_t i = 0; i < n; ++i) { - v8::Handle v = properties->Get(i); + for (uint32_t i = 0; i < n; ++i) { + v8::Handle v = properties->Get(i); - TRI_Utf8ValueNFC str(TRI_UNKNOWN_MEM_ZONE, v); - char const* s = *str; + TRI_Utf8ValueNFC str(TRI_UNKNOWN_MEM_ZONE, v); + char const* s = *str; - if (s != 0 && *s) { - string suffix = (current->Get(v)->IsFunction()) ? "()" : ""; + if (s != 0 && *s) { + string const suffix = (current->Get(v)->IsFunction()) ? "()" : ""; + + if (*prefix == '\0' || TRI_IsPrefixString(s, prefix)) { string name = path + s + suffix; - - if (*prefix == '\0' || TRI_IsPrefixString(s, prefix)) { - linenoiseAddCompletion(lc, name.c_str()); - completions.push_back(name); - } + completions.push_back(name); } } } + } + // sort completions + size_t const n = completions.size(); - lc->multiLine = 1; - TRI_FreeString(TRI_CORE_MEM_ZONE, prefix); + std::sort(completions.begin(), completions.end(), + [](std::string const& l, std::string const& r) -> bool { + int res = strcasecmp(l.c_str(), r.c_str()); + return (res < 0); + } + ); + for (size_t i = 0; i < n; ++i) { + linenoiseAddCompletion(lc, completions[i].c_str()); + } + + lc->multiLine = 1; + TRI_FreeString(TRI_CORE_MEM_ZONE, prefix); } #endif