9 static char **kmaps
[] = {kmap_en
, kmap_fa
};
11 static char **kmap_find(char *name
)
14 for (i
= 0; i
< LEN(kmaps
); i
++)
15 if (name
&& kmaps
[i
][0] && !strcmp(name
, kmaps
[i
][0]))
20 static char *kmap_map(char *kmap
, int c
)
23 char **keymap
= kmap_find(kmap
);
25 return keymap
[c
] ? keymap
[c
] : cs
;
28 /* map cursor horizontal position to terminal column number */
29 int led_pos(char *s
, int pos
)
31 return dir_context(s
) >= 0 ? pos
: xcols
- pos
- 1;
34 static int led_posctx(int dir
, int pos
)
36 return dir
>= 0 ? pos
: xcols
- pos
- 1;
39 static int led_offdir(char **chrs
, int *pos
, int i
)
41 if (pos
[i
] + ren_cwid(chrs
[i
], pos
[i
]) == pos
[i
+ 1])
43 if (pos
[i
+ 1] + ren_cwid(chrs
[i
+ 1], pos
[i
+ 1]) == pos
[i
])
48 static void led_markrev(int n
, char **chrs
, int *pos
, int *att
)
52 conf_highlight_revdir(&hl
);
54 int dir
= led_offdir(chrs
, pos
, i
);
56 while (i
+ 1 < n
&& led_offdir(chrs
, pos
, i
) == dir
)
59 for (j
= beg
; j
<= i
; j
++)
60 att
[j
] = syn_merge(att
[j
], hl
);
66 static char *led_render(char *s0
)
69 int *pos
; /* pos[i]: the screen position of the i-th character */
70 int *off
; /* off[i]: the character at screen position i */
71 int *att
; /* att[i]: the attributes of i-th character */
72 char **chrs
; /* chrs[i]: the i-th character in s1 */
76 int ctx
= dir_context(s0
);
77 chrs
= uc_chop(s0
, &n
);
78 pos
= ren_position(s0
);
79 off
= malloc(xcols
* sizeof(off
[0]));
80 memset(off
, 0xff, xcols
* sizeof(off
[0]));
81 for (i
= 0; i
< n
; i
++) {
83 int curwid
= ren_cwid(chrs
[i
], curpos
);
84 if (curpos
>= 0 && curpos
+ curwid
< xcols
) {
85 for (j
= 0; j
< curwid
; j
++) {
86 off
[led_posctx(ctx
, curpos
+ j
)] = i
;
87 if (led_posctx(ctx
, curpos
+ j
) > maxcol
)
88 maxcol
= led_posctx(ctx
, curpos
+ j
);
92 att
= syn_highlight(ex_filetype(), s0
);
93 led_markrev(n
, chrs
, pos
, att
);
98 int att_new
= o
>= 0 ? att
[o
] : 0;
99 sbuf_str(out
, term_att(att_new
, att_old
));
102 if (ren_translate(chrs
[o
], s0
))
103 sbuf_str(out
, ren_translate(chrs
[o
], s0
));
104 else if (uc_isprint(chrs
[o
]))
105 sbuf_mem(out
, chrs
[o
], uc_len(chrs
[o
]));
107 for (j
= i
; j
<= maxcol
&& off
[j
] == o
; j
++)
109 while (i
<= maxcol
&& off
[i
] == o
)
116 sbuf_str(out
, term_att(0, att_old
));
121 return sbuf_done(out
);
124 void led_print(char *s
, int row
)
126 char *r
= led_render(s
);
133 static int led_lastchar(char *s
)
135 char *r
= *s
? strchr(s
, '\0') : s
;
137 r
= uc_beg(s
, r
- 1);
141 static int led_lastword(char *s
)
143 char *r
= *s
? uc_beg(s
, strchr(s
, '\0') - 1) : s
;
145 while (r
> s
&& uc_isspace(r
))
146 r
= uc_beg(s
, r
- 1);
147 kind
= r
> s
? uc_kind(r
) : 0;
148 while (r
> s
&& uc_kind(uc_beg(s
, r
- 1)) == kind
)
149 r
= uc_beg(s
, r
- 1);
153 static void led_printparts(char *ai
, char *pref
, char *main
, char *post
, char *kmap
)
162 off
= uc_slen(sbuf_buf(ln
));
163 /* cursor position for inserting the next character */
164 if (*pref
|| *main
|| *ai
) {
165 int len
= sbuf_len(ln
);
166 sbuf_str(ln
, kmap_map(kmap
, 'a'));
168 idir
= ren_pos(sbuf_buf(ln
), off
) -
169 ren_pos(sbuf_buf(ln
), off
- 1) < 0 ? -1 : +1;
174 led_print(sbuf_buf(ln
), -1);
175 pos
= ren_cursor(sbuf_buf(ln
), ren_pos(sbuf_buf(ln
), MAX(0, off
- 1)));
176 term_pos(-1, led_pos(sbuf_buf(ln
), pos
+ idir
));
181 /* continue reading the character starting with c */
182 static char *led_readchar(int c
, char *kmap
)
187 if (c
== TK_CTL('v')) { /* literal character */
188 buf
[0] = term_read();
192 if (c
== TK_CTL('k')) { /* digraph */
199 for (i
= 0; i
< LEN(digraphs
); i
++)
200 if (digraphs
[i
][0][0] == c1
&& digraphs
[i
][0][1] == c2
)
201 return digraphs
[i
][1];
204 if ((c
& 0xc0) == 0xc0) { /* utf-8 character */
207 for (i
= 1; i
< n
; i
++)
208 buf
[i
] = term_read();
212 return kmap_map(kmap
, c
);
215 char *led_read(char **kmap
)
221 *kmap
= conf_kmapalt();
227 return led_readchar(c
, *kmap
);
234 static char *led_line(char *pref
, char *post
, char *ai
, int ai_max
, int *key
, char **kmap
)
237 int ai_len
= strlen(ai
);
246 led_printparts(ai
, pref
, uc_lastline(sbuf_buf(sb
)), post
, *kmap
);
250 *kmap
= conf_kmapalt();
258 sbuf_cut(sb
, led_lastchar(sbuf_buf(sb
)));
265 sbuf_cut(sb
, led_lastword(sbuf_buf(sb
)));
277 if (reg_get(0, &lnmode
))
278 sbuf_str(sb
, reg_get(0, &lnmode
));
281 if (c
== '\n' || TK_INT(c
))
283 if ((cs
= led_readchar(c
, *kmap
)))
286 if (c
== '\n' || TK_INT(c
))
290 return sbuf_done(sb
);
293 /* read an ex command */
294 char *led_prompt(char *pref
, char *post
, char **kmap
)
298 s
= led_line(pref
, post
, "", 0, &key
, kmap
);
305 /* read visual command input */
306 char *led_input(char *pref
, char *post
, char *ai
, int ai_max
, char **kmap
)
308 struct sbuf
*sb
= sbuf_make();
309 char *first_ai
= NULL
;
312 char *ln
= led_line(pref
, post
, ai
, ai_max
, &key
, kmap
);
314 first_ai
= uc_dup(ai
);
320 led_printparts(ai
, pref
? pref
: "", uc_lastline(ln
),
321 key
== '\n' ? "" : post
, *kmap
);
324 if (!pref
|| !pref
[0]) { /* updating autoindent */
325 int ai_len
= ai_max
? strlen(ai
) : 0;
326 for (i
= 0; isspace((unsigned char) ln
[i
]); i
++)
328 ai
[ai_len
++] = ln
[i
];
336 while (ai_max
&& post
[0] && (post
[0] == ' ' || post
[0] == '\t'))
339 strcpy(ai
, first_ai
);
342 return sbuf_done(sb
);