Loading slc/trunk/Makefile.am +3 −1 Original line number Diff line number Diff line Loading @@ -5,7 +5,9 @@ slc_SOURCES= src/slc.hh \ src/options.cc \ src/options.hh \ src/screen.hh \ src/screen.cc src/screen.cc \ src/history.hh \ src/history.cc CLEANFILES= *~ '\#*' .*.swp .*~ Loading slc/trunk/src/history.cc 0 → 100644 +29 −0 Original line number Diff line number Diff line #include "slc.hh" #include "history.hh" History::History(size_t size) : size_(size) {} History::~History() { // save into file; } void History::add(const string &line) { if (table_.size() + 1 > size_) table_.erase(table_.begin()); table_.push_back(line); ++size_; } const string &History::get(size_t off) const { assert(table_.size() > 0); assert(off < table_.size()); return table_[table_.size() - 1 - off]; } const string &History::get() const { return table_.back(); } size_t History::size() const { return table_.size(); } slc/trunk/src/history.hh 0 → 100644 +28 −0 Original line number Diff line number Diff line #ifndef HISTORY_HH # define HISTORY_HH # include <vector> # define HISTORY_SIZE 256 class History { public: History(size_t size); ~History(); const string &get(size_t off) const; const string &get() const; void add(const string &line); size_t size() const; void save(const string &filename); private: string filename_; std::vector<string> table_; size_t size_; }; extern History H; #endif slc/trunk/src/screen.cc +135 −25 Original line number Diff line number Diff line #include <ctype.h> #include <signal.h> #include "slc.hh" #include "screen.hh" #include "history.hh" Screen::Screen() { msg_ = 0; cmd_ = 0; } Screen::Screen() {} void Screen::init() { // Init ncurses Loading @@ -28,50 +29,159 @@ void Screen::init() { // Create msg window msg_ = newwin(row - 3, col, 0, 0); box(msg_, 0, 0); wrefresh(msg_); // Create cmd window cmd_ = newwin(3, col, row - 3, 0); box(cmd_, 0 , 0); // set buf value *cmd_buffer_ = 0; cmd_buf_off_ = 0; cmd_buf_win_off_ = 0; cmd_buf_win_size_ = col - 1; cmd_history_off_ = 0; wmove(cmd_, 1, 1); wrefresh(cmd_); //register sigwinch } void Screen::run() { int key; int x,y; while (1) { key = getch(); getyx(cmd_, y,x); int key = getch(); switch(key) { // KEY UP case KEY_UP: if (cmd_history_off_ + 1 > H.size()) break; if (cmd_history_off_ == 0) memcpy(cmd_history_buffer_, cmd_buffer_, CMD_BUFFER_SIZE); strncpy(cmd_buffer_, H.get(cmd_history_off_++).c_str(), CMD_BUFFER_SIZE); cmd_buffer_[CMD_BUFFER_SIZE - 1] = 0; break; // KEY DOWN case KEY_DOWN: if (cmd_history_off_ == 0) break; --cmd_history_off_; if (cmd_history_off_ == 0) memcpy(cmd_buffer_, cmd_history_buffer_, CMD_BUFFER_SIZE); else { strncpy(cmd_buffer_, H.get(cmd_history_off_ - 1).c_str(), CMD_BUFFER_SIZE); cmd_buffer_[CMD_BUFFER_SIZE - 1] = 0; } break; // KEY LEFT case KEY_LEFT: wmove(cmd_, y, --x); if (cmd_buf_off_ > 0) --cmd_buf_off_; break; // KEY RIGHT case KEY_RIGHT: wmove(cmd_, y, ++x); if ((size_t) cmd_buf_off_ < strlen(cmd_buffer_)) ++cmd_buf_off_; break; case 10: werase(cmd_); box(cmd_, 0, 0); wmove(cmd_, 1, 1); // exec command // save buffer in history H.add(cmd_buffer_); // send buffer wprintw(msg_, "%s\n", cmd_buffer_); wrefresh(msg_); // purge buffer *cmd_buffer_ = 0; cmd_buf_off_ = 0; cmd_buf_win_off_ = 0; cmd_history_off_ = 0; break; case KEY_BACKSPACE: if (x <= 1) break; wmove(cmd_, y, --x); waddch(cmd_, ' '); wmove(cmd_, y, x); break; case KEY_RESIZE: wrefresh(cmd_); wrefresh(msg_); if (cmd_buf_off_ == 0) break; del_char(cmd_buffer_, --cmd_buf_off_, CMD_BUFFER_SIZE); break; default: waddch(cmd_, key | A_BOLD); if (!isprint(key)) break; if (cmd_buf_off_ >= CMD_BUFFER_SIZE - 1) break; add_char(key, cmd_buffer_, cmd_buf_off_++, CMD_BUFFER_SIZE); } draw_cmd(); } } void Screen::draw_cmd() { char print_buf[CMD_BUFFER_SIZE]; // clean and redraw the cmd box werase(cmd_); box(cmd_, 0, 0); wmove(cmd_, 1, 1); // compute offset if ((ssize_t) cmd_buf_off_ - cmd_buf_win_off_ > cmd_buf_win_size_) ++cmd_buf_win_off_; // copy part of buffer in print buffer strncpy(print_buf, cmd_buffer_ + cmd_buf_win_off_, cmd_buf_win_size_ - 2); print_buf[cmd_buf_win_size_ - 1] = 0; // print print buffer wattron(cmd_, A_BOLD); wprintw(cmd_, "%s", print_buf); wattroff(cmd_, A_BOLD); // move cursor to right pos wmove(cmd_, 1, 1 + cmd_buf_off_); wrefresh(cmd_); } void Screen::add_char(char c, char *string, ssize_t offset, size_t buf_len) { assert(string); size_t len = strlen(string); // check if add one char is possible if (len + 1 >= buf_len - 1) return; // check if offset is good if (offset >= (ssize_t) buf_len - 1 || offset < 0) return; // move one char every char for (ssize_t i = len; i >= offset; --i) string[i + 1] = string[i]; string[offset] = c; } void Screen::del_char(char *string, ssize_t offset, size_t buf_len) { assert(string); size_t len = strlen(string); // check if del one char is possible if (len == 0) return; // check if offset is good if (offset >= (ssize_t) buf_len - 1 || offset < 0) return; // move one char every char for (; string[offset] != 0; ++offset) string[offset] = string[offset + 1]; } void sigwinch(int) { return; } Screen &operator<< (Screen &scr, const string &s) { wprintw(scr.msg_, "%s", s.c_str()); wrefresh(scr.msg_); return scr; } Screen &operator<< (Screen &scr, int i) { wprintw(scr.msg_, "%d", i); wrefresh(scr.msg_); return scr; } slc/trunk/src/screen.hh +21 −0 Original line number Diff line number Diff line Loading @@ -3,15 +3,36 @@ # include <ncurses.h> #define CMD_BUFFER_SIZE 512 class Screen { public: Screen(); void init(); void run(); friend Screen &operator<< (Screen &, const string &s); friend Screen &operator<< (Screen &, int i); private: void draw_cmd(); void add_char(char c, char *string, ssize_t offset, size_t len); void del_char(char *string, ssize_t offset, size_t len); void sigwinch(int); private: WINDOW *msg_; // cmd window WINDOW *cmd_; char cmd_buffer_[CMD_BUFFER_SIZE]; char cmd_history_buffer_[CMD_BUFFER_SIZE]; ssize_t cmd_buf_off_; ssize_t cmd_buf_win_off_; size_t cmd_buf_win_size_; size_t cmd_history_off_; }; extern Screen S; #endif Loading
slc/trunk/Makefile.am +3 −1 Original line number Diff line number Diff line Loading @@ -5,7 +5,9 @@ slc_SOURCES= src/slc.hh \ src/options.cc \ src/options.hh \ src/screen.hh \ src/screen.cc src/screen.cc \ src/history.hh \ src/history.cc CLEANFILES= *~ '\#*' .*.swp .*~ Loading
slc/trunk/src/history.cc 0 → 100644 +29 −0 Original line number Diff line number Diff line #include "slc.hh" #include "history.hh" History::History(size_t size) : size_(size) {} History::~History() { // save into file; } void History::add(const string &line) { if (table_.size() + 1 > size_) table_.erase(table_.begin()); table_.push_back(line); ++size_; } const string &History::get(size_t off) const { assert(table_.size() > 0); assert(off < table_.size()); return table_[table_.size() - 1 - off]; } const string &History::get() const { return table_.back(); } size_t History::size() const { return table_.size(); }
slc/trunk/src/history.hh 0 → 100644 +28 −0 Original line number Diff line number Diff line #ifndef HISTORY_HH # define HISTORY_HH # include <vector> # define HISTORY_SIZE 256 class History { public: History(size_t size); ~History(); const string &get(size_t off) const; const string &get() const; void add(const string &line); size_t size() const; void save(const string &filename); private: string filename_; std::vector<string> table_; size_t size_; }; extern History H; #endif
slc/trunk/src/screen.cc +135 −25 Original line number Diff line number Diff line #include <ctype.h> #include <signal.h> #include "slc.hh" #include "screen.hh" #include "history.hh" Screen::Screen() { msg_ = 0; cmd_ = 0; } Screen::Screen() {} void Screen::init() { // Init ncurses Loading @@ -28,50 +29,159 @@ void Screen::init() { // Create msg window msg_ = newwin(row - 3, col, 0, 0); box(msg_, 0, 0); wrefresh(msg_); // Create cmd window cmd_ = newwin(3, col, row - 3, 0); box(cmd_, 0 , 0); // set buf value *cmd_buffer_ = 0; cmd_buf_off_ = 0; cmd_buf_win_off_ = 0; cmd_buf_win_size_ = col - 1; cmd_history_off_ = 0; wmove(cmd_, 1, 1); wrefresh(cmd_); //register sigwinch } void Screen::run() { int key; int x,y; while (1) { key = getch(); getyx(cmd_, y,x); int key = getch(); switch(key) { // KEY UP case KEY_UP: if (cmd_history_off_ + 1 > H.size()) break; if (cmd_history_off_ == 0) memcpy(cmd_history_buffer_, cmd_buffer_, CMD_BUFFER_SIZE); strncpy(cmd_buffer_, H.get(cmd_history_off_++).c_str(), CMD_BUFFER_SIZE); cmd_buffer_[CMD_BUFFER_SIZE - 1] = 0; break; // KEY DOWN case KEY_DOWN: if (cmd_history_off_ == 0) break; --cmd_history_off_; if (cmd_history_off_ == 0) memcpy(cmd_buffer_, cmd_history_buffer_, CMD_BUFFER_SIZE); else { strncpy(cmd_buffer_, H.get(cmd_history_off_ - 1).c_str(), CMD_BUFFER_SIZE); cmd_buffer_[CMD_BUFFER_SIZE - 1] = 0; } break; // KEY LEFT case KEY_LEFT: wmove(cmd_, y, --x); if (cmd_buf_off_ > 0) --cmd_buf_off_; break; // KEY RIGHT case KEY_RIGHT: wmove(cmd_, y, ++x); if ((size_t) cmd_buf_off_ < strlen(cmd_buffer_)) ++cmd_buf_off_; break; case 10: werase(cmd_); box(cmd_, 0, 0); wmove(cmd_, 1, 1); // exec command // save buffer in history H.add(cmd_buffer_); // send buffer wprintw(msg_, "%s\n", cmd_buffer_); wrefresh(msg_); // purge buffer *cmd_buffer_ = 0; cmd_buf_off_ = 0; cmd_buf_win_off_ = 0; cmd_history_off_ = 0; break; case KEY_BACKSPACE: if (x <= 1) break; wmove(cmd_, y, --x); waddch(cmd_, ' '); wmove(cmd_, y, x); break; case KEY_RESIZE: wrefresh(cmd_); wrefresh(msg_); if (cmd_buf_off_ == 0) break; del_char(cmd_buffer_, --cmd_buf_off_, CMD_BUFFER_SIZE); break; default: waddch(cmd_, key | A_BOLD); if (!isprint(key)) break; if (cmd_buf_off_ >= CMD_BUFFER_SIZE - 1) break; add_char(key, cmd_buffer_, cmd_buf_off_++, CMD_BUFFER_SIZE); } draw_cmd(); } } void Screen::draw_cmd() { char print_buf[CMD_BUFFER_SIZE]; // clean and redraw the cmd box werase(cmd_); box(cmd_, 0, 0); wmove(cmd_, 1, 1); // compute offset if ((ssize_t) cmd_buf_off_ - cmd_buf_win_off_ > cmd_buf_win_size_) ++cmd_buf_win_off_; // copy part of buffer in print buffer strncpy(print_buf, cmd_buffer_ + cmd_buf_win_off_, cmd_buf_win_size_ - 2); print_buf[cmd_buf_win_size_ - 1] = 0; // print print buffer wattron(cmd_, A_BOLD); wprintw(cmd_, "%s", print_buf); wattroff(cmd_, A_BOLD); // move cursor to right pos wmove(cmd_, 1, 1 + cmd_buf_off_); wrefresh(cmd_); } void Screen::add_char(char c, char *string, ssize_t offset, size_t buf_len) { assert(string); size_t len = strlen(string); // check if add one char is possible if (len + 1 >= buf_len - 1) return; // check if offset is good if (offset >= (ssize_t) buf_len - 1 || offset < 0) return; // move one char every char for (ssize_t i = len; i >= offset; --i) string[i + 1] = string[i]; string[offset] = c; } void Screen::del_char(char *string, ssize_t offset, size_t buf_len) { assert(string); size_t len = strlen(string); // check if del one char is possible if (len == 0) return; // check if offset is good if (offset >= (ssize_t) buf_len - 1 || offset < 0) return; // move one char every char for (; string[offset] != 0; ++offset) string[offset] = string[offset + 1]; } void sigwinch(int) { return; } Screen &operator<< (Screen &scr, const string &s) { wprintw(scr.msg_, "%s", s.c_str()); wrefresh(scr.msg_); return scr; } Screen &operator<< (Screen &scr, int i) { wprintw(scr.msg_, "%d", i); wrefresh(scr.msg_); return scr; }
slc/trunk/src/screen.hh +21 −0 Original line number Diff line number Diff line Loading @@ -3,15 +3,36 @@ # include <ncurses.h> #define CMD_BUFFER_SIZE 512 class Screen { public: Screen(); void init(); void run(); friend Screen &operator<< (Screen &, const string &s); friend Screen &operator<< (Screen &, int i); private: void draw_cmd(); void add_char(char c, char *string, ssize_t offset, size_t len); void del_char(char *string, ssize_t offset, size_t len); void sigwinch(int); private: WINDOW *msg_; // cmd window WINDOW *cmd_; char cmd_buffer_[CMD_BUFFER_SIZE]; char cmd_history_buffer_[CMD_BUFFER_SIZE]; ssize_t cmd_buf_off_; ssize_t cmd_buf_win_off_; size_t cmd_buf_win_size_; size_t cmd_history_off_; }; extern Screen S; #endif