mirror of
https://github.com/urbit/shrub.git
synced 2024-12-20 01:01:37 +03:00
term: batch simple input events into a single %txt
By accumulating %txt events until we reach a more complex event or reach the end of the input buffer, we can significantly reduce the "overhead" of pasting text into the terminal. Instead of an event for each character, we now inject up to a buffer's worth of characters (currently, 123 bytes) at a time. This makes pasting process much faster. Incidentally, the behavior for pasting text with syntax errors into the dojo may be a little bit surprising: after every buffer boundary, the dojo will complain about the syntax error, moving the cursor to its location, and causing the remainder of the text to be inserted in that position. This may result in garbled-looking input in some cases. This ux problem should be resolved on dojo's end, perhaps by highlighting syntax errors with color, instead of the cursor. Alleviates most of the need for #5687.
This commit is contained in:
parent
531fd61ace
commit
c5b07f5203
@ -158,10 +158,11 @@
|
||||
c3_y col_y; // column coordinate
|
||||
} esc;
|
||||
|
||||
struct {
|
||||
c3_y syb_y[5]; // utf8 code buffer
|
||||
c3_w len_w; // present length
|
||||
c3_w wid_w; // total width
|
||||
struct { // input buffering
|
||||
c3_y syb_y[5]; // utf8 code buffer
|
||||
c3_w len_w; // present length
|
||||
c3_w wid_w; // total width
|
||||
u3_noun imp; // %txt input buffer
|
||||
} fut;
|
||||
|
||||
struct {
|
||||
|
@ -147,6 +147,7 @@ u3_term_log_init(void)
|
||||
|
||||
uty_u->tat_u.fut.len_w = 0;
|
||||
uty_u->tat_u.fut.wid_w = 0;
|
||||
uty_u->tat_u.fut.imp = u3_nul;
|
||||
}
|
||||
|
||||
// default size
|
||||
@ -636,9 +637,28 @@ _term_io_belt(u3_utty* uty_u, u3_noun blb)
|
||||
}
|
||||
}
|
||||
|
||||
/* _term_io_suck_char(): process a single character.
|
||||
/* _term_io_spit(): input the buffer (if any), then input the belt (if any)
|
||||
*/
|
||||
static void
|
||||
_term_io_spit(u3_utty* uty_u, u3_noun bet) {
|
||||
u3_utat* tat_u = &uty_u->tat_u;
|
||||
if (u3_nul != tat_u->fut.imp) {
|
||||
_term_io_belt(uty_u, u3nc(c3__txt, u3kb_flop(tat_u->fut.imp)));
|
||||
tat_u->fut.imp = u3_nul;
|
||||
}
|
||||
if (u3_none != bet) {
|
||||
_term_io_belt(uty_u, bet);
|
||||
}
|
||||
}
|
||||
|
||||
/* _term_io_suck_char(): process a single character.
|
||||
*
|
||||
* Note that this accumulates simple inputs in a buffer, and is not
|
||||
* guaranteed to flush it fully. After a call (or sequence of calls)
|
||||
* to this function, please call _term_io_spit(uty_u, u3_none) to
|
||||
* flush any remainder.
|
||||
*/
|
||||
static void
|
||||
_term_io_suck_char(u3_utty* uty_u, c3_y cay_y)
|
||||
{
|
||||
u3_utat* tat_u = &uty_u->tat_u;
|
||||
@ -652,10 +672,10 @@ _term_io_suck_char(u3_utty* uty_u, c3_y cay_y)
|
||||
_term_it_dump_buf(uty_u, &uty_u->ufo_u.bel_u);
|
||||
break;
|
||||
}
|
||||
case 'A': _term_io_belt(uty_u, u3nc(c3__aro, 'u')); break;
|
||||
case 'B': _term_io_belt(uty_u, u3nc(c3__aro, 'd')); break;
|
||||
case 'C': _term_io_belt(uty_u, u3nc(c3__aro, 'r')); break;
|
||||
case 'D': _term_io_belt(uty_u, u3nc(c3__aro, 'l')); break;
|
||||
case 'A': _term_io_spit(uty_u, u3nc(c3__aro, 'u')); break;
|
||||
case 'B': _term_io_spit(uty_u, u3nc(c3__aro, 'd')); break;
|
||||
case 'C': _term_io_spit(uty_u, u3nc(c3__aro, 'r')); break;
|
||||
case 'D': _term_io_spit(uty_u, u3nc(c3__aro, 'l')); break;
|
||||
//
|
||||
case 'M': tat_u->esc.mou = c3y; break;
|
||||
}
|
||||
@ -667,13 +687,13 @@ _term_io_suck_char(u3_utty* uty_u, c3_y cay_y)
|
||||
// XX for backwards compatibility, check kelvin version
|
||||
// and fallback to [%met @c]
|
||||
//
|
||||
_term_io_belt(uty_u, u3nt(c3__mod, c3__met, cay_y));
|
||||
_term_io_spit(uty_u, u3nt(c3__mod, c3__met, cay_y));
|
||||
}
|
||||
else if ( 8 == cay_y || 127 == cay_y ) {
|
||||
tat_u->esc.ape = c3n;
|
||||
// XX backwards compatibility [%met @c]
|
||||
//
|
||||
_term_io_belt(uty_u, u3nq(c3__mod, c3__met, c3__bac, u3_nul));
|
||||
_term_io_spit(uty_u, u3nq(c3__mod, c3__met, c3__bac, u3_nul));
|
||||
}
|
||||
else if ( ('[' == cay_y) || ('O' == cay_y) ) {
|
||||
tat_u->esc.bra = c3y;
|
||||
@ -698,7 +718,7 @@ _term_io_suck_char(u3_utty* uty_u, c3_y cay_y)
|
||||
c3_y row_y = cay_y - 32;
|
||||
// only acknowledge button 1 presses within our window
|
||||
if ( 1 != tat_u->esc.ton_y && row_y <= tat_u->siz.row_l ) {
|
||||
_term_io_belt(uty_u, u3nt(c3__hit,
|
||||
_term_io_spit(uty_u, u3nt(c3__hit,
|
||||
tat_u->esc.col_y - 1,
|
||||
tat_u->siz.row_l - row_y));
|
||||
}
|
||||
@ -720,28 +740,28 @@ _term_io_suck_char(u3_utty* uty_u, c3_y cay_y)
|
||||
wug = u3do("taft", huv);
|
||||
|
||||
tat_u->fut.len_w = tat_u->fut.wid_w = 0;
|
||||
_term_io_belt(uty_u, u3nt(c3__txt, wug, u3_nul));
|
||||
tat_u->fut.imp = u3nc(wug, tat_u->fut.imp);
|
||||
}
|
||||
}
|
||||
// individual characters
|
||||
//
|
||||
else {
|
||||
if ( (cay_y >= 32) && (cay_y < 127) ) { // visual ascii
|
||||
_term_io_belt(uty_u, u3nt(c3__txt, cay_y, u3_nul));
|
||||
tat_u->fut.imp = u3nc(cay_y, tat_u->fut.imp);
|
||||
}
|
||||
else if ( 0 == cay_y ) { // null
|
||||
_term_it_dump_buf(uty_u, &uty_u->ufo_u.bel_u);
|
||||
}
|
||||
else if ( 8 == cay_y || 127 == cay_y ) { // backspace & delete
|
||||
_term_io_belt(uty_u, u3nc(c3__bac, u3_nul));
|
||||
_term_io_spit(uty_u, u3nc(c3__bac, u3_nul));
|
||||
}
|
||||
else if ( 10 == cay_y || 13 == cay_y ) { // newline & carriage return
|
||||
_term_io_belt(uty_u, u3nc(c3__ret, u3_nul));
|
||||
_term_io_spit(uty_u, u3nc(c3__ret, u3_nul));
|
||||
}
|
||||
else if ( cay_y <= 26 ) {
|
||||
// XX backwards compatibility [%ctl @c]
|
||||
//
|
||||
_term_io_belt(uty_u, u3nt(c3__mod, c3__ctl, ('a' + (cay_y - 1))));
|
||||
_term_io_spit(uty_u, u3nt(c3__mod, c3__ctl, ('a' + (cay_y - 1))));
|
||||
}
|
||||
else if ( 27 == cay_y ) {
|
||||
tat_u->esc.ape = c3y;
|
||||
@ -799,6 +819,7 @@ _term_suck(u3_utty* uty_u, const c3_y* buf, ssize_t siz_i)
|
||||
for ( i=0; i < siz_i; i++ ) {
|
||||
_term_io_suck_char(uty_u, buf[i]);
|
||||
}
|
||||
_term_io_spit(uty_u, u3_none);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user