Last active
February 11, 2018 14:08
-
-
Save geekskick/2b3a9751af65962fcda1dda885f9092b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <vector> | |
#include <string> | |
#include <unordered_map> | |
class LineBuffer; | |
class Output{ | |
public: | |
void refresh(void){ | |
std::cout << "Output::refresh\n"; | |
} | |
// ... | |
}; | |
class KeyCommand{ | |
public: | |
virtual ~KeyCommand(void){} | |
virtual int Execute(LineBuffer&, Output&) = 0; | |
}; | |
class Line{ | |
public: | |
Line(void):cursorPosition(0){} | |
void moveCursorLeft(const int numberChars = 1) { this->cursorPosition-= numberChars; } | |
void moveCursorRight(const int numberChars = 1) { this->cursorPosition+= numberChars; } | |
void overwriteLetters(const std::string& letters){ this->letters = letters; } | |
std::string& string(void) { return this->letters; } | |
void removeLetter(void){ | |
this->letters.erase(this->letters.begin() + --this->cursorPosition); | |
} | |
void insert(const char letter) { | |
this->letters.insert(this->cursorPosition, this->letters); | |
this->cursorPosition++; | |
} | |
void operator +=(const char& rhs){ | |
this->letters += rhs; | |
moveCursorRight(); | |
} | |
void operator +=(const std::string& rhs){ | |
this->letters += rhs; | |
moveCursorRight(rhs.length()); | |
} | |
protected: | |
std::string letters; | |
int cursorPosition; | |
}; | |
class LineBuffer{ | |
public: | |
LineBuffer(void): activeLineNumber(-1){} | |
void addLine(void){ | |
this->buffer.emplace_back(); | |
this->activeLineNumber++; | |
} | |
void moveActiveLineUp(const int numberLines = 1){ | |
if(this->activeLineNumber+numberLines >= 0){ | |
this->activeLineNumber -= numberLines; | |
} | |
} | |
void moveActiveLineDown(const int numberLines = 1){ | |
if(this->activeLineNumber + numberLines <= this->buffer.size()){ | |
this->activeLineNumber += numberLines; | |
} | |
} | |
std::vector<Line>& history(void){ return this->buffer; } | |
void copyLine(const int from, const int to){ this->buffer[to] = this->buffer[from]; } | |
Line& activeLine(void){ return this->buffer[this->activeLineNumber];} | |
void clear(void){ this->buffer.clear(); this->activeLineNumber = -1; } | |
friend std::ostream& operator <<(std::ostream& os, LineBuffer& lb){ | |
int i = 1; | |
for (auto& line: lb.buffer) { | |
os << i++ << ":\t" << line.string() << "\n"; | |
} | |
return os; | |
} | |
protected: | |
std::vector<Line> buffer; | |
int activeLineNumber; | |
}; | |
class Key: public KeyCommand{ | |
public: | |
virtual ~Key(void){} | |
Key(const char v) : visualOutput(v){} | |
char visual(void){return this->visualOutput; } | |
protected: | |
char visualOutput; | |
}; | |
class ReturnKey: public Key{ | |
public: | |
ReturnKey(void) : Key('\r') {} | |
~ReturnKey(void){} | |
int Execute(LineBuffer& lb, Output& o){ | |
lb.addLine(); | |
o.refresh(); | |
return 1; | |
} | |
}; | |
class DeleteKey: public Key{ | |
public: | |
DeleteKey(void) : Key(0x8) {} | |
~DeleteKey(void){} | |
int Execute(LineBuffer& lb, Output &o){ | |
lb.activeLine().removeLetter(); | |
o.refresh(); | |
return 1; | |
} | |
}; | |
class UpKey:public Key{ | |
public: | |
UpKey(void) : Key('\033[A') {} | |
int Execute(LineBuffer&lb, Output&){ | |
lb.moveActiveLineUp(); | |
return 1; | |
} | |
}; | |
class DownKey:public Key{ | |
public: | |
DownKey(void) : Key('\033[B') {} | |
int Execute(LineBuffer&lb, Output&){ | |
lb.moveActiveLineDown(); | |
return 1; | |
} | |
}; | |
class LeftKey:public Key{ | |
public: | |
LeftKey(void) : Key('\033[C') {} | |
int Execute(LineBuffer&lb, Output&){ | |
lb.activeLine().moveCursorLeft(); | |
return 1; | |
} | |
}; | |
class RightKey:public Key{ | |
public: | |
RightKey(void) : Key('\033[D') {} | |
int Execute(LineBuffer&lb, Output&){ | |
lb.activeLine().moveCursorRight(); | |
return 1; | |
} | |
}; | |
int main(int argc, const char * argv[]) { | |
LineBuffer lb; | |
ReturnKey rKey; | |
DeleteKey delKey; | |
UpKey upKey; | |
DownKey downKey; | |
LeftKey leftKey; | |
RightKey rightKey; | |
std::unordered_map<std::string, KeyCommand*> commands; | |
Output out; | |
std::string in; | |
commands["ret"] = &rKey; | |
commands["del"] = &delKey; | |
commands["movup"] = &upKey; | |
commands["movdown"] = &downKey; | |
commands["movleft"] = &leftKey; | |
commands["movright"] = &rightKey; | |
lb.addLine(); | |
while(1){ | |
std::cin >> in; | |
if(in == "quit"){ | |
break; | |
} | |
else if(in == "print"){ | |
std::cout << lb; | |
} | |
else if(commands.end() != commands.find(in)){ | |
commands[in]->Execute(lb, out); | |
} | |
else{ | |
lb.activeLine() += in; | |
} | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment