esc

Externally Scriptable Editor

git clone git://mccd.space/esc

commit 2340849aad69c1d5ba56792081e66b9f11b4a37d
parent 6849e4b9fa7ae6a34cebcd0eaeec76ffa1cd4940
Author: Marc Coquand <marc@coquand.email>
Date:   Thu, 19 Feb 2026 17:46:23 +0100

keybindings

Diffstat:
Meditor.c | 13+++++++------
Meditor.h | 1+
Mmain.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;