diff --git a/README.md b/README.md index 6fe5f23c..17f3f31b 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,12 @@ The `projects/vs20xx` folders contain Visual Studio projects. The `projects/xcode` folder contains an Xcode project. +The `projects/make.mac` folder also contains a `make` project. +From that folder, run `make`. + +`cd projects/make.mac` +`make` + ### Linux The `projects/make` folder contains a `make` project. diff --git a/src/module/repl.wren b/src/module/repl.wren index 81d34187..487dfb9f 100644 --- a/src/module/repl.wren +++ b/src/module/repl.wren @@ -2,6 +2,41 @@ import "meta" for Meta import "io" for Stdin, Stdout import "os" for Platform +class History { + construct new() { + _list = [] + _index = 0 + } + add(line) { + if (line=="") return + if (line==lastEntry) { + _index = _list.count + return + } + + _list.add(line) + _index = _list.count + } + isBottom { _index == _list.count } + lastEntry { + if (_list.isEmpty) return "" + + return _list[-1] + } + entry { + if (_index == _list.count) return false + return _list[_index] + } + next() { + if (_index < _list.count) { _index = _index + 1 } + return this + } + previous() { + if (_index > 0) { _index = _index - 1 } + return this + } +} + /// Abstract base class for the REPL. Manages the input line and history, but /// does not render. class Repl { @@ -9,8 +44,7 @@ class Repl { _cursor = 0 _line = "" - _history = [] - _historyIndex = 0 + _history = History.new() } cursor { _cursor } @@ -129,35 +163,25 @@ class Repl { } previousHistory() { - if (_historyIndex == 0) return - - _historyIndex = _historyIndex - 1 - _line = _history[_historyIndex] + _line = _history.previous().entry || _line _cursor = _line.count } nextHistory() { - if (_historyIndex >= _history.count) return - - _historyIndex = _historyIndex + 1 - if (_historyIndex < _history.count) { - _line = _history[_historyIndex] - _cursor = _line.count - } else { + _line = _history.next().entry || _line + // if we are at the bottom and have not edited the buffer then + // allow us to move down into an empty line + if (_history.isBottom && _history.lastEntry == _line) { _line = "" - _cursor = 0 } + _cursor = _line.count } executeInput() { // Remove the completion hint. refreshLine(false) - // Add it to the history (if the line is interesting). - if (_line != "" && (_history.isEmpty || _history[-1] != _line)) { - _history.add(_line) - _historyIndex = _history.count - } + _history.add(_line) // Reset the current line. var input = _line diff --git a/src/module/repl.wren.inc b/src/module/repl.wren.inc index e14d33f3..c7126ab4 100644 --- a/src/module/repl.wren.inc +++ b/src/module/repl.wren.inc @@ -4,6 +4,41 @@ static const char* replModuleSource = "import \"io\" for Stdin, Stdout\n" "import \"os\" for Platform\n" "\n" +"class History {\n" +" construct new() {\n" +" _list = []\n" +" _index = 0\n" +" }\n" +" add(line) {\n" +" if (line==\"\") return\n" +" if (line==lastEntry) {\n" +" _index = _list.count \n" +" return\n" +" }\n" +"\n" +" _list.add(line)\n" +" _index = _list.count \n" +" }\n" +" isBottom { _index == _list.count }\n" +" lastEntry {\n" +" if (_list.isEmpty) return \"\"\n" +"\n" +" return _list[-1]\n" +" }\n" +" entry {\n" +" if (_index == _list.count) return false\n" +" return _list[_index]\n" +" }\n" +" next() {\n" +" if (_index < _list.count) { _index = _index + 1 }\n" +" return this\n" +" }\n" +" previous() {\n" +" if (_index > 0) { _index = _index - 1 }\n" +" return this\n" +" }\n" +"}\n" +"\n" "/// Abstract base class for the REPL. Manages the input line and history, but\n" "/// does not render.\n" "class Repl {\n" @@ -11,8 +46,7 @@ static const char* replModuleSource = " _cursor = 0\n" " _line = \"\"\n" "\n" -" _history = []\n" -" _historyIndex = 0\n" +" _history = History.new()\n" " }\n" "\n" " cursor { _cursor }\n" @@ -131,35 +165,25 @@ static const char* replModuleSource = " }\n" "\n" " previousHistory() {\n" -" if (_historyIndex == 0) return\n" -"\n" -" _historyIndex = _historyIndex - 1\n" -" _line = _history[_historyIndex]\n" +" _line = _history.previous().entry || _line\n" " _cursor = _line.count\n" " }\n" "\n" " nextHistory() {\n" -" if (_historyIndex >= _history.count) return\n" -"\n" -" _historyIndex = _historyIndex + 1\n" -" if (_historyIndex < _history.count) {\n" -" _line = _history[_historyIndex]\n" -" _cursor = _line.count\n" -" } else {\n" +" _line = _history.next().entry || _line\n" +" // if we are at the bottom and have not edited the buffer then\n" +" // allow us to move down into an empty line\n" +" if (_history.isBottom && _history.lastEntry == _line) {\n" " _line = \"\"\n" -" _cursor = 0\n" " }\n" +" _cursor = _line.count\n" " }\n" "\n" " executeInput() {\n" " // Remove the completion hint.\n" " refreshLine(false)\n" "\n" -" // Add it to the history (if the line is interesting).\n" -" if (_line != \"\" && (_history.isEmpty || _history[-1] != _line)) {\n" -" _history.add(_line)\n" -" _historyIndex = _history.count\n" -" }\n" +" _history.add(_line)\n" "\n" " // Reset the current line.\n" " var input = _line\n"