Commit afccda67 authored by Seblu's avatar Seblu
Browse files

Ajout de l'history

Nouvelle gestion du positionnement
parent 3491fc61
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -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 .*~

+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();
}
+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
+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
@@ -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;
}
+21 −0
Original line number Diff line number Diff line
@@ -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