sim

the sim text editor
git clone git://ssnf.xyz/sim
Log | Files | Refs | README

commit dcfa54da43d06623c133d973cbc7c375040ecf75
parent 256ff3955e54c488b48a51113f56f9fd507cad85
Author: ssnf <ssnf@ssnf.xyz>
Date:   Thu, 10 Jul 2025 16:28:05 -0500

add signal-based window resize support

Diffstat:
Mposix.c | 22+++++++++++++++-------
Msim.c | 82+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msim.h | 13+++++++------
3 files changed, 67 insertions(+), 50 deletions(-)

diff --git a/posix.c b/posix.c @@ -1,23 +1,23 @@ -#include <sys/ioctl.h> #include <stdio.h> + +#include <sys/ioctl.h> +#include <signal.h> #include <termios.h> #include "sim.h" -void win_end(void); -void win_init(Window* w); -void win_query(Window* w); +static void handle(int); static struct termios initial_state; -void +extern void win_end(void) { printf(ED CSI "H"); tcsetattr(0, TCSAFLUSH, &initial_state); } -void +extern void win_init(Window* w) { struct termios raw_state; @@ -30,9 +30,10 @@ win_init(Window* w) printf(CSI "H\t" CSI "6n"); scanf("\x1b[%*d;%huR", &w->t); --w->t; + handle(SIGWINCH); } -void +extern void win_query(Window* w) { struct winsize ws; @@ -41,3 +42,10 @@ win_query(Window* w) w->wx = ws.ws_col; w->wy = ws.ws_row; } + +static void +handle(int sig) +{ + resize(); + signal(SIGWINCH, handle); +} diff --git a/sim.c b/sim.c @@ -85,9 +85,6 @@ typedef struct { ushort size; } Frame; -void die(char*, ...); -void* emalloc(ulong); -void* erealloc(void*, ulong); static Rune* Strchr(Rune *s, Rune r); static String Strn(Rune *r, ulong n); static Rune* Strnstr(Rune *s1, Rune *s2, ulong n); @@ -107,6 +104,7 @@ static void delete(int arg); static void dot(int arg); static void redo(int arg); static void escape(int c); +static uchar getc2(void); static Rune getr(void); static void init(void); static void input(String* s, uint line, char* prefix); @@ -130,7 +128,6 @@ static void msg(uint line, char* fmt, ...); static void paste(int arg); static void pline(int arg); static uchar r2u(char *s, Rune r); -static void resize(void); static uint runesiz(Rune c, ulong wx); static void search(int arg); static int selection(int arg); @@ -151,11 +148,11 @@ static void move(int); static void quit(int); static void yank(int arg); -static Frame* fr, frame[FILECOUNT]; -static File* f, file[FILECOUNT]; -static String istr, srch; -static Window w; -static uint counter; +static Frame frame[FILECOUNT], *fr = frame; +static File file[FILECOUNT], *f = file; +static String istr, srch; +static Window w; +static uint counter; static char *ctrune[0x20] = { "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel", "bs" , "\\t", "\\n", "vt" , "ff" , "cr" , "so" , "si", @@ -165,7 +162,7 @@ static char *ctrune[0x20] = { #include "config.h" -void +extern void die(char* fmt, ...) { static char *s; @@ -192,7 +189,7 @@ die(char* fmt, ...) abort(); } -void* +extern void* emalloc(ulong n) { void* p; @@ -204,7 +201,7 @@ emalloc(ulong n) return p; } -void* +extern void* erealloc(void* p, ulong n) { p = realloc(p, n); @@ -213,6 +210,20 @@ erealloc(void* p, ulong n) return p; } +extern void +resize(void) +{ + Window wt; + + win_query(&wt); + if (wt.wx != w.wx || wt.wy != w.wy) { + w.wx = wt.wx; + w.wy = wt.wy; + fr_zero(fr); + fr_update(); + } +} + static Rune* Strchr(Rune *s, Rune r) { @@ -542,7 +553,7 @@ static void escape(int c) { counter = 0; - c = fgetc(stdin) - 0x30; + c = getc2() - 0x30; if (c > 0 && c <= 8) { --c; f = &file[c]; @@ -552,6 +563,21 @@ escape(int c) ungetc(c + 0x30, stdin); } +static uchar +getc2(void) +{ + uchar c; + +get: + c = getchar(); + if (c == (uchar)EOF) { + if (!feof(stdin)) + goto get; + exit(0); + } + return c; +} + static Rune getr(void) { @@ -561,7 +587,7 @@ getr(void) r = 0; seq = 0; do { - c = fgetc(stdin); + c = getc2(); if (c2r(&r, c, &seq) == -1) { seq = 0; ungetc(c, stdin); @@ -633,7 +659,6 @@ insert(int arg) break; } for (;;) { - resize(); fr_update(); switch (c.s[0] = getr()) { case Esc: @@ -669,15 +694,13 @@ init(void) { uint i; - win_init(&w); for (i = 0; i < FILECOUNT; ++i) { file_init(&file[i]); fr_init(&frame[i]); } - f = &file[0]; - fr = &frame[0]; str_init(&srch); str_init(&istr); + win_init(&w); } static void @@ -718,7 +741,7 @@ static void file_load(File* f) { FILE *disk; - ulong i, n; + ulong n; char *s; s = NULL; @@ -730,9 +753,8 @@ file_load(File* f) n = 0; do { s = erealloc(s, n + 4096); - i = fread(s + n, 1, 4096, disk); - n += i; - } while (i != 0); + n += fread(s + n, 1, 4096, disk); + } while (!feof(disk)); s[n] = '\0'; u2str(&f->s, s); free(s); @@ -1061,7 +1083,7 @@ pline(int arg) } curmov(0, h); printf("%-4lu ", l); - i = fgetc(stdin); + i = getc2(); if (i != Esc) ungetc(i, stdin); } @@ -1104,19 +1126,6 @@ r2u(char *s, Rune r) return p - s; } -static void -resize(void) -{ - Window wt; - - win_query(&wt); - if (wt.wx != w.wx || wt.wy != w.wy) { - w.wx = wt.wx; - w.wy = wt.wy; - fr_zero(fr); - } -} - static uint runesiz(Rune c, ulong wx) { @@ -1409,7 +1418,6 @@ main(int argc, char* argv[]) file_load(f); } for (;;) { - resize(); fr_update(); c = getr(); for (i = 0; i < LENGTH(keys); ++i) { diff --git a/sim.h b/sim.h @@ -12,9 +12,10 @@ typedef struct { ushort t; } Window; -void die(char* fmt, ...); -void* emalloc(ulong n); -void* erealloc(void* p, ulong n); -void win_end(void); -void win_init(Window* w); -void win_query(Window* w); +extern void die(char* fmt, ...); +extern void* emalloc(ulong n); +extern void* erealloc(void* p, ulong n); +extern void resize(void); +extern void win_end(void); +extern void win_init(Window* w); +extern void win_query(Window* w);