8 static char *kmap_map(char *kmap
, int c
)
11 char **keymap
= conf_kmap(kmap
);
13 return keymap
[c
] ? keymap
[c
] : cs
;
16 static int led_posctx(int dir
, int pos
, int beg
, int end
)
18 return dir
>= 0 ? pos
- beg
: end
- pos
- 1;
21 /* map cursor horizontal position to terminal column number */
22 int led_pos(char *s
, int pos
)
24 return led_posctx(dir_context(s
), pos
, xleft
, xleft
+ xcols
);
27 static int led_offdir(char **chrs
, int *pos
, int i
)
29 if (pos
[i
] + ren_cwid(chrs
[i
], pos
[i
]) == pos
[i
+ 1])
31 if (pos
[i
+ 1] + ren_cwid(chrs
[i
+ 1], pos
[i
+ 1]) == pos
[i
])
36 static void led_markrev(int n
, char **chrs
, int *pos
, int *att
)
40 conf_highlight_revdir(&hl
);
42 int dir
= led_offdir(chrs
, pos
, i
);
44 while (i
+ 1 < n
&& led_offdir(chrs
, pos
, i
) == dir
)
47 for (j
= beg
; j
<= i
; j
++)
48 att
[j
] = syn_merge(hl
, att
[j
]);
54 static char *led_render(char *s0
, int cbeg
, int cend
)
57 int *pos
; /* pos[i]: the screen position of the i-th character */
58 int *off
; /* off[i]: the character at screen position i */
59 int *att
; /* att[i]: the attributes of i-th character */
60 char **chrs
; /* chrs[i]: the i-th character in s1 */
64 int ctx
= dir_context(s0
);
65 chrs
= uc_chop(s0
, &n
);
66 pos
= ren_position(s0
);
67 off
= malloc((cend
- cbeg
) * sizeof(off
[0]));
68 memset(off
, 0xff, (cend
- cbeg
) * sizeof(off
[0]));
69 for (i
= 0; i
< n
; i
++) {
70 int curwid
= ren_cwid(chrs
[i
], pos
[i
]);
71 int curbeg
= led_posctx(ctx
, pos
[i
], cbeg
, cend
);
72 int curend
= led_posctx(ctx
, pos
[i
] + curwid
- 1, cbeg
, cend
);
73 if (curbeg
>= 0 && curbeg
< (cend
- cbeg
) &&
74 curend
>= 0 && curend
< (cend
- cbeg
))
75 for (j
= 0; j
< curwid
; j
++)
76 off
[led_posctx(ctx
, pos
[i
] + j
, cbeg
, cend
)] = i
;
78 att
= syn_highlight(ex_filetype(), s0
);
79 led_markrev(n
, chrs
, pos
, att
);
83 int o
= off
[i
- cbeg
];
84 int att_new
= o
>= 0 ? att
[o
] : 0;
85 sbuf_str(out
, term_att(att_new
, att_old
));
88 if (ren_translate(chrs
[o
], s0
))
89 sbuf_str(out
, ren_translate(chrs
[o
], s0
));
90 else if (uc_isprint(chrs
[o
]))
91 sbuf_mem(out
, chrs
[o
], uc_len(chrs
[o
]));
93 for (j
= i
; j
< cend
&& off
[j
- cbeg
] == o
; j
++)
95 while (i
< cend
&& off
[i
- cbeg
] == o
)
102 sbuf_str(out
, term_att(0, att_old
));
107 return sbuf_done(out
);
110 void led_print(char *s
, int row
)
112 char *r
= led_render(s
, xleft
, xleft
+ xcols
);
119 static int led_lastchar(char *s
)
121 char *r
= *s
? strchr(s
, '\0') : s
;
123 r
= uc_beg(s
, r
- 1);
127 static int led_lastword(char *s
)
129 char *r
= *s
? uc_beg(s
, strchr(s
, '\0') - 1) : s
;
131 while (r
> s
&& uc_isspace(r
))
132 r
= uc_beg(s
, r
- 1);
133 kind
= r
> s
? uc_kind(r
) : 0;
134 while (r
> s
&& uc_kind(uc_beg(s
, r
- 1)) == kind
)
135 r
= uc_beg(s
, r
- 1);
139 static void led_printparts(char *ai
, char *pref
, char *main
, char *post
, char *kmap
)
148 off
= uc_slen(sbuf_buf(ln
));
149 /* cursor position for inserting the next character */
150 if (*pref
|| *main
|| *ai
) {
151 int len
= sbuf_len(ln
);
152 sbuf_str(ln
, kmap_map(kmap
, 'a'));
154 idir
= ren_pos(sbuf_buf(ln
), off
) -
155 ren_pos(sbuf_buf(ln
), off
- 1) < 0 ? -1 : +1;
160 pos
= ren_cursor(sbuf_buf(ln
), ren_pos(sbuf_buf(ln
), MAX(0, off
- 1)));
161 if (pos
>= xleft
+ xcols
)
162 xleft
= pos
- xcols
/ 2;
164 xleft
= pos
< xcols
? 0 : pos
- xcols
/ 2;
165 led_print(sbuf_buf(ln
), -1);
166 term_pos(-1, led_pos(sbuf_buf(ln
), pos
+ idir
));
171 /* continue reading the character starting with c */
172 static char *led_readchar(int c
, char *kmap
)
177 if (c
== TK_CTL('v')) { /* literal character */
178 buf
[0] = term_read();
182 if (c
== TK_CTL('k')) { /* digraph */
189 return conf_digraph(c1
, c2
);
191 if ((c
& 0xc0) == 0xc0) { /* utf-8 character */
194 for (i
= 1; i
< n
; i
++)
195 buf
[i
] = term_read();
199 return kmap_map(kmap
, c
);
202 char *led_read(char **kmap
)
208 *kmap
= ex_kmapalt();
214 return led_readchar(c
, *kmap
);
221 static char *led_line(char *pref
, char *post
, char *ai
, int ai_max
, int *key
, char **kmap
)
224 int ai_len
= strlen(ai
);
233 led_printparts(ai
, pref
, sbuf_buf(sb
), post
, *kmap
);
237 *kmap
= ex_kmapalt();
245 sbuf_cut(sb
, led_lastchar(sbuf_buf(sb
)));
252 sbuf_cut(sb
, led_lastword(sbuf_buf(sb
)));
264 if (reg_get(0, &lnmode
))
265 sbuf_str(sb
, reg_get(0, &lnmode
));
268 if (c
== '\n' || TK_INT(c
))
270 if ((cs
= led_readchar(c
, *kmap
)))
273 if (c
== '\n' || TK_INT(c
))
277 return sbuf_done(sb
);
280 /* read an ex command */
281 char *led_prompt(char *pref
, char *post
, char **kmap
)
284 char *s
= led_line(pref
, post
, "", 0, &key
, kmap
);
286 struct sbuf
*sb
= sbuf_make();
293 return sbuf_done(sb
);
299 /* read visual command input */
300 char *led_input(char *pref
, char *post
, char **kmap
)
302 struct sbuf
*sb
= sbuf_make();
304 int ai_max
= xai
? sizeof(ai
) - 1 : 0;
307 while (n
< ai_max
&& (*pref
== ' ' || *pref
== '\t'))
311 char *ln
= led_line(pref
, post
, ai
, ai_max
, &key
, kmap
);
312 int ln_sp
= 0; /* number of initial spaces in ln */
313 while (ln
[ln_sp
] && (ln
[ln_sp
] == ' ' || ln
[ln_sp
] == '\t'))
315 if (ln
[ln_sp
] || (pref
&& pref
[0]) ||
316 (key
!= '\n' && post
[0] && post
[0] != '\n'))
323 led_printparts(ai
, pref
? pref
: "", uc_lastline(ln
),
324 key
== '\n' ? "" : post
, *kmap
);
327 if (!pref
|| !pref
[0]) { /* updating autoindent */
328 int ai_len
= ai_max
? strlen(ai
) : 0;
330 if (ai_len
+ ai_new
> ai_max
)
331 ai_new
= ai_max
- ai_len
;
332 memcpy(ai
+ ai_len
, ln
, ai_new
);
333 ai
[ai_len
+ ai_new
] = '\0';
341 while (xai
&& (post
[n
] == ' ' || post
[n
] == '\t'))
343 memmove(post
, post
+ n
, strlen(post
) - n
+ 1);
347 return sbuf_done(sb
);