tconf: move variables to conf.h - neatvi - [fork] simple vi-type editor with UTF-8 support (HTM) git clone git://src.adamsgaard.dk/neatvi (DIR) Log (DIR) Files (DIR) Refs (DIR) README --- (DIR) commit c217902ff19a4981fef0f0e478f2cae4416e99c7 (DIR) parent 84c242d464735708949dc486a36af9ef16853a70 (HTM) Author: Ali Gholami Rudi <ali@rudi.ir> Date: Tue, 19 May 2015 11:52:26 +0430 conf: move variables to conf.h Diffstat: M Makefile | 5 ++++- A conf.c | 46 +++++++++++++++++++++++++++++++ A conf.h | 52 +++++++++++++++++++++++++++++++ M dir.c | 54 +++++++++---------------------- M kmap.h | 7 +++++-- M led.c | 26 ++++++++++++++++++-------- M ren.c | 30 ++++++++++-------------------- M vi.c | 2 +- M vi.h | 6 ++++++ 9 files changed, 157 insertions(+), 71 deletions(-) --- (DIR) diff --git a/Makefile b/Makefile t@@ -2,9 +2,12 @@ CC = cc CFLAGS = -Wall -O2 LDFLAGS = -OBJS = vi.o ex.o lbuf.o sbuf.o ren.o dir.o reg.o led.o uc.o term.o rset.o cmd.o +OBJS = vi.o ex.o lbuf.o sbuf.o ren.o dir.o reg.o led.o uc.o term.o rset.o cmd.o conf.o all: vi + +conf.o: conf.h + %.o: %.c $(CC) -c $(CFLAGS) $< vi: $(OBJS) (DIR) diff --git a/conf.c b/conf.c t@@ -0,0 +1,46 @@ +#include "conf.h" +#include "vi.h" + +char *conf_kmapalt(void) +{ + return KMAPALT; +} + +int conf_dirmark(int idx, char **pat, int *ctx, int *dir, int *grp) +{ + if (idx < 0 || idx >= LEN(dirmarks)) + return 1; + if (pat) + *pat = dirmarks[idx].pat; + if (ctx) + *ctx = dirmarks[idx].ctx; + if (dir) + *dir = dirmarks[idx].dir; + if (grp) + *grp = dirmarks[idx].grp; + return 0; +} + +int conf_dircontext(int idx, char **pat, int *ctx) +{ + if (idx < 0 || idx >= LEN(dircontexts)) + return 1; + if (pat) + *pat = dircontexts[idx].pat; + if (ctx) + *ctx = dircontexts[idx].dir; + return 0; +} + +int conf_placeholder(int idx, char **s, char **d, int *wid) +{ + if (idx < 0 || idx >= LEN(placeholders)) + return 1; + if (s) + *s = placeholders[idx].s; + if (d) + *d = placeholders[idx].d; + if (wid) + *wid = placeholders[idx].wid; + return 0; +} (DIR) diff --git a/conf.h b/conf.h t@@ -0,0 +1,52 @@ +/* neatvi configuration file */ + +/* the alternate keymap (^F and ^E in insert mode to switch) */ +#define KMAPALT "fa" + +/* right-to-left characters (used only in dircontexts and dirmarks) */ +#define CR2L "ءآأؤإئابةتثجحخدذرزسشصضطظعغـفقكلمنهوىييپچژکگی؛،»«؟ًٌٍَُِّْ" +/* neutral characters (used only in dircontexts and dirmarks) */ +#define CNEUT "-!\"#$%&'()*+,./:;<=>?@^_`{|}~ " + +/* direction context patterns; specifies the direction of a whole line */ +static struct dircontext { + int dir; + char *pat; +} dircontexts[] = { + {-1, "^[" CR2L "]"}, + {+1, "^[a-zA-Z_0-9]"}, +}; + +/* direction marks; the direction of a few words in a line */ +static struct dirmark { + int ctx; /* the direction context for this mark; 0 means any */ + int dir; /* the direction of the matched text */ + int grp; /* the nested subgroup; 0 means no groups */ + char *pat; +} dirmarks[] = { + {+0, +1, 1, "\\\\\\*\\[([^]]+)\\]"}, + {+1, -1, 0, "[" CR2L "][" CNEUT CR2L "]*[" CR2L "]"}, + {-1, +1, 0, "[a-zA-Z0-9_][^" CR2L "\\\\`$']*[a-zA-Z0-9_]"}, + {+0, +1, 0, "$([^$]+)\\$"}, + {+0, +1, 1, "\\\\[a-zA-Z0-9_]+\\{([^}]+)\\}"}, + {-1, +1, 0, "\\\\."}, + {-1, +1, 0, "\\\\[^ \t]+"}, +}; + +/* character placeholders */ +static struct placeholder { + char *s; /* the source character */ + char *d; /* the placeholder */ + int wid; /* the width of the placeholder */ +} placeholders[] = { + {"", "-", 1}, + {"", "-", 1}, + {"ْ", "ـْ", 1}, + {"ٌ", "ـٌ", 1}, + {"ٍ", "ـٍ", 1}, + {"ً", "ـً", 1}, + {"ُ", "ـُ", 1}, + {"ِ", "ـِ", 1}, + {"َ", "ـَ", 1}, + {"ّ", "ـّ", 1}, +}; (DIR) diff --git a/dir.c b/dir.c t@@ -3,31 +3,6 @@ #include <string.h> #include "vi.h" -#define CR2L "ءآأؤإئابةتثجحخدذرزسشصضطظعغـفقكلمنهوىييپچژکگی؛،»«؟ًٌٍَُِّْ" -#define CNEUT "-!\"#$%&'()*+,./:;<=>?@^_`{|}~ " - -/* direction context patterns */ -static struct dcontext { - int dir; - char *pat; -} dcontexts[] = { - {-1, "^[" CR2L "]"}, - {+1, "^[a-zA-Z_0-9]"}, -}; - -/* direction marks */ -static struct dmark { - int ctx; /* the direction context for this mark; 0 means any */ - int dir; /* the direction of matched text */ - int grp; /* the nested subgroup; 0 means no groups */ - char *pat; -} dmarks[] = { - {+0, +1, 0, "$([^$]+)\\$"}, - {+0, +1, 1, "\\\\\\*\\[([^]]+)\\]"}, - {+1, -1, 0, "[" CR2L "][" CNEUT CR2L "]*[" CR2L "]"}, - {-1, +1, 0, "[a-zA-Z0-9_][^" CR2L "\\\\`$']*[a-zA-Z0-9_]"}, -}; - static struct rset *dir_rslr; /* pattern of marks for left-to-right strings */ static struct rset *dir_rsrl; /* pattern of marks for right-to-left strings */ static struct rset *dir_rsctx; /* direction context patterns */ t@@ -38,21 +13,20 @@ static int dir_match(char **chrs, int beg, int end, int ctx, int *rec, int subs[16 * 2]; struct rset *rs = ctx < 0 ? dir_rsrl : dir_rslr; struct sbuf *str = sbuf_make(); + int grp; int flg = (beg ? RE_NOTBOL : 0) | (chrs[end][0] ? RE_NOTEOL : 0); int found; sbuf_mem(str, chrs[beg], chrs[end] - chrs[beg]); found = rset_find(rs, sbuf_buf(str), LEN(subs) / 2, subs, flg); if (found >= 0 && r_beg && r_end && c_beg && c_end) { - struct dmark *dm = &dmarks[found]; char *s = sbuf_buf(str); - int grp = dm->grp; + conf_dirmark(found, NULL, NULL, dir, &grp); *r_beg = beg + uc_off(s, subs[0]); *r_end = beg + uc_off(s, subs[1]); *c_beg = subs[grp * 2 + 0] >= 0 ? beg + uc_off(s, subs[grp * 2 + 0]) : *r_beg; *c_end = subs[grp * 2 + 1] >= 0 ? beg + uc_off(s, subs[grp * 2 + 1]) : *r_end; - *dir = dm->dir; *rec = grp > 0; } sbuf_free(str); t@@ -93,13 +67,14 @@ static void dir_fix(char **chrs, int *ord, int dir, int beg, int end) int dir_context(char *s) { int found; + int dir; if (xdir == 'L') return +1; if (xdir == 'R') return -1; found = rset_find(dir_rsctx, s ? s : "", 0, NULL, 0); - if (found >= 0) - return dcontexts[found].dir; + if (!conf_dircontext(found, NULL, &dir)) + return dir; return xdir == 'r' ? -1 : +1; } t@@ -122,16 +97,17 @@ void dir_init(void) char *relr[128]; char *rerl[128]; char *ctx[128]; - int i; - for (i = 0; i < LEN(dmarks); i++) { - relr[i] = dmarks[i].ctx >= 0 ? dmarks[i].pat : NULL; - rerl[i] = dmarks[i].ctx <= 0 ? dmarks[i].pat : NULL; + int curctx, i; + char *pat; + for (i = 0; !conf_dirmark(i, &pat, &curctx, NULL, NULL); i++) { + relr[i] = curctx >= 0 ? pat : NULL; + rerl[i] = curctx <= 0 ? pat : NULL; } - dir_rslr = rset_make(LEN(dmarks), relr, 0); - dir_rsrl = rset_make(LEN(dmarks), rerl, 0); - for (i = 0; i < LEN(dcontexts); i++) - ctx[i] = dcontexts[i].pat; - dir_rsctx = rset_make(LEN(dcontexts), ctx, 0); + dir_rslr = rset_make(i, relr, 0); + dir_rsrl = rset_make(i, rerl, 0); + for (i = 0; !conf_dircontext(i, &pat, NULL); i++) + ctx[i] = pat; + dir_rsctx = rset_make(i, ctx, 0); } void dir_done(void) (DIR) diff --git a/kmap.h b/kmap.h t@@ -1,6 +1,9 @@ -static char *kmap_def[256]; +static char *kmap_en[256] = { + [0] = "en", +}; -static char *kmap_farsi[256] = { +static char *kmap_fa[256] = { + [0] = "fa", ['`'] = "", ['1'] = "۱", ['2'] = "۲", (DIR) diff --git a/led.c b/led.c t@@ -5,9 +5,19 @@ #include "vi.h" #include "kmap.h" -static char **led_kmap = kmap_def; +static char **kmaps[] = {kmap_en, kmap_fa}; +static char **led_kmap = kmap_en; -static char *keymap(char **kmap, int c) +static char **kmap_find(char *name) +{ + int i; + for (i = 0; i < LEN(kmaps); i++) + if (kmaps[i][0] && !strcmp(name, kmaps[i][0])) + return kmaps[i]; + return kmap_en; +} + +static char *kmap_map(char **kmap, int c) { static char cs[4]; cs[0] = c; t@@ -22,7 +32,7 @@ int led_pos(char *s, int pos) char *led_keymap(int c) { - return c >= 0 ? keymap(led_kmap, c) : NULL; + return c >= 0 ? kmap_map(led_kmap, c) : NULL; } static char *led_render(char *s0) t@@ -115,7 +125,7 @@ static void led_printparts(char *ai, char *pref, char *main, char *post) /* cursor position for inserting the next character */ if (*pref || *main || *ai) { int len = sbuf_len(ln); - sbuf_str(ln, keymap(led_kmap, 'a')); + sbuf_str(ln, kmap_map(led_kmap, 'a')); sbuf_str(ln, post); idir = ren_pos(sbuf_buf(ln), off) - ren_pos(sbuf_buf(ln), off - 1) < 0 ? -1 : +1; t@@ -143,10 +153,10 @@ static char *led_line(char *pref, char *post, char *ai, int ai_max, int *key, ch c = term_read(-1); switch (c) { case TK_CTL('f'): - *kmap = kmap_farsi; + *kmap = kmap_find(conf_kmapalt()); continue; case TK_CTL('e'): - *kmap = kmap_def; + *kmap = kmap_en; continue; case TK_CTL('h'): case 127: t@@ -174,7 +184,7 @@ static char *led_line(char *pref, char *post, char *ai, int ai_max, int *key, ch default: if (c == '\n' || TK_INT(c)) break; - sbuf_str(sb, keymap(*kmap, c)); + sbuf_str(sb, kmap_map(*kmap, c)); } if (c == '\n' || TK_INT(c)) break; t@@ -186,7 +196,7 @@ static char *led_line(char *pref, char *post, char *ai, int ai_max, int *key, ch /* read an ex command */ char *led_prompt(char *pref, char *post) { - char **kmap = kmap_def; + char **kmap = kmap_en; char *s; int key; s = led_line(pref, post, "", 0, &key, &kmap); (DIR) diff --git a/ren.c b/ren.c t@@ -177,36 +177,26 @@ int ren_region(char *s, int c1, int c2, int *l1, int *l2, int closed) return 0; } -static struct placeholder { - char *s; /* the source character */ - char *d; /* the placeholder */ -} placeholders[] = { - {"", "-"}, - {"", "-"}, - {"ْ", "ـْ"}, - {"ٌ", "ـٌ"}, - {"ٍ", "ـٍ"}, - {"ً", "ـً"}, - {"ُ", "ـُ"}, - {"ِ", "ـِ"}, - {"َ", "ـَ"}, - {"ّ", "ـّ"}, -}; - static char *ren_placeholder(char *s) { - int i = 0; + char *src, *dst; + int wid, i; int c = uc_code(s); - for (i = 0; i < LEN(placeholders); i++) - if (uc_code(placeholders[i].s) == c) - return placeholders[i].d; + for (i = 0; !conf_placeholder(i, &src, &dst, &wid); i++) + if (uc_code(src) == c) + return dst; return NULL; } int ren_cwid(char *s, int pos) { + char *src, *dst; + int wid, i; if (s[0] == '\t') return 8 - (pos & 7); + for (i = 0; !conf_placeholder(i, &src, &dst, &wid); i++) + if (uc_code(src) == uc_code(s)) + return wid; return 1; } (DIR) diff --git a/vi.c b/vi.c t@@ -32,7 +32,7 @@ static void vi_draw(void) term_record(); for (i = xtop; i < xtop + xrows; i++) { char *s = lbuf_get(xb, i); - led_print(s ? s : "~", i - xtop); + led_print(s ? s : (i ? "~" : ""), i - xtop); } vi_drawmsg(); term_pos(xrow, led_pos(lbuf_get(xb, i), xcol)); (DIR) diff --git a/vi.h b/vi.h t@@ -124,6 +124,12 @@ void ex_show(char *msg); /* process management */ char *cmd_pipe(char *cmd, char *s); +/* configuration variables */ +char *conf_kmapalt(void); +int conf_dirmark(int idx, char **pat, int *ctx, int *dir, int *grp); +int conf_dircontext(int idx, char **pat, int *ctx); +int conf_placeholder(int idx, char **s, char **d, int *wid); + /* global variables */ #define PATHLEN 512