8 static char **kmaps
[] = {kmap_en
, kmap_fa
};
10 static char **kmap_find(char *name
)
13 for (i
= 0; i
< LEN(kmaps
); i
++)
14 if (name
&& kmaps
[i
][0] && !strcmp(name
, kmaps
[i
][0]))
19 static char *kmap_map(char *kmap
, int c
)
22 char **keymap
= kmap_find(kmap
);
24 return keymap
[c
] ? keymap
[c
] : cs
;
27 /* map cursor horizontal position to terminal column number */
28 int led_pos(char *s
, int pos
)
30 return dir_context(s
) >= 0 ? pos
: xcols
- pos
- 1;
33 char *led_keymap(char *kmap
, int c
)
35 return c
>= 0 ? kmap_map(kmap
, c
) : NULL
;
38 static char *led_render(char *s0
)
41 int *pos
; /* pos[i]: the screen position of the i-th character */
42 int *off
; /* off[i]: the character at screen position i */
43 char **chrs
; /* chrs[i]: the i-th character in s1 */
46 chrs
= uc_chop(s0
, &n
);
47 pos
= ren_position(s0
);
48 off
= malloc(xcols
* sizeof(off
[0]));
49 memset(off
, 0xff, xcols
* sizeof(off
[0]));
50 for (i
= 0; i
< n
; i
++) {
52 int curwid
= ren_cwid(chrs
[i
], curpos
);
53 if (curpos
>= 0 && curpos
+ curwid
< xcols
) {
54 for (j
= 0; j
< curwid
; j
++) {
55 off
[led_pos(s0
, curpos
+ j
)] = i
;
56 if (led_pos(s0
, curpos
+ j
) > maxcol
)
57 maxcol
= led_pos(s0
, curpos
+ j
);
66 if (ren_translate(chrs
[o
], s0
))
67 sbuf_str(out
, ren_translate(chrs
[o
], s0
));
68 else if (uc_isprint(chrs
[o
]))
69 sbuf_mem(out
, chrs
[o
], uc_len(chrs
[o
]));
71 for (j
= i
; j
<= maxcol
&& off
[j
] == o
; j
++)
73 while (i
<= maxcol
&& off
[i
] == o
)
83 return sbuf_done(out
);
86 void led_print(char *s
, int row
)
88 char *r
= led_render(s
);
95 static int led_lastchar(char *s
)
97 char *r
= *s
? strchr(s
, '\0') : s
;
103 static int led_lastword(char *s
)
105 char *r
= *s
? uc_beg(s
, strchr(s
, '\0') - 1) : s
;
107 while (r
> s
&& uc_isspace(r
))
108 r
= uc_beg(s
, r
- 1);
109 kind
= r
> s
? uc_kind(r
) : 0;
110 while (r
> s
&& uc_kind(uc_beg(s
, r
- 1)) == kind
)
111 r
= uc_beg(s
, r
- 1);
115 static void led_printparts(char *ai
, char *pref
, char *main
, char *post
, char *kmap
)
124 off
= uc_slen(sbuf_buf(ln
));
125 /* cursor position for inserting the next character */
126 if (*pref
|| *main
|| *ai
) {
127 int len
= sbuf_len(ln
);
128 sbuf_str(ln
, kmap_map(kmap
, 'a'));
130 idir
= ren_pos(sbuf_buf(ln
), off
) -
131 ren_pos(sbuf_buf(ln
), off
- 1) < 0 ? -1 : +1;
135 led_print(sbuf_buf(ln
), -1);
136 pos
= ren_cursor(sbuf_buf(ln
), ren_pos(sbuf_buf(ln
), off
- 1));
137 term_pos(-1, led_pos(sbuf_buf(ln
), pos
+ idir
));
141 static char *led_line(char *pref
, char *post
, char *ai
, int ai_max
, int *key
, char **kmap
)
144 int ai_len
= strlen(ai
);
152 led_printparts(ai
, pref
, sbuf_buf(sb
), post
, *kmap
);
156 *kmap
= conf_kmapalt();
164 sbuf_cut(sb
, led_lastchar(sbuf_buf(sb
)));
170 sbuf_chr(sb
, term_read(-1));
174 sbuf_cut(sb
, led_lastword(sbuf_buf(sb
)));
185 if (c
== '\n' || TK_INT(c
))
187 sbuf_str(sb
, kmap_map(*kmap
, c
));
189 if (c
== '\n' || TK_INT(c
))
193 return sbuf_done(sb
);
196 /* read an ex command */
197 char *led_prompt(char *pref
, char *post
, char **kmap
)
201 s
= led_line(pref
, post
, "", 0, &key
, kmap
);
208 /* read visual command input */
209 char *led_input(char *pref
, char *post
, char *ai
, int ai_max
, char **kmap
)
211 struct sbuf
*sb
= sbuf_make();
212 char *first_ai
= NULL
;
215 char *ln
= led_line(pref
, post
, ai
, ai_max
, &key
, kmap
);
217 first_ai
= uc_dup(ai
);
223 led_printparts(ai
, pref
? pref
: "", ln
, key
== '\n' ? "" : post
, *kmap
);
231 while (ai_max
&& post
[0] && (post
[0] == ' ' || post
[0] == '\t'))
234 strcpy(ai
, first_ai
);
237 return sbuf_done(sb
);