esc
Externally Scriptable Editor
git clone git://mccd.space/esc
| Log | Files | Refs | README |
commit 2340849aad69c1d5ba56792081e66b9f11b4a37d parent 6849e4b9fa7ae6a34cebcd0eaeec76ffa1cd4940 Author: Marc Coquand <marc@coquand.email> Date: Thu, 19 Feb 2026 17:46:23 +0100 keybindings Diffstat:
| M | editor.c | | | 13 | +++++++------ |
| M | editor.h | | | 1 | + |
| M | main.c | | | 47 | ++++++++++++++++++++++++++++++++++++++++++++--- |
3 files changed, 52 insertions(+), 9 deletions(-)
diff --git a/editor.c b/editor.c
@@ -85,7 +85,6 @@ void editor_cursor_left(Editor *ed) {
(ed->buffer[ed->cursor_idx] & 0xC0) == 0x80)
ed->cursor_idx--;
}
- ed->selection_anchor = ed->cursor_idx;
}
void editor_cursor_right(Editor *ed) {
@@ -94,6 +93,9 @@ void editor_cursor_right(Editor *ed) {
SDL_StepUTF8(&next, NULL);
ed->cursor_idx = (int)(next - ed->buffer);
}
+}
+
+void editor_clear_selection(Editor *ed) {
ed->selection_anchor = ed->cursor_idx;
}
@@ -104,13 +106,14 @@ void editor_cursor_up(Editor *ed) {
int visual_col = 0;
const char *p = ed->buffer + line_start;
+
while (p < ed->buffer + ed->cursor_idx) {
if (*p == '\t') {
visual_col += TAB_SIZE - (visual_col % TAB_SIZE);
- p++;
- } else {
SDL_StepUTF8(&p, NULL);
+ } else {
visual_col++;
+ SDL_StepUTF8(&p, NULL);
}
}
@@ -127,7 +130,6 @@ void editor_cursor_up(Editor *ed) {
SDL_StepUTF8(&ptr, NULL);
ed->cursor_idx = (int)(ptr - ed->buffer);
}
- ed->selection_anchor = ed->cursor_idx;
}
void editor_cursor_down(Editor *ed) {
int line_start = ed->cursor_idx;
@@ -139,6 +141,7 @@ void editor_cursor_down(Editor *ed) {
while (p < ed->buffer + ed->cursor_idx) {
if (*p == '\t') {
visual_col += TAB_SIZE - (visual_col % TAB_SIZE);
+ SDL_StepUTF8(&p, NULL);
} else {
SDL_StepUTF8(&p, NULL);
visual_col++;
@@ -156,8 +159,6 @@ void editor_cursor_down(Editor *ed) {
}
ed->cursor_idx = (int)(ptr - ed->buffer);
}
-
- ed->selection_anchor = ed->cursor_idx;
}
void editor_set_cursor_from_coords(Editor *ed, float mx, float my,
float scroll_x, float scroll_y) {
diff --git a/editor.h b/editor.h
@@ -26,6 +26,7 @@ void editor_insert_text(Editor *ed, const char *text, bool replace);
void editor_newline(Editor *ed);
void editor_delete_back(Editor *ed);
void editor_delete_forward(Editor *ed);
+void editor_clear_selection(Editor *ed);
void editor_delete_range(Editor *ed, int start, int end);
// Cursor Movement
diff --git a/main.c b/main.c
@@ -1,6 +1,7 @@
#include "editor.h"
#include <SDL3/SDL.h>
#include <SDL3/SDL_events.h>
+#include <SDL3/SDL_keycode.h>
#include <SDL3/SDL_main.h>
#include <SDL3_ttf/SDL_ttf.h>
#include <stdbool.h>
@@ -67,21 +68,60 @@ int main(int argc, char *argv[]) {
case SDLK_TAB:
editor_insert_text(ed, "\t",
true);
+ editor_clear_selection(ed);
break;
case SDLK_RETURN:
editor_newline(ed);
+ editor_clear_selection(ed);
break;
+ case SDLK_B:
+ if (!(event.key.mod &
+ SDL_KMOD_ALT) &&
+ !event.key.repeat)
+ break;
case SDLK_LEFT:
editor_cursor_left(ed);
+ if (!(event.key.mod &
+ SDL_KMOD_SHIFT) ||
+ event.key.repeat)
+ editor_clear_selection(
+ ed);
break;
+ case SDLK_F:
+ if (!(event.key.mod &
+ SDL_KMOD_ALT) &&
+ !event.key.repeat)
+ break;
case SDLK_RIGHT:
editor_cursor_right(ed);
+ if (!(event.key.mod &
+ SDL_KMOD_SHIFT))
+ editor_clear_selection(
+ ed);
break;
+ case SDLK_P:
+ if (!(event.key.mod &
+ SDL_KMOD_ALT) &&
+ !event.key.repeat)
+ break;
case SDLK_UP:
editor_cursor_up(ed);
+ if (!(event.key.mod &
+ SDL_KMOD_SHIFT))
+ editor_clear_selection(
+ ed);
break;
+ case SDLK_N:
+ if (!(event.key.mod &
+ SDL_KMOD_ALT) &&
+ !event.key.repeat)
+ break;
case SDLK_DOWN:
editor_cursor_down(ed);
+ if (!(event.key.mod &
+ SDL_KMOD_SHIFT))
+ editor_clear_selection(
+ ed);
break;
}
case SDL_EVENT_MOUSE_BUTTON_DOWN:
@@ -115,13 +155,14 @@ int main(int argc, char *argv[]) {
editor_set_cursor_from_coords(
ed, mx, my, scroll_x,
scroll_y);
- // We don't update
- // selection_anchor here, so the
- // range expands
}
break;
case SDL_EVENT_TEXT_INPUT:
+ if ((SDL_GetModState() &
+ (SDL_KMOD_ALT | SDL_KMOD_CTRL))) {
+ break;
+ }
editor_insert_text(ed, event.text.text,
true);
break;