tren: insertion offset for bidirectional text - 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 587184fefe29e50689e767573d9af112e2824ddd
(DIR) parent 1ed75144175e7ea9b167a76c9b096b4c144ddfad
(HTM) Author: Ali Gholami Rudi <ali@rudi.ir>
Date: Tue, 5 May 2015 22:39:51 +0430
ren: insertion offset for bidirectional text
See the comments of ren_insertionoffset().
Diffstat:
M ren.c | 40 +++++++++++++++++++++++++++----
M vi.c | 23 +++--------------------
2 files changed, 38 insertions(+), 25 deletions(-)
---
(DIR) diff --git a/ren.c b/ren.c
t@@ -262,9 +262,39 @@ int ren_cmp(char *s, int pos1, int pos2)
*/
int ren_insertionoffset(char *s, int pos, int pre)
{
- int l1;
- if (!s)
- return 0;
- l1 = ren_off(s, pos);
- return pre ? l1 : l1 + 1;
+ int *ord; /* ord[i]: the order of the i-th char on the screen */
+ int *map; /* map[i]: the char appearing i-th on the screen */
+ int n = uc_slen(s);
+ int oprev, o, onext; /* the offset the of previous, current, and next positions */
+ int cord; /* the order of the current position on the screen */
+ int i;
+ ord = malloc(n * sizeof(ord[0]));
+ for (i = 0; i < n; i++)
+ ord[i] = i;
+ ren_reorder(s, ord);
+ map = malloc(n * sizeof(map[0]));
+ for (i = 0; i < n; i++)
+ map[ord[i]] = i;
+ if (uc_chr(s, n - 1)[0] == '\n')
+ n--;
+ o = ren_off(s, pos);
+ cord = ord[o];
+ oprev = cord > 0 ? map[cord - 1] : -1;
+ onext = cord < n - 1 ? map[cord + 1] : -1;
+ free(map);
+ free(ord);
+ if (oprev < 0 && onext < 0)
+ return pre ? o : o + 1;
+ if (pre) {
+ if (oprev >= 0)
+ return oprev < o ? o : o + 1;
+ else
+ return onext > o ? o : o + 1;
+ } else {
+ if (onext >= 0)
+ return onext > o ? o + 1 : o;
+ else
+ return oprev < o ? o + 1 : o;
+ }
+ return 0;
}
(DIR) diff --git a/vi.c b/vi.c
t@@ -110,28 +110,11 @@ static char *lbuf_chr(struct lbuf *lb, int r, int c)
return "";
}
-static int lbuf_indents(struct lbuf *lb, int r)
-{
- char *ln = lbuf_get(lb, r);
- int n;
- char **chrs;
- int i = 0;
- if (!ln)
- return 0;
- chrs = uc_chop(ln ? ln : "", &n);
- while (i < n && chrs[i][0] != '\n' && uc_isspace(chrs[i]))
- i++;
- free(chrs);
- return i;
-}
-
static void lbuf_postindents(struct lbuf *lb, int *r, int *c)
{
- char *ln = lbuf_get(lb, *r);
- if (ln)
- *c = ren_pos(ln, lbuf_indents(lb, *r));
- else
- lbuf_eol(lb, r, c, -1);
+ lbuf_eol(lb, r, c, -1);
+ while (uc_isspace(lbuf_chr(lb, *r, *c)))
+ lbuf_lnnext(lb, r, c, +1);
}
static void lbuf_findchar(struct lbuf *lb, int *row, int *col, char *cs, int dir, int n)