Label completion behaves almost identical to bash completion now. If you

have labels "food" and "foobar", and no others starting with "f", and you
type "pr f<TAB>", it will show you both of them, then leave your prompt
looking like "pr foo" with the cursor after the 2nd "o".

Differences from bash:

- In case of multiple completions, bash's default behaviour requires you
  to press Tab twice to see them. We only need one Tab. bash can actually
  be configured to only need one Tab, too.

- We don't beep. Ever.

- We're case-insensitive. bash is case-sensitive by default, though it
  can be configured to be insensitive.

There's one remaining bug in the completion: when we get to the bottom of
the scroll buffer, and the buffer is full (e.g. when the scroll bar handle
is at its minimum size), *and* there's only one possible completion, the
console prints a new blank line after the new (completed) prompt.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@559 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
urchlay 2005-06-25 01:13:00 +00:00
parent b97d1937de
commit e607410e1f
3 changed files with 54 additions and 19 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: EquateList.cxx,v 1.15 2005-06-24 00:03:39 urchlay Exp $
// $Id: EquateList.cxx,v 1.16 2005-06-25 01:13:00 urchlay Exp $
//============================================================================
#include <string>
@ -182,9 +182,11 @@ bool EquateList::saveFile(string file) {
out << "--- Symbol List (sorted by symbol)" << endl;
int hardSize = sizeof(hardCodedEquates)/sizeof(struct Equate);
// we don't have these pre-loaded any more.
// int hardSize = sizeof(hardCodedEquates)/sizeof(struct Equate);
// for(int i=hardSize; i<currentSize; i++)
for(int i=hardSize; i<currentSize; i++) {
for(int i=0; i<currentSize; i++) {
int a = ourVcsEquates[i].address;
if(a >= 0) {
sprintf(buf, "%-24s %04x \n", ourVcsEquates[i].label, a);
@ -209,13 +211,19 @@ string EquateList::loadFile(string file) {
if(!in.is_open())
return "Unable to read symbols from " + file;
int hardSize = sizeof(hardCodedEquates)/sizeof(struct Equate);
// Make sure the hard-coded equates show up first
ourVcsEquates.clear();
/*
// Don't preload these: they cause more trouble than they're worth
// Besides which, any sane symfile will already have them all.
int hardSize = sizeof(hardCodedEquates)/sizeof(struct Equate);
for(int i=0; i<hardSize; i++) {
ourVcsEquates.push_back(hardCodedEquates[i]);
}
*/
while( !in.eof() ) {
curVal = 0;
@ -310,22 +318,40 @@ string EquateList::dumpAll() {
int EquateList::countCompletions(const char *in) {
int count = 0;
completions = "";
completions = compPrefix = "";
cerr << "Attempting to complete \"" << in << "\"" << endl;
// cerr << "Attempting to complete \"" << in << "\"" << endl;
for(int i=0; i<currentSize; i++) {
if(ourVcsEquates[i].address != -1) {
const char *l = ourVcsEquates[i].label;
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;
}
}
}
cerr << "Found " << count << " label(s):" << endl << completions << endl;
// cerr << "Found " << count << " label(s):" << endl << completions << endl;
return count;
}
const char *EquateList::getCompletions() {
return completions.c_str();
}
const char *EquateList::getCompletionPrefix() {
return compPrefix.c_str();
}

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: EquateList.hxx,v 1.9 2005-06-24 00:03:39 urchlay Exp $
// $Id: EquateList.hxx,v 1.10 2005-06-25 01:13:00 urchlay Exp $
//============================================================================
#ifndef EQUATELIST_HXX
@ -40,6 +40,7 @@ class EquateList {
string dumpAll();
int countCompletions(const char *in);
const char *getCompletions();
const char *getCompletionPrefix();
private:
int calcSize();
@ -47,6 +48,7 @@ class EquateList {
string extractLabel(char *c);
int extractValue(char *c);
string completions;
string compPrefix;
private:
Equates ourVcsEquates;

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.15 2005-06-24 12:01:27 stephena Exp $
// $Id: PromptWidget.cxx,v 1.16 2005-06-25 01:13:00 urchlay Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -217,34 +217,41 @@ bool PromptWidget::handleKeyDown(int ascii, int keycode, int modifiers)
break;
}
int oldPos = _currentPos;
nextLine();
int possibilities = instance()->debugger().equates()->countCompletions(str + lastSpace + 1);
if(possibilities < 1) {
delete[] str;
break;
}
nextLine();
const char *got = instance()->debugger().equates()->getCompletions();
if(possibilities == 1) {
// add to buffer as though user typed it (plus a space)
_currentPos = _promptStartPos + lastSpace + 1;
while(*got != '\0') {
_buffer[_currentPos++] = *got++;
putcharIntern(*got++);
}
_buffer[_currentPos++] = ' ';
putcharIntern(' ');
_promptEndPos = _currentPos;
} else {
// add to buffer as-is, then add PROMPT plus whatever the user's typed
// add to buffer as-is, then add PROMPT plus whatever we have so far
_currentPos = _promptStartPos + lastSpace + 1;
print("\n");
print(got);
print("\n");
print(PROMPT);
print(str);
int offset = _currentPos - oldPos;
_promptStartPos += offset;
_promptEndPos += offset;
_promptStartPos = _currentPos;
for(i=0; i<lastSpace; i++)
putcharIntern(str[i]);
putcharIntern(' ');
print( instance()->debugger().equates()->getCompletionPrefix() );
_promptEndPos = _currentPos;
}
draw();
delete[] str;