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
This commit is contained in:
urchlay 2005-06-27 03:32:51 +00:00
parent 408a90142a
commit 865416aacd
4 changed files with 90 additions and 23 deletions

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // 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 #ifndef DEBUGGER_HXX
@ -51,7 +51,7 @@ enum {
for all debugging operations in Stella (parser, 6502 debugger, etc). for all debugging operations in Stella (parser, 6502 debugger, etc).
@author Stephen Anthony @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 class Debugger : public DialogContainer
{ {
@ -228,6 +228,7 @@ class Debugger : public DialogContainer
PackedBitArray *readtraps() { return readTraps; } PackedBitArray *readtraps() { return readTraps; }
PackedBitArray *writetraps() { return writeTraps; } PackedBitArray *writetraps() { return writeTraps; }
DebuggerParser *parser() { return myParser; }
protected: protected:
Console* myConsole; Console* myConsole;
System* mySystem; System* mySystem;

View File

@ -13,14 +13,14 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // 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 "bspf.hxx"
#include "Debugger.hxx" #include "Debugger.hxx"
#include "DebuggerParser.hxx" #include "DebuggerParser.hxx"
#include "D6502.hxx" #include "D6502.hxx"
#include "EquateList.hxx" #include "DebuggerParser.hxx"
// TODO: finish this, replace run() and getArgs() with versions // TODO: finish this, replace run() and getArgs() with versions
// that use this table. // that use this table.
@ -839,6 +839,46 @@ string DebuggerParser::run(const string& command) {
return commandResult; 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. ////// executor methods for commands[] array. All are void, no args.
// "a" // "a"

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // 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 #ifndef DEBUGGER_PARSER_HXX
@ -51,6 +51,9 @@ class DebuggerParser
string addWatch(string watch); string addWatch(string watch);
string delWatch(int which); string delWatch(int which);
void delAllWatches(); void delAllWatches();
int countCompletions(const char *in);
const char *getCompletions();
const char *getCompletionPrefix();
private: private:
@ -80,6 +83,9 @@ class DebuggerParser
StringArray watches; StringArray watches;
static Command commands[]; static Command commands[];
string completions;
string compPrefix;
void executeA(); void executeA();
void executeBase(); void executeBase();
void executeBreak(); void executeBreak();

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // 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 // Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project // Copyright (C) 2002-2004 The ScummVM project
@ -28,6 +28,7 @@
#include "Version.hxx" #include "Version.hxx"
#include "Debugger.hxx" #include "Debugger.hxx"
#include "DebuggerDialog.hxx" #include "DebuggerDialog.hxx"
#include "DebuggerParser.hxx"
#include "PromptWidget.hxx" #include "PromptWidget.hxx"
#include "EquateList.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 27: // escape FIXME - possibly remove this one?
case 9: // tab case 9: // tab
{ {
// Tab completion: we complete either commands or labels, but not
// both at once.
if(_currentPos <= _promptStartPos) if(_currentPos <= _promptStartPos)
break; break;
scrollToCurrent(); scrollToCurrent();
int len = _promptEndPos - _promptStartPos; int len = _promptEndPos - _promptStartPos;
if(len < 2) // minimum length for a command + a space is 2
break;
int lastDelimPos = -1; int lastDelimPos = -1;
char delimiter = '\0'; char delimiter = '\0';
@ -216,25 +218,41 @@ bool PromptWidget::handleKeyDown(int ascii, int keycode, int modifiers)
} }
str[len] = '\0'; str[len] = '\0';
const char *completionList;
const char *prefix;
int possibilities;
if(lastDelimPos < 0) { if(lastDelimPos < 0) {
delete[] str; // no delimiters, do command completion:
break; DebuggerParser *parser = instance()->debugger().parser();
} possibilities = parser->countCompletions(str);
EquateList *equates = instance()->debugger().equates(); if(possibilities < 1) {
int possibilities = equates->countCompletions(str + lastDelimPos + 1); delete[] str;
if(possibilities < 1) { break;
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) { if(possibilities == 1) {
// add to buffer as though user typed it (plus a space) // add to buffer as though user typed it (plus a space)
_currentPos = _promptStartPos + lastDelimPos + 1; _currentPos = _promptStartPos + lastDelimPos + 1;
while(*got != '\0') { while(*completionList != '\0') {
putcharIntern(*got++); putcharIntern(*completionList++);
} }
putcharIntern(' '); putcharIntern(' ');
_promptEndPos = _currentPos; _promptEndPos = _currentPos;
@ -244,7 +262,7 @@ bool PromptWidget::handleKeyDown(int ascii, int keycode, int modifiers)
_currentPos = _promptStartPos + lastDelimPos + 1; _currentPos = _promptStartPos + lastDelimPos + 1;
print("\n"); print("\n");
print(got); print(completionList);
print("\n"); print("\n");
print(PROMPT); print(PROMPT);
@ -253,8 +271,10 @@ bool PromptWidget::handleKeyDown(int ascii, int keycode, int modifiers)
for(i=0; i<lastDelimPos; i++) for(i=0; i<lastDelimPos; i++)
putcharIntern(str[i]); putcharIntern(str[i]);
putcharIntern(delimiter); if(lastDelimPos > 0)
print( equates->getCompletionPrefix() ); putcharIntern(delimiter);
print(prefix);
_promptEndPos = _currentPos; _promptEndPos = _currentPos;
} }
draw(); draw();