mirror of https://github.com/stella-emu/stella.git
refactored history buffer and increased max size from 20 to 1000
This commit is contained in:
parent
2420988cab
commit
587bdee678
|
@ -542,19 +542,41 @@ void PromptWidget::textPaste()
|
|||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
int PromptWidget::historyDir(int& index, int direction, bool promptSpace)
|
||||
{
|
||||
int historySize = int(_history.size()) + (promptSpace ? 1 : 0);
|
||||
|
||||
index += direction;
|
||||
if(index < 0)
|
||||
index += historySize;
|
||||
else
|
||||
index %= historySize;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void PromptWidget::historyAdd(const string& entry)
|
||||
{
|
||||
if(_historyIndex >= _history.size())
|
||||
_history.push_back(entry);
|
||||
else
|
||||
_history[_historyIndex] = entry;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void PromptWidget::addToHistory(const char* str)
|
||||
{
|
||||
// Do not add duplicates, remove old duplicate
|
||||
if(_historySize)
|
||||
if(_history.size())
|
||||
{
|
||||
int i = _historyIndex;
|
||||
int historyEnd = _historyIndex % _historySize;
|
||||
int historyEnd = _historyIndex % _history.size();
|
||||
|
||||
do
|
||||
{
|
||||
if(--i < 0)
|
||||
i =_historySize - 1;
|
||||
historyDir(i, -1);
|
||||
|
||||
if(!BSPF::compareIgnoreCase(_history[i], str))
|
||||
{
|
||||
|
@ -563,76 +585,55 @@ void PromptWidget::addToHistory(const char* str)
|
|||
do
|
||||
{
|
||||
prevJ = j;
|
||||
j = (j + 1) % (_historySize);
|
||||
historyDir(j, +1);
|
||||
_history[prevJ] = _history[j];
|
||||
}
|
||||
while(j != historyEnd);
|
||||
|
||||
#if defined(BSPF_WINDOWS)
|
||||
strncpy_s(_history[prevJ], kLineBufferSize, _history[j], kLineBufferSize - 1);
|
||||
#else
|
||||
strncpy(_history[prevJ], _history[j], kLineBufferSize - 1);
|
||||
#endif
|
||||
} while(j != historyEnd);
|
||||
|
||||
if(--_historyIndex < 0)
|
||||
_historyIndex = _historySize - 1;
|
||||
_historySize--;
|
||||
historyDir(_historyIndex, -1);
|
||||
break;
|
||||
}
|
||||
} while(i != historyEnd);
|
||||
}
|
||||
|
||||
#if defined(BSPF_WINDOWS)
|
||||
strncpy_s(_history[_historyIndex], kLineBufferSize, str, kLineBufferSize - 1);
|
||||
#else
|
||||
strncpy(_history[_historyIndex], str, kLineBufferSize - 1);
|
||||
#endif
|
||||
_historyIndex = (_historyIndex + 1) % kHistorySize;
|
||||
while(i != historyEnd);
|
||||
}
|
||||
historyAdd(str);
|
||||
_historyLine = 0; // reset history scroll
|
||||
|
||||
if (_historySize < kHistorySize)
|
||||
_historySize++;
|
||||
_historyIndex = (_historyIndex + 1) % kHistorySize;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool PromptWidget::historyScroll(int direction)
|
||||
{
|
||||
if(_historySize == 0)
|
||||
if(_history.size() == 0)
|
||||
return false;
|
||||
|
||||
if(_historyLine == 0)
|
||||
{
|
||||
int i;
|
||||
string input;
|
||||
|
||||
for(i = 0; i < _promptEndPos - _promptStartPos; i++)
|
||||
_history[_historyIndex][i] = buffer(_promptStartPos + i); //FIXME: int to char??
|
||||
for(int i = _promptStartPos; i < _promptEndPos; i++)
|
||||
input += buffer(i) & 0x7f;
|
||||
|
||||
_history[_historyIndex][i] = '\0';
|
||||
historyAdd(input);
|
||||
}
|
||||
|
||||
// Advance to the next line in the history
|
||||
int histSize = _historySize + (_historySize < kHistorySize ? 1 : 0);
|
||||
int line = _historyLine + direction;
|
||||
// Advance to the next/prev line in the history
|
||||
historyDir(_historyLine, direction, _history.size() < kHistorySize);
|
||||
|
||||
if(line < 0)
|
||||
line += histSize;
|
||||
line %= histSize;
|
||||
|
||||
// If anything in the buffer, search the history.
|
||||
if(_currentPos > _promptStartPos) {
|
||||
// Search the history using the original input
|
||||
do
|
||||
{
|
||||
int idx = line ? (_historyIndex - line + _historySize) % _historySize
|
||||
int idx = _historyLine
|
||||
? (_historyIndex - _historyLine + _history.size()) % int(_history.size())
|
||||
: _historyIndex;
|
||||
|
||||
if(BSPF::startsWithIgnoreCase(_history[idx], _history[_historyIndex]))
|
||||
break;
|
||||
|
||||
line += direction;
|
||||
if(line < 0)
|
||||
line += histSize;
|
||||
line %= histSize;
|
||||
} while(line); // if line == 0, nothing was found
|
||||
// Advance to the next/prev line in the history
|
||||
historyDir(_historyLine, direction, _history.size() < kHistorySize);
|
||||
}
|
||||
_historyLine = line;
|
||||
while(_historyLine); // If _historyLine == 0, nothing was found
|
||||
|
||||
// Remove the current user text
|
||||
_currentPos = _promptStartPos;
|
||||
|
@ -642,7 +643,8 @@ bool PromptWidget::historyScroll(int direction)
|
|||
scrollToCurrent();
|
||||
|
||||
// Print the text from the history
|
||||
int idx = _historyLine ? (_historyIndex - _historyLine + _historySize) % _historySize
|
||||
int idx = _historyLine
|
||||
? (_historyIndex - _historyLine + _history.size()) % int(_history.size())
|
||||
: _historyIndex;
|
||||
|
||||
for(int i = 0; i < kLineBufferSize && _history[idx][i] != '\0'; i++)
|
||||
|
@ -652,7 +654,7 @@ bool PromptWidget::historyScroll(int direction)
|
|||
// Ensure once more the caret is visible (in case of very long history entries)
|
||||
scrollToCurrent();
|
||||
|
||||
return line;
|
||||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -42,8 +42,6 @@ class PromptWidget : public Widget, public CommandSender
|
|||
~PromptWidget() override = default;
|
||||
|
||||
public:
|
||||
ATTRIBUTE_FMT_PRINTF int printf(const char* format, ...);
|
||||
ATTRIBUTE_FMT_PRINTF int vprintf(const char* format, va_list argptr);
|
||||
void print(const string& str);
|
||||
void printPrompt();
|
||||
string saveBuffer(const FilesystemNode& file);
|
||||
|
@ -54,6 +52,8 @@ class PromptWidget : public Widget, public CommandSender
|
|||
void addToHistory(const char *str);
|
||||
|
||||
protected:
|
||||
ATTRIBUTE_FMT_PRINTF int printf(const char* format, ...);
|
||||
ATTRIBUTE_FMT_PRINTF int vprintf(const char* format, va_list argptr);
|
||||
int& buffer(int idx) { return _buffer[idx % kBufferSize]; }
|
||||
|
||||
void drawWidget(bool hilite) override;
|
||||
|
@ -99,7 +99,7 @@ class PromptWidget : public Widget, public CommandSender
|
|||
enum {
|
||||
kBufferSize = 32768,
|
||||
kLineBufferSize = 256,
|
||||
kHistorySize = 50
|
||||
kHistorySize = 1000
|
||||
};
|
||||
|
||||
int _buffer[kBufferSize]; // NOLINT (will be rewritten soon)
|
||||
|
@ -117,8 +117,7 @@ class PromptWidget : public Widget, public CommandSender
|
|||
|
||||
ScrollBarWidget* _scrollBar;
|
||||
|
||||
char _history[kHistorySize][kLineBufferSize]; // NOLINT (will be rewritten soon)
|
||||
int _historySize{0};
|
||||
std::vector<string> _history;
|
||||
int _historyIndex{0};
|
||||
int _historyLine{0};
|
||||
int _tabCount{-1};
|
||||
|
@ -130,6 +129,9 @@ class PromptWidget : public Widget, public CommandSender
|
|||
bool _firstTime{true};
|
||||
bool _exitedEarly{false};
|
||||
|
||||
int historyDir(int& index, int direction, bool promptSpace = false);
|
||||
void historyAdd(const string& entry);
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
PromptWidget() = delete;
|
||||
|
|
Loading…
Reference in New Issue