Skip to content

Commit

Permalink
Put the window size into the data model
Browse files Browse the repository at this point in the history
  • Loading branch information
arximboldi committed Aug 4, 2017
1 parent 161a9fc commit 7538341
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 44 deletions.
40 changes: 22 additions & 18 deletions src/ewig/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,6 @@ namespace ewig {

using commands = std::unordered_map<std::string, command>;

constexpr auto quit = [] (auto m, auto)
{
return std::pair{m, [] (auto&& ctx) { ctx.finish(); }};
};

static const auto global_commands = commands
{
{"insert", key_command(insert_char)},
Expand Down Expand Up @@ -61,7 +56,12 @@ static const auto global_commands = commands
{"select-whole-buffer", edit_command(select_whole_buffer)},
};

result<application, action> save(application state, coord)
result<application, action> quit(application app)
{
return {app, [] (auto&& ctx) { ctx.finish(); }};
}

result<application, action> save(application state)
{
if (!is_dirty(state.current)) {
return put_message(state, "nothing to save");
Expand Down Expand Up @@ -91,9 +91,9 @@ coord actual_cursor(buffer buf)
};
}

coord editor_size(coord size)
coord editor_size(application app)
{
return {size.row - 2, size.col};
return {app.window_size.row - 2, app.window_size.col};
}

application clear_input(application state)
Expand All @@ -117,22 +117,27 @@ result<application, action> update(application state, action ev)
[](auto&&) {})(ev);
return state;
},
[&](const terminal_action& ev) -> result_t
[&](const resize_action& ev) -> result_t
{
state.window_size = ev.size;
return state;
},
[&](const key_action& ev) -> result_t
{
state.input = state.input.push_back(ev.key);
const auto& map = state.keys.get();
auto it = map.find(state.input);
if (it != map.end()) {
if (!it->second.empty()) {
auto result = eval_command(state, it->second, ev.size);
auto result = eval_command(state, it->second);
return {clear_input(result.first), result.second};
}
} else if (key_seq{ev.key} != key::ctrl('[')) {
using std::get;
auto is_single_char = state.input.size() == 1;
auto [kres, kkey] = ev.key;
if (is_single_char && !kres && !std::iscntrl(kkey)) {
auto result = eval_command(state, "insert", ev.size);
auto result = eval_command(state, "insert");
return {clear_input(result.first), result.second};
} else {
return clear_input(put_message(state, "unbound key sequence: " +
Expand All @@ -144,28 +149,27 @@ result<application, action> update(application state, action ev)
}

result<application, action> eval_command(application state,
const std::string& cmd,
coord size)
const std::string& cmd)
{
auto it = global_commands.find(cmd);
if (it != global_commands.end()) {
return it->second(put_message(state, "calling command: "s + cmd), size);
return it->second(put_message(state, "calling command: "s + cmd));
} else {
return put_message(state, "unknown command: "s + cmd);
}
}

application apply_edit(application state, coord size, buffer edit)
application apply_edit(application state, buffer edit)
{
state.current = record(state.current,
scroll_to_cursor(edit, editor_size(size)));
scroll_to_cursor(edit, editor_size(state)));
return state;
}

application apply_edit(application state, coord size, std::pair<buffer, text> edit)
application apply_edit(application state, std::pair<buffer, text> edit)
{
state.current = record(state.current,
scroll_to_cursor(edit.first, editor_size(size)));
scroll_to_cursor(edit.first, editor_size(state)));
return put_clipboard(state, edit.second);
}

Expand Down
37 changes: 19 additions & 18 deletions src/ewig/application.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,11 @@

namespace ewig {

struct terminal_action
{
key_code key;
coord size;
};
struct key_action { key_code key; };
struct resize_action { coord size; };

using action = std::variant<terminal_action,
using action = std::variant<key_action,
resize_action,
buffer_action>;

struct message
Expand All @@ -46,24 +44,27 @@ struct message

struct application
{
coord window_size;
buffer current;
key_map keys;
key_seq input;
immer::vector<text> clipboard;
immer::vector<message> messages;
};

using command = std::function<result<application, action>(application, coord)>;
using command = std::function<result<application, action>(application)>;

coord editor_size(application app);

application paste(application app, coord size);
application put_message(application state, std::string str);
application put_clipboard(application state, text content);
application clear_input(application state);

result<application, action> save(application app, coord);
result<application, action> quit(application app);
result<application, action> save(application app);
result<application, action> eval_command(application state,
const std::string& cmd,
coord editor_size);
const std::string& cmd);
result<application, action> update(application state, action ev);

application apply_edit(application state, coord size, buffer edit);
Expand All @@ -72,34 +73,34 @@ application apply_edit(application state, coord size, std::pair<buffer, text> ed
template <typename Fn>
command edit_command(Fn fn)
{
return [=] (application state, coord size) {
return apply_edit(state, size, fn(state.current));
return [=] (application state) {
return apply_edit(state, fn(state.current));
};
}

template <typename Fn>
command paste_command(Fn fn)
{
return [=] (application state, coord size) {
return apply_edit(state, size, fn(state.current, state.clipboard.back()));
return [=] (application state) {
return apply_edit(state, fn(state.current, state.clipboard.back()));
};
}

template <typename Fn>
command scroll_command(Fn fn)
{
return [=] (application state, coord size) {
state.current = fn(state.current, editor_size(size));
return [=] (application state) {
state.current = fn(state.current, editor_size(state));
return state;
};
}

template <typename Fn>
command key_command(Fn fn)
{
return [=] (application state, coord size) {
return [=] (application state) {
auto key = std::get<1>(state.input.back());
return apply_edit(state, size, fn(state.current, key));
return apply_edit(state, fn(state.current, key));
};
}

Expand Down
1 change: 0 additions & 1 deletion src/ewig/buffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ coord actual_cursor(buffer buf);
coord actual_display_cursor(const buffer& buf);

index display_line_col(const line& ln, index col);
coord editor_size(coord size);

buffer page_up(buffer buf, coord size);
buffer page_down(buffer buf, coord size);
Expand Down
4 changes: 2 additions & 2 deletions src/ewig/draw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,11 @@ void draw_text_cursor(const buffer& buf, coord window_size)
cursor.row < buf.scroll.row + window_size.row);
}

void draw(const application& app, coord size)
void draw(const application& app)
{
::erase();

size = editor_size(size);
auto size = editor_size(app);
::move(0, 0);
draw_text(app.current, size);

Expand Down
2 changes: 1 addition & 1 deletion src/ewig/draw.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ enum class color
mode_line_message,
};

void draw(const application& app, coord size);
void draw(const application& app);
void draw_text(const buffer& buf, coord size);
void draw_mode_line(const buffer& buffer, index maxcol);
void draw_message(const message& msg);
Expand Down
4 changes: 2 additions & 2 deletions src/ewig/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ const auto key_map_emacs = make_key_map(

void run(const char* fname)
{
auto init = application{load_buffer(fname), key_map_emacs};
auto serv = boost::asio::io_service{};
auto term = terminal{serv};
auto view = [&] (auto&& state) { draw(state, term.size()); };
auto view = [&] (auto&& state) { draw(state); };
auto quit = [&] { term.stop(); };
auto init = application{term.size(), load_buffer(fname), key_map_emacs};
auto st = store<application, action>{serv, init, update, view, quit};
term.start([&] (auto ev) { st.dispatch (ev); });
serv.run();
Expand Down
7 changes: 6 additions & 1 deletion src/ewig/terminal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,12 @@ void terminal::next_()
auto key = wint_t{};
auto res = ::wget_wch(win_.get(), &key);
next_();
handler_({{res, key}, size()});
// fixme: in theory we should be able to check key ==
// KEY_RESIZE but it seems to not really work...
if (key == KEY_RESIZE)
handler_(resize_action{size()});
else
handler_(key_action{{res, key}});
}
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/ewig/terminal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ namespace ewig {

struct terminal
{
using action_handler = std::function<void(terminal_action)>;
using action_handler = std::function<void(action)>;

terminal(boost::asio::io_service& serv);

Expand Down

0 comments on commit 7538341

Please sign in to comment.