#include "Action.hpp" Action::Action(Action::Type type, std::function<void(Config & config, Action & action)> apply, std::function<void(Config & config, Action & action)> undo, std::function<bool(Config & config, Action & action)> appliable) { this->type = type; this->apply = apply; this->undo = undo; this->appliable = appliable; } Action Action::addLinesIfNeeded(int nbLines) { auto apply = [nbLines](Config & config, Action &) { config.addLines(1); }; auto undo = [](Config &, Action &) { }; auto appliable = [](Config &, Action &) { return true; }; return {Type::AddLines, apply, undo, appliable}; } Action Action::moveWordIndex(int movement) { auto apply = [movement](Config & config, Action &) { config.moveWordIndex(movement); }; auto undo = [movement](Config & config, Action &) { config.moveWordIndex(movement); }; auto appliable = [movement](Config & config, Action &) { bool possible = config.moveWordIndex(movement); if (possible) moveWordIndex(-movement); return possible; }; return {Type::MoveWord, apply, undo, appliable}; } Action Action::moveCharacterIndex(int movement) { auto apply = [movement](Config & config, Action &) { config.moveCharacterIndex(movement); }; auto undo = [movement](Config & config, Action &) { config.moveCharacterIndex(movement); }; auto appliable = [movement](Config & config, Action &) { bool possible = config.moveCharacterIndex(movement); if (possible) moveCharacterIndex(-movement); return possible; }; return {Type::MoveChar, apply, undo, appliable}; } Action Action::addHypothesis(const std::string & colName, std::size_t lineIndex, const std::string & hypothesis) { auto apply = [colName, lineIndex, hypothesis](Config & config, Action &) { config.getFirstEmpty(colName, lineIndex) = hypothesis; }; auto undo = [colName, lineIndex](Config & config, Action &) { config.getLastNotEmpty(colName, lineIndex) = ""; }; auto appliable = [colName, lineIndex](Config & config, Action &) { return config.has(colName, lineIndex, 0); }; return {Type::Write, apply, undo, appliable}; } Action Action::addHypothesisRelative(const std::string & colName, Object object, int relativeIndex, const std::string & hypothesis) { auto apply = [colName, object, relativeIndex, hypothesis](Config & config, Action & a) { int lineIndex = 0; if (object == Object::Buffer) lineIndex = config.getWordIndex() + relativeIndex; else lineIndex = config.getStack(relativeIndex); return addHypothesis(colName, lineIndex, "").apply(config, a); }; auto undo = [colName, object, relativeIndex](Config & config, Action & a) { int lineIndex = 0; if (object == Object::Buffer) lineIndex = config.getWordIndex() + relativeIndex; else lineIndex = config.getStack(relativeIndex); return addHypothesis(colName, lineIndex, "").undo(config, a); }; auto appliable = [colName, object, relativeIndex](Config & config, Action & a) { int lineIndex = 0; if (object == Object::Buffer) lineIndex = config.getWordIndex() + relativeIndex; else if (config.hasStack(relativeIndex)) lineIndex = config.getStack(relativeIndex); else return false; return addHypothesis(colName, lineIndex, "").appliable(config, a); }; return {Type::Write, apply, undo, appliable}; } Action::Object Action::str2object(const std::string & s) { if (s == "b") return Object::Buffer; if (s == "s") return Object::Stack; util::myThrow(fmt::format("Invalid object '{}'", s)); return Object::Buffer; }