tconf: move variables to conf.h - neatvi - [fork] simple vi-type editor with UTF-8 support
git clone git://src.adamsgaard.dk/neatvi
Log
Files
Refs
README
---
commit c217902ff19a4981fef0f0e478f2cae4416e99c7
parent 84c242d464735708949dc486a36af9ef16853a70
Author: Ali Gholami Rudi 
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(-)
---
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)
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;
+}
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},
+};
diff --git a/dir.c b/dir.c
t@@ -3,31 +3,6 @@
 #include 
 #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)
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'] = "۲",
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);
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;
 }
 
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));
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