Skip to content

Commit

Permalink
vim: Reworked error flow
Browse files Browse the repository at this point in the history
  • Loading branch information
Petr Laštovička committed May 11, 2022
1 parent cae6f0b commit 090d48d
Show file tree
Hide file tree
Showing 15 changed files with 115 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ void Storage::loadData(const string& path, shared_ptr<table::Table>& table) {
for (size_t x = 0; file; x++) {
bool lineEnd;
string cellContent = move(importText(file, lineEnd));
table->updateCell(table::Coordinates(x, y), cellContent);
auto insertRes = table->updateCell(table::Coordinates(x, y), cellContent);
if (!insertRes.success) throw invalid_argument("Cannot open file: "s + insertRes.message);
if (lineEnd) break;
}
}
Expand Down
13 changes: 11 additions & 2 deletions Semestralni_prace/src/cz/lastaapps/vimxel/table/table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,11 @@ void Table::updateCellWithResult(const Coordinates& coord, SSingleTerm term) {
mMap.insert_or_assign(coord, make_unique<TextCell>(current.getContent(), term, false));
}

void Table::updateCell(const Coordinates& coord, const string& content) {
mChanged = true;
TableUpdateResult Table::updateCell(const Coordinates& coord, const string& content) {
const string oldContent = getCell(coord).getContent();
destroyOldCell(coord);

try {
switch (isExpression(content)) {
case CT::EMPTY: {
deleteCell(coord);
Expand Down Expand Up @@ -125,6 +126,13 @@ void Table::updateCell(const Coordinates& coord, const string& content) {
default:
throw runtime_error("Unknown content type");
}
mChanged = true;
return TableUpdateResult{true, ""};
}
catch (exception& e) {
updateCell(coord, oldContent);
return TableUpdateResult{false, e.what()};
}
}
bool Table::tryParseNumber(const string& content, long double& out) {
string noSpaces;
Expand Down Expand Up @@ -222,6 +230,7 @@ void Table::createExecutionPlanRecursive(const Coordinates& coord, ExecutionArgs
bool hasBeenVisited = args.visited.find(coord) != args.visited.end();
if (hasBeenVisited) {
args.cycleRoots.insert(coord);
throw invalid_argument("Cycle found, invalid argument");
return;
}
args.visited.insert(coord);
Expand Down
6 changes: 5 additions & 1 deletion Semestralni_prace/src/cz/lastaapps/vimxel/table/table.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ namespace cz::lastaapps::vimxel::table {

enum class CellContentType {EMPTY, TEXT, ESCAPED, EXPRESSION};
using CT = table::CellContentType;
struct TableUpdateResult {
bool success = false;
string message;
};

class Table final {
private:
Expand All @@ -32,7 +36,7 @@ class Table final {
Table(const Table&& other) = delete;
Table& operator=(const Table& other) = delete;
const Cell& getCell(const Coordinates& coord) const;
void updateCell(const Coordinates& coord, const string& content);
TableUpdateResult updateCell(const Coordinates& coord, const string& content);
void deleteCell(const Coordinates& coord);

shared_ptr<CellContract> createCellContract();
Expand Down
39 changes: 26 additions & 13 deletions Semestralni_prace/src/cz/lastaapps/vimxel/vim/commandParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@ ParserResult CommandParser::handleKey(Mode& outMode) {
}
case KEY_ENTER:
case '\n': { // ENTER
Res res = handleCommand();
mCommand = "";
outMode = Mode::NORMAL;
Res res = handleCommand(outMode);
if (res != Res::UNKNOWN) {
mCommand = "";
outMode = Mode::NORMAL;
} else if (mCommand == "")
outMode = Mode::NORMAL;

return res;
}
case KEY_BACKSPACE: {
Expand All @@ -42,33 +46,39 @@ ParserResult CommandParser::handleKey(Mode& outMode) {
return Res::NOPE;
}

ParserResult CommandParser::handleCommand() {
ParserResult CommandParser::handleCommand(Mode& outMode) {
trim(mCommand);
if (mCommand.empty()) return ParserResult::NOPE;

{
auto res = tryQuitAndWrite();
auto res = tryQuitAndWrite(outMode);
if (res != ParserResult::UNKNOWN) return res;
}
{
auto res = tryJump();
auto res = tryJump(outMode);
if (res != ParserResult::UNKNOWN) return res;
}
return ParserResult::UNKNOWN;
}
ParserResult CommandParser::tryQuitAndWrite() {
mState->mErrorMsg = "No filename specified";
ParserResult CommandParser::tryQuitAndWrite(Mode& outMode) {
if (mCommand == "q") {
if (mState->mTable->changed()) {
mState->mErrorMsg = "You have unsaved changes";
return ParserResult::ERROR;
mState->mReturnMode = Mode::COMMAND;
outMode = Mode::ERROR;
return ParserResult::UPDATE;
} else {
return ParserResult::QUIT;
}
}
if (mCommand == "q!") return ParserResult::QUIT;
if (mCommand == "wq" || mCommand == "w") {
if (mState->mFilename.empty()) return ParserResult::ERROR;
if (mState->mFilename.empty()){
mState->mErrorMsg = "No filename specified";
mState->mReturnMode = Mode::COMMAND;
outMode = Mode::ERROR;
return ParserResult::UPDATE;
}
storage::Storage::saveData(mState->mTable, mState->mFilename);
mState->mTable->clearChanged();
if (mCommand == "w")
Expand All @@ -87,15 +97,18 @@ ParserResult CommandParser::tryQuitAndWrite() {
storage::Storage::saveData(mState->mTable, filename);
return true;
};

mState->mErrorMsg = "No filename specified";
mState->mReturnMode = Mode::COMMAND;
if (mCommand.rfind("w ", 0) == 0) {
return save(2) ? ParserResult::UPDATE : ParserResult::ERROR;
return save(2) ? ParserResult::UPDATE : (outMode = Mode::ERROR, ParserResult::UPDATE);
}
if (mCommand.rfind("wq ") == 0) {
return save(3) ? ParserResult::QUIT : ParserResult::ERROR;
return save(3) ? ParserResult::QUIT : (outMode = Mode::ERROR, ParserResult::UPDATE);
}
return ParserResult::UNKNOWN;
}
ParserResult CommandParser::tryJump() {
ParserResult CommandParser::tryJump(Mode&) {
string letters;
size_t pos = 0;
bool inDigits = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ class CommandParser final : public AbsParser {
ParserResult handleKey(Mode & outMode) override;
pair<string, size_t> getTextAndPosition() override;
private:
ParserResult handleCommand();
ParserResult tryQuitAndWrite();
ParserResult tryJump();
ParserResult handleCommand(Mode& outMode);
ParserResult tryQuitAndWrite(Mode& outMode);
ParserResult tryJump(Mode& outMode);
};
}

Expand Down
20 changes: 20 additions & 0 deletions Semestralni_prace/src/cz/lastaapps/vimxel/vim/errorParser.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "errorParser.hpp"

using namespace std;
namespace cz::lastaapps::vimxel::vim {

ErrorParser::ErrorParser(VimState* state)
: mState(state) {}

Res ErrorParser::handleKey(Mode& outMode) {
int ch = getch();
if (ch == ERR) return Res::NOPE;

outMode = mState->mReturnMode;
return Res::UPDATE;
}
pair<string, size_t> ErrorParser::getTextAndPosition() {
return make_pair(mState->mErrorMsg, -1);
}

} // namespace cz::lastaapps::vimxel::vim
23 changes: 23 additions & 0 deletions Semestralni_prace/src/cz/lastaapps/vimxel/vim/errorParser.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef H_ERROR_PARSER
#define H_ERROR_PARSER
#include "absParser.hpp"
#include "vimState.hpp"
#include "parserResult.hpp"
#include "../table/coordinate.hpp"

#include <ncurses.h>

using namespace std;
namespace cz::lastaapps::vimxel::vim {
using Res = ParserResult;
class ErrorParser final : public AbsParser {
private:
VimState* mState;
public:
ErrorParser(VimState* state);
Res handleKey(Mode & outMode) override;
pair<string, size_t> getTextAndPosition() override;
};
}

#endif
33 changes: 16 additions & 17 deletions Semestralni_prace/src/cz/lastaapps/vimxel/vim/insertParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,16 @@ ParserResult InsertParser::handleKey(Mode& outMode) {
}
case KEY_ENTER:
case '\n': { // ENTER
saveContent();
mText = "";
mCursor = (size_t)-1;
outMode = Mode::NORMAL;
auto insertRes = mState->mTable->updateCell(mPos, mText);
if (insertRes.success) {
mText = "";
mCursor = (size_t)-1;
outMode = Mode::NORMAL;
} else {
mState->mErrorMsg = insertRes.message;
mState->mReturnMode = Mode::INSERT;
outMode = Mode::ERROR;
}
return Res::UPDATE;
}
case KEY_BACKSPACE: {
Expand All @@ -41,19 +47,19 @@ ParserResult InsertParser::handleKey(Mode& outMode) {
}
return Res::UPDATE;
}
case KEY_LEFT:{
if (mCursor != 0) mCursor --;
case KEY_LEFT: {
if (mCursor != 0) mCursor--;
return Res::UPDATE;
}
case KEY_RIGHT:{
if (mCursor < mText.length()) mCursor ++;
case KEY_RIGHT: {
if (mCursor < mText.length()) mCursor++;
return Res::UPDATE;
}
case KEY_UP:{
case KEY_UP: {
mCursor = 0;
return Res::UPDATE;
}
case KEY_DOWN:{
case KEY_DOWN: {
mCursor = mText.length();
return Res::UPDATE;
}
Expand All @@ -66,13 +72,6 @@ ParserResult InsertParser::handleKey(Mode& outMode) {
return Res::NOPE;
}

void InsertParser::saveContent() {
if (mText.empty())
mState->mTable->updateCell(mPos, "");
else
mState->mTable->updateCell(mPos, mText);
}

bool InsertParser::checkLoad() {
if (mCursor == (size_t)-1) {
mPos = mState->mPos;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ class InsertParser final : public AbsParser {
pair<string, size_t> getTextAndPosition() override;

private:
void saveContent();
bool checkLoad();
};
}
Expand Down
2 changes: 2 additions & 0 deletions Semestralni_prace/src/cz/lastaapps/vimxel/vim/mode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ string to_string(Mode m) {
return "INSERT";
case Mode::COMMAND:
return "COMMAND";
case Mode::ERROR:
return "ERROR";
}
throw invalid_argument("Unknown Vim Mode");
}
Expand Down
1 change: 1 addition & 0 deletions Semestralni_prace/src/cz/lastaapps/vimxel/vim/mode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ enum class Mode {
NORMAL,
INSERT,
COMMAND,
ERROR,
};
string to_string(Mode m);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
namespace cz::lastaapps::vimxel::vim {
enum class ParserResult {
UNKNOWN,
ERROR,
NOPE,
UPDATE,
ACCEPTED,
Expand Down
9 changes: 2 additions & 7 deletions Semestralni_prace/src/cz/lastaapps/vimxel/vim/vimParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ ParserResult VimParser::handleKeyBoard() {
case ParserResult::UNKNOWN:
unknowsInfo();
break;
case ParserResult::ERROR:
errorInfo();
break;
case ParserResult::UPDATE:
updateInfo();
break;
Expand Down Expand Up @@ -62,6 +59,8 @@ AbsParser& VimParser::getParser() {
return commandParser;
case Mode::INSERT:
return insertParser;
case Mode::ERROR:
return errorParser;
default:
throw runtime_error("Unknown mode");
}
Expand All @@ -76,10 +75,6 @@ void VimParser::unknowsInfo() {
VimInfo info(-1, "Unknow command or key sequence", mMode);
notifyContracts(info);
}
void VimParser::errorInfo() {
VimInfo info(-1, mState.mErrorMsg, mMode);
notifyContracts(info);
}

void VimParser::setPos(const table::Coordinates& coord) {
mState.mPos = coord;
Expand Down
2 changes: 2 additions & 0 deletions Semestralni_prace/src/cz/lastaapps/vimxel/vim/vimParser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "normalParser.hpp"
#include "insertParser.hpp"
#include "commandParser.hpp"
#include "errorParser.hpp"
#include "vimContract.hpp"
#include "parserResult.hpp"
#include "vimState.hpp"
Expand All @@ -27,6 +28,7 @@ class VimParser final {
NormalParser normalParser = NormalParser(&mState);
InsertParser insertParser = InsertParser(&mState);
CommandParser commandParser = CommandParser(&mState);
ErrorParser errorParser = ErrorParser(&mState);

struct VimStateCallback final : public display::StateCallback {
VimParser* mParent;
Expand Down
2 changes: 2 additions & 0 deletions Semestralni_prace/src/cz/lastaapps/vimxel/vim/vimState.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define H_VIM_STATE
#include <memory>

#include "mode.hpp"
#include "../display/state.hpp"
#include "../table/table.hpp"

Expand All @@ -15,6 +16,7 @@ struct VimState {
table::Coordinates mPos;
table::Coordinates mViewPort;
string mErrorMsg;
Mode mReturnMode;

VimState(
shared_ptr<display::State> displayState,
Expand Down

0 comments on commit 090d48d

Please sign in to comment.