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
// 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;

View File

@ -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"

View File

@ -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();

View File

@ -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; i<lastDelimPos; i++)
putcharIntern(str[i]);
putcharIntern(delimiter);
print( equates->getCompletionPrefix() );
if(lastDelimPos > 0)
putcharIntern(delimiter);
print(prefix);
_promptEndPos = _currentPos;
}
draw();