From 6848115c18de36747269b1f8bc1a62f11a6c5592 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 12 Jan 2011 18:24:00 +0100 Subject: [PATCH 1/2] backend for tab completion: keywords --- apps/openmw/mwgui/console.cpp | 22 ++++++++++++++ apps/openmw/mwgui/console.hpp | 11 +++++-- components/compiler/extensions.cpp | 7 +++++ components/compiler/extensions.hpp | 3 ++ components/compiler/scanner.cpp | 47 ++++++++++++++++++------------ components/compiler/scanner.hpp | 21 +++++++------ 6 files changed, 80 insertions(+), 31 deletions(-) diff --git a/apps/openmw/mwgui/console.cpp b/apps/openmw/mwgui/console.cpp index 471b2810b..35381a957 100644 --- a/apps/openmw/mwgui/console.cpp +++ b/apps/openmw/mwgui/console.cpp @@ -1,6 +1,8 @@ #include "console.hpp" +#include + #include #include "../mwscript/extensions.hpp" @@ -26,6 +28,12 @@ namespace MWGui bool Console::compile (const std::string& cmd, Compiler::Output& output) { + + listNames(); + for (std::vector::iterator iter (mNames.begin()); iter!=mNames.end(); ++iter) + std::cout << *iter << ", "; + std::cout << std::endl; + try { ErrorHandler::reset(); @@ -67,6 +75,20 @@ namespace MWGui printError ((type==ErrorMessage ? "error: " : "warning: ") + message); } + void Console::listNames() + { + if (mNames.empty()) + { + std::istringstream input (""); + + Compiler::Scanner scanner (*this, input, mCompilerContext.getExtensions()); + + scanner.listKeywords (mNames); + + std::sort (mNames.begin(), mNames.end()); + } + } + Console::Console(int w, int h, MWWorld::Environment& environment, const Compiler::Extensions& extensions) : Layout("openmw_console_layout.xml"), diff --git a/apps/openmw/mwgui/console.hpp b/apps/openmw/mwgui/console.hpp index 25212d627..4a80cde99 100644 --- a/apps/openmw/mwgui/console.hpp +++ b/apps/openmw/mwgui/console.hpp @@ -21,10 +21,11 @@ namespace MWGui class Console : private OEngine::GUI::Layout, private Compiler::ErrorHandler { private: - + MWScript::CompilerContext mCompilerContext; MWWorld::Environment& mEnvironment; - + std::vector mNames; + bool compile (const std::string& cmd, Compiler::Output& output); /// Report error to the user. @@ -32,7 +33,11 @@ namespace MWGui /// Report a file related error virtual void report (const std::string& message, Type type); - + + void listNames(); + ///< Write all valid identifiers and keywords into mNames and sort them. + /// \note If mNames is not empty, this function is a no-op. + public: MyGUI::EditPtr command; MyGUI::EditPtr history; diff --git a/components/compiler/extensions.cpp b/components/compiler/extensions.cpp index 3b1d180b1..c6a74b234 100644 --- a/components/compiler/extensions.cpp +++ b/components/compiler/extensions.cpp @@ -207,4 +207,11 @@ namespace Compiler throw std::logic_error ("unsupported code segment"); } } + + void Extensions::listKeywords (std::vector& keywords) const + { + for (std::map::const_iterator iter (mKeywords.begin()); + iter!=mKeywords.end(); ++iter) + keywords.push_back (iter->first); + } } diff --git a/components/compiler/extensions.hpp b/components/compiler/extensions.hpp index 960cac157..53ebfa31b 100644 --- a/components/compiler/extensions.hpp +++ b/components/compiler/extensions.hpp @@ -78,6 +78,9 @@ namespace Compiler void generateInstructionCode (int keyword, std::vector& code, Literals& literals, const std::string& id, int optionalArguments) const; ///< Append code for function to \a code. + + void listKeywords (std::vector& keywords) const; + ///< Append all known keywords to \æ kaywords. }; } diff --git a/components/compiler/scanner.cpp b/components/compiler/scanner.cpp index 310fc9ec5..080ca7d98 100644 --- a/components/compiler/scanner.cpp +++ b/components/compiler/scanner.cpp @@ -230,27 +230,27 @@ namespace Compiler return true; } + static const char *keywords[] = + { + "begin", "end", + "short", "long", "float", + "if", "endif", "else", "elseif", + "while", "endwhile", + "return", + "messagebox", + "set", "to", + "getsquareroot", + "menumode", + "random", + "startscript", "stopscript", "scriptrunning", + "getdistance", + "getsecondspassed", + "enable", "disable", "getdisabled", + 0 + }; + bool Scanner::scanName (char c, Parser& parser, bool& cont) { - static const char *keywords[] = - { - "begin", "end", - "short", "long", "float", - "if", "endif", "else", "elseif", - "while", "endwhile", - "return", - "messagebox", - "set", "to", - "getsquareroot", - "menumode", - "random", - "startscript", "stopscript", "scriptrunning", - "getdistance", - "getsecondspassed", - "enable", "disable", "getdisabled", - 0 - }; - std::string name; if (!scanName (c, name)) @@ -513,4 +513,13 @@ namespace Compiler mPutbackCode = keyword; mPutbackLoc = loc; } + + void Scanner::listKeywords (std::vector& keywords) + { + for (int i=0; Compiler::keywords[i]; ++i) + keywords.push_back (Compiler::keywords[i]); + + if (mExtensions) + mExtensions->listKeywords (keywords); + } } diff --git a/components/compiler/scanner.hpp b/components/compiler/scanner.hpp index da0bfa17a..53cb92ef2 100644 --- a/components/compiler/scanner.hpp +++ b/components/compiler/scanner.hpp @@ -3,6 +3,7 @@ #include #include +#include #include "tokenloc.hpp" @@ -24,7 +25,7 @@ namespace Compiler Putback_None, Putback_Special, Putback_Integer, Putback_Float, Putback_Name, Putback_Keyword }; - + ErrorHandler& mErrorHandler; TokenLoc mLoc; TokenLoc mPrevLoc; @@ -101,21 +102,23 @@ namespace Compiler void scan (Parser& parser); ///< Scan a token and deliver it to the parser. - void putbackSpecial (int code, const TokenLoc& loc); + void putbackSpecial (int code, const TokenLoc& loc); ///< put back a special token - void putbackInt (int value, const TokenLoc& loc); - ///< put back an integer token + void putbackInt (int value, const TokenLoc& loc); + ///< put back an integer token - void putbackFloat (float value, const TokenLoc& loc); - ///< put back a float token + void putbackFloat (float value, const TokenLoc& loc); + ///< put back a float token - void putbackName (const std::string& name, const TokenLoc& loc); + void putbackName (const std::string& name, const TokenLoc& loc); ///< put back a name toekn - void putbackKeyword (int keyword, const TokenLoc& loc); + void putbackKeyword (int keyword, const TokenLoc& loc); ///< put back a keyword token - + + void listKeywords (std::vector& keywords); + ///< Append all known keywords to \æ kaywords. }; } From d865c3cfc6330b75e4471499c397ee2b697ca138 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 12 Jan 2011 18:48:37 +0100 Subject: [PATCH 2/2] backend for tab completion: identifiers --- apps/openmw/mwgui/console.cpp | 11 ++++++++ apps/openmw/mwgui/console.hpp | 2 ++ components/esm_store/reclists.hpp | 44 ++++++++++++++++++++++++++++--- 3 files changed, 53 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwgui/console.cpp b/apps/openmw/mwgui/console.cpp index 35381a957..07905bcb9 100644 --- a/apps/openmw/mwgui/console.cpp +++ b/apps/openmw/mwgui/console.cpp @@ -79,12 +79,23 @@ namespace MWGui { if (mNames.empty()) { + // keywords std::istringstream input (""); Compiler::Scanner scanner (*this, input, mCompilerContext.getExtensions()); scanner.listKeywords (mNames); + // identifier + const ESMS::ESMStore& store = mEnvironment.mWorld->getStore(); + + for (ESMS::RecListList::const_iterator iter (store.recLists.begin()); + iter!=store.recLists.end(); ++iter) + { + iter->second->listIdentifier (mNames); + } + + // sort std::sort (mNames.begin(), mNames.end()); } } diff --git a/apps/openmw/mwgui/console.hpp b/apps/openmw/mwgui/console.hpp index 4a80cde99..d08ac5887 100644 --- a/apps/openmw/mwgui/console.hpp +++ b/apps/openmw/mwgui/console.hpp @@ -37,6 +37,8 @@ namespace MWGui void listNames(); ///< Write all valid identifiers and keywords into mNames and sort them. /// \note If mNames is not empty, this function is a no-op. + /// \note The list may contain duplicates (if a name is a keyword and an identifier at the same + /// time). public: MyGUI::EditPtr command; diff --git a/components/esm_store/reclists.hpp b/components/esm_store/reclists.hpp index a03e325a9..9dd42b7b9 100644 --- a/components/esm_store/reclists.hpp +++ b/components/esm_store/reclists.hpp @@ -4,6 +4,7 @@ #include "components/esm/records.hpp" #include #include +#include #include #include #include @@ -14,7 +15,7 @@ using namespace boost::algorithm; - + namespace ESMS { using namespace ESM; @@ -23,6 +24,7 @@ namespace ESMS { virtual void load(ESMReader &esm, const std::string &id) = 0; virtual int getSize() = 0; + virtual void listIdentifier (std::vector& identifier) const = 0; static std::string toLower (const std::string& name) { @@ -76,6 +78,12 @@ namespace ESMS } int getSize() { return list.size(); } + + virtual void listIdentifier (std::vector& identifier) const + { + for (typename MapType::const_iterator iter (list.begin()); iter!=list.end(); ++iter) + identifier.push_back (iter->first); + } }; /// Modified version of RecListT for records, that need to store their own ID @@ -117,6 +125,12 @@ namespace ESMS } int getSize() { return list.size(); } + + virtual void listIdentifier (std::vector& identifier) const + { + for (typename MapType::const_iterator iter (list.begin()); iter!=list.end(); ++iter) + identifier.push_back (iter->first); + } }; // The only difference to the above is a slight change to the load() @@ -163,6 +177,12 @@ namespace ESMS } int getSize() { return list.size(); } + + virtual void listIdentifier (std::vector& identifier) const + { + for (typename MapType::const_iterator iter (list.begin()); iter!=list.end(); ++iter) + identifier.push_back (iter->first); + } }; /* Land textures are indexed by an integer number @@ -181,6 +201,8 @@ namespace ESMS int getSize() { return count; } + virtual void listIdentifier (std::vector& identifier) const {} + void load(ESMReader &esm, const std::string &id) { LandTexture lt; @@ -210,6 +232,8 @@ namespace ESMS LandList() : count(0) {} int getSize() { return count; } + virtual void listIdentifier (std::vector& identifier) const {} + // Find land for the given coordinates. Return null if no data. const Land *search(int x, int y) const { @@ -246,7 +270,7 @@ namespace ESMS } }; - + // Cells aren't simply indexed by name. Exterior cells are treated // separately. // TODO: case handling (cell names are case-insensitive, but they are also showen to the @@ -267,6 +291,12 @@ namespace ESMS typedef std::map ExtCells; ExtCells extCells; + virtual void listIdentifier (std::vector& identifier) const + { + for (IntCells::const_iterator iter (intCells.begin()); iter!=intCells.end(); ++iter) + identifier.push_back (iter->first); + } + ~CellList() { for (IntCells::iterator it = intCells.begin(); it!=intCells.end(); ++it) @@ -407,6 +437,12 @@ namespace ESMS } int getSize() { return list.size(); } + + virtual void listIdentifier (std::vector& identifier) const + { + for (typename MapType::const_iterator iter (list.begin()); iter!=list.end(); ++iter) + identifier.push_back (iter->first); + } }; template @@ -429,6 +465,8 @@ namespace ESMS return list.size(); } + virtual void listIdentifier (std::vector& identifier) const {} + // Find the given object ID, or return NULL if not found. const X* search (int id) const { @@ -458,9 +496,7 @@ namespace ESMS /* We need special lists for: - Land Path grids - Land textures */ } #endif