mirror of https://github.com/stella-emu/stella.git
further improved debugger tab auto complete (see #240)
This commit is contained in:
parent
4ebf3f2203
commit
abde496632
|
@ -467,13 +467,12 @@ just by re-running the relevant commands in the prompt.</p>
|
|||
<h3><a name="TabCompletion">Tab Key Auto-Complete</a></h3>
|
||||
|
||||
<p>While entering a command, label or function, you can type a partial name and
|
||||
press the Tab key to attempt to auto-complete it. If you've ever used
|
||||
press the (Shift +) Tab key to attempt to auto-complete it. If you've ever used
|
||||
"bash", this will be immediately familiar. If not, try it: load up
|
||||
a ROM, go to the debugger, type "g" (but don't press Enter),
|
||||
then hit Tab. The "g" will change to "gfx" (since this is the only
|
||||
built-in command starting with a "g"). If there are multiple possible
|
||||
completions (try with "tr" instead of "g"), you'll see a list of them,
|
||||
and your partial name will be completed as far as possible.
|
||||
completions (try with "tr" instead of "g"), you can tab through them.
|
||||
After the first character, the autocompletion considers all
|
||||
characters in the right order as a match (e.g. "twf" will be completed to
|
||||
"trapWriteIf"). Alternatively you can make use of the camel case names and type
|
||||
|
|
|
@ -160,6 +160,9 @@ bool PromptWidget::handleKeyDown(StellaKey key, StellaMod mod)
|
|||
bool handled = true;
|
||||
bool dirty = false;
|
||||
|
||||
if(key != KBDK_TAB && !StellaModTest::isShift(mod))
|
||||
_tabCount = -1;
|
||||
|
||||
switch(key)
|
||||
{
|
||||
case KBDK_RETURN:
|
||||
|
@ -209,121 +212,87 @@ bool PromptWidget::handleKeyDown(StellaKey key, StellaMod mod)
|
|||
// both at once.
|
||||
|
||||
if(_currentPos <= _promptStartPos)
|
||||
break;
|
||||
break; // no input
|
||||
|
||||
scrollToCurrent();
|
||||
|
||||
int len = _promptEndPos - _promptStartPos;
|
||||
if(len > 255) len = 255;
|
||||
|
||||
if(_tabCount != -1)
|
||||
len = int(strlen(_inputStr));
|
||||
if(len > 255)
|
||||
len = 255;
|
||||
|
||||
int lastDelimPos = -1;
|
||||
char delimiter = '\0';
|
||||
|
||||
char inputStr[256]; // NOLINT (will be rewritten soon)
|
||||
for(int i = 0; i < len; i++)
|
||||
{
|
||||
inputStr[i] = buffer(_promptStartPos + i) & 0x7f;
|
||||
// copy the input at first tab press only
|
||||
if(_tabCount == -1)
|
||||
_inputStr[i] = buffer(_promptStartPos + i) & 0x7f;
|
||||
// whitespace characters
|
||||
if(strchr("{*@<> =[]()+-/&|!^~%", inputStr[i]))
|
||||
if(strchr("{*@<> =[]()+-/&|!^~%", _inputStr[i]))
|
||||
{
|
||||
lastDelimPos = i;
|
||||
delimiter = inputStr[i];
|
||||
delimiter = _inputStr[i];
|
||||
}
|
||||
}
|
||||
inputStr[len] = '\0';
|
||||
size_t strLen = len - lastDelimPos - 1;
|
||||
if(_tabCount == -1)
|
||||
_inputStr[len] = '\0';
|
||||
|
||||
StringList list;
|
||||
string completionList;
|
||||
string prefix;
|
||||
|
||||
if(lastDelimPos < 0)
|
||||
{
|
||||
if(lastDelimPos == -1)
|
||||
// no delimiters, do only command completion:
|
||||
const DebuggerParser& parser = instance().debugger().parser();
|
||||
parser.getCompletions(inputStr, list);
|
||||
|
||||
if(list.size() < 1)
|
||||
break;
|
||||
|
||||
sort(list.begin(), list.end());
|
||||
completionList = list[0];
|
||||
for(uInt32 i = 1; i < list.size(); ++i)
|
||||
completionList += " " + list[i];
|
||||
prefix = getCompletionPrefix(list);
|
||||
}
|
||||
instance().debugger().parser().getCompletions(_inputStr, list);
|
||||
else
|
||||
{
|
||||
size_t strLen = len - lastDelimPos - 1;
|
||||
// do not show ALL commands/labels without any filter as it makes no sense
|
||||
if(strLen > 0)
|
||||
{
|
||||
// Special case for 'help' command
|
||||
if(BSPF::startsWithIgnoreCase(inputStr, "help"))
|
||||
{
|
||||
instance().debugger().parser().getCompletions(inputStr + lastDelimPos + 1, list);
|
||||
}
|
||||
if(BSPF::startsWithIgnoreCase(_inputStr, "help"))
|
||||
instance().debugger().parser().getCompletions(_inputStr + lastDelimPos + 1, list);
|
||||
else
|
||||
{
|
||||
// do not show ALL labels without any filter as it makes no sense
|
||||
if(strLen > 0)
|
||||
{
|
||||
// we got a delimiter, so this must be a label or a function
|
||||
const Debugger& dbg = instance().debugger();
|
||||
|
||||
dbg.cartDebug().getCompletions(inputStr + lastDelimPos + 1, list);
|
||||
dbg.getCompletions(inputStr + lastDelimPos + 1, list);
|
||||
dbg.cartDebug().getCompletions(_inputStr + lastDelimPos + 1, list);
|
||||
dbg.getCompletions(_inputStr + lastDelimPos + 1, list);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if(list.size() < 1)
|
||||
break;
|
||||
|
||||
sort(list.begin(), list.end());
|
||||
completionList = list[0];
|
||||
for(uInt32 i = 1; i < list.size(); ++i)
|
||||
completionList += " " + list[i];
|
||||
prefix = getCompletionPrefix(list);
|
||||
}
|
||||
|
||||
// TODO: tab through list
|
||||
|
||||
if(list.size() == 1)
|
||||
if(StellaModTest::isShift(mod))
|
||||
{
|
||||
// add to buffer as though user typed it (plus a space)
|
||||
_currentPos = _promptStartPos + lastDelimPos + 1;
|
||||
const char* clptr = completionList.c_str();
|
||||
while(*clptr != '\0')
|
||||
putcharIntern(*clptr++);
|
||||
|
||||
putcharIntern(' ');
|
||||
_promptEndPos = _currentPos;
|
||||
if(--_tabCount < 0)
|
||||
_tabCount = int(list.size()) - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_tabCount = (++_tabCount) % list.size();
|
||||
|
||||
nextLine();
|
||||
// add to buffer as-is, then add PROMPT plus whatever we have so far
|
||||
_currentPos = _promptStartPos + lastDelimPos + 1;
|
||||
_currentPos = _promptStartPos;
|
||||
killLine(1); // kill whole line
|
||||
|
||||
print("\n");
|
||||
print(completionList);
|
||||
print("\n");
|
||||
print(PROMPT);
|
||||
|
||||
_promptStartPos = _currentPos;
|
||||
|
||||
if(prefix.length() < strLen)
|
||||
{
|
||||
for(int i = 0; i < len; i++)
|
||||
putcharIntern(inputStr[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// start with-autocompleted, fixed string...
|
||||
for(int i = 0; i < lastDelimPos; i++)
|
||||
putcharIntern(inputStr[i]);
|
||||
|
||||
putcharIntern(_inputStr[i]);
|
||||
if(lastDelimPos > 0)
|
||||
putcharIntern(delimiter);
|
||||
|
||||
print(prefix);
|
||||
}
|
||||
// ...and add current autocompletion string
|
||||
print(list[_tabCount]);
|
||||
putcharIntern(' ');
|
||||
_promptEndPos = _currentPos;
|
||||
}
|
||||
|
||||
dirty = true;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -122,6 +122,8 @@ class PromptWidget : public Widget, public CommandSender
|
|||
int _historySize;
|
||||
int _historyIndex;
|
||||
int _historyLine;
|
||||
int _tabCount{-1};
|
||||
char _inputStr[256];
|
||||
|
||||
int _kConsoleCharWidth, _kConsoleCharHeight, _kConsoleLineHeight;
|
||||
|
||||
|
|
Loading…
Reference in New Issue