mirror of
https://github.com/OpenTTD/OpenTTD
synced 2026-01-16 00:42:45 +01:00
Add: Basic autocompletion on tab for console commands (#12163)
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "textbuf_type.h"
|
||||
#include "window_gui.h"
|
||||
#include "autocompletion.h"
|
||||
#include "console_gui.h"
|
||||
#include "console_internal.h"
|
||||
#include "window_func.h"
|
||||
@@ -68,9 +69,44 @@ static std::deque<IConsoleLine> _iconsole_buffer;
|
||||
|
||||
static bool TruncateBuffer();
|
||||
|
||||
class ConsoleAutoCompletion final : public AutoCompletion {
|
||||
public:
|
||||
using AutoCompletion::AutoCompletion;
|
||||
|
||||
private:
|
||||
std::vector<std::string> GetSuggestions(std::string_view prefix, std::string_view query) override
|
||||
{
|
||||
prefix = StrTrimView(prefix);
|
||||
std::vector<std::string> suggestions;
|
||||
|
||||
/* We only suggest commands or aliases, so we only do it for the first token or an argument to help command. */
|
||||
if (!prefix.empty() && prefix != "help") {
|
||||
return suggestions;
|
||||
}
|
||||
|
||||
for (const auto &[_, command] : IConsole::Commands()) {
|
||||
if (command.name.starts_with(query)) {
|
||||
suggestions.push_back(command.name);
|
||||
}
|
||||
}
|
||||
for (const auto &[_, alias] : IConsole::Aliases()) {
|
||||
if (alias.name.starts_with(query)) {
|
||||
suggestions.push_back(alias.name);
|
||||
}
|
||||
}
|
||||
|
||||
return suggestions;
|
||||
}
|
||||
|
||||
void ApplySuggestion(std::string_view prefix, std::string_view suggestion) override
|
||||
{
|
||||
this->textbuf->Assign(fmt::format("{}{} ", prefix, suggestion));
|
||||
}
|
||||
};
|
||||
|
||||
/* ** main console cmd buffer ** */
|
||||
static Textbuf _iconsole_cmdline(ICON_CMDLN_SIZE);
|
||||
static ConsoleAutoCompletion _iconsole_tab_completion(&_iconsole_cmdline);
|
||||
static std::deque<std::string> _iconsole_history;
|
||||
static ptrdiff_t _iconsole_historypos;
|
||||
IConsoleModes _iconsole_mode;
|
||||
@@ -86,6 +122,7 @@ static void IConsoleClearCommand()
|
||||
_iconsole_cmdline.pixels = 0;
|
||||
_iconsole_cmdline.caretpos = 0;
|
||||
_iconsole_cmdline.caretxoffs = 0;
|
||||
_iconsole_tab_completion.Reset();
|
||||
SetWindowDirty(WC_CONSOLE, 0);
|
||||
}
|
||||
|
||||
@@ -258,8 +295,18 @@ struct IConsoleWindow : Window
|
||||
IConsoleCmdExec("clear");
|
||||
break;
|
||||
|
||||
default:
|
||||
if (_iconsole_cmdline.HandleKeyPress(key, keycode) != HKPR_NOT_HANDLED) {
|
||||
case WKC_TAB:
|
||||
if (_iconsole_tab_completion.AutoComplete()) {
|
||||
this->SetDirty();
|
||||
}
|
||||
break;
|
||||
|
||||
default: {
|
||||
HandleKeyPressResult handle_result = _iconsole_cmdline.HandleKeyPress(key, keycode);
|
||||
if (handle_result != HKPR_NOT_HANDLED) {
|
||||
if (handle_result == HKPR_EDITING) {
|
||||
_iconsole_tab_completion.Reset();
|
||||
}
|
||||
IConsoleWindow::scroll = 0;
|
||||
IConsoleResetHistoryPos();
|
||||
this->SetDirty();
|
||||
@@ -267,6 +314,7 @@ struct IConsoleWindow : Window
|
||||
return ES_NOT_HANDLED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ES_HANDLED;
|
||||
}
|
||||
@@ -274,13 +322,14 @@ struct IConsoleWindow : Window
|
||||
void InsertTextString(WidgetID, const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end) override
|
||||
{
|
||||
if (_iconsole_cmdline.InsertString(str, marked, caret, insert_location, replacement_end)) {
|
||||
_iconsole_tab_completion.Reset();
|
||||
IConsoleWindow::scroll = 0;
|
||||
IConsoleResetHistoryPos();
|
||||
this->SetDirty();
|
||||
}
|
||||
}
|
||||
|
||||
Textbuf *GetFocusedTextbuf() const override
|
||||
const Textbuf *GetFocusedTextbuf() const override
|
||||
{
|
||||
return &_iconsole_cmdline;
|
||||
}
|
||||
@@ -434,6 +483,7 @@ static void IConsoleHistoryNavigate(int direction)
|
||||
} else {
|
||||
_iconsole_cmdline.Assign(_iconsole_history[_iconsole_historypos]);
|
||||
}
|
||||
_iconsole_tab_completion.Reset();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user