refactored history buffer and increased max size from 20 to 1000

This commit is contained in:
Thomas Jentzsch 2021-05-10 16:06:43 +02:00
parent 2420988cab
commit 587bdee678
2 changed files with 64 additions and 60 deletions

View File

@ -542,19 +542,41 @@ void PromptWidget::textPaste()
#endif #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) void PromptWidget::addToHistory(const char* str)
{ {
// Do not add duplicates, remove old duplicate // Do not add duplicates, remove old duplicate
if(_historySize) if(_history.size())
{ {
int i = _historyIndex; int i = _historyIndex;
int historyEnd = _historyIndex % _historySize; int historyEnd = _historyIndex % _history.size();
do do
{ {
if(--i < 0) historyDir(i, -1);
i =_historySize - 1;
if(!BSPF::compareIgnoreCase(_history[i], str)) if(!BSPF::compareIgnoreCase(_history[i], str))
{ {
@ -563,76 +585,55 @@ void PromptWidget::addToHistory(const char* str)
do do
{ {
prevJ = j; prevJ = j;
j = (j + 1) % (_historySize); historyDir(j, +1);
_history[prevJ] = _history[j];
}
while(j != historyEnd);
#if defined(BSPF_WINDOWS) historyDir(_historyIndex, -1);
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--;
break; break;
} }
} while(i != historyEnd);
} }
while(i != historyEnd);
#if defined(BSPF_WINDOWS) }
strncpy_s(_history[_historyIndex], kLineBufferSize, str, kLineBufferSize - 1); historyAdd(str);
#else
strncpy(_history[_historyIndex], str, kLineBufferSize - 1);
#endif
_historyIndex = (_historyIndex + 1) % kHistorySize;
_historyLine = 0; // reset history scroll _historyLine = 0; // reset history scroll
_historyIndex = (_historyIndex + 1) % kHistorySize;
if (_historySize < kHistorySize)
_historySize++;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool PromptWidget::historyScroll(int direction) bool PromptWidget::historyScroll(int direction)
{ {
if(_historySize == 0) if(_history.size() == 0)
return false; return false;
if(_historyLine == 0) if(_historyLine == 0)
{ {
int i; string input;
for(i = 0; i < _promptEndPos - _promptStartPos; i++) for(int i = _promptStartPos; i < _promptEndPos; i++)
_history[_historyIndex][i] = buffer(_promptStartPos + i); //FIXME: int to char?? input += buffer(i) & 0x7f;
_history[_historyIndex][i] = '\0'; historyAdd(input);
} }
// Advance to the next line in the history // Advance to the next/prev line in the history
int histSize = _historySize + (_historySize < kHistorySize ? 1 : 0); historyDir(_historyLine, direction, _history.size() < kHistorySize);
int line = _historyLine + direction;
if(line < 0) // Search the history using the original input
line += histSize;
line %= histSize;
// If anything in the buffer, search the history.
if(_currentPos > _promptStartPos) {
do do
{ {
int idx = line ? (_historyIndex - line + _historySize) % _historySize int idx = _historyLine
? (_historyIndex - _historyLine + _history.size()) % int(_history.size())
: _historyIndex; : _historyIndex;
if(BSPF::startsWithIgnoreCase(_history[idx], _history[_historyIndex])) if(BSPF::startsWithIgnoreCase(_history[idx], _history[_historyIndex]))
break; break;
line += direction; // Advance to the next/prev line in the history
if(line < 0) historyDir(_historyLine, direction, _history.size() < kHistorySize);
line += histSize;
line %= histSize;
} while(line); // if line == 0, nothing was found
} }
_historyLine = line; while(_historyLine); // If _historyLine == 0, nothing was found
// Remove the current user text // Remove the current user text
_currentPos = _promptStartPos; _currentPos = _promptStartPos;
@ -642,7 +643,8 @@ bool PromptWidget::historyScroll(int direction)
scrollToCurrent(); scrollToCurrent();
// Print the text from the history // Print the text from the history
int idx = _historyLine ? (_historyIndex - _historyLine + _historySize) % _historySize int idx = _historyLine
? (_historyIndex - _historyLine + _history.size()) % int(_history.size())
: _historyIndex; : _historyIndex;
for(int i = 0; i < kLineBufferSize && _history[idx][i] != '\0'; i++) 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) // Ensure once more the caret is visible (in case of very long history entries)
scrollToCurrent(); scrollToCurrent();
return line; return true;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -42,8 +42,6 @@ class PromptWidget : public Widget, public CommandSender
~PromptWidget() override = default; ~PromptWidget() override = default;
public: 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 print(const string& str);
void printPrompt(); void printPrompt();
string saveBuffer(const FilesystemNode& file); string saveBuffer(const FilesystemNode& file);
@ -54,6 +52,8 @@ class PromptWidget : public Widget, public CommandSender
void addToHistory(const char *str); void addToHistory(const char *str);
protected: 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]; } int& buffer(int idx) { return _buffer[idx % kBufferSize]; }
void drawWidget(bool hilite) override; void drawWidget(bool hilite) override;
@ -99,7 +99,7 @@ class PromptWidget : public Widget, public CommandSender
enum { enum {
kBufferSize = 32768, kBufferSize = 32768,
kLineBufferSize = 256, kLineBufferSize = 256,
kHistorySize = 50 kHistorySize = 1000
}; };
int _buffer[kBufferSize]; // NOLINT (will be rewritten soon) int _buffer[kBufferSize]; // NOLINT (will be rewritten soon)
@ -117,8 +117,7 @@ class PromptWidget : public Widget, public CommandSender
ScrollBarWidget* _scrollBar; ScrollBarWidget* _scrollBar;
char _history[kHistorySize][kLineBufferSize]; // NOLINT (will be rewritten soon) std::vector<string> _history;
int _historySize{0};
int _historyIndex{0}; int _historyIndex{0};
int _historyLine{0}; int _historyLine{0};
int _tabCount{-1}; int _tabCount{-1};
@ -130,6 +129,9 @@ class PromptWidget : public Widget, public CommandSender
bool _firstTime{true}; bool _firstTime{true};
bool _exitedEarly{false}; bool _exitedEarly{false};
int historyDir(int& index, int direction, bool promptSpace = false);
void historyAdd(const string& entry);
private: private:
// Following constructors and assignment operators not supported // Following constructors and assignment operators not supported
PromptWidget() = delete; PromptWidget() = delete;