Autocomplete config variables

This commit is contained in:
yvt 2019-07-14 19:15:30 +09:00
parent bfe746abca
commit e4efc8b5fc
No known key found for this signature in database
GPG Key ID: 48F2768FA8D07C92
3 changed files with 60 additions and 0 deletions

View File

@ -122,6 +122,7 @@ namespace spades {
void Load();
void Flush();
/** Return a list of all config variables, sorted by name. */
std::vector<std::string> GetAllItemNames();
};
/*

View File

@ -28,6 +28,54 @@ namespace spades {
namespace gui {
namespace {
std::string EscapeQuotes(std::string s) { return Replace(s, "\"", "\\\""); }
/** Equivalent to `std::string::starts_with` (since C++20) */
bool StartsWith(const std::string &subject, const std::string &prefix) {
if (subject.size() < prefix.size()) {
return false;
}
for (std::size_t i = 0; i < prefix.size(); ++i) {
if (subject[i] != prefix[i]) {
return false;
}
}
return true;
}
class ConfigNameIterator : public ConsoleCommandCandidateIterator {
std::vector<std::string> const names;
std::string query;
std::size_t i = 0;
ConsoleCommandCandidate current;
public:
ConfigNameIterator(const std::string &query)
: names{Settings::GetInstance()->GetAllItemNames()}, query{query} {
// Find the starting position
i = std::lower_bound(names.begin(), names.end(), query) - names.begin();
}
const ConsoleCommandCandidate &GetCurrent() override { return current; }
bool MoveNext() override {
if (i >= names.size() || !StartsWith(names[i], query)) {
// Make sure it returns `MoveNext` indefinitely
i = names.size();
return false;
}
// Create `ConsoleCommandCandidate` for the current
// config variable
Settings::ItemHandle cvarHandle{names[i], nullptr};
current.name = names[i];
current.description = " = \"" + EscapeQuotes(cvarHandle) + "\"";
i += 1;
return true;
}
};
} // namespace
bool ConfigConsoleResponder::ExecCommand(const Handle<ConsoleCommand> &cmd) {
@ -54,5 +102,10 @@ namespace spades {
return true;
}
Handle<ConsoleCommandCandidateIterator>
ConfigConsoleResponder::AutocompleteCommandName(const std::string &name) {
return {new ConfigNameIterator(name), false};
}
} // namespace gui
} // namespace spades

View File

@ -19,6 +19,9 @@
#pragma once
#include <Core/RefCountedObject.h>
#include <string>
#include "ConsoleCommandCandidate.h"
namespace spades {
namespace gui {
@ -28,6 +31,9 @@ namespace spades {
class ConfigConsoleResponder {
public:
static bool ExecCommand(const Handle<ConsoleCommand> &);
static Handle<ConsoleCommandCandidateIterator>
AutocompleteCommandName(const std::string &name);
};
} // namespace gui
} // namespace spades