Implements scrolling in the InputWindow of the REPL.
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
b73bfe6482
commit
340d37f4a1
|
@ -13,7 +13,8 @@ namespace MalachScriptRepl {
|
|||
int _row = 0;
|
||||
int _col = 0;
|
||||
int _rightPos = 0;
|
||||
[[maybe_unused]] int _scroll = 0;
|
||||
int _scroll = 0;
|
||||
int _lineCount;
|
||||
|
||||
std::function<void(const std::vector<std::u8string>&)> _onChange;
|
||||
|
||||
|
@ -21,6 +22,7 @@ namespace MalachScriptRepl {
|
|||
InputWindow(int height, int width, int y, int x) {
|
||||
_window = newwin(height, width, y, x);
|
||||
keypad(_window, true);
|
||||
_lineCount = height;
|
||||
}
|
||||
|
||||
inline void RegisterOnChange(std::function<void(const std::vector<std::u8string>&)> listener) {
|
||||
|
@ -37,7 +39,13 @@ namespace MalachScriptRepl {
|
|||
return std::pair<int, int>(row, col);
|
||||
}
|
||||
|
||||
inline void MoveCursorPosition(int row, int col) { wmove(_window, row, col); }
|
||||
inline void MoveCursorPosition(int row, int col) {
|
||||
auto& line = _lines[row + _scroll];
|
||||
if (col > (int)line.size()) {
|
||||
col = line.size();
|
||||
}
|
||||
wmove(_window, row, col);
|
||||
}
|
||||
|
||||
inline void MoveCursorLeft() {
|
||||
if (_col > 0) {
|
||||
|
@ -47,7 +55,7 @@ namespace MalachScriptRepl {
|
|||
}
|
||||
|
||||
inline void MoveCursorRight() {
|
||||
auto& line = _lines[_row];
|
||||
auto& line = _lines[_row + _scroll];
|
||||
if (_col < (int)line.size()) {
|
||||
wmove(_window, _row, ++_col);
|
||||
_rightPos = _col;
|
||||
|
@ -57,47 +65,57 @@ namespace MalachScriptRepl {
|
|||
inline void MoveCursorUp() {
|
||||
if (_row > 0) {
|
||||
_col = _rightPos;
|
||||
if (_col > (int)_lines[_row - 1].size()) {
|
||||
_col = (int)_lines[_row - 1].size();
|
||||
if (_col > (int)_lines[_row - 1 + _scroll].size()) {
|
||||
_col = (int)_lines[_row - 1 + _scroll].size();
|
||||
}
|
||||
wmove(_window, --_row, _col);
|
||||
} else {
|
||||
ScrollUp();
|
||||
}
|
||||
}
|
||||
|
||||
inline void MoveCursorDown() {
|
||||
if (_row < (int)_lines.size() - 1) {
|
||||
if (_row < _lineCount - 1 && _row + _scroll < (int)_lines.size() - 1) {
|
||||
_col = _rightPos;
|
||||
if (_col > (int)_lines[_row + 1].size()) {
|
||||
_col = (int)_lines[_row + 1].size();
|
||||
if (_col > (int)_lines[_row + 1 + _scroll].size()) {
|
||||
_col = (int)_lines[_row + 1 + _scroll].size();
|
||||
}
|
||||
wmove(_window, ++_row, _col);
|
||||
} else {
|
||||
ScrollDown();
|
||||
}
|
||||
}
|
||||
|
||||
inline void Backspace() {
|
||||
if (_col > 0) {
|
||||
mvwdelch(_window, _row, --_col);
|
||||
auto& line = _lines[_row];
|
||||
line = line.erase(_col, 1);
|
||||
_onChange(_lines);
|
||||
auto& line = _lines[_row + _scroll];
|
||||
if (_col < (int)line.size()) {
|
||||
line = line.erase(_col, 1);
|
||||
_onChange(_lines);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void Return() {
|
||||
_lines.insert(_lines.begin() + _row + 1, u8"");
|
||||
_row++;
|
||||
_col = 0;
|
||||
for (size_t i = _row - 1; i < _lines.size(); i++) {
|
||||
wmove(_window, i, 0);
|
||||
wclrtoeol(_window);
|
||||
waddstr(_window, (char*)_lines[i].c_str());
|
||||
_lines.insert(_lines.begin() + _row + _scroll + 1, u8"");
|
||||
if (_row >= _lineCount - 1) {
|
||||
ScrollDown();
|
||||
} else {
|
||||
_row++;
|
||||
_col = 0;
|
||||
for (size_t i = _row - 1; i < _lines.size(); i++) {
|
||||
wmove(_window, i, 0);
|
||||
wclrtoeol(_window);
|
||||
waddstr(_window, (char*)_lines[i].c_str());
|
||||
}
|
||||
wmove(_window, _row, _col);
|
||||
}
|
||||
wmove(_window, _row, _col);
|
||||
}
|
||||
inline void Tab() {
|
||||
wmove(_window, _row, 0);
|
||||
wclrtoeol(_window);
|
||||
auto& line = _lines[_row];
|
||||
auto& line = _lines[_row + _scroll];
|
||||
if ((int)line.length() <= _col) {
|
||||
line += u8" ";
|
||||
} else {
|
||||
|
@ -113,19 +131,20 @@ namespace MalachScriptRepl {
|
|||
}
|
||||
|
||||
inline void GoToEndOfLine() {
|
||||
_col = _lines[_row].size();
|
||||
_col = _lines[_row + _scroll].size();
|
||||
_rightPos = _col;
|
||||
wmove(_window, _row, _col);
|
||||
}
|
||||
|
||||
inline void GoToStartOfLine() {
|
||||
_col = _lines[_row].size();
|
||||
_rightPos = _col;
|
||||
_col = 0;
|
||||
_rightPos = 0;
|
||||
wmove(_window, _row, _col);
|
||||
}
|
||||
|
||||
inline void Input(int c) {
|
||||
wmove(_window, _row, 0);
|
||||
auto& line = _lines[_row];
|
||||
auto& line = _lines[_row + _scroll];
|
||||
if ((int)line.length() <= _col) {
|
||||
line += (char8_t)c;
|
||||
} else {
|
||||
|
@ -138,15 +157,66 @@ namespace MalachScriptRepl {
|
|||
_onChange(_lines);
|
||||
}
|
||||
|
||||
inline void ResetText() {
|
||||
auto pos = GetCursorPosition();
|
||||
wclear(_window);
|
||||
for (size_t i = 0; i < _lines.size() && (int)i < _lineCount; i++) {
|
||||
wmove(_window, i, 0);
|
||||
waddnstr(_window, (char*)_lines[i + _scroll].c_str(), _lines[i + _scroll].size());
|
||||
}
|
||||
MoveCursorPosition(pos.first, pos.second);
|
||||
Refresh();
|
||||
}
|
||||
|
||||
inline void ScrollDown() {
|
||||
if (_scroll + _row < (int)_lines.size() - 1) {
|
||||
_scroll++;
|
||||
ResetText();
|
||||
|
||||
_col = _rightPos;
|
||||
if (_col > (int)_lines[_row + _scroll].size()) {
|
||||
_col = (int)_lines[_row + _scroll].size();
|
||||
}
|
||||
wmove(_window, _row, _col);
|
||||
}
|
||||
}
|
||||
inline void ScrollUp() {
|
||||
if (_scroll <= 0) {
|
||||
return;
|
||||
}
|
||||
_scroll--;
|
||||
ResetText();
|
||||
|
||||
_col = _rightPos;
|
||||
if (_col > (int)_lines[_row + _scroll].size()) {
|
||||
_col = (int)_lines[_row + _scroll].size();
|
||||
}
|
||||
wmove(_window, _row, _col);
|
||||
}
|
||||
|
||||
inline void SetScriptWithDiagnostics(const std::u8string& script,
|
||||
const MalachScript::Diagnostics::Diagnostic* diag) {
|
||||
auto yx = GetCursorPosition();
|
||||
|
||||
Clear();
|
||||
|
||||
size_t linenum = 0;
|
||||
size_t index = 0;
|
||||
size_t linestart = 0;
|
||||
|
||||
std::istringstream f((char*)script.data());
|
||||
std::string line;
|
||||
while (std::getline(f, line)) {
|
||||
if ((int)linenum == _scroll) {
|
||||
linestart = index;
|
||||
}
|
||||
index += line.size() + 1;
|
||||
linenum++;
|
||||
}
|
||||
|
||||
if (diag != nullptr) {
|
||||
auto start = diag->GetSpan().GetStart();
|
||||
auto end = diag->GetSpan().GetEnd() + 1;
|
||||
auto start = diag->GetSpan().GetStart() - linestart;
|
||||
auto end = diag->GetSpan().GetEnd() - linestart;
|
||||
if (end > script.size()) {
|
||||
end = script.size();
|
||||
if (start == end && start > 0) {
|
||||
|
@ -154,11 +224,11 @@ namespace MalachScriptRepl {
|
|||
}
|
||||
}
|
||||
|
||||
waddnstr(_window, (char*)script.c_str(), start);
|
||||
waddnstr(_window, (char*)script.substr(linestart).data(), start);
|
||||
wattron(_window, COLOR_PAIR(1));
|
||||
waddnstr(_window, (char*)script.substr(start).data(), end - start);
|
||||
waddnstr(_window, (char*)script.substr(start + linestart).data(), end - start);
|
||||
wattroff(_window, COLOR_PAIR(1));
|
||||
waddnstr(_window, (char*)script.substr(end).data(), script.size() - end);
|
||||
waddnstr(_window, (char*)script.substr(end + linestart).data(), script.size() - end);
|
||||
|
||||
if (start >= script.size() - 1) {
|
||||
wattron(_window, COLOR_PAIR(1));
|
||||
|
@ -166,7 +236,7 @@ namespace MalachScriptRepl {
|
|||
wattroff(_window, COLOR_PAIR(1));
|
||||
}
|
||||
} else {
|
||||
waddstr(_window, (char*)script.c_str());
|
||||
waddstr(_window, (char*)script.substr(linestart).data());
|
||||
}
|
||||
MoveCursorPosition(yx.first, yx.second);
|
||||
Refresh();
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include <fstream>
|
||||
#include <ncurses.h>
|
||||
#include <sstream>
|
||||
#include "../src/Parser/Lexer/Lexer.hpp"
|
||||
|
@ -8,14 +9,22 @@
|
|||
void ParseAndUpdate(const std::vector<std::u8string>& lines, WINDOW* diagnosticsWindow, WINDOW* parsedWindow,
|
||||
MalachScriptRepl::InputWindow& inputWindow) {
|
||||
std::u8string script;
|
||||
for (const auto& line : lines) {
|
||||
script += line;
|
||||
script += '\n';
|
||||
for (size_t i = 0; i < lines.size(); i++) {
|
||||
script += lines[i];
|
||||
if (i != lines.size() - 1) {
|
||||
script += '\n';
|
||||
}
|
||||
}
|
||||
|
||||
std::ofstream outfile;
|
||||
outfile.open("script.ms", std::ios::out | std::ios::trunc);
|
||||
outfile << (char*)script.data();
|
||||
outfile.close();
|
||||
|
||||
auto logger = MalachScript::Diagnostics::Logger();
|
||||
auto lexer = MalachScript::Parser::Lexer(u8"diag", script, &logger);
|
||||
const auto* firstToken = lexer.Lex();
|
||||
[[maybe_unused]] const auto* parsedResult = MalachScript::Parser::Parser::Parse(firstToken, u8"diag", &logger);
|
||||
const auto* parsedResult = MalachScript::Parser::Parser::Parse(firstToken, u8"diag", &logger);
|
||||
|
||||
const MalachScript::Diagnostics::Diagnostic* diag = nullptr;
|
||||
wclear(diagnosticsWindow);
|
||||
|
|
Loading…
Reference in New Issue