From 865416aacd804c43507b0b0425805eaef0dc2857 Mon Sep 17 00:00:00 2001 From: urchlay Date: Mon, 27 Jun 2005 03:32:51 +0000 Subject: [PATCH] First pass at command completion. Actually this may be the only pass: it seems to be working just fine. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@567 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba --- stella/src/debugger/Debugger.hxx | 5 ++- stella/src/debugger/DebuggerParser.cxx | 44 +++++++++++++++++++- stella/src/debugger/DebuggerParser.hxx | 8 +++- stella/src/gui/PromptWidget.cxx | 56 +++++++++++++++++--------- 4 files changed, 90 insertions(+), 23 deletions(-) diff --git a/stella/src/debugger/Debugger.hxx b/stella/src/debugger/Debugger.hxx index 56f4348fb..673e2c7bb 100644 --- a/stella/src/debugger/Debugger.hxx +++ b/stella/src/debugger/Debugger.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: Debugger.hxx,v 1.31 2005-06-24 16:36:41 urchlay Exp $ +// $Id: Debugger.hxx,v 1.32 2005-06-27 03:32:50 urchlay Exp $ //============================================================================ #ifndef DEBUGGER_HXX @@ -51,7 +51,7 @@ enum { for all debugging operations in Stella (parser, 6502 debugger, etc). @author Stephen Anthony - @version $Id: Debugger.hxx,v 1.31 2005-06-24 16:36:41 urchlay Exp $ + @version $Id: Debugger.hxx,v 1.32 2005-06-27 03:32:50 urchlay Exp $ */ class Debugger : public DialogContainer { @@ -228,6 +228,7 @@ class Debugger : public DialogContainer PackedBitArray *readtraps() { return readTraps; } PackedBitArray *writetraps() { return writeTraps; } + DebuggerParser *parser() { return myParser; } protected: Console* myConsole; System* mySystem; diff --git a/stella/src/debugger/DebuggerParser.cxx b/stella/src/debugger/DebuggerParser.cxx index a995e4791..178daf822 100644 --- a/stella/src/debugger/DebuggerParser.cxx +++ b/stella/src/debugger/DebuggerParser.cxx @@ -13,14 +13,14 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: DebuggerParser.cxx,v 1.36 2005-06-27 01:36:00 urchlay Exp $ +// $Id: DebuggerParser.cxx,v 1.37 2005-06-27 03:32:51 urchlay Exp $ //============================================================================ #include "bspf.hxx" #include "Debugger.hxx" #include "DebuggerParser.hxx" #include "D6502.hxx" -#include "EquateList.hxx" +#include "DebuggerParser.hxx" // TODO: finish this, replace run() and getArgs() with versions // that use this table. @@ -839,6 +839,46 @@ string DebuggerParser::run(const string& command) { return commandResult; } +// completion-related stuff: +int DebuggerParser::countCompletions(const char *in) { + int count = 0, i = 0; + completions = compPrefix = ""; + + // cerr << "Attempting to complete \"" << in << "\"" << endl; + do { + const char *l = commands[i].cmdString.c_str(); + + if(STR_N_CASE_CMP(l, in, strlen(in)) == 0) { + if(compPrefix == "") + compPrefix += l; + else { + int nonMatch = 0; + const char *c = compPrefix.c_str(); + while(*c != '\0' && tolower(*c) == tolower(l[nonMatch])) { + c++; + nonMatch++; + } + compPrefix.erase(nonMatch, compPrefix.length()); + // cerr << "compPrefix==" << compPrefix << endl; + } + + if(count++) completions += " "; + completions += l; + } + } while(commands[++i].cmdString != ""); + + // cerr << "Found " << count << " label(s):" << endl << completions << endl; + return count; +} + +const char *DebuggerParser::getCompletions() { + return completions.c_str(); +} + +const char *DebuggerParser::getCompletionPrefix() { + return compPrefix.c_str(); +} + ////// executor methods for commands[] array. All are void, no args. // "a" diff --git a/stella/src/debugger/DebuggerParser.hxx b/stella/src/debugger/DebuggerParser.hxx index 31bc01262..a26233265 100644 --- a/stella/src/debugger/DebuggerParser.hxx +++ b/stella/src/debugger/DebuggerParser.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: DebuggerParser.hxx,v 1.18 2005-06-27 01:36:03 urchlay Exp $ +// $Id: DebuggerParser.hxx,v 1.19 2005-06-27 03:32:51 urchlay Exp $ //============================================================================ #ifndef DEBUGGER_PARSER_HXX @@ -51,6 +51,9 @@ class DebuggerParser string addWatch(string watch); string delWatch(int which); void delAllWatches(); + int countCompletions(const char *in); + const char *getCompletions(); + const char *getCompletionPrefix(); private: @@ -80,6 +83,9 @@ class DebuggerParser StringArray watches; static Command commands[]; + string completions; + string compPrefix; + void executeA(); void executeBase(); void executeBreak(); diff --git a/stella/src/gui/PromptWidget.cxx b/stella/src/gui/PromptWidget.cxx index 8baa71edd..a4e6f87ef 100644 --- a/stella/src/gui/PromptWidget.cxx +++ b/stella/src/gui/PromptWidget.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: PromptWidget.cxx,v 1.19 2005-06-25 17:26:32 stephena Exp $ +// $Id: PromptWidget.cxx,v 1.20 2005-06-27 03:32:51 urchlay Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -28,6 +28,7 @@ #include "Version.hxx" #include "Debugger.hxx" #include "DebuggerDialog.hxx" +#include "DebuggerParser.hxx" #include "PromptWidget.hxx" #include "EquateList.hxx" @@ -195,13 +196,14 @@ bool PromptWidget::handleKeyDown(int ascii, int keycode, int modifiers) case 27: // escape FIXME - possibly remove this one? case 9: // tab { + // Tab completion: we complete either commands or labels, but not + // both at once. + if(_currentPos <= _promptStartPos) break; scrollToCurrent(); int len = _promptEndPos - _promptStartPos; - if(len < 2) // minimum length for a command + a space is 2 - break; int lastDelimPos = -1; char delimiter = '\0'; @@ -216,25 +218,41 @@ bool PromptWidget::handleKeyDown(int ascii, int keycode, int modifiers) } str[len] = '\0'; + const char *completionList; + const char *prefix; + int possibilities; + if(lastDelimPos < 0) { - delete[] str; - break; - } + // no delimiters, do command completion: + DebuggerParser *parser = instance()->debugger().parser(); + possibilities = parser->countCompletions(str); - EquateList *equates = instance()->debugger().equates(); - int possibilities = equates->countCompletions(str + lastDelimPos + 1); - if(possibilities < 1) { - delete[] str; - break; - } + if(possibilities < 1) { + delete[] str; + break; + } - const char *got = equates->getCompletions(); + completionList = parser->getCompletions(); + prefix = parser->getCompletionPrefix(); + } else { + // we got a delimiter, so this must be a label: + EquateList *equates = instance()->debugger().equates(); + possibilities = equates->countCompletions(str + lastDelimPos + 1); + + if(possibilities < 1) { + delete[] str; + break; + } + + completionList = equates->getCompletions(); + prefix = equates->getCompletionPrefix(); + } if(possibilities == 1) { // add to buffer as though user typed it (plus a space) _currentPos = _promptStartPos + lastDelimPos + 1; - while(*got != '\0') { - putcharIntern(*got++); + while(*completionList != '\0') { + putcharIntern(*completionList++); } putcharIntern(' '); _promptEndPos = _currentPos; @@ -244,7 +262,7 @@ bool PromptWidget::handleKeyDown(int ascii, int keycode, int modifiers) _currentPos = _promptStartPos + lastDelimPos + 1; print("\n"); - print(got); + print(completionList); print("\n"); print(PROMPT); @@ -253,8 +271,10 @@ bool PromptWidget::handleKeyDown(int ascii, int keycode, int modifiers) for(i=0; igetCompletionPrefix() ); + if(lastDelimPos > 0) + putcharIntern(delimiter); + + print(prefix); _promptEndPos = _currentPos; } draw();