Skip to content
Permalink
Browse files

Implement the Enter key in istatik

  • Loading branch information
nfomon committed Sep 24, 2015
1 parent 3adb6ce commit d71eceb86d0bd0261b76f953f2a4ed8638a9ed31
Showing with 82 additions and 6 deletions.
  1. +1 −1 exstatik/Lexer.cpp
  2. +65 −4 istatik/InputWindow.cpp
  3. +4 −1 istatik/InputWindow.h
  4. +12 −0 statik/ObjectPool.h
@@ -220,6 +220,6 @@ auto_ptr<Rule> exstatik::CreateLexer_C() {
// regexps
or_->AddChild(REGEXP("ID", boost::regex("[A-Za-z_][0-9A-Za-z_]*")));
or_->AddChild(REGEXP("INT", boost::regex("[0-9]+")));
or_->AddChild(REGEXP("WS", boost::regex("[ \t\r]+")));
or_->AddChild(REGEXP("WS", boost::regex("[ \t\r\n]+")));
return lexer;
}
@@ -128,9 +128,25 @@ Char* Line::Insert(int x, int ch) {
return c;
}

Char* Line::Insert(int x, auto_ptr<Char> ac) {
Char* c = m_charpool.Insert(ac); // FIXME ObjectPool violation... ah well.
// OP is dumb anyway.
g_log.info() << "Line " << y << " inserting " << *c;
if ((size_t)x > m_chars.size()) {
std::stringstream s;
s << "Cannot insert " << *c << "; x out of bounds";
throw ISError(s.str());
} else if (m_chars.size() == (size_t)x) {
m_chars.push_back(c);
} else {
m_chars.insert(m_chars.begin() + x, c);
}
return c;
}

