sim

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

commit 4e2cfe55274595f5c971b5e409a316a2091867d0
parent d3fcbd4ed5bc7b59ae782e213ed184fcb3d8d90f
Author: ssnf <ssnf@ssnf.xyz>
Date:   Sun,  2 Mar 2025 14:31:02 +0000

add utf8

Diffstat:
Mconfig.def.h | 7++++---
Msim.c | 454++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
2 files changed, 348 insertions(+), 113 deletions(-)

diff --git a/config.def.h b/config.def.h @@ -1,8 +1,9 @@ -#define STATUS "%lu,%u 0x%02x %s%s -%lu- %u" \ +#define STATUS "%lu,%u 0x%02lx %s %s%s -%lu- %u" \ , f->dot.p1 \ , curpos() \ - , f->s.s[f->dot.p1] \ - , f->name.n ? f->name.s : "-unnamed-" \ + , rune \ + , urune \ + , fname \ , (f->bd == f->b) ? "" : "*" \ , f - file \ , counter diff --git a/sim.c b/sim.c @@ -7,12 +7,14 @@ #define MINSIZE 16 #define MAXEMPTY 256 +#define UTFMAX 6 #define FILECOUNT 8 #define LENGTH(a) (sizeof(a)/sizeof(a[0])) #define RED(a) CSI "31m" a CSI "0m" #define GREEN(a) CSI "32m" a CSI "0m" typedef long Posn; +typedef ulong Rune; enum { Up = 1, @@ -44,7 +46,7 @@ typedef struct { } Address; typedef struct { - char* s; + Rune *s; ulong n; /*number of filled characters*/ ulong size; } String; @@ -86,12 +88,17 @@ typedef struct { 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); +static String Utf(char* s); static void blind_reader(Frame* fr, Posn p0); static void blind_writer(ushort line, ushort offset, ushort top, ushort bot); static void buf_add( String* is, String* ds, uint c, uint arg, uint count ); static void buf_free(Buffer* p); +static int c2r(Rune *r, uchar c, uchar *seq); static void change(int arg); static uint charsiz(char c, ulong wx); static void count(int arg); @@ -101,6 +108,7 @@ static void delete(int arg); static void dot(int arg); static void redo(int arg); static void escape(int c); +static Rune getr(void); static void init(void); static void input(String* s, uint line, char* prefix); static void insert(int arg); @@ -122,18 +130,22 @@ static void gmove(int arg); 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 void search(int arg); static int selection(int arg); +static ulong str2u(char** buf, String s); static void str_init(String* p); static void str_close(String* p); +static void str_dup(String* p, String q); static void str_zero(String* p); static void str_insure(String* p, ulong n); -static void str_addc(String* p, int c); -static void str_adds(String* p, char* s, ulong n); -static void str_delc(String* p); -static void str_insert(String* p, String* q, Posn p0); +static void str_addr(String* p, Rune r); +static void str_adds(String* p, String q); +static void str_delr(String* p); +static void str_insert(String* p, String q, Posn p0); static void str_delete(String* p, Posn p0, Posn p1); +static void u2str(String *s, char *u); static void undo(int arg); static void move(int); static void quit(int); @@ -144,14 +156,21 @@ static File* f, file[FILECOUNT]; 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", + "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", + "can", "em" , "sub", "esc", "fs" , "gs" , "rs" , "us" +}; #include "config.h" void die(char* fmt, ...) { - uint i; + static char *s; va_list ap; + uint i; win_end(); va_start(ap, fmt); @@ -162,11 +181,13 @@ die(char* fmt, ...) else fputc('\n', stderr); for (i = 0; i < FILECOUNT; ++i) { - if (!file[i].s.n) + f = file + i; + if (!f->s.n) continue; - str_adds(&file[i].name, ".swap", 5); + str_adds(&f->name, Utf(".swap")); file_save(i); - fprintf(stderr, "file saved to %s\n", file[i].name.s); + str2u(&s, f->name); + fprintf(stderr, "file saved to %s\n", s); } abort(); } @@ -192,6 +213,50 @@ erealloc(void* p, ulong n) return p; } +static Rune* +Strchr(Rune *s, Rune r) +{ + for (;*s != '\0'; ++s) + if (*s == r) + return s; + return NULL; +} + +static String +Strn(Rune *r, ulong n) +{ + static String s; + ulong l; + + l = (n + 1) * sizeof(*s.s); + s.s = erealloc(s.s, l); + s.n = n; + memcpy(s.s, r, l); + s.s[s.n] = '\0'; + return s; +} + +static Rune* +Strnstr(Rune *s1, Rune *s2, ulong n) +{ + n *= sizeof(*s2); + do { + s1 = Strchr(s1, s2[0]); + if (s1 != NULL && !memcmp(s1, s2, n)) + return s1; + } while (s1++ != NULL); + return NULL; +} + +static String +Utf(char* s) +{ + static String t; + + u2str(&t, s); + return t; +} + static void blind_reader(Frame* fr, Posn p0) { @@ -221,7 +286,9 @@ blind_reader(Frame* fr, Posn p0) static void blind_writer(ushort line, ushort offset, ushort top, ushort bot) { - ushort i, o; + static char *s; + Posn i, o; + ulong n; i = o = 0; if (offset >= top) @@ -231,9 +298,10 @@ blind_writer(ushort line, ushort offset, ushort top, ushort bot) else if (fr->n) o = fr->n - 1; curmov(0, offset > line ? 0 : line - offset); - fwrite(&f->s.s[fr->a[i].p0], fr->a[o].p1 - fr->a[i].p0 - , 1, stdout - ); + i = fr->a[i].p0; + o = fr->a[o].p1; + n = str2u(&s, Strn(f->s.s + i, o - i)); + fwrite(s, n, 1, stdout); } static void @@ -245,9 +313,9 @@ buf_add(String* is, String* ds, uint c, uint arg, uint count) f->b->next->prev = f->b; f->b = f->b->next; if (is != NULL) - str_insert(&f->b->is, is, 0); + str_insert(&f->b->is, *is, 0); if (ds != NULL) - str_insert(&f->b->ds, ds, 0); + str_insert(&f->b->ds, *ds, 0); f->b->c = c; f->b->arg = arg; f->b->count = count; @@ -265,14 +333,52 @@ buf_free(Buffer* p) free(p); } +static int +c2r(Rune *r, uchar c, uchar *seq) +{ + if (*seq != 0) { + if ((c & 0xc0) != 0x80) { + *seq = 0; + return -1; + } + *r = (*r << 6) | (c & 0x3f); + --*seq; + return 0; + } + if ((c & 0x80) == 0) { + *r = c & 0x7f; + *seq = 0; + } else if ((c & 0xe0) == 0xc0) { + *r = c & 0x1f; + *seq = 1; + } else if ((c & 0xf0) == 0xe0) { + *r = c & 0x0f; + *seq = 2; + } else if ((c & 0xf8) == 0xf0) { + *r = c & 0x07; + *seq = 3; + } else if ((c & 0xfc) == 0xf8) { + *r = c & 0x03; + *seq = 4; + } else if ((c & 0xfe) == 0xfc) { + *r = c & 0x01; + *seq = 5; + } else { + *r = c; + *seq = 0; + } + return 0; +} + static void change(int arg) { String s; - uint count; + Address *a; + uint count; if (!arg) - arg = fgetc(stdin); + arg = getr(); switch (arg) { case 'x': arg = Letter; break; case 'c': arg = Line; break; @@ -286,15 +392,16 @@ change(int arg) if (arg == Word || arg == Letter || arg > 0x7f) ++f->dot.p1; str_init(&s); - if (f->dot.p0 != f->dot.p1) { - str_adds(&s, f->s.s + f->dot.p0, f->dot.p1 - f->dot.p0); - str_delete(&f->s, f->dot.p0, f->dot.p1); + a = &f->dot; + if (a->p0 != a->p1) { + str_adds(&s, Strn(f->s.s + a->p0, a->p1 - a->p0)); + str_delete(&f->s, a->p0, a->p1); + a->p1 = a->p0; } - f->dot.p0 = f->dot.p1 = f->dot.p0; fr_zero(fr); insert(0); if (s.n) - str_insert(&f->b->ds, &s, 0); + str_insert(&f->b->ds, s, 0); f->b->c = Change; f->b->arg = arg; f->b->count = count; @@ -342,12 +449,13 @@ static void delete(int arg) { String s; - uint count; + Address *a; + uint count; if (!f->s.n) return; if (!arg) { - switch (arg = fgetc(stdin)) { + switch (arg = getr()) { case 'x': arg = Letter; break; case 'd': arg = Line; break; case 'G': arg = Bottom; break; @@ -362,15 +470,15 @@ delete(int arg) if ((arg = selection(arg)) < 0) return; str_init(&s); - str_zero(&istr); - str_adds(&s, f->s.s + f->dot.p0, f->dot.p1 + 1 - f->dot.p0); - str_adds(&istr, f->s.s + f->dot.p0, f->dot.p1 + 1 - f->dot.p0); + a = &f->dot; + str_adds(&s, Strn(f->s.s + a->p0, a->p1 + 1 - a->p0)); + str_dup(&istr, s); buf_add(NULL, &s, Delete, arg, count); - str_delete(&f->s, f->dot.p0, f->dot.p1 + 1); + str_delete(&f->s, a->p0, a->p1 + 1); str_close(&s); - if (f->dot.p0 == f->s.n && f->dot.p0) - --f->dot.p0; - f->dot.p1 = f->dot.p0; + if (a->p0 == f->s.n && a->p0) + --a->p0; + a->p1 = a->p0; fr_update(); } @@ -378,9 +486,11 @@ static void dot(int arg) { String ds; + Address *a; if (f->b->prev == NULL) return; + a = &f->dot; arg = f->b->arg; counter = f->b->count; switch (f->b->c) { @@ -389,7 +499,7 @@ dot(int arg) move(EndLine); else move(arg); - str_insert(&f->s, &f->b->is, f->dot.p0); + str_insert(&f->s, f->b->is, a->p0); buf_add(&f->b->is, NULL, Insert, arg, counter); break; case Delete: @@ -400,14 +510,14 @@ dot(int arg) if (f->b->ds.n) { selection(arg); if (arg == Word || arg == Letter || arg > 0x7f) - ++f->dot.p1; - str_adds( - &ds, f->s.s + f->dot.p0, f->dot.p1 - f->dot.p0 + ++a->p1; + str_adds(&ds + , Strn(f->s.s + a->p0, a->p1 - a->p0) ); - str_delete(&f->s, f->dot.p0, f->dot.p1); + str_delete(&f->s, a->p0, a->p1); } if (f->b->is.n) - str_insert(&f->s, &f->b->is, f->dot.p0); + str_insert(&f->s, f->b->is, f->dot.p0); buf_add(&f->b->is, &ds, Change, arg, f->b->count); str_close(&ds); f->dot.p1 = f->dot.p0; @@ -430,7 +540,7 @@ redo(int arg) if (f->b->ds.n) str_delete(&f->s, f->b->p0, f->b->p0 + f->b->ds.n); if (f->b->is.n) - str_insert(&f->s, &f->b->is, f->b->p0); + str_insert(&f->s, f->b->is, f->b->p0); f->dot.p0 = f->dot.p1 = f->b->p0; fr_zero(fr); fr_update(); @@ -450,25 +560,46 @@ escape(int c) ungetc(c + 0x30, stdin); } +static Rune +getr(void) +{ + Rune r; + uchar c, seq; + + r = 0; + seq = 0; + do { + c = fgetc(stdin); + if (c2r(&r, c, &seq) == -1) { + seq = 0; + ungetc(c, stdin); + } + } while (seq != 0); + return r; +} + static void input(String* s, uint line, char* prefix) { - uchar c; + static char *t; + Rune r; for (;;) { - msg(line, "%s%s", prefix, s->s); - switch (c = fgetc(stdin)) { + str2u(&t, *s); + msg(line, "%s%s", prefix, t); + switch (r = getr()) { case Esc: str_zero(s); case '\n': return; case Del: - str_delc(s); + str_delr(s); break; default: - str_addc(s, c); + str_addr(s, r); } } + s->s[s->n] = '\0'; } static int @@ -493,9 +624,9 @@ insert(int arg) String s, c; if (f->s.s[f->s.n - 1] != '\n') - str_addc(&f->s, '\n'); + str_addr(&f->s, '\n'); str_init(&s), str_init(&c); - str_addc(&c, '\0'); + str_addr(&c, '\0'); switch (arg) { case StartLine: case EndLine: @@ -504,36 +635,35 @@ insert(int arg) break; case Down: move(EndLine); - str_addc(&s, '\n'); - str_insert(&f->s, &s, f->dot.p0); + str_addr(&s, '\n'); + str_insert(&f->s, s, f->dot.p0); ++f->dot.p1; break; } for (;;) { resize(); fr_update(); - switch (c.s[0] = fgetc(stdin)) { + switch (c.s[0] = getr()) { case Esc: goto endmode; case Del: if (f->dot.p1 != f->dot.p0) { - str_delc(&s); + str_delr(&s); str_delete(&f->s, f->dot.p1 - 1, f->dot.p1); --f->dot.p1; } break; default: - str_addc(&s, c.s[0]); - str_insert(&f->s, &c, f->dot.p1); + str_addr(&s, c.s[0]); + str_insert(&f->s, c, f->dot.p1); } f->dot.p1 = f->dot.p0 + s.n; } endmode: - str_zero(&istr); - str_insert(&istr, &s, 0); + str_dup(&istr, s); for (counter ? --counter : 0; counter; --counter) { - str_insert(&istr, &s, istr.n); - str_insert(&f->s, &s, f->dot.p0); + str_insert(&istr, s, istr.n); + str_insert(&f->s, s, f->dot.p0); } buf_add(&istr, NULL, Insert, arg, counter); str_close(&s), str_close(&c); @@ -561,13 +691,16 @@ init(void) static void file_close(int arg) { + static char *s; + if (arg != -1) f = &file[arg]; if (f->bd != f->b) { + str2u(&s, f->name); msg(w.wy / 2, RED("Save %s?") " [y/n]" - , f->name.n ? f->name.s : "-unnamed-" + , f->name.n ? s : "-unnamed-" ); - if (fgetc(stdin) == 'y') + if (getr() == 'y') file_save(arg); } str_close(&f->s); @@ -592,19 +725,25 @@ file_init(File* f) static void file_load(File* f) { - FILE* disk; - - if (!(disk = fopen(f->name.s, "r"))) + FILE *disk; + ulong i, n; + char *s; + + s = NULL; + str2u(&s, f->name); + disk = fopen(s, "r"); + if (disk == NULL) return; - fseek(disk, 0, SEEK_END); - if ((f->s.n = ftell(disk))) { - str_insure(&f->s, f->s.n); - rewind(disk); - fread(f->s.s, f->s.n, 1, disk); - } - fclose(disk); - f->dot.p0 = f->dot.p1 = 0; - fr_zero(fr); + s = NULL; + n = 0; + do { + s = erealloc(s, n + 4096); + i = fread(s + n, 1, 4096, disk); + n += i; + } while (i != 0); + s[n] = '\0'; + u2str(&f->s, s); + free(s); } static void @@ -618,19 +757,23 @@ file_open(int arg) static void file_save(int arg) { - FILE* disk; + static char *s; + FILE *disk; + ulong n; - if (arg == -1) - arg = f - file; - if (!file[arg].name.n) { - input(&file[arg].name, w.wy / 2, "File name: "); - if (!file[arg].name.n) + if (arg != -1) + f = &file[arg]; + if (!f->name.n) { + input(&f->name, w.wy / 2, "File name: "); + if (!f->name.n) return; } - disk = fopen(file[arg].name.s, "w"); - fwrite(file[arg].s.s, file[arg].s.n, 1, disk); + str2u(&s, f->name); + disk = fopen(s, "w"); + n = str2u(&s, f->s); + fwrite(s, n, 1, disk); fclose(disk); - file[arg].bd = file[arg].b; + f->bd = f->b; } static void @@ -724,7 +867,9 @@ fr_insure(Frame* fr, ushort n) static void fr_update(void) { - static char stat[128]; + static char stat[128], u[UTFMAX + 1]; + static char *fname, *urune; + Rune rune; uint half; half = w.wy / 2; @@ -734,6 +879,16 @@ fr_update(void) blind_writer(half, fr->cur, half, half + (w.wy % 2)); } else printf(ED); + str2u(&fname, f->name.n ? f->name : Utf("-unnamed-")); + rune = f->s.s[f->dot.p1]; + if (rune < 0x20) + urune = ctrune[rune]; + else if (rune == 0x7f) + urune = "del"; + else { + r2u(u, rune); + urune = u; + } snprintf(stat, w.wx, STATUS); /*i dont care. TODO: care*/ msg(w.wy, "%s", stat); curmov(curpos() + 1, half); @@ -886,7 +1041,7 @@ msg(uint line, char* fmt, ...) static void paste(int arg) { - str_insert(&f->s, &istr, f->dot.p0); + str_insert(&f->s, istr, f->dot.p0); buf_add(&istr, NULL, Insert, 0, 1); } @@ -919,6 +1074,44 @@ pline(int arg) ungetc(i, stdin); } +static uchar +r2u(char *s, Rune r) +{ + char* p; + + p = s; + if (r < (1 << 7)) { + *p++ = r; + } else if (r < (1 << 11)) { + *p++ = 0xc0 | (r >> 6); + *p++ = 0x80 | (r & 0x3f); + } else if (r < (1 << 16)) { + *p++ = 0xe0 | (r >> 12); + *p++ = 0x80 | ((r >> 6) & 0x3f); + *p++ = 0x80 | (r & 0x3f); + } else if (r < (1 << 21)) { + *p++ = 0xf0 | (r >> 18); + *p++ = 0x80 | ((r >> 12) & 0x3f); + *p++ = 0x80 | ((r >> 6) & 0x3f); + *p++ = 0x80 | (r & 0x3f); + } else if (r < (1 << 26)) { + *p++ = 0xf8 | (r >> 24); + *p++ = 0x80 | ((r >> 18) & 0x3f); + *p++ = 0x80 | ((r >> 12) & 0x3f); + *p++ = 0x80 | ((r >> 6) & 0x3f); + *p++ = 0x80 | (r & 0x3f); + } else if (r < (1 << 31)) { + *p++ = 0xfe | (r >> 30); + *p++ = 0x80 | ((r >> 24) & 0x3f); + *p++ = 0x80 | ((r >> 18) & 0x3f); + *p++ = 0x80 | ((r >> 12) & 0x3f); + *p++ = 0x80 | ((r >> 6) & 0x3f); + *p++ = 0x80 | (r & 0x3f); + } + *p = '\0'; + return p - s; +} + static void resize(void) { @@ -936,7 +1129,7 @@ static void search(int arg) { Posn pos; - char* p; + Rune *r; f->s.s[f->s.n] = 0; if (arg == '/' || arg == '?') { @@ -948,8 +1141,8 @@ search(int arg) } if (arg == '/' || arg == 'n') { move(Right); - p = strstr(f->s.s + f->dot.p0, srch.s); - if (p == NULL) { + r = Strnstr(f->s.s + f->dot.p0, srch.s, srch.n); + if (r == NULL) { move(Left); return; } @@ -962,16 +1155,18 @@ search(int arg) && f->s.s[f->dot.p1] != srch.s[0] ; ); - if (!strncmp(f->s.s + f->dot.p1, srch.s, srch.n)) + if (!memcmp(f->s.s + f->dot.p1 + , srch.s , srch.n * sizeof(*srch.s) + )) break; if (!f->dot.p1) { f->dot.p0 = f->dot.p1 = pos; return; } } - p = f->s.s + f->dot.p1; + r = f->s.s + f->dot.p1; } - f->dot.p0 = f->dot.p1 = p - f->s.s; + f->dot.p0 = f->dot.p1 = r - f->s.s; if (srch.s[0] == '\n' && srch.s[1] != '\n') move(Right); fr_update(); @@ -1021,7 +1216,7 @@ selection(int arg) move(EndWord); break; case Till: - arg = fgetc(stdin); + arg = getr(); if (arg == Esc) return 0; till: @@ -1044,6 +1239,19 @@ selection(int arg) return arg; } +static ulong +str2u(char** u, String s) +{ + ulong i, n; + + n = 0; + *u = erealloc(*u, (s.n + 1) * UTFMAX); + for (i = 0; i < s.n; ++i) + n += r2u(*u + n, s.s[i]); + (*u)[n] = '\0'; + return n; +} + static void str_init(String* p) { @@ -1060,6 +1268,13 @@ str_close(String* p) } static void +str_dup(String* p, String q) +{ + str_zero(p); + str_adds(p, q); +} + +static void str_zero(String* p) { if (p->size > MAXEMPTY) { @@ -1067,61 +1282,78 @@ str_zero(String* p) p->size = MAXEMPTY; } p->n = 0; - memset(p->s, 0, p->size); + memset(p->s, 0, p->size * sizeof(*p->s)); } static void str_insure(String* p, ulong n) { - if (p->size < n) { + if (p->size < n + 1) { p->size = n + MAXEMPTY; p->s = erealloc(p->s, p->size * sizeof(*p->s)); } } static void -str_addc(String* p, int c) +str_addr(String* p, Rune r) { - str_insure(p, p->n + 2); - p->s[p->n++] = c; + str_insure(p, p->n + 1); + p->s[p->n++] = r; p->s[p->n] = '\0'; } static void -str_adds(String* p, char* s, ulong n) +str_adds(String *p, String q) { - str_insure(p, p->n + n + 1); - memmove(p->s + p->n, s, n); - p->n += n; + str_insure(p, p->n + q.n); + memcpy(p->s + p->n, q.s, q.n * sizeof(*q.s)); + p->n += q.n; p->s[p->n] = '\0'; } static void -str_delc(String* p) +str_delr(String* p) { if (p->n) - p->s[--p->n] = 0; + p->s[--p->n] = '\0'; } static void -str_insert(String* p, String* q, Posn p0) +str_insert(String* p, String q, Posn p0) { - str_insure(p, p->n + q->n + 1); - memmove(p->s + p0 + q->n, p->s + p0, p->n - p0); - memmove(p->s + p0, q->s, q->n); - p->n += q->n; + str_insure(p, p->n + q.n); + memmove(p->s + p0 + q.n, p->s + p0 + , (p->n - p0) * sizeof(*p->s) + ); + memmove(p->s + p0, q.s, q.n * sizeof(*q.s)); + p->n += q.n; p->s[p->n] = '\0'; } static void str_delete(String* p, Posn p0, Posn p1) { - memmove(p->s + p0, p->s + p1, p->n - p1); + memmove(p->s + p0, p->s + p1, (p->n - p1) * sizeof(*p->s)); p->n -= p1 - p0; p->s[p->n] = '\0'; } static void +u2str(String *s, char *u) +{ + Rune r; + uchar seq; + + str_zero(s); + for (seq = 0; *u != '\0'; ++u) { + if (c2r(&r, *u, &seq) == -1) + --u; + else if (seq == 0) + str_addr(s, r); + } +} + +static void undo(int arg) { if (f->b->prev == NULL) @@ -1134,7 +1366,7 @@ undo(int arg) if (f->b->is.n) str_delete(&f->s, f->b->p0, f->b->p0 + f->b->is.n); if (f->b->ds.n) - str_insert(&f->s, &f->b->ds, f->b->p0); + str_insert(&f->s, f->b->ds, f->b->p0); f->dot.p0 = f->dot.p1 = f->b->p0; f->b = f->b->prev; fr_zero(fr); @@ -1144,10 +1376,12 @@ undo(int arg) static void yank(int arg) { + Address a; + if (!f->s.n) return; if (!arg) { - switch (arg = fgetc(stdin)) { + switch (arg = getr()) { case 'y': arg = Line; break; case 'G': arg = Bottom; break; case 'g': arg = Top; break; @@ -1159,8 +1393,8 @@ yank(int arg) } if ((arg = selection(arg)) < 0) return; - str_zero(&istr); - str_adds(&istr, f->s.s + f->dot.p0, f->dot.p1 + 1 - f->dot.p0); + a = f->dot; + str_dup(&istr, Strn(f->s.s + a.p0, a.p1 + 1 - a.p0)); } int @@ -1171,13 +1405,13 @@ main(int argc, char* argv[]) init(); if (argv[1]) { - str_adds(&f->name, argv[1], strlen(argv[1])); + str_adds(&f->name, Utf(argv[1])); file_load(f); } for (;;) { resize(); fr_update(); - c = fgetc(stdin); + c = getr(); for (i = 0; i < LENGTH(keys); ++i) { if (keys[i].key == c) { keys[i].func(keys[i].value);