summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--buffer.c6
-rw-r--r--config.c137
-rw-r--r--ide-highlights.c4
-rw-r--r--ide-hover.c4
-rw-r--r--main.c26
-rw-r--r--ted.c49
-rw-r--r--ted.cfg6
-rw-r--r--ted.h38
8 files changed, 181 insertions, 89 deletions
diff --git a/buffer.c b/buffer.c
index bb7fabf..12295e7 100644
--- a/buffer.c
+++ b/buffer.c
@@ -2612,7 +2612,7 @@ bool buffer_handle_click(Ted *ted, TextBuffer *buffer, vec2 click, u8 times) {
ted_switch_to_buffer(ted, buffer);
}
if (buffer == ted->active_buffer) {
- switch (ted->key_modifier) {
+ switch (ted_get_key_modifier(ted)) {
case KEY_MODIFIER_SHIFT:
// select to position
buffer_select_to_pos(buffer, buffer_pos);
@@ -2624,9 +2624,9 @@ bool buffer_handle_click(Ted *ted, TextBuffer *buffer, vec2 click, u8 times) {
// go to definition/declaration
buffer_cursor_move_to_pos(buffer, buffer_pos);
GotoType type = GOTO_DEFINITION;
- if (ted->key_modifier & KEY_MODIFIER_SHIFT)
+ if (ted_is_shift_down(ted))
type = GOTO_DECLARATION;
- else if (ted->key_modifier & KEY_MODIFIER_ALT)
+ else if (ted_is_alt_down(ted))
type = GOTO_TYPE_DEFINITION;
buffer_goto_word_at_cursor(buffer, type);
}
diff --git a/config.c b/config.c
index 1fd2675..46dc258 100644
--- a/config.c
+++ b/config.c
@@ -45,6 +45,11 @@ typedef struct {
size_t buf_size;
bool per_language;
} SettingString;
+typedef struct {
+ const char *name;
+ const KeyCombo *control;
+ bool per_language;
+} SettingKeyCombo;
typedef enum {
SETTING_BOOL = 1,
@@ -52,7 +57,8 @@ typedef enum {
SETTING_U16,
SETTING_U32,
SETTING_FLOAT,
- SETTING_STRING
+ SETTING_STRING,
+ SETTING_KEY_COMBO
} SettingType;
typedef struct {
SettingType type;
@@ -65,12 +71,13 @@ typedef struct {
SettingU32 _u32;
SettingFloat _float;
SettingString _string;
+ SettingKeyCombo _key;
} u;
} SettingAny;
// core settings
static const Settings settings_zero = {0};
-static SettingBool const settings_bool[] = {
+static const SettingBool settings_bool[] = {
{"auto-indent", &settings_zero.auto_indent, true},
{"auto-add-newline", &settings_zero.auto_add_newline, true},
{"auto-reload", &settings_zero.auto_reload, true},
@@ -91,7 +98,7 @@ static SettingBool const settings_bool[] = {
{"highlight-enabled", &settings_zero.highlight_enabled, true},
{"highlight-auto", &settings_zero.highlight_auto, true},
};
-static SettingU8 const settings_u8[] = {
+static const SettingU8 settings_u8[] = {
{"tab-width", &settings_zero.tab_width, 1, 100, true},
{"cursor-width", &settings_zero.cursor_width, 1, 100, true},
{"undo-save-time", &settings_zero.undo_save_time, 1, 200, true},
@@ -100,23 +107,23 @@ static SettingU8 const settings_u8[] = {
{"scrolloff", &settings_zero.scrolloff, 1, 100, true},
{"tags-max-depth", &settings_zero.tags_max_depth, 1, 100, false},
};
-static SettingU16 const settings_u16[] = {
+static const SettingU16 settings_u16[] = {
{"text-size", &settings_zero.text_size, TEXT_SIZE_MIN, TEXT_SIZE_MAX, false},
{"max-menu-width", &settings_zero.max_menu_width, 10, U16_MAX, false},
{"error-display-time", &settings_zero.error_display_time, 0, U16_MAX, false},
{"framerate-cap", &settings_zero.framerate_cap, 3, 1000, false},
};
-static SettingU32 const settings_u32[] = {
+static const SettingU32 settings_u32[] = {
{"max-file-size", &settings_zero.max_file_size, 100, 2000000000, false},
{"max-file-size-view-only", &settings_zero.max_file_size_view_only, 100, 2000000000, false},
};
-static SettingFloat const settings_float[] = {
+static const SettingFloat settings_float[] = {
{"cursor-blink-time-on", &settings_zero.cursor_blink_time_on, 0, 1000, true},
{"cursor-blink-time-off", &settings_zero.cursor_blink_time_off, 0, 1000, true},
{"hover-time", &settings_zero.hover_time, 0, INFINITY, true},
{"ctrl-scroll-adjust-text-size", &settings_zero.ctrl_scroll_adjust_text_size, -10, 10, true},
};
-static SettingString const settings_string[] = {
+static const SettingString settings_string[] = {
{"build-default-command", settings_zero.build_default_command, sizeof settings_zero.build_default_command, true},
{"build-command", settings_zero.build_command, sizeof settings_zero.build_command, true},
{"root-identifiers", settings_zero.root_identifiers, sizeof settings_zero.root_identifiers, true},
@@ -125,6 +132,10 @@ static SettingString const settings_string[] = {
{"comment-start", settings_zero.comment_start, sizeof settings_zero.comment_start, true},
{"comment-end", settings_zero.comment_end, sizeof settings_zero.comment_end, true},
};
+static const SettingKeyCombo settings_key_combo[] = {
+ {"hover-key", &settings_zero.hover_key, true},
+ {"highlight-key", &settings_zero.highlight_key, true},
+};
static void setting_bool_set(Settings *settings, const SettingBool *set, bool value) {
@@ -150,6 +161,10 @@ static void setting_string_set(Settings *settings, const SettingString *set, con
char *control = (char *)settings + (set->control - (char*)&settings_zero);
str_cpy(control, set->buf_size, value);
}
+static void setting_key_combo_set(Settings *settings, const SettingKeyCombo *set, KeyCombo value) {
+ KeyCombo *control = (KeyCombo *)((char *)settings + ((char*)set->control - (char*)&settings_zero));
+ *control = value;
+}
typedef struct {
@@ -244,29 +259,68 @@ static void config_part_free(ConfigPart *part) {
memset(part, 0, sizeof *part);
}
+static SDL_Keycode config_parse_key(ConfigReader *cfg, const char *str) {
+ SDL_Keycode keycode = SDL_GetKeyFromName(str);
+ if (keycode != SDLK_UNKNOWN)
+ return keycode;
+ typedef struct {
+ const char *keyname1;
+ const char *keyname2; // alternate key name
+ SDL_Keycode keycode;
+ } KeyName;
+ static KeyName const key_names[] = {
+ {"X1", NULL, KEYCODE_X1},
+ {"X2", NULL, KEYCODE_X2},
+ {"Enter", NULL, SDLK_RETURN},
+ {"Equals", "Equal", SDLK_EQUALS},
+ };
+ for (size_t i = 0; i < arr_count(key_names); ++i) {
+ KeyName const *k = &key_names[i];
+ if (streq_case_insensitive(str, k->keyname1) || (k->keyname2 && streq_case_insensitive(str, k->keyname2))) {
+ keycode = k->keycode;
+ break;
+ }
+ }
+ if (keycode != SDLK_UNKNOWN)
+ return keycode;
+
+ if (isdigit(str[0])) { // direct keycode numbers, e.g. Ctrl+24 or Ctrl+08
+ char *endp;
+ long n = strtol(str, &endp, 10);
+ if (*endp == '\0' && n > 0) {
+ return (SDL_Keycode)n;
+ } else {
+ config_err(cfg, "Invalid keycode number: %s", str);
+ return 0;
+ }
+ } else {
+ config_err(cfg, "Unrecognized key name: %s.", str);
+ return 0;
+ }
+}
// Returns the key combination described by str.
-static u32 config_parse_key_combo(ConfigReader *cfg, const char *str) {
+static KeyCombo config_parse_key_combo(ConfigReader *cfg, const char *str) {
u32 modifier = 0;
// read modifier
while (true) {
if (str_has_prefix(str, "Ctrl+")) {
if (modifier & KEY_MODIFIER_CTRL) {
config_err(cfg, "Ctrl+ written twice");
- return 0;
+ return (KeyCombo){0};
}
modifier |= KEY_MODIFIER_CTRL;
str += strlen("Ctrl+");
} else if (str_has_prefix(str, "Shift+")) {
if (modifier & KEY_MODIFIER_SHIFT) {
config_err(cfg, "Shift+ written twice");
- return 0;
+ return (KeyCombo){0};
}
modifier |= KEY_MODIFIER_SHIFT;
str += strlen("Shift+");
} else if (str_has_prefix(str, "Alt+")) {
if (modifier & KEY_MODIFIER_ALT) {
config_err(cfg, "Alt+ written twice");
- return 0;
+ return (KeyCombo){0};
}
modifier |= KEY_MODIFIER_ALT;
str += strlen("Alt+");
@@ -274,42 +328,9 @@ static u32 config_parse_key_combo(ConfigReader *cfg, const char *str) {
}
// read key
- SDL_Keycode keycode = SDL_GetKeyFromName(str);
- if (keycode == SDLK_UNKNOWN) {
- typedef struct {
- const char *keyname1;
- const char *keyname2; // alternate key name
- SDL_Keycode keycode;
- } KeyName;
- static KeyName const key_names[] = {
- {"X1", NULL, KEYCODE_X1},
- {"X2", NULL, KEYCODE_X2},
- {"Enter", NULL, SDLK_RETURN},
- {"Equals", "Equal", SDLK_EQUALS},
- };
- for (size_t i = 0; i < arr_count(key_names); ++i) {
- KeyName const *k = &key_names[i];
- if (streq_case_insensitive(str, k->keyname1) || (k->keyname2 && streq_case_insensitive(str, k->keyname2))) {
- keycode = k->keycode;
- break;
- }
- }
- if (keycode == SDLK_UNKNOWN) {
- if (isdigit(str[0])) { // direct keycode numbers, e.g. Ctrl+24 or Ctrl+08
- char *endp;
- long n = strtol(str, &endp, 10);
- if (*endp == '\0' && n > 0) {
- keycode = (SDL_Keycode)n;
- } else {
- config_err(cfg, "Invalid keycode number: %s", str);
- return 0;
- }
- } else {
- config_err(cfg, "Unrecognized key name: %s.", str);
- return 0;
- }
- }
- }
+ SDL_Keycode keycode = config_parse_key(cfg, str);
+ if (keycode == SDLK_UNKNOWN)
+ return (KeyCombo){0};
return KEY_COMBO(modifier, keycode);
}
@@ -430,6 +451,13 @@ static void config_init_settings(void) {
opt->u._string = settings_string[i];
++opt;
}
+ for (size_t i = 0; i < arr_count(settings_key_combo); ++i) {
+ opt->type = SETTING_KEY_COMBO;
+ opt->name = settings_key_combo[i].name;
+ opt->per_language = settings_key_combo[i].per_language;
+ opt->u._key = settings_key_combo[i];
+ ++opt;
+ }
settings_initialized = true;
}
@@ -753,7 +781,7 @@ static void config_parse_line(ConfigReader *cfg, Settings **applicable_settings,
} break;
case SECTION_KEYBOARD: {
// lines like Ctrl+Down = 10 :down
- u32 key_combo = config_parse_key_combo(cfg, key);
+ KeyCombo key_combo = config_parse_key_combo(cfg, key);
KeyAction action = {0};
action.key_combo = key_combo;
llong argument = 1; // default argument = 1
@@ -798,7 +826,7 @@ static void config_parse_line(ConfigReader *cfg, Settings **applicable_settings,
bool have = false;
// check if we already have an action for this key combo
arr_foreach_ptr(settings->key_actions, KeyAction, act) {
- if (act->key_combo == key_combo) {
+ if (act->key_combo.value == key_combo.value) {
*act = action;
have = true;
break;
@@ -961,6 +989,13 @@ static void config_parse_line(ConfigReader *cfg, Settings **applicable_settings,
setting_string_set(settings, setting, value);
}
} break;
+ case SETTING_KEY_COMBO: {
+ const SettingKeyCombo *setting = &setting_any->u._key;
+ KeyCombo combo = config_parse_key_combo(cfg, value);
+ if (combo.value) {
+ setting_key_combo_set(settings, setting, combo);
+ }
+ } break;
}
}
@@ -970,9 +1005,9 @@ static void config_parse_line(ConfigReader *cfg, Settings **applicable_settings,
static int key_action_qsort_cmp_combo(const void *av, const void *bv) {
const KeyAction *a = av, *b = bv;
- if (a->key_combo < b->key_combo)
+ if (a->key_combo.value < b->key_combo.value)
return -1;
- if (a->key_combo > b->key_combo)
+ if (a->key_combo.value > b->key_combo.value)
return 1;
return 0;
}
diff --git a/ide-highlights.c b/ide-highlights.c
index 4188f4e..8c58657 100644
--- a/ide-highlights.c
+++ b/ide-highlights.c
@@ -52,9 +52,9 @@ void highlights_frame(Ted *ted) {
return;
}
const Settings *settings = buffer_settings(buffer);
- bool f2_down = SDL_GetKeyboardState(NULL)[SDL_SCANCODE_F2];
+ bool key_down = ted_is_key_combo_down(ted, settings->highlight_key);
if (!settings->highlight_enabled
- || (!settings->highlight_auto && !f2_down)) {
+ || (!settings->highlight_auto && !key_down)) {
highlights_close(ted);
return;
}
diff --git a/ide-hover.c b/ide-hover.c
index b88a960..4c6c5f2 100644
--- a/ide-hover.c
+++ b/ide-hover.c
@@ -89,9 +89,9 @@ void hover_frame(Ted *ted, double dt) {
return;
Hover *hover = &ted->hover;
- bool f1_down = SDL_GetKeyboardState(NULL)[SDL_SCANCODE_F1];
+ bool key_down = ted_is_key_combo_down(ted, settings->hover_key);
- bool open_hover = f1_down || hover->time >= settings->hover_time;
+ bool open_hover = key_down || hover->time >= settings->hover_time;
hover->time += dt;
diff --git a/main.c b/main.c
index 8d15c1b..974bc8a 100644
--- a/main.c
+++ b/main.c
@@ -5,7 +5,6 @@ FUTURE FEATURES:
- better undo chaining (dechain on backspace?)
- manual.md
- regenerate tags for completion too if there are no results
-- make go-to-definition/hover/highlight modifier key configurable
- font setting & support for multiple fonts to cover more characters
- support for variable-width fonts
- robust find (results shouldn't move around when you type things)
@@ -602,28 +601,21 @@ int main(int argc, char **argv) {
double frame_start = time_get_seconds();
ted->frame_time = frame_start;
- SDL_Event event;
- Uint8 const *keyboard_state = SDL_GetKeyboardState(NULL);
-
+ SDL_PumpEvents();
+ u32 key_modifier = ted_get_key_modifier(ted);
{ // get mouse position
int mouse_x = 0, mouse_y = 0;
ted->mouse_state = SDL_GetMouseState(&mouse_x, &mouse_y);
ted->mouse_pos = Vec2((float)mouse_x, (float)mouse_y);
}
- bool ctrl_down = keyboard_state[SDL_SCANCODE_LCTRL] || keyboard_state[SDL_SCANCODE_RCTRL];
- bool shift_down = keyboard_state[SDL_SCANCODE_LSHIFT] || keyboard_state[SDL_SCANCODE_RSHIFT];
- bool alt_down = keyboard_state[SDL_SCANCODE_LALT] || keyboard_state[SDL_SCANCODE_RALT];
memset(ted->nmouse_clicks, 0, sizeof ted->nmouse_clicks);
memset(ted->nmouse_releases, 0, sizeof ted->nmouse_releases);
ted->scroll_total_x = ted->scroll_total_y = 0;
ted_update_window_dimensions(ted);
- u32 key_modifier = (u32)ctrl_down << KEY_MODIFIER_CTRL_BIT
- | (u32)shift_down << KEY_MODIFIER_SHIFT_BIT
- | (u32)alt_down << KEY_MODIFIER_ALT_BIT;
- ted->key_modifier = key_modifier;
+ SDL_Event event;
while (SDL_PollEvent(&event)) {
TextBuffer *buffer = ted->active_buffer;
@@ -632,7 +624,7 @@ int main(int argc, char **argv) {
command_execute(ted, CMD_QUIT, 1);
break;
case SDL_MOUSEWHEEL: {
- if (ctrl_down) {
+ if (ted_is_ctrl_down(ted)) {
// adjust text size with ctrl+scroll
Settings *settings = ted_active_settings(ted);
scroll_wheel_text_size_change += settings->ctrl_scroll_adjust_text_size * event.wheel.preciseY;
@@ -840,16 +832,16 @@ int main(int argc, char **argv) {
TextBuffer *active_buffer = ted->active_buffer;
if (active_buffer && key_modifier == KEY_MODIFIER_ALT) {
// alt + arrow keys to scroll
- double scroll_speed = 20.0;
+ double scroll_speed = 40.0;
double scroll_amount_x = scroll_speed * frame_dt * 1.5; // characters are taller than they are wide
double scroll_amount_y = scroll_speed * frame_dt;
- if (keyboard_state[SDL_SCANCODE_UP])
+ if (ted_is_key_down(ted, SDLK_UP))
buffer_scroll(active_buffer, 0, -scroll_amount_y);
- if (keyboard_state[SDL_SCANCODE_DOWN])
+ if (ted_is_key_down(ted, SDLK_DOWN))
buffer_scroll(active_buffer, 0, +scroll_amount_y);
- if (keyboard_state[SDL_SCANCODE_LEFT])
+ if (ted_is_key_down(ted, SDLK_LEFT))
buffer_scroll(active_buffer, -scroll_amount_x, 0);
- if (keyboard_state[SDL_SCANCODE_RIGHT])
+ if (ted_is_key_down(ted, SDLK_RIGHT))
buffer_scroll(active_buffer, +scroll_amount_x, 0);
}
diff --git a/ted.c b/ted.c
index d5335d4..4eb43be 100644
--- a/ted.c
+++ b/ted.c
@@ -35,6 +35,49 @@ static void ted_vset_message(Ted *ted, MessageType type, const char *fmt, va_lis
}
}
+bool ted_is_key_down(Ted *ted, SDL_Keycode key) {
+ // not currently used but there might be a reason for it in the future
+ (void)ted;
+
+ const Uint8 *kbd_state = SDL_GetKeyboardState(NULL);
+ for (int i = 0; i < SDL_NUM_SCANCODES; ++i) {
+ if (kbd_state[i] && SDL_GetKeyFromScancode((SDL_Scancode)i) == key) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ted_is_key_combo_down(Ted *ted, KeyCombo combo) {
+ if (!ted_is_key_down(ted, KEY_COMBO_KEY(combo)))
+ return false;
+ if (KEY_COMBO_MODIFIER(combo) != ted_get_key_modifier(ted))
+ return false;
+ return true;
+}
+
+bool ted_is_ctrl_down(Ted *ted) {
+ return ted_is_key_down(ted, SDLK_LCTRL) || ted_is_key_down(ted, SDLK_RCTRL);
+}
+
+bool ted_is_shift_down(Ted *ted) {
+ return ted_is_key_down(ted, SDLK_LSHIFT) || ted_is_key_down(ted, SDLK_RSHIFT);
+}
+
+bool ted_is_alt_down(Ted *ted) {
+ return ted_is_key_down(ted, SDLK_LALT) || ted_is_key_down(ted, SDLK_RALT);
+}
+
+u32 ted_get_key_modifier(Ted *ted) {
+ u32 ctrl_down = ted_is_ctrl_down(ted);
+ u32 shift_down = ted_is_shift_down(ted);
+ u32 alt_down = ted_is_alt_down(ted);
+ return ctrl_down << KEY_MODIFIER_CTRL_BIT
+ | shift_down << KEY_MODIFIER_SHIFT_BIT
+ | alt_down << KEY_MODIFIER_ALT_BIT;
+}
+
+
void ted_set_message(Ted *ted, MessageType type, const char *fmt, ...) {
va_list args;
va_start(args, fmt);
@@ -559,7 +602,7 @@ void ted_load_configs(Ted *ted, bool reloading) {
}
void ted_press_key(Ted *ted, SDL_Keycode keycode, SDL_Keymod modifier) {
- u32 key_combo = KEY_COMBO(
+ KeyCombo key_combo = KEY_COMBO(
(u32)((modifier & (KMOD_LCTRL|KMOD_RCTRL)) != 0) << KEY_MODIFIER_CTRL_BIT |
(u32)((modifier & (KMOD_LSHIFT|KMOD_RSHIFT)) != 0) << KEY_MODIFIER_SHIFT_BIT |
(u32)((modifier & (KMOD_LALT|KMOD_RALT)) != 0) << KEY_MODIFIER_ALT_BIT,
@@ -570,9 +613,9 @@ void ted_press_key(Ted *ted, SDL_Keycode keycode, SDL_Keymod modifier) {
u32 hi = arr_len(key_actions);
while (lo < hi) {
u32 mid = (lo + hi) / 2;
- if (key_actions[mid].key_combo < key_combo) {
+ if (key_actions[mid].key_combo.value < key_combo.value) {
lo = mid + 1;
- } else if (key_actions[mid].key_combo > key_combo) {
+ } else if (key_actions[mid].key_combo.value > key_combo.value) {
hi = mid;
} else {
command_execute(ted, key_actions[mid].command, key_actions[mid].argument);
diff --git a/ted.cfg b/ted.cfg
index dbcc9d7..375901c 100644
--- a/ted.cfg
+++ b/ted.cfg
@@ -51,12 +51,16 @@ lsp-log = off
# display function signature help? (only with LSP running)
# this is the thing at the bottom of ted which shows the parameters to the function you're calling
signature-help-enabled = yes
-# display hover info when F1 key is pressed? (only with LSP running)
+# display hover info when the F1 key is pressed? (only with LSP running)
hover-enabled = yes
+# key used to show hover info
+hover-key = F1
# if this is set to x, then hover info will be displayed without F1 key after x seconds (with LSP running)
hover-time = 1e10
# highlight instances of the variable under the cursor when the F2 key is pressed? (only with LSP running)
highlight-enabled = yes
+# key used to highlight variable under cursor
+highlight-key = F2
# don't require F2 key for highlighting
highlight-auto = no
# maximum editable file size.
diff --git a/ted.h b/ted.h
index 12dfcb5..25dfd0a 100644
--- a/ted.h
+++ b/ted.h
@@ -155,8 +155,6 @@ enum {
KEYCODE_X2
};
/// see \ref KEY_COMBO
-#define KEY_COMBO_COUNT (SCANCODE_COUNT << 3)
-/// see \ref KEY_COMBO
enum {
KEY_MODIFIER_CTRL_BIT,
KEY_MODIFIER_SHIFT_BIT,
@@ -168,16 +166,24 @@ enum {
#define KEY_MODIFIER_SHIFT ((u32)1<<KEY_MODIFIER_SHIFT_BIT)
/// see \ref KEY_COMBO
#define KEY_MODIFIER_ALT ((u32)1<<KEY_MODIFIER_ALT_BIT)
-/// Create "key combo" from modifier and key.
-///
/// a "key combo" is some subset of {control, shift, alt} + some key.
-#define KEY_COMBO(modifier, key) ((u32)(modifier) \
- | ((u32)(key >> 30) << 3)\
- | ((u32)(key) & ~(1u<<30)) << 4) // annoyingly SDL sets bit 30 for some keycodes
+typedef struct {
+ /// high 32 bits = SDL_Keycode\n
+ /// low 8 bits = key modifier (see e.g. \ref KEY_MODIFIER_SHIFT)\n
+ /// the remaining 24 bits are currently reserved and should be 0.
+ u64 value;
+} KeyCombo;
+/// Create \ref KeyCombo from modifier and key.
+#define KEY_COMBO(modifier, key) ((KeyCombo){.value = (u64)(modifier) \
+ | ((u64)(key) << 32)})
+/// extract `SDL_Keycode` from \ref KeyCombo
+#define KEY_COMBO_KEY(combo) ((SDL_Keycode)((combo.value) >> 32))
+/// extract key modifier from \ref KeyCombo
+#define KEY_COMBO_MODIFIER(combo) ((u32)((combo.value) & 0xff))
/// Thing to do when a key combo is pressed.
typedef struct {
- u32 key_combo;
+ KeyCombo key_combo;
Command command;
i64 argument;
} KeyAction;
@@ -255,6 +261,8 @@ typedef struct {
bool highlight_enabled;
bool highlight_auto;
bool vsync;
+ KeyCombo hover_key;
+ KeyCombo highlight_key;
u8 tab_width;
u8 cursor_width;
u8 undo_save_time;
@@ -697,8 +705,6 @@ typedef struct Ted {
/// settings to use when no buffer is open
Settings *default_settings;
float window_width, window_height;
- /// which of shift, alt, ctrl are down right now.
- u32 key_modifier;
vec2 mouse_pos;
u32 mouse_state;
/// `nmouse_clicks[i]` = length of `mouse_clicks[i]`
@@ -1535,6 +1541,18 @@ SymbolInfo *tags_get_symbols(Ted *ted);
// === ted.c ===
/// for fatal errors
void die(PRINTF_FORMAT_STRING const char *fmt, ...) ATTRIBUTE_PRINTF(1, 2);
+/// returns `true` if the given key is down
+bool ted_is_key_down(Ted *ted, SDL_Keycode key);
+/// returns `true` if the given \ref KeyCombo is down
+bool ted_is_key_combo_down(Ted *ted, KeyCombo key_combo);
+/// returns `true` if either ctrl key is down
+bool ted_is_ctrl_down(Ted *ted);
+/// returns `true` if either shift key is down
+bool ted_is_shift_down(Ted *ted);
+/// returns `true` if either alt key is down
+bool ted_is_alt_down(Ted *ted);
+/// see \ref KEY_MODIFIER_CTRL, etc.
+u32 ted_get_key_modifier(Ted *ted);
/// display a message to the user
void ted_set_message(Ted *ted, MessageType type, PRINTF_FORMAT_STRING const char *fmt, ...) ATTRIBUTE_PRINTF(3, 4);
/// display an error to the user