tren: return placeholder characters from ren_translate() - neatvi - [fork] simp… | |
git clone git://src.adamsgaard.dk/neatvi | |
Log | |
Files | |
Refs | |
README | |
--- | |
commit 0c2fb9f33f08de99cfc4e5b61e14259bbbe2c468 | |
parent a183ae6d1a2a745051c1f2a45f1b4de5fcaa4d5d | |
Author: Ali Gholami Rudi <[email protected]> | |
Date: Sun, 17 May 2015 10:10:27 +0430 | |
ren: return placeholder characters from ren_translate() | |
Placeholders are useful especially for zerowidth characters. | |
Diffstat: | |
M dir.c | 2 +- | |
M led.c | 45 ++++++++++++++++++++---------… | |
M ren.c | 64 +++++++++++++++++++++--------… | |
M uc.c | 6 ++---- | |
M vi.h | 3 ++- | |
5 files changed, 77 insertions(+), 43 deletions(-) | |
--- | |
diff --git a/dir.c b/dir.c | |
t@@ -3,7 +3,7 @@ | |
#include <string.h> | |
#include "vi.h" | |
-#define CR2L "ءآأؤإئابةتثجحخدذرزسشصضطظ�… | |
+#define CR2L "ءآأؤإئابةتثجحخدذرزسشصضطظ�… | |
#define CNEUT "-!\"#$%&'()*+,./:;<=>?@^_`{|}~ " | |
/* direction context patterns */ | |
diff --git a/led.c b/led.c | |
t@@ -31,33 +31,45 @@ static char *led_render(char *s0) | |
int *pos; /* pos[i]: the screen position of the i-th character … | |
int *off; /* off[i]: the character at screen position i */ | |
char **chrs; /* chrs[i]: the i-th character in s1 */ | |
- char *s1; | |
struct sbuf *out; | |
- int i; | |
- s1 = ren_translate(s0 ? s0 : ""); | |
- chrs = uc_chop(s1, &n); | |
+ int i, j; | |
+ chrs = uc_chop(s0, &n); | |
pos = ren_position(s0); | |
off = malloc(xcols * sizeof(off[0])); | |
memset(off, 0xff, xcols * sizeof(off[0])); | |
for (i = 0; i < n; i++) { | |
- int curpos = led_pos(s0, pos[i]); | |
- if (curpos >= 0 && curpos < xcols) { | |
- off[curpos] = i; | |
- if (curpos > maxcol) | |
- maxcol = curpos; | |
+ int curpos = pos[i]; | |
+ int curwid = ren_cwid(chrs[i], curpos); | |
+ if (curpos >= 0 && curpos + curwid < xcols) { | |
+ for (j = 0; j < curwid; j++) { | |
+ off[led_pos(s0, curpos + j)] = i; | |
+ if (led_pos(s0, curpos + j) > maxcol) | |
+ maxcol = led_pos(s0, curpos + j); | |
+ } | |
} | |
} | |
out = sbuf_make(); | |
- for (i = 0; i <= maxcol; i++) { | |
- if (off[i] >= 0 && uc_isprint(chrs[off[i]])) | |
- sbuf_mem(out, chrs[off[i]], uc_len(chrs[off[i]])); | |
- else | |
+ i = 0; | |
+ while (i <= maxcol) { | |
+ int o = off[i]; | |
+ if (o >= 0) { | |
+ if (ren_translate(chrs[o], s0)) | |
+ sbuf_str(out, ren_translate(chrs[o], s0)); | |
+ else if (uc_isprint(chrs[o])) | |
+ sbuf_mem(out, chrs[o], uc_len(chrs[o])); | |
+ else | |
+ for (j = i; j <= maxcol && off[j] == o; j++) | |
+ sbuf_chr(out, ' '); | |
+ while (i <= maxcol && off[i] == o) | |
+ i++; | |
+ } else { | |
sbuf_chr(out, ' '); | |
+ i++; | |
+ } | |
} | |
free(pos); | |
free(off); | |
free(chrs); | |
- free(s1); | |
return sbuf_done(out); | |
} | |
t@@ -99,15 +111,16 @@ static void led_printparts(char *ai, char *pref, char *ma… | |
sbuf_str(ln, pref); | |
sbuf_str(ln, main); | |
off = uc_slen(sbuf_buf(ln)); | |
- sbuf_str(ln, post); | |
/* cursor position for inserting the next character */ | |
- if (post[0]) { | |
+ if (post[0] && post[0] != '\n') { | |
+ sbuf_str(ln, post); | |
pos = ren_cursor(sbuf_buf(ln), ren_pos(sbuf_buf(ln), off)); | |
} else { | |
int len = sbuf_len(ln); | |
sbuf_str(ln, keymap(led_kmap, 'a')); | |
pos = ren_cursor(sbuf_buf(ln), ren_pos(sbuf_buf(ln), off)); | |
sbuf_cut(ln, len); | |
+ sbuf_str(ln, post); | |
} | |
led_print(sbuf_buf(ln), -1); | |
term_pos(-1, led_pos(sbuf_buf(ln), pos)); | |
diff --git a/ren.c b/ren.c | |
t@@ -11,7 +11,7 @@ int *ren_position(char *s) | |
int i, n; | |
char **chrs = uc_chop(s, &n); | |
int *off, *pos; | |
- int diff = 0; | |
+ int cpos = 0; | |
pos = malloc((n + 1) * sizeof(pos[0])); | |
for (i = 0; i < n; i++) | |
pos[i] = i; | |
t@@ -20,11 +20,10 @@ int *ren_position(char *s) | |
for (i = 0; i < n; i++) | |
off[pos[i]] = i; | |
for (i = 0; i < n; i++) { | |
- pos[off[i]] += diff; | |
- if (*chrs[i] == '\t') | |
- diff += 8 - (pos[off[i]] & 7) - 1; | |
+ pos[off[i]] = cpos; | |
+ cpos += ren_cwid(chrs[off[i]], cpos); | |
} | |
- pos[n] = n + diff; | |
+ pos[n] = cpos; | |
free(chrs); | |
free(off); | |
return pos; | |
t@@ -39,22 +38,6 @@ int ren_wid(char *s) | |
return ret; | |
} | |
-char *ren_translate(char *s) | |
-{ | |
- struct sbuf *sb = sbuf_make(); | |
- char *r = s; | |
- while (*r) { | |
- char *c = uc_shape(s, r); | |
- if (!strcmp(c, "")) | |
- c = "-"; | |
- if (!strcmp(c, "")) | |
- c = "-"; | |
- sbuf_str(sb, c); | |
- r = uc_next(r); | |
- } | |
- return sbuf_done(sb); | |
-} | |
- | |
/* find the next character after visual position p; if cur start from p itself… | |
static int pos_next(int *pos, int n, int p, int cur) | |
{ | |
t@@ -175,3 +158,42 @@ int ren_region(char *s, int c1, int c2, int *l1, int *l2,… | |
free(ord); | |
return 0; | |
} | |
+ | |
+static struct placeholder { | |
+ char *s; /* the source character */ | |
+ char *d; /* the placeholder */ | |
+} placeholders[] = { | |
+ {"", "-"}, | |
+ {"", "-"}, | |
+ {"ْ", "ـْ"}, | |
+ {"ٌ", "ـٌ"}, | |
+ {"ٍ", "ـٍ"}, | |
+ {"ً", "ـً"}, | |
+ {"ُ", "ـُ"}, | |
+ {"ِ", "ـِ"}, | |
+ {"َ", "ـَ"}, | |
+ {"ّ", "ـّ"}, | |
+}; | |
+ | |
+static char *ren_placeholder(char *s) | |
+{ | |
+ int i = 0; | |
+ int c = uc_code(s); | |
+ for (i = 0; i < LEN(placeholders); i++) | |
+ if (uc_code(placeholders[i].s) == c) | |
+ return placeholders[i].d; | |
+ return NULL; | |
+} | |
+ | |
+int ren_cwid(char *s, int pos) | |
+{ | |
+ if (s[0] == '\t') | |
+ return 8 - (pos & 7); | |
+ return 1; | |
+} | |
+ | |
+char *ren_translate(char *s, char *ln) | |
+{ | |
+ char *p = ren_placeholder(s); | |
+ return p ? p : uc_shape(ln, s); | |
+} | |
diff --git a/uc.c b/uc.c | |
t@@ -323,10 +323,8 @@ char *uc_shape(char *beg, char *s) | |
int prev = 0; | |
int next = 0; | |
int curr = uc_code(s); | |
- if (!curr || !UC_R2L(curr)) { | |
- uc_cput(out, curr); | |
- return out; | |
- } | |
+ if (!curr || !UC_R2L(curr)) | |
+ return NULL; | |
r = s; | |
while (r > beg) { | |
r = uc_beg(beg, r - 1); | |
diff --git a/vi.h b/vi.h | |
t@@ -45,7 +45,6 @@ void rset_free(struct rset *re); | |
/* rendering lines */ | |
int *ren_position(char *s); | |
-char *ren_translate(char *s); | |
int ren_cursor(char *s, int pos); | |
int ren_next(char *s, int p, int dir); | |
int ren_eol(char *s, int dir); | |
t@@ -53,6 +52,8 @@ int ren_pos(char *s, int off); | |
int ren_off(char *s, int pos); | |
int ren_wid(char *s); | |
int ren_region(char *s, int c1, int c2, int *l1, int *l2, int closed); | |
+char *ren_translate(char *s, char *ln); | |
+int ren_cwid(char *s, int pos); | |
/* text direction */ | |
int dir_context(char *s); |