123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549 |
- #ifndef _BIM_CORE_H
- #define _BIM_CORE_H
- #define _XOPEN_SOURCE 700
- #define _DARWIN_C_SOURCE
- #define _DEFAULT_SOURCE
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdint.h>
- #include <stdarg.h>
- #include <unistd.h>
- #include <termios.h>
- #include <signal.h>
- #include <libgen.h>
- #include <locale.h>
- #include <wchar.h>
- #include <ctype.h>
- #include <dirent.h>
- #include <poll.h>
- #include <limits.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/ioctl.h>
- #include <sys/stat.h>
- #include <sys/wait.h>
- #include <kuroko/vm.h>
- #ifdef __DATE__
- # define BIM_BUILD_DATE " built " __DATE__ " at " __TIME__
- #else
- # define BIM_BUILD_DATE DATE ""
- #endif
- #ifdef GIT_TAG
- # define TAG "-" GIT_TAG
- #else
- # define TAG "-alpha"
- #endif
- #define BLOCK_SIZE 4096
- #define ENTER_KEY '\r'
- #define LINE_FEED '\n'
- #define BACKSPACE_KEY 0x08
- #define DELETE_KEY 0x7F
- #define DEFAULT_KEY_WAIT (global_config.background_task ? 0 : -1)
- enum Key {
- KEY_TIMEOUT = -1,
- KEY_CTRL_AT = 0, /* Base */
- KEY_CTRL_A, KEY_CTRL_B, KEY_CTRL_C, KEY_CTRL_D, KEY_CTRL_E, KEY_CTRL_F, KEY_CTRL_G, KEY_CTRL_H,
- KEY_CTRL_I, KEY_CTRL_J, KEY_CTRL_K, KEY_CTRL_L, KEY_CTRL_M, KEY_CTRL_N, KEY_CTRL_O, KEY_CTRL_P,
- KEY_CTRL_Q, KEY_CTRL_R, KEY_CTRL_S, KEY_CTRL_T, KEY_CTRL_U, KEY_CTRL_V, KEY_CTRL_W, KEY_CTRL_X,
- KEY_CTRL_Y, KEY_CTRL_Z, /* Note we keep ctrl-z mapped in termios as suspend */
- KEY_CTRL_OPEN, KEY_CTRL_BACKSLASH, KEY_CTRL_CLOSE, KEY_CTRL_CARAT, KEY_CTRL_UNDERSCORE,
- /* Space... */
- /* Some of these are equivalent to things above */
- KEY_BACKSPACE = 0x08,
- KEY_LINEFEED = '\n',
- KEY_ENTER = '\r',
- KEY_TAB = '\t',
- /* Basic printable characters go here. */
- /* Delete is special */
- KEY_DELETE = 0x7F,
- /* Unicode codepoints go here */
- KEY_ESCAPE = 0x400000, /* Escape would normally be 27, but is special because reasons */
- KEY_F1, KEY_F2, KEY_F3, KEY_F4,
- KEY_F5, KEY_F6, KEY_F7, KEY_F8,
- KEY_F9, KEY_F10, KEY_F11, KEY_F12,
- /* TODO ALT, SHIFT, etc., for F keys */
- KEY_MOUSE, /* Must be followed with a 3-byte mouse read */
- KEY_MOUSE_SGR, /* Followed by an SGR-style sequence of mouse data */
- KEY_HOME, KEY_END, KEY_PAGE_UP, KEY_PAGE_DOWN,
- KEY_UP, KEY_DOWN, KEY_RIGHT, KEY_LEFT,
- KEY_SHIFT_UP, KEY_SHIFT_DOWN, KEY_SHIFT_RIGHT, KEY_SHIFT_LEFT,
- KEY_CTRL_UP, KEY_CTRL_DOWN, KEY_CTRL_RIGHT, KEY_CTRL_LEFT,
- KEY_ALT_UP, KEY_ALT_DOWN, KEY_ALT_RIGHT, KEY_ALT_LEFT,
- KEY_ALT_SHIFT_UP, KEY_ALT_SHIFT_DOWN, KEY_ALT_SHIFT_RIGHT, KEY_ALT_SHIFT_LEFT,
- KEY_SHIFT_TAB,
- /* Special signals for paste start, paste end */
- KEY_PASTE_BEGIN, KEY_PASTE_END,
- };
- struct key_name_map {
- enum Key keycode;
- char * name;
- };
- extern struct key_name_map KeyNames[];
- /**
- * Syntax highlighting flags.
- */
- #define FLAG_NONE 0
- #define FLAG_KEYWORD 1
- #define FLAG_STRING 2
- #define FLAG_COMMENT 3
- #define FLAG_TYPE 4
- #define FLAG_PRAGMA 5
- #define FLAG_NUMERAL 6
- #define FLAG_ERROR 7
- #define FLAG_DIFFPLUS 8
- #define FLAG_DIFFMINUS 9
- #define FLAG_NOTICE 10
- #define FLAG_BOLD 11
- #define FLAG_LINK (12 + (1<<4))
- #define FLAG_ESCAPE 13
- #define FLAG_EXTRA 14
- #define FLAG_SPECIAL 15
- #define FLAG_LINK_COLOR 12
- #define FLAG_UNDERLINE (1 << 4)
- #define FLAG_SELECT (1 << 5)
- #define FLAG_SEARCH (1 << 6)
- #define FLAG_MASK_COLORS 0x0F
- #define FLAG_MASK_ATTRIB 0x70
- /**
- * Line buffer definitions
- *
- * Lines are essentially resizable vectors of char_t structs,
- * which represent single codepoints in the file.
- */
- typedef struct {
- uint32_t display_width:4;
- uint32_t flags:7;
- uint32_t codepoint:21;
- } __attribute__((packed)) char_t;
- /**
- * Lines have available and actual lengths, describing
- * how much space was allocated vs. how much is being
- * used at the moment.
- */
- typedef struct {
- int available;
- int actual;
- int istate;
- int is_current;
- int rev_status;
- char_t text[];
- } line_t;
- typedef struct background_task {
- struct _env * env;
- void (*func)(struct background_task*);
- struct background_task * next;
- int _private_i;
- void * _private_p;
- } background_task_t;
- /**
- * Global configuration state
- *
- * At the moment, this is all in a global, but in the future
- * this should be passed around to various functions.
- */
- typedef struct {
- /* Terminal size */
- int term_width, term_height;
- int bottom_size;
- line_t ** yanks;
- size_t yank_count;
- int yank_is_full_lines;
- int tty_in;
- const char * bimrc_path;
- const char * syntax_fallback;
- uint32_t * search;
- int overlay_mode;
- line_t * command_buffer;
- int command_offset, command_col_no;
- struct syntax_definition * command_syn, * command_syn_back;
- int history_point;
- int search_point;
- int search_direction;
- int prev_line, prev_col, prev_coffset, prev_offset;
- unsigned int highlight_on_open:1;
- unsigned int initial_file_is_read_only:1;
- unsigned int go_to_line:1;
- unsigned int break_from_selection:1;
- unsigned int can_scroll:1;
- unsigned int can_hideshow:1;
- unsigned int can_altscreen:1;
- unsigned int can_mouse:1;
- unsigned int can_unicode:1;
- unsigned int can_bright:1;
- unsigned int can_title:1;
- unsigned int can_bce:1;
- unsigned int can_24bit:1;
- unsigned int can_256color:1;
- unsigned int can_italic:1;
- unsigned int can_insert:1;
- unsigned int can_bracketedpaste:1;
- unsigned int can_sgrmouse:1;
- unsigned int history_enabled:1;
- unsigned int highlight_parens:1;
- unsigned int smart_case:1;
- unsigned int highlight_current_line:1;
- unsigned int shift_scrolling:1;
- unsigned int check_git:1;
- unsigned int color_gutter:1;
- unsigned int relative_lines:1;
- unsigned int numbers:1;
- unsigned int horizontal_shift_scrolling:1;
- unsigned int hide_statusbar:1;
- unsigned int tabs_visible:1;
- unsigned int autohide_tabs:1;
- unsigned int smart_complete:1;
- unsigned int has_terminal:1;
- unsigned int search_wraps:1;
- unsigned int had_error:1;
- unsigned int use_biminfo:1;
- int cursor_padding;
- int split_percent;
- int scroll_amount;
- int tab_offset;
- char * tab_indicator;
- char * space_indicator;
- background_task_t * background_task;
- background_task_t * tail_task;
- } global_config_t;
- #define OVERLAY_MODE_NONE 0
- #define OVERLAY_MODE_READ_ONE 1
- #define OVERLAY_MODE_COMMAND 2
- #define OVERLAY_MODE_SEARCH 3
- #define OVERLAY_MODE_COMPLETE 4
- #define OVERLAY_MODE_FILESEARCH 5
- #define HISTORY_SENTINEL 0
- #define HISTORY_INSERT 1
- #define HISTORY_DELETE 2
- #define HISTORY_REPLACE 3
- #define HISTORY_REMOVE_LINE 4
- #define HISTORY_ADD_LINE 5
- #define HISTORY_REPLACE_LINE 6
- #define HISTORY_MERGE_LINES 7
- #define HISTORY_SPLIT_LINE 8
- #define HISTORY_BREAK 10
- typedef struct history {
- struct history * previous;
- struct history * next;
- int type;
- int line;
- int col;
- union {
- struct {
- int lineno;
- int offset;
- int codepoint;
- int old_codepoint;
- } insert_delete_replace;
- struct {
- int lineno;
- line_t * contents;
- line_t * old_contents;
- } remove_replace_line;
- struct {
- int lineno;
- int split;
- } add_merge_split_lines;
- } contents;
- } history_t;
- /**
- * Buffer data
- *
- * A buffer describes a file, and stores
- * its name as well as the editor state
- * (cursor offsets, etc.) and the actual
- * line buffers.
- */
- typedef struct _env {
- unsigned int loading:1;
- unsigned int tabs:1;
- unsigned int modified:1;
- unsigned int readonly:1;
- unsigned int indent:1;
- unsigned int checkgitstatusonwrite:1;
- unsigned int crnl:1;
- unsigned int numbers:1;
- unsigned int gutter:1;
- unsigned int slowop:1;
- int highlighting_paren;
- int maxcolumn;
- short mode;
- short tabstop;
- char * file_name;
- int offset;
- int coffset;
- int line_no;
- int line_count;
- int line_avail;
- int col_no;
- int preferred_column;
- struct syntax_definition * syntax;
- line_t ** lines;
- history_t * history;
- history_t * last_save_history;
- int width;
- int left;
- int start_line;
- int sel_col;
- int start_col;
- int prev_line;
- } buffer_t;
- struct theme_def {
- const char * name;
- void * callable;
- };
- extern struct theme_def * themes;
- extern void add_colorscheme(struct theme_def theme);
- struct syntax_state {
- buffer_t * env;
- line_t * line;
- int line_no;
- int state;
- int i;
- };
- struct completion_match {
- char * string;
- char * file;
- char * search;
- };
- struct syntax_definition {
- char * name;
- char ** ext;
- int (*calculate)(struct syntax_state *);
- int prefers_spaces;
- int (*completion_qualifier)(int c);
- int (*completion_matcher)(uint32_t * comp, struct completion_match ** matches, int * matches_count, int complete_match, int * matches_len, buffer_t * env);
- void * krkFunc;
- void * krkClass;
- };
- extern struct syntax_definition * syntaxes;
- /**
- * Editor mode states
- */
- #define MODE_NORMAL 0
- #define MODE_INSERT 1
- #define MODE_LINE_SELECTION 2
- #define MODE_REPLACE 3
- #define MODE_CHAR_SELECTION 4
- #define MODE_COL_SELECTION 5
- #define MODE_COL_INSERT 6
- #define MODE_DIRECTORY_BROWSE 7
- struct action_def {
- char * name;
- void (*action)();
- int options;
- const char * description;
- };
- extern struct action_def * mappable_actions;
- #define ARG_IS_INPUT 0x01 /* Takes the key that triggered it as the first argument */
- #define ARG_IS_CUSTOM 0x02 /* Takes a custom argument which is specific to the method */
- #define ARG_IS_PROMPT 0x04 /* Prompts for an argument. */
- #define ACTION_IS_RW 0x08 /* Needs to be able to write. */
- #define BIM_ACTION(name, options, description) \
- void name (); /* Define the action with unknown arguments */ \
- void __attribute__((constructor)) _install_ ## name (void) { \
- add_action((struct action_def){#name, name, options, description}); \
- } \
- void name
- struct command_def {
- char * name;
- int (*command)(char *, int, char * arg[]);
- const char * description;
- };
- #define BIM_COMMAND(cmd_name, cmd_str, description) \
- int bim_command_ ## cmd_name (char * cmd, int argc, char * argv[]); \
- void __attribute__((constructor)) _install_cmd_ ## cmd_name (void) { \
- add_command((struct command_def){cmd_str, bim_command_ ## cmd_name, description}); \
- } \
- int bim_command_ ## cmd_name (char * cmd __attribute__((unused)), int argc __attribute__((unused)), char * argv[] __attribute__((unused)))
- #define BIM_ALIAS(alias, alias_name, cmd_name) \
- void __attribute__((constructor)) _install_alias_ ## alias_name (void) { \
- add_command((struct command_def){alias, bim_command_ ## cmd_name, "Alias for " #cmd_name}); \
- }
- #define BIM_PREFIX_COMMAND(cmd_name, cmd_prefix, description) \
- int bim_command_ ## cmd_name (char * cmd, int argc, char * argv[]); \
- void __attribute__((constructor)) _install_cmd_ ## cmd_name (void) { \
- add_prefix_command((struct command_def){cmd_prefix, bim_command_ ## cmd_name, description}); \
- } \
- int bim_command_ ## cmd_name (char * cmd __attribute__((unused)), int argc __attribute__((unused)), char * argv[] __attribute__((unused)))
- extern const char * flag_to_color(int _flag);
- extern void redraw_line(int x);
- extern int git_examine(char * filename);
- extern void search_next(void);
- extern void set_preferred_column(void);
- extern void quit(const char * message);
- extern void close_buffer(void);
- extern void set_syntax_by_name(const char * name);
- extern void rehighlight_search(line_t * line);
- extern void try_to_center();
- extern int read_one_character(char * message);
- extern void bim_unget(int c);
- #define bim_getch() bim_getch_timeout(200)
- extern int bim_getch_timeout(int timeout);
- extern buffer_t * buffer_new(void);
- extern FILE * open_biminfo(void);
- extern int fetch_from_biminfo(buffer_t * buf);
- extern int update_biminfo(buffer_t * buf, int is_open);
- extern buffer_t * buffer_close(buffer_t * buf);
- extern int to_eight(uint32_t codepoint, char * out);
- extern char * name_from_key(enum Key keycode);
- extern void add_action(struct action_def action);
- extern void open_file(char * file);
- extern void recalculate_selected_lines(void);
- extern void add_command(struct command_def command);
- extern void add_prefix_command(struct command_def command);
- extern void render_command_input_buffer(void);
- extern void unhighlight_matching_paren(void);
- extern void add_syntax(struct syntax_definition def);
- struct ColorName {
- const char * name;
- const char ** value;
- };
- extern struct ColorName color_names[];
- struct bim_function {
- char * command;
- struct bim_function * next;
- };
- extern struct bim_function ** user_functions;
- extern int run_function(char * name);
- extern int has_function(char * name);
- extern void find_matching_paren(int * out_line, int * out_col, int in_col);
- extern void render_error(char * message, ...);
- extern void render_commandline_message(char * message, ...);
- extern void pause_for_key(void);
- #define add_match(match_string, match_file, match_search) do { \
- if (*matches_count == *matches_len) { \
- (*matches_len) *= 2; \
- *matches = realloc(*matches, sizeof(struct completion_match) * (*matches_len)); \
- } \
- (*matches)[*matches_count].string = strdup(match_string); \
- (*matches)[*matches_count].file = strdup(match_file); \
- (*matches)[*matches_count].search = strdup(match_search); \
- (*matches_count)++; \
- } while (0)
- #define add_if_match(name,desc) do { \
- int i = 0; \
- while (comp[i] && comp[i] == (unsigned char)name[i]) i++; \
- if (comp[i] == '\0') { \
- add_match(name,desc,""); \
- } \
- } while (0)
- struct action_map {
- int key;
- void (*method)();
- int options;
- int arg;
- };
- #define opt_rep 0x1 /* This action will be repeated */
- #define opt_arg 0x2 /* This action will take a specified argument */
- #define opt_char 0x4 /* This action will read a character to pass as an argument */
- #define opt_nav 0x8 /* This action will consume the nav buffer as its argument */
- #define opt_rw 0x10 /* Must not be read-only */
- #define opt_norm 0x20 /* Returns to normal mode */
- #define opt_byte 0x40 /* Same as opt_char but forces a byte */
- struct mode_names {
- const char * description;
- const char * name;
- struct action_map ** mode;
- };
- extern struct mode_names mode_names[];
- #define paint(length, flag) do { for (int i = 0; i < (length) && state->i < state->line->actual; i++, state->i++) { \
- state->line->text[state->i].flags = (state->line->text[state->i].flags & (3 << 5)) | (flag); \
- } } while (0)
- #define charat() (state->i < state->line->actual ? state->line->text[(state->i)].codepoint : -1)
- #define nextchar() (state->i + 1 < state->line->actual ? state->line->text[(state->i+1)].codepoint : -1)
- #define lastchar() (state->i - 1 >= 0 ? state->line->text[(state->i-1)].codepoint : -1)
- #define skip() (state->i++)
- #define charrel(x) ((state->i + (x) >= 0 && state->i + (x) < state->line->actual) ? state->line->text[(state->i+(x))].codepoint : -1)
- static int match_and_paint(struct syntax_state * state, const char * keyword, int flag, int (*keyword_qualifier)(int c));
- static int common_comment_buzzwords(struct syntax_state * state);
- static int paint_comment(struct syntax_state * state);
- static struct syntax_definition * find_syntax_calculator(const char * name);
- #define nest(lang, low) \
- do { \
- state->state = (state->state < 1 ? 0 : state->state - low); \
- do { state->state = lang(state); } while (state->state == 0); \
- if (state->state == -1) return low; \
- return state->state + low; \
- } while (0)
- /* Hacky workaround for isdigit not really accepting Unicode stuff */
- static __attribute__((used)) int _isdigit(int c) { if (c > 128) return 0; return isdigit(c); }
- static __attribute__((used)) int _isxdigit(int c) { if (c > 128) return 0; return isxdigit(c); }
- #undef isdigit
- #undef isxdigit
- #define isdigit(c) _isdigit(c)
- #define isxdigit(c) _isxdigit(c)
- #endif /* _BIM_CORE_H */
|