Char* Line::Delete(int x) {
if ((size_t)x >= m_chars.size()) {
throw ISError("Cannot insert; x out of bounds");
throw ISError("Cannot delete; x out of bounds");
}
Char* c = m_chars.at(x);
c->Unlink();
@@ -139,6 +155,17 @@ Char* Line::Delete(int x) {
return c;
}

auto_ptr<Char> Line::Extract(int x) {
if ((size_t)x >= m_chars.size()) {
throw ISError("Cannot extract; x out of bounds");
}
Char* c = m_chars.at(x);
g_log.debug() << " before extract: " << m_chars.size();
m_chars.erase(m_chars.begin() + x);
g_log.debug() << " after extract: " << m_chars.size();
return m_charpool.Extract(*c);
}

/* LineBuf public */

LineBuf::LineBuf(size_t maxcols)
@@ -182,7 +209,9 @@ WindowResponse LineBuf::Insert(int y, int x, int ch) {
int y0 = y;
// Re-draw the window starting at the newly-entered character
do {
response.actions.push_back(WindowAction(WindowAction::MOVE, y, x));
string s = m_lines.at(y).GetString(x);
g_log.debug() << "Printing str: " << s;
for (size_t i = 0; i < s.size(); ++i) {
response.actions.push_back(WindowAction(WindowAction::INSERT, y, x + i, s[i]));
}
@@ -210,7 +239,37 @@ WindowResponse LineBuf::Insert(int y, int x, int ch) {
}

WindowResponse LineBuf::Enter(int y, int x, int ch) {
g_log.debug() << "Processing Enter at (" << y << "," << x << ")";
g_log.debug();
WindowResponse response;
if ((size_t)y > m_lines.size()) {
throw ISError(string("Cannot insert Enter; y out of bounds"));
} else if (m_lines.size() == (size_t)y) {
g_log.debug() << "Inserting blank line right here at end";
m_lines.push_back(new Line(y));
} else {
g_log.debug() << "Inserting blank line in the middle";
m_lines.insert(m_lines.begin()+y+1, new Line(y+1));
for (line_vec::iterator i = m_lines.begin()+y+2; i != m_lines.end(); ++i) {
++i->y;
}
}
// Clear end of this line
while ((size_t)x < m_lines.at(y).Size()) {
g_log.debug() << "Enter: clearing (" << y << "," << m_lines.at(y).LastIndex() << ")";
response.actions.push_back(WindowAction(WindowAction::DELETE));
auto_ptr<Char> c = m_lines.at(y).Extract(m_lines.at(y).LastIndex());
m_lines.at(y+1).Insert(0, c);
}

// Next line is populated; draw it
string s = m_lines.at(y+1).GetString(0);
response.actions.push_back(WindowAction(WindowAction::MOVE, y+1, 0));
for (size_t i = 0; i < s.size(); ++i) {
g_log.debug() << "Enter: inserting " << y+1 << "," << i << ":" << s[i];
response.actions.push_back(WindowAction(WindowAction::INSERT, y+1, i, s[i]));
}
response.actions.push_back(WindowAction(WindowAction::MOVE, y+1, 0));
return response;
}

@@ -308,7 +367,7 @@ WindowResponse InputWindow::Input(int y, int x, int ch) {
WindowResponse response;
if (m_linebuf.HasLine(y-1)) {
if (!m_linebuf.HasChar(y-1, x)) {
x = m_linebuf.LastIndexOfLine(y-1);
x = std::max(m_linebuf.LastIndexOfLine(y-1), 0);
}
response.actions.push_back(WindowAction(WindowAction::MOVE, y-1, x));
}
@@ -317,17 +376,19 @@ WindowResponse InputWindow::Input(int y, int x, int ch) {
WindowResponse response;
if (m_linebuf.HasLine(y+1)) {
if (!m_linebuf.HasChar(y+1, x)) {
x = m_linebuf.LastIndexOfLine(y+1);
x = std::max(m_linebuf.LastIndexOfLine(y+1), 0);
}
response.actions.push_back(WindowAction(WindowAction::MOVE, y+1, x));
} else if (m_linebuf.HasLine(y)) {
response.actions.push_back(WindowAction(WindowAction::MOVE, y+1, 0));
}
return response;
} else if (KEY_DC == ch) {
return m_linebuf.Delete(y, x);
} else if (KEY_BACKSPACE == ch) {
return m_linebuf.Backspace(y, x);
} else if (KEY_ENTER == ch || '\n' == ch) {
//return m_linebuf.Enter(y, x, ch);
return m_linebuf.Enter(y, x, ch);
} else {
return m_linebuf.Insert(y, x, ch);
}
@@ -41,10 +41,12 @@ class Line {
Char* GetBefore(int x);
Char* GetAtOrAfter(int x);
Char* Insert(int x, int ch);
Char* Insert(int x, std::auto_ptr<Char> c);
Char* Delete(int x);
std::auto_ptr<Char> Extract(int x);
int y;
private:
typedef std::vector<Char*> char_vec;
int y;
char_vec m_chars;
statik::ObjectPool<Char> m_charpool;
};
@@ -54,6 +56,7 @@ class LineBuf {
LineBuf(size_t maxcols);
bool HasChar(int y, int x) const;
bool HasLine(int y) const;
size_t Size() const { return m_lines.size(); }
int LastIndexOfLine(int y) const;
WindowResponse Insert(int y, int x, int ch);
WindowResponse Enter(int y, int x, int ch);
@@ -45,6 +45,18 @@ class ObjectPool {
m_unlinked.insert(&item);
}

std::auto_ptr<T> Extract(T& item) {
g_log.debug() << "Object pool extracting " << item << " - " << &item;
g_san.debug() << "Object pool extracting " << item << " - " << &item;
if (m_active.end() == m_active.find(&item)) {
std::stringstream s;
s << "Cannot extract " << item << "; item not found in pool";
throw SError(s.str());
}
m_active.erase(&item);
return std::auto_ptr<T>(&item);
}

void Cleanup() {
for (item_mod_iter i = m_unlinked.begin(); i != m_unlinked.end(); ++i) {
g_log.debug() << "Object pool deleting " << **i << " - " << *i;

0 comments on commit d71eceb

Please sign in to comment.
You can’t perform that action at this time.