Mon, 15 Dec 2014 10:31:52 +0200
- added experimental support for rcon tab-completion
--- a/sources/interface.cpp Mon Dec 15 09:12:50 2014 +0200 +++ b/sources/interface.cpp Mon Dec 15 10:31:52 2014 +0200 @@ -719,6 +719,19 @@ g_needOutputRender = true; break; + case '\t': + { + int space = current_input().find (" "); + + if (g_inputState == INPUTSTATE_NORMAL + and g_cursor > 0 + and (space == -1 or space >= g_cursor)) + { + RCONSession::get_session()->request_tab_complete (current_input().mid (0, g_cursor)); + } + } + break; + case '\n': case KEY_ENTER: switch (g_inputState) @@ -768,6 +781,8 @@ safe_disconnect ([]() {set_input_state (INPUTSTATE_ADDRESS);}); break; } + + render(); } // ------------------------------------------------------------------------------------------------- @@ -926,3 +941,18 @@ return max (rows, 1); } + +// ------------------------------------------------------------------------------------------------- +// +FUNCTION +Interface::tab_complete (const String& part, const String& complete) -> void +{ + String& input = mutable_current_input(); + + if (input.starts_with (part)) + { + input.replace (0, part.length(), complete); + g_cursor = complete.length(); + g_needInputRender = true; + } +}
--- a/sources/interface.h Mon Dec 15 09:12:50 2014 +0200 +++ b/sources/interface.h Mon Dec 15 10:31:52 2014 +0200 @@ -40,4 +40,6 @@ FUNCTION set_title (const String& message) -> void; FUNCTION update_statusbar() -> void; FUNCTION connect (String address, String password) -> void; + FUNCTION need_refresh() -> void; + FUNCTION tab_complete (const String& part, const String& complete) -> void; };
--- a/sources/network/rconsession.cpp Mon Dec 15 09:12:50 2014 +0200 +++ b/sources/network/rconsession.cpp Mon Dec 15 10:31:52 2014 +0200 @@ -187,6 +187,29 @@ case SVRC_UPDATE: process_server_updates (packet); break; + + case SVRC_TABCOMPLETE: + { + StringList completes; + + for (signed int i = packet.read_byte(); i > 0; --i) + completes << packet.read_string(); + + if (completes.size() == 1) + Interface::tab_complete (m_lastTabComplete, completes[0]); + else if (not completes.is_empty()) + { + print ("Completions for '%1':\n", m_lastTabComplete); + + for (int i = 0; i < completes.size(); i += 8) + { + Range<int> spliceRange (i, min (i + 8, completes.size() - 1)); + StringList splice (completes.splice (spliceRange)); + print ("- %1\n", splice.join (", ")); + } + } + } + break; } } } @@ -340,3 +363,21 @@ { return m_level; } + +// ------------------------------------------------------------------------------------------------- +// +METHOD +RCONSession::request_tab_complete (const String& part) -> void +{ + if (m_serverProtocol >= 4) + { + Bytestream packet; + packet.write_byte (CLRC_TABCOMPLETE); + packet.write_string (part); + send (packet); + bump_last_ping(); + m_lastTabComplete = part; + } + else + print ("Server protocol is %1, cannot tab-complete\n", m_serverProtocol); +}
--- a/sources/network/rconsession.h Mon Dec 15 09:12:50 2014 +0200 +++ b/sources/network/rconsession.h Mon Dec 15 10:31:52 2014 +0200 @@ -37,7 +37,7 @@ // enum { - RCON_PROTOCOL_VERSION = 3 + RCON_PROTOCOL_VERSION = 4 }; // ------------------------------------------------------------------------------------------------- @@ -51,6 +51,7 @@ SVRC_INVALIDPASSWORD, SVRC_MESSAGE, SVRC_UPDATE, + SVRC_TABCOMPLETE, }; // ------------------------------------------------------------------------------------------------- @@ -62,6 +63,7 @@ CLRC_COMMAND, CLRC_PONG, CLRC_DISCONNECT, + CLRC_TABCOMPLETE, }; // ------------------------------------------------------------------------------------------------- @@ -107,6 +109,7 @@ METHOD state() const -> RCONSessionState; METHOD level() const -> const String&; METHOD is_active() const -> bool; + METHOD request_tab_complete (const String& part) -> void; static METHOD new_session() -> RCONSession*; static METHOD get_session() -> RCONSession*; @@ -124,4 +127,5 @@ String m_hostname; int m_numAdmins; String m_level; + String m_lastTabComplete; };