1 #ifndef __MLE_H 2 #define __MLE_H 3 4 #include <stdint.h> 5 #include <limits.h> 6 #include <termbox.h> 7 #include <uthash.h> 8 #include <lua53/lua.h> 9 #include <lua53/lualib.h> 10 #include <lua53/lauxlib.h> 11 #include "mlbuf.h" 12 13 // Typedefs 14 typedef struct editor_s editor_t; // A container for editor-wide globals 15 typedef struct bview_s bview_t; // A view of a buffer 16 typedef struct bview_rect_s bview_rect_t; // A rectangle in bview with a default styling 17 typedef struct bview_listener_s bview_listener_t; // A listener to buffer events in a bview 18 typedef void (*bview_listener_cb_t)(bview_t *bview, baction_t *action, void *udata); // A bview_listener_t callback 19 typedef struct cursor_s cursor_t; // A cursor (insertion mark + selection bound mark) in a buffer 20 typedef struct loop_context_s loop_context_t; // Context for a single _editor_loop 21 typedef struct cmd_s cmd_t; // A command definition 22 typedef struct cmd_context_s cmd_context_t; // Context for a single command invocation 23 typedef struct observer_s observer_t; // An observer of a cmd or event 24 typedef struct kinput_s kinput_t; // A single key input (similar to a tb_event from termbox) 25 typedef struct kmacro_s kmacro_t; // A sequence of kinputs and a name 26 typedef struct kmap_s kmap_t; // A map of keychords to functions 27 typedef struct kmap_node_s kmap_node_t; // A node in a list of keymaps 28 typedef struct kbinding_def_s kbinding_def_t; // A definition of a keymap 29 typedef struct kbinding_s kbinding_t; // A single binding in a keymap 30 typedef struct syntax_s syntax_t; // A syntax definition 31 typedef struct syntax_node_s syntax_node_t; // A node in a linked list of syntaxes 32 typedef struct srule_def_s srule_def_t; // A definition of a syntax 33 typedef struct aproc_s aproc_t; // An asynchronous process 34 typedef void (*aproc_cb_t)(aproc_t *self, char *buf, size_t buf_len); // An aproc_t callback 35 typedef struct editor_prompt_params_s editor_prompt_params_t; // Extra params for editor_prompt 36 typedef struct tb_event tb_event_t; // A termbox event 37 typedef struct prompt_history_s prompt_history_t; // A map of prompt histories keyed by prompt_str 38 typedef struct prompt_hnode_s prompt_hnode_t; // A node in a linked list of prompt history 39 typedef int (*cmd_func_t)(cmd_context_t *ctx); // A command function 40 typedef int (*observer_func_t)(char *event_name, void *event_data, void *udata); // An event callback function 41 typedef struct uscript_s uscript_t; // A userscript 42 typedef struct uhandle_s uhandle_t; // A method handle in a uscript 43 44 // kinput_t 45 struct kinput_s { 46 uint8_t mod; 47 uint32_t ch; 48 uint16_t key; 49 }; 50 51 // bview_rect_t 52 struct bview_rect_s { 53 int x; 54 int y; 55 int w; 56 int h; 57 uint16_t fg; 58 uint16_t bg; 59 }; 60 61 // editor_t 62 struct editor_s { 63 int w; 64 int h; 65 bview_t *top_bviews; 66 bview_t *all_bviews; 67 bview_t *active; 68 bview_t *active_edit; 69 bview_t *active_edit_root; 70 bview_t *status; 71 bview_t *prompt; 72 bview_rect_t rect_edit; 73 bview_rect_t rect_status; 74 bview_rect_t rect_prompt; 75 syntax_t *syntax_map; 76 int is_display_disabled; 77 kmacro_t *macro_map; 78 kinput_t macro_toggle_key; 79 kmacro_t *macro_record; 80 kmacro_t *macro_apply; 81 size_t macro_apply_input_index; 82 int is_recording_macro; 83 char *startup_macro_name; 84 cmd_t *cmd_map; 85 kmap_t *kmap_map; 86 kmap_t *kmap_normal; 87 kmap_t *kmap_prompt_input; 88 kmap_t *kmap_prompt_yn; 89 kmap_t *kmap_prompt_yna; 90 kmap_t *kmap_prompt_ok; 91 kmap_t *kmap_prompt_isearch; 92 kmap_t *kmap_prompt_menu; 93 kmap_t *kmap_menu; 94 prompt_history_t *prompt_history; 95 char *kmap_init_name; 96 kmap_t *kmap_init; 97 aproc_t *aprocs; 98 uscript_t *uscripts; 99 observer_t *observers; 100 FILE *tty; 101 int ttyfd; 102 char *syntax_override; 103 int linenum_type; 104 int tab_width; 105 int tab_to_space; 106 int trim_paste; 107 int auto_indent; 108 int read_rc_file; 109 int highlight_bracket_pairs; 110 int color_col; 111 int soft_wrap; 112 int viewport_scope_x; // TODO cli option 113 int viewport_scope_y; // TODO cli option 114 int headless_mode; 115 loop_context_t *loop_ctx; 116 int loop_depth; 117 int is_in_init; 118 char *insertbuf; 119 size_t insertbuf_size; 120 char *cut_buffer; 121 #define MLE_ERRSTR_SIZE 256 122 char errstr[MLE_ERRSTR_SIZE]; 123 char infostr[MLE_ERRSTR_SIZE]; 124 int debug_exit_after_startup; 125 int debug_dump_state_on_exit; 126 int exit_code; 127 }; 128 129 // srule_def_t 130 struct srule_def_s { 131 char *re; 132 char *re_end; 133 uint16_t fg; 134 uint16_t bg; 135 }; 136 137 // syntax_node_t 138 struct syntax_node_s { 139 srule_t *srule; 140 syntax_node_t *next; 141 syntax_node_t *prev; 142 }; 143 144 // syntax_t 145 struct syntax_s { 146 char *name; 147 char *path_pattern; 148 int tab_width; 149 int tab_to_space; 150 srule_node_t *srules; 151 UT_hash_handle hh; 152 }; 153 154 // bview_t 155 struct bview_s { 156 #define MLE_BVIEW_TYPE_EDIT 0 157 #define MLE_BVIEW_TYPE_STATUS 1 158 #define MLE_BVIEW_TYPE_PROMPT 2 159 editor_t *editor; 160 int x; 161 int y; 162 int w; 163 int h; 164 int is_resized; 165 int type; 166 int linenum_width; 167 int abs_linenum_width; 168 int rel_linenum_width; 169 bview_rect_t rect_caption; 170 bview_rect_t rect_lines; 171 bview_rect_t rect_margin_left; 172 bview_rect_t rect_buffer; 173 bview_rect_t rect_margin_right; 174 buffer_t *buffer; 175 bint_t viewport_x; 176 bint_t viewport_x_vcol; 177 bint_t viewport_y; 178 bline_t *viewport_bline; 179 int viewport_scope_x; 180 int viewport_scope_y; 181 bview_t *split_parent; 182 bview_t *split_child; 183 float split_factor; 184 int split_is_vertical; 185 char *prompt_str; 186 char *path; 187 bint_t startup_linenum; 188 kmap_node_t *kmap_stack; 189 kmap_node_t *kmap_tail; 190 cursor_t *cursors; 191 cursor_t *active_cursor; 192 char *last_search; 193 srule_t *isearch_rule; 194 int tab_width; 195 int tab_to_space; 196 syntax_t *syntax; 197 aproc_t *aproc; 198 cmd_func_t menu_callback; 199 int is_menu; 200 #ifndef PATH_MAX 201 #define PATH_MAX 4096 202 #endif 203 char init_cwd[PATH_MAX + 1]; 204 bview_listener_t *listeners; 205 bview_t *top_next; 206 bview_t *top_prev; 207 bview_t *all_next; 208 bview_t *all_prev; 209 }; 210 211 // bview_listener_t 212 struct bview_listener_s { 213 bview_listener_cb_t callback; 214 void *udata; 215 bview_listener_t *next; 216 bview_listener_t *prev; 217 }; 218 219 // cursor_t 220 struct cursor_s { 221 bview_t *bview; 222 mark_t *mark; 223 mark_t *anchor; 224 int is_anchored; 225 int is_asleep; 226 srule_t *sel_rule; 227 char *cut_buffer; 228 cursor_t *next; 229 cursor_t *prev; 230 }; 231 232 // kmacro_t 233 struct kmacro_s { 234 char *name; 235 kinput_t *inputs; 236 size_t inputs_len; 237 size_t inputs_cap; 238 UT_hash_handle hh; 239 }; 240 241 // cmd_t 242 struct cmd_s { 243 char *name; 244 cmd_func_t func; 245 void *udata; 246 int is_resolved; 247 UT_hash_handle hh; 248 }; 249 250 // kbinding_def_t 251 struct kbinding_def_s { 252 #define MLE_KBINDING_DEF(pcmdname, pkeypatt) { (pcmdname), (pkeypatt), NULL } 253 #define MLE_KBINDING_DEF_EX(pcmdname, pkeypatt, pstatp) { (pcmdname), (pkeypatt), (pstatp) } 254 char *cmd_name; 255 char *key_patt; 256 char *static_param; 257 }; 258 259 // kbinding_t 260 struct kbinding_s { 261 kinput_t input; 262 char *cmd_name; 263 cmd_t *cmd; 264 char *static_param; 265 char *key_patt; 266 int is_leaf; 267 kbinding_t *children; 268 UT_hash_handle hh; 269 }; 270 271 // kmap_node_t 272 struct kmap_node_s { 273 kmap_t *kmap; 274 bview_t *bview; 275 kmap_node_t *next; 276 kmap_node_t *prev; 277 }; 278 279 // kmap_t 280 struct kmap_s { 281 char *name; 282 kbinding_t *bindings; 283 int allow_fallthru; 284 char *default_cmd_name; 285 cmd_t *default_cmd; 286 UT_hash_handle hh; 287 }; 288 289 // cmd_context_t 290 struct cmd_context_s { 291 #define MLE_PASTEBUF_INCR 1024 292 editor_t *editor; 293 loop_context_t *loop_ctx; 294 cmd_t *cmd; 295 buffer_t *buffer; 296 bview_t *bview; 297 cursor_t *cursor; 298 kinput_t input; 299 char *static_param; 300 int is_user_input; 301 kinput_t *pastebuf; 302 size_t pastebuf_len; 303 size_t pastebuf_size; 304 int has_pastebuf_leftover; 305 kinput_t pastebuf_leftover; 306 }; 307 308 // observer_t 309 struct observer_s { 310 char *event_name; 311 observer_func_t callback; 312 void *udata; 313 observer_t *next; 314 observer_t *prev; 315 }; 316 317 // loop_context_t 318 struct loop_context_s { 319 #define MLE_LOOP_CTX_MAX_NUMERIC_LEN 20 320 #define MLE_LOOP_CTX_MAX_NUMERIC_PARAMS 8 321 #define MLE_LOOP_CTX_MAX_WILDCARD_PARAMS 8 322 #define MLE_LOOP_CTX_MAX_COMPLETE_TERM_SIZE 256 323 bview_t *invoker; 324 char numeric[MLE_LOOP_CTX_MAX_NUMERIC_LEN + 1]; 325 kbinding_t *numeric_node; 326 int numeric_len; 327 uintmax_t numeric_params[MLE_LOOP_CTX_MAX_NUMERIC_PARAMS]; 328 int numeric_params_len; 329 uint32_t wildcard_params[MLE_LOOP_CTX_MAX_WILDCARD_PARAMS]; 330 int wildcard_params_len; 331 kbinding_t *binding_node; 332 int need_more_input; 333 int should_exit; 334 char *prompt_answer; 335 cmd_func_t prompt_callack; 336 prompt_hnode_t *prompt_hnode; 337 int tab_complete_index; 338 char tab_complete_term[MLE_LOOP_CTX_MAX_COMPLETE_TERM_SIZE]; 339 cmd_t *last_cmd; 340 str_t last_insert; 341 }; 342 343 // aproc_t 344 struct aproc_s { 345 editor_t *editor; 346 void *owner; 347 aproc_t **owner_aproc; 348 FILE *rpipe; 349 FILE *wpipe; 350 pid_t pid; 351 int rfd; 352 int wfd; 353 int is_done; 354 aproc_cb_t callback; 355 aproc_t *next; 356 aproc_t *prev; 357 }; 358 359 // editor_prompt_params_t 360 struct editor_prompt_params_s { 361 char *data; 362 int data_len; 363 kmap_t *kmap; 364 bview_listener_cb_t prompt_cb; 365 void *prompt_cb_udata; 366 }; 367 368 // prompt_history_t 369 struct prompt_history_s { 370 char *prompt_str; 371 prompt_hnode_t *prompt_hlist; 372 UT_hash_handle hh; 373 }; 374 375 // prompt_hnode_t 376 struct prompt_hnode_s { 377 char *data; 378 bint_t data_len; 379 prompt_hnode_t *prev; 380 prompt_hnode_t *next; 381 }; 382 383 // uscript_t 384 struct uscript_s { 385 editor_t *editor; 386 lua_State *L; 387 uhandle_t *uhandles; 388 uscript_t *prev; 389 uscript_t *next; 390 }; 391 392 // uhandle_t 393 struct uhandle_s { 394 uscript_t *uscript; 395 int callback_ref; 396 uhandle_t *next; 397 uhandle_t *prev; 398 }; 399 400 // editor functions 401 int editor_init(editor_t *editor, int argc, char **argv); 402 int editor_run(editor_t *editor); 403 int editor_deinit(editor_t *editor); 404 int editor_prompt(editor_t *editor, char *prompt, editor_prompt_params_t *params, char **optret_answer); 405 int editor_menu(editor_t *editor, cmd_func_t fn_callback, char *opt_buf_data, int opt_buf_data_len, aproc_t *opt_aproc, bview_t **optret_menu); 406 int editor_open_bview(editor_t *editor, bview_t *opt_parent, int type, char *opt_path, int opt_path_len, int make_active, bint_t linenum, int skip_resize, buffer_t *opt_buffer, bview_t **optret_bview); 407 int editor_close_bview(editor_t *editor, bview_t *bview, int *optret_num_closed); 408 int editor_set_active(editor_t *editor, bview_t *bview); 409 int editor_bview_edit_count(editor_t *editor); 410 int editor_count_bviews_by_buffer(editor_t *editor, buffer_t *buffer); 411 int editor_register_cmd(editor_t *editor, cmd_t *cmd); 412 int editor_register_observer(editor_t *editor, char *event_name, void *udata, observer_func_t fn_callback, observer_t **optret_observer); 413 int editor_notify_observers(editor_t *editor, char *event_name, void *event_data); 414 int editor_destroy_observer(editor_t *editor, observer_t *observer); 415 int editor_get_input(editor_t *editor, loop_context_t *loop_ctx, cmd_context_t *ctx); 416 int editor_display(editor_t *editor); 417 int editor_debug_dump(editor_t *editor, FILE *fp); 418 int editor_input_to_key(editor_t *editor, kinput_t *input, char *keybuf); 419 420 // bview functions 421 bview_t *bview_get_split_root(bview_t *self); 422 bview_t *bview_new(editor_t *editor, char *opt_path, int opt_path_len, buffer_t *opt_buffer); 423 int bview_add_cursor_asleep(bview_t *self, bline_t *opt_bline, bint_t opt_col, cursor_t **optret_cursor); 424 int bview_add_cursor(bview_t *self, bline_t *opt_bline, bint_t opt_col, cursor_t **optret_cursor); 425 int bview_add_listener(bview_t *self, bview_listener_cb_t fn_callback, void *udata); 426 int bview_center_viewport_y(bview_t *self); 427 int bview_destroy(bview_t *self); 428 int bview_destroy_listener(bview_t *self, bview_listener_t *listener); 429 int bview_draw(bview_t *self); 430 int bview_draw_cursor(bview_t *self, int set_real_cursor); 431 int bview_get_active_cursor_count(bview_t *self); 432 int bview_get_screen_coords(bview_t *self, mark_t *mark, int *ret_x, int *ret_y, struct tb_cell **optret_cell); 433 int bview_max_viewport_y(bview_t *self); 434 int bview_open(bview_t *self, char *path, int path_len); 435 int bview_pop_kmap(bview_t *bview, kmap_t **optret_kmap); 436 int bview_push_kmap(bview_t *bview, kmap_t *kmap); 437 int bview_rectify_viewport(bview_t *self); 438 int bview_remove_cursor(bview_t *self, cursor_t *cursor); 439 int bview_remove_cursors_except(bview_t *self, cursor_t *one); 440 int bview_resize(bview_t *self, int x, int y, int w, int h); 441 int bview_set_syntax(bview_t *self, char *opt_syntax); 442 int bview_set_viewport_y(bview_t *self, bint_t y, int do_rectify); 443 int bview_split(bview_t *self, int is_vertical, float factor, bview_t **optret_bview); 444 int bview_wake_sleeping_cursors(bview_t *self); 445 int bview_zero_viewport_y(bview_t *self); 446 447 // cursor functions 448 int cursor_clone(cursor_t *cursor, int use_srules, cursor_t **ret_clone); 449 int cursor_cut_copy(cursor_t *cursor, int is_cut, int use_srules, int append); 450 int cursor_destroy(cursor_t *cursor); 451 int cursor_drop_anchor(cursor_t *cursor, int use_srules); 452 int cursor_get_lo_hi(cursor_t *cursor, mark_t **ret_lo, mark_t **ret_hi); 453 int cursor_get_mark(cursor_t *cursor, mark_t **ret_mark); 454 int cursor_get_anchor(cursor_t *cursor, mark_t **ret_anchor); 455 int cursor_lift_anchor(cursor_t *cursor); 456 int cursor_replace(cursor_t *cursor, int interactive, char *opt_regex, char *opt_replacement); 457 int cursor_select_between(cursor_t *cursor, mark_t *a, mark_t *b, int use_srules); 458 int cursor_select_by(cursor_t *cursor, const char *strat, int use_srules); 459 int cursor_select_by_bracket(cursor_t *cursor, int use_srules); 460 int cursor_select_by_string(cursor_t *cursor, int use_srules); 461 int cursor_select_by_word_back(cursor_t *cursor, int use_srules); 462 int cursor_select_by_word(cursor_t *cursor, int use_srules); 463 int cursor_select_by_word_forward(cursor_t *cursor, int use_srules); 464 int cursor_toggle_anchor(cursor_t *cursor, int use_srules); 465 int cursor_uncut(cursor_t *cursor); 466 467 // cmd functions 468 int cmd_anchor_by(cmd_context_t *ctx); 469 int cmd_apply_macro_by(cmd_context_t *ctx); 470 int cmd_apply_macro(cmd_context_t *ctx); 471 int cmd_browse(cmd_context_t *ctx); 472 int cmd_close(cmd_context_t *ctx); 473 int cmd_copy_by(cmd_context_t *ctx); 474 int cmd_copy(cmd_context_t *ctx); 475 int cmd_ctag(cmd_context_t *ctx); 476 int cmd_cut_by(cmd_context_t *ctx); 477 int cmd_cut(cmd_context_t *ctx); 478 int cmd_delete_after(cmd_context_t *ctx); 479 int cmd_delete_before(cmd_context_t *ctx); 480 int cmd_delete_word_after(cmd_context_t *ctx); 481 int cmd_delete_word_before(cmd_context_t *ctx); 482 int cmd_drop_cursor_column(cmd_context_t *ctx); 483 int cmd_drop_sleeping_cursor(cmd_context_t *ctx); 484 int cmd_find_word(cmd_context_t *ctx); 485 int cmd_fsearch(cmd_context_t *ctx); 486 int cmd_fsearch_fzy(cmd_context_t *ctx); 487 int cmd_grep(cmd_context_t *ctx); 488 int cmd_indent(cmd_context_t *ctx); 489 int cmd_insert_data(cmd_context_t *ctx); 490 int cmd_insert_newline_above(cmd_context_t *ctx); 491 int cmd_insert_newline(cmd_context_t *ctx); 492 int cmd_insert_tab(cmd_context_t *ctx); 493 int cmd_isearch(cmd_context_t *ctx); 494 int cmd_jump(cmd_context_t *ctx); 495 int cmd_less(cmd_context_t *ctx); 496 int cmd_move_beginning(cmd_context_t *ctx); 497 int cmd_move_bol(cmd_context_t *ctx); 498 int cmd_move_bracket_back(cmd_context_t *ctx); 499 int cmd_move_bracket_forward(cmd_context_t *ctx); 500 int cmd_move_bracket_toggle(cmd_context_t *ctx); 501 int cmd_move_down(cmd_context_t *ctx); 502 int cmd_move_end(cmd_context_t *ctx); 503 int cmd_move_eol(cmd_context_t *ctx); 504 int cmd_move_left(cmd_context_t *ctx); 505 int cmd_move_page_down(cmd_context_t *ctx); 506 int cmd_move_page_up(cmd_context_t *ctx); 507 int cmd_move_relative(cmd_context_t *ctx); 508 int cmd_move_right(cmd_context_t *ctx); 509 int cmd_move_to_line(cmd_context_t *ctx); 510 int cmd_move_until_back(cmd_context_t *ctx); 511 int cmd_move_until_forward(cmd_context_t *ctx); 512 int cmd_move_up(cmd_context_t *ctx); 513 int cmd_move_word_back(cmd_context_t *ctx); 514 int cmd_move_word_forward(cmd_context_t *ctx); 515 int cmd_next(cmd_context_t *ctx); 516 int cmd_noop(cmd_context_t *ctx); 517 int cmd_open_file(cmd_context_t *ctx); 518 int cmd_open_new(cmd_context_t *ctx); 519 int cmd_open_replace_file(cmd_context_t *ctx); 520 int cmd_open_replace_new(cmd_context_t *ctx); 521 int cmd_outdent(cmd_context_t *ctx); 522 int cmd_perl(cmd_context_t *ctx); 523 int cmd_pop_kmap(cmd_context_t *ctx); 524 int cmd_prev(cmd_context_t *ctx); 525 int cmd_push_kmap(cmd_context_t *ctx); 526 int cmd_quit(cmd_context_t *ctx); 527 int cmd_quit_without_saving(cmd_context_t *ctx); 528 int cmd_redo(cmd_context_t *ctx); 529 int cmd_redraw(cmd_context_t *ctx); 530 int cmd_remove_extra_cursors(cmd_context_t *ctx); 531 int cmd_replace(cmd_context_t *ctx); 532 int cmd_save_as(cmd_context_t *ctx); 533 int cmd_save(cmd_context_t *ctx); 534 int cmd_search(cmd_context_t *ctx); 535 int cmd_search_next(cmd_context_t *ctx); 536 int cmd_set_opt(cmd_context_t *ctx); 537 int cmd_shell(cmd_context_t *ctx); 538 int cmd_show_help(cmd_context_t *ctx); 539 int cmd_split_horizontal(cmd_context_t *ctx); 540 int cmd_split_vertical(cmd_context_t *ctx); 541 int cmd_toggle_anchor(cmd_context_t *ctx); 542 int cmd_uncut(cmd_context_t *ctx); 543 int cmd_undo(cmd_context_t *ctx); 544 int cmd_viewport_bot(cmd_context_t *ctx); 545 int cmd_viewport_mid(cmd_context_t *ctx); 546 int cmd_viewport_toggle(cmd_context_t *ctx); 547 int cmd_viewport_top(cmd_context_t *ctx); 548 int cmd_wake_sleeping_cursors(cmd_context_t *ctx); 549 550 // async functions 551 aproc_t *aproc_new(editor_t *editor, void *owner, aproc_t **owner_aproc, char *shell_cmd, int rw, aproc_cb_t fn_callback); 552 int aproc_set_owner(aproc_t *aproc, void *owner, aproc_t **owner_aproc); 553 int aproc_destroy(aproc_t *aproc, int preempt); 554 int aproc_drain_all(aproc_t *aprocs, int *ttyfd); 555 556 // uscript functions 557 uscript_t *uscript_run(editor_t *editor, char *path); 558 int uscript_destroy(uscript_t *uscript); 559 560 // util functions 561 int util_shell_exec(editor_t *editor, char *cmd, long timeout_s, char *input, size_t input_len, int setsid, char *opt_shell, char **optret_output, size_t *optret_output_len); 562 int util_popen2(char *cmd, int setsid, char *opt_shell, int *optret_fdread, int *optret_fdwrite, pid_t *optret_pid); 563 int util_get_bracket_pair(uint32_t ch, int *optret_is_closing); 564 int util_is_file(char *path, char *opt_mode, FILE **optret_file); 565 int util_is_dir(char *path); 566 int util_pcre_match(char *re, char *subject, int subject_len, char **optret_capture, int *optret_capture_len); 567 int util_pcre_replace(char *re, char *subj, char *repl, char **ret_result, int *ret_result_len); 568 int util_timeval_is_gt(struct timeval *a, struct timeval *b); 569 char *util_escape_shell_arg(char *str, int l); 570 int tb_print(int x, int y, uint16_t fg, uint16_t bg, char *str); 571 int tb_printf(bview_rect_t rect, int x, int y, uint16_t fg, uint16_t bg, const char *fmt, ...); 572 int tb_printf_attr(bview_rect_t rect, int x, int y, const char *fmt, ...); 573 void str_append_stop(str_t *str, char *data, char *data_stop); 574 void str_append(str_t *str, char *data); 575 void str_append_len(str_t *str, char *data, size_t data_len); 576 void str_ensure_cap(str_t *str, size_t cap); 577 void str_clear(str_t *str); 578 void str_free(str_t *str); 579 void str_append_replace_with_backrefs(str_t *str, char *subj, char *repl, int pcre_rc, int *pcre_ovector, int pcre_ovecsize); 580 581 // Globals 582 extern editor_t _editor; 583 584 // Macros 585 #define MLE_VERSION "1.4.3" 586 587 #define MLE_OK 0 588 #define MLE_ERR 1 589 590 #define MLE_PROMPT_YES "yes" 591 #define MLE_PROMPT_NO "no" 592 #define MLE_PROMPT_ALL "all" 593 594 #define MLE_DEFAULT_TAB_WIDTH 4 595 #define MLE_DEFAULT_TAB_TO_SPACE 1 596 #define MLE_DEFAULT_TRIM_PASTE 1 597 #define MLE_DEFAULT_AUTO_INDENT 0 598 #define MLE_DEFAULT_MACRO_TOGGLE_KEY "M-r" 599 #define MLE_DEFAULT_HILI_BRACKET_PAIRS 1 600 #define MLE_DEFAULT_READ_RC_FILE 1 601 #define MLE_DEFAULT_SOFT_WRAP 0 602 603 #define MLE_LOG_ERR(fmt, ...) do { \ 604 fprintf(stderr, (fmt), __VA_ARGS__); \ 605 } while (0) 606 607 #define MLE_SET_ERR(editor, fmt, ...) do { \ 608 snprintf((editor)->errstr, MLE_ERRSTR_SIZE, (fmt), __VA_ARGS__); \ 609 } while (0) 610 611 #define MLE_SET_INFO(editor, fmt, ...) do { \ 612 snprintf((editor)->infostr, MLE_ERRSTR_SIZE, (fmt), __VA_ARGS__); \ 613 } while (0) 614 615 #define MLE_RETURN_ERR(editor, fmt, ...) do { \ 616 MLE_SET_ERR((editor), (fmt), __VA_ARGS__); \ 617 return MLE_ERR; \ 618 } while (0) 619 620 #define MLE_MIN(a,b) (((a)<(b)) ? (a) : (b)) 621 #define MLE_MAX(a,b) (((a)>(b)) ? (a) : (b)) 622 623 #define MLE_BVIEW_IS_EDIT(bview) ((bview)->type == MLE_BVIEW_TYPE_EDIT) 624 #define MLE_BVIEW_IS_MENU(bview) ((bview)->is_menu && MLE_BVIEW_IS_EDIT(bview)) 625 #define MLE_BVIEW_IS_POPUP(bview) ((bview)->type == MLE_BVIEW_TYPE_POPUP) 626 #define MLE_BVIEW_IS_STATUS(bview) ((bview)->type == MLE_BVIEW_TYPE_STATUS) 627 #define MLE_BVIEW_IS_PROMPT(bview) ((bview)->type == MLE_BVIEW_TYPE_PROMPT) 628 629 #define MLE_MARK_COL_TO_VCOL(pmark) ( \ 630 (pmark)->col >= (pmark)->bline->char_count \ 631 ? (pmark)->bline->char_vwidth \ 632 : ( (pmark)->col <= 0 ? 0 : (pmark)->bline->chars[(pmark)->col].vcol ) \ 633 ) 634 635 #define MLE_COL_TO_VCOL(pline, pcol, pmax) ( \ 636 (pcol) >= (pline)->char_count \ 637 ? (pmax) \ 638 : ( (pcol) <= 0 ? 0 : (pline)->chars[(pcol)].vcol ) \ 639 ) 640 641 // Setter macros for kinput structs 642 #define MLE_KINPUT_SET_EX(pi, pfill, pmod, pch, pkey) do { \ 643 memset(&(pi), (pfill), sizeof(pi)); \ 644 (pi).mod = (pmod); \ 645 (pi).ch = (pch); \ 646 (pi).key = (pkey); \ 647 } while(0) 648 #define MLE_KINPUT_SET(pi, pmod, pch, pkey) MLE_KINPUT_SET_EX(pi, 0x00, pmod, pch, pkey) 649 #define MLE_KINPUT_SET_SPECIAL(pi, pmod) MLE_KINPUT_SET_EX(pi, 0xff, pmod, 0xffffffff, 0xffff) 650 #define MLE_KINPUT_SET_NUMERIC(pi) MLE_KINPUT_SET_SPECIAL(pi, 0x40) 651 #define MLE_KINPUT_SET_WILDCARD(pi) MLE_KINPUT_SET_SPECIAL(pi, 0x80) 652 #define MLE_KINPUT_COPY(pi, pj) memcpy(&(pi), &(pj), sizeof(pi)) 653 654 #define MLE_LINENUM_TYPE_ABS 0 655 #define MLE_LINENUM_TYPE_REL 1 656 #define MLE_LINENUM_TYPE_BOTH 2 657 658 #define MLE_PARAM_WILDCARD(pctx, pn) ( \ 659 (pn) < (pctx)->loop_ctx->wildcard_params_len \ 660 ? (pctx)->loop_ctx->wildcard_params[(pn)] \ 661 : 0 \ 662 ) 663 664 #define MLE_BRACKET_PAIR_MAX_SEARCH 10000 665 666 #define MLE_RE_WORD_FORWARD "((?<=\\w)\\W|$)" 667 #define MLE_RE_WORD_BACK "((?<=\\W)\\w|^)" 668 669 /* 670 TODO PRIORITY 671 [ ] catch ENOSPC 672 [ ] cleanup lua api, e.g., multi-retval 673 [ ] reduce compiler warnings 674 [ ] add cmd_tabulate 675 [ ] add `_free_` hint to (opt)ret vars that need to be freed 676 [ ] finish uscript callbacks 677 [ ] add some sort of syntax checking via hooks 678 [ ] add ## param to page_up/down (by half/third etc) 679 [ ] fix alt/ctrl-enter in prompt inserts newline 680 [ ] replace mark_set_pcre_capture with mark local 681 [ ] fix invalid cli switch should exit(1) 682 [ ] use editor prompt history when bview prompt history is empty 683 TODO BACKLOG 684 [ ] improve isearch kmap (next/prev history) 685 [ ] add option to undo bactions in same loop# as a group 686 [ ] add buffer_repeat 687 [ ] add block select/move 688 [ ] investigate crash when M-e cat'ing huge files 689 [ ] add mark stack (push, move around, pop to go back) 690 [ ] add last cmd status indicator 691 [ ] pass in (bline_t *opt_hint) to buffer_get_ *and start from there instead of first_line 692 [ ] check if buffer exists by inode instead of path 693 [ ] review default key bindings 694 [ ] review use of multi_cursor_code 695 [ ] review use of MLE_RETURN_ERR 696 [ ] move single-use macros out of mle.h 697 TODO REWRITE 698 [ ] rewrite kmap, trie code is hard to read, ** and ## is not elegant, do not use kinput as hash key 699 [ ] rewrite hili code (use_srules sucks; overlapping multi rules bug; test_buffer_srule_overlap.c.todo) 700 [ ] rewrite aproc and menu code 701 [ ] rewrite buffer_set_mmapped to avoid huge mallocs 702 TODO MAYBE 703 [ ] ?allow uscripts to preempt control, use shared uscriptfd 704 [ ] ?add vim emulation mode 705 [ ] ?add refcounting to prevent uscripts from segfaulting 706 [ ] ?make colors, status line, layout configurable 707 [ ] ?add multi-level undo/redo 708 [ ] ?add simple mouse support 709 */ 710 711 #endif 712