mirror of https://github.com/stella-emu/stella.git
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:
parent
408a90142a
commit
865416aacd
|
@ -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;
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue