#ifndef KEYBIND_H #define KEYBIND_H #include #include "app.h" enum direction { DIR_FORWARD, DIR_BACKWARD, }; union keybind_args { enum direction dir; void *ptr; }; typedef struct app (*keybind_func)(struct app, union keybind_args); struct bind { const SDL_Keymod mod; keybind_func func; union keybind_args args; }; #define BINDS_SIZE 10 struct keybinds { uint8_t size; const struct bind binds[BINDS_SIZE]; }; struct app keybind_mv_cur_char(struct app app, union keybind_args args); struct app keybind_forward_char(struct app app, union keybind_args args); struct app keybind_delete_char(struct app app, union keybind_args args); struct app keybind_mv_cur_word(struct app app, union keybind_args args); struct app keybind_delete_word(struct app app, union keybind_args args); struct app keybind_insert_newline(struct app app, union keybind_args args); #if defined(KEYBIND_IMP) || defined(IMP) struct app keybind_mv_cur_char(struct app app, union keybind_args args) { if ( args.dir == DIR_FORWARD ) { app.buf = buffer_mv_cur_right(app.buf); } if ( args.dir == DIR_BACKWARD ) { app.buf = buffer_mv_cur_left(app.buf); } return app; } struct app keybind_delete_char(struct app app, union keybind_args args) { if ( args.dir == DIR_FORWARD ) { app.buf = buffer_remove_char(app.buf, app.buf.cur); } if ( args.dir == DIR_BACKWARD ) { app.buf = buffer_remove_char(app.buf, --app.buf.cur); } return app; } struct app keybind_mv_cur_word(struct app app, union keybind_args args) { size_t index; enum buffer_err err; if ( args.dir == DIR_FORWARD ) { RET_UNWRAP2(index, err, struct ret_size_t_err, buffer_index_fw_word(app.buf)); if ( err != BUFFER_ERR_OK ) { if ( err == BUFFER_ERR_INVALID_CUR_POS ) { app.buf.cur = app.buf.data.size; } return app; } app.buf.cur = index; } if ( args.dir == DIR_BACKWARD ) { RET_UNWRAP2(index, err, struct ret_size_t_err, buffer_index_bw_word(app.buf)); if ( err != BUFFER_ERR_OK ) { if ( err == BUFFER_ERR_INVALID_CUR_POS ) { app.buf.cur = app.buf.data.size; } return app; } app.buf.cur = index; } return app; } struct app keybind_delete_word(struct app app, union keybind_args args) { size_t index, n_rm; enum buffer_err err; if ( args.dir == DIR_BACKWARD ) { RET_UNWRAP2(index, err, struct ret_size_t_err, buffer_index_bw_word(app.buf)); if ( err != BUFFER_ERR_OK ) { if ( err == BUFFER_ERR_INVALID_CUR_POS ) { app.buf.cur = app.buf.data.size; } return app; } RET_UNWRAP3(app.buf, n_rm, err, struct ret_buffer_size_t_err, buffer_remove_between(app.buf, index, app.buf.cur)); if ( err != BUFFER_ERR_OK ) { return app; } app.buf.cur -= n_rm; } if ( args.dir == DIR_FORWARD ) { RET_UNWRAP2(index, err, struct ret_size_t_err, buffer_index_fw_word(app.buf)); if ( err != BUFFER_ERR_OK ) { if ( err == BUFFER_ERR_INVALID_CUR_POS ) { app.buf.cur = app.buf.data.size; } return app; } RET_UNWRAP3(app.buf, n_rm, err, struct ret_buffer_size_t_err, buffer_remove_between(app.buf, app.buf.cur, index)); if ( err != BUFFER_ERR_OK ) { return app; } } return app; } struct app keybind_insert_newline(struct app app, union keybind_args args) { (void) args; app.buf = buffer_insert_char(app.buf, app.buf.cur, '\n'); return app; } #endif /* defined(KEYBIND_IMP) || defined(IMP) */ #endif