From 2b6208917e92d93f94ad6620c5135d1bcd237ea8 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sat, 9 Feb 2008 10:08:30 +0000 Subject: command completion (single match) --- src/client/console.cc | 113 ++++++++++++++++++++++++++++++++++++++-------- src/client/console.h | 1 + src/core/commandbuffer.cc | 43 ++++++++++++++++++ src/core/commandbuffer.h | 3 ++ src/core/cvar.h | 4 ++ src/core/func.h | 5 ++ src/render/render.cc | 6 +-- src/render/tga.cc | 2 +- 8 files changed, 153 insertions(+), 24 deletions(-) diff --git a/src/client/console.cc b/src/client/console.cc index 83d69de..71f3d5a 100644 --- a/src/client/console.cc +++ b/src/client/console.cc @@ -41,17 +41,18 @@ public: // private client console object Console console; -// client console input -std::string input; - // console text data std::deque text; +// input history +std::deque history; +std::deque::reverse_iterator history_pos; +size_t input_pos = 0; + // console visibility bool console_visible; - size_t console_scroll = 0; -size_t input_pos = 0; + //--- engine functions -------------------------------------------- @@ -65,11 +66,19 @@ extern "C" void func_con_toggle(std::stringstream &args) void init() { con_print << "Initializing console..." << std::endl; - + console_visible = false; - + // add engine functions core::func::add("con_toggle", func_con_toggle); + + text.clear(); + console_scroll = 0; + + history.clear(); + history.push_back(""); + history_pos = history.rbegin(); + input_pos = 0; } void shutdown() @@ -78,6 +87,12 @@ void shutdown() // remove engine functions core::func::remove("con_toggle"); + + text.clear(); + console_scroll = 0; + + history.clear(); + input_pos = 0; } void draw() @@ -140,12 +155,12 @@ void draw() // draw the console input gl::color(0.0f, 1.0f, 0.0f, 1.0f); - draw_text(CHARWIDTH, video::height*con_height - CHARHEIGHT - 4, input); + draw_text(CHARWIDTH, video::height*con_height - CHARHEIGHT - 4, (*history_pos)); // draw cursor if ((core::time() - ::floorf(core::time())) < 0.5f) { std::string cursor("_"); - draw_text(CHARWIDTH*(input.size()+1), video::height*con_height - CHARHEIGHT - 4 , cursor); + draw_text(CHARWIDTH*(input_pos+1), video::height*con_height - CHARHEIGHT - 4 , cursor); } gl::disable(GL_TEXTURE_2D); } @@ -168,23 +183,76 @@ void toggle() { console_visible = !console_visible; setkeyboardmode(console_visible); - console_scroll = 0; - input.clear(); - input_pos = 0; + + if (console_visible) { + console_scroll = 0; + input_pos = 0; + + history_pos = history.rbegin(); + (*history_pos).clear(); + } } void keypressed(const SDL_keysym &keysym) { + std::deque::reverse_iterator upit; + switch( keysym.sym ) { + case SDLK_TAB: + core::commandbuffer::complete( (*history_pos), input_pos); + break; case SDLK_RETURN: - if (input.size()) { - core::cmd << input << std::endl; - input.clear(); + if ((*history_pos).size()) { + // store input into history + while (history.size() >= MAXHISTOLINES) { + history.pop_front(); + } + + core::cmd << (*history_pos) << std::endl; + + history.push_back(""); + history_pos = history.rbegin(); + input_pos = 0; + } + break; + case SDLK_KP8: + case SDLK_UP: + upit = history_pos; + ++upit; + if (upit != history.rend()) { + history_pos = upit; + input_pos = (*history_pos).size(); + } + break; + case SDLK_KP2: + case SDLK_DOWN: + if (history_pos != history.rbegin()) { + --history_pos; + input_pos = (*history_pos).size(); } break; + case SDLK_KP7: + case SDLK_HOME: + input_pos = 0; + break; + case SDLK_KP1: + case SDLK_END: + input_pos = (*history_pos).size(); + break; + case SDLK_KP4: + case SDLK_LEFT: + if (input_pos > 0) + input_pos--; + break; + case SDLK_KP6: + case SDLK_RIGHT: + if (input_pos <= (*history_pos).size()) + input_pos++; + break; case SDLK_BACKSPACE: - if (input.size()) { - input.erase(input.size()-1, 1); + if ((*history_pos).size() && input_pos) { + (*history_pos).erase(input_pos-1, 1); + input_pos--; } break; case SDLK_PAGEUP: @@ -196,12 +264,17 @@ void keypressed(const SDL_keysym &keysym) else console_scroll = 0; break; default: + if ((keysym.sym >= 32 ) && (keysym.sym <175)) { + if (input_pos == (*history_pos).size()) + (*history_pos) += keysym_to_char(keysym); + else + (*history_pos).insert(input_pos, 1, keysym_to_char(keysym)); + input_pos++; + } break; } - if ((keysym.sym >= 32 ) && (keysym.sym <175)) { - input += keysym_to_char(keysym); - } + } bool visible() diff --git a/src/client/console.h b/src/client/console.h index e558438..e848720 100644 --- a/src/client/console.h +++ b/src/client/console.h @@ -15,6 +15,7 @@ #include const size_t MAXCONLINES=2048; +const size_t MAXHISTOLINES=512; namespace client { diff --git a/src/core/commandbuffer.cc b/src/core/commandbuffer.cc index eaa8504..a46863c 100644 --- a/src/core/commandbuffer.cc +++ b/src/core/commandbuffer.cc @@ -10,6 +10,7 @@ // C++ headers #include #include +#include namespace core { @@ -73,6 +74,48 @@ void clear() while (core::cmd.getline(line, MAXCMDSIZE-1)); } +void complete(std::string &input, size_t &pos) +{ + std::list match; + + std::string partial = input.substr(0, pos); + if (!partial.size()) + return; + + // search function registry for matches + std::map::iterator f; + for (f = func::registry.begin(); f != func::registry.end(); f++) { + if (partial == (*f).first.substr(0, partial.size())) { + match.push_back((*f).first); + //con_print << " " << (*f).first << std::endl; + } + } + + // search cvar registry for matches + std::map::iterator c; + for (c = cvar::registry.begin(); c != cvar::registry.end(); c++) { + if (partial == (*c).first.substr(0, partial.size())) { + match.push_back((*c).first); + //con_print << " " << (*c).first << std::endl; + } + } + + if (!match.size()) + return; + + if (match.size() == 1) { + std::list::iterator l; + l = match.begin(); + input.replace(0, pos, (*l)); + pos = (*l).size(); + } else { + std::list::iterator l; + for (l = match.begin(); l !=match.end(); l++) + con_print << " " << (*l) << std::endl; + } + +} + } // namespace commandbuffer } // namespace core diff --git a/src/core/commandbuffer.h b/src/core/commandbuffer.h index c18acd0..6f5b324 100644 --- a/src/core/commandbuffer.h +++ b/src/core/commandbuffer.h @@ -26,6 +26,9 @@ void execute(); /// flush the command buffer void clear(); +/// tab completion +void complete(std::string &input, size_t &pos); + } } diff --git a/src/core/cvar.h b/src/core/cvar.h index 660f03e..205a416 100644 --- a/src/core/cvar.h +++ b/src/core/cvar.h @@ -8,6 +8,7 @@ #define __INCLUDED_CORE_CVAR_H__ #include +#include namespace core { @@ -77,6 +78,9 @@ Cvar find(const char *name); /// list the cvar registry void list(); +/// the Cvar registry +extern std::map registry; + } // namespace cvar } // namespace core diff --git a/src/core/func.h b/src/core/func.h index ad189b8..3a58295 100644 --- a/src/core/func.h +++ b/src/core/func.h @@ -10,6 +10,8 @@ #include "sys/sys.h" #include +#include +#include namespace core { @@ -34,6 +36,9 @@ Func find(const std::string &functionname); /// list the function registry void list(); +/// the function registry +extern std::map registry; + } // namespace func } // namespace core diff --git a/src/render/render.cc b/src/render/render.cc index aafa9ba..fce3b6a 100644 --- a/src/render/render.cc +++ b/src/render/render.cc @@ -17,9 +17,9 @@ void init() { con_print << "Initializing renderer..." << std::endl; - con_print << " Renderer: " << gl::renderer() << std::endl; - con_print << " Vendor: " << gl::vendor() << std::endl; - con_print << " Version: " << gl::version() << std::endl; + con_print << " renderer " << gl::renderer() << std::endl; + con_print << " vendor " << gl::vendor() << std::endl; + con_print << " version " << gl::version() << std::endl; con_print << "Loading textures..." << std::endl; diff --git a/src/render/tga.cc b/src/render/tga.cc index 5aa3665..3584566 100644 --- a/src/render/tga.cc +++ b/src/render/tga.cc @@ -74,7 +74,7 @@ TGA::image *TGA::load(const char *filename) f->read((void *)&bits, sizeof(GLubyte)); f->skip(length +1); - con_debug << "TGA loading " << width << "x" << height << " " << (int) bits << "bpp" << std::endl; + con_debug << " TGA loading " << width << "x" << height << " " << (int) bits << "bpp" << std::endl; if (imgType != TGA_RLE) { // Check for 24 or 32 Bit -- cgit v1.2.3