From 776de8b3d962a8884795870bdbe2b4d65d606f37 Mon Sep 17 00:00:00 2001 From: fang Date: Sun, 20 Dec 2020 13:40:29 +0100 Subject: [PATCH 001/104] lull: make dill-blit explicit superset of blit Likewise for belt. This necessitates renaming the %mor blit for newlines to %nel, making this require a new runtime version. That's fine, more breaking changes are to follow. --- pkg/arvo/lib/hood/drum.hoon | 10 +++------ pkg/arvo/mar/blit.hoon | 2 +- pkg/arvo/sys/lull.hoon | 26 ++++++---------------- pkg/arvo/sys/vane/dill.hoon | 4 ++-- pkg/interface/src/views/apps/term/store.js | 2 +- pkg/urbit/include/c/motes.h | 1 + pkg/urbit/vere/io/term.c | 2 +- 7 files changed, 16 insertions(+), 31 deletions(-) diff --git a/pkg/arvo/lib/hood/drum.hoon b/pkg/arvo/lib/hood/drum.hoon index e3c33eda90..801b8559d6 100644 --- a/pkg/arvo/lib/hood/drum.hoon +++ b/pkg/arvo/lib/hood/drum.hoon @@ -725,7 +725,7 @@ (ta-hom %del (dec pos.inp)) :: ++ ta-ctl :: hear control - |= key=@ud + |= key=@c ^+ +> =. ris ?.(?=(?(%g %r) key) ~ ris) ?+ key ta-bel @@ -790,11 +790,10 @@ ++ ta-fec :: apply effect |= fec=sole-effect ^+ +> - ?- fec + ?+ fec +>(..ta (se-blit fec)) [%bel *] ta-bel [%blk *] +> [%bye *] +>(..ta (se-klin gyl)) - [%clr *] +>(..ta (se-blit fec)) [%det *] (ta-got +.fec) [%err *] (ta-err p.fec) [%klr *] +>(..ta (se-blit %klr (make:klr p.fec))) @@ -805,10 +804,7 @@ [%pro *] (ta-pro +.fec) [%tab *] +>(..ta (se-tab p.fec)) [%tan *] +>(..ta (se-dump p.fec)) - [%sag *] +>(..ta (se-blit fec)) - [%sav *] +>(..ta (se-blit fec)) [%txt *] +>(..ta (se-text p.fec)) - [%url *] +>(..ta (se-blit fec)) == :: ++ ta-dog :: change cursor @@ -878,7 +874,7 @@ == :: ++ ta-met :: meta key - |= key=@ud + |= key=@c ^+ +> =. ris ~ ?+ key ta-bel diff --git a/pkg/arvo/mar/blit.hoon b/pkg/arvo/mar/blit.hoon index 4c23c5705e..b50c0fa7d7 100644 --- a/pkg/arvo/mar/blit.hoon +++ b/pkg/arvo/mar/blit.hoon @@ -22,7 +22,7 @@ %clr b+& %hop (numb p.blit) %lin a+(turn p.blit |=(c=@c s+(tuft c))) - %mor b+& + %nel b+& %url s+p.blit :: %sag diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index 92f45dfa2a..76af8fd43b 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -1045,7 +1045,7 @@ :::: :: (1d2) :: +$ blew [p=@ud q=@ud] :: columns rows - +$ belt :: old belt + +$ belt :: outside belt $% [%aro p=?(%d %l %r %u)] :: arrow key [%bac ~] :: true backspace [%ctl p=@c] :: control-key @@ -1054,43 +1054,31 @@ [%ret ~] :: return [%txt p=(list @c)] :: utf32 text == :: - +$ blit :: old blit + +$ blit :: outside blit $% [%bel ~] :: make a noise [%clr ~] :: clear the screen [%hop p=@ud] :: set cursor position [%klr p=stub] :: set styled line [%lin p=(list @c)] :: set current line - [%mor ~] :: newline + [%nel ~] :: newline [%sag p=path q=*] :: save to jamfile [%sav p=path q=@] :: save to file [%url p=@t] :: activate url == :: - +$ dill-belt :: new belt - $% [%aro p=?(%d %l %r %u)] :: arrow key - [%bac ~] :: true backspace + +$ dill-belt :: inside belt + $% belt :: outside belt [%cru p=@tas q=(list tank)] :: echo error - [%ctl p=@] :: control-key - [%del ~] :: true delete [%hey ~] :: refresh - [%met p=@] :: meta-key - [%ret ~] :: return [%rez p=@ud q=@ud] :: resize, cols, rows - [%txt p=(list @c)] :: utf32 text [%yow p=gill:gall] :: connect to app == :: - +$ dill-blit :: new blit - $% [%bel ~] :: make a noise - [%clr ~] :: clear the screen - [%hop p=@ud] :: set cursor position - [%klr p=stub] :: styled text + +$ dill-blit :: inside blit + $% blit :: outside blit [%mor p=(list dill-blit)] :: multiple blits [%pom p=stub] :: styled prompt [%pro p=(list @c)] :: show as cursor+line [%qit ~] :: close console [%out p=(list @c)] :: send output line - [%sag p=path q=*] :: save to jamfile - [%sav p=path q=@] :: save to file - [%url p=@t] :: activate url == :: +$ flog :: sent to %dill $% [%crop p=@ud] :: trim kernel state diff --git a/pkg/arvo/sys/vane/dill.hoon b/pkg/arvo/sys/vane/dill.hoon index 4e08fc0e09..c30d581acf 100644 --- a/pkg/arvo/sys/vane/dill.hoon +++ b/pkg/arvo/sys/vane/dill.hoon @@ -169,14 +169,14 @@ ?: ?=(%out -.bit) %+ done %blit :~ [%lin p.bit] - [%mor ~] + [%nel ~] see [%hop pos] == ?: ?=(%klr -.bit) %+ done %blit :~ [%klr p.bit] - [%mor ~] + [%nel ~] see [%hop pos] == diff --git a/pkg/interface/src/views/apps/term/store.js b/pkg/interface/src/views/apps/term/store.js index ac74cafe2a..795f5bc463 100644 --- a/pkg/interface/src/views/apps/term/store.js +++ b/pkg/interface/src/views/apps/term/store.js @@ -63,7 +63,7 @@ export default class Store { this.state.lines[this.state.lines.length - 1] = blit; this.setState({ lines: this.state.lines }); break; - case 'mor': + case 'nel': this.state.lines.push(''); this.setState({ lines: this.state.lines }); break; diff --git a/pkg/urbit/include/c/motes.h b/pkg/urbit/include/c/motes.h index 240086ec9f..0ff014ec7c 100644 --- a/pkg/urbit/include/c/motes.h +++ b/pkg/urbit/include/c/motes.h @@ -770,6 +770,7 @@ # define c3__ne c3_s2('n','e') # define c3__need c3_s4('n','e','e','d') # define c3__neft c3_s4('n','e','f','t') +# define c3__nel c3_s3('n','e','l') # define c3__nest c3_s4('n','e','s','t') # define c3__netd c3_s4('n','e','t','d') # define c3__new c3_s3('n','e','w') diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index fe58abc32c..45ff0c809b 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -1405,7 +1405,7 @@ _term_ef_blit(u3_utty* uty_u, _term_it_show_tour(uty_u, u3k(u3t(blt))); } break; - case c3__mor: { + case c3__nel: { _term_it_show_more(uty_u); } break; From 48c9f76ba385eab1545744d2e7b91245b7e42c22 Mon Sep 17 00:00:00 2001 From: fang Date: Sun, 20 Dec 2020 20:51:37 +0100 Subject: [PATCH 002/104] term: move cursor to absolute visual position Instead of relative, character-based position. In anticipation of greater degrees of cursor freedom, and so that we don't have to track invisible characters all the time. --- pkg/urbit/include/vere/vere.h | 1 - pkg/urbit/vere/io/term.c | 54 +++++++++-------------------------- 2 files changed, 14 insertions(+), 41 deletions(-) diff --git a/pkg/urbit/include/vere/vere.h b/pkg/urbit/include/vere/vere.h index 657d1860d7..f1646ee1bc 100644 --- a/pkg/urbit/include/vere/vere.h +++ b/pkg/urbit/include/vere/vere.h @@ -148,7 +148,6 @@ c3_y* lin_y; // current line (utf8) c3_w byt_w; // utf8 line-length c3_w wor_w; // utf32 line-length - c3_w sap_w; // escape chars in line c3_w cus_w; // cursor position } mir; diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index 45ff0c809b..c6aba89951 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -220,7 +220,6 @@ u3_term_log_init(void) uty_u->tat_u.mir.lin_y = 0; uty_u->tat_u.mir.byt_w = 0; uty_u->tat_u.mir.wor_w = 0; - uty_u->tat_u.mir.sap_w = 0; uty_u->tat_u.mir.cus_w = 0; uty_u->tat_u.esc.ape = c3n; @@ -463,27 +462,16 @@ _term_it_show_blank(u3_utty* uty_u) static void _term_it_show_cursor(u3_utty* uty_u, c3_w cur_w) { - c3_w cus_w = uty_u->tat_u.mir.cus_w; - c3_w dif_w; + c3_c cur_c[5]; + c3_c len_c = sprintf(cur_c, "%d", cur_w + 1); - //NOTE assumes all styled text precedes the cursor. drum enforces this. - // - cur_w += uty_u->tat_u.mir.sap_w; + uv_buf_t esc_u = TERM_LIT_BUF("\033["); + uv_buf_t pos_u = uv_buf_init(cur_c, len_c); + uv_buf_t cha_u = TERM_LIT_BUF("G"); - if ( cur_w < cus_w ) { - dif_w = cus_w - cur_w; - - while ( dif_w-- ) { - _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.cub1_u); - } - } - else if ( cur_w > cus_w ) { - dif_w = cur_w - cus_w; - - while ( dif_w-- ) { - _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.cuf1_u); - } - } + _term_it_dump_buf(uty_u, &esc_u); + _term_it_dump_buf(uty_u, &pos_u); + _term_it_dump_buf(uty_u, &cha_u); uty_u->tat_u.mir.cus_w = cur_w; } @@ -491,7 +479,7 @@ _term_it_show_cursor(u3_utty* uty_u, c3_w cur_w) /* _term_it_show_line(): render current line. */ static void -_term_it_show_line(u3_utty* uty_u, c3_w wor_w, c3_w sap_w) +_term_it_show_line(u3_utty* uty_u, c3_w wor_w) { u3_utat* tat_u = &uty_u->tat_u; @@ -511,7 +499,6 @@ _term_it_show_line(u3_utty* uty_u, c3_w wor_w, c3_w sap_w) // tat_u->mir.cus_w += wor_w; tat_u->mir.wor_w = wor_w; - tat_u->mir.sap_w = sap_w; } /* _term_it_refresh_line(): refresh current line. @@ -521,11 +508,10 @@ _term_it_refresh_line(u3_utty* uty_u) { u3_utat* tat_u = &uty_u->tat_u; c3_w wor_w = tat_u->mir.wor_w; - c3_w sap_w = tat_u->mir.sap_w; c3_w cus_w = tat_u->mir.cus_w; _term_it_show_clear(uty_u); - _term_it_show_line(uty_u, wor_w, sap_w); + _term_it_show_line(uty_u, wor_w); _term_it_show_cursor(uty_u, cus_w); } @@ -534,8 +520,7 @@ _term_it_refresh_line(u3_utty* uty_u) static void _term_it_set_line(u3_utty* uty_u, c3_w* lin_w, - c3_w wor_w, - c3_w sap_w) + c3_w wor_w) { u3_utat* tat_u = &uty_u->tat_u; c3_y* hun_y = (c3_y*)lin_w; @@ -577,9 +562,8 @@ _term_it_set_line(u3_utty* uty_u, tat_u->mir.lin_y = hun_y; tat_u->mir.byt_w = byt_w; tat_u->mir.wor_w = wor_w; - tat_u->mir.sap_w = sap_w; - _term_it_show_line(uty_u, wor_w, sap_w); + _term_it_show_line(uty_u, wor_w); } /* _term_it_show_more(): new current line. @@ -1244,7 +1228,6 @@ _term_it_show_stub(u3_utty* uty_u, // tracking total and escape characters written // c3_w i_w = 0; - c3_w sap_w = 0; { u3_noun nub = tub; while ( u3_nul != nub ) { @@ -1264,7 +1247,6 @@ _term_it_show_stub(u3_utty* uty_u, c3_o mor_o = c3n; lin_w[i_w++] = 27; lin_w[i_w++] = '['; - sap_w += 2; // text decorations // @@ -1274,10 +1256,8 @@ _term_it_show_stub(u3_utty* uty_u, while ( u3_nul != des ) { if ( c3y == mor_o ) { lin_w[i_w++] = ';'; - sap_w++; } _term_it_put_deco(&lin_w[i_w++], u3h(des)); - sap_w++; mor_o = c3y; des = u3t(des); } @@ -1289,12 +1269,10 @@ _term_it_show_stub(u3_utty* uty_u, if ( u3_nul != bag ) { if ( c3y == mor_o ) { lin_w[i_w++] = ';'; - sap_w++; } lin_w[i_w++] = '4'; c3_w put_w = _term_it_put_tint(&lin_w[i_w], bag); i_w += put_w; - sap_w += ++put_w; mor_o = c3y; } @@ -1303,17 +1281,14 @@ _term_it_show_stub(u3_utty* uty_u, if ( u3_nul != fog ) { if ( c3y == mor_o ) { lin_w[i_w++] = ';'; - sap_w++; } lin_w[i_w++] = '3'; c3_w put_w = _term_it_put_tint(&lin_w[i_w], fog); i_w += put_w; - sap_w += ++put_w; mor_o = c3y; } lin_w[i_w++] = 'm'; - sap_w++; } // write the text itself @@ -1329,14 +1304,13 @@ _term_it_show_stub(u3_utty* uty_u, lin_w[i_w++] = '['; lin_w[i_w++] = '0'; lin_w[i_w++] = 'm'; - sap_w += 4; } nub = u3t(nub); } } - _term_it_set_line(uty_u, lin_w, i_w, sap_w); + _term_it_set_line(uty_u, lin_w, i_w); u3z(tub); } @@ -1358,7 +1332,7 @@ _term_it_show_tour(u3_utty* uty_u, } } - _term_it_set_line(uty_u, lin_w, len_w, 0); + _term_it_set_line(uty_u, lin_w, len_w); u3z(lin); } From 3ad0c4e1d0202f893c1efd25b90ef19b1ea8ae84 Mon Sep 17 00:00:00 2001 From: fang Date: Wed, 27 Jan 2021 16:47:43 +0100 Subject: [PATCH 003/104] dill: remove outdated compatibility workaround Current era runs exclusively on v1.0 and up. --- pkg/arvo/sys/vane/dill.hoon | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pkg/arvo/sys/vane/dill.hoon b/pkg/arvo/sys/vane/dill.hoon index c30d581acf..6af5583b18 100644 --- a/pkg/arvo/sys/vane/dill.hoon +++ b/pkg/arvo/sys/vane/dill.hoon @@ -184,12 +184,6 @@ =. see [%lin p.bit] (done %blit [see [%hop pos] ~]) ?: ?=(%pom -.bit) - ::NOTE treat "styled prompt" without style as plain prompt, - :: to allow rendering by older runtimes - ::TODO remove me once v0.10.9+ has high/guaranteed adoption - :: - ?: (levy p.bit (cork head |*(s=stye =(*stye s)))) - $(bit [%pro (zing (turn p.bit tail))]) =. see [%klr p.bit] (done %blit [see [%hop pos] ~]) ?: ?=(%hop -.bit) From 5d8b44ccbc8946506f8981ee875c43b421059221 Mon Sep 17 00:00:00 2001 From: fang Date: Thu, 28 Jan 2021 01:20:45 +0100 Subject: [PATCH 004/104] dill: support 2d %hop Instead of confining you to just the bottom row. 0,0 is bottom left. Doesn't behave exactly as expected for non-zero column coordinates yet, but all in due time. --- pkg/arvo/mar/blit.hoon | 3 ++- pkg/arvo/sys/lull.hoon | 2 +- pkg/arvo/sys/vane/dill.hoon | 4 ++-- pkg/urbit/vere/io/term.c | 35 +++++++++++++++++++++++++---------- 4 files changed, 30 insertions(+), 14 deletions(-) diff --git a/pkg/arvo/mar/blit.hoon b/pkg/arvo/mar/blit.hoon index b50c0fa7d7..b2e7783e3f 100644 --- a/pkg/arvo/mar/blit.hoon +++ b/pkg/arvo/mar/blit.hoon @@ -20,7 +20,8 @@ ?- -.blit %bel b+& %clr b+& - %hop (numb p.blit) + %hop ?@ p.blit (numb p.blit) + (pairs 'row'^(numb r.p.blit) 'col'^(numb c.p.blit) ~) %lin a+(turn p.blit |=(c=@c s+(tuft c))) %nel b+& %url s+p.blit diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index 76af8fd43b..02daec58c2 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -1057,7 +1057,7 @@ +$ blit :: outside blit $% [%bel ~] :: make a noise [%clr ~] :: clear the screen - [%hop p=@ud] :: set cursor position + [%hop p=$@(@ud [r=@ud c=@ud])] :: set cursor row/pos [%klr p=stub] :: set styled line [%lin p=(list @c)] :: set current line [%nel ~] :: newline diff --git a/pkg/arvo/sys/vane/dill.hoon b/pkg/arvo/sys/vane/dill.hoon index 6af5583b18..67d79fcea9 100644 --- a/pkg/arvo/sys/vane/dill.hoon +++ b/pkg/arvo/sys/vane/dill.hoon @@ -21,7 +21,7 @@ $: ram=term :: console program tem=(unit (list dill-belt)) :: pending, reverse wid=_80 :: terminal width - pos=@ud :: cursor position + pos=$@(@ud [@ud @ud]) :: cursor position see=$%([%lin (list @c)] [%klr stub]) :: current line == :: +$ log-level ?(%hush %soft %loud) :: none, line, full @@ -430,7 +430,7 @@ ?~ session=(~(get by dug.all) u.hey.all) [~ ~] ?+ t.t.tyl ~ [%line ~] ``blit+!>(`blit`see.u.session) - [%cursor ~] ``atom+!>(pos.u.session) + [%cursor ~] ``blit+!>(`blit`hop+pos.u.session) == == :: diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index c6aba89951..be0bef8a9e 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -457,23 +457,32 @@ _term_it_show_blank(u3_utty* uty_u) _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.clear_u); } -/* _term_it_show_cursor(): set current line, transferring pointer. +/* _term_it_move_cursor(): move cursor to row & column + NOTE: row 0 is at the bottom, col 0 is to the left */ static void -_term_it_show_cursor(u3_utty* uty_u, c3_w cur_w) +_term_it_move_cursor(u3_utty* uty_u, c3_w row_w, c3_w col_w) { - c3_c cur_c[5]; - c3_c len_c = sprintf(cur_c, "%d", cur_w + 1); + c3_c col_c[5]; + c3_c wol_c = sprintf(col_c, "%d", col_w + 1); + + c3_c row_c[5]; + c3_c wow_c = sprintf(row_c, "%d", ( uty_u->tat_u.siz.row_l - row_w )); uv_buf_t esc_u = TERM_LIT_BUF("\033["); - uv_buf_t pos_u = uv_buf_init(cur_c, len_c); - uv_buf_t cha_u = TERM_LIT_BUF("G"); + uv_buf_t col_u = uv_buf_init(col_c, wol_c); + uv_buf_t sep_u = TERM_LIT_BUF(";"); + uv_buf_t row_u = uv_buf_init(row_c, wow_c); + uv_buf_t cha_u = TERM_LIT_BUF("H"); _term_it_dump_buf(uty_u, &esc_u); - _term_it_dump_buf(uty_u, &pos_u); + _term_it_dump_buf(uty_u, &row_u); + _term_it_dump_buf(uty_u, &sep_u); + _term_it_dump_buf(uty_u, &col_u); _term_it_dump_buf(uty_u, &cha_u); - uty_u->tat_u.mir.cus_w = cur_w; + //TODO should also store row + uty_u->tat_u.mir.cus_w = col_w; } /* _term_it_show_line(): render current line. @@ -512,7 +521,7 @@ _term_it_refresh_line(u3_utty* uty_u) _term_it_show_clear(uty_u); _term_it_show_line(uty_u, wor_w); - _term_it_show_cursor(uty_u, cus_w); + _term_it_move_cursor(uty_u, 0, cus_w); } /* _term_it_set_line(): set current line. @@ -1361,7 +1370,13 @@ _term_ef_blit(u3_utty* uty_u, case c3__hop: { if ( c3n == u3_Host.ops_u.tem ) { - _term_it_show_cursor(uty_u, u3t(blt)); + u3_noun pos = u3t(blt); + if ( c3y == u3r_ud(pos) ) { + _term_it_move_cursor(uty_u, 0, pos); + } + else { + _term_it_move_cursor(uty_u, u3h(pos), u3t(pos)); + } } } break; From 8cfa1516d81ee414d7f14667f2143ab0a6cee9e4 Mon Sep 17 00:00:00 2001 From: fang Date: Thu, 4 Feb 2021 00:47:57 +0100 Subject: [PATCH 005/104] term: refactor CSI escape sequence sending --- pkg/urbit/vere/io/term.c | 46 +++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index be0bef8a9e..b4f11afd7b 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -420,6 +420,34 @@ _term_it_send(u3_utty* uty_u, _term_it_write(uty_u, &buf_u, (void*)hun_y); } +/* _term_it_send_csi(): send csi escape sequence +*/ +static void +_term_it_send_csi(u3_utty *uty_u, c3_c cmd_c, c3_w num_w, ...) +{ + va_list ap; + va_start(ap, num_w); + + uv_buf_t esc_u = TERM_LIT_BUF("\033["); + _term_it_dump_buf(uty_u, &esc_u); + + uv_buf_t sep_u = TERM_LIT_BUF(";"); //REVIEW re-use works fine, but is it? + while ( num_w > 0 ) { + c3_w par_w = va_arg(ap, c3_w); + c3_c pas_c[5]; + c3_c was_c = sprintf(pas_c, "%d", par_w); + uv_buf_t pas_u = uv_buf_init(pas_c, was_c); + _term_it_dump_buf(uty_u, &pas_u); + + if ( --num_w > 0 ) { + _term_it_dump_buf(uty_u, &sep_u); + } + } + + uv_buf_t cmd_u = uv_buf_init(&cmd_c, 1); + _term_it_dump_buf(uty_u, &cmd_u); +} + /* _term_it_send_cord(): write a cord. */ static void @@ -463,23 +491,7 @@ _term_it_show_blank(u3_utty* uty_u) static void _term_it_move_cursor(u3_utty* uty_u, c3_w row_w, c3_w col_w) { - c3_c col_c[5]; - c3_c wol_c = sprintf(col_c, "%d", col_w + 1); - - c3_c row_c[5]; - c3_c wow_c = sprintf(row_c, "%d", ( uty_u->tat_u.siz.row_l - row_w )); - - uv_buf_t esc_u = TERM_LIT_BUF("\033["); - uv_buf_t col_u = uv_buf_init(col_c, wol_c); - uv_buf_t sep_u = TERM_LIT_BUF(";"); - uv_buf_t row_u = uv_buf_init(row_c, wow_c); - uv_buf_t cha_u = TERM_LIT_BUF("H"); - - _term_it_dump_buf(uty_u, &esc_u); - _term_it_dump_buf(uty_u, &row_u); - _term_it_dump_buf(uty_u, &sep_u); - _term_it_dump_buf(uty_u, &col_u); - _term_it_dump_buf(uty_u, &cha_u); + _term_it_send_csi(uty_u, 'H', 2, uty_u->tat_u.siz.row_l - row_w, col_w + 1); //TODO should also store row uty_u->tat_u.mir.cus_w = col_w; From dc2c990c0feacb21e49cbb8743b2861beac2418b Mon Sep 17 00:00:00 2001 From: fang Date: Thu, 4 Feb 2021 01:05:48 +0100 Subject: [PATCH 006/104] term: avoid touching prompt during printf We want to decouple drum state & semantics from term.c. But we also want to continue showing printfs without mangling whatever the arvo side is doing. Short of formalizing various "terminal modes", the best we can do it assume that the main session is always in drum mode, and use that assumption to squeeze into the actual content stream when doing printfs. In essence, we insert the printf between the prompt and content, pushing the content up into terminal scrollback. Both the prompt and cursor position are maintained without knowledge of their original states. Because this logic relies on knowing the (accurate) terminal height, and this logic being the *only* thing in term.c that reads from the height, we no longer initialize the terminal size with a sane height. Instead, we set it to zero, and check for that to determine whether we're ready to use this logic or not. Due to the way this inserting works, trailing newlines are no longer required from the output. For consistency, we manually add trailing newlines when this logic cannot be used, both in the above-described circumstance, and the less-common case of u3l_log. This will of course need to be accounted for in all existing calls to u3l_log, but we move that into the next commit for readability's sake. --- pkg/urbit/noun/log.c | 2 ++ pkg/urbit/vere/io/term.c | 35 +++++++++++++++++++++++++---------- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/pkg/urbit/noun/log.c b/pkg/urbit/noun/log.c index 8d58fef29b..acaf9abeb6 100644 --- a/pkg/urbit/noun/log.c +++ b/pkg/urbit/noun/log.c @@ -22,6 +22,8 @@ u3l_log(const char* format, ...) // this process did not set a logging function, fallback to stderr // vfprintf(stderr, format, myargs); + fprintf(stderr, "\r\n"); + fflush(stderr); } va_end(myargs); diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index b4f11afd7b..5dc3663bc0 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -233,7 +233,7 @@ u3_term_log_init(void) // { uty_u->tat_u.siz.col_l = 80; - uty_u->tat_u.siz.row_l = 24; + uty_u->tat_u.siz.row_l = 0; } // initialize spinner state @@ -1452,7 +1452,7 @@ u3_term_io_hija(void) { u3_utty* uty_u = _term_main(); - if ( uty_u ) { + if ( uty_u && uty_u->tat_u.siz.row_l ) { if ( uty_u->fid_i > 2 ) { // We *should* in fact, produce some kind of fake FILE* for // non-console terminals. If we use this interface enough... @@ -1477,11 +1477,16 @@ u3_term_io_hija(void) perror("hija-fcntl-0"); c3_assert(!"hija-fcntl"); } - _write(uty_u->fid_i, "\r", 1); - { - uv_buf_t* buf_u = &uty_u->ufo_u.out.el_u; - _write(uty_u->fid_i, buf_u->base, buf_u->len); - } + + // save cursor position, + // set scroll region to exclude the prompt, + // scroll up one line to make space, + // and move the cursor onto that space. + // + _term_it_send_csi(uty_u, 's', 0); + _term_it_send_csi(uty_u, 'r', 2, 1, uty_u->tat_u.siz.row_l - 1); + _term_it_send_csi(uty_u, 'S', 1, 1); + _term_it_send_csi(uty_u, 'H', 2, uty_u->tat_u.siz.row_l - 1, 1); } return stdout; } @@ -1496,7 +1501,7 @@ u3_term_io_loja(int x) { u3_utty* uty_u = _term_main(); - if ( uty_u ) { + if ( uty_u && uty_u->tat_u.siz.row_l ) { if ( uty_u->fid_i > 2 ) { // We *should* in fact, produce some kind of fake FILE* for // non-console terminals. If we use this interface enough... @@ -1524,10 +1529,18 @@ u3_term_io_loja(int x) perror("hija-fcntl-0"); c3_assert(!"loja-fcntl"); } - _term_it_refresh_line(uty_u); + + // clear the scrolling region we set previously, + // and restore cursor to its original position. + // + _term_it_send_csi(uty_u, 'r', 0); + _term_it_send_csi(uty_u, 'u', 0); } } } + else { + fprintf(stdout, "\n"); + } } /* u3_term_it_log(): writes a log message @@ -1536,7 +1549,9 @@ void u3_term_io_log(c3_c* line) { FILE* stream = u3_term_io_hija(); - u3_term_io_loja(fprintf(stream, "%s", line)); + int x = fprintf(stream, "%s", line); + fflush(stream); + u3_term_io_loja(x); //TODO remove arg? unused... } /* u3_term_tape_to(): dump a tape to a file. From 9631be65ad53a9127bb60aaef7519da3e4f44e2e Mon Sep 17 00:00:00 2001 From: fang Date: Sat, 6 Feb 2021 00:45:38 +0100 Subject: [PATCH 007/104] vere: remove trailing newlines from u3l_log calls As of dc2c990c0 these are redundant, and keeping them in would result in trailing whiteline. The result is that sometimes we call u3l_log with the empty string. We simply want it to insert a newline into the scrollback for us. GCC complains about this, because it leads to using an empty format string, but we consider this sane behavior. We update the flags accordingly. --- pkg/urbit/configure | 2 +- pkg/urbit/daemon/main.c | 4 +- pkg/urbit/jets/c/rep.c | 2 +- pkg/urbit/jets/c/rip.c | 2 +- pkg/urbit/jets/e/argon2.c | 4 +- pkg/urbit/jets/e/blake.c | 4 +- pkg/urbit/jets/e/jam.c | 6 +-- pkg/urbit/jets/e/ripe.c | 8 +-- pkg/urbit/jets/e/rub.c | 2 +- pkg/urbit/jets/e/secp.c | 18 +++---- pkg/urbit/jets/f/core.c | 2 +- pkg/urbit/jets/f/look.c | 2 +- pkg/urbit/noun/allocate.c | 16 +++--- pkg/urbit/noun/events.c | 20 ++++---- pkg/urbit/noun/hashtable.c | 2 +- pkg/urbit/noun/jets.c | 42 +++++++-------- pkg/urbit/noun/manage.c | 36 ++++++------- pkg/urbit/noun/nock.c | 2 +- pkg/urbit/noun/trace.c | 6 +-- pkg/urbit/noun/vortex.c | 8 +-- pkg/urbit/vere/auto.c | 8 +-- pkg/urbit/vere/dawn.c | 46 ++++++++--------- pkg/urbit/vere/disk.c | 10 ++-- pkg/urbit/vere/foil.c | 4 +- pkg/urbit/vere/io/ames.c | 96 +++++++++++++++++----------------- pkg/urbit/vere/io/behn.c | 4 +- pkg/urbit/vere/io/cttp.c | 12 ++--- pkg/urbit/vere/io/fore.c | 14 ++--- pkg/urbit/vere/io/hind.c | 4 +- pkg/urbit/vere/io/http.c | 60 +++++++++++----------- pkg/urbit/vere/io/term.c | 14 ++--- pkg/urbit/vere/io/unix.c | 102 ++++++++++++++++++------------------- pkg/urbit/vere/king.c | 44 ++++++++-------- pkg/urbit/vere/lord.c | 15 +++--- pkg/urbit/vere/newt.c | 2 +- pkg/urbit/vere/pier.c | 90 ++++++++++++++++---------------- pkg/urbit/vere/save.c | 2 +- pkg/urbit/vere/walk.c | 14 ++--- pkg/urbit/worker/main.c | 3 +- pkg/urbit/worker/serf.c | 14 ++--- 40 files changed, 374 insertions(+), 372 deletions(-) diff --git a/pkg/urbit/configure b/pkg/urbit/configure index cfc42f83e3..d592f0c70d 100755 --- a/pkg/urbit/configure +++ b/pkg/urbit/configure @@ -90,7 +90,7 @@ do LDFLAGS="${LDFLAGS-} -I$header" done cat >config.mk <cax.har_p); @@ -31,7 +31,7 @@ u3qe_jam(u3_atom a) u3a_print_memory(stderr, "total", tot_w); u3a_print_memory(stderr, "memoization cache", mem_w); u3h_root* har_u = u3to(u3h_root, u3R->cax.har_p); - u3l_log("memoization entries: %d\r\n", har_u->use_w); + u3l_log("memoization entries: %d", har_u->use_w); u3a_print_memory(stderr, "unused free", u3a_open(u3R)); return tot_w; } diff --git a/pkg/urbit/jets/e/ripe.c b/pkg/urbit/jets/e/ripe.c index 908e6aa1c4..bb77576295 100644 --- a/pkg/urbit/jets/e/ripe.c +++ b/pkg/urbit/jets/e/ripe.c @@ -30,7 +30,7 @@ if ( 1 != ret_w ) { u3a_free(dat_y); EVP_MD_CTX_destroy(con_u); - u3l_log("\rripe jet: crypto library fail 1\n"); + u3l_log("\rripe jet: crypto library fail 1"); return u3m_bail(c3__fail); } @@ -38,14 +38,14 @@ u3a_free(dat_y); if (1 != ret_w) { EVP_MD_CTX_destroy(con_u); - u3l_log("\rripe jet: crypto library fail 2\n"); + u3l_log("\rripe jet: crypto library fail 2"); return u3m_bail(c3__fail); } ret_w = EVP_DigestFinal_ex(con_u, sib_y, &sil_w); if ( 1 != ret_w ) { EVP_MD_CTX_destroy(con_u); - u3l_log("\rripe jet: crypto library fail 3\n"); + u3l_log("\rripe jet: crypto library fail 3"); return u3m_bail(c3__fail); } @@ -68,7 +68,7 @@ u3ud(wid) || u3ud(dat)) ) { - u3l_log("\rripe jet: argument error\n"); + u3l_log("\rripe jet: argument error"); return u3m_bail(c3__exit); } else { diff --git a/pkg/urbit/jets/e/rub.c b/pkg/urbit/jets/e/rub.c index 641e53035b..48a1116b38 100644 --- a/pkg/urbit/jets/e/rub.c +++ b/pkg/urbit/jets/e/rub.c @@ -31,7 +31,7 @@ // Sanity check: crash if decoding more bits than available if ( c3y == u3qa_gth(x, m)) { - // u3l_log("[%%rub-hard %d %d %d]\r\n", a, x, m); + // u3l_log("[%%rub-hard %d %d %d]", a, x, m); return u3m_bail(c3__exit); } diff --git a/pkg/urbit/jets/e/secp.c b/pkg/urbit/jets/e/secp.c index 61efda4810..2b3a9231f3 100644 --- a/pkg/urbit/jets/e/secp.c +++ b/pkg/urbit/jets/e/secp.c @@ -64,7 +64,7 @@ u3we_sign(u3_noun cor) 0)) || (c3n == u3ud(has)) || (c3n == u3ud(prv))) { - u3l_log("\rsecp jet: crypto package error\n"); + u3l_log("\rsecp jet: crypto package error"); return u3m_bail(c3__exit); } else { return (u3qe_sign(has, prv)); @@ -100,7 +100,7 @@ u3qe_sign(u3_atom has, (secp256k1_nonce_function) NULL, /* IN: nonce-function ptr ; NULL = default */ (const void *) NULL); /* IN: data for nonce function; not used */ if (1 != ret) { - u3l_log("\rsecp jet: crypto package error\n"); + u3l_log("\rsecp jet: crypto package error"); return u3m_bail(c3__exit); } @@ -113,7 +113,7 @@ u3qe_sign(u3_atom has, & v, /* OUT: v */ & sig_u); /* IN: 65 byte sig */ if (1 != ret) { - u3l_log("\rsecp jet: crypto package error\n"); + u3l_log("\rsecp jet: crypto package error"); return u3m_bail(c3__exit); } @@ -149,7 +149,7 @@ u3we_reco(u3_noun cor) (c3n == u3ud(sir)) || (c3n == u3ud(sis)) ) { - u3l_log("\rsecp jet: crypto package error\n"); + u3l_log("\rsecp jet: crypto package error"); return u3m_bail(c3__exit); } else { return u3qe_reco(has, siv, sir, sis); @@ -197,7 +197,7 @@ u3qe_reco(u3_atom has, ras_y, /* IN: r/s */ siv_ws); /* IN: v */ if (1 != ret) { - u3l_log("\rsecp jet: crypto package error\n"); + u3l_log("\rsecp jet: crypto package error"); return u3m_bail(c3__exit); } @@ -210,7 +210,7 @@ u3qe_reco(u3_atom has, has_y); /* IN: message has */ if (1 != ret) { - u3l_log("\rsecp jet: crypto package error\n"); + u3l_log("\rsecp jet: crypto package error"); return u3m_bail(c3__exit); } @@ -226,7 +226,7 @@ u3qe_reco(u3_atom has, SECP256K1_EC_UNCOMPRESSED); /* IN: flags */ if (1 != ret) { - u3l_log("\rsecp jet: crypto package error\n"); + u3l_log("\rsecp jet: crypto package error"); return u3m_bail(c3__exit); } @@ -269,7 +269,7 @@ u3we_make(u3_noun cor) (c3n == u3ud(has)) || (c3n == u3ud(prv)) ) { - u3l_log("\rsecp jet: crypto package error\n"); + u3l_log("\rsecp jet: crypto package error"); return u3m_bail(c3__exit); } else { return u3qe_make(has, prv); @@ -303,7 +303,7 @@ u3qe_make(u3_atom has, (void *) NULL, /* IN: arbitrary data pointer (unused) */ 0); /* IN: attempt number (0 == normal) */ if (1 != ret_ws) { - u3l_log("\rsecp jet: crypto package error\n"); + u3l_log("\rsecp jet: crypto package error"); return u3m_bail(c3__exit); } diff --git a/pkg/urbit/jets/f/core.c b/pkg/urbit/jets/f/core.c index 753ea74de3..5d7ef8015c 100644 --- a/pkg/urbit/jets/f/core.c +++ b/pkg/urbit/jets/f/core.c @@ -22,7 +22,7 @@ (u3_nul == u3h(hr_con)) && (u3_nul == u3t(hr_con)) ) { - u3l_log("old core\r\n"); + u3l_log("old core"); abort(); } } diff --git a/pkg/urbit/jets/f/look.c b/pkg/urbit/jets/f/look.c index e54091b0b2..038f7a5228 100644 --- a/pkg/urbit/jets/f/look.c +++ b/pkg/urbit/jets/f/look.c @@ -20,7 +20,7 @@ u3r_trel(dab, &n_dab, &l_dab, &r_dab); if ( c3n == u3du(n_dab) ) { // return u3m_bail(c3__fail); - u3l_log("bad look\r\n"); + u3l_log("bad look"); return u3m_bail(c3__exit) ; } else { diff --git a/pkg/urbit/noun/allocate.c b/pkg/urbit/noun/allocate.c index 4536069a65..1737890be1 100644 --- a/pkg/urbit/noun/allocate.c +++ b/pkg/urbit/noun/allocate.c @@ -433,7 +433,7 @@ _ca_willoc(c3_w len_w, c3_w ald_w, c3_w alp_w) sel_w += 1; } - // u3l_log("walloc %d: *pfr_p %x\n", len_w, u3R->all.fre_p[sel_w]); + // u3l_log("walloc %d: *pfr_p %x", len_w, u3R->all.fre_p[sel_w]); while ( 1 ) { u3p(u3a_fbox) *pfr_p = &u3R->all.fre_p[sel_w]; @@ -568,7 +568,7 @@ u3a_walloc(c3_w len_w) u3a_botox(ptr_v) == (u3a_box*)(void *)0x200dfe3e4 ) { static int xuc_i; - u3l_log("xuc_i %d\r\n", xuc_i); + u3l_log("xuc_i %d", xuc_i); if ( 1 == xuc_i ) { u3a_box* box_u = u3a_botox(ptr_v); @@ -684,7 +684,7 @@ u3a_malloc(size_t len_i) if ( u3a_botox(out_w) == (u3a_box*)(void *)0x3bdd1c80) { static int xuc_i = 0; - u3l_log("xuc_i %d\r\n", xuc_i); + u3l_log("xuc_i %d", xuc_i); // if ( 1 == xuc_i ) { abort(); } xuc_i++; } @@ -917,7 +917,7 @@ u3a_free(void* tox_v) c3_w pad_w = tox_w[-1]; c3_w* org_w = tox_w - (pad_w + 1); - // u3l_log("free %p %p\r\n", org_w, tox_w); + // u3l_log("free %p %p", org_w, tox_w); u3a_wfree(org_w); } @@ -1065,7 +1065,7 @@ _ca_take_atom(u3a_atom* old_u) u3_noun new = u3a_to_pug(u3a_outa(new_u)); #ifdef VERBOSE_TAKE - u3l_log("%s: atom %p to %p\r\n", ( c3y == u3a_is_north(u3R) ) + u3l_log("%s: atom %p to %p", ( c3y == u3a_is_north(u3R) ) ? "north" : "south", old_u, @@ -1103,7 +1103,7 @@ _ca_take_cell(u3a_cell* old_u, u3_noun hed, u3_noun tel) u3_cell new = u3a_to_pom(u3a_outa(new_u)); #ifdef VERBOSE_TAKE - u3l_log("%s: cell %p to %p\r\n", ( c3y == u3a_is_north(u3R) ) + u3l_log("%s: cell %p to %p", ( c3y == u3a_is_north(u3R) ) ? "north" : "south", old_u, @@ -1162,7 +1162,7 @@ _ca_take_next_north(u3a_pile* pil_u, u3_noun veb) c3_assert( c3y == u3a_north_is_normal(u3R, nov) ); #ifdef VERBOSE_TAKE - u3l_log("north: %p is already %p\r\n", veb_u, u3a_to_ptr(nov)); + u3l_log("north: %p is already %p", veb_u, u3a_to_ptr(nov)); #endif _me_gain_use(nov); // bypass branches in u3k() @@ -1218,7 +1218,7 @@ _ca_take_next_south(u3a_pile* pil_u, u3_noun veb) c3_assert( c3y == u3a_south_is_normal(u3R, nov) ); #ifdef VERBOSE_TAKE - u3l_log("south: %p is already %p\r\n", veb_u, u3a_to_ptr(nov)); + u3l_log("south: %p is already %p", veb_u, u3a_to_ptr(nov)); #endif _me_gain_use(nov); // bypass branches in u3k() diff --git a/pkg/urbit/noun/events.c b/pkg/urbit/noun/events.c index df82bb9cfd..37bdbbcb1e 100644 --- a/pkg/urbit/noun/events.c +++ b/pkg/urbit/noun/events.c @@ -64,7 +64,7 @@ u3e_check(c3_c* cap_c) } sum_w += mug_w; } - u3l_log("%s: sum %x (%x, %x)\r\n", cap_c, sum_w, nor_w, sou_w); + u3l_log("%s: sum %x (%x, %x)", cap_c, sum_w, nor_w, sou_w); } } @@ -137,7 +137,7 @@ u3e_fault(void* adr_v, c3_i ser_i) #if 0 if ( pag_w == 131041 ) { - u3l_log("dirty page %d (at %p); unprotecting %p to %p\r\n", + u3l_log("dirty page %d (at %p); unprotecting %p to %p", pag_w, adr_v, (u3_Loom + (pag_w << u3a_page)), @@ -342,7 +342,7 @@ _ce_patch_verify(u3_ce_patch* pat_u) } #if 0 else { - u3l_log("verify: patch %d/%d, %x\r\n", pag_w, i_w, mug_w); + u3l_log("verify: patch %d/%d, %x", pag_w, i_w, mug_w); } #endif } @@ -459,7 +459,7 @@ _ce_patch_save_page(u3_ce_patch* pat_u, (1 << u3a_page)); #if 0 - u3l_log("protect a: page %d\r\n", pag_w); + u3l_log("protect a: page %d", pag_w); #endif _ce_patch_write_page(pat_u, pgc_w, mem_w); @@ -485,7 +485,7 @@ _ce_patch_junk_page(u3_ce_patch* pat_u, c3_w blk_w = (pag_w >> 5); c3_w bit_w = (pag_w & 31); - // u3l_log("protect b: page %d\r\n", pag_w); + // u3l_log("protect b: page %d", pag_w); if ( -1 == mprotect(u3_Loom + (pag_w << u3a_page), (1 << (u3a_page + 2)), PROT_READ) ) @@ -689,7 +689,7 @@ _ce_patch_apply(u3_ce_patch* pat_u) } } #if 0 - u3l_log("apply: %d, %x\n", pag_w, u3r_mug_words(mem_w, (1 << u3a_page))); + u3l_log("apply: %d, %x", pag_w, u3r_mug_words(mem_w, (1 << u3a_page))); #endif } } @@ -714,7 +714,7 @@ _ce_image_blit(u3e_image* img_u, c3_w off_w = (ptr_w - u3_Loom); c3_w pag_w = (off_w >> u3a_page); - u3l_log("blit: page %d, mug %x\r\n", pag_w, + u3l_log("blit: page %d, mug %x", pag_w, u3r_mug_words(ptr_w, (1 << u3a_page))); } #endif @@ -869,17 +869,17 @@ u3e_live(c3_o nuu_o, c3_c* dir_c) -(1 << u3a_page)); if ( 0 != mprotect((void *)u3_Loom, u3a_bytes, PROT_READ) ) { - u3l_log("loom: live mprotect: %s\r\n", strerror(errno)); + u3l_log("loom: live mprotect: %s", strerror(errno)); c3_assert(0); } - u3l_log("boot: protected loom\r\n"); + u3l_log("boot: protected loom"); } /* If the images were empty, we are logically booting. */ if ( (0 == u3P.nor_u.pgs_w) && (0 == u3P.sou_u.pgs_w) ) { - u3l_log("live: logical boot\r\n"); + u3l_log("live: logical boot"); nuu_o = c3y; } else { diff --git a/pkg/urbit/noun/hashtable.c b/pkg/urbit/noun/hashtable.c index 8ae60209ea..a77e4eaac7 100644 --- a/pkg/urbit/noun/hashtable.c +++ b/pkg/urbit/noun/hashtable.c @@ -392,7 +392,7 @@ _ch_trim_slot(u3h_root* har_u, u3h_slot *sot_w, c3_w lef_w, c3_w rem_w) else { u3_noun kev = u3h_slot_to_noun(*sot_w); *sot_w = 0; - // u3l_log("trim: freeing %x, use count %d\r\n", kev, u3a_use(kev))); + // u3l_log("trim: freeing %x, use count %d", kev, u3a_use(kev))); u3z(kev); har_u->arm_u.mug_w = _ch_skip_slot(har_u->arm_u.mug_w, lef_w); diff --git a/pkg/urbit/noun/jets.c b/pkg/urbit/noun/jets.c index e443e7b3b9..40a84024b5 100644 --- a/pkg/urbit/noun/jets.c +++ b/pkg/urbit/noun/jets.c @@ -80,7 +80,7 @@ _cj_hash(c3_c* has_c) { c3_w i_w, len_w = strlen(has_c); if ( 64 != len_w ) { - u3l_log("bash not 64 characters: %s\r\n", has_c); + u3l_log("bash not 64 characters: %s", has_c); c3_assert(0); } c3_assert( 64 == len_w ); @@ -254,18 +254,18 @@ _cj_axis(u3_noun fol) (0 != p_fol) || (!_(u3a_is_cat(q_fol))) ) { - u3l_log("axis: bad a\r\n"); + u3l_log("axis: bad a"); return 0; } return q_fol; } else { if ( 9 != p_fol ) - { u3l_log("axis: bad b\r\n"); return 0; } + { u3l_log("axis: bad b"); return 0; } if ( !_(u3a_is_cat(q_fol)) ) - { u3l_log("axis: bad c\r\n"); return 0; } + { u3l_log("axis: bad c"); return 0; } if ( !_(u3du(r_fol)) || (0 != u3h(r_fol)) || (1 != u3t(r_fol)) ) - { u3l_log("axis: bad d\r\n"); return 0; } + { u3l_log("axis: bad d"); return 0; } return q_fol; } @@ -296,7 +296,7 @@ _cj_warm_hump(c3_l jax_l, u3_noun huc) ((1 << 31) & (axe_l = (c3_w)axe_d)) || (axe_l < 2) ) { - u3l_log("jets: activate: bad fcs %s\r\n", jet_u->fcs_c); + u3l_log("jets: activate: bad fcs %s", jet_u->fcs_c); } } else { @@ -304,7 +304,7 @@ _cj_warm_hump(c3_l jax_l, u3_noun huc) u3_noun fol = u3kdb_get(u3k(huc), nam); if ( u3_none == fol ) { - u3l_log("jets: activate: bad fcs %s\r\n", jet_u->fcs_c); + u3l_log("jets: activate: bad fcs %s", jet_u->fcs_c); } else { axe_l = _cj_axis(fol); @@ -799,7 +799,7 @@ _cj_hot_mean(c3_l par_l, u3_noun nam) while ( (cop_u = &dev_u[i_l])->cos_c ) { if ( _(u3r_sing_c(cop_u->cos_c, nam)) ) { #if 0 - u3l_log("hot: bound jet %d/%s/%s/\r\n", + u3l_log("hot: bound jet %d/%s/%s/", cop_u->jax_l, cop_u->cos_c, par_u ? par_u->cos_c : "~"); @@ -911,7 +911,7 @@ _cj_kick_z(u3_noun cor, u3j_core* cop_u, u3j_harm* ham_u, u3_atom axe) ham_u->liv = c3y; if ( c3n == u3r_sing(ame, pro) ) { - u3l_log("test: %s %s: mismatch: good %x, bad %x\r\n", + u3l_log("test: %s %s: mismatch: good %x, bad %x", cop_u->cos_c, (!strcmp(".2", ham_u->fcs_c)) ? "$" : ham_u->fcs_c, u3r_mug(ame), @@ -924,7 +924,7 @@ _cj_kick_z(u3_noun cor, u3j_core* cop_u, u3j_harm* ham_u, u3_atom axe) else { #if 1 - u3l_log("test: %s %s\r\n", + u3l_log("test: %s %s", cop_u->cos_c, (!strcmp(".2", ham_u->fcs_c)) ? "$" : ham_u->fcs_c); #endif @@ -947,13 +947,13 @@ _cj_hook_in(u3_noun cor, u3_noun roc, tem, got, pat, nam, huc; if ( c3n == u3du(cor) ) { - u3l_log("_cj_hook_in failure: c3n == u3du(cor)\r\n"); + u3l_log("_cj_hook_in failure: c3n == u3du(cor)"); return u3m_bail(c3__fail); } loc = _cj_spot(cor, NULL); if ( u3_none == loc ) { - u3l_log("_cj_hook_in failure: u3_none == loc\r\n"); + u3l_log("_cj_hook_in failure: u3_none == loc"); return u3m_bail(c3__fail); } @@ -1018,7 +1018,7 @@ _cj_hook_in(u3_noun cor, else { u3_noun sat = u3t(pat); if ( c3y == u3h(sat) ) { - u3l_log("_cj_hook_in failure: c3y == u3h(sat)\r\n"); + u3l_log("_cj_hook_in failure: c3y == u3h(sat)"); return u3m_bail(c3__fail); } else { @@ -1706,7 +1706,7 @@ u3j_gate_prep(u3j_site* sit_u, u3_noun cor) pay = u3qc_cap(pax), pam = u3qc_mas(pax); if ( 3 != pay || 2 == pam || (3 != pam && 3 != u3qc_cap(pam)) ) { - u3l_log("u3j_gate_prep(): parent axis includes sample\r\n"); + u3l_log("u3j_gate_prep(): parent axis includes sample"); u3m_p("axis", pax); u3_weak act = _cj_find_warm(loc); c3_assert( u3_none != act ); @@ -1777,12 +1777,12 @@ _cj_minx(u3_noun cey, u3_noun cor) par = u3r_at(axe, cor); if ( u3_none == par || c3n == u3du(par) ) { - u3l_log("fund: %s is bogus\r\n", u3r_string(nam)); + u3l_log("fund: %s is bogus", u3r_string(nam)); return u3_none; } pel = _cj_spot(par, NULL); if ( u3_none == pel ) { - u3l_log("fund: in %s, parent %x not found at %d\r\n", + u3l_log("fund: in %s, parent %x not found at %d", u3r_string(nam), u3r_mug(u3h(par)), axe); @@ -1841,7 +1841,7 @@ _cj_mine(u3_noun cey, u3_noun cor, u3_noun bas) jax_l = _cj_hot_mean(par_l, nam); #if 0 u3m_p("new jet", bal); - u3l_log(" bat %x, jax %d\r\n", u3r_mug(bat), jax_l); + u3l_log(" bat %x, jax %d", u3r_mug(bat), jax_l); #endif if ( !(u3C.wag_w & u3o_hashless) ) { @@ -1859,7 +1859,7 @@ _cj_mine(u3_noun cey, u3_noun cor, u3_noun bas) for ( i_w = 32; i_w > 0; ) { u3l_log("%02x", dig_y[--i_w]); } - u3l_log("\r\n"); + u3l_log(""); } } @@ -1889,7 +1889,7 @@ _cj_mine(u3_noun cey, u3_noun cor, u3_noun bas) if ( c3n == hav_o ) { u3m_p("unregistered battery", bal); - u3l_log("hash: %x\r\n", bas); + u3l_log("hash: %x", bas); } u3z(bas); } @@ -2112,7 +2112,7 @@ _cj_ream(u3_noun all) act = u3nq(jax_l, hap, bal, _cj_jit(jax_l, bat)); #if 0 u3m_p("old jet", bal); - u3l_log(" bat %x, jax %d\r\n", u3r_mug(bat), jax_l); + u3l_log(" bat %x, jax %d", u3r_mug(bat), jax_l); #endif u3h_put(u3R->jed.war_p, loc, act); } @@ -2151,7 +2151,7 @@ _cj_ream(u3_noun all) act = u3nq(jax_l, hap, bal, _cj_jit(jax_l, bat)); #if 0 u3m_p("old jet", bal); - u3l_log(" bat %x, jax %d\r\n", u3r_mug(bat), jax_l); + u3l_log(" bat %x, jax %d", u3r_mug(bat), jax_l); #endif u3h_put(u3R->jed.war_p, loc, act); } diff --git a/pkg/urbit/noun/manage.c b/pkg/urbit/noun/manage.c index 23ad01e537..8681067d44 100644 --- a/pkg/urbit/noun/manage.c +++ b/pkg/urbit/noun/manage.c @@ -101,7 +101,7 @@ _cm_punt(u3_noun tax) static void _write(int fd, const void *buf, size_t count) { if (count != write(fd, buf, count)){ - u3l_log("write failed\r\n"); + u3l_log("write failed"); c3_assert(0); } } @@ -306,7 +306,7 @@ _cm_signal_recover(c3_l sig_l, u3_noun arg) while ( rod_u->kid_p ) { #if 0 - u3l_log("collecting %d frames\r\n", + u3l_log("collecting %d frames", u3kb_lent((u3to(u3_road, rod_u->kid_p)->bug.tax)); #endif tax = u3kb_weld(_cm_stack_recover(u3to(u3_road, rod_u->kid_p)), tax); @@ -356,7 +356,7 @@ _cm_signal_deep(c3_w mil_w) itm_u.it_value.tv_usec = 1000 * (mil_w % 1000); if ( setitimer(ITIMER_VIRTUAL, &itm_u, 0) ) { - u3l_log("loom: set timer failed %s\r\n", strerror(errno)); + u3l_log("loom: set timer failed %s", strerror(errno)); } else { signal(SIGVTALRM, _cm_signal_handle_alrm); @@ -385,7 +385,7 @@ _cm_signal_done() timerclear(&itm_u.it_value); if ( setitimer(ITIMER_VIRTUAL, &itm_u, 0) ) { - u3l_log("loom: clear timer failed %s\r\n", strerror(errno)); + u3l_log("loom: clear timer failed %s", strerror(errno)); } } @@ -417,7 +417,7 @@ u3m_file(c3_c* pas_c) c3_y* pad_y; if ( (fid_i < 0) || (fstat(fid_i, &buf_b) < 0) ) { - u3l_log("%s: %s\r\n", pas_c, strerror(errno)); + u3l_log("%s: %s", pas_c, strerror(errno)); return u3m_bail(c3__fail); } fln_w = buf_b.st_size; @@ -612,7 +612,7 @@ u3m_dump(void) fre_u = fre_u->nex_u; } } - u3l_log("dump: hat_w %x, fre_w %x, allocated %x\n", + u3l_log("dump: hat_w %x, fre_w %x, allocated %x", hat_w, fre_w, (hat_w - fre_w)); if ( 0 != (hat_w - fre_w) ) { @@ -624,14 +624,14 @@ u3m_dump(void) if ( 0 != box_u->use_w ) { #ifdef U3_MEMORY_DEBUG - // u3l_log("live %d words, code %x\n", box_u->siz_w, box_u->cod_w); + // u3l_log("live %d words, code %x", box_u->siz_w, box_u->cod_w); #endif mem_w += box_u->siz_w; } box_w += box_u->siz_w; } - u3l_log("second count: %x\n", mem_w); + u3l_log("second count: %x", mem_w); } } #endif @@ -1511,7 +1511,7 @@ u3m_p(const c3_c* cap_c, u3_noun som) { c3_c* pre_c = u3m_pretty(som); - u3l_log("%s: %s\r\n", cap_c, pre_c); + u3l_log("%s: %s", cap_c, pre_c); c3_free(pre_c); } @@ -1568,7 +1568,7 @@ _cm_limits(void) rlm.rlim_cur = c3_min(rlm.rlim_max, (65536 << 10)); if ( 0 != setrlimit(RLIMIT_STACK, &rlm) ) { - u3l_log("boot: stack size: %s\r\n", strerror(errno)); + u3l_log("boot: stack size: %s", strerror(errno)); exit(1); } } @@ -1587,7 +1587,7 @@ _cm_limits(void) // no exit, not a critical limit // if ( 0 != setrlimit(RLIMIT_NOFILE, &rlm) ) { - u3l_log("boot: open file limit: %s\r\n", strerror(errno)); + u3l_log("boot: open file limit: %s", strerror(errno)); } } @@ -1601,7 +1601,7 @@ _cm_limits(void) // no exit, not a critical limit // if ( 0 != setrlimit(RLIMIT_CORE, &rlm) ) { - u3l_log("boot: core limit: %s\r\n", strerror(errno)); + u3l_log("boot: core limit: %s", strerror(errno)); } } # endif @@ -1613,7 +1613,7 @@ static void _cm_signals(void) { if ( 0 != sigsegv_install_handler(u3e_fault) ) { - u3l_log("boot: sigsegv install failed\n"); + u3l_log("boot: sigsegv install failed"); exit(1); } // signal(SIGINT, _loom_stop); @@ -1629,7 +1629,7 @@ _cm_signals(void) sigaddset(&set, SIGPROF); if ( 0 != pthread_sigmask(SIG_BLOCK, &set, NULL) ) { - u3l_log("boot: thread mask SIGPROF: %s\r\n", strerror(errno)); + u3l_log("boot: thread mask SIGPROF: %s", strerror(errno)); exit(1); } } @@ -1666,17 +1666,17 @@ u3m_init(void) MAP_ANON | MAP_PRIVATE, -1, 0); - u3l_log("boot: mapping %dMB failed\r\n", (len_w / (1024 * 1024))); + u3l_log("boot: mapping %dMB failed", (len_w / (1024 * 1024))); u3l_log("see urbit.org/using/install/#about-swap-space" " for adding swap space\r\n"); if ( -1 != (c3_ps)map_v ) { - u3l_log("if porting to a new platform, try U3_OS_LoomBase %p\r\n", + u3l_log("if porting to a new platform, try U3_OS_LoomBase %p", dyn_v); } exit(1); } - u3l_log("loom: mapped %dMB\r\n", len_w >> 20); + u3l_log("loom: mapped %dMB", len_w >> 20); } } @@ -1715,7 +1715,7 @@ u3m_boot(c3_c* dir_c) */ { c3_w len_w = u3j_boot(nuu_o); - u3l_log("boot: installed %d jets\r\n", len_w); + u3l_log("boot: installed %d jets", len_w); } /* Reactivate jets on old kernel. diff --git a/pkg/urbit/noun/nock.c b/pkg/urbit/noun/nock.c index 06aab9b986..dc39089345 100644 --- a/pkg/urbit/noun/nock.c +++ b/pkg/urbit/noun/nock.c @@ -44,7 +44,7 @@ _n_hint(u3_noun zep, low_i = 1; if ( 0 == (u3R->pro.nox_d % 65536ULL) ) { if ( c3__spot == zep ) { - u3l_log("spot %d/%d : %d/%d\r\n", + u3l_log("spot %d/%d : %d/%d", u3h(u3h(u3t(hod))), u3t(u3h(u3t(hod))), u3h(u3t(u3t(hod))), diff --git a/pkg/urbit/noun/trace.c b/pkg/urbit/noun/trace.c index f8fe81320c..61e78e1bf9 100644 --- a/pkg/urbit/noun/trace.c +++ b/pkg/urbit/noun/trace.c @@ -167,7 +167,7 @@ _t_samp_process(u3_road* rod_u) pef = t_pef; } - // u3l_log("sample: stack length %d\r\n", u3kb_lent(u3k(pal))); + // u3l_log("sample: stack length %d", u3kb_lent(u3k(pal))); return pal; } } @@ -540,7 +540,7 @@ u3t_boot(void) sigemptyset(&set); sigaddset(&set, SIGPROF); if ( 0 != pthread_sigmask(SIG_UNBLOCK, &set, NULL) ) { - u3l_log("trace: thread mask SIGPROF: %s\r\n", strerror(errno)); + u3l_log("trace: thread mask SIGPROF: %s", strerror(errno)); } } @@ -573,7 +573,7 @@ u3t_boff(void) sigemptyset(&set); sigaddset(&set, SIGPROF); if ( 0 != pthread_sigmask(SIG_BLOCK, &set, NULL) ) { - u3l_log("trace: thread mask SIGPROF: %s\r\n", strerror(errno)); + u3l_log("trace: thread mask SIGPROF: %s", strerror(errno)); } } diff --git a/pkg/urbit/noun/vortex.c b/pkg/urbit/noun/vortex.c index 4bd17746af..37f4864ae0 100644 --- a/pkg/urbit/noun/vortex.c +++ b/pkg/urbit/noun/vortex.c @@ -60,9 +60,9 @@ _cv_lite(u3_noun pil) eve = tal; } - u3l_log("lite: arvo formula %x\r\n", u3r_mug(pil)); + u3l_log("lite: arvo formula %x", u3r_mug(pil)); pro = u3v_life(u3k(eve)); - u3l_log("lite: core %x\r\n", u3r_mug(pro)); + u3l_log("lite: core %x", u3r_mug(pro)); u3z(pil); return pro; @@ -89,7 +89,7 @@ u3v_boot_lite(u3_noun pil) u3z(pro); } - u3l_log("lite: final state %x\r\n", u3r_mug(u3A->roc)); + u3l_log("lite: final state %x", u3r_mug(u3A->roc)); return c3y; } @@ -209,7 +209,7 @@ _cv_mole(u3_noun fot, (0 != q_uco) || (c3n == u3r_sing(fot, r_uco)) ) { - u3l_log("strange mole %s\n", u3r_string(san))); + u3l_log("strange mole %s", u3r_string(san))); u3z(fot); u3z(uco); return c3n; } diff --git a/pkg/urbit/vere/auto.c b/pkg/urbit/vere/auto.c index 759f9a6e47..b98bbd74e7 100644 --- a/pkg/urbit/vere/auto.c +++ b/pkg/urbit/vere/auto.c @@ -107,7 +107,7 @@ u3_auto_bail_slog(u3_ovum* egg_u, u3_noun lud) c3_w len_w = 1; while ( u3_nul != dul ) { - u3l_log("%s: bail %u\r\n", car_c, len_w++); + u3l_log("%s: bail %u", car_c, len_w++); u3_pier_punt_goof(car_c, u3k(u3h(dul))); dul = u3t(dul); @@ -256,7 +256,7 @@ _auto_kick_lost(u3_noun pax, u3_noun fav) c3_c* tag_c = u3r_string(u3h(fav)); c3_c* pax_c = u3r_string(tox); - u3l_log("kick: lost %%%s on %s\n", tag_c, pax_c); + u3l_log("kick: lost %%%s on %s", tag_c, pax_c); c3_free(pax_c); c3_free(tag_c); @@ -376,12 +376,12 @@ u3_auto_info(u3_auto* car_u) { u3_auto* nex_u; - u3l_log(" drivers:\n"); + u3l_log(" drivers:"); while ( car_u ) { nex_u = car_u->nex_u; - u3l_log(" %.*s: live=%s, queue=%u\n", + u3l_log(" %.*s: live=%s, queue=%u", u3r_met(3, car_u->nam_m), (c3_c*)&car_u->nam_m, ( c3y == car_u->liv_o ) ? "&" : "|", diff --git a/pkg/urbit/vere/dawn.c b/pkg/urbit/vere/dawn.c index a2e09ab1cb..91eabaaf97 100644 --- a/pkg/urbit/vere/dawn.c +++ b/pkg/urbit/vere/dawn.c @@ -70,7 +70,7 @@ _dawn_post_json(c3_c* url_c, uv_buf_t lod_u) uv_buf_t buf_u = uv_buf_init(c3_malloc(1), 0); if ( !(curl = curl_easy_init()) ) { - u3l_log("failed to initialize libcurl\n"); + u3l_log("failed to initialize libcurl"); exit(1); } @@ -94,12 +94,12 @@ _dawn_post_json(c3_c* url_c, uv_buf_t lod_u) // XX retry? if ( CURLE_OK != result ) { - u3l_log("failed to fetch %s: %s\n", + u3l_log("failed to fetch %s: %s", url_c, curl_easy_strerror(result)); exit(1); } if ( 300 <= cod_l ) { - u3l_log("error fetching %s: HTTP %ld\n", url_c, cod_l); + u3l_log("error fetching %s: HTTP %ld", url_c, cod_l); exit(1); } @@ -121,7 +121,7 @@ _dawn_get_jam(c3_c* url_c) uv_buf_t buf_u = uv_buf_init(c3_malloc(1), 0); if ( !(curl = curl_easy_init()) ) { - u3l_log("failed to initialize libcurl\n"); + u3l_log("failed to initialize libcurl"); exit(1); } @@ -137,12 +137,12 @@ _dawn_get_jam(c3_c* url_c) // XX retry? if ( CURLE_OK != result ) { - u3l_log("failed to fetch %s: %s\n", + u3l_log("failed to fetch %s: %s", url_c, curl_easy_strerror(result)); exit(1); } if ( 300 <= cod_l ) { - u3l_log("error fetching %s: HTTP %ld\n", url_c, cod_l); + u3l_log("error fetching %s: HTTP %ld", url_c, cod_l); exit(1); } @@ -206,7 +206,7 @@ _dawn_fail(u3_noun who, u3_noun rac, u3_noun sas) } } - u3l_log("boot: invalid keys for %s '%s'\r\n", rac_c, how_c); + u3l_log("boot: invalid keys for %s '%s'", rac_c, how_c); // XX deconstruct sas, print helpful error messages u3m_p("pre-boot error", u3t(sas)); @@ -222,7 +222,7 @@ static u3_noun _dawn_need_unit(u3_noun nit, c3_c* msg_c) { if ( u3_nul == nit ) { - u3l_log("%s\r\n", msg_c); + u3l_log("%s", msg_c); exit(1); } else { @@ -241,7 +241,7 @@ _dawn_purl(u3_noun rac) if ( 0 == u3_Host.ops_u.eth_c ) { if ( c3__czar == rac ) { - u3l_log("boot: galaxy requires ethereum gateway via -e\r\n"); + u3l_log("boot: galaxy requires ethereum gateway via -e"); exit(1); } @@ -256,7 +256,7 @@ _dawn_purl(u3_noun rac) if ( u3_nul == rul ) { if ( c3__czar == rac ) { - u3l_log("boot: galaxy requires ethereum gateway via -e\r\n"); + u3l_log("boot: galaxy requires ethereum gateway via -e"); exit(1); } @@ -288,11 +288,11 @@ _dawn_turf(c3_c* dns_c) u3_noun rul = u3dc("rush", u3k(dns), u3k(par)); if ( (u3_nul == rul) || (c3n == u3h(u3t(rul))) ) { - u3l_log("boot: invalid domain specified with -H %s\r\n", dns_c); + u3l_log("boot: invalid domain specified with -H %s", dns_c); exit(1); } else { - u3l_log("boot: overriding network domains with %s\r\n", dns_c); + u3l_log("boot: overriding network domains with %s", dns_c); u3_noun dom = u3t(u3t(rul)); tuf = u3nc(u3k(dom), u3_nul); } @@ -342,7 +342,7 @@ u3_dawn_vent(u3_noun seed) // pin block number // { - u3l_log("boot: retrieving latest block\r\n"); + u3l_log("boot: retrieving latest block"); u3_noun oct = u3v_wish("bloq:give:dawn"); u3_noun kob = _dawn_eth_rpc(url_c, u3k(oct)); @@ -369,7 +369,7 @@ u3_dawn_vent(u3_noun seed) u3_noun who; who = u3k(ship); - u3l_log("boot: retrieving %s's public keys\r\n", + u3l_log("boot: retrieving %s's public keys", u3_Host.ops_u.who_c); { @@ -390,7 +390,7 @@ u3_dawn_vent(u3_noun seed) u3_noun liv = u3_nul; // u3_noun liv = _dawn_get_json(parent, /some/url) - u3l_log("boot: verifying keys\r\n"); + u3l_log("boot: verifying keys"); // (each sponsor=ship error=@tas) // @@ -402,7 +402,7 @@ u3_dawn_vent(u3_noun seed) return u3_none; } - u3l_log("boot: getting sponsor\r\n"); + u3l_log("boot: getting sponsor"); pos = _dawn_sponsor(u3k(ship), u3k(rank), u3k(pot)); u3z(pot); u3z(liv); } @@ -411,7 +411,7 @@ u3_dawn_vent(u3_noun seed) // (map ship [=life =pass]): galaxy table // { - u3l_log("boot: retrieving galaxy table\r\n"); + u3l_log("boot: retrieving galaxy table"); u3_noun oct = u3do("czar:give:dawn", u3k(bok)); u3_noun raz = _dawn_eth_rpc(url_c, u3k(oct)); @@ -427,7 +427,7 @@ u3_dawn_vent(u3_noun seed) tuf = _dawn_turf(u3_Host.ops_u.dns_c); } else { - u3l_log("boot: retrieving network domains\r\n"); + u3l_log("boot: retrieving network domains"); u3_noun oct = u3do("turf:give:dawn", u3k(bok)); u3_noun fut = _dawn_eth_rpc(url_c, u3k(oct)); @@ -445,7 +445,7 @@ u3_dawn_vent(u3_noun seed) { u3_noun who = u3dc("scot", 'p', u3k(pos)); c3_c* who_c = u3r_string(who); - u3l_log("boot: retrieving keys for sponsor %s\r\n", who_c); + u3l_log("boot: retrieving keys for sponsor %s", who_c); u3z(who); c3_free(who_c); } @@ -495,8 +495,8 @@ _dawn_come(u3_noun stars) c3_rand(eny_w); eny = u3i_words(16, eny_w); - u3l_log("boot: mining a comet. May take up to an hour.\r\n"); - u3l_log("If you want to boot faster, get an Urbit identity.\r\n"); + u3l_log("boot: mining a comet. May take up to an hour."); + u3l_log("If you want to boot faster, get an Urbit identity."); seed = u3dc("come:dawn", u3k(stars), u3k(eny)); u3z(eny); @@ -506,7 +506,7 @@ _dawn_come(u3_noun stars) u3_noun who = u3dc("scot", 'p', u3k(u3h(seed))); c3_c* who_c = u3r_string(who); - u3l_log("boot: found comet %s\r\n", who_c); + u3l_log("boot: found comet %s", who_c); // enable to print and save comet private key for future reuse // @@ -515,7 +515,7 @@ _dawn_come(u3_noun stars) u3_noun key = u3dc("scot", c3__uw, u3qe_jam(seed)); c3_c* key_c = u3r_string(key); - u3l_log("boot: comet private key\n %s\n", key_c); + u3l_log("boot: comet private key\n %s", key_c); { c3_c pat_c[64]; diff --git a/pkg/urbit/vere/disk.c b/pkg/urbit/vere/disk.c index 691f2ae683..1ecf971134 100644 --- a/pkg/urbit/vere/disk.c +++ b/pkg/urbit/vere/disk.c @@ -258,7 +258,7 @@ u3_disk_plan(u3_disk* log_u, u3_fact* tac_u) { c3_assert( (1ULL + log_u->sen_d) == tac_u->eve_d ); log_u->sen_d++; - + if ( !log_u->put_u.ent_u ) { c3_assert( !log_u->put_u.ext_u ); log_u->put_u.ent_u = log_u->put_u.ext_u = tac_u; @@ -665,7 +665,7 @@ u3_disk_exit(u3_disk* log_u) void u3_disk_info(u3_disk* log_u) { - u3l_log(" disk: live=%s, event=%" PRIu64 "\n", + u3l_log(" disk: live=%s, event=%" PRIu64, ( c3y == log_u->liv_o ) ? "&" : "|", log_u->dun_d); @@ -673,7 +673,7 @@ u3_disk_info(u3_disk* log_u) u3_read* red_u = log_u->red_u; while ( red_u ) { - u3l_log(" read: %" PRIu64 "-%" PRIu64 "\n", + u3l_log(" read: %" PRIu64 "-%" PRIu64, red_u->eve_d, (red_u->eve_d + red_u->len_d) - 1); } @@ -681,12 +681,12 @@ u3_disk_info(u3_disk* log_u) if ( log_u->put_u.ext_u ) { if ( log_u->put_u.ext_u != log_u->put_u.ent_u ) { - u3l_log(" save: %" PRIu64 "-%" PRIu64 "\n", + u3l_log(" save: %" PRIu64 "-%" PRIu64, log_u->put_u.ext_u->eve_d, log_u->put_u.ent_u->eve_d); } else { - u3l_log(" save: %" PRIu64 "\n", log_u->put_u.ext_u->eve_d); + u3l_log(" save: %" PRIu64, log_u->put_u.ext_u->eve_d); } } } diff --git a/pkg/urbit/vere/foil.c b/pkg/urbit/vere/foil.c index 9c78cd2969..0da0c3a4e2 100644 --- a/pkg/urbit/vere/foil.c +++ b/pkg/urbit/vere/foil.c @@ -52,10 +52,10 @@ static void _foil_fail(const c3_c* why_c, c3_i err_i) { if ( err_i ) { - u3l_log("%s: error: %s\r\n", why_c, uv_strerror(err_i)); + u3l_log("%s: error: %s", why_c, uv_strerror(err_i)); c3_assert(0); } else { - u3l_log("%s: file error\r\n", why_c); + u3l_log("%s: file error", why_c); } exit(1); } diff --git a/pkg/urbit/vere/io/ames.c b/pkg/urbit/vere/io/ames.c index 8c658afcf4..a923ab74af 100644 --- a/pkg/urbit/vere/io/ames.c +++ b/pkg/urbit/vere/io/ames.c @@ -349,7 +349,7 @@ _ames_send_cb(uv_udp_send_t* req_u, c3_i sas_i) u3_ames* sam_u = pac_u->sam_u; if ( sas_i && (c3y == sam_u->fig_u.net_o) ) { - u3l_log("ames: send fail: %s\n", uv_strerror(sas_i)); + u3l_log("ames: send fail: %s", uv_strerror(sas_i)); sam_u->fig_u.net_o = c3n; } else { @@ -388,7 +388,7 @@ _ames_send(u3_pact* pac_u) if ( sas_i ) { if ( c3y == sam_u->fig_u.net_o ) { - u3l_log("ames: send fail: %s\n", uv_strerror(sas_i)); + u3l_log("ames: send fail: %s", uv_strerror(sas_i)); sam_u->fig_u.net_o = c3n; } @@ -522,7 +522,7 @@ _ames_czar_gone(u3_pact* pac_u, time_t now) u3_ames* sam_u = pac_u->sam_u; if ( c3y == sam_u->imp_o[pac_u->imp_y] ) { - u3l_log("ames: czar at %s: not found (b)\n", pac_u->dns_c); + u3l_log("ames: czar at %s: not found (b)", pac_u->dns_c); sam_u->imp_o[pac_u->imp_y] = c3n; } @@ -552,7 +552,7 @@ _ames_czar_here(u3_pact* pac_u, time_t now, struct sockaddr_in* add_u) u3_noun nam = u3dc("scot", c3__if, u3i_word(pip_w)); c3_c* nam_c = u3r_string(nam); - u3l_log("ames: czar %s: ip %s\n", pac_u->dns_c, nam_c); + u3l_log("ames: czar %s: ip %s", pac_u->dns_c, nam_c); c3_free(nam_c); u3z(nam); @@ -617,7 +617,7 @@ _ames_czar(u3_pact* pac_u) if ( !sam_u->dns_c ) { u3_noun nam = u3dc("scot", 'p', pac_u->imp_y); c3_c* nam_c = u3r_string(nam); - u3l_log("ames: no galaxy domain for %s, no-op\r\n", nam_c); + u3l_log("ames: no galaxy domain for %s, no-op", nam_c); c3_free(nam_c); u3z(nam); @@ -662,7 +662,7 @@ _ames_czar(u3_pact* pac_u) } if ( 255 <= sas_i ) { - u3l_log("ames: czar: galaxy domain %s truncated\n", sam_u->dns_c); + u3l_log("ames: czar: galaxy domain %s truncated", sam_u->dns_c); _ames_pact_free(pac_u); return; } @@ -675,7 +675,7 @@ _ames_czar(u3_pact* pac_u) _ames_czar_cb, pac_u->dns_c, 0, 0)) ) { - u3l_log("ames: %s\n", uv_strerror(sas_i)); + u3l_log("ames: %s", uv_strerror(sas_i)); _ames_czar_gone(pac_u, now); return; } @@ -690,7 +690,7 @@ static void _ames_ef_send(u3_ames* sam_u, u3_noun lan, u3_noun pac) { if ( c3n == sam_u->car_u.liv_o ) { - u3l_log("ames: not yet live, dropping outbound\r\n"); + u3l_log("ames: not yet live, dropping outbound"); u3z(lan); u3z(pac); return; } @@ -752,7 +752,7 @@ _ames_cap_queue(u3_ames* sam_u) sam_u->sat_u.dop_d++; if ( u3C.wag_w & u3o_verbose ) { - u3l_log("ames: packet dropped (%" PRIu64 " total)\n", sam_u->sat_u.dop_d); + u3l_log("ames: packet dropped (%" PRIu64 " total)", sam_u->sat_u.dop_d); } } @@ -762,7 +762,7 @@ _ames_cap_queue(u3_ames* sam_u) if ( (sam_u->sat_u.dop_d && (0 == (sam_u->sat_u.dop_d % 1000))) && !(u3C.wag_w & u3o_verbose) ) { - u3l_log("ames: packet dropped (%" PRIu64 " total)\n", sam_u->sat_u.dop_d); + u3l_log("ames: packet dropped (%" PRIu64 " total)", sam_u->sat_u.dop_d); } } @@ -780,7 +780,7 @@ _ames_punt_goof(u3_noun lud) c3_w len_w = 1; while ( u3_nul != dul ) { - u3l_log("ames: bail %u\r\n", len_w++); + u3l_log("ames: bail %u", len_w++); u3_pier_punt_goof("ames", u3k(u3h(dul))); dul = u3t(dul); } @@ -801,13 +801,13 @@ _ames_hear_bail(u3_ovum* egg_u, u3_noun lud) || (0 == (sam_u->sat_u.fal_d % 1000)) ) { _ames_punt_goof(lud); - u3l_log("ames: packet failed (%" PRIu64 " total)\n\n", sam_u->sat_u.fal_d); + u3l_log("ames: packet failed (%" PRIu64 " total)", sam_u->sat_u.fal_d); } else { u3z(lud); if ( 0 == (sam_u->sat_u.fal_d % 1000) ) { - u3l_log("ames: packet failed (%" PRIu64 " total)\n\n", sam_u->sat_u.fal_d); + u3l_log("ames: packet failed (%" PRIu64 " total)", sam_u->sat_u.fal_d); } } @@ -841,7 +841,7 @@ _ames_forward(u3_panc* pac_u, u3_noun las) sam_u->sat_u.fow_d++; if ( 0 == (sam_u->sat_u.fow_d % 1000000) ) { - u3l_log("ames: forwarded %" PRIu64 " total\n", sam_u->sat_u.fow_d); + u3l_log("ames: forwarded %" PRIu64 " total", sam_u->sat_u.fow_d); } if ( u3C.wag_w & u3o_verbose ) { @@ -851,7 +851,7 @@ _ames_forward(u3_panc* pac_u, u3_noun las) c3_c* rec_c = u3r_string(rec); c3_y* pip_y = (c3_y*)&pac_u->ore_u.pip_w; - u3l_log("ames: forwarding for %s to %s from %d.%d.%d.%d:%d\n", + u3l_log("ames: forwarding for %s to %s from %d.%d.%d.%d:%d", sen_c, rec_c, pip_y[0], pip_y[1], pip_y[2], pip_y[3], pac_u->ore_u.por_s); @@ -870,7 +870,7 @@ _ames_forward(u3_panc* pac_u, u3_noun las) // validate lane and skip self if galaxy // if ( c3n == u3r_cell(lan, &tag, &dat) ) { - u3l_log("ames: bogus lane\n"); + u3l_log("ames: bogus lane"); u3m_p("lan", lan); } else { @@ -885,7 +885,7 @@ _ames_forward(u3_panc* pac_u, u3_noun las) { sen_o = c3n; if ( u3C.wag_w & u3o_verbose ) { - u3l_log("ames: forward skipping self\n"); + u3l_log("ames: forward skipping self"); } } } @@ -918,7 +918,7 @@ _ames_lane_scry_cb(void* vod_p, u3_noun nun) // if ( u3_none == las ) { if ( 5 < ++sam_u->sat_u.saw_d ) { - u3l_log("ames: giving up scry\n"); + u3l_log("ames: giving up scry"); sam_u->fig_u.see_o = c3n; } _ames_put_packet(sam_u, _ames_serialize_packet(pac_u, c3n), pac_u->ore_u); @@ -982,7 +982,7 @@ _ames_try_forward(u3_ames* sam_u, if ( (u3_none == lac) && (1000 < sam_u->sat_u.foq_d) ) { sam_u->sat_u.fod_d++; if ( 0 == (sam_u->sat_u.fod_d % 10000) ) { - u3l_log("ames: dropped %" PRIu64 " forwards total\n", + u3l_log("ames: dropped %" PRIu64 " forwards total", sam_u->sat_u.fod_d); } @@ -1067,7 +1067,7 @@ _ames_hear(u3_ames* sam_u, { sam_u->sat_u.hed_d++; if ( 0 == (sam_u->sat_u.hed_d % 100000) ) { - u3l_log("ames: %" PRIu64 " dropped, failed to read header\n", + u3l_log("ames: %" PRIu64 " dropped, failed to read header", sam_u->sat_u.hed_d); } @@ -1084,7 +1084,7 @@ _ames_hear(u3_ames* sam_u, { sam_u->sat_u.vet_d++; if ( 0 == (sam_u->sat_u.vet_d % 100000) ) { - u3l_log("ames: %" PRIu64 " dropped for version mismatch\n", + u3l_log("ames: %" PRIu64 " dropped for version mismatch", sam_u->sat_u.vet_d); } @@ -1101,7 +1101,7 @@ _ames_hear(u3_ames* sam_u, if ( (c3n == _ames_sift_body(&hed_u, &bod_u, bod_w, bod_y)) ) { sam_u->sat_u.bod_d++; if ( 0 == (sam_u->sat_u.bod_d % 100) ) { - u3l_log("ames: %" PRIu64 " dropped, failed to read body\n", + u3l_log("ames: %" PRIu64 " dropped, failed to read body", sam_u->sat_u.bod_d); } @@ -1114,7 +1114,7 @@ _ames_hear(u3_ames* sam_u, if ( bod_u.mug_l != hed_u.mug_l ) { sam_u->sat_u.mut_d++; if ( 0 == (sam_u->sat_u.mut_d % 100000) ) { - u3l_log("ames: %" PRIu64 " dropped for invalid mug\n", + u3l_log("ames: %" PRIu64 " dropped for invalid mug", sam_u->sat_u.mut_d); } @@ -1153,7 +1153,7 @@ _ames_recv_cb(uv_udp_t* wax_u, { if ( 0 > nrd_i ) { if ( u3C.wag_w & u3o_verbose ) { - u3l_log("ames: recv: fail: %s\n", uv_strerror(nrd_i)); + u3l_log("ames: recv: fail: %s", uv_strerror(nrd_i)); } c3_free(buf_u->base); } @@ -1162,7 +1162,7 @@ _ames_recv_cb(uv_udp_t* wax_u, } else if ( flg_i & UV_UDP_PARTIAL ) { if ( u3C.wag_w & u3o_verbose ) { - u3l_log("ames: recv: fail: message truncated\n"); + u3l_log("ames: recv: fail: message truncated"); } c3_free(buf_u->base); } @@ -1198,8 +1198,8 @@ _ames_io_start(u3_ames* sam_u) por_s = zar_s; } else if ( por_s != zar_s ) { - u3l_log("ames: czar: overriding port %d with -p %d\n", zar_s, por_s); - u3l_log("ames: czar: WARNING: %d required for discoverability\n", zar_s); + u3l_log("ames: czar: overriding port %d with -p %d", zar_s, por_s); + u3l_log("ames: czar: WARNING: %d required for discoverability", zar_s); } } @@ -1218,12 +1218,12 @@ _ames_io_start(u3_ames* sam_u) if ( (ret_i = uv_udp_bind(&sam_u->wax_u, (const struct sockaddr*)&add_u, 0)) != 0 ) { - u3l_log("ames: bind: %s\n", uv_strerror(ret_i)); + u3l_log("ames: bind: %s", uv_strerror(ret_i)); if ( (c3__czar == rac) && (UV_EADDRINUSE == ret_i) ) { - u3l_log(" ...perhaps you've got two copies of vere running?\n"); + u3l_log(" ...perhaps you've got two copies of vere running?"); } // XX revise @@ -1238,10 +1238,10 @@ _ames_io_start(u3_ames* sam_u) } if ( c3y == u3_Host.ops_u.net ) { - u3l_log("ames: live on %d\n", sam_u->pir_u->por_s); + u3l_log("ames: live on %d", sam_u->pir_u->por_s); } else { - u3l_log("ames: live on %d (localhost only)\n", sam_u->pir_u->por_s); + u3l_log("ames: live on %d (localhost only)", sam_u->pir_u->por_s); } uv_udp_recv_start(&sam_u->wax_u, _ames_alloc, _ames_recv_cb); @@ -1272,7 +1272,7 @@ _ames_ef_turf(u3_ames* sam_u, u3_noun tuf) u3z(tuf); } else if ( (c3n == sam_u->pir_u->fak_o) && (0 == sam_u->dns_c) ) { - u3l_log("ames: turf: no domains\n"); + u3l_log("ames: turf: no domains"); } // XX is this ever necessary? @@ -1416,7 +1416,7 @@ _ames_io_kick(u3_auto* car_u, u3_noun wir, u3_noun cad) ret_o = c3n; } else { - u3l_log("kick: strange send\r\n"); + u3l_log("kick: strange send"); ret_o = _ames_kick_newt(sam_u, u3k(tag), u3k(dat)); } } break; @@ -1467,21 +1467,21 @@ _ames_io_info(u3_auto* car_u) # define FLAG(a) ( (c3y == a) ? "&" : "|" ) - u3l_log(" config:\n"); - u3l_log(" filtering: %s\n", FLAG(sam_u->fig_u.fit_o)); - u3l_log(" can send: %s\n", FLAG(sam_u->fig_u.net_o)); - u3l_log(" can scry: %s\n", FLAG(sam_u->fig_u.see_o)); - u3l_log(" counters:\n"); - u3l_log(" dropped: %" PRIu64 "\n", sam_u->sat_u.dop_d); - u3l_log(" forwards dropped: %" PRIu64 "\n", sam_u->sat_u.fod_d); - u3l_log(" forwards pending: %" PRIu64 "\n", sam_u->sat_u.foq_d); - u3l_log(" forwarded: %" PRIu64 "\n", sam_u->sat_u.fow_d); - u3l_log(" filtered (hed): %" PRIu64 "\n", sam_u->sat_u.hed_d); - u3l_log(" filtered (ver): %" PRIu64 "\n", sam_u->sat_u.vet_d); - u3l_log(" filtered (mug): %" PRIu64 "\n", sam_u->sat_u.mut_d); - u3l_log(" filtered (bod): %" PRIu64 "\n", sam_u->sat_u.bod_d); - u3l_log(" crashed: %" PRIu64 "\n", sam_u->sat_u.fal_d); - u3l_log(" cached lanes: %u\n", u3h_wyt(sam_u->lax_p)); + u3l_log(" config:"); + u3l_log(" filtering: %s", FLAG(sam_u->fig_u.fit_o)); + u3l_log(" can send: %s", FLAG(sam_u->fig_u.net_o)); + u3l_log(" can scry: %s", FLAG(sam_u->fig_u.see_o)); + u3l_log(" counters:"); + u3l_log(" dropped: %" PRIu64, sam_u->sat_u.dop_d); + u3l_log(" forwards dropped: %" PRIu64, sam_u->sat_u.fod_d); + u3l_log(" forwards pending: %" PRIu64, sam_u->sat_u.foq_d); + u3l_log(" forwarded: %" PRIu64, sam_u->sat_u.fow_d); + u3l_log(" filtered (hed): %" PRIu64, sam_u->sat_u.hed_d); + u3l_log(" filtered (ver): %" PRIu64, sam_u->sat_u.vet_d); + u3l_log(" filtered (mug): %" PRIu64, sam_u->sat_u.mut_d); + u3l_log(" filtered (bod): %" PRIu64, sam_u->sat_u.bod_d); + u3l_log(" crashed: %" PRIu64, sam_u->sat_u.fal_d); + u3l_log(" cached lanes: %u", u3h_wyt(sam_u->lax_p)); } /* u3_ames_io_init(): initialize ames I/O. diff --git a/pkg/urbit/vere/io/behn.c b/pkg/urbit/vere/io/behn.c index a6a7b0736f..3ae0e739eb 100644 --- a/pkg/urbit/vere/io/behn.c +++ b/pkg/urbit/vere/io/behn.c @@ -55,7 +55,7 @@ _behn_wake_bail(u3_ovum* egg_u, u3_noun lud) u3_auto_bail_slog(egg_u, lud); u3_ovum_free(egg_u); - u3l_log("behn: timer failed; queue blocked\n"); + u3l_log("behn: timer failed; queue blocked"); // XX review, add flag to continue? // @@ -156,7 +156,7 @@ _behn_born_bail(u3_ovum* egg_u, u3_noun lud) u3_auto_bail_slog(egg_u, lud); u3_ovum_free(egg_u); - u3l_log("behn: initialization failed\n"); + u3l_log("behn: initialization failed"); // XX review, add flag to continue? // diff --git a/pkg/urbit/vere/io/cttp.c b/pkg/urbit/vere/io/cttp.c index 0d0fbb1bae..2a4d36a5c2 100644 --- a/pkg/urbit/vere/io/cttp.c +++ b/pkg/urbit/vere/io/cttp.c @@ -562,7 +562,7 @@ _cttp_creq_new(u3_cttp* ctp_u, c3_l num_l, u3_noun hes) // Parse the url out of the new style url passed to us. u3_noun unit_pul = u3do("de-purl:html", u3k(url)); if (c3n == u3r_du(unit_pul)) { - u3l_log("cttp: url parsing failed\n"); + u3l_log("cttp: url parsing failed"); u3z(hes); return 0; } @@ -737,7 +737,7 @@ _cttp_creq_fail(u3_creq* ceq_u, const c3_c* err_c) // XX anything other than a 504? c3_w cod_w = 504; - u3l_log("http: fail (%d, %d): %s\r\n", ceq_u->num_l, cod_w, err_c); + u3l_log("http: fail (%d, %d): %s", ceq_u->num_l, cod_w, err_c); // XX include err_c as response body? _cttp_http_client_receive(ceq_u, cod_w, u3_nul, u3_nul); @@ -973,7 +973,7 @@ _cttp_ef_http_client(u3_cttp* ctp_u, u3_noun tag, u3_noun dat) if ( (c3n == u3r_cell(dat, &num, &req)) || (c3n == u3r_safe_word(num, &num_l)) ) { - u3l_log("cttp: strange request\n"); + u3l_log("cttp: strange request"); ret_o = c3n; } else if ( (ceq_u = _cttp_creq_new(ctp_u, num_l, u3k(req))) ) { @@ -981,7 +981,7 @@ _cttp_ef_http_client(u3_cttp* ctp_u, u3_noun tag, u3_noun dat) ret_o = c3y; } else { - u3l_log("cttp: strange request (unparsable url)\n"); + u3l_log("cttp: strange request (unparsable url)"); ret_o = c3n; } } @@ -989,7 +989,7 @@ _cttp_ef_http_client(u3_cttp* ctp_u, u3_noun tag, u3_noun dat) c3_l num_l; if ( c3n == u3r_safe_word(dat, &num_l) ) { - u3l_log("cttp: strange cancel-request\n"); + u3l_log("cttp: strange cancel-request"); ret_o = c3n; } else if ( (ceq_u =_cttp_creq_find(ctp_u, num_l)) ) { @@ -1003,7 +1003,7 @@ _cttp_ef_http_client(u3_cttp* ctp_u, u3_noun tag, u3_noun dat) } } else { - u3l_log("cttp: strange effect (unknown type)\n"); + u3l_log("cttp: strange effect (unknown type)"); ret_o = c3n; } diff --git a/pkg/urbit/vere/io/fore.c b/pkg/urbit/vere/io/fore.c index cb46fd187d..19868084ca 100644 --- a/pkg/urbit/vere/io/fore.c +++ b/pkg/urbit/vere/io/fore.c @@ -17,7 +17,7 @@ static void _fore_inject_bail(u3_ovum* egg_u, u3_noun lud) { u3_auto_bail_slog(egg_u, lud); - u3l_log("pier: injected event failed\n"); + u3l_log("pier: injected event failed"); u3_ovum_free(egg_u); } @@ -28,7 +28,7 @@ static void _fore_import_bail(u3_ovum* egg_u, u3_noun lud) { u3_auto_bail_slog(egg_u, lud); - u3l_log("pier: import failed\n"); + u3l_log("pier: import failed"); u3_ovum_free(egg_u); } @@ -44,20 +44,20 @@ _fore_inject(u3_auto* car_u, c3_c* pax_c) u3_noun riw, cad, tar, wir; if ( c3n == u3r_cell(ovo, &riw, &cad) ) { - u3l_log("pier: invalid ovum in -I\n"); + u3l_log("pier: invalid ovum in -I"); } else if ( (c3n == u3a_is_cell(cad)) || (c3n == u3a_is_atom(u3h(cad))) ) { - u3l_log("pier: invalid card in -I ovum\n"); + u3l_log("pier: invalid card in -I ovum"); } else if ( c3n == u3r_cell(riw, &tar, &wir) ) { - u3l_log("pier: invalid wire in -I ovum\n"); + u3l_log("pier: invalid wire in -I ovum"); } else if ( (c3n == u3a_is_atom(tar)) || (1 < u3r_met(3, tar)) ) { - u3l_log("pier: invalid target in -I wire\n"); + u3l_log("pier: invalid target in -I wire"); } else { { @@ -65,7 +65,7 @@ _fore_inject(u3_auto* car_u, c3_c* pax_c) u3_noun ser = u3do("spat", u3k(riw)); c3_c* wir_c = u3r_string(ser); - u3l_log("pier: injecting %%%s event on %s\n", tag_c, wir_c); + u3l_log("pier: injecting %%%s event on %s", tag_c, wir_c); c3_free(tag_c); c3_free(wir_c); diff --git a/pkg/urbit/vere/io/hind.c b/pkg/urbit/vere/io/hind.c index b8b1577ee6..62a6fea3ae 100644 --- a/pkg/urbit/vere/io/hind.c +++ b/pkg/urbit/vere/io/hind.c @@ -37,7 +37,7 @@ _hind_io_kick(u3_auto* car_u, u3_noun wir, u3_noun cad) case c3__exit: { ret_o = c3y; - u3l_log("<<>>\n"); + u3l_log("<<>>"); u3_pier_exit(car_u->pir_u); } break; @@ -51,7 +51,7 @@ _hind_io_kick(u3_auto* car_u, u3_noun wir, u3_noun cad) case c3__vega: { ret_o = c3y; - u3l_log("<<>>\n"); + u3l_log("<<>>"); } break; // NB: startup explicitly handled in pier.c diff --git a/pkg/urbit/vere/io/http.c b/pkg/urbit/vere/io/http.c index 229584cd94..973e0c763d 100644 --- a/pkg/urbit/vere/io/http.c +++ b/pkg/urbit/vere/io/http.c @@ -648,10 +648,10 @@ _http_start_respond(u3_hreq* req_u, u3_noun data, u3_noun complete) { - // u3l_log("start\n"); + // u3l_log("start"); if ( u3_rsat_plan != req_u->sat_e ) { - //u3l_log("duplicate response\n"); + //u3l_log("duplicate response"); return; } @@ -724,14 +724,14 @@ _http_continue_respond(u3_hreq* req_u, u3_noun data, u3_noun complete) { - // u3l_log("continue\n"); + // u3l_log("continue"); // XX add sequence numbers for %continue effects? // Arvo does not (currently) guarantee effect idempotence!! // response has not yet been started if ( u3_rsat_ripe != req_u->sat_e ) { - // u3l_log("duplicate response\n"); + // u3l_log("duplicate response"); return; } @@ -864,7 +864,7 @@ _http_seq_continue(void* vod_p, u3_noun nun) _http_start_respond(req_u, 403, u3_nul, u3_nul, c3y); } else if ( u3_none == aut ) { - u3l_log("http: authentication scry failed\n"); + u3l_log("http: authentication scry failed"); _http_start_respond(req_u, 500, u3_nul, u3_nul, c3y); } else { @@ -926,7 +926,7 @@ _http_rec_accept(h2o_handler_t* han_u, h2o_req_t* rec_u) if ( u3_none == req ) { if ( (u3C.wag_w & u3o_verbose) ) { - u3l_log("strange %.*s request\n", (int)rec_u->method.len, + u3l_log("strange %.*s request", (int)rec_u->method.len, rec_u->method.base); } c3_c* msg_c = "bad request"; @@ -1016,7 +1016,7 @@ _http_conn_free(uv_handle_t* han_t) noh_u = noh_u->nex_u; } - u3l_log("http conn free %d of %u server %d\n", hon_u->coq_l, len_w, htp_u->sev_l); + u3l_log("http conn free %d of %u server %d", hon_u->coq_l, len_w, htp_u->sev_l); } #endif @@ -1033,13 +1033,13 @@ _http_conn_free(uv_handle_t* han_t) noh_u = noh_u->nex_u; } - u3l_log("http conn free %u remaining\n", len_w); + u3l_log("http conn free %u remaining", len_w); } #endif if ( (0 == htp_u->hon_u) && (0 != h2o_u->ctx_u.shutdown_requested) ) { #if 0 - u3l_log("http conn free %d free server %d\n", hon_u->coq_l, htp_u->sev_l); + u3l_log("http conn free %d free server %d", hon_u->coq_l, htp_u->sev_l); #endif _http_serv_free(htp_u); } @@ -1063,7 +1063,7 @@ _http_conn_new(u3_http* htp_u) _http_conn_link(htp_u, hon_u); #if 0 - u3l_log("http conn neww %d server %d\n", hon_u->coq_l, htp_u->sev_l); + u3l_log("http conn neww %d server %d", hon_u->coq_l, htp_u->sev_l); #endif return hon_u; @@ -1113,7 +1113,7 @@ _http_serv_unlink(u3_http* htp_u) { // XX link elsewhere initially, relink on start? #if 0 - u3l_log("http serv unlink %d\n", htp_u->sev_l); + u3l_log("http serv unlink %d", htp_u->sev_l); #endif u3_http* pre_u = htp_u->htd_u->htp_u; @@ -1222,7 +1222,7 @@ http_serv_free_cb(uv_timer_t* tim_u) u3_http* htp_u = tim_u->data; #if 0 - u3l_log("http serv free cb %d\n", htp_u->sev_l); + u3l_log("http serv free cb %d", htp_u->sev_l); #endif _http_serv_really_free(htp_u); @@ -1236,7 +1236,7 @@ static void _http_serv_free(u3_http* htp_u) { #if 0 - u3l_log("http serv free %d\n", htp_u->sev_l); + u3l_log("http serv free %d", htp_u->sev_l); #endif c3_assert( 0 == htp_u->hon_u ); @@ -1306,7 +1306,7 @@ _http_serv_close(u3_http* htp_u) h2o_context_request_shutdown(&h2o_u->ctx_u); #if 0 - u3l_log("http serv close %d %p\n", htp_u->sev_l, &htp_u->wax_u); + u3l_log("http serv close %d %p", htp_u->sev_l, &htp_u->wax_u); #endif uv_close((uv_handle_t*)&htp_u->wax_u, _http_serv_close_cb); @@ -1347,7 +1347,7 @@ _http_serv_accept(u3_http* htp_u) if ( 0 != (sas_i = uv_accept((uv_stream_t*)&htp_u->wax_u, (uv_stream_t*)&hon_u->wax_u)) ) { if ( (u3C.wag_w & u3o_verbose) ) { - u3l_log("http: accept: %s\n", uv_strerror(sas_i)); + u3l_log("http: accept: %s", uv_strerror(sas_i)); } uv_close((uv_handle_t*)&hon_u->wax_u, _http_conn_free); @@ -1376,7 +1376,7 @@ _http_serv_listen_cb(uv_stream_t* str_u, c3_i sas_i) u3_http* htp_u = (u3_http*)str_u; if ( 0 != sas_i ) { - u3l_log("http: listen_cb: %s\n", uv_strerror(sas_i)); + u3l_log("http: listen_cb: %s", uv_strerror(sas_i)); } else { _http_serv_accept(htp_u); @@ -1494,13 +1494,13 @@ _http_serv_start(u3_http* htp_u) continue; } - u3l_log("http: listen: %s\n", uv_strerror(sas_i)); + u3l_log("http: listen: %s", uv_strerror(sas_i)); _http_serv_free(htp_u); return; } - u3l_log("http: %s live on %s://localhost:%d\n", + u3l_log("http: %s live on %s://localhost:%d", (c3y == htp_u->lop) ? "loopback" : "web interface", (c3y == htp_u->sec) ? "https" : "http", htp_u->por_s); @@ -1558,7 +1558,7 @@ _http_init_tls(uv_buf_t key_u, uv_buf_t cer_u) BIO_free(bio_u); if( 0 == sas_i ) { - u3l_log("http: load private key failed:\n"); + u3l_log("http: load private key failed:"); ERR_print_errors_fp(u3_term_io_hija()); u3_term_io_loja(1); @@ -1576,7 +1576,7 @@ _http_init_tls(uv_buf_t key_u, uv_buf_t cer_u) X509_free(xer_u); if( 0 == sas_i ) { - u3l_log("http: load certificate failed:\n"); + u3l_log("http: load certificate failed:"); ERR_print_errors_fp(u3_term_io_hija()); u3_term_io_loja(1); @@ -1656,19 +1656,19 @@ _http_search_req(u3_httd* htd_u, if ( !(htp_u = _http_serv_find(htd_u, sev_l)) ) { if ( bug_w ) { - u3l_log("http: server not found: %x\r\n", sev_l); + u3l_log("http: server not found: %x", sev_l); } return 0; } else if ( !(hon_u = _http_conn_find(htp_u, coq_l)) ) { if ( bug_w ) { - u3l_log("http: connection not found: %x/%d\r\n", sev_l, coq_l); + u3l_log("http: connection not found: %x/%d", sev_l, coq_l); } return 0; } else if ( !(req_u = _http_req_find(hon_u, seq_l)) ) { if ( bug_w ) { - u3l_log("http: request not found: %x/%d/%d\r\n", + u3l_log("http: request not found: %x/%d/%d", sev_l, coq_l, seq_l); } return 0; @@ -1760,7 +1760,7 @@ _http_serv_restart(u3_httd* htd_u) _http_serv_start_all(htd_u); } else { - u3l_log("http: restarting servers to apply configuration\n"); + u3l_log("http: restarting servers to apply configuration"); while ( 0 != htp_u ) { if ( c3y == htp_u->liv ) { @@ -1812,7 +1812,7 @@ u3_http_ef_form(u3_httd* htd_u, u3_noun fig) !( c3y == pro || c3n == pro ) || !( c3y == log || c3n == log ) || !( c3y == red || c3n == red ) ) { - u3l_log("http: form: invalid card\n"); + u3l_log("http: form: invalid card"); u3z(fig); return; } @@ -1907,14 +1907,14 @@ _http_ef_http_server(u3_httd* htd_u, _http_continue_respond(req_u, u3k(data), u3k(complete)); } else if (c3y == u3r_sing_c("cancel", u3h(response))) { - u3l_log("http: %%cancel not handled yet\n"); + u3l_log("http: %%cancel not handled yet"); } else { - u3l_log("http: strange response\n"); + u3l_log("http: strange response"); } } else { - u3l_log("http: strange response\n"); + u3l_log("http: strange response"); } } @@ -2028,7 +2028,7 @@ _reck_mole(u3_noun fot, if ( (c3n == u3r_cell(uco, &p_uco, &q_uco)) || (u3_nul != p_uco) ) { - u3l_log("strange mole %s\n", u3r_string(san)); + u3l_log("strange mole %s", u3r_string(san)); u3z(fot); u3z(uco); return c3n; } @@ -2166,7 +2166,7 @@ _http_io_info(u3_auto* car_u) sec_y++; seq_u = seq_u->nex_u; } - u3l_log(" open slogstreams: %d\n", sec_y); + u3l_log(" open slogstreams: %d", sec_y); } /* u3_http_io_init(): initialize http I/O. diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index 5dc3663bc0..47481f7de4 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -330,7 +330,7 @@ _term_it_write_cb(uv_write_t* wri_u, c3_i sas_i) // write failure is logged, but otherwise ignored. // if ( 0 != sas_i ) { - u3l_log("term: write: %s\n", uv_strerror(sas_i)); + u3l_log("term: write: %s", uv_strerror(sas_i)); } c3_free(wri_u->data); @@ -382,7 +382,7 @@ _term_it_write(u3_utty* uty_u, // synchronous write failure is logged, but otherwise ignored // if ( ret_i < 0 ) { - u3l_log("term: write: %s\n", uv_strerror(ret_i)); + u3l_log("term: write: %s", uv_strerror(ret_i)); } c3_free(ptr_v); @@ -837,14 +837,14 @@ _term_suck(u3_utty* uty_u, const c3_y* buf, ssize_t siz_i) // The process hangs if we do nothing (and ctrl-z // then corrupts the event log), so we force shutdown. // - u3l_log("term: hangup (EOF)\r\n"); + u3l_log("term: hangup (EOF)"); // XX revise // u3_pier_bail(u3_king_stub()); } else if ( siz_i < 0 ) { - u3l_log("term %d: read: %s\n", uty_u->tid_l, uv_strerror(siz_i)); + u3l_log("term %d: read: %s", uty_u->tid_l, uv_strerror(siz_i)); } else { c3_i i; @@ -1688,7 +1688,7 @@ _term_io_kick(u3_auto* car_u, u3_noun wir, u3_noun cad) || (u3_nul != q_pud) || (c3n == _reck_orchid(c3__ud, u3k(p_pud), &tid_l)) ) { - u3l_log("term: bad tire\n"); + u3l_log("term: bad tire"); ret_o = c3n; } else { @@ -1709,8 +1709,8 @@ _term_io_kick(u3_auto* car_u, u3_noun wir, u3_noun cad) { u3_utty* uty_u = _term_ef_get(tid_l); if ( 0 == uty_u ) { - // u3l_log("no terminal %d\n", tid_l); - // u3l_log("uty_u %p\n", u3_Host.uty_u); + // u3l_log("no terminal %d", tid_l); + // u3l_log("uty_u %p", u3_Host.uty_u); } else { u3_noun bis = dat; diff --git a/pkg/urbit/vere/io/unix.c b/pkg/urbit/vere/io/unix.c index ec07e53a54..efd903f15b 100644 --- a/pkg/urbit/vere/io/unix.c +++ b/pkg/urbit/vere/io/unix.c @@ -171,35 +171,35 @@ _unix_rm_r_cb(const c3_c* pax_c, { switch ( typeflag ) { default: - u3l_log("bad file type in rm_r: %s\r\n", pax_c); + u3l_log("bad file type in rm_r: %s", pax_c); break; case FTW_F: if ( 0 != unlink(pax_c) && ENOENT != errno ) { - u3l_log("error unlinking (in rm_r) %s: %s\n", + u3l_log("error unlinking (in rm_r) %s: %s", pax_c, strerror(errno)); c3_assert(0); } break; case FTW_D: - u3l_log("shouldn't have gotten pure directory: %s\r\n", pax_c); + u3l_log("shouldn't have gotten pure directory: %s", pax_c); break; case FTW_DNR: - u3l_log("couldn't read directory: %s\r\n", pax_c); + u3l_log("couldn't read directory: %s", pax_c); break; case FTW_NS: - u3l_log("couldn't stat path: %s\r\n", pax_c); + u3l_log("couldn't stat path: %s", pax_c); break; case FTW_DP: if ( 0 != rmdir(pax_c) && ENOENT != errno ) { - u3l_log("error rmdiring %s: %s\n", pax_c, strerror(errno)); + u3l_log("error rmdiring %s: %s", pax_c, strerror(errno)); c3_assert(0); } break; case FTW_SL: - u3l_log("got symbolic link: %s\r\n", pax_c); + u3l_log("got symbolic link: %s", pax_c); break; case FTW_SLN: - u3l_log("got nonexistent symbolic link: %s\r\n", pax_c); + u3l_log("got nonexistent symbolic link: %s", pax_c); break; } @@ -213,7 +213,7 @@ _unix_rm_r(c3_c* pax_c) { if ( 0 > nftw(pax_c, _unix_rm_r_cb, 100, FTW_DEPTH | FTW_PHYS ) && ENOENT != errno) { - u3l_log("rm_r error on %s: %s\r\n", pax_c, strerror(errno)); + u3l_log("rm_r error on %s: %s", pax_c, strerror(errno)); } } @@ -223,7 +223,7 @@ static void _unix_mkdir(c3_c* pax_c) { if ( 0 != mkdir(pax_c, 0755) && EEXIST != errno) { - u3l_log("error mkdiring %s: %s\n", pax_c, strerror(errno)); + u3l_log("error mkdiring %s: %s", pax_c, strerror(errno)); c3_assert(0); } } @@ -240,7 +240,7 @@ _unix_write_file_hard(c3_c* pax_c, u3_noun mim) u3_noun dat = u3t(u3t(mim)); if ( fid_i < 0 ) { - u3l_log("error opening %s for writing: %s\r\n", + u3l_log("error opening %s for writing: %s", pax_c, strerror(errno)); u3z(mim); return 0; @@ -256,7 +256,7 @@ _unix_write_file_hard(c3_c* pax_c, u3_noun mim) rit_w = write(fid_i, dat_y, siz_w); if ( rit_w != siz_w ) { - u3l_log("error writing %s: %s\r\n", + u3l_log("error writing %s: %s", pax_c, strerror(errno)); mug_w = 0; } @@ -286,7 +286,7 @@ _unix_write_file_soft(u3_ufil* fil_u, u3_noun mim) goto _unix_write_file_soft_go; } else { - u3l_log("error opening file (soft) %s: %s\r\n", + u3l_log("error opening file (soft) %s: %s", fil_u->pax_c, strerror(errno)); u3z(mim); return; @@ -299,17 +299,17 @@ _unix_write_file_soft(u3_ufil* fil_u, u3_noun mim) red_ws = read(fid_i, old_y, len_ws); if ( close(fid_i) < 0 ) { - u3l_log("error closing file (soft) %s: %s\r\n", + u3l_log("error closing file (soft) %s: %s", fil_u->pax_c, strerror(errno)); } if ( len_ws != red_ws ) { if ( red_ws < 0 ) { - u3l_log("error reading file (soft) %s: %s\r\n", + u3l_log("error reading file (soft) %s: %s", fil_u->pax_c, strerror(errno)); } else { - u3l_log("wrong # of bytes read in file %s: %d %d\r\n", + u3l_log("wrong # of bytes read in file %s: %d %d", fil_u->pax_c, len_ws, red_ws); } c3_free(old_y); @@ -385,7 +385,7 @@ _unix_scan_mount_point(u3_unix* unx_u, u3_umon* mon_u) { DIR* rid_u = opendir(mon_u->dir_u.pax_c); if ( !rid_u ) { - u3l_log("error opening pier directory: %s: %s\r\n", + u3l_log("error opening pier directory: %s: %s", mon_u->dir_u.pax_c, strerror(errno)); return; } @@ -398,7 +398,7 @@ _unix_scan_mount_point(u3_unix* unx_u, u3_umon* mon_u) c3_w err_w; if ( 0 != (err_w = u3_readdir_r(rid_u, &ent_u, &out_u)) ) { - u3l_log("erroring loading pier directory %s: %s\r\n", + u3l_log("erroring loading pier directory %s: %s", mon_u->dir_u.pax_c, strerror(errno)); c3_assert(0); @@ -418,7 +418,7 @@ _unix_scan_mount_point(u3_unix* unx_u, u3_umon* mon_u) struct stat buf_u; if ( 0 != stat(pax_c, &buf_u) ) { - u3l_log("can't stat pier directory %s: %s\r\n", + u3l_log("can't stat pier directory %s: %s", mon_u->dir_u.pax_c, strerror(errno)); c3_free(pax_c); continue; @@ -462,7 +462,7 @@ static void _unix_free_file(u3_ufil *fil_u) { if ( 0 != unlink(fil_u->pax_c) && ENOENT != errno ) { - u3l_log("error unlinking %s: %s\n", fil_u->pax_c, strerror(errno)); + u3l_log("error unlinking %s: %s", fil_u->pax_c, strerror(errno)); c3_assert(0); } @@ -574,7 +574,7 @@ _unix_delete_mount_point(u3_unix* unx_u, u3_noun mon) mon_u = unx_u->mon_u; if ( !mon_u ) { - u3l_log("mount point already gone: %s\r\n", nam_c); + u3l_log("mount point already gone: %s", nam_c); goto _delete_mount_point_out; } if ( 0 == strcmp(nam_c, mon_u->nam_c) ) { @@ -590,7 +590,7 @@ _unix_delete_mount_point(u3_unix* unx_u, u3_noun mon) } if ( !mon_u->nex_u ) { - u3l_log("mount point already gone: %s\r\n", nam_c); + u3l_log("mount point already gone: %s", nam_c); goto _delete_mount_point_out; } @@ -710,7 +710,7 @@ _unix_update_file(u3_unix* unx_u, u3_ufil* fil_u) return u3nc(u3nc(_unix_string_to_path(unx_u, fil_u->pax_c), u3_nul), u3_nul); } else { - u3l_log("error opening file %s: %s\r\n", + u3l_log("error opening file %s: %s", fil_u->pax_c, strerror(errno)); return u3_nul; } @@ -722,17 +722,17 @@ _unix_update_file(u3_unix* unx_u, u3_ufil* fil_u) red_ws = read(fid_i, dat_y, len_ws); if ( close(fid_i) < 0 ) { - u3l_log("error closing file %s: %s\r\n", + u3l_log("error closing file %s: %s", fil_u->pax_c, strerror(errno)); } if ( len_ws != red_ws ) { if ( red_ws < 0 ) { - u3l_log("error reading file %s: %s\r\n", + u3l_log("error reading file %s: %s", fil_u->pax_c, strerror(errno)); } else { - u3l_log("wrong # of bytes read in file %s: %d %d\r\n", + u3l_log("wrong # of bytes read in file %s: %d %d", fil_u->pax_c, len_ws, red_ws); } c3_free(dat_y); @@ -808,7 +808,7 @@ _unix_update_dir(u3_unix* unx_u, u3_udir* dir_u) if ( (fid_i < 0) || (fstat(fid_i, &buf_u) < 0) ) { if ( ENOENT != errno ) { - u3l_log("_unix_update_dir: error opening file %s: %s\r\n", + u3l_log("_unix_update_dir: error opening file %s: %s", nod_u->pax_c, strerror(errno)); } @@ -818,7 +818,7 @@ _unix_update_dir(u3_unix* unx_u, u3_udir* dir_u) } else { if ( close(fid_i) < 0 ) { - u3l_log("_unix_update_dir: error closing file %s: %s\r\n", + u3l_log("_unix_update_dir: error closing file %s: %s", nod_u->pax_c, strerror(errno)); } @@ -833,7 +833,7 @@ _unix_update_dir(u3_unix* unx_u, u3_udir* dir_u) DIR* rid_u = opendir(dir_u->pax_c); if ( !rid_u ) { - u3l_log("error opening directory %s: %s\r\n", + u3l_log("error opening directory %s: %s", dir_u->pax_c, strerror(errno)); c3_assert(0); } @@ -845,7 +845,7 @@ _unix_update_dir(u3_unix* unx_u, u3_udir* dir_u) if ( (err_w = u3_readdir_r(rid_u, &ent_u, &out_u)) != 0 ) { - u3l_log("error loading directory %s: %s\r\n", + u3l_log("error loading directory %s: %s", dir_u->pax_c, strerror(err_w)); c3_assert(0); } @@ -861,7 +861,7 @@ _unix_update_dir(u3_unix* unx_u, u3_udir* dir_u) struct stat buf_u; if ( 0 != stat(pax_c, &buf_u) ) { - u3l_log("can't stat %s: %s\r\n", pax_c, strerror(errno)); + u3l_log("can't stat %s: %s", pax_c, strerror(errno)); c3_free(pax_c); continue; } @@ -871,13 +871,13 @@ _unix_update_dir(u3_unix* unx_u, u3_udir* dir_u) if ( 0 == strcmp(pax_c, nod_u->pax_c) ) { if ( S_ISDIR(buf_u.st_mode) ) { if ( c3n == nod_u->dir ) { - u3l_log("not a directory: %s\r\n", nod_u->pax_c); + u3l_log("not a directory: %s", nod_u->pax_c); c3_assert(0); } } else { if ( c3y == nod_u->dir ) { - u3l_log("not a file: %s\r\n", nod_u->pax_c); + u3l_log("not a file: %s", nod_u->pax_c); c3_assert(0); } } @@ -912,7 +912,7 @@ _unix_update_dir(u3_unix* unx_u, u3_udir* dir_u) } if ( closedir(rid_u) < 0 ) { - u3l_log("error closing directory %s: %s\r\n", + u3l_log("error closing directory %s: %s", dir_u->pax_c, strerror(errno)); } @@ -983,7 +983,7 @@ _unix_initial_update_file(c3_c* pax_c, c3_c* bas_c) return u3_nul; } else { - u3l_log("error opening initial file %s: %s\r\n", + u3l_log("error opening initial file %s: %s", pax_c, strerror(errno)); return u3_nul; } @@ -995,17 +995,17 @@ _unix_initial_update_file(c3_c* pax_c, c3_c* bas_c) red_ws = read(fid_i, dat_y, len_ws); if ( close(fid_i) < 0 ) { - u3l_log("error closing initial file %s: %s\r\n", + u3l_log("error closing initial file %s: %s", pax_c, strerror(errno)); } if ( len_ws != red_ws ) { if ( red_ws < 0 ) { - u3l_log("error reading initial file %s: %s\r\n", + u3l_log("error reading initial file %s: %s", pax_c, strerror(errno)); } else { - u3l_log("wrong # of bytes read in initial file %s: %d %d\r\n", + u3l_log("wrong # of bytes read in initial file %s: %d %d", pax_c, len_ws, red_ws); } c3_free(dat_y); @@ -1033,7 +1033,7 @@ _unix_initial_update_dir(c3_c* pax_c, c3_c* bas_c) DIR* rid_u = opendir(pax_c); if ( !rid_u ) { - u3l_log("error opening initial directory: %s: %s\r\n", + u3l_log("error opening initial directory: %s: %s", pax_c, strerror(errno)); return u3_nul; } @@ -1044,7 +1044,7 @@ _unix_initial_update_dir(c3_c* pax_c, c3_c* bas_c) c3_w err_w; if ( 0 != (err_w = u3_readdir_r(rid_u, &ent_u, &out_u)) ) { - u3l_log("error loading initial directory %s: %s\r\n", + u3l_log("error loading initial directory %s: %s", pax_c, strerror(errno)); c3_assert(0); @@ -1061,7 +1061,7 @@ _unix_initial_update_dir(c3_c* pax_c, c3_c* bas_c) struct stat buf_u; if ( 0 != stat(pox_c, &buf_u) ) { - u3l_log("initial can't stat %s: %s\r\n", + u3l_log("initial can't stat %s: %s", pox_c, strerror(errno)); c3_free(pox_c); continue; @@ -1079,7 +1079,7 @@ _unix_initial_update_dir(c3_c* pax_c, c3_c* bas_c) } if ( closedir(rid_u) < 0 ) { - u3l_log("error closing initial directory %s: %s\r\n", + u3l_log("error closing initial directory %s: %s", pax_c, strerror(errno)); } @@ -1170,16 +1170,16 @@ _unix_sync_change(u3_unix* unx_u, u3_udir* dir_u, u3_noun pax, u3_noun mim) if ( c3n == u3du(pax) ) { if ( u3_nul == pax ) { - u3l_log("can't sync out file as top-level, strange\r\n"); + u3l_log("can't sync out file as top-level, strange"); } else { - u3l_log("sync out: bad path\r\n"); + u3l_log("sync out: bad path"); } u3z(pax); u3z(mim); return; } else if ( c3n == u3du(u3t(pax)) ) { - u3l_log("can't sync out file as top-level, strangely\r\n"); + u3l_log("can't sync out file as top-level, strangely"); u3z(pax); u3z(mim); } else { @@ -1209,7 +1209,7 @@ _unix_sync_change(u3_unix* unx_u, u3_udir* dir_u, u3_noun pax, u3_noun mim) } if ( c3n == nod_u->dir ) { - u3l_log("weird, we got a file when we weren't expecting to\r\n"); + u3l_log("weird, we got a file when we weren't expecting to"); c3_assert(0); } @@ -1292,7 +1292,7 @@ u3_unix_acquire(c3_c* pax_c) if ( NULL != (loq_u = fopen(paf_c, "r")) ) { if ( 1 != fscanf(loq_u, "%" SCNu32, &pid_w) ) { - u3l_log("lockfile %s is corrupt!\n", paf_c); + u3l_log("lockfile %s is corrupt!", paf_c); kill(getpid(), SIGTERM); sleep(1); c3_assert(0); } @@ -1300,7 +1300,7 @@ u3_unix_acquire(c3_c* pax_c) c3_w i_w; if ( -1 != kill(pid_w, SIGTERM) ) { - u3l_log("unix: stopping process %d, live in %s...\n", + u3l_log("unix: stopping process %d, live in %s...", pid_w, pax_c); for ( i_w = 0; i_w < 16; i_w++ ) { @@ -1318,10 +1318,10 @@ u3_unix_acquire(c3_c* pax_c) } } if ( 16 == i_w ) { - u3l_log("unix: process %d seems unkillable!\n", pid_w); + u3l_log("unix: process %d seems unkillable!", pid_w); c3_assert(0); } - u3l_log("unix: stopped old process %u\n", pid_w); + u3l_log("unix: stopped old process %u", pid_w); } } fclose(loq_u); @@ -1329,7 +1329,7 @@ u3_unix_acquire(c3_c* pax_c) } if ( NULL == (loq_u = fopen(paf_c, "w")) ) { - u3l_log("unix: unable to open %s\n", paf_c); + u3l_log("unix: unable to open %s", paf_c); c3_assert(0); } diff --git a/pkg/urbit/vere/king.c b/pkg/urbit/vere/king.c index fd8ba8c693..3f9d453cc4 100644 --- a/pkg/urbit/vere/king.c +++ b/pkg/urbit/vere/king.c @@ -242,7 +242,7 @@ _king_get_atom(c3_c* url_c) uv_buf_t buf_u = uv_buf_init(c3_malloc(1), 0); if ( !(curl = curl_easy_init()) ) { - u3l_log("failed to initialize libcurl\n"); + u3l_log("failed to initialize libcurl"); exit(1); } @@ -257,13 +257,13 @@ _king_get_atom(c3_c* url_c) // XX retry? // if ( CURLE_OK != result ) { - u3l_log("failed to fetch %s: %s\n", + u3l_log("failed to fetch %s: %s", url_c, curl_easy_strerror(result)); u3_king_bail(); exit(1); } if ( 300 <= cod_l ) { - u3l_log("error fetching %s: HTTP %ld\n", url_c, cod_l); + u3l_log("error fetching %s: HTTP %ld", url_c, cod_l); u3_king_bail(); exit(1); } @@ -289,12 +289,12 @@ _get_cmd_output(c3_c *cmd_c, c3_c *out_c, c3_w len_c) { FILE *fp = popen(cmd_c, "r"); if ( NULL == fp ) { - u3l_log("'%s' failed\n", cmd_c); + u3l_log("'%s' failed", cmd_c); exit(1); } if ( NULL == fgets(out_c, len_c, fp) ) { - u3l_log("'%s' produced no output\n", cmd_c); + u3l_log("'%s' produced no output", cmd_c); exit(1); } @@ -327,7 +327,7 @@ _git_pill_url(c3_c *out_c, c3_c *arv_c) assert(NULL != arv_c); if ( 0 != system("which git >> /dev/null") ) { - u3l_log("boot: could not find git executable\r\n"); + u3l_log("boot: could not find git executable"); exit(1); } @@ -344,7 +344,7 @@ _boothack_pill(void) u3_noun pil; if ( 0 != u3_Host.ops_u.pil_c ) { - u3l_log("boot: loading pill %s\r\n", u3_Host.ops_u.pil_c); + u3l_log("boot: loading pill %s", u3_Host.ops_u.pil_c); pil = u3m_file(u3_Host.ops_u.pil_c); } else { @@ -360,12 +360,12 @@ _boothack_pill(void) strcpy(url_c, u3_Host.ops_u.url_c); } - u3l_log("boot: downloading pill %s\r\n", url_c); + u3l_log("boot: downloading pill %s", url_c); pil = _king_get_atom(url_c); } if ( 0 != u3_Host.ops_u.arv_c ) { - u3l_log("boot: preparing filesystem from %s\r\n", + u3l_log("boot: preparing filesystem from %s", u3_Host.ops_u.arv_c); arv = u3nc(u3_nul, u3_unix_initial_into_card(u3_Host.ops_u.arv_c)); } @@ -385,7 +385,7 @@ _boothack_key(u3_noun kef) if ( u3_nul == des ) { c3_c* kef_c = u3r_string(kef); - u3l_log("dawn: invalid private keys: %s\r\n", kef_c); + u3l_log("dawn: invalid private keys: %s", kef_c); c3_free(kef_c); exit(1); } @@ -394,7 +394,7 @@ _boothack_key(u3_noun kef) // u3_noun pro = u3m_soft(0, u3ke_cue, u3k(u3t(des))); if ( u3_blip != u3h(pro) ) { - u3l_log("dawn: unable to cue private key\r\n"); + u3l_log("dawn: unable to cue private key"); exit(1); } seed = u3k(u3t(pro)); @@ -412,7 +412,7 @@ _boothack_key(u3_noun kef) u3_noun whu = u3dc("slaw", 'p', u3k(woh)); if ( u3_nul == whu ) { - u3l_log("dawn: invalid ship specified with -w %s\r\n", + u3l_log("dawn: invalid ship specified with -w %s", u3_Host.ops_u.who_c); exit(1); } @@ -420,7 +420,7 @@ _boothack_key(u3_noun kef) if ( c3n == u3r_sing(ship, u3t(whu)) ) { u3_noun how = u3dc("scot", 'p', u3k(ship)); c3_c* how_c = u3r_string(u3k(how)); - u3l_log("dawn: mismatch between -w %s and -K %s\r\n", + u3l_log("dawn: mismatch between -w %s and -K %s", u3_Host.ops_u.who_c, how_c); u3z(how); @@ -451,7 +451,7 @@ _boothack_doom(void) u3_noun whu = u3dc("slaw", 'p', u3k(fak)); if ( u3_nul == whu ) { - u3l_log("boot: malformed -F ship %s\r\n", u3_Host.ops_u.fak_c); + u3l_log("boot: malformed -F ship %s", u3_Host.ops_u.fak_c); exit(1); } @@ -485,7 +485,7 @@ _boothack_doom(void) kef = u3i_string(u3_Host.ops_u.gen_c); } else { - u3l_log("boot: must specify a key with -k or -G\r\n"); + u3l_log("boot: must specify a key with -k or -G"); exit(1); } @@ -580,7 +580,7 @@ _king_sign_cb(uv_signal_t* sil_u, c3_i num_i) { switch ( num_i ) { default: { - u3l_log("\r\nmysterious signal %d\r\n", num_i); + u3l_log("\r\nmysterious signal %d", num_i); break; } @@ -590,7 +590,7 @@ _king_sign_cb(uv_signal_t* sil_u, c3_i num_i) } case SIGINT: { - u3l_log("\r\ninterrupt\r\n"); + u3l_log("\r\ninterrupt"); u3_term_ef_ctlc(); break; } @@ -690,7 +690,7 @@ _king_boot_ivory(void) if ( u3_Host.ops_u.lit_c ) { if ( c3n == u3u_mmap_read("lite", u3_Host.ops_u.lit_c, &len_d, &byt_y) ) { - u3l_log("lite: unable to load ivory pill at %s\n", + u3l_log("lite: unable to load ivory pill at %s", u3_Host.ops_u.lit_c); exit(1); } @@ -705,21 +705,21 @@ _king_boot_ivory(void) u3_weak pil; if ( u3_none == (pil = u3s_cue_xeno_with(sil_u, len_d, byt_y)) ) { - u3l_log("lite: unable to cue ivory pill\r\n"); + u3l_log("lite: unable to cue ivory pill"); exit(1); } u3s_cue_xeno_done(sil_u); if ( c3n == u3v_boot_lite(pil)) { - u3l_log("lite: boot failed\r\n"); + u3l_log("lite: boot failed"); exit(1); } } if ( u3_Host.ops_u.lit_c ) { if ( c3n == u3u_munmap(len_d, byt_y) ) { - u3l_log("lite: unable to unmap ivory pill at %s\n", + u3l_log("lite: unable to unmap ivory pill at %s", u3_Host.ops_u.lit_c); exit(1); } @@ -772,7 +772,7 @@ u3_king_commence() rlm.rlim_cur = 0; if ( 0 != setrlimit(RLIMIT_CORE, &rlm) ) { - u3l_log("king: unable to disable core dumps: %s\r\n", strerror(errno)); + u3l_log("king: unable to disable core dumps: %s", strerror(errno)); exit(1); } } diff --git a/pkg/urbit/vere/lord.c b/pkg/urbit/vere/lord.c index b910da1fd3..7c8b165150 100644 --- a/pkg/urbit/vere/lord.c +++ b/pkg/urbit/vere/lord.c @@ -281,13 +281,13 @@ _lord_plea_live(u3_lord* god_u, u3_noun dat) case u3_writ_meld: { // XX wire into cb // - u3l_log("pier: meld complete\n"); + u3l_log("pier: meld complete"); } break; case u3_writ_pack: { // XX wire into cb // - u3l_log("pier: pack complete\n"); + u3l_log("pier: pack complete"); } break; } @@ -373,7 +373,8 @@ _lord_plea_flog(u3_lord* god_u, u3_noun dat) } c3_c* tan_c = u3r_string(dat); - u3C.stderr_log_f(tan_c); + // u3C.stderr_log_f(tan_c); + u3l_log("y%sy", tan_c); c3_free(tan_c); if ( 0 != pir_u->sog_f ) { @@ -1076,10 +1077,10 @@ _lord_on_serf_bail(void* ptr_v, u3_lord* god_u = ptr_v; if ( UV_EOF == err_i ) { - u3l_log("pier: serf unexpectedly shut down\r\n"); + u3l_log("pier: serf unexpectedly shut down"); } else { - u3l_log("pier: serf error: %s\r\n", err_c); + u3l_log("pier: serf error: %s", err_c); } _lord_bail(god_u); @@ -1090,7 +1091,7 @@ _lord_on_serf_bail(void* ptr_v, void u3_lord_info(u3_lord* god_u) { - u3l_log(" lord: live=%s, event=%" PRIu64 ", mug=%x, queue=%u\n", + u3l_log(" lord: live=%s, event=%" PRIu64 ", mug=%x, queue=%u", ( c3y == god_u->liv_o ) ? "&" : "|", god_u->eve_d, god_u->mug_l, @@ -1125,7 +1126,7 @@ u3_lord_init(c3_c* pax_c, c3_w wag_w, c3_d key_d[4], u3_lord_cb cb_u) c3_c hap_c[11]; c3_i err_i; - sprintf(key_c, "%" PRIx64 ":%" PRIx64 ":%" PRIx64 ":%" PRIx64 "", + sprintf(key_c, "%" PRIx64 ":%" PRIx64 ":%" PRIx64 ":%" PRIx64, god_u->key_d[0], god_u->key_d[1], god_u->key_d[2], diff --git a/pkg/urbit/vere/newt.c b/pkg/urbit/vere/newt.c index d96c7197d2..b352c39f3f 100644 --- a/pkg/urbit/vere/newt.c +++ b/pkg/urbit/vere/newt.c @@ -378,7 +378,7 @@ u3_newt_moat_info(u3_moat* mot_u) } if ( len_w ) { - u3l_log(" newt: %u inbound ipc messages pending\n", len_w); + u3l_log(" newt: %u inbound ipc messages pending", len_w); } } diff --git a/pkg/urbit/vere/pier.c b/pkg/urbit/vere/pier.c index 42f12a0b4c..edf7c3fdee 100644 --- a/pkg/urbit/vere/pier.c +++ b/pkg/urbit/vere/pier.c @@ -266,7 +266,7 @@ _pier_work(u3_work* wok_u) // XX this is when "boot" is actually complete // XX even better would be after neighboring with our sponsor // - u3l_log("pier (%" PRIu64 "): live\r\n", pir_u->god_u->eve_d); + u3l_log("pier (%" PRIu64 "): live", pir_u->god_u->eve_d); // XX move callbacking to king // @@ -479,10 +479,10 @@ _pier_on_scry_done(void* ptr_v, u3_noun nun) u3_weak res = u3r_at(7, nun); if (u3_none == res) { - u3l_log("pier: scry failed\n"); + u3l_log("pier: scry failed"); } else { - u3l_log("pier: scry succeeded\n"); + u3l_log("pier: scry succeeded"); // serialize as desired // @@ -523,10 +523,10 @@ _pier_on_scry_done(void* ptr_v, u3_noun nun) snprintf(fil_c, 2048, "%s/.urb/put/%s.%s", pir_u->pax_c, pac_c+1, ext_c); u3_walk_save(fil_c, 0, out, pir_u->pax_c, pad); - u3l_log("pier: scry in %s\n", fil_c); + u3l_log("pier: scry in %s", fil_c); } - u3l_log("pier: exit\n"); + u3l_log("pier: exit"); u3_pier_exit(pir_u); u3z(nun); @@ -605,7 +605,7 @@ _pier_work_init(u3_pier* pir_u) } else { // run the requested scry, jam to disk, then exit // - u3l_log("pier: scry\n"); + u3l_log("pier: scry"); u3_pier_peek_last(pir_u, u3_nul, u3k(car), u3k(dek), u3k(pax), pir_u, _pier_on_scry_done); } @@ -654,7 +654,7 @@ _pier_wyrd_fail(u3_pier* pir_u, u3_ovum* egg_u, u3_noun lud) { // XX version negotiation failed, print upgrade message // - u3l_log("pier: version negotation failed\n\n"); + u3l_log("pier: version negotation failed"); // XX only print trace with -v ? // @@ -740,7 +740,7 @@ _pier_on_lord_wyrd_done(void* ptr_v, // XX messaging, cli argument to bypass // - u3l_log("pier: version negotiation failed; downgrade\n"); + u3l_log("pier: version negotiation failed; downgrade"); _pier_wyrd_fail(pir_u, egg_u, u3_nul); } else { @@ -833,7 +833,7 @@ _pier_wyrd_init(u3_pier* pir_u) pir_u->sat_e = u3_psat_wyrd; - u3l_log("vere: checking version compatibility\n"); + u3l_log("vere: checking version compatibility"); { u3_lord* god_u = pir_u->god_u; @@ -1022,11 +1022,11 @@ _pier_play(u3_play* pay_u) if ( god_u->eve_d == pay_u->eve_d ) { // XX should be play_cb // - u3l_log("---------------- playback complete ----------------\r\n"); + u3l_log("---------------- playback complete ----------------"); u3_term_stop_spinner(); if ( pay_u->eve_d < log_u->dun_d ) { - // u3l_log("pier: replay barrier reached, shutting down\r\n"); + // u3l_log("pier: replay barrier reached, shutting down"); // // XX graceful shutdown // // // u3_lord_save(pir_u->god_u); @@ -1035,7 +1035,7 @@ _pier_play(u3_play* pay_u) // XX temporary hack // - u3l_log("pier: replay barrier reached, cramming\r\n"); + u3l_log("pier: replay barrier reached, cramming"); u3_pier_cram(pir_u); } else if ( pay_u->eve_d == log_u->dun_d ) { @@ -1061,12 +1061,12 @@ _pier_on_lord_play_done(void* ptr_v, u3_info fon_u, c3_l mug_l) c3_assert( u3_psat_play == pir_u->sat_e ); - u3l_log("pier: (%" PRIu64 "): play: done\r\n", tac_u->eve_d); + u3l_log("pier: (%" PRIu64 "): play: done", tac_u->eve_d); // XX optional // if ( tac_u->mug_l && (tac_u->mug_l != mug_l) ) { - u3l_log("pier: (%" PRIu64 "): play: mug mismatch %x %x\r\n", + u3l_log("pier: (%" PRIu64 "): play: mug mismatch %x %x", tac_u->eve_d, tac_u->mug_l, mug_l); @@ -1115,7 +1115,7 @@ _pier_on_lord_play_bail(void* ptr_v, u3_info fon_u, // XX optional // if ( las_l && (las_l != mug_l) ) { - u3l_log("pier: (%" PRIu64 "): play bail: mug mismatch %x %x\r\n", + u3l_log("pier: (%" PRIu64 "): play bail: mug mismatch %x %x", (c3_d)(eve_d - 1ULL), las_l, mug_l); @@ -1126,7 +1126,7 @@ _pier_on_lord_play_bail(void* ptr_v, u3_info fon_u, // #if 0 { - u3l_log("pier: (%" PRIu64 "): play: retry\r\n", eve_d); + u3l_log("pier: (%" PRIu64 "): play: retry", eve_d); fon_u.ext_u = tac_u; @@ -1147,7 +1147,7 @@ _pier_on_lord_play_bail(void* ptr_v, u3_info fon_u, } #else { - u3l_log("pier: (%" PRIu64 "): play: bail\r\n", eve_d); + u3l_log("pier: (%" PRIu64 "): play: bail", eve_d); u3_pier_punt_goof("play", dud); { u3_noun wir, tag; @@ -1183,12 +1183,12 @@ _pier_play_init(u3_pier* pir_u, c3_d eve_d) pay_u->eve_d = eve_d; pay_u->sen_d = god_u->eve_d; - u3l_log("---------------- playback starting ----------------\r\n"); + u3l_log("---------------- playback starting ----------------"); if ( (1ULL + god_u->eve_d) == eve_d ) { - u3l_log("pier: replaying event %" PRIu64 "\r\n", eve_d); + u3l_log("pier: replaying event %" PRIu64, eve_d); } else { - u3l_log("pier: replaying events %" PRIu64 "-%" PRIu64 "\r\n", + u3l_log("pier: replaying events %" PRIu64 "-%" PRIu64, (c3_d)(1ULL + god_u->eve_d), eve_d); } @@ -1317,7 +1317,7 @@ _pier_on_lord_cram(void* ptr_v) // XX temporary hack // if ( u3_psat_play == pir_u->sat_e ) { - u3l_log("pier: cram complete, shutting down\r\n"); + u3l_log("pier: cram complete, shutting down"); u3_pier_bail(pir_u); exit(0); } @@ -1346,7 +1346,7 @@ _pier_on_lord_exit(void* ptr_v) pir_u->god_u = 0; if ( u3_psat_done != pir_u->sat_e ) { - u3l_log("pier: serf shutdown unexpected\r\n"); + u3l_log("pier: serf shutdown unexpected"); u3_pier_bail(pir_u); } // if we made it all the way here, it's our jab to wrap up @@ -1407,10 +1407,10 @@ _pier_on_lord_live(void* ptr_v) // if ( u3_Host.ops_u.til_c ) { if ( 1 == sscanf(u3_Host.ops_u.til_c, "%" PRIu64 "", &eve_d) ) { - u3l_log("pier: replay till %" PRIu64 "\r\n", eve_d); + u3l_log("pier: replay till %" PRIu64, eve_d); } else { - u3l_log("pier: ignoring invalid replay barrier '%s'\r\n", + u3l_log("pier: ignoring invalid replay barrier '%s'", u3_Host.ops_u.til_c); eve_d = log_u->dun_d; } @@ -1434,51 +1434,51 @@ u3_pier_info(u3_pier* pir_u) { switch ( pir_u->sat_e ) { default: { - u3l_log("pier: unknown state: %u\r\n", pir_u->sat_e); + u3l_log("pier: unknown state: %u", pir_u->sat_e); } break; case u3_psat_init: { - u3l_log("pier: init\n"); + u3l_log("pier: init"); } break; case u3_psat_boot: { - u3l_log("pier: boot\n"); + u3l_log("pier: boot"); } break; case u3_psat_play: { - u3l_log("pier: play\n"); + u3l_log("pier: play"); { u3_play* pay_u = pir_u->pay_u; - u3l_log(" target: %" PRIu64 "\n", pay_u->eve_d); - u3l_log(" sent: %" PRIu64 "\n", pay_u->sen_d); - u3l_log(" read: %" PRIu64 "\n", pay_u->req_d); + u3l_log(" target: %" PRIu64, pay_u->eve_d); + u3l_log(" sent: %" PRIu64, pay_u->sen_d); + u3l_log(" read: %" PRIu64, pay_u->req_d); } } break; case u3_psat_work: { - u3l_log("pier: work\n"); + u3l_log("pier: work"); { u3_work* wok_u = pir_u->wok_u; - u3l_log(" effects: released=%" PRIu64 "\n", wok_u->fec_u.rel_d); + u3l_log(" effects: released=%" PRIu64, wok_u->fec_u.rel_d); if ( wok_u->fec_u.ext_u ) { if ( wok_u->fec_u.ext_u != wok_u->fec_u.ent_u ) { - u3l_log(" pending %" PRIu64 "-%" PRIu64 "\n", + u3l_log(" pending %" PRIu64 "-%" PRIu64, wok_u->fec_u.ext_u->eve_d, wok_u->fec_u.ent_u->eve_d); } else { - u3l_log(" pending %" PRIu64 "\n", wok_u->fec_u.ext_u->eve_d); + u3l_log(" pending %" PRIu64, wok_u->fec_u.ext_u->eve_d); } } if ( wok_u->wal_u ) { - u3l_log(" wall: %" PRIu64 "\n", wok_u->wal_u->eve_d); + u3l_log(" wall: %" PRIu64, wok_u->wal_u->eve_d); } if ( wok_u->car_u ) { @@ -1488,7 +1488,7 @@ u3_pier_info(u3_pier* pir_u) } break; case u3_psat_done: { - u3l_log("pier: done\n"); + u3l_log("pier: done"); } break; } @@ -2181,10 +2181,12 @@ _pier_dump_wall(FILE* fil_u, u3_noun wol) while ( u3_nul != wal ) { _pier_dump_tape(fil_u, u3k(u3h(wal))); - putc(13, fil_u); - putc(10, fil_u); - wal = u3t(wal); + + if ( u3_nul != wal ) { + putc(13, fil_u); + putc(10, fil_u); + } } u3z(wol); @@ -2226,8 +2228,6 @@ u3_pier_tank(c3_l tab_l, c3_w pri_w, u3_noun tac) if ( 0 == u3A->roc ) { if ( c3__leaf == u3h(tac) ) { _pier_dump_tape(fil_u, u3k(u3t(tac))); - putc(13, fil_u); - putc(10, fil_u); } } // We are calling nock here, but hopefully need no protection. @@ -2274,12 +2274,12 @@ u3_pier_punt_goof(const c3_c* cap_c, u3_noun dud) u3x_cell(dud, &mot, &tan); - u3l_log("\n"); + u3l_log(""); u3_pier_punt(0, u3qb_flop(tan)); { c3_c* mot_c = u3r_string(mot); - u3l_log("%s: bail: %%%s\r\n", cap_c, mot_c); + u3l_log("%s: bail: %%%s", cap_c, mot_c); c3_free(mot_c); } @@ -2295,7 +2295,7 @@ u3_pier_punt_ovum(const c3_c* cap_c, u3_noun wir, u3_noun tag) u3_noun riw = u3do("spat", wir); c3_c* wir_c = u3r_string(riw); - u3l_log("%s: %%%s event on %s failed\r\n\n", cap_c, tag_c, wir_c); + u3l_log("%s: %%%s event on %s failed", cap_c, tag_c, wir_c); c3_free(tag_c); c3_free(wir_c); diff --git a/pkg/urbit/vere/save.c b/pkg/urbit/vere/save.c index e2c042b243..f413efe970 100644 --- a/pkg/urbit/vere/save.c +++ b/pkg/urbit/vere/save.c @@ -31,7 +31,7 @@ u3_save_ef_chld(u3_pier *pir_u) /* modified for cases with no pid_w */ - u3l_log("checkpoint: complete %d\n", sav_u->pid_w); + u3l_log("checkpoint: complete %d", sav_u->pid_w); pid_w = wait(&loc_i); if (0 != sav_u->pid_w) { c3_assert(pid_w == sav_u->pid_w); diff --git a/pkg/urbit/vere/walk.c b/pkg/urbit/vere/walk.c index 1f7095a188..e7c042bce2 100644 --- a/pkg/urbit/vere/walk.c +++ b/pkg/urbit/vere/walk.c @@ -44,7 +44,7 @@ u3_walk_safe(c3_c* pas_c) c3_y* pad_y; if ( (fid_i < 0) || (fstat(fid_i, &buf_b) < 0) ) { - // u3l_log("%s: %s\n", pas_c, strerror(errno)); + // u3l_log("%s: %s", pas_c, strerror(errno)); return 0; } fln_w = buf_b.st_size; @@ -76,7 +76,7 @@ u3_walk_load(c3_c* pas_c) c3_y* pad_y; if ( (fid_i < 0) || (fstat(fid_i, &buf_b) < 0) ) { - u3l_log("%s: %s\n", pas_c, strerror(errno)); + u3l_log("%s: %s", pas_c, strerror(errno)); return u3m_bail(c3__fail); } fln_w = buf_b.st_size; @@ -124,7 +124,7 @@ _walk_mkdirp(c3_c* bas_c, u3_noun pax) pax_c[len_w] = '\0'; if ( 0 != mkdir(pax_c, 0755) && EEXIST != errno ) { - u3l_log("error mkdiring %s: %s\n", pax_c, strerror(errno)); + u3l_log("error mkdiring %s: %s", pax_c, strerror(errno)); u3m_bail(c3__fail); } @@ -147,7 +147,7 @@ u3_walk_save(c3_c* pas_c, u3_noun tim, u3_atom pad, c3_c* bas_c, u3_noun pax) return u3_walk_save(pas_c, tim, pad, 0, u3_nul); } - u3l_log("%s: %s\n", pas_c, strerror(errno)); + u3l_log("%s: %s", pas_c, strerror(errno)); u3m_bail(c3__fail); } @@ -162,7 +162,7 @@ u3_walk_save(c3_c* pas_c, u3_noun tim, u3_atom pad, c3_c* bas_c, u3_noun pax) c3_free(pad_y); if ( rit_w != fln_w ) { - u3l_log("%s: %s\n", pas_c, strerror(errno)); + u3l_log("%s: %s", pas_c, strerror(errno)); u3m_bail(c3__fail); } @@ -192,7 +192,7 @@ _walk_in(const c3_c* dir_c, c3_w len_w) struct dirent* out_n; if ( u3_readdir_r(dir_d, &ent_n, &out_n) != 0 ) { - u3l_log("%s: %s\n", dir_c, strerror(errno)); + u3l_log("%s: %s", dir_c, strerror(errno)); break; } else if ( !out_n ) { @@ -274,7 +274,7 @@ u3_walk(const c3_c* dir_c, u3_noun old) struct stat buf_b; if ( 0 != stat(dir_c, &buf_b) ) { - u3l_log("can't stat %s\n", dir_c); + u3l_log("can't stat %s", dir_c); // return u3m_bail(c3__fail); c3_assert(0); } diff --git a/pkg/urbit/worker/main.c b/pkg/urbit/worker/main.c index 46895f093b..0034eb012a 100644 --- a/pkg/urbit/worker/main.c +++ b/pkg/urbit/worker/main.c @@ -82,7 +82,8 @@ _cw_serf_send_slog(u3_noun hod) static void _cw_serf_send_stdr(c3_c* str_c) { - _cw_serf_send(u3nc(c3__flog, u3i_string(str_c))); + // _cw_serf_send(u3nc(c3__flog, u3i_string(str_c))); + _cw_serf_send(u3nc(c3__flog, u3i_string("lmao"))); } diff --git a/pkg/urbit/worker/serf.c b/pkg/urbit/worker/serf.c index 1173ae344f..91ec1274fc 100644 --- a/pkg/urbit/worker/serf.c +++ b/pkg/urbit/worker/serf.c @@ -260,7 +260,7 @@ _serf_grab(u3_serf* sef_u) u3z(sef_u->sac); sef_u->sac = u3_nul; - u3l_log("\n"); + u3l_log(""); } } @@ -298,7 +298,7 @@ u3_serf_post(u3_serf* sef_u) if ( c3y == sef_u->pac_o ) { u3a_print_memory(stderr, "serf: pack: gained", u3m_pack()); - u3l_log("\n"); + u3l_log(""); sef_u->pac_o = c3n; } } @@ -480,7 +480,7 @@ _serf_poke(u3_serf* sef_u, c3_c* cap_c, c3_w mil_w, u3_noun job) if ( (c3__belt != tag) && (c3__crud != tag) ) { - u3l_log("serf: %s (%" PRIu64 ") %s\r\n", cap_c, sef_u->sen_d, txt_c); + u3l_log("serf: %s (%" PRIu64 ") %s", cap_c, sef_u->sen_d, txt_c); } } #endif @@ -500,7 +500,7 @@ _serf_poke(u3_serf* sef_u, c3_c* cap_c, c3_w mil_w, u3_noun job) clr_w = ms_w > 1000 ? 1 : ms_w < 100 ? 2 : 3; // red, green, yellow if ( clr_w != 2 ) { - u3l_log("\x1b[3%dm%%%s (%" PRIu64 ") %4d.%02dms\x1b[0m\n", + u3l_log("\x1b[3%dm%%%s (%" PRIu64 ") %4d.%02dms\x1b[0m", clr_w, txt_c, sef_u->sen_d, ms_w, (int) (d0.tv_usec % 1000) / 10); } @@ -539,7 +539,7 @@ _serf_work(u3_serf* sef_u, c3_w mil_w, u3_noun job) // if ( u3_blip == u3h(gon) ) { u3_noun vir = _serf_sure(sef_u, pre_w, u3k(u3t(gon))); - + u3z(gon); u3z(job); return u3nc(c3__done, u3nt(u3i_chubs(1, &sef_u->dun_d), sef_u->mug_l, @@ -917,7 +917,7 @@ u3_serf_live(u3_serf* sef_u, u3_noun com, u3_noun* ret) return c3n; } - u3l_log("serf (%" PRIu64 "): saving rock\r\n", sef_u->dun_d); + u3l_log("serf (%" PRIu64 "): saving rock", sef_u->dun_d); if ( c3n == u3u_cram(sef_u->dir_c, eve_d) ) { fprintf(stderr, "serf (%" PRIu64 "): unable to jam state\r\n", eve_d); @@ -1061,7 +1061,7 @@ u3_serf_writ(u3_serf* sef_u, u3_noun wit, u3_noun* pel) static u3_noun _serf_ripe(u3_serf* sef_u) { - // u3l_log("serf: ripe %" PRIu64 "\r\n", sef_u->dun_d); + // u3l_log("serf: ripe %" PRIu64, sef_u->dun_d); sef_u->mug_l = ( 0 == sef_u->dun_d ) ? 0 From 7ab6d7dc9c38d0f75c9d048e2249489f316c5b18 Mon Sep 17 00:00:00 2001 From: fang Date: Tue, 9 Feb 2021 15:43:16 +0100 Subject: [PATCH 008/104] term: add minimal mouse support Only detects mouse clicks. Though, "9" mode seems broken, or unsupported or something? Probably need to upgrade to "1000" mode or higher, but that also reports scrolling events and such, which don't want to steal from the context we're running in just yet. --- pkg/arvo/lib/hood/drum.hoon | 10 +++++++++ pkg/arvo/mar/belt.hoon | 1 + pkg/arvo/sys/lull.hoon | 1 + pkg/urbit/include/vere/vere.h | 3 +++ pkg/urbit/vere/io/term.c | 40 +++++++++++++++++++++++++++++++++++ 5 files changed, 55 insertions(+) diff --git a/pkg/arvo/lib/hood/drum.hoon b/pkg/arvo/lib/hood/drum.hoon index 801b8559d6..3a9f18d0aa 100644 --- a/pkg/arvo/lib/hood/drum.hoon +++ b/pkg/arvo/lib/hood/drum.hoon @@ -699,6 +699,7 @@ [%bac *] ta-bac [%ctl *] (ta-ctl p.bet) [%del *] ta-del + [%hit *] (ta-hit +.bet) [%met *] (ta-met p.bet) [%ret *] ta-ret [%txt *] (ta-txt p.bet) @@ -779,6 +780,15 @@ ta-bel (ta-hom %del pos.inp) :: + ++ ta-hit :: hear click + |= [r=@ud c=@ud] + ^+ +> + ?. =(0 r) +> + =/ pol=@ud + (lent-char:klr (make:klr cad.pom)) + ?: (lth c pol) +>.$ + +>.$(pos.inp (min (sub c pol) (lent buf.say.inp))) + :: ++ ta-erl :: hear local error |= pos=@ud ta-bel(pos.inp (min pos (lent buf.say.inp))) diff --git a/pkg/arvo/mar/belt.hoon b/pkg/arvo/mar/belt.hoon index 1c5a6e1ea6..bb8e29ce5e 100644 --- a/pkg/arvo/mar/belt.hoon +++ b/pkg/arvo/mar/belt.hoon @@ -15,6 +15,7 @@ bac+ul ctl+(cu taft so) del+ul + hit+(ot 'r'^ni 'c'^ni ~) met+(cu taft so) ret+ul txt+(ar (cu taft so)) diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index 02daec58c2..53cf2d2c77 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -1050,6 +1050,7 @@ [%bac ~] :: true backspace [%ctl p=@c] :: control-key [%del ~] :: true delete + [%hit r=@ud c=@ud] :: mouse click [%met p=@c] :: meta-key [%ret ~] :: return [%txt p=(list @c)] :: utf32 text diff --git a/pkg/urbit/include/vere/vere.h b/pkg/urbit/include/vere/vere.h index f1646ee1bc..7dba712c32 100644 --- a/pkg/urbit/include/vere/vere.h +++ b/pkg/urbit/include/vere/vere.h @@ -154,6 +154,9 @@ struct { // escape code control c3_o ape; // escape received c3_o bra; // bracket or O received + c3_o mou; // M (for mouse event) received + c3_y ton_y; // mouse button + c3_y col_y; // column coordinate } esc; struct { diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index 47481f7de4..f09f059a03 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -224,6 +224,9 @@ u3_term_log_init(void) uty_u->tat_u.esc.ape = c3n; uty_u->tat_u.esc.bra = c3n; + uty_u->tat_u.esc.mou = c3n; + uty_u->tat_u.esc.ton_y = 0; + uty_u->tat_u.esc.col_y = 0; uty_u->tat_u.fut.len_w = 0; uty_u->tat_u.fut.wid_w = 0; @@ -723,6 +726,8 @@ _term_io_suck_char(u3_utty* uty_u, c3_y cay_y) { u3_utat* tat_u = &uty_u->tat_u; + // escape sequences + // if ( c3y == tat_u->esc.ape ) { if ( c3y == tat_u->esc.bra ) { switch ( cay_y ) { @@ -734,6 +739,8 @@ _term_io_suck_char(u3_utty* uty_u, c3_y cay_y) 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 'M': tat_u->esc.mou = c3y; break; } tat_u->esc.ape = tat_u->esc.bra = c3n; } @@ -760,6 +767,27 @@ _term_io_suck_char(u3_utty* uty_u, c3_y cay_y) } } } + // mouse input + // + else if ( c3y == tat_u->esc.mou ) { + if ( 0 == tat_u->esc.ton_y ) { + tat_u->esc.ton_y = cay_y - 31; + } + else if ( 0 == tat_u->esc.col_y ) { + tat_u->esc.col_y = cay_y - 32; + } + else { + 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, tat_u->siz.row_l - row_y, tat_u->esc.col_y - 1)); + } + tat_u->esc.mou = c3n; + tat_u->esc.ton_y = tat_u->esc.col_y = 0; + } + } + // unicode inputs + // else if ( 0 != tat_u->fut.wid_w ) { tat_u->fut.syb_y[tat_u->fut.len_w++] = cay_y; @@ -775,6 +803,8 @@ _term_io_suck_char(u3_utty* uty_u, c3_y cay_y) _term_io_belt(uty_u, u3nt(c3__txt, wug, u3_nul)); } } + // individual characters + // else { if ( (cay_y >= 32) && (cay_y < 127) ) { _term_io_belt(uty_u, u3nt(c3__txt, cay_y, u3_nul)); @@ -1615,6 +1645,11 @@ _term_io_talk(u3_auto* car_u) if ( c3n == u3_Host.ops_u.tem ) { u3_utty* uty_u = _term_main(); + // start mouse handling + // + uv_buf_t mon_u = TERM_LIT_BUF("\033[?9h"); + _term_it_dump_buf(uty_u, &mon_u); + uv_read_start((uv_stream_t*)&(uty_u->pop_u), _term_alloc, _term_read_cb); @@ -1781,6 +1816,11 @@ _term_io_exit(u3_auto* car_u) uv_read_stop((uv_stream_t*)&(uty_u->pop_u)); if ( c3n == u3_Host.ops_u.tem ) { + // stop mouse handling + // + uv_buf_t mof_u = TERM_LIT_BUF("\033[?9l"); + _term_it_dump_buf(uty_u, &mof_u); + uv_timer_t* han_u = &(uty_u->tat_u.sun_u.tim_u); han_u->data = car_u; From 3fdef146888a19209303614dc1fe9dd63ef93a30 Mon Sep 17 00:00:00 2001 From: fang Date: Wed, 10 Feb 2021 01:22:56 +0100 Subject: [PATCH 009/104] dill: stop redrawing the prompt & cursor No longer inserts newlines or redraws the prompt post-print, pushing this responsibility down to drum where it belongs. Additionally, separates the flow for dill's own output, from that of the console application. This lets us keep the desired behavior for now, and will ease reworking in the future. Last-printed-line and cursor position are still kept around in dill state, in order to respond to the relevant scry endpoints. These should either be refactored to scry into the underlying console app, or be removed entirely in favor of %hey. --- pkg/arvo/lib/hood/drum.hoon | 19 +++++++++----- pkg/arvo/sys/lull.hoon | 2 +- pkg/arvo/sys/vane/dill.hoon | 52 ++++++++++++++++++++++--------------- 3 files changed, 45 insertions(+), 28 deletions(-) diff --git a/pkg/arvo/lib/hood/drum.hoon b/pkg/arvo/lib/hood/drum.hoon index 3a9f18d0aa..5c23fe1626 100644 --- a/pkg/arvo/lib/hood/drum.hoon +++ b/pkg/arvo/lib/hood/drum.hoon @@ -538,6 +538,15 @@ leaf+(weld (scag (sub edg 3) tape) "...") leaf+tape :: +++ se-blin :: print and newline + |= lin=dill-blit:dill + ^+ +> + :: newline means we need to redraw the prompt, + :: so update the prompt mirror accordingly. + :: + =. mir [0 ~] + (se-blit %mor lin [%nel ~] ~) +:: ++ se-dump :: print tanks |= tac=(list tank) ^+ +> @@ -548,7 +557,7 @@ ?. ((sane %t) (crip i.wol)) :: XX upstream validation ~& bad-text+<`*`i.wol> $(wol t.wol) - $(wol t.wol, +>.^$ (se-blit %out (tuba i.wol))) + $(wol t.wol, +>.^$ (se-blin %out (tuba i.wol))) :: ++ se-join :: confirm connection |= gyl=gill:gall @@ -587,9 +596,7 @@ |= lin=(pair @ud stub) ^+ +> ?: =(mir lin) +> - =. +> ?:(=(p.mir p.lin) +> (se-blit %hop p.lin)) - =. +> ?:(=(q.mir q.lin) +> (se-blit %pom q.lin)) - +>(mir lin) + (se-blit(mir lin) %mor [%pom q.lin] [%hop p.lin] ~) :: ++ se-just :: adjusted buffer |= [pom=stub lin=(pair @ud (list @c))] @@ -627,7 +634,7 @@ ?. ((sane %t) (crip txt)) :: XX upstream validation ~& bad-text+<`*`txt> +> - (se-blit %out (tuba txt)) + (se-blin %out (tuba txt)) :: ++ se-poke :: send a poke |= [gyl=gill:gall par=cage] @@ -806,7 +813,7 @@ [%bye *] +>(..ta (se-klin gyl)) [%det *] (ta-got +.fec) [%err *] (ta-err p.fec) - [%klr *] +>(..ta (se-blit %klr (make:klr p.fec))) + [%klr *] +>(..ta (se-blin %klr (make:klr p.fec))) [%mor *] |- ^+ +>.^$ ?~ p.fec +>.^$ $(p.fec t.p.fec, +>.^$ ^$(fec i.p.fec)) diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index 53cf2d2c77..54dd51e366 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -1060,7 +1060,7 @@ [%clr ~] :: clear the screen [%hop p=$@(@ud [r=@ud c=@ud])] :: set cursor row/pos [%klr p=stub] :: set styled line - [%lin p=(list @c)] :: set current line + [%lin p=(list @c)] :: set line at cursor [%nel ~] :: newline [%sag p=path q=*] :: save to jamfile [%sav p=path q=@] :: save to file diff --git a/pkg/arvo/sys/vane/dill.hoon b/pkg/arvo/sys/vane/dill.hoon index 67d79fcea9..d1f552a95d 100644 --- a/pkg/arvo/sys/vane/dill.hoon +++ b/pkg/arvo/sys/vane/dill.hoon @@ -107,7 +107,7 @@ %harm +> %hail (send %hey ~) %belt (send `dill-belt`p.kyz) - %text (from %out (tuba p.kyz)) + %text (fore (tuba p.kyz) ~) %crud :: (send `dill-belt`[%cru p.kyz q.kyz]) (crud p.kyz q.kyz) %blew (send %rez p.p.kyz q.p.kyz) @@ -134,9 +134,8 @@ %+ turn (flop tac) |=(a=tank (~(win re a) [0 wid])) == - |- ^+ +>.^$ - ?~ wall +>.^$ - $(wall t.wall, +>.^$ (from %out (tuba i.wall))) + ?: =(~ wall) +>.$ + (fore (turn wall tuba)) :: ++ dump :: pass down to hey |= git=gift @@ -159,6 +158,29 @@ |= [=wire =note] +>(moz :_(moz [hen %pass wire note])) :: + ++ fore :: send dill output + ::NOTE there are still implicit assumptions + :: about the underlying console app's + :: semantics here. specifically, trailing + :: newlines are important to not getting + :: overwritten by the drum prompt, and a + :: bottom-of-screen cursor position gives + :: nicest results. a more agnostic solution + :: will need to replace this arm, someday. + :: perhaps +send this to .ram instead? + :: + |= liz=(list (list @c)) + ^+ +> + =. +> + =| biz=(list blit) + |- ^+ +>.^$ + ?~ liz (done %blit biz) + $(liz t.liz, biz (welp biz [%lin i.liz] [%nel ~] ~)) + :: since dill is acting on its own accord, + :: we %hey the term app so it may clean up. + :: + (send %hey ~) + :: ++ from :: receive blit |= bit=dill-blit ^+ +> @@ -167,25 +189,13 @@ ?~ p.bit +>.^$ $(p.bit t.p.bit, +>.^$ ^$(bit i.p.bit)) ?: ?=(%out -.bit) - %+ done %blit - :~ [%lin p.bit] - [%nel ~] - see - [%hop pos] - == - ?: ?=(%klr -.bit) - %+ done %blit - :~ [%klr p.bit] - [%nel ~] - see - [%hop pos] - == + (done %blit [%lin p.bit]~) ?: ?=(%pro -.bit) =. see [%lin p.bit] - (done %blit [see [%hop pos] ~]) + (done %blit [%lin p.bit]~) ?: ?=(%pom -.bit) =. see [%klr p.bit] - (done %blit [see [%hop pos] ~]) + (done %blit [%klr p.bit]~) ?: ?=(%hop -.bit) (done(pos p.bit) %blit [bit ~]) ?: ?=(%qit -.bit) @@ -253,7 +263,7 @@ :: ~& [%take-gall-onto +>.sih] ?- -.+>.sih %| (crud %onto p.p.+>.sih) - %& (done %blit [%lin (tuba "{}")]~) + %& (fore (tuba "{}") ~) == :: [%gall %unto *] @@ -268,7 +278,7 @@ == :: [%clay %note *] - (from %out (tuba p.sih ' ' ~(ram re q.sih))) + (fore (tuba p.sih ' ' ~(ram re q.sih)) ~) :: [?(%behn %clay) %writ *] init From be8713f15187766b8ab9f00bf769256a938231a7 Mon Sep 17 00:00:00 2001 From: fang Date: Wed, 10 Feb 2021 17:03:03 +0100 Subject: [PATCH 010/104] dill: stop tracking prompt & cursor position As follow-up to 3fdef1468, we now no longer store the prompt or cursor in state. These were still used for view initialization, but it's more appropriate to %hey the underlying console application in those cases. The scry endpoints we remove, expecting clients that depended on them to send a %hail instead. --- pkg/arvo/sys/vane/dill.hoon | 66 +++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/pkg/arvo/sys/vane/dill.hoon b/pkg/arvo/sys/vane/dill.hoon index d1f552a95d..a9bb19bfe4 100644 --- a/pkg/arvo/sys/vane/dill.hoon +++ b/pkg/arvo/sys/vane/dill.hoon @@ -8,7 +8,7 @@ -- :: => |% :: console protocol +$ axle :: - $: %4 ::TODO replace ducts with session ids :: + $: %5 ::TODO replace ducts with session ids :: hey=(unit duct) :: default duct dug=(map duct axon) :: conversations eye=(jug duct duct) :: outside listeners @@ -21,8 +21,6 @@ $: ram=term :: console program tem=(unit (list dill-belt)) :: pending, reverse wid=_80 :: terminal width - pos=$@(@ud [@ud @ud]) :: cursor position - see=$%([%lin (list @c)] [%klr stub]) :: current line == :: +$ log-level ?(%hush %soft %loud) :: none, line, full -- => :: @@ -191,13 +189,9 @@ ?: ?=(%out -.bit) (done %blit [%lin p.bit]~) ?: ?=(%pro -.bit) - =. see [%lin p.bit] (done %blit [%lin p.bit]~) ?: ?=(%pom -.bit) - =. see [%klr p.bit] (done %blit [%klr p.bit]~) - ?: ?=(%hop -.bit) - (done(pos p.bit) %blit [bit ~]) ?: ?=(%qit -.bit) (dump %logo ~) (done %blit [bit ~]) @@ -339,8 +333,8 @@ :: =* duc (need hey.all) =/ app %hood - =/ see (tuba "") - =/ zon=axon [app input=[~ ~] width=80 cursor=(lent see) lin+see] + =/ say (tuba "") + =/ zon=axon [app input=[~ ~] width=80] :: =^ moz all abet:(~(into as duc zon) ~) [moz ..^$] @@ -370,10 +364,12 @@ ~| [%no-session session.task] ?> =(~ session.task) =/ session (need hey.all) - =/ =axon (~(got by dug.all) session) - :: register the viewer and send them the prompt line + =/ nus (need (ax session)) + :: register the viewer and send a %hey so they get the full screen :: - :- [hen %give %blit [see.axon]~]~ + =^ moz all + abet:(send:nus %hey ~) + :- moz ..^$(eye.all (~(put ju eye.all) session hen)) :: ?: ?=(%flee -.task) @@ -399,8 +395,34 @@ [moz ..^$] :: ++ load :: import old state - |= old=axle - ..^$(all old) + =< |= old=any-axle + ?- -.old + %5 ..^$(all old) + %4 $(old (axle-4-to-5 old)) + == + |% + +$ any-axle $%(axle axle-4) + :: + +$ axle-4 + $: %4 + hey=(unit duct) + dug=(map duct axon-4) + eye=(jug duct duct) + lit=? + veb=(map @tas log-level) + == + :: + +$ axon-4 + $: ram=term + tem=(unit (list dill-belt)) + wid=_80 + pos=$@(@ud [@ud @ud]) + see=$%([%lin (list @c)] [%klr stub]) + == + :: + ++ axle-4-to-5 |=(axle-4 [%5 +<+(dug (~(run by dug) axon-4-to-5))]) + ++ axon-4-to-5 |=(axon-4 [ram tem wid]) + -- :: ++ scry ^- roon @@ -429,20 +451,8 @@ =(%$ syd) == ~ - :: /dx/sessions//line blit current line (prompt) of default session - :: /dx/sessions//cursor @ud current cursor position of default session - ::TODO support asking for specific sessions once session ids are real - :: - ?. ?=(%x ren) ~ - ?+ tyl ~ - [%sessions %$ *] - ?~ hey.all [~ ~] - ?~ session=(~(get by dug.all) u.hey.all) [~ ~] - ?+ t.t.tyl ~ - [%line ~] ``blit+!>(`blit`see.u.session) - [%cursor ~] ``blit+!>(`blit`hop+pos.u.session) - == - == + ::TODO scry endpoints for /sessions + ~ :: ++ stay all :: From 0b1fde059535b9d143efda471e5f980567bd1772 Mon Sep 17 00:00:00 2001 From: fang Date: Wed, 10 Feb 2021 20:05:26 +0100 Subject: [PATCH 011/104] dill: remove now-redundant blits Previously, these affected dill state. Now, they're equivalent to %lin and %klr blits. --- pkg/arvo/lib/hood/drum.hoon | 6 +++--- pkg/arvo/mar/dill/blit.hoon | 2 +- pkg/arvo/sys/lull.hoon | 3 --- pkg/arvo/sys/vane/dill.hoon | 6 ------ 4 files changed, 4 insertions(+), 13 deletions(-) diff --git a/pkg/arvo/lib/hood/drum.hoon b/pkg/arvo/lib/hood/drum.hoon index 5c23fe1626..0933630ad2 100644 --- a/pkg/arvo/lib/hood/drum.hoon +++ b/pkg/arvo/lib/hood/drum.hoon @@ -557,7 +557,7 @@ ?. ((sane %t) (crip i.wol)) :: XX upstream validation ~& bad-text+<`*`i.wol> $(wol t.wol) - $(wol t.wol, +>.^$ (se-blin %out (tuba i.wol))) + $(wol t.wol, +>.^$ (se-blin %lin (tuba i.wol))) :: ++ se-join :: confirm connection |= gyl=gill:gall @@ -596,7 +596,7 @@ |= lin=(pair @ud stub) ^+ +> ?: =(mir lin) +> - (se-blit(mir lin) %mor [%pom q.lin] [%hop p.lin] ~) + (se-blit(mir lin) %mor [%klr q.lin] [%hop p.lin] ~) :: ++ se-just :: adjusted buffer |= [pom=stub lin=(pair @ud (list @c))] @@ -634,7 +634,7 @@ ?. ((sane %t) (crip txt)) :: XX upstream validation ~& bad-text+<`*`txt> +> - (se-blin %out (tuba txt)) + (se-blin %lin (tuba txt)) :: ++ se-poke :: send a poke |= [gyl=gill:gall par=cage] diff --git a/pkg/arvo/mar/dill/blit.hoon b/pkg/arvo/mar/dill/blit.hoon index 77e5cecf47..f70280139e 100644 --- a/pkg/arvo/mar/dill/blit.hoon +++ b/pkg/arvo/mar/dill/blit.hoon @@ -20,7 +20,7 @@ ?+ -.dib ~|(unsupported-blit+-.dib !!) %mor [%a (turn p.dib |=(a=dill-blit:dill json(dib a)))] %hop (frond %hop (numb p.dib)) - ?(%pro %out) (frond -.dib (tape (tufa p.dib))) + %lin (frond -.dib (tape (tufa p.dib))) ?(%bel %clr) (frond %act %s -.dib) == -- diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index 54dd51e366..beac6898b3 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -1076,10 +1076,7 @@ +$ dill-blit :: inside blit $% blit :: outside blit [%mor p=(list dill-blit)] :: multiple blits - [%pom p=stub] :: styled prompt - [%pro p=(list @c)] :: show as cursor+line [%qit ~] :: close console - [%out p=(list @c)] :: send output line == :: +$ flog :: sent to %dill $% [%crop p=@ud] :: trim kernel state diff --git a/pkg/arvo/sys/vane/dill.hoon b/pkg/arvo/sys/vane/dill.hoon index a9bb19bfe4..16db0f8d90 100644 --- a/pkg/arvo/sys/vane/dill.hoon +++ b/pkg/arvo/sys/vane/dill.hoon @@ -186,12 +186,6 @@ |- ^+ +>.^$ ?~ p.bit +>.^$ $(p.bit t.p.bit, +>.^$ ^$(bit i.p.bit)) - ?: ?=(%out -.bit) - (done %blit [%lin p.bit]~) - ?: ?=(%pro -.bit) - (done %blit [%lin p.bit]~) - ?: ?=(%pom -.bit) - (done %blit [%klr p.bit]~) ?: ?=(%qit -.bit) (dump %logo ~) (done %blit [bit ~]) From c75e0e03945f42900aa30a4e4db43048c2d4fe8f Mon Sep 17 00:00:00 2001 From: fang Date: Fri, 12 Feb 2021 00:29:29 +0100 Subject: [PATCH 012/104] dill: store sessions by @tas, not duct This prepares us for actually making use of multiple session in a sane way. Notable implicit change is that we no longer crash on an "unrecognized duct", instead always handling it as destined for the default session. --- pkg/arvo/sys/lull.hoon | 21 +++++--- pkg/arvo/sys/vane/dill.hoon | 98 ++++++++++++++++++++++--------------- 2 files changed, 72 insertions(+), 47 deletions(-) diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index beac6898b3..f8628830ce 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -1017,29 +1017,34 @@ == :: +$ task :: in request ->$ $~ [%vega ~] :: - $% [%belt p=belt] :: terminal input - [%blew p=blew] :: terminal config - [%boot lit=? p=*] :: weird %dill boot + $% [%boot lit=? p=*] :: weird %dill boot [%crop p=@ud] :: trim kernel state [%crud p=@tas q=(list tank)] :: print error - [%flee session=~] :: unwatch session [%flog p=flog] :: wrapped error - [%flow p=@tas q=(list gill:gall)] :: terminal config - [%hail ~] :: terminal refresh [%heft ~] :: memory report - [%hook ~] :: this term hung up [%harm ~] :: all terms hung up $>(%init vane-task) :: after gall ready [%meld ~] :: unify memory [%noop ~] :: no operation [%pack ~] :: compact memory + [%shot ses=@tas task=session-task] :: task for session [%talk p=tank] :: [%text p=tape] :: - [%view session=~] :: watch session blits $>(%trim vane-task) :: trim state $>(%vega vane-task) :: report upgrade [%verb ~] :: verbose mode [%knob tag=term level=?(%hush %soft %loud)] :: error verbosity + session-task :: for default session + == :: + :: :: + +$ session-task :: session request + $% [%belt p=belt] :: terminal input + [%blew p=blew] :: terminal config + [%flee ~] :: unwatch session + [%flow p=@tas q=(list gill:gall)] :: terminal config + [%hail ~] :: terminal refresh + [%hook ~] :: this term hung up + [%view ~] :: watch session blits == :: :: :::: :: (1d2) diff --git a/pkg/arvo/sys/vane/dill.hoon b/pkg/arvo/sys/vane/dill.hoon index 16db0f8d90..c3051f8f96 100644 --- a/pkg/arvo/sys/vane/dill.hoon +++ b/pkg/arvo/sys/vane/dill.hoon @@ -8,16 +8,16 @@ -- :: => |% :: console protocol +$ axle :: - $: %5 ::TODO replace ducts with session ids :: + $: %5 :: hey=(unit duct) :: default duct - dug=(map duct axon) :: conversations - eye=(jug duct duct) :: outside listeners + dug=(map @tas axon) :: conversations + eye=(jug @tas duct) :: outside listeners lit=? :: boot in lite mode $= veb :: vane verbosities $~ (~(put by *(map @tas log-level)) %hole %soft) :: quiet packet crashes (map @tas log-level) :: == :: -+$ axon :: dill per duct ++$ axon :: dill session $: ram=term :: console program tem=(unit (list dill-belt)) :: pending, reverse wid=_80 :: terminal width @@ -92,10 +92,10 @@ |% ++ as :: per cause =| moz=(list move) - |_ [hen=duct axon] + |_ [hen=duct ses=@tas axon] ++ abet :: resolve ^- [(list move) axle] - [(flop moz) all(dug (~(put by dug.all) hen +<+))] + [(flop moz) all(dug (~(put by dug.all) ses +<+>))] :: ++ call :: receive input |= kyz=task @@ -140,12 +140,11 @@ ?> ?=(^ hey.all) +>(moz [[u.hey.all %give git] moz]) :: - ++ done :: return gift + ++ done :: gift to viewers |= git=gift =- +>.$(moz (weld - moz)) %+ turn - :- hen - ~(tap in (~(get ju eye.all) hen)) + ~(tap in (~(get ju eye.all) ses)) |=(=duct [duct %give git]) :: ++ deal :: pass to %gall @@ -227,13 +226,13 @@ ^+ +> ?^ tem +>(tem `[bet u.tem]) - (deal / [%poke [%dill-belt -:!>(bet) bet]]) + (deal /send/[ses] [%poke [%dill-belt -:!>(bet) bet]]) :: ++ hood-set-boot-apps (deal / [%poke %drum-set-boot-apps !>(lit.all)]) :: ++ peer - (deal / [%watch /drum]) + (deal /peer/[ses] [%watch /drum]) ::TODO rename subscription path :: ++ show :: permit reads on desk |= des=desk @@ -281,12 +280,20 @@ == -- :: - ++ ax :: make ++as - |= hen=duct + ++ ax :: make ++as from name + |= [hen=duct ses=@tas] ^- (unit _as) - =/ nux (~(get by dug.all) hen) + =/ nux (~(get by dug.all) ses) ?~ nux ~ - (some ~(. as hen u.nux)) + (some ~(. as hen ses u.nux)) + :: + ++ aw :: make ++as from wire + |= [hen=duct wir=wire] + ^- (unit _as) + %+ ax hen + ?+ wir %$ + [?(%peer %send) @ *] i.t.wir + == -- |% :: poke+peek pattern ++ call :: handle request @@ -297,7 +304,10 @@ ^+ [*(list move) ..^$] ~| wrapped-task =/ task=task ((harden task) wrapped-task) + :: unwrap session tasks, default to session %$ :: + =^ ses=@tas task + ?:(?=(%shot -.task) +.task [%$ task]) :: error notifications "downcast" to %crud :: =? task ?=(^ dud) @@ -330,7 +340,9 @@ =/ say (tuba "") =/ zon=axon [app input=[~ ~] width=80] :: - =^ moz all abet:(~(into as duc zon) ~) + =^ moz all abet:(~(into as duc %$ zon) ~) + ::REVIEW can anything relevant happen between %boot and %init? + =. eye.all (~(put ju eye.all) %$ duc) [moz ..^$] :: %flog tasks are unwrapped and sent back to us on our default duct :: @@ -351,37 +363,33 @@ ?: ?=(%knob -.task) =. veb.all (~(put by veb.all) tag.task level.task) [~ ..^$] + :: %view opens a subscription to the target session, on the current duct :: ?: ?=(%view -.task) - :: crash on viewing non-existent session - :: - ~| [%no-session session.task] - ?> =(~ session.task) - =/ session (need hey.all) - =/ nus (need (ax session)) + =/ nus + :: crash on viewing non-existent session + :: + ~| [%no-session ses] + (need (ax hen ses)) :: register the viewer and send a %hey so they get the full screen :: =^ moz all abet:(send:nus %hey ~) :- moz - ..^$(eye.all (~(put ju eye.all) session hen)) + ..^$(eye.all (~(put ju eye.all) ses hen)) + :: %flee closes a subscription to the target session, from the current duct :: ?: ?=(%flee -.task) :- ~ - ~| [%no-session session.task] - ?> =(~ session.task) - =/ session (need hey.all) - ..^$(eye.all (~(del ju eye.all) session hen)) + ..^$(eye.all (~(del ju eye.all) ses hen)) :: - =/ nus (ax hen) - =? nus &(?=(~ nus) ?=(^ hey.all)) - ::TODO allow specifying target session in task - (ax u.hey.all) + =/ nus + (ax hen ses) ?~ nus - :: :hen is an unrecognized duct + :: session :ses does not exist :: could be before %boot (or %boot failed) :: - ~& [%dill-call-no-flow hen -.task] + ~& [%dill-call-no-session ses hen -.task] =/ tan ?:(?=(%crud -.task) q.task ~) [((slog (flop tan)) ~) ..^$] :: @@ -414,8 +422,21 @@ see=$%([%lin (list @c)] [%klr stub]) == :: - ++ axle-4-to-5 |=(axle-4 [%5 +<+(dug (~(run by dug) axon-4-to-5))]) - ++ axon-4-to-5 |=(axon-4 [ram tem wid]) + ++ axle-4-to-5 + |= axle-4 + ^- axle + :- %5 + =- [hey nug nay lit veb] + %+ roll ~(tap by dug) + |= [[=duct =axon-4] nug=(map @tas axon) nay=(jug @tas duct)] + =/ ses=@tas + ~| [%unexpected-duct duct] + ?>(=([//term/1]~ duct) %$) + :- (~(put by nug) ses (axon-4-to-5 axon-4)) + %+ ~(put by nay) ses + (~(put in (~(get ju eye) duct)) duct) + :: + ++ axon-4-to-5 |=(axon-4 `axon`[ram tem wid]) -- :: ++ scry @@ -456,12 +477,11 @@ ?^ dud ~|(%dill-take-dud (mean tang.u.dud)) :: - =/ nus (ax hen) + =/ nus (aw hen tea) ?~ nus - :: :hen is an unrecognized duct - :: could be before %boot (or %boot failed) + :: :tea points to an unrecognized session :: - ~& [%dill-take-no-flow hen -.hin +<.hin] + ~& [%dill-take-no-session tea -.hin +<.hin] [~ ..^$] =^ moz all abet:(take:u.nus tea hin) [moz ..^$] From 9f0166914f89594b1f4c119f65eaf5a6c9349feb Mon Sep 17 00:00:00 2001 From: fang Date: Fri, 12 Feb 2021 00:58:09 +0100 Subject: [PATCH 013/104] dill: tidier gall %onto print Before recent dill changes, this wouldn't always be visible, since it would get drawn in place of (and subsequently get overwritten by) the prompt. Now that it displays consistently again, it should look a bit better than just a noun dump. This is somewhat redundant with gall's own "reloading agent" printfs, but you know what they say: printfs don't real! --- pkg/arvo/sys/vane/dill.hoon | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/arvo/sys/vane/dill.hoon b/pkg/arvo/sys/vane/dill.hoon index c3051f8f96..540e009300 100644 --- a/pkg/arvo/sys/vane/dill.hoon +++ b/pkg/arvo/sys/vane/dill.hoon @@ -247,10 +247,9 @@ ^+ +> ?- sih [%gall %onto *] - :: ~& [%take-gall-onto +>.sih] ?- -.+>.sih %| (crud %onto p.p.+>.sih) - %& (fore (tuba "{}") ~) + %& (fore (tuba "{(t q)}ed %{(t p)}":[t=trip p.p.sih]) ~) == :: [%gall %unto *] From 53cd568af94bedcb5fe11762d46c7556864393cf Mon Sep 17 00:00:00 2001 From: fang Date: Fri, 12 Feb 2021 01:02:29 +0100 Subject: [PATCH 014/104] dill: printf when rendering to non-default session As per the note a couple lines up, +fore depends on drum semantics being active. We can only guarantee those being present for the default session, not for any others. So, we print a warning when appropriate. --- pkg/arvo/sys/vane/dill.hoon | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/arvo/sys/vane/dill.hoon b/pkg/arvo/sys/vane/dill.hoon index 540e009300..4f2607483b 100644 --- a/pkg/arvo/sys/vane/dill.hoon +++ b/pkg/arvo/sys/vane/dill.hoon @@ -167,6 +167,7 @@ :: perhaps +send this to .ram instead? :: |= liz=(list (list @c)) + ~? !=(%$ ses) [%d %foreing-in-session ses] ^+ +> =. +> =| biz=(list blit) From 2e7afdd543cecfbd333b6ebb1012b60dab861f88 Mon Sep 17 00:00:00 2001 From: fang Date: Sat, 13 Feb 2021 00:07:04 +0100 Subject: [PATCH 015/104] lull: remove old/unused dill tasks Some of the remainder are still _presently_ unused, but point at functionality we want to support again in the near future. The ones removed here are either redundant or have no clear purpose. --- pkg/arvo/sys/lull.hoon | 6 +----- pkg/arvo/sys/vane/dill.hoon | 1 - pkg/urbit/vere/io/term.c | 6 ------ 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index f8628830ce..33ba339413 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -1007,9 +1007,7 @@ ++ dill ^? |% +$ gift :: out result <-$ - $% [%bbye ~] :: reset prompt - [%blit p=(list blit)] :: terminal output - [%burl p=@t] :: activate url + $% [%blit p=(list blit)] :: terminal output [%logo ~] :: logout [%meld ~] :: unify memory [%pack ~] :: compact memory @@ -1022,10 +1020,8 @@ [%crud p=@tas q=(list tank)] :: print error [%flog p=flog] :: wrapped error [%heft ~] :: memory report - [%harm ~] :: all terms hung up $>(%init vane-task) :: after gall ready [%meld ~] :: unify memory - [%noop ~] :: no operation [%pack ~] :: compact memory [%shot ses=@tas task=session-task] :: task for session [%talk p=tank] :: diff --git a/pkg/arvo/sys/vane/dill.hoon b/pkg/arvo/sys/vane/dill.hoon index 4f2607483b..34f0a3cd02 100644 --- a/pkg/arvo/sys/vane/dill.hoon +++ b/pkg/arvo/sys/vane/dill.hoon @@ -102,7 +102,6 @@ ^+ +> ?+ -.kyz ~& [%strange-kiss -.kyz] +> %flow +> - %harm +> %hail (send %hey ~) %belt (send `dill-belt`p.kyz) %text (fore (tuba p.kyz) ~) diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index f09f059a03..d81832fdfb 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -1732,12 +1732,6 @@ _term_io_kick(u3_auto* car_u, u3_noun wir, u3_noun cad) ret_o = c3n; } break; - // XX review, accepted and ignored - // - case c3__bbye: { - ret_o = c3y; - } break; - case c3__blit: { ret_o = c3y; From 00dd0656e8588550205a31edaf88752a78e38d04 Mon Sep 17 00:00:00 2001 From: fang Date: Sat, 13 Feb 2021 00:55:32 +0100 Subject: [PATCH 016/104] zuse: move styx engine into zuse styx and stub are both defined in lull. Having functions for dealing with them in zuse rather than userspace is fitting. While not a _common_ format per se, it still seems best at home in +format, instead of on its own. --- pkg/arvo/lib/hood/drum.hoon | 79 +------------------------------------ pkg/arvo/sys/zuse.hoon | 78 ++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 78 deletions(-) diff --git a/pkg/arvo/lib/hood/drum.hoon b/pkg/arvo/lib/hood/drum.hoon index 0933630ad2..3bbb7efc66 100644 --- a/pkg/arvo/lib/hood/drum.hoon +++ b/pkg/arvo/lib/hood/drum.hoon @@ -133,6 +133,7 @@ =| biz=(list dill-blit:dill) |% ++ this . +++ klr klr:format +$ state ^state :: proxy +$ any-state ^any-state :: proxy ++ on-init se-abet:this(eel (deft-fish our.hid)) @@ -1136,82 +1137,4 @@ ?: |(?=(~ a) (alnm i.a)) i $(i +(i), a t.a) -- -:: -++ klr :: styx/stub engine - =, dill - |% - ++ make :: stub from styx - |= a=styx ^- stub - =| b=stye - %+ reel - |- ^- stub - %- zing %+ turn a - |= a=$@(@t (pair styl styx)) - ?@ a [b (tuba (trip a))]~ - ^$(a q.a, b (styd p.a b)) - :: - |= [a=(pair stye (list @c)) b=stub] - ?~ b [a ~] - ?. =(p.a p.i.b) [a b] - [[p.a (weld q.a q.i.b)] t.b] - :: - ++ styd :: stye from styl - |= [a=styl b=stye] ^+ b :: with inheritance - :+ ?~ p.a p.b - ?~ u.p.a ~ - (~(put in p.b) u.p.a) - (fall p.q.a p.q.b) - (fall q.q.a q.q.b) - :: - ++ lent-char - |= a=stub ^- @ - (roll (lnts-char a) add) - :: - ++ lnts-char :: stub pair tail lengths - |= a=stub ^- (list @) - %+ turn a - |= a=(pair stye (list @c)) - (lent q.a) - :: - ++ brek :: index + incl-len of - |= [a=@ b=(list @)] :: stub pair w= idx a - =| [c=@ i=@] - |- ^- (unit (pair @ @)) - ?~ b ~ - =. c (add c i.b) - ?: (gte c a) - `[i c] - $(i +(i), b t.b) - :: - ++ slag :: slag stub, keep stye - |= [a=@ b=stub] - ^- stub - =+ c=(lnts-char b) - =+ i=(brek a c) - ?~ i b - =+ r=(^slag +(p.u.i) b) - ?: =(a q.u.i) - r - =+ n=(snag p.u.i b) - :_ r :- p.n - (^slag (sub (snag p.u.i c) (sub q.u.i a)) q.n) - :: - ++ scag :: scag stub, keep stye - |= [a=@ b=stub] - ^- stub - =+ c=(lnts-char b) - =+ i=(brek a c) - ?~ i b - ?: =(a q.u.i) - (^scag +(p.u.i) b) - %+ welp - (^scag p.u.i b) - =+ n=(snag p.u.i b) - :_ ~ :- p.n - (^scag (sub (snag p.u.i c) (sub q.u.i a)) q.n) - :: - ++ swag :: swag stub, keep stye - |= [[a=@ b=@] c=stub] - (scag b (slag a c)) - -- -- diff --git a/pkg/arvo/sys/zuse.hoon b/pkg/arvo/sys/zuse.hoon index c647366350..17d90e0462 100644 --- a/pkg/arvo/sys/zuse.hoon +++ b/pkg/arvo/sys/zuse.hoon @@ -3697,6 +3697,84 @@ ~ (some (~(run by lum) need)) -- ::dejs-soft + :: + ++ klr :: styx/stub engine + =, dill + |% + ++ make :: stub from styx + |= a=styx ^- stub + =| b=stye + %+ reel + |- ^- stub + %- zing %+ turn a + |= a=$@(@t (pair styl styx)) + ?@ a [b (tuba (trip a))]~ + ^$(a q.a, b (styd p.a b)) + :: + |= [a=(pair stye (list @c)) b=stub] + ?~ b [a ~] + ?. =(p.a p.i.b) [a b] + [[p.a (weld q.a q.i.b)] t.b] + :: + ++ styd :: stye from styl + |= [a=styl b=stye] ^+ b :: with inheritance + :+ ?~ p.a p.b + ?~ u.p.a ~ + (~(put in p.b) u.p.a) + (fall p.q.a p.q.b) + (fall q.q.a q.q.b) + :: + ++ lent-char + |= a=stub ^- @ + (roll (lnts-char a) add) + :: + ++ lnts-char :: stub text lengths + |= a=stub ^- (list @) + %+ turn a + |= a=(pair stye (list @c)) + (lent q.a) + :: + ++ brek :: index + incl-len of + |= [a=@ b=(list @)] :: stub pair w/ idx a + =| [c=@ i=@] + |- ^- (unit (pair @ @)) + ?~ b ~ + =. c (add c i.b) + ?: (gte c a) + `[i c] + $(i +(i), b t.b) + :: + ++ slag :: slag stub + |= [a=@ b=stub] + ^- stub + =+ c=(lnts-char b) + =+ i=(brek a c) + ?~ i b + =+ r=(^slag +(p.u.i) b) + ?: =(a q.u.i) + r + =+ n=(snag p.u.i b) + :_ r :- p.n + (^slag (sub (snag p.u.i c) (sub q.u.i a)) q.n) + :: + ++ scag :: scag stub + |= [a=@ b=stub] + ^- stub + =+ c=(lnts-char b) + =+ i=(brek a c) + ?~ i b + ?: =(a q.u.i) + (^scag +(p.u.i) b) + %+ welp + (^scag p.u.i b) + =+ n=(snag p.u.i b) + :_ ~ :- p.n + (^scag (sub (snag p.u.i c) (sub q.u.i a)) q.n) + :: + ++ swag :: swag stub + |= [[a=@ b=@] c=stub] + (scag b (slag a c)) + -- :: klr -- :: :: :::: ++differ :: (2d) hunt-mcilroy From 75b2c025e5ba6a7116da3feb9dac8784faad6f8e Mon Sep 17 00:00:00 2001 From: fang Date: Wed, 17 Feb 2021 00:59:52 +0100 Subject: [PATCH 017/104] term: cap & store cursor row position Adds the vertical position of the cursor to mirror state, and caps the cursor movement to the edges of the known window. --- pkg/urbit/include/vere/vere.h | 3 ++- pkg/urbit/vere/io/term.c | 24 +++++++++++++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/pkg/urbit/include/vere/vere.h b/pkg/urbit/include/vere/vere.h index 7dba712c32..7cf68e3f94 100644 --- a/pkg/urbit/include/vere/vere.h +++ b/pkg/urbit/include/vere/vere.h @@ -148,7 +148,8 @@ c3_y* lin_y; // current line (utf8) c3_w byt_w; // utf8 line-length c3_w wor_w; // utf32 line-length - c3_w cus_w; // cursor position + c3_w rus_w; // cursor position (row) + c3_w cus_w; // cursor position (column) } mir; struct { // escape code control diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index d81832fdfb..14d9abb93a 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -220,6 +220,7 @@ u3_term_log_init(void) uty_u->tat_u.mir.lin_y = 0; uty_u->tat_u.mir.byt_w = 0; uty_u->tat_u.mir.wor_w = 0; + uty_u->tat_u.mir.rus_w = 0; uty_u->tat_u.mir.cus_w = 0; uty_u->tat_u.esc.ape = c3n; @@ -488,15 +489,25 @@ _term_it_show_blank(u3_utty* uty_u) _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.clear_u); } -/* _term_it_move_cursor(): move cursor to row & column - NOTE: row 0 is at the bottom, col 0 is to the left -*/ +/* _term_it_move_cursor(): move cursor to row & column + * + * row 0 is at the bottom, col 0 is to the left. + * if the given position exceeds the known window size, + * it is clipped to stay within the window. + */ static void _term_it_move_cursor(u3_utty* uty_u, c3_w row_w, c3_w col_w) { - _term_it_send_csi(uty_u, 'H', 2, uty_u->tat_u.siz.row_l - row_w, col_w + 1); + c3_l row_l = uty_u->tat_u.siz.row_l; + c3_l col_l = uty_u->tat_u.siz.col_l; + if ( row_w >= row_l ) { row_w = row_l - 1; } + if ( col_w >= col_l ) { col_w = col_l - 1; } - //TODO should also store row + _term_it_send_csi(uty_u, 'H', 2, row_l - row_w, col_w + 1); + //TODO send s for saving cursor position? + + //TODO how does this interact with window resizing? + uty_u->tat_u.mir.rus_w = row_w; uty_u->tat_u.mir.cus_w = col_w; } @@ -603,6 +614,9 @@ _term_it_show_more(u3_utty* uty_u) } uty_u->tat_u.mir.cus_w = 0; + if ( uty_u->tat_u.mir.rus_w > 0 ) { + uty_u->tat_u.mir.rus_w--; + } } /* _term_it_path(): path for console file. From 30ac51e2816731a2617f2d60a413fbc19f0c8c9e Mon Sep 17 00:00:00 2001 From: fang Date: Wed, 17 Feb 2021 17:04:45 +0100 Subject: [PATCH 018/104] term: no longer redraw the prompt as part of %clr Instead, rely on the console application to send whatever is needed directly following a %clr blit. --- pkg/arvo/lib/hood/drum.hoon | 2 +- pkg/urbit/vere/io/term.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/arvo/lib/hood/drum.hoon b/pkg/arvo/lib/hood/drum.hoon index 3bbb7efc66..b6848111c0 100644 --- a/pkg/arvo/lib/hood/drum.hoon +++ b/pkg/arvo/lib/hood/drum.hoon @@ -755,7 +755,7 @@ ?: =(pos.inp len) ta-bel (ta-kil %r [pos.inp (sub len pos.inp)]) - %l +>(..ta (se-blit %clr ~)) + %l +>(..ta (se-blit(q.mir ~) %clr ~)) %n (ta-aro %d) %p (ta-aro %u) %r ?~ ris diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index 14d9abb93a..bf7feefdce 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -1420,7 +1420,6 @@ _term_ef_blit(u3_utty* uty_u, case c3__clr: { if ( c3n == u3_Host.ops_u.tem ) { _term_it_show_blank(uty_u); - _term_it_refresh_line(uty_u); } } break; From 8a3605f8182bc8d552e1f6b82130d7bb690df6e2 Mon Sep 17 00:00:00 2001 From: fang Date: Wed, 17 Feb 2021 17:17:46 +0100 Subject: [PATCH 019/104] term: rename _show_clear to _clear_line --- pkg/urbit/vere/io/term.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index bf7feefdce..916c106284 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -467,10 +467,10 @@ _term_it_send_cord(u3_utty* uty_u, u3z(txt); } -/* _term_it_show_clear(): clear to the beginning of the current line. +/* _term_it_clear_line(): clear line of cursor */ static void -_term_it_show_clear(u3_utty* uty_u) +_term_it_clear_line(u3_utty* uty_u) { if ( uty_u->tat_u.siz.col_l ) { _term_it_dump(uty_u, TERM_LIT("\r")); @@ -545,7 +545,7 @@ _term_it_refresh_line(u3_utty* uty_u) c3_w wor_w = tat_u->mir.wor_w; c3_w cus_w = tat_u->mir.cus_w; - _term_it_show_clear(uty_u); + _term_it_clear_line(uty_u); _term_it_show_line(uty_u, wor_w); _term_it_move_cursor(uty_u, 0, cus_w); } @@ -1437,14 +1437,14 @@ _term_ef_blit(u3_utty* uty_u, case c3__klr: { if ( c3n == u3_Host.ops_u.tem ) { - _term_it_show_clear(uty_u); + _term_it_clear_line(uty_u); } _term_it_show_stub(uty_u, u3k(u3t(blt))); } break; case c3__lin: { if ( c3n == u3_Host.ops_u.tem ) { - _term_it_show_clear(uty_u); + _term_it_clear_line(uty_u); } _term_it_show_tour(uty_u, u3k(u3t(blt))); } break; @@ -1472,10 +1472,10 @@ _term_ef_blit(u3_utty* uty_u, // XX check u3_Host.ops_u.tem ? // XX this looks to be broken, - // multiple calls to _show_clear will discard the mirror state + // multiple calls to _clear_line will discard the mirror state // if ( c3y == u3a_is_atom(txt) ) { - _term_it_show_clear(uty_u); + _term_it_clear_line(uty_u); _term_it_send_cord(uty_u, u3k(txt)); From a4e20facb77cf851c984a8dc9ae8cf4f584adc30 Mon Sep 17 00:00:00 2001 From: fang Date: Thu, 18 Feb 2021 01:28:25 +0100 Subject: [PATCH 020/104] term: decouple line clearing from line printing This simplifies the behavior of individual blits, making their implementation simpler and giving arvo more control. This lets us write on top of existing content, instead of completely replacing the affected row. Additionally, lets us draw starting at the cursor position, instead of the leftmost column. To retain the previous behavior, preface with [%hop 0] to move the cursor to the start of the line, [%wyp ~] to clear the existing content, and finally your %lin to render it. --- pkg/arvo/lib/hood/drum.hoon | 8 ++++++-- pkg/arvo/sys/lull.hoon | 7 ++++--- pkg/arvo/sys/vane/dill.hoon | 2 +- pkg/urbit/include/c/motes.h | 1 + pkg/urbit/vere/io/term.c | 14 +++++++------- 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/pkg/arvo/lib/hood/drum.hoon b/pkg/arvo/lib/hood/drum.hoon index b6848111c0..581585c42c 100644 --- a/pkg/arvo/lib/hood/drum.hoon +++ b/pkg/arvo/lib/hood/drum.hoon @@ -546,7 +546,11 @@ :: so update the prompt mirror accordingly. :: =. mir [0 ~] - (se-blit %mor lin [%nel ~] ~) + ::TODO doing hops and wyps conditionally based on the mirror state seems + :: better, but doesn't cover edge cases. results in dojo's ">=" being + :: rendered alongside the prompt in scrollback, for example. + :: figure out a way to make that work! + (se-blit %mor [%hop 0] [%wyp ~] lin [%nel ~] ~) :: ++ se-dump :: print tanks |= tac=(list tank) @@ -597,7 +601,7 @@ |= lin=(pair @ud stub) ^+ +> ?: =(mir lin) +> - (se-blit(mir lin) %mor [%klr q.lin] [%hop p.lin] ~) + (se-blit(mir lin) %mor [%hop 0] [%wyp ~] [%klr q.lin] [%hop p.lin] ~) :: ++ se-just :: adjusted buffer |= [pom=stub lin=(pair @ud (list @c))] diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index 33ba339413..5323878c7a 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -1059,13 +1059,14 @@ +$ blit :: outside blit $% [%bel ~] :: make a noise [%clr ~] :: clear the screen - [%hop p=$@(@ud [r=@ud c=@ud])] :: set cursor row/pos - [%klr p=stub] :: set styled line - [%lin p=(list @c)] :: set line at cursor + [%hop p=$@(@ud [r=@ud c=@ud])] :: set cursor col/pos + [%klr p=stub] :: put styled + [%lin p=(list @c)] :: put text at cursor [%nel ~] :: newline [%sag p=path q=*] :: save to jamfile [%sav p=path q=@] :: save to file [%url p=@t] :: activate url + [%wyp ~] :: wipe cursor line == :: +$ dill-belt :: inside belt $% belt :: outside belt diff --git a/pkg/arvo/sys/vane/dill.hoon b/pkg/arvo/sys/vane/dill.hoon index 34f0a3cd02..b3a51890b2 100644 --- a/pkg/arvo/sys/vane/dill.hoon +++ b/pkg/arvo/sys/vane/dill.hoon @@ -171,7 +171,7 @@ =. +> =| biz=(list blit) |- ^+ +>.^$ - ?~ liz (done %blit biz) + ?~ liz (done %blit [%hop 0] [%wyp ~] biz) $(liz t.liz, biz (welp biz [%lin i.liz] [%nel ~] ~)) :: since dill is acting on its own accord, :: we %hey the term app so it may clean up. diff --git a/pkg/urbit/include/c/motes.h b/pkg/urbit/include/c/motes.h index 0ff014ec7c..a06d7d2577 100644 --- a/pkg/urbit/include/c/motes.h +++ b/pkg/urbit/include/c/motes.h @@ -1269,6 +1269,7 @@ # define c3__wtsg c3_s4('w','t','s','g') # define c3__wtts c3_s4('w','t','t','s') # define c3__wtzp c3_s4('w','t','z','p') +# define c3__wyp c3_s3('w','y','p') # define c3__wyrd c3_s4('w','y','r','d') # define c3__yew c3_s3('y','a','w') # define c3__yell c3_s4('y','e','l','l') diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index 916c106284..3363a37c88 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -601,7 +601,7 @@ _term_it_set_line(u3_utty* uty_u, _term_it_show_line(uty_u, wor_w); } -/* _term_it_show_more(): new current line. +/* _term_it_show_more(): render newline, moving cursor down */ static void _term_it_show_more(u3_utty* uty_u) @@ -1436,16 +1436,10 @@ _term_ef_blit(u3_utty* uty_u, } break; case c3__klr: { - if ( c3n == u3_Host.ops_u.tem ) { - _term_it_clear_line(uty_u); - } _term_it_show_stub(uty_u, u3k(u3t(blt))); } break; case c3__lin: { - if ( c3n == u3_Host.ops_u.tem ) { - _term_it_clear_line(uty_u); - } _term_it_show_tour(uty_u, u3k(u3t(blt))); } break; @@ -1483,6 +1477,12 @@ _term_ef_blit(u3_utty* uty_u, _term_it_refresh_line(uty_u); } } break; + + case c3__wyp: { + if ( c3n == u3_Host.ops_u.tem ) { + _term_it_clear_line(uty_u); + } + } break; } u3z(blt); From 0d8288e666c93a40f50b9b130d386063b2768066 Mon Sep 17 00:00:00 2001 From: fang Date: Thu, 18 Feb 2021 01:31:52 +0100 Subject: [PATCH 021/104] term: better %url handling %url blits are meant for "activating" urls. Of course, opening a new browser tab from within a C program is difficult, so we don't do it. This is still better than doing the faux activation by just printing the url. term.c no longer really knows where/how to draw it, and it's meant as interactive behavior rather than visual output, anyway. --- pkg/arvo/lib/hood/drum.hoon | 1 + pkg/urbit/vere/io/term.c | 16 ++-------------- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/pkg/arvo/lib/hood/drum.hoon b/pkg/arvo/lib/hood/drum.hoon index 581585c42c..be7d5a02aa 100644 --- a/pkg/arvo/lib/hood/drum.hoon +++ b/pkg/arvo/lib/hood/drum.hoon @@ -827,6 +827,7 @@ [%tab *] +>(..ta (se-tab p.fec)) [%tan *] +>(..ta (se-dump p.fec)) [%txt *] +>(..ta (se-text p.fec)) + [%url *] +>(..ta (se-text:(se-blit fec) (trip p.fec))) == :: ++ ta-dog :: change cursor diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index 3363a37c88..9dfc755d4f 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -1462,20 +1462,8 @@ _term_ef_blit(u3_utty* uty_u, } break; case c3__url: { - u3_noun txt = u3t(blt); - - // XX check u3_Host.ops_u.tem ? - // XX this looks to be broken, - // multiple calls to _clear_line will discard the mirror state - // - if ( c3y == u3a_is_atom(txt) ) { - _term_it_clear_line(uty_u); - - _term_it_send_cord(uty_u, u3k(txt)); - - _term_it_show_more(uty_u); - _term_it_refresh_line(uty_u); - } + // platform-agnostically opening the default web browser from within a + // c program is an unsolved problem. } break; case c3__wyp: { From d974d4cc4e0e782af940664198bc8107a3d92dcd Mon Sep 17 00:00:00 2001 From: fang Date: Thu, 18 Feb 2021 13:46:51 +0100 Subject: [PATCH 022/104] term: restore cursor position after draw calls This keeps the cursor position at the last %hop location. And being able to go back to that position without relying on state is just plain convenient. The exception here is %nel blits, which move the cursor (down and) to the start of the line, as expected of "new line" semantics. --- pkg/urbit/include/vere/vere.h | 2 ++ pkg/urbit/vere/io/term.c | 15 +++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/pkg/urbit/include/vere/vere.h b/pkg/urbit/include/vere/vere.h index 7cf68e3f94..08f27798c1 100644 --- a/pkg/urbit/include/vere/vere.h +++ b/pkg/urbit/include/vere/vere.h @@ -199,6 +199,8 @@ uv_buf_t el_u; // clr_bol clear to beginning // uv_buf_t el1_u; // clr_eol clear to end uv_buf_t ed_u; // clear to end of screen + uv_buf_t sc_u; // save cursor position + uv_buf_t rc_u; // restore cursor position uv_buf_t bel_u; // bel sound bell uv_buf_t cub1_u; // parm_left uv_buf_t cuf1_u; // parm_right diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index 9dfc755d4f..9de6194f91 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -167,6 +167,8 @@ u3_term_log_init(void) uty_u->ufo_u.out.el_u = TERM_LIT_BUF("\033[K"); // uty_u->ufo_u.out.el1_u = TERM_LIT_BUF("\033[1K"); uty_u->ufo_u.out.ed_u = TERM_LIT_BUF("\033[J"); + uty_u->ufo_u.out.sc_u = TERM_LIT_BUF("\033[s"); + uty_u->ufo_u.out.rc_u = TERM_LIT_BUF("\033[u"); uty_u->ufo_u.out.bel_u = TERM_LIT_BUF("\x7"); uty_u->ufo_u.out.cub1_u = TERM_LIT_BUF("\x8"); uty_u->ufo_u.out.cuf1_u = TERM_LIT_BUF("\033[C"); @@ -475,9 +477,9 @@ _term_it_clear_line(u3_utty* uty_u) if ( uty_u->tat_u.siz.col_l ) { _term_it_dump(uty_u, TERM_LIT("\r")); _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.el_u); + _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.rc_u); uty_u->tat_u.mir.wor_w = 0; - uty_u->tat_u.mir.cus_w = 0; } } @@ -487,6 +489,7 @@ static void _term_it_show_blank(u3_utty* uty_u) { _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.clear_u); + _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.rc_u); } /* _term_it_move_cursor(): move cursor to row & column @@ -504,9 +507,8 @@ _term_it_move_cursor(u3_utty* uty_u, c3_w row_w, c3_w col_w) if ( col_w >= col_l ) { col_w = col_l - 1; } _term_it_send_csi(uty_u, 'H', 2, row_l - row_w, col_w + 1); - //TODO send s for saving cursor position? + _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.sc_u); - //TODO how does this interact with window resizing? uty_u->tat_u.mir.rus_w = row_w; uty_u->tat_u.mir.cus_w = col_w; } @@ -528,11 +530,11 @@ _term_it_show_line(u3_utty* uty_u, c3_w wor_w) memcpy(hun_y, tat_u->mir.lin_y, len_w); _term_it_send(uty_u, len_w, hun_y); + _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.rc_u); } // XX refactor to avoid updating state // - tat_u->mir.cus_w += wor_w; tat_u->mir.wor_w = wor_w; } @@ -543,11 +545,11 @@ _term_it_refresh_line(u3_utty* uty_u) { u3_utat* tat_u = &uty_u->tat_u; c3_w wor_w = tat_u->mir.wor_w; - c3_w cus_w = tat_u->mir.cus_w; + _term_it_move_cursor(uty_u, 0, 0); _term_it_clear_line(uty_u); _term_it_show_line(uty_u, wor_w); - _term_it_move_cursor(uty_u, 0, cus_w); + _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.rc_u); } /* _term_it_set_line(): set current line. @@ -617,6 +619,7 @@ _term_it_show_more(u3_utty* uty_u) if ( uty_u->tat_u.mir.rus_w > 0 ) { uty_u->tat_u.mir.rus_w--; } + _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.sc_u); } /* _term_it_path(): path for console file. From b936e1d92853cbca6c632e8b236efafcad835362 Mon Sep 17 00:00:00 2001 From: fang Date: Thu, 18 Feb 2021 20:03:18 +0100 Subject: [PATCH 023/104] term: save only changes to the bottom line The bottom line is where we draw the spinner, so we're only interested in screen draws that affect that part of the screen (so that we may restore it after having drawn the spinner there). Given recent changes, redraws should be less frequent than updates, so we lazily store the utf32 encoded line contents in state, instead of the eagerly converted utf8 version. --- pkg/urbit/include/vere/vere.h | 3 +- pkg/urbit/vere/io/term.c | 162 ++++++++++++++++++++++------------ 2 files changed, 107 insertions(+), 58 deletions(-) diff --git a/pkg/urbit/include/vere/vere.h b/pkg/urbit/include/vere/vere.h index 08f27798c1..86acd1eb36 100644 --- a/pkg/urbit/include/vere/vere.h +++ b/pkg/urbit/include/vere/vere.h @@ -145,8 +145,7 @@ } siz; struct { - c3_y* lin_y; // current line (utf8) - c3_w byt_w; // utf8 line-length + c3_w* lin_w; // bottom line (utf32) c3_w wor_w; // utf32 line-length c3_w rus_w; // cursor position (row) c3_w cus_w; // cursor position (column) diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index 9de6194f91..56daedf531 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -219,8 +219,7 @@ u3_term_log_init(void) // Initialize mirror and accumulator state. // { - uty_u->tat_u.mir.lin_y = 0; - uty_u->tat_u.mir.byt_w = 0; + uty_u->tat_u.mir.lin_w = 0; uty_u->tat_u.mir.wor_w = 0; uty_u->tat_u.mir.rus_w = 0; uty_u->tat_u.mir.cus_w = 0; @@ -469,17 +468,32 @@ _term_it_send_cord(u3_utty* uty_u, u3z(txt); } +/* _term_it_free_line(): wipe line stored by _term_it_save_line +*/ +static void +_term_it_free_line(u3_utty* uty_u) +{ + c3_free(uty_u->tat_u.mir.lin_w); + uty_u->tat_u.mir.lin_w = 0; + uty_u->tat_u.mir.wor_w = 0; +} + /* _term_it_clear_line(): clear line of cursor */ static void _term_it_clear_line(u3_utty* uty_u) { + //REVIEW why this conditional? if ( uty_u->tat_u.siz.col_l ) { _term_it_dump(uty_u, TERM_LIT("\r")); _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.el_u); _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.rc_u); + } - uty_u->tat_u.mir.wor_w = 0; + // if we're clearing the bottom line, clear our mirror of it too + // + if ( 0 == uty_u->tat_u.mir.rus_w ) { + _term_it_free_line(uty_u); } } @@ -513,51 +527,10 @@ _term_it_move_cursor(u3_utty* uty_u, c3_w row_w, c3_w col_w) uty_u->tat_u.mir.cus_w = col_w; } -/* _term_it_show_line(): render current line. +/* _term_it_show_line(): print at cursor */ static void -_term_it_show_line(u3_utty* uty_u, c3_w wor_w) -{ - u3_utat* tat_u = &uty_u->tat_u; - - // we have to reallocate the current line on write, - // or we have a data race if a) the write is async, - // and b) a new output line arrives before the write completes. - // - { - c3_w len_w = tat_u->mir.byt_w; - c3_y* hun_y = c3_malloc(len_w); - memcpy(hun_y, tat_u->mir.lin_y, len_w); - - _term_it_send(uty_u, len_w, hun_y); - _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.rc_u); - } - - // XX refactor to avoid updating state - // - tat_u->mir.wor_w = wor_w; -} - -/* _term_it_refresh_line(): refresh current line. -*/ -static void -_term_it_refresh_line(u3_utty* uty_u) -{ - u3_utat* tat_u = &uty_u->tat_u; - c3_w wor_w = tat_u->mir.wor_w; - - _term_it_move_cursor(uty_u, 0, 0); - _term_it_clear_line(uty_u); - _term_it_show_line(uty_u, wor_w); - _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.rc_u); -} - -/* _term_it_set_line(): set current line. -*/ -static void -_term_it_set_line(u3_utty* uty_u, - c3_w* lin_w, - c3_w wor_w) +_term_it_show_line(u3_utty* uty_u, c3_w* lin_w, c3_w wor_w) { u3_utat* tat_u = &uty_u->tat_u; c3_y* hun_y = (c3_y*)lin_w; @@ -595,12 +568,84 @@ _term_it_set_line(u3_utty* uty_u, } } - c3_free(tat_u->mir.lin_y); - tat_u->mir.lin_y = hun_y; - tat_u->mir.byt_w = byt_w; - tat_u->mir.wor_w = wor_w; + //NOTE lin_w freed through hun_y by _send + _term_it_send(uty_u, byt_w, hun_y); + _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.rc_u); +} - _term_it_show_line(uty_u, wor_w); +/* _term_it_refresh_line(): refresh current line. +*/ +static void +_term_it_refresh_line(u3_utty* uty_u) //TODO rename restore +{ + u3_utat* tat_u = &uty_u->tat_u; + c3_w* lin_w = tat_u->mir.lin_w; + c3_w wor_w = tat_u->mir.wor_w; + + if ( (0 != lin_w) && (0 < wor_w) ) { + // we have to reallocate the current line on write, + // or we have a data race if a) the write is async, + // and b) a new output line arrives before the write completes. + // also, _show_line would free it. + // + c3_w* hun_w = c3_malloc( sizeof(c3_w) * wor_w ); + memcpy(hun_w, lin_w, wor_w * sizeof(c3_w)); + + _term_it_send_csi(uty_u, 'H', 2, tat_u->siz.row_l, 0); + _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.el_u); + _term_it_show_line(uty_u, hun_w, wor_w); + } +} + +/* _term_it_save_line(): store line if relevant to internal logic + * RETAINs lin_w + */ +static void +_term_it_save_line(u3_utty* uty_u, c3_w* lin_w, c3_w wor_w) +{ + u3_utat* tat_u = &uty_u->tat_u; + + // keep track of changes to bottom-most line, to aid spinner drawing logic + // + if ( 0 == tat_u->mir.rus_w ) { + c3_w* nip_w = tat_u->mir.lin_w; + c3_w wod_w = tat_u->mir.wor_w; + c3_w off_w = tat_u->mir.cus_w; + c3_w wyd_w = off_w + wor_w; + + // if we have no buffer, make one + // + if ( 0 == nip_w ) { + nip_w = c3_malloc( sizeof(c3_w) * wyd_w ); + wod_w = wyd_w; + + // initialize offset with spaces + // + for ( c3_w i_w = 0; i_w < off_w; i_w++ ) { + nip_w[i_w] = ' '; + } + } + // if we have a buffer, but it's too short, make a bigger one + // + else if ( wyd_w > wod_w ) { + c3_w* nic_w = c3_malloc( sizeof(c3_w) * wyd_w ); + memcpy(nic_w, nip_w, wod_w); + + // initialize fresh offset with spaces + // + for ( c3_w i_w = wod_w; i_w < off_w; i_w++ ) { + nic_w[i_w] = ' '; + } + + c3_free(nip_w); + nip_w = nic_w; + wod_w = wyd_w; + } + + memcpy(nip_w + off_w, lin_w, sizeof(c3_w) * wor_w); + tat_u->mir.lin_w = nip_w; + tat_u->mir.wor_w = wod_w; + } } /* _term_it_show_more(): render newline, moving cursor down @@ -613,13 +658,18 @@ _term_it_show_more(u3_utty* uty_u) } else { _term_it_dump(uty_u, TERM_LIT("\r\n")); + _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.sc_u); } uty_u->tat_u.mir.cus_w = 0; if ( uty_u->tat_u.mir.rus_w > 0 ) { uty_u->tat_u.mir.rus_w--; } - _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.sc_u); + else { + // newline at bottom of screen, so bottom line is now empty + // + _term_it_free_line(uty_u); + } } /* _term_it_path(): path for console file. @@ -1176,8 +1226,6 @@ u3_term_ef_ctlc(void) _term_ovum_plan(uty_u->car_u, wir, cad); } - - _term_it_refresh_line(uty_u); } /* _term_it_put_value(): put numeric color value on lin_w. @@ -1378,7 +1426,8 @@ _term_it_show_stub(u3_utty* uty_u, } } - _term_it_set_line(uty_u, lin_w, i_w); + _term_it_save_line(uty_u, lin_w, i_w); + _term_it_show_line(uty_u, lin_w, i_w); u3z(tub); } @@ -1400,7 +1449,8 @@ _term_it_show_tour(u3_utty* uty_u, } } - _term_it_set_line(uty_u, lin_w, len_w); + _term_it_save_line(uty_u, lin_w, len_w); + _term_it_show_line(uty_u, lin_w, len_w); u3z(lin); } From 881f9ebfaaf34d6702d949d18565e628105d3ac5 Mon Sep 17 00:00:00 2001 From: fang Date: Fri, 19 Feb 2021 12:24:31 +0100 Subject: [PATCH 024/104] drum: redraw prompt only if it changed --- pkg/arvo/lib/hood/drum.hoon | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/arvo/lib/hood/drum.hoon b/pkg/arvo/lib/hood/drum.hoon index be7d5a02aa..257bfee91e 100644 --- a/pkg/arvo/lib/hood/drum.hoon +++ b/pkg/arvo/lib/hood/drum.hoon @@ -601,7 +601,9 @@ |= lin=(pair @ud stub) ^+ +> ?: =(mir lin) +> - (se-blit(mir lin) %mor [%hop 0] [%wyp ~] [%klr q.lin] [%hop p.lin] ~) + %+ se-blit(mir lin) %mor + ?: =(q.mir q.lin) [%hop p.lin]~ + [[%hop 0] [%wyp ~] [%klr q.lin] [%hop p.lin] ~] :: ++ se-just :: adjusted buffer |= [pom=stub lin=(pair @ud (list @c))] From 84fd5746362275a991bba9c91f72d9c18f493da2 Mon Sep 17 00:00:00 2001 From: fang Date: Fri, 19 Feb 2021 12:50:52 +0100 Subject: [PATCH 025/104] term: ensure pre-init logging renders nicely Without the \r, the first couple printfs (generally, regarding replay) would not align on the lefthand side. --- pkg/urbit/vere/io/term.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index 56daedf531..428ed936f9 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -1623,7 +1623,7 @@ u3_term_io_loja(int x) } } else { - fprintf(stdout, "\n"); + fprintf(stdout, "\r\n"); } } From ea1b348754d82eb9734d36319175b76240de754b Mon Sep 17 00:00:00 2001 From: fang Date: Fri, 19 Feb 2021 14:45:59 +0100 Subject: [PATCH 026/104] term: ensure spinner is drawn on the bottom line That's the one line we track. If it gets drawn anywhere else, we can't restore the overwritten contents. --- pkg/urbit/vere/io/term.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index 428ed936f9..6a5acc2b09 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -1037,8 +1037,14 @@ _term_spin_step(u3_utty* uty_u) // One-time cursor backoff. // if ( c3n == tat_u->sun_u.diz_o ) { - c3_w i_w; + // if we know where the bottom line is, and the cursor is not on it, + // move it to the bottom left + // + if ( tat_u->siz.row_l && tat_u->mir.rus_w > 0 ) { + _term_it_send_csi(uty_u, 'H', 2, tat_u->siz.row_l, 0); + } + c3_w i_w; for ( i_w = bac_w; i_w < sol_w; i_w++ ) { if ( lef_u.len != write(fid_i, lef_u.base, lef_u.len) ) { return; From 66f37099ba35eff9148acb5009c28f83b113f93d Mon Sep 17 00:00:00 2001 From: fang Date: Fri, 19 Feb 2021 14:51:28 +0100 Subject: [PATCH 027/104] vere: clean up, rename, undo debug changes, etc. --- pkg/urbit/include/vere/vere.h | 4 ++-- pkg/urbit/vere/io/term.c | 33 +++++++++------------------------ pkg/urbit/vere/lord.c | 3 +-- pkg/urbit/vere/pier.c | 2 +- pkg/urbit/worker/main.c | 3 +-- 5 files changed, 14 insertions(+), 31 deletions(-) diff --git a/pkg/urbit/include/vere/vere.h b/pkg/urbit/include/vere/vere.h index 86acd1eb36..4157e6ea6b 100644 --- a/pkg/urbit/include/vere/vere.h +++ b/pkg/urbit/include/vere/vere.h @@ -195,8 +195,8 @@ // } inn; struct { uv_buf_t clear_u; // clear_screen - uv_buf_t el_u; // clr_bol clear to beginning - // uv_buf_t el1_u; // clr_eol clear to end + uv_buf_t el_u; // clr_bol clear to end of line + // uv_buf_t el1_u; // clr_eol clear to beginning of line uv_buf_t ed_u; // clear to end of screen uv_buf_t sc_u; // save cursor position uv_buf_t rc_u; // restore cursor position diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index 6a5acc2b09..edf113409f 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -453,21 +453,6 @@ _term_it_send_csi(u3_utty *uty_u, c3_c cmd_c, c3_w num_w, ...) _term_it_dump_buf(uty_u, &cmd_u); } -/* _term_it_send_cord(): write a cord. -*/ -static void -_term_it_send_cord(u3_utty* uty_u, - u3_atom txt) -{ - c3_w len_w = u3r_met(3, txt); - c3_y* hun_y = c3_malloc(len_w); - u3r_bytes(0, len_w, hun_y, txt); - - _term_it_send(uty_u, len_w, hun_y); - - u3z(txt); -} - /* _term_it_free_line(): wipe line stored by _term_it_save_line */ static void @@ -573,10 +558,10 @@ _term_it_show_line(u3_utty* uty_u, c3_w* lin_w, c3_w wor_w) _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.rc_u); } -/* _term_it_refresh_line(): refresh current line. +/* _term_it_restore_line(): refresh current line. */ static void -_term_it_refresh_line(u3_utty* uty_u) //TODO rename restore +_term_it_restore_line(u3_utty* uty_u) { u3_utat* tat_u = &uty_u->tat_u; c3_w* lin_w = tat_u->mir.lin_w; @@ -648,10 +633,10 @@ _term_it_save_line(u3_utty* uty_u, c3_w* lin_w, c3_w wor_w) } } -/* _term_it_show_more(): render newline, moving cursor down +/* _term_it_show_nel(): render newline, moving cursor down */ static void -_term_it_show_more(u3_utty* uty_u) +_term_it_show_nel(u3_utty* uty_u) { if ( c3y == u3_Host.ops_u.tem ) { _term_it_dump(uty_u, TERM_LIT("\n")); @@ -778,6 +763,7 @@ _term_io_belt(u3_utty* uty_u, u3_noun blb) { u3_ovum* egg_u = _term_ovum_plan(uty_u->car_u, wir, cad); + //REVIEW do we not want even a small delay here? // no spinner delay on %ret // if ( c3__ret == u3h(blb) ) { @@ -1129,7 +1115,7 @@ u3_term_stop_spinner(void) uv_timer_stop(&tat_u->sun_u.tim_u); if ( c3y == tat_u->sun_u.diz_o ) { - _term_it_refresh_line(uty_u); + _term_it_restore_line(uty_u); tat_u->sun_u.end_d = _term_msc_out_host(); tat_u->sun_u.diz_o = c3n; } @@ -1503,7 +1489,7 @@ _term_ef_blit(u3_utty* uty_u, } break; case c3__nel: { - _term_it_show_more(uty_u); + _term_it_show_nel(uty_u); } break; case c3__sav: { @@ -1526,9 +1512,7 @@ _term_ef_blit(u3_utty* uty_u, } break; case c3__wyp: { - if ( c3n == u3_Host.ops_u.tem ) { - _term_it_clear_line(uty_u); - } + _term_it_clear_line(uty_u); } break; } @@ -1600,6 +1584,7 @@ u3_term_io_loja(int x) } else { if ( c3y == u3_Host.ops_u.tem ) { + fprintf(stdout, "\n"); fflush(stdout); } else { diff --git a/pkg/urbit/vere/lord.c b/pkg/urbit/vere/lord.c index 7c8b165150..20fa660e54 100644 --- a/pkg/urbit/vere/lord.c +++ b/pkg/urbit/vere/lord.c @@ -373,8 +373,7 @@ _lord_plea_flog(u3_lord* god_u, u3_noun dat) } c3_c* tan_c = u3r_string(dat); - // u3C.stderr_log_f(tan_c); - u3l_log("y%sy", tan_c); + u3C.stderr_log_f(tan_c); c3_free(tan_c); if ( 0 != pir_u->sog_f ) { diff --git a/pkg/urbit/vere/pier.c b/pkg/urbit/vere/pier.c index edf7c3fdee..a9aac357b7 100644 --- a/pkg/urbit/vere/pier.c +++ b/pkg/urbit/vere/pier.c @@ -301,7 +301,7 @@ _pier_on_lord_work_spin(void* ptr_v, u3_atom pin, c3_o del_o) u3_term_start_spinner(pin, del_o); } -/* _pier_on_lord_work_spin(): stop spinner +/* _pier_on_lord_work_spun(): stop spinner */ static void _pier_on_lord_work_spun(void* ptr_v) diff --git a/pkg/urbit/worker/main.c b/pkg/urbit/worker/main.c index 0034eb012a..46895f093b 100644 --- a/pkg/urbit/worker/main.c +++ b/pkg/urbit/worker/main.c @@ -82,8 +82,7 @@ _cw_serf_send_slog(u3_noun hod) static void _cw_serf_send_stdr(c3_c* str_c) { - // _cw_serf_send(u3nc(c3__flog, u3i_string(str_c))); - _cw_serf_send(u3nc(c3__flog, u3i_string("lmao"))); + _cw_serf_send(u3nc(c3__flog, u3i_string(str_c))); } From 374c6c8f4a2a6043a824a6daef992da84e9aef8d Mon Sep 17 00:00:00 2001 From: fang Date: Fri, 19 Feb 2021 14:53:14 +0100 Subject: [PATCH 028/104] vere: render printfs in grey To hint to developers that this form of output isn't as concrete or reliable as they might assume it to be. --- pkg/urbit/vere/pier.c | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/urbit/vere/pier.c b/pkg/urbit/vere/pier.c index a9aac357b7..80f35de58b 100644 --- a/pkg/urbit/vere/pier.c +++ b/pkg/urbit/vere/pier.c @@ -2212,6 +2212,7 @@ u3_pier_tank(c3_l tab_l, c3_w pri_w, u3_noun tac) case 3: fprintf(fil_u, "\033[31m>>> "); break; case 2: fprintf(fil_u, "\033[33m>> "); break; case 1: fprintf(fil_u, "\033[32m> "); break; + case 0: fprintf(fil_u, "\033[90m" ); break; } } else { From 74924d34683f8e9f1b8e6a9bec9ca555151afa77 Mon Sep 17 00:00:00 2001 From: fang Date: Mon, 8 Mar 2021 16:19:33 +0100 Subject: [PATCH 029/104] webterm: update for nu-dill, rewrite with xterm.js Updates /app/herm and dependencies to work with latest dill, and rewrites the entire webterm frontend to use xterm.js for rendering. Webterm code needs a bit more work. Its subscription handling might want to be moved out, it needs to handle resizing, react to landscape theme changes, etc. --- pkg/arvo/app/herm.hoon | 11 +- pkg/arvo/mar/blit.hoon | 4 +- pkg/interface/package-lock.json | 10 + pkg/interface/package.json | 2 + pkg/interface/src/logic/api/global.ts | 2 + pkg/interface/src/logic/api/term.ts | 18 + pkg/interface/src/logic/lib/bel.js | 1 - pkg/interface/src/logic/lib/bel.ts | 1 + pkg/interface/src/types/term-update.ts | 33 ++ pkg/interface/src/views/apps/term/api.js | 47 -- pkg/interface/src/views/apps/term/app.js | 94 ---- pkg/interface/src/views/apps/term/app.tsx | 413 ++++++++++++++++++ .../src/views/apps/term/components/history.js | 33 -- .../src/views/apps/term/components/input.js | 114 ----- .../src/views/apps/term/components/line.js | 68 --- .../src/views/apps/term/css/custom.css | 141 ++++++ pkg/interface/src/views/apps/term/store.js | 90 ---- .../src/views/apps/term/subscription.js | 82 ---- 18 files changed, 626 insertions(+), 538 deletions(-) create mode 100644 pkg/interface/src/logic/api/term.ts delete mode 100644 pkg/interface/src/logic/lib/bel.js create mode 100644 pkg/interface/src/logic/lib/bel.ts create mode 100644 pkg/interface/src/types/term-update.ts delete mode 100644 pkg/interface/src/views/apps/term/api.js delete mode 100644 pkg/interface/src/views/apps/term/app.js create mode 100644 pkg/interface/src/views/apps/term/app.tsx delete mode 100644 pkg/interface/src/views/apps/term/components/history.js delete mode 100644 pkg/interface/src/views/apps/term/components/input.js delete mode 100644 pkg/interface/src/views/apps/term/components/line.js delete mode 100644 pkg/interface/src/views/apps/term/store.js delete mode 100644 pkg/interface/src/views/apps/term/subscription.js diff --git a/pkg/arvo/app/herm.hoon b/pkg/arvo/app/herm.hoon index cd791b2afa..8d295d526c 100644 --- a/pkg/arvo/app/herm.hoon +++ b/pkg/arvo/app/herm.hoon @@ -49,14 +49,9 @@ |= =path ^- (quip card:agent:gall _this) ?> ?=([%session @ ~] path) - :_ this - :: scry prompt and cursor position out of dill for initial response - :: - =/ base=^path - /dx/(scot %p our.bowl)//(scot %da now.bowl)/sessions - :~ [%give %fact ~ %blit !>(.^(blit:dill (weld base //line)))] - [%give %fact ~ %blit !>(`blit:dill`hop+.^(@ud (weld base //cursor)))] - == + :: tell session to refresh, so new client knows what's on screen + ::TODO should client be responsible for this? + [[%pass [%view %$ ~] %arvo %d %hail ~]~ this] :: ++ on-arvo |= [=wire =sign-arvo] diff --git a/pkg/arvo/mar/blit.hoon b/pkg/arvo/mar/blit.hoon index b2e7783e3f..15d5768d70 100644 --- a/pkg/arvo/mar/blit.hoon +++ b/pkg/arvo/mar/blit.hoon @@ -25,6 +25,7 @@ %lin a+(turn p.blit |=(c=@c s+(tuft c))) %nel b+& %url s+p.blit + %wyp b+& :: %sag %- pairs @@ -54,7 +55,8 @@ ++ color |= =tint ?@ tint ?~(tint ~ s+tint) - s+(crip ((x-co:co 6) (rep 3 ~[b g r]:tint))) + =, tint + (pairs r+(numb r) g+(numb g) b+(numb b) ~) -- == == diff --git a/pkg/interface/package-lock.json b/pkg/interface/package-lock.json index d4a06d132a..8eecc5bbf0 100644 --- a/pkg/interface/package-lock.json +++ b/pkg/interface/package-lock.json @@ -10517,6 +10517,16 @@ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, + "xterm": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/xterm/-/xterm-4.10.0.tgz", + "integrity": "sha512-Wn66I8YpSVkgP3R95GjABC6Eb21pFfnCSnyIqKIIoUI13ohvwd0KGVzUDfyEFfSAzKbPJfrT2+vt7SfUXBZQKQ==" + }, + "xterm-addon-fit": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xterm-addon-fit/-/xterm-addon-fit-0.5.0.tgz", + "integrity": "sha512-DsS9fqhXHacEmsPxBJZvfj2la30Iz9xk+UKjhQgnYNkrUIN5CYLbw7WEfz117c7+S86S/tpHPfvNxJsF5/G8wQ==" + }, "y18n": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", diff --git a/pkg/interface/package.json b/pkg/interface/package.json index a65578c438..c0cb24c391 100644 --- a/pkg/interface/package.json +++ b/pkg/interface/package.json @@ -44,6 +44,8 @@ "styled-system": "^5.1.5", "suncalc": "^1.8.0", "urbit-ob": "^5.0.1", + "xterm": "^4.10.0", + "xterm-addon-fit": "^0.5.0", "yup": "^0.29.3", "zustand": "^3.3.1" }, diff --git a/pkg/interface/src/logic/api/global.ts b/pkg/interface/src/logic/api/global.ts index 8ed02020b4..3264be194c 100644 --- a/pkg/interface/src/logic/api/global.ts +++ b/pkg/interface/src/logic/api/global.ts @@ -12,6 +12,7 @@ import GraphApi from './graph'; import S3Api from './s3'; import {HarkApi} from './hark'; import SettingsApi from './settings'; +import TermApi from './term'; export default class GlobalApi extends BaseApi { local = new LocalApi(this.ship, this.channel, this.store); @@ -24,6 +25,7 @@ export default class GlobalApi extends BaseApi { graph = new GraphApi(this.ship, this.channel, this.store); hark = new HarkApi(this.ship, this.channel, this.store); settings = new SettingsApi(this.ship, this.channel, this.store); + term = new TermApi(this.ship, this.channel, this.store); constructor( public ship: Patp, diff --git a/pkg/interface/src/logic/api/term.ts b/pkg/interface/src/logic/api/term.ts new file mode 100644 index 0000000000..35ccf909e0 --- /dev/null +++ b/pkg/interface/src/logic/api/term.ts @@ -0,0 +1,18 @@ +import BaseApi from './base'; +import { StoreState } from '../store/type'; + +export type Belt = + | { aro: 'd' | 'l' | 'r' | 'u' } + | { bac: null } + | { ctl: string } + | { del: null } + | { hit: { r: number, c: number } } + | { met: string } + | { ret: null } + | { txt: Array }; + +export default class TermApi extends BaseApi { + public sendBelt(belt: Belt) { + return this.action('herm', 'belt', belt); + } +} diff --git a/pkg/interface/src/logic/lib/bel.js b/pkg/interface/src/logic/lib/bel.js deleted file mode 100644 index 77ee145071..0000000000 --- a/pkg/interface/src/logic/lib/bel.js +++ /dev/null @@ -1 +0,0 @@ -export default new Audio('data:@file/ogg;base64,T2dnUwACAAAAAAAAAAAu9RJ+AAAAAO+u/l4BHgF2b3JiaXMAAAAAAUAfAAAAAAAAYG0AAAAAAACZAU9nZ1MAAAAAAAAAAAAALvUSfgEAAACXEgK4Czv///////////+1A3ZvcmJpcysAAABYaXBoLk9yZyBsaWJWb3JiaXMgSSAyMDEyMDIwMyAoT21uaXByZXNlbnQpAAAAAAEFdm9yYmlzEkJDVgEAAAEADFIUISUZU0pjCJVSUikFHWNQW0cdY9Q5RiFkEFOISRmle08qlVhKyBFSWClFHVNMU0mVUpYpRR1jFFNIIVPWMWWhcxRLhkkJJWxNrnQWS+iZY5YxRh1jzlpKnWPWMUUdY1JSSaFzGDpmJWQUOkbF6GJ8MDqVokIovsfeUukthYpbir3XGlPrLYQYS2nBCGFz7bXV3EpqxRhjjDHGxeJTKILQkFUAAAEAAEAEAUJDVgEACgAAwlAMRVGA0JBVAEAGAIAAFEVxFMdxHEeSJMsCQkNWAQBAAAACAAAojuEokiNJkmRZlmVZlqZ5lqi5qi/7ri7rru3qug6EhqwEAMgAABiGIYfeScyQU5BJJilVzDkIofUOOeUUZNJSxphijFHOkFMMMQUxhtAphRDUTjmlDCIIQ0idZM4gSz3o4GLnOBAasiIAiAIAAIxBjCHGkHMMSgYhco5JyCBEzjkpnZRMSiittJZJCS2V1iLnnJROSialtBZSy6SU1kIrBQAABDgAAARYCIWGrAgAogAAEIOQUkgpxJRiTjGHlFKOKceQUsw5xZhyjDHoIFTMMcgchEgpxRhzTjnmIGQMKuYchAwyAQAAAQ4AAAEWQqEhKwKAOAEAgyRpmqVpomhpmih6pqiqoiiqquV5pumZpqp6oqmqpqq6rqmqrmx5nml6pqiqnimqqqmqrmuqquuKqmrLpqvatumqtuzKsm67sqzbnqrKtqm6sm6qrm27smzrrizbuuR5quqZput6pum6quvasuq6su2ZpuuKqivbpuvKsuvKtq3Ksq5rpum6oqvarqm6su3Krm27sqz7puvqturKuq7Ksu7btq77sq0Lu+i6tq7Krq6rsqzrsi3rtmzbQsnzVNUzTdf1TNN1Vde1bdV1bVszTdc1XVeWRdV1ZdWVdV11ZVv3TNN1TVeVZdNVZVmVZd12ZVeXRde1bVWWfV11ZV+Xbd33ZVnXfdN1dVuVZdtXZVn3ZV33hVm3fd1TVVs3XVfXTdfVfVvXfWG2bd8XXVfXVdnWhVWWdd/WfWWYdZ0wuq6uq7bs66os676u68Yw67owrLpt/K6tC8Or68ax676u3L6Patu+8Oq2Mby6bhy7sBu/7fvGsamqbZuuq+umK+u6bOu+b+u6cYyuq+uqLPu66sq+b+u68Ou+Lwyj6+q6Ksu6sNqyr8u6Lgy7rhvDatvC7tq6cMyyLgy37yvHrwtD1baF4dV1o6vbxm8Lw9I3dr4AAIABBwCAABPKQKEhKwKAOAEABiEIFWMQKsYghBBSCiGkVDEGIWMOSsYclBBKSSGU0irGIGSOScgckxBKaKmU0EoopaVQSkuhlNZSai2m1FoMobQUSmmtlNJaaim21FJsFWMQMuekZI5JKKW0VkppKXNMSsagpA5CKqWk0kpJrWXOScmgo9I5SKmk0lJJqbVQSmuhlNZKSrGl0kptrcUaSmktpNJaSam11FJtrbVaI8YgZIxByZyTUkpJqZTSWuaclA46KpmDkkopqZWSUqyYk9JBKCWDjEpJpbWSSiuhlNZKSrGFUlprrdWYUks1lJJaSanFUEprrbUaUys1hVBSC6W0FkpprbVWa2ottlBCa6GkFksqMbUWY22txRhKaa2kElspqcUWW42ttVhTSzWWkmJsrdXYSi051lprSi3W0lKMrbWYW0y5xVhrDSW0FkpprZTSWkqtxdZaraGU1koqsZWSWmyt1dhajDWU0mIpKbWQSmyttVhbbDWmlmJssdVYUosxxlhzS7XVlFqLrbVYSys1xhhrbjXlUgAAwIADAECACWWg0JCVAEAUAABgDGOMQWgUcsw5KY1SzjknJXMOQggpZc5BCCGlzjkIpbTUOQehlJRCKSmlFFsoJaXWWiwAAKDAAQAgwAZNicUBCg1ZCQBEAQAgxijFGITGIKUYg9AYoxRjECqlGHMOQqUUY85ByBhzzkEpGWPOQSclhBBCKaWEEEIopZQCAAAKHAAAAmzQlFgcoNCQFQFAFAAAYAxiDDGGIHRSOikRhExKJ6WREloLKWWWSoolxsxaia3E2EgJrYXWMmslxtJiRq3EWGIqAADswAEA7MBCKDRkJQCQBwBAGKMUY845ZxBizDkIITQIMeYchBAqxpxzDkIIFWPOOQchhM455yCEEELnnHMQQgihgxBCCKWU0kEIIYRSSukghBBCKaV0EEIIoZRSCgAAKnAAAAiwUWRzgpGgQkNWAgB5AACAMUo5JyWlRinGIKQUW6MUYxBSaq1iDEJKrcVYMQYhpdZi7CCk1FqMtXYQUmotxlpDSq3FWGvOIaXWYqw119RajLXm3HtqLcZac865AADcBQcAsAMbRTYnGAkqNGQlAJAHAEAgpBRjjDmHlGKMMeecQ0oxxphzzinGGHPOOecUY4w555xzjDHnnHPOOcaYc84555xzzjnnoIOQOeecc9BB6JxzzjkIIXTOOecchBAKAAAqcAAACLBRZHOCkaBCQ1YCAOEAAIAxlFJKKaWUUkqoo5RSSimllFICIaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKZVSSimllFJKKaWUUkoppQAg3woHAP8HG2dYSTorHA0uNGQlABAOAAAYwxiEjDknJaWGMQildE5KSSU1jEEopXMSUkopg9BaaqWk0lJKGYSUYgshlZRaCqW0VmspqbWUUigpxRpLSqml1jLnJKSSWkuttpg5B6Wk1lpqrcUQQkqxtdZSa7F1UlJJrbXWWm0tpJRaay3G1mJsJaWWWmupxdZaTKm1FltLLcbWYkutxdhiizHGGgsA4G5wAIBIsHGGlaSzwtHgQkNWAgAhAQAEMko555yDEEIIIVKKMeeggxBCCCFESjHmnIMQQgghhIwx5yCEEEIIoZSQMeYchBBCCCGEUjrnIIRQSgmllFJK5xyEEEIIpZRSSgkhhBBCKKWUUkopIYQQSimllFJKKSWEEEIopZRSSimlhBBCKKWUUkoppZQQQiillFJKKaWUEkIIoZRSSimllFJCCKWUUkoppZRSSighhFJKKaWUUkoJJZRSSimllFJKKSGUUkoppZRSSimlAACAAwcAgAAj6CSjyiJsNOHCAxAAAAACAAJMAIEBgoJRCAKEEQgAAAAAAAgA+AAASAqAiIho5gwOEBIUFhgaHB4gIiQAAAAAAAAAAAAAAAAET2dnUwAE1RQAAAAAAAAu9RJ+AgAAAI+1UkUWbC8oJiQmKTc/RUVKWVRZVFZSUlJUV7qmd+oLx6QAgM0PiQSIMgmD9wDA8XvSzu5GNsva2WY+G85HV47eGBjur0ytj7Wzzewi2GBPz+5b5X5VkUKKy+P8uLzGfVyHdViHddimbdqm+vy4btM2bZ807djY2NjYmGmapmlWldmyNVsAAKbnXqjLAQBgrioAKJAAb4YBnDhIAAC27/UAAAAA45QIAAC7yTUBAADiQvsHAQAAot2slRd+/38AgHMlAEjBmx0AbNebLgAAgELltBYAAKCevTMAAMApA6ZROkjlAADw70oAkIIW6jMGALj7mNICAAC4yb6wAAAA5AL8fgcApk062Be+/wAA/AYAAgwQThMFAACArWpvCQAAdgKupkwAjRoAps1ukZcDAMAtAEAABjMCALC6GAAAgGj+odwAAEAB+7LvDnsP2ACWzMqoP/z7/wWADgBjwHY/xAAAAMy+IgAANBy/qbrb7Pbss8JZflyWAZJLw6WXAQAwDBDkAkwOAwBQfkkAAADcl8vVBAAAmA8+jGyL2BYT0nbND21ideV3xyy/U4qXlgCSSeNKfvjxNQHAMMAMKiBsbroBAABqor8AAAA6aM89+Rq6bvnk8LNKyvW8jyhPT0aIqTiefOpxfN3z2tGPswCGCW+WuQAAVJUF+uoAADx8dxcAAMBXAMBZqNm60vW9d44pypUD2Tl6luUkHdG5J5lxL0aFvMpY9y7OZ7Kj0NP2j2okAQCKCd8aEhwAAAOrCubTAADuuhZTAACwBktTUYYsypUTa++md34yaa8b31WXw4LZ/dB8ts9kOjOBgcl+OxzDxOtjXdfTAQB2C59ZJvj+zwcgKg5g8281AADAO8mGdLGzJy8kGD3ERJHSb8+KRreqsOe5iOA9+xk5RWYymr8t9fFcQ7UYPsf2CXO954oPXuRGAHoJPwokOACABBB9GJcCcDgMkr9TdStxcpHkOhDXOM40AADwtFHUzvluekfz0aP9mJ3KRw3ySu6e3k716lNJD845W/XCUnx96lspKQF7uni6YS5qaskPgwAAbkmqK5Xg958CMAAAlRyw848OAABGZmJHO2stuZprN5F4lw9/TAzNcykrrzAGQKT90Hzs9r7xON7h+h6Zh6owHipmsZi9HkcWrez9yFa25VxKjKcAcgnfCiQ4AIAK4PvQVQCcdOjsxOnO6qfsJ3fjALg3jw8MAAA4+pwLvc++cP6Da+BtgBK2Vchno/edw7oW9qfD6fCyfroxFvJA1J66eKe6X3caZA80fZoqIQBiCluUZIK/vwYgxgAIxWABAACzX87PD/e+ypZoZFzUgnT++Vfp0fDw+dEiJHzSHi4Jx9zOop6xOOLsMJv7o2RE6rgPC7QJCbg+iH2+j5OvYnTfZwBiieULScgAAGICCMAMAJTm0o7SZPPNrK4DMVjQnAAAoNazHL/ohsVDDnj1B1OiRQleU7ja3e2WOJqRCOfRlPtCOd1Xx4golDIpbZ458jXWa69PzEdWAl6L5caU4PODAKhVnoBdv4oBAAAxjs0+Ot/dzjg+fzV8Ll86PhGvL0dScur4fEpmFL7LtyA4Nl/lyJPLSxTD6GB2yR6n0xYDZ/Ki8AelZfcaMgBeiuWCJAzH3QEgRh/Ax9sXACBA5nuEprLWUgjNyZV1K0F59+b2ekLV6ygkgbeuJuF2mIlXES5VwEoYIydHWAcdfNrynQPbVs45Vnz0W5H4NsEAXorpzpTguRsArDEAQsVfDQAAai1bx861KN9Kd+gh5gcxYnuummTspfSig6uKfBD7ktk84S407NtlEEiIwPnIFpc0c1mn6l8NIwrqmFZHTOQGAGKK9H2ZQX8AgOgHABonCQAIoSiMDtY3DcIRbnuH6zxUxkQwrhJ2Fpywr6ZfxvDqKyW58VRo40fXz5/cpf7H3YRUgr9LRT8pNxJaVHecnCt+ZV2tAWJK8dUqwVUdACVGkCL93e/IyMrIukLnyg3MMbZ+9/OKc/Z7JuYqlQlMVOODRxW/vKQqdZPbQui0ML9ZSJo33YhFgCY5BjIkne70UjNULgVNfirfm7+RSw=='); diff --git a/pkg/interface/src/logic/lib/bel.ts b/pkg/interface/src/logic/lib/bel.ts new file mode 100644 index 0000000000..6de9d6ee33 --- /dev/null +++ b/pkg/interface/src/logic/lib/bel.ts @@ -0,0 +1 @@ +export default 'data:@file/ogg;base64,T2dnUwACAAAAAAAAAAAu9RJ+AAAAAO+u/l4BHgF2b3JiaXMAAAAAAUAfAAAAAAAAYG0AAAAAAACZAU9nZ1MAAAAAAAAAAAAALvUSfgEAAACXEgK4Czv///////////+1A3ZvcmJpcysAAABYaXBoLk9yZyBsaWJWb3JiaXMgSSAyMDEyMDIwMyAoT21uaXByZXNlbnQpAAAAAAEFdm9yYmlzEkJDVgEAAAEADFIUISUZU0pjCJVSUikFHWNQW0cdY9Q5RiFkEFOISRmle08qlVhKyBFSWClFHVNMU0mVUpYpRR1jFFNIIVPWMWWhcxRLhkkJJWxNrnQWS+iZY5YxRh1jzlpKnWPWMUUdY1JSSaFzGDpmJWQUOkbF6GJ8MDqVokIovsfeUukthYpbir3XGlPrLYQYS2nBCGFz7bXV3EpqxRhjjDHGxeJTKILQkFUAAAEAAEAEAUJDVgEACgAAwlAMRVGA0JBVAEAGAIAAFEVxFMdxHEeSJMsCQkNWAQBAAAACAAAojuEokiNJkmRZlmVZlqZ5lqi5qi/7ri7rru3qug6EhqwEAMgAABiGIYfeScyQU5BJJilVzDkIofUOOeUUZNJSxphijFHOkFMMMQUxhtAphRDUTjmlDCIIQ0idZM4gSz3o4GLnOBAasiIAiAIAAIxBjCHGkHMMSgYhco5JyCBEzjkpnZRMSiittJZJCS2V1iLnnJROSialtBZSy6SU1kIrBQAABDgAAARYCIWGrAgAogAAEIOQUkgpxJRiTjGHlFKOKceQUsw5xZhyjDHoIFTMMcgchEgpxRhzTjnmIGQMKuYchAwyAQAAAQ4AAAEWQqEhKwKAOAEAgyRpmqVpomhpmih6pqiqoiiqquV5pumZpqp6oqmqpqq6rqmqrmx5nml6pqiqnimqqqmqrmuqquuKqmrLpqvatumqtuzKsm67sqzbnqrKtqm6sm6qrm27smzrrizbuuR5quqZput6pum6quvasuq6su2ZpuuKqivbpuvKsuvKtq3Ksq5rpum6oqvarqm6su3Krm27sqz7puvqturKuq7Ksu7btq77sq0Lu+i6tq7Krq6rsqzrsi3rtmzbQsnzVNUzTdf1TNN1Vde1bdV1bVszTdc1XVeWRdV1ZdWVdV11ZVv3TNN1TVeVZdNVZVmVZd12ZVeXRde1bVWWfV11ZV+Xbd33ZVnXfdN1dVuVZdtXZVn3ZV33hVm3fd1TVVs3XVfXTdfVfVvXfWG2bd8XXVfXVdnWhVWWdd/WfWWYdZ0wuq6uq7bs66os676u68Yw67owrLpt/K6tC8Or68ax676u3L6Patu+8Oq2Mby6bhy7sBu/7fvGsamqbZuuq+umK+u6bOu+b+u6cYyuq+uqLPu66sq+b+u68Ou+Lwyj6+q6Ksu6sNqyr8u6Lgy7rhvDatvC7tq6cMyyLgy37yvHrwtD1baF4dV1o6vbxm8Lw9I3dr4AAIABBwCAABPKQKEhKwKAOAEABiEIFWMQKsYghBBSCiGkVDEGIWMOSsYclBBKSSGU0irGIGSOScgckxBKaKmU0EoopaVQSkuhlNZSai2m1FoMobQUSmmtlNJaaim21FJsFWMQMuekZI5JKKW0VkppKXNMSsagpA5CKqWk0kpJrWXOScmgo9I5SKmk0lJJqbVQSmuhlNZKSrGl0kptrcUaSmktpNJaSam11FJtrbVaI8YgZIxByZyTUkpJqZTSWuaclA46KpmDkkopqZWSUqyYk9JBKCWDjEpJpbWSSiuhlNZKSrGFUlprrdWYUks1lJJaSanFUEprrbUaUys1hVBSC6W0FkpprbVWa2ottlBCa6GkFksqMbUWY22txRhKaa2kElspqcUWW42ttVhTSzWWkmJsrdXYSi051lprSi3W0lKMrbWYW0y5xVhrDSW0FkpprZTSWkqtxdZaraGU1koqsZWSWmyt1dhajDWU0mIpKbWQSmyttVhbbDWmlmJssdVYUosxxlhzS7XVlFqLrbVYSys1xhhrbjXlUgAAwIADAECACWWg0JCVAEAUAABgDGOMQWgUcsw5KY1SzjknJXMOQggpZc5BCCGlzjkIpbTUOQehlJRCKSmlFFsoJaXWWiwAAKDAAQAgwAZNicUBCg1ZCQBEAQAgxijFGITGIKUYg9AYoxRjECqlGHMOQqUUY85ByBhzzkEpGWPOQSclhBBCKaWEEEIopZQCAAAKHAAAAmzQlFgcoNCQFQFAFAAAYAxiDDGGIHRSOikRhExKJ6WREloLKWWWSoolxsxaia3E2EgJrYXWMmslxtJiRq3EWGIqAADswAEA7MBCKDRkJQCQBwBAGKMUY845ZxBizDkIITQIMeYchBAqxpxzDkIIFWPOOQchhM455yCEEELnnHMQQgihgxBCCKWU0kEIIYRSSukghBBCKaV0EEIIoZRSCgAAKnAAAAiwUWRzgpGgQkNWAgB5AACAMUo5JyWlRinGIKQUW6MUYxBSaq1iDEJKrcVYMQYhpdZi7CCk1FqMtXYQUmotxlpDSq3FWGvOIaXWYqw119RajLXm3HtqLcZac865AADcBQcAsAMbRTYnGAkqNGQlAJAHAEAgpBRjjDmHlGKMMeecQ0oxxphzzinGGHPOOecUY4w555xzjDHnnHPOOcaYc84555xzzjnnoIOQOeecc9BB6JxzzjkIIXTOOecchBAKAAAqcAAACLBRZHOCkaBCQ1YCAOEAAIAxlFJKKaWUUkqoo5RSSimllFICIaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKZVSSimllFJKKaWUUkoppQAg3woHAP8HG2dYSTorHA0uNGQlABAOAAAYwxiEjDknJaWGMQildE5KSSU1jEEopXMSUkopg9BaaqWk0lJKGYSUYgshlZRaCqW0VmspqbWUUigpxRpLSqml1jLnJKSSWkuttpg5B6Wk1lpqrcUQQkqxtdZSa7F1UlJJrbXWWm0tpJRaay3G1mJsJaWWWmupxdZaTKm1FltLLcbWYkutxdhiizHGGgsA4G5wAIBIsHGGlaSzwtHgQkNWAgAhAQAEMko555yDEEIIIVKKMeeggxBCCCFESjHmnIMQQgghhIwx5yCEEEIIoZSQMeYchBBCCCGEUjrnIIRQSgmllFJK5xyEEEIIpZRSSgkhhBBCKKWUUkopIYQQSimllFJKKSWEEEIopZRSSimlhBBCKKWUUkoppZQQQiillFJKKaWUEkIIoZRSSimllFJCCKWUUkoppZRSSighhFJKKaWUUkoJJZRSSimllFJKKSGUUkoppZRSSimlAACAAwcAgAAj6CSjyiJsNOHCAxAAAAACAAJMAIEBgoJRCAKEEQgAAAAAAAgA+AAASAqAiIho5gwOEBIUFhgaHB4gIiQAAAAAAAAAAAAAAAAET2dnUwAE1RQAAAAAAAAu9RJ+AgAAAI+1UkUWbC8oJiQmKTc/RUVKWVRZVFZSUlJUV7qmd+oLx6QAgM0PiQSIMgmD9wDA8XvSzu5GNsva2WY+G85HV47eGBjur0ytj7Wzzewi2GBPz+5b5X5VkUKKy+P8uLzGfVyHdViHddimbdqm+vy4btM2bZ807djY2NjYmGmapmlWldmyNVsAAKbnXqjLAQBgrioAKJAAb4YBnDhIAAC27/UAAAAA45QIAAC7yTUBAADiQvsHAQAAot2slRd+/38AgHMlAEjBmx0AbNebLgAAgELltBYAAKCevTMAAMApA6ZROkjlAADw70oAkIIW6jMGALj7mNICAAC4yb6wAAAA5AL8fgcApk062Be+/wAA/AYAAgwQThMFAACArWpvCQAAdgKupkwAjRoAps1ukZcDAMAtAEAABjMCALC6GAAAgGj+odwAAEAB+7LvDnsP2ACWzMqoP/z7/wWADgBjwHY/xAAAAMy+IgAANBy/qbrb7Pbss8JZflyWAZJLw6WXAQAwDBDkAkwOAwBQfkkAAADcl8vVBAAAmA8+jGyL2BYT0nbND21ideV3xyy/U4qXlgCSSeNKfvjxNQHAMMAMKiBsbroBAABqor8AAAA6aM89+Rq6bvnk8LNKyvW8jyhPT0aIqTiefOpxfN3z2tGPswCGCW+WuQAAVJUF+uoAADx8dxcAAMBXAMBZqNm60vW9d44pypUD2Tl6luUkHdG5J5lxL0aFvMpY9y7OZ7Kj0NP2j2okAQCKCd8aEhwAAAOrCubTAADuuhZTAACwBktTUYYsypUTa++md34yaa8b31WXw4LZ/dB8ts9kOjOBgcl+OxzDxOtjXdfTAQB2C59ZJvj+zwcgKg5g8281AADAO8mGdLGzJy8kGD3ERJHSb8+KRreqsOe5iOA9+xk5RWYymr8t9fFcQ7UYPsf2CXO954oPXuRGAHoJPwokOACABBB9GJcCcDgMkr9TdStxcpHkOhDXOM40AADwtFHUzvluekfz0aP9mJ3KRw3ySu6e3k716lNJD845W/XCUnx96lspKQF7uni6YS5qaskPgwAAbkmqK5Xg958CMAAAlRyw848OAABGZmJHO2stuZprN5F4lw9/TAzNcykrrzAGQKT90Hzs9r7xON7h+h6Zh6owHipmsZi9HkcWrez9yFa25VxKjKcAcgnfCiQ4AIAK4PvQVQCcdOjsxOnO6qfsJ3fjALg3jw8MAAA4+pwLvc++cP6Da+BtgBK2Vchno/edw7oW9qfD6fCyfroxFvJA1J66eKe6X3caZA80fZoqIQBiCluUZIK/vwYgxgAIxWABAACzX87PD/e+ypZoZFzUgnT++Vfp0fDw+dEiJHzSHi4Jx9zOop6xOOLsMJv7o2RE6rgPC7QJCbg+iH2+j5OvYnTfZwBiieULScgAAGICCMAMAJTm0o7SZPPNrK4DMVjQnAAAoNazHL/ohsVDDnj1B1OiRQleU7ja3e2WOJqRCOfRlPtCOd1Xx4golDIpbZ458jXWa69PzEdWAl6L5caU4PODAKhVnoBdv4oBAAAxjs0+Ot/dzjg+fzV8Ll86PhGvL0dScur4fEpmFL7LtyA4Nl/lyJPLSxTD6GB2yR6n0xYDZ/Ki8AelZfcaMgBeiuWCJAzH3QEgRh/Ax9sXACBA5nuEprLWUgjNyZV1K0F59+b2ekLV6ygkgbeuJuF2mIlXES5VwEoYIydHWAcdfNrynQPbVs45Vnz0W5H4NsEAXorpzpTguRsArDEAQsVfDQAAai1bx861KN9Kd+gh5gcxYnuummTspfSig6uKfBD7ktk84S407NtlEEiIwPnIFpc0c1mn6l8NIwrqmFZHTOQGAGKK9H2ZQX8AgOgHABonCQAIoSiMDtY3DcIRbnuH6zxUxkQwrhJ2Fpywr6ZfxvDqKyW58VRo40fXz5/cpf7H3YRUgr9LRT8pNxJaVHecnCt+ZV2tAWJK8dUqwVUdACVGkCL93e/IyMrIukLnyg3MMbZ+9/OKc/Z7JuYqlQlMVOODRxW/vKQqdZPbQui0ML9ZSJo33YhFgCY5BjIkne70UjNULgVNfirfm7+RSw=='; diff --git a/pkg/interface/src/types/term-update.ts b/pkg/interface/src/types/term-update.ts new file mode 100644 index 0000000000..cad19fe504 --- /dev/null +++ b/pkg/interface/src/types/term-update.ts @@ -0,0 +1,33 @@ + +export type TermUpdate = + | Blit; + +export type Tint = + | null + | 'r' | 'g' | 'b' | 'c' | 'm' | 'y' | 'k' | 'w' + | { r: number, g: number, b: number }; + +export type Deco = null | 'br' | 'un' | 'bl'; + +export type Stye = { + deco: Array, + back: Tint, + fore: Tint +}; + +export type Stub = { + stye: Stye, + text: Array +} + +export type Blit = + | { bel: null } // make a noise + | { clr: null } // clear the screen + | { hop: number | { row: number, col: number } } // set cursor col/pos + | { klr: Array } // put styled + | { lin: Array } // put text at cursor + | { nel: null } // newline + | { sag: { path: string, file: string } } // save to jamfile + | { sav: { path: string, file: string } } // save to file + | { url: string } // activate url + | { wyp: null } // wipe cursor line diff --git a/pkg/interface/src/views/apps/term/api.js b/pkg/interface/src/views/apps/term/api.js deleted file mode 100644 index 8216a771dc..0000000000 --- a/pkg/interface/src/views/apps/term/api.js +++ /dev/null @@ -1,47 +0,0 @@ -import _ from 'lodash'; - -export default class Api { - constructor(ship, channel) { - this.ship = ship; - this.channel = channel; - this.bindPaths = []; - } - - bind(path, method, ship = this.ship, appl = 'herm', success, fail) { - this.bindPaths = _.uniq([...this.bindPaths, path]); - - window.subscriptionId = this.channel.subscribe(ship, appl, path, - (err) => { - fail(err); - }, - (event) => { - success({ - data: event, - from: { - ship, - path - } - }); - }, - (err) => { - fail(err); - }); - } - - belt(belt) { - return this.action('herm', 'belt', belt); - } - - action(appl, mark, data) { - return new Promise((resolve, reject) => { - this.channel.poke(window.ship, appl, mark, data, - (json) => { - resolve(json); - }, - (err) => { - reject(err); - }); - }); - } -} - diff --git a/pkg/interface/src/views/apps/term/app.js b/pkg/interface/src/views/apps/term/app.js deleted file mode 100644 index 6413a4f6de..0000000000 --- a/pkg/interface/src/views/apps/term/app.js +++ /dev/null @@ -1,94 +0,0 @@ -import React, { Component } from 'react'; -import { Route } from 'react-router-dom'; -import Helmet from 'react-helmet'; - -import { History } from './components/history'; -import { Input } from './components/input'; - -import { Box, Col } from '@tlon/indigo-react'; - -import Api from './api'; -import Store from './store'; -import Subscription from './subscription'; - -import './css/custom.css'; - -export default class TermApp extends Component { - constructor(props) { - super(props); - this.store = new Store(); - this.store.setStateHandler(this.setState.bind(this)); - - this.state = this.store.state; - } - - resetControllers() { - this.api = null; - this.subscription = null; - } - - componentDidMount() { - this.resetControllers(); - const channel = new window.channel(); - this.api = new Api(this.props.ship, channel); - this.store.api = this.api; - - this.subscription = new Subscription(this.store, this.api, channel); - this.subscription.start(); - } - - componentWillUnmount() { - this.subscription.delete(); - this.store.clear(); - this.resetControllers(); - } - - render() { - return ( - <> - - { this.props.notificationsCount ? `(${String(this.props.notificationsCount) }) `: '' }Landscape - - - { - return ( - - - - - - - ); - }} - /> - - - ); - } -} diff --git a/pkg/interface/src/views/apps/term/app.tsx b/pkg/interface/src/views/apps/term/app.tsx new file mode 100644 index 0000000000..1a9f49fc49 --- /dev/null +++ b/pkg/interface/src/views/apps/term/app.tsx @@ -0,0 +1,413 @@ +import React, { + Component, + useState, + useEffect, + useRef, + useCallback +} from 'react'; +import { Route } from 'react-router-dom'; +import Helmet from 'react-helmet'; + +import { Terminal, ITerminalOptions } from 'xterm'; +import { FitAddon } from 'xterm-addon-fit'; +import { saveAs } from 'file-saver'; + +import { Box, Col } from '@tlon/indigo-react'; + +import './css/custom.css'; +import GlobalApi from '~/logic/api/global'; +import { Belt } from '~/logic/api/term'; +import { Blit, Stye, Stub, Tint, Deco } from '~/types/term-update'; + +import bel from '../../../logic/lib/bel'; + +type TermAppProps = { + api: GlobalApi; + ship: string; + notificationsCount: number; +} + +type Sessions = { + [id: string]: { + term: Terminal, + fit: FitAddon, + sub: boolean + }; +} + +const termConfig: ITerminalOptions = { + logLevel: 'warn', + // + convertEol: true, + // + rows: 24, + cols: 80, + scrollback: 10000, + // + theme: { //TODO vary with landscape theme? + foreground: 'black', + background: 'white', + cursor: 'black', + cursorAccent: 'white', + //TODO selection color + }, + bellStyle: 'sound', + bellSound: bel, + // + // allows text selection by holding modifier (option, or shift) + macOptionClickForcesSelection: true, +} + +const csi = (cmd: string, ...args: Array) => { + return '\x1b[' + args.join(';') + cmd; +} + +const tint = (t: Tint) => { + switch (t) { + case null: return '9'; + case 'k': return '0'; + case 'r': return '1'; + case 'g': return '2'; + case 'y': return '3'; + case 'b': return '4'; + case 'm': return '5'; + case 'c': return '6'; + case 'w': return '7'; + default: return `8;2;${t.r%256};${t.g%256};${t.b%256}`; + } +} + +const stye = (s: Stye) => { + let out = ''; + + // text decorations + // + if (s.deco.length > 0) { + out += s.deco.reduce((decs: Array, deco: Deco) => { + switch (deco) { + case null: decs.push(0); return decs; + case 'br': decs.push(1); return decs; + case 'un': decs.push(4); return decs; + case 'bl': decs.push(5); return decs; + default: console.log('weird deco', deco); return decs; + } + }, []).join(';'); + } + + // background color + // + if (s.back !== null) { + if (out !== '') out += ';'; + out += '4'; + out += tint(s.back); + } + + // foreground color + // + if (s.fore !== null) { + if (out !== '') out += ';'; + out += '3'; + out += tint(s.fore); + } + + if (out === '') return out; + return '\x1b[' + out + 'm'; +} + +export default function TermApp(props: TermAppProps) { + const { api } = props; + + const container = useRef(null); + const [sessions, setSessions] = useState({}); + const [selected, setSelected] = useState('default'); //TODO allow switching + + const onSlog = useCallback((slog) => { + if (!sessions['default']) { + console.log('default session mia!', 'slog:', slog); + return; + } + const term = sessions['default'].term; + + // set scroll region to exclude the bottom line, + // scroll up one line, + // move cursor to start of the newly created whitespace, + // set text to grey, + // print the slog, + // restore color, scroll region, and cursor. + // + term.write(csi('r', 1, term.rows - 1) + + csi('S', 1) + + csi('H', term.rows - 1, 1) + + csi('m', 90) + + slog + + csi('m', 0) + + csi('r') + + csi('u')); + }, []); + + const onBlit = useCallback((ses: string, blit: Blit) => { + //TODO + if (!sessions[ses]) { + console.log('on blit: no such session', ses); + return; + } + + const term = sessions[ses].term; + let out = ''; + + if ('bel' in blit) { + out += '\x07'; + } + else if ('clr' in blit) { + term.clear(); + out += csi('u'); + } + else if ('hop' in blit) { + if (typeof blit.hop === 'number') { + out += csi('H', term.rows, blit.hop + 1); + } + else { + out += csi('H', term.rows - blit.hop.row, blit.hop.col + 1); + } + out += csi('s'); // save cursor position + } + else if ('lin' in blit) { + out += blit.lin.join(''); + out += csi('u'); + } + else if ('klr' in blit) { + out += blit.klr.reduce((lin: string, p: Stub) => { + lin += stye(p.stye); + lin += p.text.join(''); + lin += csi('m', 0); + return lin; + }, ''); + out += csi('u'); + } + else if ('nel' in blit) { + out += '\n'; + } + else if ('sag' in blit || 'sav' in blit) { + const sav = ('sag' in blit) ? blit.sag : blit.sav; + let name = sav.path.split('/').slice(-2).join('.'); + let buff = new Buffer(sav.file, 'base64'); + let blob = new Blob([buff], {type: 'application/octet-stream'}); + saveAs(blob, name); + } + else if ('url' in blit) { + window.open(blit.url); + } + else if ('wyp' in blit) { + out += '\r' + csi('K'); + out += csi('u'); + } + else { + console.log('weird blit', blit); + } + + sessions[ses].term.write(out); + }, []); + + const setupSlog = useCallback(() => { + console.log('slog: setting up...'); + let available = false; + const slog = new EventSource('/~_~/slog', { withCredentials: true }); + + slog.onopen = e => { + console.log('slog: opened stream'); + available = true; + } + + slog.onmessage = e => { + onSlog(e.data); + } + + slog.onerror = e => { + console.error('slog: eventsource error:', e); + if (available) { + window.setTimeout(() => { + if (slog.readyState !== EventSource.CLOSED) return; + console.log('slog: reconnecting...'); + setupSlog(); + }, 10000); + } + } + }, [onSlog]); + + const onInput = useCallback((ses: string, e) => { + const term = sessions[ses].term; + let belts: Array = []; + let strap = ''; + + while (e.length > 0) { + let c = e.charCodeAt(0); + + // text input + // + if (c >= 32 && c !== 127) { + strap += e[0]; + e = e.slice(1); + continue; + } else if ('' !== strap) { + belts.push({ txt: strap.split('') }); + strap = ''; + } + + // special keys/characters + if (0 === c) { + term.write('\x07'); // bel + } + else if (8 === c || 127 === c) { + belts.push({ bac: null }); + } + else if (13 === c) { + belts.push({ ret: null }); + } + else if (c <= 26) { + belts.push({ ctl: String.fromCharCode(96 + c) }); + } + + // escape sequences + // + if (27 === c) { // ESC + e = e.slice(1); + c = e.charCodeAt(0); + if (91 === c || 79 === c) { // [ or O + e = e.slice(1); + c = e.charCodeAt(0); + switch (c) { + case 65: belts.push({ aro: 'u' }); break; + case 66: belts.push({ aro: 'd' }); break; + case 67: belts.push({ aro: 'r' }); break; + case 68: belts.push({ aro: 'l' }); break; + // + case 77: + const m = e.charCodeAt(1) - 31; + if (1 === m) { + const c = e.charCodeAt(2) - 32; + const r = e.charCodeAt(3) - 32; + belts.push({ hit: { r: term.rows - r, c: c - 1 } }); + } + e = e.slice(3); + break; + // + default: term.write('\x07'); break; // bel + } + } + else if (c >= 97 && c <= 122) { // a <= c <= z + belts.push({ met: e[0] }); + } + else if (c === 46) { // . + belts.push({ met: 'dot' }); + } + else if (c === 8 || c === 127) { + belts.push({ met: 'bac' }); + } + else { + term.write('\x07'); break; // bel + } + } + + e = e.slice(1); + } + if ('' !== strap) { + belts.push({ txt: strap.split('') }); + strap = ''; + } + belts.map(b => { //NOTE passing api.term.sendBelt makes `this` undefined! + api.term.sendBelt(b); + }); + }, [sessions, api.term]); + + // on-init, open slogstream + // + useEffect(() => { + setupSlog(); + return () => { + //TODO clean up subs? + }; + }, []); + + // when switching sessions, initialize if necessary + // + useEffect(() => { + // initialize terminal + // + if (!sessions[selected]) { + // set up terminal + // + console.log('new term!', selected); + let term = new Terminal(termConfig); + const fit = new FitAddon(); + term.loadAddon(fit); + + // start mouse reporting + // + term.write(csi('?9h')); + + // set up event handlers + // + term.onData((e) => onInput(selected, e)); + term.onBinary((e) => onInput(selected, e)); + + //TODO open subscription + + // persist in state + // + sessions[selected] = { term, fit, sub: false }; + setSessions(sessions); + } + + if (container.current) { + sessions[selected].term.open(container.current); //TODO once + sessions[selected].fit.fit(); //TODO if not default, send %blew + } + + console.log('need sub?', selected, sessions[selected].sub); + if (!sessions[selected].sub) { + //TODO BaseSubscribe? + let ses = selected; + if (ses === 'default') ses = ''; + //TODO get from a SubscriptionBase somewhere? + console.log('starting sub', selected); + api.subscribe('/session/', 'PUT', api.ship, 'herm', + (e) => { + onBlit(selected, e.data); + }, + (err) => { // fail + console.log(err); + //TODO resubscribe + }, + () => { // quit + //TODO resubscribe + }); + //TODO set in state + } + //TODO can we do sessions[selected]? + }, [container.current, sessions, selected, onBlit]); + + return ( + <> + + { props.notificationsCount ? `(${String(props.notificationsCount) }) `: '' }Landscape + + + + + + + ); +} diff --git a/pkg/interface/src/views/apps/term/components/history.js b/pkg/interface/src/views/apps/term/components/history.js deleted file mode 100644 index 93eb0a0110..0000000000 --- a/pkg/interface/src/views/apps/term/components/history.js +++ /dev/null @@ -1,33 +0,0 @@ -import React, { Component } from 'react'; -import { Box } from '@tlon/indigo-react'; - -import Line from './line'; - -export class History extends Component { - constructor(props) { - super(props); - } - - render() { - return ( - - - {this.props.log.map((line, i) => { - return ; - })} - - - ); - } - } - -export default History; diff --git a/pkg/interface/src/views/apps/term/components/input.js b/pkg/interface/src/views/apps/term/components/input.js deleted file mode 100644 index 695c4a80f1..0000000000 --- a/pkg/interface/src/views/apps/term/components/input.js +++ /dev/null @@ -1,114 +0,0 @@ -import React, { Component } from 'react'; -import { Row, Box, BaseInput } from '@tlon/indigo-react'; - -export class Input extends Component { - constructor(props) { - super(props); - this.state = {}; - this.keyPress = this.keyPress.bind(this); - this.paste = this.paste.bind(this); - this.click = this.click.bind(this); - this.inputRef = React.createRef(); - } - - componentDidUpdate() { - if ( - !document.activeElement == document.body - || document.activeElement == this.inputRef.current - ) { - this.inputRef.current.focus(); - this.inputRef.current.setSelectionRange(this.props.cursor, this.props.cursor); - } - } - - keyPress(e) { - let key = e.key; - // let paste and leap events pass - if ((e.getModifierState('Control') || event.getModifierState('Meta')) - && (e.key === 'v' || e.key === '/')) { - return; - } - - let belt = null; - if (key === 'ArrowLeft') belt = {aro: 'l'}; - else if (key === 'ArrowRight') belt = {aro: 'r'}; - else if (key === 'ArrowUp') belt = {aro: 'u'}; - else if (key === 'ArrowDown') belt = {aro: 'd'}; - else if (key === 'Backspace') belt = {bac: null}; - else if (key === 'Delete') belt = {del: null}; - else if (key === 'Tab') belt = {ctl: 'i'}; - else if (key === 'Enter') belt = {ret: null}; - else if (key.length === 1) belt = {txt: [key]}; - else belt = null; - - if (belt && e.getModifierState('Control')) { - if (belt.txt !== undefined) belt = {ctl: belt.txt[0]}; - } else - if (belt && - (e.getModifierState('Meta') || e.getModifierState('Alt'))) { - if (belt.bac !== undefined) belt = {met: 'bac'}; - } - - if (belt !== null) { - this.props.api.belt(belt); - } - - e.preventDefault(); - } - - paste(e) { - const clipboardData = e.clipboardData || window.clipboardData; - const clipboardText = clipboardData.getData('Text'); - this.props.api.belt({ txt: [...clipboardText] }); - e.preventDefault(); - } - - click(e) { - // prevent desynced cursor movement - e.preventDefault(); - e.target.setSelectionRange(this.props.cursor, this.props.cursor); - } - - render() { - const line = this.props.line; - let prompt = 'connecting...'; - if (line) { - if (line.lin) { - prompt = line.lin.join(''); - } - //TODO render prompt style - else if (line.klr) { - prompt = line.klr.reduce((l, p) => (l + p.text.join('')), ''); - } - } - return ( - - - - - - ); - } -} - -export default Input; diff --git a/pkg/interface/src/views/apps/term/components/line.js b/pkg/interface/src/views/apps/term/components/line.js deleted file mode 100644 index 88c46314d8..0000000000 --- a/pkg/interface/src/views/apps/term/components/line.js +++ /dev/null @@ -1,68 +0,0 @@ -import React from 'react'; -import { Text } from '@tlon/indigo-react'; - -export default React.memo(({line}) => { - - // line body to jsx - //NOTE lines are lists of characters that might span multiple codepoints - // - let text = ''; - if (line.lin) { - text = line.lin.join(''); - } - else if (line.klr) { - text = line.klr.map((part, i) => { - let prop = part.stye.deco.reduce((prop, deco) => { - switch (deco) { - case null: return prop; - case 'br': return {bold: true, ...prop}; - case 'bl': return {className: 'blink', ...prop}; - case 'un': return {style: {textDecoration: 'underline'}, ...prop}; - default: console.log('weird deco', deco); return prop; - } - }, {}); - switch (part.stye.fore) { - case null: break; - case 'r': prop.color = 'red'; break; - case 'g': prop.color = 'green'; break; - case 'b': prop.color = 'blue'; break; - case 'c': prop.color = 'cyan'; break; - case 'm': prop.color = 'purple'; break; - case 'y': prop.color = 'yellow'; break; - case 'k': prop.color = 'black'; break; - case 'w': prop.color = 'white'; break; - default: prop.color = '#' + part.stye.fore; - } - switch (part.stye.back) { - case null: break; - case 'r': prop.backgroundColor = 'red'; break; - case 'g': prop.backgroundColor = 'green'; break; - case 'b': prop.backgroundColor = 'blue'; break; - case 'c': prop.backgroundColor = 'cyan'; break; - case 'm': prop.backgroundColor = 'purple'; break; - case 'y': prop.backgroundColor = 'yellow'; break; - case 'k': prop.backgroundColor = 'black'; break; - case 'w': prop.backgroundColor = 'white'; break; - default: prop.backgroundColor = '#' + part.stye.back; - } - if (Object.keys(prop).length === 0) - { - return part.text; - } else { - return ( - {part.text.join('')} - ); - } - }); - } - - // render line - // - return ( - - {text} - - ); -}); diff --git a/pkg/interface/src/views/apps/term/css/custom.css b/pkg/interface/src/views/apps/term/css/custom.css index b25bcdbd9f..b5222f5e67 100644 --- a/pkg/interface/src/views/apps/term/css/custom.css +++ b/pkg/interface/src/views/apps/term/css/custom.css @@ -14,3 +14,144 @@ input#term { 90% { opacity: 0; } 100% { opacity: 0; } } + +/** + * Default styles for xterm.js + * TODO import from xterm in node_modules, but how? + */ + + .xterm { + font-feature-settings: "liga" 0; + position: relative; + user-select: none; + -ms-user-select: none; + -webkit-user-select: none; +} + +.xterm.focus, +.xterm:focus { + outline: none; +} + +.xterm .xterm-helpers { + position: absolute; + top: 0; + /** + * The z-index of the helpers must be higher than the canvases in order for + * IMEs to appear on top. + */ + z-index: 5; +} + +.xterm .xterm-helper-textarea { + padding: 0; + border: 0; + margin: 0; + /* Move textarea out of the screen to the far left, so that the cursor is not visible */ + position: absolute; + opacity: 0; + left: -9999em; + top: 0; + width: 0; + height: 0; + z-index: -5; + /** Prevent wrapping so the IME appears against the textarea at the correct position */ + white-space: nowrap; + overflow: hidden; + resize: none; +} + +.xterm .composition-view { + /* TODO: Composition position got messed up somewhere */ + background: #000; + color: #FFF; + display: none; + position: absolute; + white-space: nowrap; + z-index: 1; +} + +.xterm .composition-view.active { + display: block; +} + +.xterm .xterm-viewport { + /* On OS X this is required in order for the scroll bar to appear fully opaque */ + background-color: #000; + overflow-y: scroll; + cursor: default; + position: absolute; + right: 0; + left: 0; + top: 0; + bottom: 0; +} + +.xterm .xterm-screen { + position: relative; +} + +.xterm .xterm-screen canvas { + position: absolute; + left: 0; + top: 0; +} + +.xterm .xterm-scroll-area { + visibility: hidden; +} + +.xterm-char-measure-element { + display: inline-block; + visibility: hidden; + position: absolute; + top: 0; + left: -9999em; + line-height: normal; +} + +.xterm { + cursor: text; +} + +.xterm.enable-mouse-events { + /* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */ + cursor: default; +} + +.xterm.xterm-cursor-pointer { + cursor: pointer; +} + +.xterm.column-select.focus { + /* Column selection mode */ + cursor: crosshair; +} + +.xterm .xterm-accessibility, +.xterm .xterm-message { + position: absolute; + left: 0; + top: 0; + bottom: 0; + right: 0; + z-index: 10; + color: transparent; +} + +.xterm .live-region { + position: absolute; + left: -9999px; + width: 1px; + height: 1px; + overflow: hidden; +} + +.xterm-dim { + opacity: 0.5; +} + +.xterm-underline { + text-decoration: underline; +} + diff --git a/pkg/interface/src/views/apps/term/store.js b/pkg/interface/src/views/apps/term/store.js deleted file mode 100644 index 795f5bc463..0000000000 --- a/pkg/interface/src/views/apps/term/store.js +++ /dev/null @@ -1,90 +0,0 @@ -import { saveAs } from 'file-saver'; -import bel from '../../../logic/lib/bel' - -export default class Store { - constructor() { - this.state = this.initialState(); - } - - initialState() { - return { - lines: [''], - cursor: 0, - }; - } - - clear() { - this.setState(this.initialState()) - } - - handleEvent(data) { - // process slogs - // - if (data.slog) { - this.state.lines.splice(this.state.lines.length-1, 0, {lin: [data.slog]}); - this.setState({ lines: this.state.lines }); - return; - } - - // process blits - // - const blit = data.data; - switch (Object.keys(blit)[0]) { - case 'bel': - bel.play(); - break; - case 'clr': - this.state.lines = this.state.lines.slice(-1); - this.setState({ lines: this.state.lines }); - break; - case 'hop': - // since lines are lists of characters that might span multiple - // codepoints, we need to calculate the byte-wise cursor position - // to avoid incorrect cursor rendering. - // - let line = this.state.lines[this.state.lines.length - 1]; - let hops; - if (line.lin) { - hops = line.lin.slice(0, blit.hop); - } - else if (line.klr) { - hops = line.klr.reduce((h, p) => { - if (h.length >= blit.hop) return h; - return [...h, ...p.text.slice(0, blit.hop - h.length)] - }, []); - } - this.setState({ cursor: hops.join('').length }); - break; - case 'lin': - this.state.lines[this.state.lines.length - 1] = blit; - this.setState({ lines: this.state.lines }); - break; - case 'klr': - this.state.lines[this.state.lines.length - 1] = blit; - this.setState({ lines: this.state.lines }); - break; - case 'nel': - this.state.lines.push(''); - this.setState({ lines: this.state.lines }); - break; - case 'sag': - blit.sav = blit.sag; - case 'sav': - let name = blit.sav.path.split('/').slice(-2).join('.'); - let buff = new Buffer(blit.sav.file, 'base64'); - let blob = new Blob([buff], {type: 'application/octet-stream'}); - saveAs(blob, name); - break; - case 'url': - //TODO too invasive? just print as ? - window.open(blit.url); - break; - default: console.log('weird blit', blit); - } - } - - setStateHandler(setState) { - this.setState = setState; - } -} - diff --git a/pkg/interface/src/views/apps/term/subscription.js b/pkg/interface/src/views/apps/term/subscription.js deleted file mode 100644 index 21f3cc8367..0000000000 --- a/pkg/interface/src/views/apps/term/subscription.js +++ /dev/null @@ -1,82 +0,0 @@ -export default class Subscription { - constructor(store, api, channel) { - this.store = store; - this.api = api; - this.channel = channel; - - this.channel.setOnChannelError(this.onChannelError.bind(this)); - this.firstRoundComplete = false; - } - - start() { - if (this.api.ship) { - this.firstRound(); - } else { - console.error('~~~ ERROR: Must set api.ship before operation ~~~'); - } - this.setupSlog(); - } - - setupSlog() { - let available = false; - const slog = new EventSource('/~_~/slog', { withCredentials: true }); - - slog.onopen = e => { - console.log('slog: opened stream'); - available = true; - } - - slog.onmessage = e => { - this.handleEvent({ slog: e.data }); - } - - slog.onerror = e => { - console.error('slog: eventsource error:', e); - if (available) { - window.setTimeout(() => { - if (slog.readyState !== EventSource.CLOSED) return; - console.log('slog: reconnecting...'); - this.setupSlog(); - }, 10000); - } - } - } - - delete() { - this.channel.delete(); - } - - onChannelError(err) { - console.error('event source error: ', err); - console.log('initiating new channel'); - this.firstRoundComplete = false; - setTimeout(2000, () => { - this.store.handleEvent({ - data: { clear : true } - }); - - this.start(); - }); - } - - subscribe(path, app) { - this.api.bind(path, 'PUT', this.api.ship, app, - this.handleEvent.bind(this), - (err) => { - console.log(err); - this.subscribe(path, app); - }, - () => { - this.subscribe(path, app); - }); - } - - firstRound() { - this.subscribe('/session/', 'herm'); - } - - handleEvent(diff) { - this.store.handleEvent(diff); - } -} - From 780b07e3d4b36ef2186aa2045b5ca929f6aaa529 Mon Sep 17 00:00:00 2001 From: fang Date: Mon, 8 Mar 2021 22:19:56 +0100 Subject: [PATCH 030/104] webterm: make %hop naming consistent with lull and belt. --- pkg/arvo/mar/blit.hoon | 2 +- pkg/interface/src/types/term-update.ts | 4 ++-- pkg/interface/src/views/apps/term/app.tsx | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/arvo/mar/blit.hoon b/pkg/arvo/mar/blit.hoon index 15d5768d70..c7b8868605 100644 --- a/pkg/arvo/mar/blit.hoon +++ b/pkg/arvo/mar/blit.hoon @@ -21,7 +21,7 @@ %bel b+& %clr b+& %hop ?@ p.blit (numb p.blit) - (pairs 'row'^(numb r.p.blit) 'col'^(numb c.p.blit) ~) + (pairs 'r'^(numb r.p.blit) 'c'^(numb c.p.blit) ~) %lin a+(turn p.blit |=(c=@c s+(tuft c))) %nel b+& %url s+p.blit diff --git a/pkg/interface/src/types/term-update.ts b/pkg/interface/src/types/term-update.ts index cad19fe504..9ae11dce70 100644 --- a/pkg/interface/src/types/term-update.ts +++ b/pkg/interface/src/types/term-update.ts @@ -23,8 +23,8 @@ export type Stub = { export type Blit = | { bel: null } // make a noise | { clr: null } // clear the screen - | { hop: number | { row: number, col: number } } // set cursor col/pos - | { klr: Array } // put styled + | { hop: number | { r: number, c: number } } // set cursor col/pos + | { klr: Array } // put styled | { lin: Array } // put text at cursor | { nel: null } // newline | { sag: { path: string, file: string } } // save to jamfile diff --git a/pkg/interface/src/views/apps/term/app.tsx b/pkg/interface/src/views/apps/term/app.tsx index 1a9f49fc49..96329efba7 100644 --- a/pkg/interface/src/views/apps/term/app.tsx +++ b/pkg/interface/src/views/apps/term/app.tsx @@ -167,7 +167,7 @@ export default function TermApp(props: TermAppProps) { out += csi('H', term.rows, blit.hop + 1); } else { - out += csi('H', term.rows - blit.hop.row, blit.hop.col + 1); + out += csi('H', term.rows - blit.hop.r, blit.hop.c + 1); } out += csi('s'); // save cursor position } From 2861de983b7d48ebcc0a730717c8904a8ba38fde Mon Sep 17 00:00:00 2001 From: fang Date: Wed, 10 Mar 2021 21:49:56 +0100 Subject: [PATCH 031/104] dill: replace %ctl and %met belts with %key Previously, we relied on foolish hacks, like [%met %bac], to send "special" keystrokes with modifiers. This updates the belt type to have %key, which represents a single keystroke, with any combination of modifier keys. Note that this has overlap with %txt to some extent. [%key ~ 'a'] should be considered equivalent and preferred to [%txt 'a' ~], but updating existing usage is left to a later commit. --- pkg/arvo/app/hood.hoon | 3 +- pkg/arvo/lib/hood/drum.hoon | 192 +++++++++++++++------- pkg/arvo/mar/belt.hoon | 34 +++- pkg/arvo/sys/lull.hoon | 6 +- pkg/arvo/sys/vane/dill.hoon | 20 ++- pkg/interface/src/logic/api/term.ts | 12 +- pkg/interface/src/views/apps/term/app.tsx | 8 +- pkg/urbit/include/c/motes.h | 1 + pkg/urbit/vere/io/term.c | 12 +- 9 files changed, 203 insertions(+), 85 deletions(-) diff --git a/pkg/arvo/app/hood.hoon b/pkg/arvo/app/hood.hoon index 24a9e524cc..27ef5005ca 100644 --- a/pkg/arvo/app/hood.hoon +++ b/pkg/arvo/app/hood.hoon @@ -2,7 +2,7 @@ /+ drum=hood-drum, helm=hood-helm, kiln=hood-kiln |% +$ state - $: %12 + $: %13 drum=state:drum helm=state:helm kiln=state:kiln @@ -15,6 +15,7 @@ [%9 drum=state:drum helm=state:helm kiln=state:kiln] [%10 drum=state:drum helm=state:helm kiln=state:kiln] [%11 drum=state:drum helm=state:helm kiln=state:kiln] + [%12 drum=any-state:drum helm=state:helm kiln=state:kiln] == +$ any-state-tuple $: drum=any-state:drum diff --git a/pkg/arvo/lib/hood/drum.hoon b/pkg/arvo/lib/hood/drum.hoon index 960f51989a..9a62bde253 100644 --- a/pkg/arvo/lib/hood/drum.hoon +++ b/pkg/arvo/lib/hood/drum.hoon @@ -1,10 +1,10 @@ /- *sole /+ sole |% -+$ any-state $%(state) -+$ state [%2 pith-2] ++$ any-state $%(state state-2) ++$ state [%3 pith] :: -++ pith-2 :: +++ pith :: $: eel=(set gill:gall) :: connect to ray=(set well:gall) :: fur=(map dude:gall (unit server)) :: servers @@ -49,6 +49,42 @@ pom=sole-prompt :: static prompt inp=sole-command :: input state == :: +:: +:: ++$ state-2 [%2 pith-2] +:: ++$ pith-2 + $: eel=(set gill:gall) + ray=(set well:gall) + fur=(map dude:gall (unit server)) + bin=(map bone source-2) + == +:: ++$ source-2 + $: edg=_80 + off=@ud + kil=kill + inx=@ud + fug=(map gill:gall (unit target-2)) + mir=(pair @ud stub) + == +:: ++$ target-2 + $: $= blt + %+ pair + (unit dill-belt-2) + (unit dill-belt-2) + ris=(unit search) + hit=history + pom=sole-prompt + inp=sole-command + == +:: ++$ dill-belt-2 + $% [%ctl p=@c] + [%met p=@c] + dill-belt:dill + == -- :: :: :: :::: :: :: @@ -217,49 +253,85 @@ == :: ++ on-load - |= [hood-version=@ud old=any-state] - =< se-abet =< se-view - =. sat old - =. dev (~(gut by bin) ost *source) - =? ..on-load (lte hood-version %4) - ~> %slog.0^leaf+"drum: starting os1 agents" - => (se-born | %home %s3-store) - => (se-born | %home %contact-view) - => (se-born | %home %contact-hook) - => (se-born | %home %contact-store) - => (se-born | %home %metadata-hook) - => (se-born | %home %metadata-store) - => (se-born | %home %goad) - ~> %slog.0^leaf+"drum: resubscribing to %dojo and %chat-cli" - => (se-drop:(se-pull our.hid %dojo) | our.hid %dojo) - (se-drop:(se-pull our.hid %chat-cli) | our.hid %chat-cli) - =? ..on-load (lte hood-version %5) - (se-born | %home %file-server) - =? ..on-load (lte hood-version %7) - (se-born | %home %glob) - =? ..on-load (lte hood-version %8) - => (se-born | %home %group-push-hook) - (se-born | %home %group-pull-hook) - =? ..on-load (lte hood-version %9) - (se-born | %home %graph-store) - =? ..on-load (lte hood-version %10) - => (se-born | %home %graph-push-hook) - (se-born | %home %graph-pull-hook) - =? ..on-load (lte hood-version %11) - => (se-born | %home %hark-graph-hook) - => (se-born | %home %hark-group-hook) - => (se-born | %home %hark-chat-hook) - => (se-born | %home %hark-store) - => (se-born | %home %observe-hook) - => (se-born | %home %metadata-pull-hook) - => (se-born | %home %metadata-push-hook) - (se-born | %home %herm) - =? ..on-load (lte hood-version %12) - => (se-born | %home %contact-push-hook) - => (se-born | %home %contact-pull-hook) - => (se-born | %home %settings-store) - (se-born | %home %group-view) - ..on-load + |^ |= [hood-version=@ud old=any-state] + =< se-abet =< se-view + =. sat (load-state old) + =. dev (~(gut by bin) ost *source) + (load-apps hood-version) + :: + ++ load-state + |= old=any-state + ^- state + ?- -.old + %3 old + %2 [%3 (pith-2-to-3 +.old)] + == + :: + ++ pith-2-to-3 + |= p=pith-2 + ^- pith + p(bin (~(run by bin.p) source-2-to-3)) + :: + ++ source-2-to-3 + |= s=source-2 + ^- source + s(fug (~(run by fug.s) |=(t=(unit target-2) (bind t target-2-to-3)))) + :: + ++ target-2-to-3 + |= t=target-2 + ^- target + :_ +.t + :- (bind p.blt.t belt-2-to-3) + (bind q.blt.t belt-2-to-3) + :: + ++ belt-2-to-3 + |= b=dill-belt-2 + ^- dill-belt:dill + ?. ?=(?(%ctl %met) -.b) b + [%key -.b p.b] + :: + ++ load-apps + |= hood-version=@ud + =? ..on-load (lte hood-version %4) + ~> %slog.0^leaf+"drum: starting os1 agents" + => (se-born | %home %s3-store) + => (se-born | %home %contact-view) + => (se-born | %home %contact-hook) + => (se-born | %home %contact-store) + => (se-born | %home %metadata-hook) + => (se-born | %home %metadata-store) + => (se-born | %home %goad) + ~> %slog.0^leaf+"drum: resubscribing to %dojo and %chat-cli" + => (se-drop:(se-pull our.hid %dojo) | our.hid %dojo) + (se-drop:(se-pull our.hid %chat-cli) | our.hid %chat-cli) + =? ..on-load (lte hood-version %5) + (se-born | %home %file-server) + =? ..on-load (lte hood-version %7) + (se-born | %home %glob) + =? ..on-load (lte hood-version %8) + => (se-born | %home %group-push-hook) + (se-born | %home %group-pull-hook) + =? ..on-load (lte hood-version %9) + (se-born | %home %graph-store) + =? ..on-load (lte hood-version %10) + => (se-born | %home %graph-push-hook) + (se-born | %home %graph-pull-hook) + =? ..on-load (lte hood-version %11) + => (se-born | %home %hark-graph-hook) + => (se-born | %home %hark-group-hook) + => (se-born | %home %hark-chat-hook) + => (se-born | %home %hark-store) + => (se-born | %home %observe-hook) + => (se-born | %home %metadata-pull-hook) + => (se-born | %home %metadata-push-hook) + (se-born | %home %herm) + =? ..on-load (lte hood-version %12) + => (se-born | %home %contact-push-hook) + => (se-born | %home %contact-pull-hook) + => (se-born | %home %settings-store) + (se-born | %home %group-view) + ..on-load + -- :: ++ reap-phat :: ack connect |= [way=wire saw=(unit tang)] @@ -721,12 +793,19 @@ ?- bet [%aro *] (ta-aro p.bet) [%bac *] ta-bac - [%ctl *] (ta-ctl p.bet) [%del *] ta-del [%hit *] (ta-hit +.bet) - [%met *] (ta-met p.bet) [%ret *] ta-ret [%txt *] (ta-txt p.bet) + :: + [%key *] + ?+ mod.bet + ?^ key.bet $(bet key.bet) + (ta-txt key.bet ~) + :: + %ctl (ta-ctl key.bet) + %met (ta-met key.bet) + == == :: ++ ta-det :: send edit @@ -750,7 +829,7 @@ (ta-hom %del (dec pos.inp)) :: ++ ta-ctl :: hear control - |= key=@c + |= key=bolt:dill ^+ +> =. ris ?.(?=(?(%g %r) key) ~ ris) ?+ key ta-bel @@ -891,8 +970,8 @@ kil ?. ?& ?=(^ old.kil) ?=(^ p.blt) - ?| ?=([%ctl ?(%k %u %w)] u.p.blt) - ?=([%met ?(%d %bac)] u.p.blt) + ?| ?=([%key %ctl ?(%k %u %w)] u.p.blt) + ?=([%key %met ?(%d [%bac ~])] u.p.blt) == == %= kil :: prepend num +(num.kil) @@ -909,17 +988,18 @@ == :: ++ ta-met :: meta key - |= key=@c + |= key=bolt:dill ^+ +> =. ris ~ ?+ key ta-bel - %dot ?. &(?=(^ old.hit) ?=(^ i.old.hit)) :: last "arg" from hist + %'.' ?. &(?=(^ old.hit) ?=(^ i.old.hit)) :: last "arg" from hist ta-bel =+ old=`(list @c)`i.old.hit =+ sop=(ta-jump(buf.say.inp old) %l %ace (lent old)) (ta-hom (cat:edit pos.inp (slag sop old))) :: - %bac ?: =(0 pos.inp) :: kill left-word + [%bac ~] + ?: =(0 pos.inp) :: kill left-word ta-bel =+ sop=(ta-pos %l %edg pos.inp) (ta-kil %l [(sub pos.inp sop) sop]) @@ -975,8 +1055,8 @@ :: %y ?. ?& ?=(^ old.kil) :: rotate & yank ?=(^ p.blt) - ?| ?=([%ctl %y] u.p.blt) - ?=([%met %y] u.p.blt) + ?| ?=([%key %ctl %y] u.p.blt) + ?=([%key %met %y] u.p.blt) == == ta-bel =+ las=(lent ta-yan) diff --git a/pkg/arvo/mar/belt.hoon b/pkg/arvo/mar/belt.hoon index bb8e29ce5e..3d417afb58 100644 --- a/pkg/arvo/mar/belt.hoon +++ b/pkg/arvo/mar/belt.hoon @@ -11,15 +11,31 @@ ^- $-(^json belt:dill) =, dejs:format %- of - :~ aro+(su (perk %d %l %r %u ~)) - bac+ul - ctl+(cu taft so) - del+ul - hit+(ot 'r'^ni 'c'^ni ~) - met+(cu taft so) - ret+ul - txt+(ar (cu taft so)) - == + |^ :* key+(ot 'mod'^mod 'key'^bot ~) + txt+(ar (cu taft so)) + bol + == + :: + ++ bol + :~ aro+(su (perk %d %l %r %u ~)) + bac+ul + del+ul + hit+(ot 'r'^ni 'c'^ni ~) + ret+ul + == + :: + ++ bot + |= jon=json + ?+ jon !! + [%s *] ((cu taft so) jon) + [%o *] ((of bol) jon) + == + :: + ++ mod + |= jon=json + ?~ jon ~ + ((su (perk %ctl %met %hyp ~)) jon) + -- -- :: +grow: convert to :: diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index 9a1bc4c4cf..133c9ea9cd 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -1068,13 +1068,15 @@ +$ belt :: outside belt $% [%aro p=?(%d %l %r %u)] :: arrow key [%bac ~] :: true backspace - [%ctl p=@c] :: control-key [%del ~] :: true delete [%hit r=@ud c=@ud] :: mouse click - [%met p=@c] :: meta-key + [%key mod=?(~ %ctl %met %hyp) key=bolt] :: input w/ modifier [%ret ~] :: return [%txt p=(list @c)] :: utf32 text == :: + +$ bolt :: single input + $@ @cF :: simple + $<(?(%txt %key) belt) :: special +$ blit :: outside blit $% [%bel ~] :: make a noise [%clr ~] :: clear the screen diff --git a/pkg/arvo/sys/vane/dill.hoon b/pkg/arvo/sys/vane/dill.hoon index b3a51890b2..0362134b6f 100644 --- a/pkg/arvo/sys/vane/dill.hoon +++ b/pkg/arvo/sys/vane/dill.hoon @@ -415,12 +415,18 @@ :: +$ axon-4 $: ram=term - tem=(unit (list dill-belt)) + tem=(unit (list dill-belt-4)) wid=_80 pos=$@(@ud [@ud @ud]) see=$%([%lin (list @c)] [%klr stub]) == :: + +$ dill-belt-4 + $% [%ctl p=@c] + [%met p=@c] + dill-belt + == + :: ++ axle-4-to-5 |= axle-4 ^- axle @@ -435,7 +441,17 @@ %+ ~(put by nay) ses (~(put in (~(get ju eye) duct)) duct) :: - ++ axon-4-to-5 |=(axon-4 `axon`[ram tem wid]) + ++ axon-4-to-5 + |= axon-4 + ^- axon + =; tem [ram tem wid] + ?~ tem ~ + %- some + %+ turn u.tem + |= b=dill-belt-4 + ^- dill-belt + ?. ?=(?(%ctl %met) -.b) b + [%key -.b p.b] -- :: ++ scry diff --git a/pkg/interface/src/logic/api/term.ts b/pkg/interface/src/logic/api/term.ts index 35ccf909e0..d380af0b69 100644 --- a/pkg/interface/src/logic/api/term.ts +++ b/pkg/interface/src/logic/api/term.ts @@ -1,14 +1,20 @@ import BaseApi from './base'; import { StoreState } from '../store/type'; -export type Belt = +type Bork = | { aro: 'd' | 'l' | 'r' | 'u' } | { bac: null } - | { ctl: string } | { del: null } | { hit: { r: number, c: number } } - | { met: string } | { ret: null } + +export type Bolt = + | string + | Bork + +export type Belt = + | Bork + | { key: { mod: null | 'ctl' | 'met' | 'hyp', key: Bolt } } | { txt: Array }; export default class TermApi extends BaseApi { diff --git a/pkg/interface/src/views/apps/term/app.tsx b/pkg/interface/src/views/apps/term/app.tsx index 96329efba7..ad17eea584 100644 --- a/pkg/interface/src/views/apps/term/app.tsx +++ b/pkg/interface/src/views/apps/term/app.tsx @@ -264,7 +264,7 @@ export default function TermApp(props: TermAppProps) { belts.push({ ret: null }); } else if (c <= 26) { - belts.push({ ctl: String.fromCharCode(96 + c) }); + belts.push({ key: { mod: 'ctl', key: String.fromCharCode(96 + c) } }); } // escape sequences @@ -295,13 +295,13 @@ export default function TermApp(props: TermAppProps) { } } else if (c >= 97 && c <= 122) { // a <= c <= z - belts.push({ met: e[0] }); + belts.push({ key: { mod: 'met', key: e[0] } }); } else if (c === 46) { // . - belts.push({ met: 'dot' }); + belts.push({ key: { mod: 'met', key: '.' } }); } else if (c === 8 || c === 127) { - belts.push({ met: 'bac' }); + belts.push({ key: { mod: 'met', key: { bac: null } } }); } else { term.write('\x07'); break; // bel diff --git a/pkg/urbit/include/c/motes.h b/pkg/urbit/include/c/motes.h index a06d7d2577..8091fc2862 100644 --- a/pkg/urbit/include/c/motes.h +++ b/pkg/urbit/include/c/motes.h @@ -603,6 +603,7 @@ # define c3__just c3_s4('j','u','s','t') # define c3__keep c3_s4('k','e','e','p') # define c3__kern c3_s4('k','e','r','n') +# define c3__key c3_s3('k','e','y') # define c3__kgo c3_s3('k','g','o') # define c3__kick c3_s4('k','i','c','k') # define c3__king c3_s4('k','i','n','g') diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index edf113409f..5db020fea0 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -800,15 +800,11 @@ _term_io_suck_char(u3_utty* uty_u, c3_y cay_y) else { if ( (cay_y >= 'a') && (cay_y <= 'z') ) { tat_u->esc.ape = c3n; - _term_io_belt(uty_u, u3nc(c3__met, cay_y)); - } - else if ( '.' == cay_y ) { - tat_u->esc.ape = c3n; - _term_io_belt(uty_u, u3nc(c3__met, c3__dot)); + _term_io_belt(uty_u, u3nt(c3__key, c3__met, cay_y)); } else if ( 8 == cay_y || 127 == cay_y ) { tat_u->esc.ape = c3n; - _term_io_belt(uty_u, u3nc(c3__met, c3__bac)); + _term_io_belt(uty_u, u3nq(c3__key, c3__met, c3__bac, u3_nul)); } else if ( ('[' == cay_y) || ('O' == cay_y) ) { tat_u->esc.bra = c3y; @@ -877,7 +873,7 @@ _term_io_suck_char(u3_utty* uty_u, c3_y cay_y) } #endif else if ( cay_y <= 26 ) { - _term_io_belt(uty_u, u3nc(c3__ctl, ('a' + (cay_y - 1)))); + _term_io_belt(uty_u, u3nt(c3__key, c3__ctl, ('a' + (cay_y - 1)))); } else if ( 27 == cay_y ) { tat_u->esc.ape = c3y; @@ -1211,7 +1207,7 @@ u3_term_ef_ctlc(void) { u3_noun wir = u3nt(c3__term, '1', u3_nul); - u3_noun cad = u3nt(c3__belt, c3__ctl, 'c'); + u3_noun cad = u3nq(c3__belt, c3__key, c3__ctl, 'c'); c3_assert( 1 == uty_u->tid_l ); c3_assert( uty_u->car_u ); From 4b7f05c6813ddca9dacba89eec00a2b42e8e8741 Mon Sep 17 00:00:00 2001 From: fang Date: Thu, 11 Mar 2021 00:45:59 +0100 Subject: [PATCH 032/104] dill: rename %lin to %put It's no longer strictly a full line of screen content, instead more accurately described now as "put text at cursor". --- pkg/arvo/lib/hood/drum.hoon | 4 ++-- pkg/arvo/lib/ph/util.hoon | 2 +- pkg/arvo/mar/blit.hoon | 2 +- pkg/arvo/mar/dill/blit.hoon | 2 +- pkg/arvo/sys/lull.hoon | 2 +- pkg/arvo/sys/vane/dill.hoon | 2 +- pkg/arvo/ted/aqua/dill.hoon | 5 +++-- pkg/interface/src/types/term-update.ts | 2 +- pkg/interface/src/views/apps/term/app.tsx | 4 ++-- pkg/urbit/vere/io/term.c | 2 +- 10 files changed, 14 insertions(+), 13 deletions(-) diff --git a/pkg/arvo/lib/hood/drum.hoon b/pkg/arvo/lib/hood/drum.hoon index 9a62bde253..3601c0274f 100644 --- a/pkg/arvo/lib/hood/drum.hoon +++ b/pkg/arvo/lib/hood/drum.hoon @@ -644,7 +644,7 @@ ?. ((sane %t) (crip i.wol)) :: XX upstream validation ~& bad-text+<`*`i.wol> $(wol t.wol) - $(wol t.wol, +>.^$ (se-blin %lin (tuba i.wol))) + $(wol t.wol, +>.^$ (se-blin %put (tuba i.wol))) :: ++ se-join :: confirm connection |= gyl=gill:gall @@ -723,7 +723,7 @@ ?. ((sane %t) (crip txt)) :: XX upstream validation ~& bad-text+<`*`txt> +> - (se-blin %lin (tuba txt)) + (se-blin %put (tuba txt)) :: ++ se-poke :: send a poke |= [gyl=gill:gall par=cage] diff --git a/pkg/arvo/lib/ph/util.hoon b/pkg/arvo/lib/ph/util.hoon index 09e7ff623d..3fd55c35ea 100644 --- a/pkg/arvo/lib/ph/util.hoon +++ b/pkg/arvo/lib/ph/util.hoon @@ -67,7 +67,7 @@ :: %+ lien p.q.uf |= =blit:dill - ?. ?=(%lin -.blit) + ?. ?=(%put -.blit) | !=(~ (find what p.blit)) == diff --git a/pkg/arvo/mar/blit.hoon b/pkg/arvo/mar/blit.hoon index c7b8868605..232c8021a9 100644 --- a/pkg/arvo/mar/blit.hoon +++ b/pkg/arvo/mar/blit.hoon @@ -22,7 +22,7 @@ %clr b+& %hop ?@ p.blit (numb p.blit) (pairs 'r'^(numb r.p.blit) 'c'^(numb c.p.blit) ~) - %lin a+(turn p.blit |=(c=@c s+(tuft c))) + %put a+(turn p.blit |=(c=@c s+(tuft c))) %nel b+& %url s+p.blit %wyp b+& diff --git a/pkg/arvo/mar/dill/blit.hoon b/pkg/arvo/mar/dill/blit.hoon index f70280139e..9384ae91d3 100644 --- a/pkg/arvo/mar/dill/blit.hoon +++ b/pkg/arvo/mar/dill/blit.hoon @@ -20,7 +20,7 @@ ?+ -.dib ~|(unsupported-blit+-.dib !!) %mor [%a (turn p.dib |=(a=dill-blit:dill json(dib a)))] %hop (frond %hop (numb p.dib)) - %lin (frond -.dib (tape (tufa p.dib))) + %put (frond -.dib (tape (tufa p.dib))) ?(%bel %clr) (frond %act %s -.dib) == -- diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index 133c9ea9cd..64168b00f0 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -1082,7 +1082,7 @@ [%clr ~] :: clear the screen [%hop p=$@(@ud [r=@ud c=@ud])] :: set cursor col/pos [%klr p=stub] :: put styled - [%lin p=(list @c)] :: put text at cursor + [%put p=(list @c)] :: put text at cursor [%nel ~] :: newline [%sag p=path q=*] :: save to jamfile [%sav p=path q=@] :: save to file diff --git a/pkg/arvo/sys/vane/dill.hoon b/pkg/arvo/sys/vane/dill.hoon index 0362134b6f..3b853f3fcc 100644 --- a/pkg/arvo/sys/vane/dill.hoon +++ b/pkg/arvo/sys/vane/dill.hoon @@ -172,7 +172,7 @@ =| biz=(list blit) |- ^+ +>.^$ ?~ liz (done %blit [%hop 0] [%wyp ~] biz) - $(liz t.liz, biz (welp biz [%lin i.liz] [%nel ~] ~)) + $(liz t.liz, biz (welp biz [%put i.liz] [%nel ~] ~)) :: since dill is acting on its own accord, :: we %hey the term app so it may clean up. :: diff --git a/pkg/arvo/ted/aqua/dill.hoon b/pkg/arvo/ted/aqua/dill.hoon index 4d3b7b2e4e..7ce9ff0737 100644 --- a/pkg/arvo/ted/aqua/dill.hoon +++ b/pkg/arvo/ted/aqua/dill.hoon @@ -17,15 +17,16 @@ %+ roll blits |= [b=blit:dill line=tape] ?- -.b - %lin (tape p.b) + %put (tape p.b) %klr (tape (zing (turn p.b tail))) - %mor ~& "{}: {line}" "" + %nel ~& "{}: {line}" "" %hop line %bel line %clr "" %sag ~& [%save-jamfile-to p.b] line %sav ~& [%save-file-to p.b] line %url ~& [%activate-url p.b] line + %wyp "" == ~? !=(~ last-line) last-line ~ diff --git a/pkg/interface/src/types/term-update.ts b/pkg/interface/src/types/term-update.ts index 9ae11dce70..3f85136539 100644 --- a/pkg/interface/src/types/term-update.ts +++ b/pkg/interface/src/types/term-update.ts @@ -25,7 +25,7 @@ export type Blit = | { clr: null } // clear the screen | { hop: number | { r: number, c: number } } // set cursor col/pos | { klr: Array } // put styled - | { lin: Array } // put text at cursor + | { put: Array } // put text at cursor | { nel: null } // newline | { sag: { path: string, file: string } } // save to jamfile | { sav: { path: string, file: string } } // save to file diff --git a/pkg/interface/src/views/apps/term/app.tsx b/pkg/interface/src/views/apps/term/app.tsx index ad17eea584..27a09a57a4 100644 --- a/pkg/interface/src/views/apps/term/app.tsx +++ b/pkg/interface/src/views/apps/term/app.tsx @@ -171,8 +171,8 @@ export default function TermApp(props: TermAppProps) { } out += csi('s'); // save cursor position } - else if ('lin' in blit) { - out += blit.lin.join(''); + else if ('put' in blit) { + out += blit.put.join(''); out += csi('u'); } else if ('klr' in blit) { diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index 5db020fea0..506063dea5 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -1480,7 +1480,7 @@ _term_ef_blit(u3_utty* uty_u, _term_it_show_stub(uty_u, u3k(u3t(blt))); } break; - case c3__lin: { + case c3__put: { _term_it_show_tour(uty_u, u3k(u3t(blt))); } break; From 81e78082479fff9958f41007580205d70726dff6 Mon Sep 17 00:00:00 2001 From: fang Date: Thu, 11 Mar 2021 19:53:57 +0100 Subject: [PATCH 033/104] webterm: improve state management/lifecycle Results in slightly better behavior... but it still breaks on dev auto-refresh? Also no longer does the ''<->'default' transform for the default session identification in state, instead always using the empty string. --- pkg/interface/src/logic/state/term.ts | 19 +++++ pkg/interface/src/views/apps/term/app.tsx | 86 +++++++++++------------ 2 files changed, 59 insertions(+), 46 deletions(-) create mode 100644 pkg/interface/src/logic/state/term.ts diff --git a/pkg/interface/src/logic/state/term.ts b/pkg/interface/src/logic/state/term.ts new file mode 100644 index 0000000000..a0a7d81ad0 --- /dev/null +++ b/pkg/interface/src/logic/state/term.ts @@ -0,0 +1,19 @@ +import { Terminal } from 'xterm'; +import { FitAddon } from 'xterm-addon-fit'; + +import { BaseState, createState } from "./base"; + +type Session = { term: Terminal, fit: FitAddon }; +type Sessions = { [id: string]: Session; } + +export interface TermState extends BaseState { + sessions: Sessions, + selected: string, +}; + +const useTermState = createState('Term', { + sessions: {}, + selected: '', // empty string is default session +}, ['sessions']); //TODO consider persisting + +export default useTermState; \ No newline at end of file diff --git a/pkg/interface/src/views/apps/term/app.tsx b/pkg/interface/src/views/apps/term/app.tsx index 27a09a57a4..6772560c07 100644 --- a/pkg/interface/src/views/apps/term/app.tsx +++ b/pkg/interface/src/views/apps/term/app.tsx @@ -5,9 +5,10 @@ import React, { useRef, useCallback } from 'react'; -import { Route } from 'react-router-dom'; import Helmet from 'react-helmet'; +import useTermState, { TermState } from '~/logic/state/term'; + import { Terminal, ITerminalOptions } from 'xterm'; import { FitAddon } from 'xterm-addon-fit'; import { saveAs } from 'file-saver'; @@ -19,7 +20,7 @@ import GlobalApi from '~/logic/api/global'; import { Belt } from '~/logic/api/term'; import { Blit, Stye, Stub, Tint, Deco } from '~/types/term-update'; -import bel from '../../../logic/lib/bel'; +import bel from '~/logic/lib/bel'; type TermAppProps = { api: GlobalApi; @@ -27,14 +28,6 @@ type TermAppProps = { notificationsCount: number; } -type Sessions = { - [id: string]: { - term: Terminal, - fit: FitAddon, - sub: boolean - }; -} - const termConfig: ITerminalOptions = { logLevel: 'warn', // @@ -118,15 +111,16 @@ export default function TermApp(props: TermAppProps) { const { api } = props; const container = useRef(null); - const [sessions, setSessions] = useState({}); - const [selected, setSelected] = useState('default'); //TODO allow switching + + //TODO allow switching of selected + const { sessions, selected, set } = useTermState(); const onSlog = useCallback((slog) => { - if (!sessions['default']) { + if (!sessions['']) { console.log('default session mia!', 'slog:', slog); return; } - const term = sessions['default'].term; + const term = sessions[''].term; // set scroll region to exclude the bottom line, // scroll up one line, @@ -143,8 +137,9 @@ export default function TermApp(props: TermAppProps) { + csi('m', 0) + csi('r') + csi('u')); - }, []); + }, [sessions['']]); + //TODO could be static function if we pass in Terminal explicitly? const onBlit = useCallback((ses: string, blit: Blit) => { //TODO if (!sessions[ses]) { @@ -205,8 +200,8 @@ export default function TermApp(props: TermAppProps) { console.log('weird blit', blit); } - sessions[ses].term.write(out); - }, []); + term.write(out); + }, [sessions]); const setupSlog = useCallback(() => { console.log('slog: setting up...'); @@ -234,7 +229,7 @@ export default function TermApp(props: TermAppProps) { } }, [onSlog]); - const onInput = useCallback((ses: string, e) => { + const onInput = useCallback((ses: string, e: string) => { const term = sessions[ses].term; let belts: Array = []; let strap = ''; @@ -328,15 +323,14 @@ export default function TermApp(props: TermAppProps) { }; }, []); - // when switching sessions, initialize if necessary - // useEffect(() => { + let ses = sessions[selected]; + // initialize terminal // - if (!sessions[selected]) { + if (!ses) { // set up terminal // - console.log('new term!', selected); let term = new Terminal(termConfig); const fit = new FitAddon(); term.loadAddon(fit); @@ -349,42 +343,41 @@ export default function TermApp(props: TermAppProps) { // term.onData((e) => onInput(selected, e)); term.onBinary((e) => onInput(selected, e)); + //TODO term.onResize - //TODO open subscription + ses = { term, fit }; - // persist in state + // open subscription // - sessions[selected] = { term, fit, sub: false }; - setSessions(sessions); - } - - if (container.current) { - sessions[selected].term.open(container.current); //TODO once - sessions[selected].fit.fit(); //TODO if not default, send %blew - } - - console.log('need sub?', selected, sessions[selected].sub); - if (!sessions[selected].sub) { - //TODO BaseSubscribe? - let ses = selected; - if (ses === 'default') ses = ''; - //TODO get from a SubscriptionBase somewhere? - console.log('starting sub', selected); - api.subscribe('/session/', 'PUT', api.ship, 'herm', + //TODO start default session alongside other landscape subscriptions, + // once subscription refactor is in. + api.subscribe('/session/'+selected, 'PUT', api.ship, 'herm', (e) => { onBlit(selected, e.data); }, (err) => { // fail - console.log(err); + console.log('sub error', selected, err); //TODO resubscribe }, () => { // quit //TODO resubscribe - }); - //TODO set in state + } + ); } - //TODO can we do sessions[selected]? - }, [container.current, sessions, selected, onBlit]); + + if (container.current && !container.current.contains(ses.term.element || null)) { + ses.term.open(container.current); + ses.fit.fit(); //TODO if not default, send %blew + ses.term.focus(); + } + + set(state => { state.sessions[selected] = ses; }); + + return () => { + //TODO unload term from container + // but term.dispose is too powerful? maybe just empty the container? + } + }, [set, sessions[selected], container.current]); return ( <> @@ -404,6 +397,7 @@ export default function TermApp(props: TermAppProps) { mx={['0','3']} mb={['0','3']} border={['0','1']} + //@ts-ignore //NOTE fix in indigo Soon™ ref={container} //TODO might somehow be undefined? > From d355d3b71ca20d96dd5a39831bc72f04f717f5e6 Mon Sep 17 00:00:00 2001 From: fang Date: Sat, 13 Mar 2021 00:38:06 +0100 Subject: [PATCH 034/104] webterm: improve style & dark mode reactivity Now reacts to changes in light/dark more, uses Landscape font set, covers up container gaps. --- pkg/interface/src/views/apps/term/app.tsx | 60 +++++-- .../src/views/apps/term/css/custom.css | 157 ------------------ 2 files changed, 47 insertions(+), 170 deletions(-) delete mode 100644 pkg/interface/src/views/apps/term/css/custom.css diff --git a/pkg/interface/src/views/apps/term/app.tsx b/pkg/interface/src/views/apps/term/app.tsx index 6772560c07..090fb5dce6 100644 --- a/pkg/interface/src/views/apps/term/app.tsx +++ b/pkg/interface/src/views/apps/term/app.tsx @@ -1,21 +1,21 @@ import React, { - Component, - useState, useEffect, useRef, useCallback } from 'react'; import Helmet from 'react-helmet'; -import useTermState, { TermState } from '~/logic/state/term'; +import useTermState from '~/logic/state/term'; +import useSettingsState from "~/logic/state/settings"; +import useLocalState from "~/logic/state/local"; -import { Terminal, ITerminalOptions } from 'xterm'; +import { Terminal, ITerminalOptions, ITheme } from 'xterm'; import { FitAddon } from 'xterm-addon-fit'; import { saveAs } from 'file-saver'; import { Box, Col } from '@tlon/indigo-react'; -import './css/custom.css'; +import '../../../../node_modules/xterm/css/xterm.css' import GlobalApi from '~/logic/api/global'; import { Belt } from '~/logic/api/term'; import { Blit, Stye, Stub, Tint, Deco } from '~/types/term-update'; @@ -28,6 +28,26 @@ type TermAppProps = { notificationsCount: number; } +const makeTheme = (dark: boolean): ITheme => { + let fg, bg: string; + if (dark) { + fg = 'white'; + bg = 'black'; + } else { + fg = 'black'; + bg = 'white'; + } + //TODO indigo colors. + // we can't pluck these from ThemeContext because they have transparency. + // technically xterm supports transparency, but it degrades performance. + return { + foreground: fg, + background: bg, + brightBlack: '#7f7f7f', //NOTE slogs + cursor: fg, + } +} + const termConfig: ITerminalOptions = { logLevel: 'warn', // @@ -37,13 +57,9 @@ const termConfig: ITerminalOptions = { cols: 80, scrollback: 10000, // - theme: { //TODO vary with landscape theme? - foreground: 'black', - background: 'white', - cursor: 'black', - cursorAccent: 'white', - //TODO selection color - }, + fontFamily: '"Source Code Pro","Roboto mono","Courier New",monospace', + //NOTE theme colors configured dynamically + // bellStyle: 'sound', bellSound: bel, // @@ -111,10 +127,13 @@ export default function TermApp(props: TermAppProps) { const { api } = props; const container = useRef(null); - //TODO allow switching of selected const { sessions, selected, set } = useTermState(); + const osDark = useLocalState((state) => state.dark); + const theme = useSettingsState(s => s.display.theme); + const dark = theme === 'dark' || (theme === 'auto' && osDark); + const onSlog = useCallback((slog) => { if (!sessions['']) { console.log('default session mia!', 'slog:', slog); @@ -323,6 +342,20 @@ export default function TermApp(props: TermAppProps) { }; }, []); + // on dark mode change, change terminals' theme + // + useEffect(() => { + const theme = makeTheme(dark); + for (let ses in sessions) { + sessions[ses].term.setOption('theme', theme); + } + if (container.current) { + container.current.style.backgroundColor = theme.background || ''; + } + }, [dark, sessions]); + + // on selected change, maybe setup the term, or put it into the container + // useEffect(() => { let ses = sessions[selected]; @@ -332,6 +365,7 @@ export default function TermApp(props: TermAppProps) { // set up terminal // let term = new Terminal(termConfig); + term.setOption('theme', makeTheme(dark)); const fit = new FitAddon(); term.loadAddon(fit); diff --git a/pkg/interface/src/views/apps/term/css/custom.css b/pkg/interface/src/views/apps/term/css/custom.css deleted file mode 100644 index b5222f5e67..0000000000 --- a/pkg/interface/src/views/apps/term/css/custom.css +++ /dev/null @@ -1,157 +0,0 @@ -input#term { - background-color: inherit; - color: inherit; -} - -.blink { - animation: 4s ease-in-out infinite opacity_blink; -} - -@keyframes opacity_blink { - 0% { opacity: 0; } - 10% { opacity: 1; } - 80% { opacity: 1; } - 90% { opacity: 0; } - 100% { opacity: 0; } -} - -/** - * Default styles for xterm.js - * TODO import from xterm in node_modules, but how? - */ - - .xterm { - font-feature-settings: "liga" 0; - position: relative; - user-select: none; - -ms-user-select: none; - -webkit-user-select: none; -} - -.xterm.focus, -.xterm:focus { - outline: none; -} - -.xterm .xterm-helpers { - position: absolute; - top: 0; - /** - * The z-index of the helpers must be higher than the canvases in order for - * IMEs to appear on top. - */ - z-index: 5; -} - -.xterm .xterm-helper-textarea { - padding: 0; - border: 0; - margin: 0; - /* Move textarea out of the screen to the far left, so that the cursor is not visible */ - position: absolute; - opacity: 0; - left: -9999em; - top: 0; - width: 0; - height: 0; - z-index: -5; - /** Prevent wrapping so the IME appears against the textarea at the correct position */ - white-space: nowrap; - overflow: hidden; - resize: none; -} - -.xterm .composition-view { - /* TODO: Composition position got messed up somewhere */ - background: #000; - color: #FFF; - display: none; - position: absolute; - white-space: nowrap; - z-index: 1; -} - -.xterm .composition-view.active { - display: block; -} - -.xterm .xterm-viewport { - /* On OS X this is required in order for the scroll bar to appear fully opaque */ - background-color: #000; - overflow-y: scroll; - cursor: default; - position: absolute; - right: 0; - left: 0; - top: 0; - bottom: 0; -} - -.xterm .xterm-screen { - position: relative; -} - -.xterm .xterm-screen canvas { - position: absolute; - left: 0; - top: 0; -} - -.xterm .xterm-scroll-area { - visibility: hidden; -} - -.xterm-char-measure-element { - display: inline-block; - visibility: hidden; - position: absolute; - top: 0; - left: -9999em; - line-height: normal; -} - -.xterm { - cursor: text; -} - -.xterm.enable-mouse-events { - /* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */ - cursor: default; -} - -.xterm.xterm-cursor-pointer { - cursor: pointer; -} - -.xterm.column-select.focus { - /* Column selection mode */ - cursor: crosshair; -} - -.xterm .xterm-accessibility, -.xterm .xterm-message { - position: absolute; - left: 0; - top: 0; - bottom: 0; - right: 0; - z-index: 10; - color: transparent; -} - -.xterm .live-region { - position: absolute; - left: -9999px; - width: 1px; - height: 1px; - overflow: hidden; -} - -.xterm-dim { - opacity: 0.5; -} - -.xterm-underline { - text-decoration: underline; -} - From 23ec162c2fed5ec51b243e3ea1fa4ded19241cab Mon Sep 17 00:00:00 2001 From: fang Date: Sat, 13 Mar 2021 02:15:02 +0100 Subject: [PATCH 035/104] term: rewrite _term_it_send_csi Instead of asynchronously printing the sequence as we render it, construct it once and then write it out synchronously. --- pkg/urbit/vere/io/term.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index 506063dea5..c471a3ebac 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -433,24 +433,31 @@ _term_it_send_csi(u3_utty *uty_u, c3_c cmd_c, c3_w num_w, ...) va_list ap; va_start(ap, num_w); - uv_buf_t esc_u = TERM_LIT_BUF("\033["); - _term_it_dump_buf(uty_u, &esc_u); + // allocate for escape sequence (2), command char (1), + // argument digits (5 per arg) and separators (1 per arg, minus 1). + // freed via _term_it_write. + // + c3_c* pas_c = malloc( sizeof(*pas_c) * (2 + num_w * 6) ); + c3_c was_c = 0; + + pas_c[was_c++] = '\033'; + pas_c[was_c++] = '['; - uv_buf_t sep_u = TERM_LIT_BUF(";"); //REVIEW re-use works fine, but is it? while ( num_w > 0 ) { c3_w par_w = va_arg(ap, c3_w); - c3_c pas_c[5]; - c3_c was_c = sprintf(pas_c, "%d", par_w); - uv_buf_t pas_u = uv_buf_init(pas_c, was_c); - _term_it_dump_buf(uty_u, &pas_u); + was_c += sprintf(pas_c+was_c, "%d", par_w); if ( --num_w > 0 ) { - _term_it_dump_buf(uty_u, &sep_u); + pas_c[was_c++] = ';'; } } - uv_buf_t cmd_u = uv_buf_init(&cmd_c, 1); - _term_it_dump_buf(uty_u, &cmd_u); + pas_c[was_c++] = cmd_c; + + uv_buf_t pas_u = uv_buf_init(pas_c, was_c); + _term_it_write(uty_u, &pas_u, pas_c); + + va_end(ap); } /* _term_it_free_line(): wipe line stored by _term_it_save_line From 8f922656807846b3be9ae1ec2f048b9cbbe03bc0 Mon Sep 17 00:00:00 2001 From: fang Date: Sat, 13 Mar 2021 02:17:06 +0100 Subject: [PATCH 036/104] term: correctly deduce stub memory requirements We were only counting one instead of two colors (fg/bg), and not allowing for combined decorators. --- pkg/urbit/vere/io/term.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index c471a3ebac..e494d1b814 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -1329,11 +1329,11 @@ _term_it_show_stub(u3_utty* uty_u, // allocate enough memory for every display character, plus styles // - //NOTE we use max 31 characters per styl for escape codes: - // 3 for opening, 4 for decorations, 15 for colors, 4 for closing, - // and 5 as separators between decorations and colors. + //NOTE we use max 48 characters per styl for escape codes: + // 2 for opening, 7 for decorations, 2x16 for colors, 4 for closing, + // and 3 as separators between decorations and colors. // - c3_w* lin_w = c3_malloc( sizeof(c3_w) * (lec_w + (31 * tuc_w)) ); + c3_w* lin_w = c3_malloc( sizeof(c3_w) * (lec_w + (48 * tuc_w)) ); // write the contents to the buffer, // tracking total and escape characters written From 7fe8c67684138ffb82e053f6096787354b8295da Mon Sep 17 00:00:00 2001 From: fang Date: Sat, 13 Mar 2021 02:34:45 +0100 Subject: [PATCH 037/104] drum: restrict +se-blin to expected/sane blits We only expect the two primary screen-draw blits here. --- pkg/arvo/lib/hood/drum.hoon | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/arvo/lib/hood/drum.hoon b/pkg/arvo/lib/hood/drum.hoon index 3601c0274f..6977cfac55 100644 --- a/pkg/arvo/lib/hood/drum.hoon +++ b/pkg/arvo/lib/hood/drum.hoon @@ -622,7 +622,9 @@ leaf+tape :: ++ se-blin :: print and newline - |= lin=dill-blit:dill + |= $= lin + $~ [%put ~] + $>(?(%put %klr) dill-blit:dill) ^+ +> :: newline means we need to redraw the prompt, :: so update the prompt mirror accordingly. From 1d43942bf2e399692584a53154210bf5287dc99a Mon Sep 17 00:00:00 2001 From: fang Date: Mon, 15 Mar 2021 21:19:28 +0100 Subject: [PATCH 038/104] various: fix compilation failures Due to recent dill changes. --- pkg/arvo/gen/aqua/dojo.hoon | 4 ++-- pkg/arvo/lib/ph/util.hoon | 6 +++--- pkg/arvo/mar/dill/belt.hoon | 4 ++-- pkg/arvo/mar/dill/blit.hoon | 4 +++- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/pkg/arvo/gen/aqua/dojo.hoon b/pkg/arvo/gen/aqua/dojo.hoon index 9850f34bf1..65f5ccf439 100644 --- a/pkg/arvo/gen/aqua/dojo.hoon +++ b/pkg/arvo/gen/aqua/dojo.hoon @@ -5,8 +5,8 @@ :- %aqua-events %+ turn ^- (list unix-event) - :~ [//term/1 %belt %ctl `@c`%e] - [//term/1 %belt %ctl `@c`%u] + :~ [//term/1 %belt %key %ctl `@c`%e] + [//term/1 %belt %key %ctl `@c`%u] [//term/1 %belt %txt ((list @c) command)] [//term/1 %belt %ret ~] == diff --git a/pkg/arvo/lib/ph/util.hoon b/pkg/arvo/lib/ph/util.hoon index 3fd55c35ea..8a7103e8fc 100644 --- a/pkg/arvo/lib/ph/util.hoon +++ b/pkg/arvo/lib/ph/util.hoon @@ -28,8 +28,8 @@ %+ send-events-to who ^- (list unix-event) :~ - [//term/1 %belt %ctl `@c`%e] - [//term/1 %belt %ctl `@c`%u] + [//term/1 %belt %key %ctl `@c`%e] + [//term/1 %belt %key %ctl `@c`%u] [//term/1 %belt %txt ((list @c) what)] [//term/1 %belt %ret ~] == @@ -40,7 +40,7 @@ |= [who=ship what=term] ^- (list ph-event) %+ send-events-to who - :~ [//term/1 %belt %ctl (,@c what)] + :~ [//term/1 %belt %key %ctl (,@c what)] == :: :: Inject a file into a ship diff --git a/pkg/arvo/mar/dill/belt.hoon b/pkg/arvo/mar/dill/belt.hoon index 1677b6ef1e..9c52902699 100644 --- a/pkg/arvo/mar/dill/belt.hoon +++ b/pkg/arvo/mar/dill/belt.hoon @@ -45,8 +45,8 @@ =+ cha=(tuba (trip q.kev)) ?> ?=([@ ~] cha) :: of a single character ?+ mod !! :: modified by one buckykey - [%ctrl ~ ~] [%ctl i.cha] - [%alt ~ ~] [%met i.cha] + [%ctrl ~ ~] [%key %ctl i.cha] + [%alt ~ ~] [%key %met i.cha] == ?@ q.kev [%txt (tuba (trip q.kev))] diff --git a/pkg/arvo/mar/dill/blit.hoon b/pkg/arvo/mar/dill/blit.hoon index 9384ae91d3..5ec9b08cbe 100644 --- a/pkg/arvo/mar/dill/blit.hoon +++ b/pkg/arvo/mar/dill/blit.hoon @@ -19,7 +19,9 @@ ^- ^json ?+ -.dib ~|(unsupported-blit+-.dib !!) %mor [%a (turn p.dib |=(a=dill-blit:dill json(dib a)))] - %hop (frond %hop (numb p.dib)) + %hop %+ frond %hop + ?@ p.dib (numb p.dib) + (pairs 'r'^(numb r.p.dib) 'c'^(numb c.p.dib) ~) %put (frond -.dib (tape (tufa p.dib))) ?(%bel %clr) (frond %act %s -.dib) == From 49a991e40e123cfc3bb5a12c395f77d9e93c087c Mon Sep 17 00:00:00 2001 From: fang Date: Fri, 19 Mar 2021 23:56:51 +0100 Subject: [PATCH 039/104] term: final +belt tweaks The previous version allowed for redundant values (both [%bac ~] and [%key ~ %bac ~] for example), had an odd constraint in @cF, and relied unnecessarily on $<. Also rewords some of the belt and blit descriptions. --- pkg/arvo/lib/hood/drum.hoon | 18 ++++++++--------- pkg/arvo/lib/ph/util.hoon | 6 +++--- pkg/arvo/mar/belt.hoon | 22 ++++++++++++--------- pkg/arvo/mar/dill/belt.hoon | 4 ++-- pkg/arvo/sys/lull.hoon | 24 ++++++++++++----------- pkg/arvo/sys/vane/dill.hoon | 2 +- pkg/interface/src/logic/api/term.ts | 11 ++++------- pkg/interface/src/views/apps/term/app.tsx | 8 ++++---- pkg/urbit/vere/io/term.c | 8 ++++---- 9 files changed, 52 insertions(+), 51 deletions(-) diff --git a/pkg/arvo/lib/hood/drum.hoon b/pkg/arvo/lib/hood/drum.hoon index 6977cfac55..4b83c1d4bf 100644 --- a/pkg/arvo/lib/hood/drum.hoon +++ b/pkg/arvo/lib/hood/drum.hoon @@ -288,7 +288,7 @@ |= b=dill-belt-2 ^- dill-belt:dill ?. ?=(?(%ctl %met) -.b) b - [%key -.b p.b] + [%mod -.b p.b] :: ++ load-apps |= hood-version=@ud @@ -793,6 +793,7 @@ ?< ?=([?(%cru %hey %rez %yow) *] bet) :: target-specific =. blt [q.blt `bet] :: remember belt ?- bet + @ (ta-txt bet ~) [%aro *] (ta-aro p.bet) [%bac *] ta-bac [%del *] ta-del @@ -800,11 +801,8 @@ [%ret *] ta-ret [%txt *] (ta-txt p.bet) :: - [%key *] - ?+ mod.bet - ?^ key.bet $(bet key.bet) - (ta-txt key.bet ~) - :: + [%mod *] + ?+ mod.bet $(bet key.bet) %ctl (ta-ctl key.bet) %met (ta-met key.bet) == @@ -972,8 +970,8 @@ kil ?. ?& ?=(^ old.kil) ?=(^ p.blt) - ?| ?=([%key %ctl ?(%k %u %w)] u.p.blt) - ?=([%key %met ?(%d [%bac ~])] u.p.blt) + ?| ?=([%mod %ctl ?(%k %u %w)] u.p.blt) + ?=([%mod %met ?(%d [%bac ~])] u.p.blt) == == %= kil :: prepend num +(num.kil) @@ -1057,8 +1055,8 @@ :: %y ?. ?& ?=(^ old.kil) :: rotate & yank ?=(^ p.blt) - ?| ?=([%key %ctl %y] u.p.blt) - ?=([%key %met %y] u.p.blt) + ?| ?=([%mod %ctl %y] u.p.blt) + ?=([%mod %met %y] u.p.blt) == == ta-bel =+ las=(lent ta-yan) diff --git a/pkg/arvo/lib/ph/util.hoon b/pkg/arvo/lib/ph/util.hoon index 8a7103e8fc..bf290948de 100644 --- a/pkg/arvo/lib/ph/util.hoon +++ b/pkg/arvo/lib/ph/util.hoon @@ -28,8 +28,8 @@ %+ send-events-to who ^- (list unix-event) :~ - [//term/1 %belt %key %ctl `@c`%e] - [//term/1 %belt %key %ctl `@c`%u] + [//term/1 %belt %mod %ctl `@c`%e] + [//term/1 %belt %mod %ctl `@c`%u] [//term/1 %belt %txt ((list @c) what)] [//term/1 %belt %ret ~] == @@ -40,7 +40,7 @@ |= [who=ship what=term] ^- (list ph-event) %+ send-events-to who - :~ [//term/1 %belt %key %ctl (,@c what)] + :~ [//term/1 %belt %mod %ctl (,@c what)] == :: :: Inject a file into a ship diff --git a/pkg/arvo/mar/belt.hoon b/pkg/arvo/mar/belt.hoon index 3d417afb58..949f5aece7 100644 --- a/pkg/arvo/mar/belt.hoon +++ b/pkg/arvo/mar/belt.hoon @@ -8,10 +8,14 @@ |% ++ noun belt:dill ++ json - ^- $-(^json belt:dill) + |= jon=^json + ^- belt:dill + ?: ?=([%s *] jon) + (taft p.jon) =, dejs:format + %. jon %- of - |^ :* key+(ot 'mod'^mod 'key'^bot ~) + |^ :* mod+(ot 'mod'^mod 'key'^bot ~) txt+(ar (cu taft so)) bol == @@ -25,16 +29,16 @@ == :: ++ bot - |= jon=json - ?+ jon !! - [%s *] ((cu taft so) jon) - [%o *] ((of bol) jon) + |= j=json + ^- bolt:dill + ?+ j !! + [%s *] (taft p.j) + [%o *] ((of bol) j) == :: ++ mod - |= jon=json - ?~ jon ~ - ((su (perk %ctl %met %hyp ~)) jon) + |= j=json + ((su (perk %ctl %met %hyp ~)) j) -- -- :: +grow: convert to diff --git a/pkg/arvo/mar/dill/belt.hoon b/pkg/arvo/mar/dill/belt.hoon index 9c52902699..5d50dcd98d 100644 --- a/pkg/arvo/mar/dill/belt.hoon +++ b/pkg/arvo/mar/dill/belt.hoon @@ -45,8 +45,8 @@ =+ cha=(tuba (trip q.kev)) ?> ?=([@ ~] cha) :: of a single character ?+ mod !! :: modified by one buckykey - [%ctrl ~ ~] [%key %ctl i.cha] - [%alt ~ ~] [%key %met i.cha] + [%ctrl ~ ~] [%mod %ctl i.cha] + [%alt ~ ~] [%mod %met i.cha] == ?@ q.kev [%txt (tuba (trip q.kev))] diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index 64168b00f0..30e91ee0ae 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -1065,19 +1065,21 @@ :::: :: (1d2) :: +$ blew [p=@ud q=@ud] :: columns rows - +$ belt :: outside belt + +$ belt :: client input + $? bolt :: simple input + [%mod mod=?(%ctl %met %hyp) key=bolt] :: w/ modifier + [%txt p=(list @c)] :: utf32 text + ::TODO consider moving %hey, %rez, %yow here :: + == :: + +$ bolt :: simple input + $@ @c :: simple keystroke $% [%aro p=?(%d %l %r %u)] :: arrow key [%bac ~] :: true backspace [%del ~] :: true delete [%hit r=@ud c=@ud] :: mouse click - [%key mod=?(~ %ctl %met %hyp) key=bolt] :: input w/ modifier [%ret ~] :: return - [%txt p=(list @c)] :: utf32 text == :: - +$ bolt :: single input - $@ @cF :: simple - $<(?(%txt %key) belt) :: special - +$ blit :: outside blit + +$ blit :: client output $% [%bel ~] :: make a noise [%clr ~] :: clear the screen [%hop p=$@(@ud [r=@ud c=@ud])] :: set cursor col/pos @@ -1089,15 +1091,15 @@ [%url p=@t] :: activate url [%wyp ~] :: wipe cursor line == :: - +$ dill-belt :: inside belt - $% belt :: outside belt + +$ dill-belt :: arvo input + $% belt :: client input [%cru p=@tas q=(list tank)] :: echo error [%hey ~] :: refresh [%rez p=@ud q=@ud] :: resize, cols, rows [%yow p=gill:gall] :: connect to app == :: - +$ dill-blit :: inside blit - $% blit :: outside blit + +$ dill-blit :: arvo output + $% blit :: client output [%mor p=(list dill-blit)] :: multiple blits [%qit ~] :: close console == :: diff --git a/pkg/arvo/sys/vane/dill.hoon b/pkg/arvo/sys/vane/dill.hoon index 3b853f3fcc..9cdba94a3a 100644 --- a/pkg/arvo/sys/vane/dill.hoon +++ b/pkg/arvo/sys/vane/dill.hoon @@ -451,7 +451,7 @@ |= b=dill-belt-4 ^- dill-belt ?. ?=(?(%ctl %met) -.b) b - [%key -.b p.b] + [%mod -.b p.b] -- :: ++ scry diff --git a/pkg/interface/src/logic/api/term.ts b/pkg/interface/src/logic/api/term.ts index d380af0b69..7d86c4d415 100644 --- a/pkg/interface/src/logic/api/term.ts +++ b/pkg/interface/src/logic/api/term.ts @@ -1,20 +1,17 @@ import BaseApi from './base'; import { StoreState } from '../store/type'; -type Bork = +export type Bolt = + | string | { aro: 'd' | 'l' | 'r' | 'u' } | { bac: null } | { del: null } | { hit: { r: number, c: number } } | { ret: null } -export type Bolt = - | string - | Bork - export type Belt = - | Bork - | { key: { mod: null | 'ctl' | 'met' | 'hyp', key: Bolt } } + | Bolt + | { mod: { mod: 'ctl' | 'met' | 'hyp', key: Bolt } } | { txt: Array }; export default class TermApi extends BaseApi { diff --git a/pkg/interface/src/views/apps/term/app.tsx b/pkg/interface/src/views/apps/term/app.tsx index 090fb5dce6..6469b040d4 100644 --- a/pkg/interface/src/views/apps/term/app.tsx +++ b/pkg/interface/src/views/apps/term/app.tsx @@ -278,7 +278,7 @@ export default function TermApp(props: TermAppProps) { belts.push({ ret: null }); } else if (c <= 26) { - belts.push({ key: { mod: 'ctl', key: String.fromCharCode(96 + c) } }); + belts.push({ mod: { mod: 'ctl', key: String.fromCharCode(96 + c) } }); } // escape sequences @@ -309,13 +309,13 @@ export default function TermApp(props: TermAppProps) { } } else if (c >= 97 && c <= 122) { // a <= c <= z - belts.push({ key: { mod: 'met', key: e[0] } }); + belts.push({ mod: { mod: 'met', key: e[0] } }); } else if (c === 46) { // . - belts.push({ key: { mod: 'met', key: '.' } }); + belts.push({ mod: { mod: 'met', key: '.' } }); } else if (c === 8 || c === 127) { - belts.push({ key: { mod: 'met', key: { bac: null } } }); + belts.push({ mod: { mod: 'met', key: { bac: null } } }); } else { term.write('\x07'); break; // bel diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index e494d1b814..5c33a71a66 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -807,11 +807,11 @@ _term_io_suck_char(u3_utty* uty_u, c3_y cay_y) else { if ( (cay_y >= 'a') && (cay_y <= 'z') ) { tat_u->esc.ape = c3n; - _term_io_belt(uty_u, u3nt(c3__key, c3__met, cay_y)); + _term_io_belt(uty_u, u3nt(c3__mod, c3__met, cay_y)); } else if ( 8 == cay_y || 127 == cay_y ) { tat_u->esc.ape = c3n; - _term_io_belt(uty_u, u3nq(c3__key, c3__met, c3__bac, u3_nul)); + _term_io_belt(uty_u, u3nq(c3__mod, c3__met, c3__bac, u3_nul)); } else if ( ('[' == cay_y) || ('O' == cay_y) ) { tat_u->esc.bra = c3y; @@ -880,7 +880,7 @@ _term_io_suck_char(u3_utty* uty_u, c3_y cay_y) } #endif else if ( cay_y <= 26 ) { - _term_io_belt(uty_u, u3nt(c3__key, c3__ctl, ('a' + (cay_y - 1)))); + _term_io_belt(uty_u, u3nt(c3__mod, c3__ctl, ('a' + (cay_y - 1)))); } else if ( 27 == cay_y ) { tat_u->esc.ape = c3y; @@ -1214,7 +1214,7 @@ u3_term_ef_ctlc(void) { u3_noun wir = u3nt(c3__term, '1', u3_nul); - u3_noun cad = u3nq(c3__belt, c3__key, c3__ctl, 'c'); + u3_noun cad = u3nq(c3__belt, c3__mod, c3__ctl, 'c'); c3_assert( 1 == uty_u->tid_l ); c3_assert( uty_u->car_u ); From 7e2cc77ae063383595353f6921b13df9040764a6 Mon Sep 17 00:00:00 2001 From: fang Date: Wed, 31 Mar 2021 22:28:22 +0200 Subject: [PATCH 040/104] clay: explicitly ask dill to print changelist Instead of emitting a "debug message" gift and hoping dill picks it up for printing. --- pkg/arvo/sys/lull.hoon | 1 - pkg/arvo/sys/vane/clay.hoon | 10 ++++++---- pkg/arvo/sys/vane/dill.hoon | 4 ---- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index 30e91ee0ae..be41f20706 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -741,7 +741,6 @@ [%hill p=(list @tas)] :: mount points [%done error=(unit error:ames)] :: ames message (n)ack [%mere p=(each (set path) (pair term tang))] :: merge result - [%note p=@tD q=tank] :: debug message [%ogre p=@tas] :: delete mount point [%rule red=dict wit=dict] :: node r+w permissions [%writ p=riot] :: response diff --git a/pkg/arvo/sys/vane/clay.hoon b/pkg/arvo/sys/vane/clay.hoon index af2f653037..3f35fbf1bd 100644 --- a/pkg/arvo/sys/vane/clay.hoon +++ b/pkg/arvo/sys/vane/clay.hoon @@ -310,7 +310,10 @@ task :: == :: $: %d :: to %dill - $>(%flog task:dill) :: + $> $? %flog :: + %text :: + == :: + task:dill :: == :: $: %g :: to %gall $>(%deal task:gall) :: @@ -334,7 +337,6 @@ == == :: $: %clay :: $> $? %mere :: - %note :: %writ :: == :: gift :: @@ -1788,7 +1790,8 @@ |= [prefix=@tD paths=(set path)] %+ turn ~(tap in paths) |= =path - [u.hun %give %note prefix (path-to-tank path)] + ^- move + [u.hun %pass /note %d %text prefix ' ' ~(ram re (path-to-tank path))] :: ++ path-to-tank |= =path @@ -4458,7 +4461,6 @@ q.p.p.+.hin [~ ..^$] :: - %note [[hen %give +.hin]~ ..^$] %wake :: TODO: handle behn errors :: diff --git a/pkg/arvo/sys/vane/dill.hoon b/pkg/arvo/sys/vane/dill.hoon index 9cdba94a3a..a56df4f6e0 100644 --- a/pkg/arvo/sys/vane/dill.hoon +++ b/pkg/arvo/sys/vane/dill.hoon @@ -70,7 +70,6 @@ == == :: $: %clay :: $> $? %mere :: - %note :: %writ :: == :: gift:clay :: @@ -262,9 +261,6 @@ (dump:(crud %reap u.p.p.+>.sih) %logo ~) %fact (from ;;(dill-blit q:`vase`+>+>.sih)) == - :: - [%clay %note *] - (fore (tuba p.sih ' ' ~(ram re q.sih)) ~) :: [?(%behn %clay) %writ *] init From 1abbe168fe0eff56e69a603ac4e8f479f79690bb Mon Sep 17 00:00:00 2001 From: fang Date: Fri, 2 Apr 2021 13:21:20 +0200 Subject: [PATCH 041/104] kh: expose to/fromNoun template logic separately Separately from deriveNoun, which gives you an entire instance. Having access to these lets you call out to the auto-generated conversion logic when writing custom code for it. --- pkg/hs/urbit-noun-core/lib/Urbit/Noun/TH.hs | 36 +++++++++++++-------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/pkg/hs/urbit-noun-core/lib/Urbit/Noun/TH.hs b/pkg/hs/urbit-noun-core/lib/Urbit/Noun/TH.hs index 54ba660d5d..89dd760273 100644 --- a/pkg/hs/urbit-noun-core/lib/Urbit/Noun/TH.hs +++ b/pkg/hs/urbit-noun-core/lib/Urbit/Noun/TH.hs @@ -1,7 +1,7 @@ {-| Template Haskell Code to Generate FromNoun and ToNoun Instances -} -module Urbit.Noun.TH (deriveNoun, deriveToNoun, deriveFromNoun) where +module Urbit.Noun.TH (deriveNoun, deriveToNoun, deriveFromNoun, deriveToNounFunc, deriveFromNounFunc) where import ClassyPrelude hiding (fromList) import Control.Monad.Fail (fail) @@ -83,13 +83,9 @@ deriveNoun n = (<>) <$> deriveToNoun n <*> deriveFromNoun n deriveToNoun :: Name -> Q [Dec] deriveToNoun tyName = do - (params, shape) <- typeShape tyName - - let exp = case shape of Vod -> vodToNoun - Tup con -> tupToNoun con - -- Enu cons -> enumToAtom cons - Sum atoms cells -> sumToNoun atoms cells + (params, _) <- typeShape tyName + exp <- deriveToNounFunc tyName params <- pure $ zip ['a' ..] params <&> \(n,_) -> mkName (singleton n) let ty = foldl' (\acc v -> AppT acc (VarT v)) (ConT tyName) params @@ -101,6 +97,15 @@ deriveToNoun tyName = do pure [InstanceD overlap ctx inst [ValD (VarP 'toNoun) body []]] +deriveToNounFunc :: Name -> Q Exp +deriveToNounFunc tyName = do + (_, shape) <- typeShape tyName + pure case shape of + Vod -> vodToNoun + Tup con -> tupToNoun con + -- Enu cons -> enumToAtom cons + Sum atoms cells -> sumToNoun atoms cells + -------------------------------------------------------------------------------- addErrTag :: String -> Exp -> Exp @@ -111,13 +116,9 @@ addErrTag tag exp = deriveFromNoun :: Name -> Q [Dec] deriveFromNoun tyName = do - (params, shape) <- typeShape tyName - - let exp = case shape of Vod -> vodFromNoun - Tup con -> tupFromNoun con - -- Enu cons -> enumFromAtom cons - Sum atoms cells -> sumFromNoun atoms cells + (params, _) <- typeShape tyName + exp <- deriveFromNounFunc tyName params <- pure $ zip ['a' ..] params <&> \(n,_) -> mkName (singleton n) let ty = foldl' (\acc v -> AppT acc (VarT v)) (ConT tyName) params @@ -129,6 +130,15 @@ deriveFromNoun tyName = do pure [InstanceD overlap ctx inst [ValD (VarP 'parseNoun) body []]] +deriveFromNounFunc :: Name -> Q Exp +deriveFromNounFunc tyName = do + (_, shape) <- typeShape tyName + pure case shape of + Vod -> vodFromNoun + Tup con -> tupFromNoun con + -- Enu cons -> enumFromAtom cons + Sum atoms cells -> sumFromNoun atoms cells + sumFromNoun :: [(String, Name)] -> [(String, ConInfo)] -> Exp sumFromNoun [] cl = taggedFromNoun cl sumFromNoun at [] = enumFromAtom at From a90489830d8b22a45bc8d9c70194aadfc0150a65 Mon Sep 17 00:00:00 2001 From: fang Date: Fri, 2 Apr 2021 13:58:13 +0200 Subject: [PATCH 042/104] kh: update Term for new dill interface Support new Belts/Blits and updated semantics. --- pkg/hs/urbit-king/lib/Urbit/Arvo/Effect.hs | 31 ++++- pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs | 59 +++++++-- pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs | 116 ++++++++++-------- .../urbit-king/lib/Urbit/Vere/Term/Logic.hs | 59 ++++----- .../urbit-king/lib/Urbit/Vere/Term/Render.hs | 39 +++++- 5 files changed, 202 insertions(+), 102 deletions(-) diff --git a/pkg/hs/urbit-king/lib/Urbit/Arvo/Effect.hs b/pkg/hs/urbit-king/lib/Urbit/Arvo/Effect.hs index 5a57829124..2f9b3b7937 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Arvo/Effect.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Arvo/Effect.hs @@ -119,15 +119,22 @@ deriveNoun ''BehnEf data Blit = Bel () | Clr () - | Hop Word64 + | Hop HopTarget | Klr Stub - | Lin [Char] - | Mor () + | Put [Char] + | Nel () | Sag Path Noun | Sav Path Atom | Url Cord + | Wyp () deriving (Eq, Ord) +--NOTE bottom-left-0-based coordinates +data HopTarget + = Col Word64 + | Roc Word64 Word64 -- row, col + deriving (Eq, Ord, Show) + data Deco = DecoBl | DecoBr @@ -205,18 +212,30 @@ instance FromNoun Tint where "w" -> pure TintW t -> fail ("invalid: " <> unpack t) +instance FromNoun HopTarget where + parseNoun = \case + A c -> pure $ Col (fromIntegral c) + C (A r) (A c) -> pure $ Roc (fromIntegral r) (fromIntegral c) + n -> fail ("invalid hop target: " <> show n) + +instance ToNoun HopTarget where + toNoun = \case + Col c -> A (fromIntegral c) + Roc r c -> C (A (fromIntegral r)) (A (fromIntegral c)) + -- Manual instance to not save the noun/atom in Sag/Sav, because these can be -- megabytes and makes king hang. instance Show Blit where show (Bel ()) = "Bel ()" show (Clr ()) = "Clr ()" - show (Hop x) = "Hop " ++ (show x) + show (Hop t) = "Hop " ++ (show t) show (Klr s) = "Klr " ++ (show s) - show (Lin c) = "Lin " ++ (show c) - show (Mor ()) = "Mor ()" + show (Put c) = "Put " ++ (show c) + show (Nel ()) = "Nel ()" show (Sag path _) = "Sag " ++ (show path) show (Sav path _) = "Sav " ++ (show path) show (Url c) = "Url " ++ (show c) + show (Wyp ()) = "Wyp ()" {-| %blip -- TODO diff --git a/pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs b/pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs index 3b97d599b6..d28bda7cdd 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs @@ -20,6 +20,7 @@ import Urbit.Arvo.Common (ReOrg(..), reorgThroughNoun) import qualified Crypto.Sign.Ed25519 as Ed import qualified Data.ByteString as BS +import qualified Data.Char as C import qualified Data.ByteString.Char8 as C import qualified Network.HTTP.Types.Method as H @@ -277,19 +278,56 @@ data LegacyBootEvent | Dawn Dawn deriving (Eq, Show) -data ArrowKey = D | L | R | U +data Bolt + = Key Char + | Aro ArrowKey + | Bac () + | Del () + | Hit Word64 Word64 + | Ret () deriving (Eq, Ord, Show) data Belt - = Aro ArrowKey - | Bac () - | Ctl Cord - | Del () - | Met Cord - | Ret () + = Bol Bolt + | Mod Modifier Bolt | Txt Tour deriving (Eq, Ord, Show) +data ArrowKey = D | L | R | U + deriving (Eq, Ord, Show) + +data Modifier = Ctl | Met | Hyp + deriving (Eq, Ord, Show) + +--NOTE required to get the above declarations into reify's type environment +-- see also ghc/ghc#9813 +$(pure []) + +instance FromNoun Bolt where + parseNoun = \case + A c -> pure $ Key $ C.chr $ fromIntegral c + n -> $(deriveFromNounFunc ''Bolt) n + +instance FromNoun Belt where + parseNoun = \case + A c -> pure $ Bol $ Key $ C.chr $ fromIntegral c + n -> runParser ($(deriveFromNounFunc ''Bolt) n) [] belt bolt + where + belt p m = $(deriveFromNounFunc ''Belt) n + bolt !b = pure $ Bol b + +instance ToNoun Bolt where + toNoun = \case + Key c -> A $ fromIntegral $ C.ord c + n -> $(deriveToNounFunc ''Bolt) n + +instance ToNoun Belt where + toNoun = \case + Bol b -> case b of + Key c -> A $ fromIntegral $ C.ord c + b -> $(deriveToNounFunc ''Bolt) b + n -> $(deriveToNounFunc ''Belt) n + data TermEv = TermEvBelt (UD, ()) Belt | TermEvBlew (UD, ()) Word Word @@ -300,7 +338,7 @@ data TermEv deriveNoun ''LegacyBootEvent deriveNoun ''ArrowKey -deriveNoun ''Belt +deriveNoun ''Modifier deriveNoun ''TermEv @@ -353,6 +391,7 @@ instance FromNoun Ev where terminal event, but we don't display any name because the cause is really the user. -} +--REVIEW doesn't that hold for _any_ terminal event? getSpinnerNameForEvent :: Ev -> Maybe Text getSpinnerNameForEvent = \case EvBlip b -> case b of @@ -367,8 +406,8 @@ getSpinnerNameForEvent = \case BlipEvTerm t | isRet t -> Nothing BlipEvTerm t -> Just "term" where - isRet (TermEvBelt _ (Ret ())) = True - isRet _ = False + isRet (TermEvBelt _ (Bol (Ret ()))) = True + isRet _ = False summarizeEvent :: Ev -> Text summarizeEvent ev = diff --git a/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs b/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs index dc49043fe8..35e047e9f5 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs @@ -46,7 +46,7 @@ import qualified Urbit.Vere.Term.Render as T -- | All stateful data in the printing to stdOutput. data LineState = LineState { lsLine :: Text - , lsCurPos :: Int + , lsCurPos :: CurPos , lsSpinTimer :: Maybe (Async ()) , lsSpinCause :: Maybe Text , lsSpinFirstRender :: Bool @@ -54,6 +54,11 @@ data LineState = LineState , lsPrevEndTime :: Wen } +data CurPos = CurPos + { row :: Int + , col :: Int + } + -- | A record used in reading data from stdInput. data ReadData = ReadData { rdBuf :: Ptr Word8 @@ -269,7 +274,7 @@ localClient doneSignal = fst <$> mkRAcquire start stop writeTerminal :: TQueue [Term.Ev] -> TMVar () -> TVar TermSize -> RIO e () writeTerminal q spinner termSizeVar = do currentTime <- io $ now - loop (LineState "" 0 Nothing Nothing True 0 currentTime) + loop (LineState "" (CurPos 0 0) Nothing Nothing True 0 currentTime) where writeBlank :: LineState -> RIO e LineState writeBlank ls = putStr "\r\n" $> ls @@ -340,7 +345,7 @@ localClient doneSignal = fst <$> mkRAcquire start stop execEv :: LineState -> Term.Ev -> RIO e LineState execEv ls = \case - Term.Blits bs -> foldM writeBlit ls bs + Term.Blits bs -> foldM (writeBlit termSizeVar) ls bs Term.Trace p -> writeTrace ls (unCord p) Term.Slog s -> writeSlog ls s Term.Blank -> writeBlank ls @@ -370,20 +375,22 @@ localClient doneSignal = fst <$> mkRAcquire start stop ] -- Writes an individual blit to the screen - writeBlit :: LineState -> Blit -> RIO e LineState - writeBlit ls = \case + writeBlit :: TVar TermSize -> LineState -> Blit -> RIO e LineState + writeBlit ts ls = \case Bel () -> T.soundBell $> ls Clr () -> do T.clearScreen - termRefreshLine ls - Hop w -> termShowCursor ls (fromIntegral w) - Klr s -> do ls2 <- termShowClear ls - termShowStub ls2 s - Lin c -> do ls2 <- termShowClear ls - termShowLine ls2 (pack c) - Mor () -> termShowMore ls + T.cursorRestore + pure ls + Hop t -> case t of + Col c -> termShowCursor ls ts 0 (fromIntegral c) + Roc r c -> termShowCursor ls ts (fromIntegral r) (fromIntegral c) + Klr s -> termShowStub ls s + Put c -> termShowLine ls (pack c) + Nel () -> termShowNewline ls Sag path noun -> pure ls Sav path atom -> pure ls Url url -> pure ls + Wyp () -> termShowClear ls termRenderDeco :: Deco -> Char termRenderDeco = \case @@ -428,48 +435,56 @@ localClient doneSignal = fst <$> mkRAcquire start stop styled = mconcat [escape, styles, "m", tape, escape, "0m"] - -- Displays and sets styled text as the current line + -- Displays styled text at the cursor termShowStub :: LineState -> Stub -> RIO e LineState - termShowStub ls (Stub s) = do - let visualLength = sum $ fmap (length . snd) s + termShowStub ls@LineState{lsCurPos} (Stub s) = do let outText = pack $ mconcat $ fmap (uncurry termRenderStubSegment) s putStr outText - pure ls { lsLine = outText, lsCurPos = visualLength } + T.cursorRestore + case row lsCurPos of + 0 -> --TODO offset by col + pure ls { lsLine = outText } + _ -> pure ls -- Moves the cursor to the requested position - termShowCursor :: LineState -> Int -> RIO e LineState - termShowCursor ls@LineState{..} {-line pos)-} newPos = do - if newPos < lsCurPos then do - T.cursorLeft (lsCurPos - newPos) - pure ls { lsCurPos = newPos } - else if newPos > lsCurPos then do - T.cursorRight (newPos - lsCurPos) - pure ls { lsCurPos = newPos } - else - pure ls + termShowCursor :: LineState -> TVar TermSize -> Int -> Int -> RIO e LineState + termShowCursor ls ts row col = do + TermSize _ h <- readTVarIO ts + T.cursorMove (max 0 (fromIntegral h - row - 1)) col + T.cursorSave + pure ls { lsCurPos = CurPos row col } -- Moves the cursor left without any mutation of the LineState. Used only -- in cursor spinning. _termSpinnerMoveLeft :: Int -> RIO e () - _termSpinnerMoveLeft = T.cursorLeft + _termSpinnerMoveLeft = liftIO . ANSI.cursorBackward -- Displays and sets the current line termShowLine :: LineState -> Text -> RIO e LineState - termShowLine ls newStr = do + termShowLine ls@LineState{lsCurPos} newStr = do putStr newStr - pure ls { lsLine = newStr, lsCurPos = (length newStr) } + T.cursorRestore + case row lsCurPos of + 0 -> --TODO offset by col + pure ls { lsLine = newStr } + _ -> pure ls termShowClear :: LineState -> RIO e LineState - termShowClear ls = do + termShowClear ls@LineState{lsCurPos} = do putStr "\r" T.clearLine - pure ls { lsLine = "", lsCurPos = 0 } + T.cursorRestore + case row lsCurPos of + 0 -> pure ls { lsLine = "" } + _ -> pure ls -- New Current Line - termShowMore :: LineState -> RIO e LineState - termShowMore ls = do + termShowNewline :: LineState -> RIO e LineState + termShowNewline ls@LineState{lsCurPos} = do putStr "\r\n" - pure ls { lsLine = "", lsCurPos = 0 } + case row lsCurPos of + 0 -> pure ls { lsLine = "", lsCurPos = lsCurPos { col = 0 } } + r -> pure ls { lsCurPos = CurPos (r-1) 0 } -- Redraw the current LineState, maintaining the current curpos termRefreshLine :: LineState -> RIO e LineState @@ -513,20 +528,17 @@ localClient doneSignal = fst <$> mkRAcquire start stop if rdEscape then if rdBracket then do case c of - 'A' -> sendBelt $ Aro U - 'B' -> sendBelt $ Aro D - 'C' -> sendBelt $ Aro R - 'D' -> sendBelt $ Aro L + 'A' -> sendBelt $ Bol $ Aro U + 'B' -> sendBelt $ Bol $ Aro D + 'C' -> sendBelt $ Bol $ Aro R + 'D' -> sendBelt $ Bol $ Aro L _ -> bell loop rd { rdEscape = False, rdBracket = False} else if isAsciiLower c then do - sendBelt $ Met $ Cord $ pack [c] - loop rd { rdEscape = False } - else if c == '.' then do - sendBelt $ Met $ Cord "dot" + sendBelt $ Mod Met $ Key c loop rd { rdEscape = False } else if w == 8 || w == 127 then do - sendBelt $ Met $ Cord "bac" + sendBelt $ Mod Met $ Bac () loop rd { rdEscape = False } else if c == '[' || c == '0' then do loop rd { rdBracket = True } @@ -543,31 +555,31 @@ localClient doneSignal = fst <$> mkRAcquire start stop error "empty utf8 accumulation buffer" Just (c, bytes) | bytes /= rdUTF8width -> error "utf8 character size mismatch?!" - Just (c, bytes) -> sendBelt $ Txt $ Tour $ [c] + Just (c, bytes) -> sendBelt $ Bol $ Key c loop rd { rdUTF8 = mempty, rdUTF8width = 0 } else if w >= 32 && w < 127 then do - sendBelt $ Txt $ Tour $ [c] + sendBelt $ Bol $ Key c loop rd else if w == 0 then do bell loop rd else if w == 8 || w == 127 then do - sendBelt $ Bac () + sendBelt $ Bol $ Bac () loop rd else if w == 13 then do - sendBelt $ Ret () + sendBelt $ Bol $ Ret () loop rd else if w == 3 then do -- ETX (^C) logInfo $ "Ctrl-c interrupt" atomically $ do writeTQueue wq [Term.Trace "interrupt\r\n"] - writeTQueue rq $ Ctl $ Cord "c" + writeTQueue rq $ Mod Ctl $ Key 'c' loop rd else if w <= 26 then do - case pack [BS.w2c (w + 97 - 1)] of - "d" -> atomically doneSignal - c -> do sendBelt $ Ctl $ Cord c + case BS.w2c (w + 97 - 1) of + 'd' -> atomically doneSignal + c -> do sendBelt $ Mod Ctl $ Key c loop rd else if w == 27 then do loop rd { rdEscape = True } @@ -644,7 +656,7 @@ term env (tsize, Client{..}) plan stat serfSIGINT = runTerm atomically take >>= \case Nothing -> pure () Just (ClientTakeBelt b) -> do - when (b == Ctl (Cord "c")) $ do + when (b == Mod Ctl (Key 'c')) $ do io serfSIGINT let beltEv = EvBlip $ BlipEvTerm $ TermEvBelt (UD 1, ()) $ b let beltFailed _ = pure () diff --git a/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Logic.hs b/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Logic.hs index 770742a684..17a2f6c119 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Logic.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Logic.hs @@ -39,11 +39,11 @@ data Ev = EvLine Text | EvSlog (Atom, Tank) | EvSpin SpinnerState - | EvMove Word + | EvMove (Word, Word) | EvBell | EvDraw | EvEdit Text - | EvMore + | EvNewl deriving (Show) data Ef @@ -62,7 +62,7 @@ data History data St = St { sHistory :: !(Seq History) , sLine :: !Text - , sCurPos :: !Word + , sCurPos :: !(Word, Word) , sSpinner :: !SpinnerState } deriving (Show) @@ -70,10 +70,10 @@ data St = St -------------------------------------------------------------------------------- init :: St -init = St mempty "" 0 Nothing +init = St mempty "" (0, 0) Nothing {-| - When we process `EvMore`, we need to append a newline to the end of + When we process `EvNewl`, we need to append a newline to the end of the current line. During normal play, the ENTER key inserts the newline for us, so we need to recreate that newline when we rebuild the state for a new terminal connection. @@ -83,15 +83,17 @@ step st@St{..} = \case EvLine t -> st & recordText t EvSlog s -> st & recordSlog s EvSpin s -> st { sSpinner = s } - EvMove w -> st { sCurPos = min w (word $ length sLine) } - EvEdit t -> st { sLine = t, sCurPos = word (length t) } - EvMore -> st { sLine = "", sCurPos = 0 } & recordText (sLine <> "\n") + EvMove p -> st { sCurPos = p } + EvEdit t -> if fst sCurPos == 0 then st { sLine = t } + else st + EvNewl -> if fst sCurPos == 0 then + st { sLine = "", sCurPos = (0, 0) } + & recordText (sLine <> "\n") + else + st { sCurPos = (((fst sCurPos) - 1), 0) } EvBell -> st EvDraw -> st where - word :: Integral i => i -> Word - word = fromIntegral - recordText :: Text -> St -> St recordText !t st@St{..} = st { sHistory = trim (sHistory |> (HistoryText t)) @@ -111,8 +113,8 @@ drawState :: St -> [Ev] drawState St{..} = hist <> out <> cur <> spin where hist = drawHistory <$> toList sHistory - out = if null sLine then [] else [EvEdit sLine] - cur = if 0 == sCurPos then [] else [EvMove $ fromIntegral $ sCurPos] + out = if null sLine then [] else [EvEdit sLine] + cur = if 0 == fst sCurPos then [] else [EvMove sCurPos] spin = maybe [] (singleton . EvSpin . Just) sSpinner drawHistory (HistoryText t) = EvLine t @@ -123,12 +125,13 @@ drawState St{..} = hist <> out <> cur <> spin fromBlit :: Arvo.Blit -> Maybe Ev fromBlit = \case - Arvo.Hop w -> Just $ EvMove $ fromIntegral w - Arvo.Bel () -> Just EvBell - Arvo.Clr () -> Just EvDraw - Arvo.Lin s -> Just $ EvEdit (pack s) - Arvo.Mor () -> Just EvMore - _ -> Nothing + Arvo.Hop (Arvo.Col c) -> Just $ EvMove (0, fromIntegral c) + Arvo.Hop (Arvo.Roc r c) -> Just $ EvMove (fromIntegral r, fromIntegral c) + Arvo.Bel () -> Just EvBell + Arvo.Clr () -> Just EvDraw + Arvo.Put s -> Just $ EvEdit (pack s) + Arvo.Nel () -> Just EvNewl + _ -> Nothing toCause :: Maybe Cord -> SpinnerCause toCause Nothing = User @@ -148,12 +151,12 @@ fromTermEv = \case toTermEv :: Ev -> Term.Ev toTermEv = \case - EvLine "" -> Term.Blank - EvLine t -> Term.Trace (Cord t) - EvSlog s -> Term.Slog s - EvSpin s -> Term.Spinr (fromCause <$> s) - EvMove w -> Term.Blits [Arvo.Hop $ fromIntegral w] - EvBell -> Term.Blits [Arvo.Bel ()] - EvDraw -> Term.Blits [Arvo.Clr ()] - EvEdit t -> Term.Blits [Arvo.Lin $ unpack t] - EvMore -> Term.Blits [Arvo.Mor ()] + EvLine "" -> Term.Blank + EvLine t -> Term.Trace (Cord t) + EvSlog s -> Term.Slog s + EvSpin s -> Term.Spinr (fromCause <$> s) + EvMove (r, c) -> Term.Blits [Arvo.Hop $ Arvo.Roc (fromIntegral r) (fromIntegral c)] + EvBell -> Term.Blits [Arvo.Bel ()] + EvDraw -> Term.Blits [Arvo.Clr ()] + EvEdit t -> Term.Blits [Arvo.Put $ unpack t] + EvNewl -> Term.Blits [Arvo.Nel ()] diff --git a/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Render.hs b/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Render.hs index 3765f9cb25..9742a6b697 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Render.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Render.hs @@ -4,9 +4,13 @@ module Urbit.Vere.Term.Render ( clearScreen , clearLine - , cursorRight - , cursorLeft , soundBell + , cursorMove + , cursorSave + , cursorRestore + , putCSI + , hijack + , lojack ) where import ClassyPrelude @@ -25,8 +29,31 @@ clearLine = liftIO $ ANSI.clearLine soundBell :: MonadIO m => m () soundBell = liftIO $ putStr "\a" -cursorLeft :: MonadIO m => Int -> m () -cursorLeft = liftIO . ANSI.cursorBackward +--NOTE top-left-0-based coordinates +cursorMove :: MonadIO m => Int -> Int -> m () +cursorMove r c = liftIO $ ANSI.setCursorPosition r c -cursorRight :: MonadIO m => Int -> m () -cursorRight = liftIO . ANSI.cursorForward +cursorSave :: MonadIO m => m () +cursorSave = liftIO $ ANSI.saveCursor + +cursorRestore :: MonadIO m => m () +cursorRestore = liftIO $ ANSI.restoreCursor + +putCSI :: MonadIO m => Char -> [Int] -> m () +putCSI c a = liftIO do + putStr "\x1b[" + putStr $ pack $ mconcat $ intersperse ";" (fmap show a) + putStr $ pack [c] + +hijack :: MonadIO m => Int -> m () +hijack h = liftIO do + putCSI 'r' [1, h-1] -- set scroll region to exclude bottom line + putCSI 'S' [1] -- scroll up one line + cursorMove (h-2) 0 -- move cursor to empty space --TODO off-by-one? + +lojack :: MonadIO m => m () +lojack = liftIO do + putCSI 'r' [] -- reset scroll region + cursorRestore -- restory cursor position + +--TODO consider ANSI.setSGR From 01b8995e334c30ceef44278756fafae92b5840fb Mon Sep 17 00:00:00 2001 From: fang Date: Fri, 2 Apr 2021 14:21:22 +0200 Subject: [PATCH 043/104] kh: decouple trace & slog writing from drum prompt New blit logic already stopped assuming the bottom line based on %nel blits, instead looking at cursor position to determine if something was getting drawn to the bottom of the screen or not. Here, we stop overwriting the bottom line entirely (except for the spinner), instead inserting the trace/slog directly above the bottom line on-screen, without overwriting anything. Side-effect of this is that trailing newlines are always there, so we can stop including them explicitly. --- pkg/hs/urbit-king/lib/Urbit/Vere/Pier.hs | 2 +- pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs | 53 ++++++++++++-------- pkg/hs/urbit-king/lib/Urbit/Vere/Term/API.hs | 2 +- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/pkg/hs/urbit-king/lib/Urbit/Vere/Pier.hs b/pkg/hs/urbit-king/lib/Urbit/Vere/Pier.hs index 5600496792..b113a6459f 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Vere/Pier.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Vere/Pier.hs @@ -322,7 +322,7 @@ pier (serf, log) vSlog startedSig injected = do io $ readTVarIO siteSlog >>= ($ s) logOther "serf" (display $ T.strip $ tankToText tank) - let err = atomically . Term.trace muxed . (<> "\r\n") + let err = atomically . Term.trace muxed (bootEvents, startDrivers) <- do env <- ask siz <- atomically $ Term.curDemuxSize demux diff --git a/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs b/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs index 35e047e9f5..45a82bb85c 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs @@ -271,31 +271,41 @@ localClient doneSignal = fst <$> mkRAcquire start stop -- Writes data to the terminal. Both the terminal reading, normal logging, -- and effect handling can all emit bytes which go to the terminal. + --TODO blanks, traces and slogs should only be written into the default + -- terminal session. writeTerminal :: TQueue [Term.Ev] -> TMVar () -> TVar TermSize -> RIO e () writeTerminal q spinner termSizeVar = do currentTime <- io $ now loop (LineState "" (CurPos 0 0) Nothing Nothing True 0 currentTime) where writeBlank :: LineState -> RIO e LineState - writeBlank ls = putStr "\r\n" $> ls + writeBlank ls = do + TermSize _ height <- readTVarIO termSizeVar + --NOTE hijack creates a blank line + T.hijack $ fromIntegral height + T.lojack + pure ls writeTrace :: LineState -> Text -> RIO e LineState writeTrace ls p = do - putStr "\r" - T.clearLine + TermSize _ height <- readTVarIO termSizeVar + T.hijack $ fromIntegral height putStr p - termRefreshLine ls + T.lojack + pure ls writeSlog :: LineState -> (Atom, Tank) -> RIO e LineState writeSlog ls slog = do - putStr "\r" - T.clearLine - TermSize width _ <- atomically $ readTVar termSizeVar + TermSize width height <- readTVarIO termSizeVar + T.hijack $ fromIntegral height -- TODO: Ignoring priority for now. Priority changes the color of, -- and adds a prefix of '>' to, the output. let lines = fmap unTape $ wash (WashCfg 0 width) $ tankTree $ snd slog - forM lines $ \line -> putStr (line <> "\r\n") - termRefreshLine ls + T.putCSI 'm' [90] --NOTE print slogs in grey + forM (intersperse "\n" lines) $ \line -> putStr line + T.putCSI 'm' [0] + T.lojack + pure ls {- Figure out how long to wait to show the spinner. When we @@ -304,6 +314,7 @@ localClient doneSignal = fst <$> mkRAcquire start stop event shortly after a previous spin, use a shorter delay to avoid giving the impression of a half-idle system. -} + --TODO this is too eager and does termRestoreLine on every keypress! doSpin :: LineState -> Maybe Text -> RIO e LineState doSpin ls@LineState{..} mTxt = do maybe (pure ()) cancel lsSpinTimer @@ -331,14 +342,14 @@ localClient doneSignal = fst <$> mkRAcquire start stop maybe (pure ()) cancel lsSpinTimer -- We do a final flush of the spinner mvar to ensure we don't -- have a lingering signal which will redisplay the spinner after - -- we call termRefreshLine below. + -- we call termRestoreLine below. atomically $ tryTakeTMVar spinner -- If we ever actually ran the spinner display callback, we need -- to force a redisplay of the command prompt. - ls <- if not lsSpinFirstRender || True - then termRefreshLine ls - else pure ls + if not lsSpinFirstRender || True + then termRestoreLine ls termSizeVar + else pure () endTime <- io $ now pure $ ls { lsSpinTimer = Nothing, lsPrevEndTime = endTime } @@ -486,12 +497,14 @@ localClient doneSignal = fst <$> mkRAcquire start stop 0 -> pure ls { lsLine = "", lsCurPos = lsCurPos { col = 0 } } r -> pure ls { lsCurPos = CurPos (r-1) 0 } - -- Redraw the current LineState, maintaining the current curpos - termRefreshLine :: LineState -> RIO e LineState - termRefreshLine ls@LineState{lsCurPos,lsLine} = do - ls <- termShowClear ls - ls <- termShowLine ls lsLine - termShowCursor ls lsCurPos + -- Redraw the bottom LineState, maintaining the current curpos + termRestoreLine :: LineState -> TVar TermSize -> RIO e () + termRestoreLine ls@LineState{lsLine} ts = do + TermSize _ h <- readTVarIO ts + T.cursorMove (fromIntegral h - 1) 0 + T.clearLine + putStr lsLine + T.cursorRestore -- ring my bell bell :: TQueue [Term.Ev] -> RIO e () @@ -573,7 +586,7 @@ localClient doneSignal = fst <$> mkRAcquire start stop -- ETX (^C) logInfo $ "Ctrl-c interrupt" atomically $ do - writeTQueue wq [Term.Trace "interrupt\r\n"] + writeTQueue wq [Term.Trace "interrupt"] writeTQueue rq $ Mod Ctl $ Key 'c' loop rd else if w <= 26 then do diff --git a/pkg/hs/urbit-king/lib/Urbit/Vere/Term/API.hs b/pkg/hs/urbit-king/lib/Urbit/Vere/Term/API.hs index 7e65d49e5e..d6b6fde609 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Vere/Term/API.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Vere/Term/API.hs @@ -22,7 +22,7 @@ import Urbit.TermSize Input Event for terminal driver: %blits -- list of blits from arvo. - %trace -- stderr line from runtime. + %trace -- stderr line from runtime (without trailing newline). %slog -- nock worker logging with priority %blank -- print a blank line %spinr -- Start or stop the spinner From 0a75ca19f31704f0a3a054af4e3647ae5a8c67b6 Mon Sep 17 00:00:00 2001 From: fang Date: Fri, 2 Apr 2021 14:25:29 +0200 Subject: [PATCH 044/104] kh: support mouse reporting for %hit belts This comes with the caveat that this specific mouse reporting mode (which should only report clicks of the primary button) doesn't actually seem to be supported by most terminal emulators, even though it precedes the more complex reporting modes. (Enabling a more complex reporting mode instead would also capture scroll events, which interferes with expected behavior while in tmux.) --- pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs | 42 +++++++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs b/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs index 45a82bb85c..8f3a80ebbc 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs @@ -64,6 +64,9 @@ data ReadData = ReadData { rdBuf :: Ptr Word8 , rdEscape :: Bool , rdBracket :: Bool + , rdMouse :: Bool + , rdMouseBut :: Word8 + , rdMouseCol :: Word8 , rdUTF8 :: ByteString , rdUTF8width :: Int } @@ -206,6 +209,9 @@ localClient doneSignal = fst <$> mkRAcquire start stop -- to the muxing client. putTMVar tsSizeChange ts) + -- start mouse reporting + putStr "\x1b[?9h" + pWriterThread <- asyncBound (writeTerminal tsWriteQueue spinnerMVar tsizeTVar) @@ -222,7 +228,7 @@ localClient doneSignal = fst <$> mkRAcquire start stop tsReadQueue <- newTQueueIO pReaderThread <- asyncBound - (readTerminal tsReadQueue tsWriteQueue (bell tsWriteQueue)) + (readTerminal tsReadQueue tsWriteQueue tsizeTVar (bell tsWriteQueue)) let client = Client { take = Just <$> asum [ readTQueue tsReadQueue <&> ClientTakeBelt, @@ -243,6 +249,9 @@ localClient doneSignal = fst <$> mkRAcquire start stop -- at shutdown, just leak the file descriptor. cancel pWriterThread + -- stop mouse reporting + putStr "\x1b[?9l" + -- inject one final newline, as we're usually on the prompt. putStr "\r\n" @@ -519,9 +528,14 @@ localClient doneSignal = fst <$> mkRAcquire start stop -- A better way to do this would be to get some sort of epoll on stdInput, -- since that's kinda closer to what libuv does? readTerminal :: forall e. HasLogFunc e - => TQueue Belt -> TQueue [Term.Ev] -> (RIO e ()) -> RIO e () - readTerminal rq wq bell = - rioAllocaBytes 1 $ \ buf -> loop (ReadData buf False False mempty 0) + => TQueue Belt + -> TQueue [Term.Ev] + -> TVar TermSize + -> RIO e () + -> RIO e () + readTerminal rq wq ts bell = + rioAllocaBytes 1 $ \ buf + -> loop (ReadData buf False False False 0 0 mempty 0) where loop :: ReadData -> RIO e () loop rd@ReadData{..} = do @@ -545,8 +559,12 @@ localClient doneSignal = fst <$> mkRAcquire start stop 'B' -> sendBelt $ Bol $ Aro D 'C' -> sendBelt $ Bol $ Aro R 'D' -> sendBelt $ Bol $ Aro L + 'M' -> pure () _ -> bell - loop rd { rdEscape = False, rdBracket = False} + rd <- case c of + 'M' -> pure rd { rdMouse = True } + _ -> pure rd + loop rd { rdEscape = False, rdBracket = False } else if isAsciiLower c then do sendBelt $ Mod Met $ Key c loop rd { rdEscape = False } @@ -558,6 +576,20 @@ localClient doneSignal = fst <$> mkRAcquire start stop else do bell loop rd { rdEscape = False } + else if rdMouse then + if rdMouseBut == 0 then do + loop rd { rdMouseBut = w - 31 } + else if rdMouseCol == 0 then do + loop rd { rdMouseCol = w - 32 } + else do + if rdMouseBut == 1 then do + let rdMouseRow = w - 32 + TermSize _ h <- readTVarIO ts + sendBelt $ Bol $ Hit + (fromIntegral h - fromIntegral rdMouseRow) + (fromIntegral rdMouseCol - 1) + else do pure () + loop rd { rdMouse = False, rdMouseBut = 0, rdMouseCol = 0 } else if rdUTF8width /= 0 then do -- continue reading into the utf8 accumulation buffer rd@ReadData{..} <- pure rd { rdUTF8 = snoc rdUTF8 w } From c4f470ec15ef150967292b858cdd0027cd95a4e0 Mon Sep 17 00:00:00 2001 From: fang Date: Sun, 4 Apr 2021 17:15:36 +0200 Subject: [PATCH 045/104] dill: properly support %talk, tanks printing Also allowing for sequences of tanks. (Not to be confused with +tang, which has stack trace/reverse-order semantics.) --- pkg/arvo/sys/lull.hoon | 4 ++-- pkg/arvo/sys/vane/dill.hoon | 25 ++++++++++++++----------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index be41f20706..ff8f8639fc 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -1042,8 +1042,8 @@ [%meld ~] :: unify memory [%pack ~] :: compact memory [%shot ses=@tas task=session-task] :: task for session - [%talk p=tank] :: - [%text p=tape] :: + [%talk p=(list tank)] :: print tanks + [%text p=tape] :: print tape $>(%trim vane-task) :: trim state $>(%vega vane-task) :: report upgrade [%verb ~] :: verbose mode diff --git a/pkg/arvo/sys/vane/dill.hoon b/pkg/arvo/sys/vane/dill.hoon index a56df4f6e0..e20f618e9f 100644 --- a/pkg/arvo/sys/vane/dill.hoon +++ b/pkg/arvo/sys/vane/dill.hoon @@ -103,6 +103,7 @@ %flow +> %hail (send %hey ~) %belt (send `dill-belt`p.kyz) + %talk (talk p.kyz) %text (fore (tuba p.kyz) ~) %crud :: (send `dill-belt`[%cru p.kyz q.kyz]) (crud p.kyz q.kyz) @@ -121,17 +122,19 @@ =/ lev=log-level (~(gut by veb.all) err %loud) :: apply log level for this error tag :: - =/ =wall - ?- lev - %hush ~ - %soft ~["crud: %{(trip err)} event failed"] - %loud :- "crud: %{(trip err)} event failed" - %- zing - %+ turn (flop tac) - |=(a=tank (~(win re a) [0 wid])) - == - ?: =(~ wall) +>.$ - (fore (turn wall tuba)) + ?- lev + %hush +>.$ + %soft (fore (tuba "crud: %{(trip err)} event failed") ~) + %loud (talk leaf+"crud: %{(trip err)} event failed" (flop tac)) + == + :: + ++ talk + |= tac=(list tank) + %- fore + %- zing + %+ turn tac + |= a=tank + (turn (~(win re a) [0 wid]) tuba) :: ++ dump :: pass down to hey |= git=gift From 5ef68d38c7a5be3a706f6ce7b21fc00ff4d9fae0 Mon Sep 17 00:00:00 2001 From: fang Date: Sun, 4 Apr 2021 17:22:41 +0200 Subject: [PATCH 046/104] gall: stop sending %onto Gall would send %onto gifts to notify about app updates and update failures. This would end up in dill, which printed some appropriate text. Here, we make gall responsible for doing this printing itself (by having it explicitly ask dill to print some tape/tank), instead of relying on the receiving end of some bespoke notification protocol. --- pkg/arvo/app/hood.hoon | 1 - pkg/arvo/lib/hood/drum.hoon | 19 ------------------- pkg/arvo/sys/lull.hoon | 1 - pkg/arvo/sys/vane/dill.hoon | 11 +---------- pkg/arvo/sys/vane/gall.hoon | 22 ++++++++++++++++------ pkg/arvo/sys/vane/jael.hoon | 11 ++--------- 6 files changed, 19 insertions(+), 46 deletions(-) diff --git a/pkg/arvo/app/hood.hoon b/pkg/arvo/app/hood.hoon index 27ef5005ca..31f881e070 100644 --- a/pkg/arvo/app/hood.hoon +++ b/pkg/arvo/app/hood.hoon @@ -112,7 +112,6 @@ |= [=wire syn=sign-arvo] ^- step:agent:gall ?+ wire ~|([%hood-bad-wire wire] !!) - [%drum *] =^(c drum.state (take-arvo:drum-core t.wire syn) [c this]) [%helm *] =^(c helm.state (take-arvo:helm-core t.wire syn) [c this]) [%kiln *] =^(c kiln.state (take-arvo:kiln-core t.wire syn) [c this]) == diff --git a/pkg/arvo/lib/hood/drum.hoon b/pkg/arvo/lib/hood/drum.hoon index 4b83c1d4bf..9b8aa85308 100644 --- a/pkg/arvo/lib/hood/drum.hoon +++ b/pkg/arvo/lib/hood/drum.hoon @@ -344,12 +344,6 @@ :: (se-drop & gyl) :: -++ take-arvo - |= [=wire =sign-arvo] - %+ take-onto wire - ?> ?=(%onto +<.sign-arvo) - +>.sign-arvo -:: ++ take-coup-phat :: ack poke |= [way=wire saw=(unit tang)] =< se-abet =< se-view @@ -360,19 +354,6 @@ :_ u.saw >[%drum-coup-fail src.hid gyl]< :: -++ take-onto :: ack start - |= [way=wire saw=(each suss:gall tang)] - =< se-abet =< se-view - ?> ?=([@ @ ~] way) - ?> (~(has by fur) i.t.way) - =/ wel=well:gall [i.way i.t.way] - ?- saw - [%| *] (se-dump p.saw) - [%& *] ?> =(q.wel p.p.saw) - :: =. +>.$ (se-text "live {}") - +>.$(fur (~(put by fur) q.wel `[p.wel %da r.p.saw])) - == -:: ++ take-agent |= [=wire =sign:agent:gall] ?+ wire ~|([%drum-bad-take-agent wire -.sign] !!) diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index ff8f8639fc..c622d5aff7 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -1611,7 +1611,6 @@ +$ gift :: outgoing result $% [%boon payload=*] :: ames response [%done error=(unit error:ames)] :: ames message (n)ack - [%onto p=(each suss tang)] :: about agent [%unto p=sign:agent] :: == :: +$ task :: incoming request diff --git a/pkg/arvo/sys/vane/dill.hoon b/pkg/arvo/sys/vane/dill.hoon index e20f618e9f..952bfda934 100644 --- a/pkg/arvo/sys/vane/dill.hoon +++ b/pkg/arvo/sys/vane/dill.hoon @@ -78,10 +78,7 @@ $>(%blit gift:dill) :: == :: $: %gall :: - $> $? %onto :: - %unto :: - == :: - gift:gall :: + $>(%unto gift:gall) :: == == :: :::::::: :: dill tiles -- @@ -248,12 +245,6 @@ |= [tea=wire sih=sign] ^+ +> ?- sih - [%gall %onto *] - ?- -.+>.sih - %| (crud %onto p.p.+>.sih) - %& (fore (tuba "{(t q)}ed %{(t p)}":[t=trip p.p.sih]) ~) - == - :: [%gall %unto *] :: ~& [%take-gall-unto +>.sih] ?- -.+>.sih diff --git a/pkg/arvo/sys/vane/gall.hoon b/pkg/arvo/sys/vane/gall.hoon index a481307874..c27e57fcce 100644 --- a/pkg/arvo/sys/vane/gall.hoon +++ b/pkg/arvo/sys/vane/gall.hoon @@ -159,7 +159,7 @@ ~< %slog.[0 leaf+"gall: molted"] :: +molt should never notify its client about agent changes :: - =- [(skip -< |=(move ?=([* %give %onto *] +<))) ->] + =- [(skip -< |=(move ?=([* %pass [%sys %say ~] *] +<))) ->] =/ adult adult-core =. state.adult [%7 system-duct outstanding contacts yokes=~ blocked]:spore @@ -263,12 +263,22 @@ :: +mo-abet: finalize, reversing moves :: +mo-pass: prepend a standard %pass to the current list of moves :: +mo-give: prepend a standard %give to the current list of moves + :: +mo-talk: build task to print config report or failure trace :: ++ mo-core . ++ mo-abed |=(hun=duct mo-core(hen hun)) ++ mo-abet [(flop moves) gall-payload] ++ mo-pass |=(p=[wire note-arvo] mo-core(moves [[hen pass+p] moves])) ++ mo-give |=(g=gift mo-core(moves [[hen give+g] moves])) + ++ mo-talk + |= rup=(each suss tang) + ^- [wire note-arvo] + :+ /sys/say %d + ^- task:dill + ?- -.rup + %& [%text "gall: {(t q)}ed %{(t p)}":[t=trip p.rup]] + %| [%talk leaf+"gall: failed" (flop p.rup)] + == :: +mo-boot: ask %ford to build us a core for the specified agent. :: ++ mo-boot @@ -346,12 +356,12 @@ =/ ap-core +.wag ?^ maybe-tang =. mo-core old - (mo-give %onto %.n u.maybe-tang) + (mo-pass (mo-talk %.n u.maybe-tang)) :: =. mo-core ap-abet:ap-core =. mo-core (mo-clear-queue dap) =/ =suss [dap %boot now] - (mo-give %onto [%.y suss]) + (mo-pass (mo-talk %.y suss)) :: +mo-subscribe-to-agent-builds: request agent update notices :: :: Also subscribe to our own source path, in case we get reloaded @@ -541,7 +551,7 @@ ++ fail |= =tang ^+ mo-core - =. mo-core (mo-give %onto |+tang) + =. mo-core (mo-pass (mo-talk |+tang)) =/ =case [%da tim] =/ =wire /sys/cor/[dap]/[her]/[desk]/(scot case) (mo-pass wire %c %warp p.beak desk ~ %next %a case /app/[dap]/hoon) @@ -1017,8 +1027,8 @@ :: =/ running (~(put by yokes.state) agent-name current-agent) =/ moves - =/ giver |=(report=(each suss tang) [hen %give %onto report]) - =/ from-suss (turn agent-config giver) + =/ talker |=(report=(each suss tang) [hen %pass (mo-talk report)]) + =/ from-suss (turn agent-config talker) :(weld agent-moves from-suss moves) :: %_ mo-core diff --git a/pkg/arvo/sys/vane/jael.hoon b/pkg/arvo/sys/vane/jael.hoon index 3bda44586f..e4948fdfd7 100644 --- a/pkg/arvo/sys/vane/jael.hoon +++ b/pkg/arvo/sys/vane/jael.hoon @@ -107,11 +107,8 @@ $>(%wake gift:behn) :: == :: $: %gall :: - $> $? %onto :: - %unto :: - == :: - gift:gall :: - == + $>(%unto gift:gall) :: + == :: == :: -- :: :: :::: @@ -557,10 +554,6 @@ =/ ships (~(get ju ship-sources-reverse.etn) source-id) %- curd =< abet (sources:~(feel su hen now pki etn) ships source) - :: - [%gall %onto *] - ~& [%jael-onto tea hin] - +>.$ :: [%gall %unto *] ?- +>-.hin From 91f32ee098ae87e000dc4d0c03564b15ed208ab9 Mon Sep 17 00:00:00 2001 From: fang Date: Mon, 5 Apr 2021 22:37:38 +0200 Subject: [PATCH 047/104] dill: reify sessions interface Implements tasks for creating and deleting new sessions, and allows terminal handler agents to distinguish between sessions. Includes bits of preparation in drum to more fully support multiple distinct sessions, but doesn't get it all the way there just yet. --- pkg/arvo/app/hood.hoon | 5 ++-- pkg/arvo/lib/hood/drum.hoon | 51 ++++++++++++++++++++++--------------- pkg/arvo/sys/lull.hoon | 15 +++++++---- pkg/arvo/sys/vane/dill.hoon | 46 ++++++++++++++++++++++++++++++--- 4 files changed, 85 insertions(+), 32 deletions(-) diff --git a/pkg/arvo/app/hood.hoon b/pkg/arvo/app/hood.hoon index 31f881e070..cd7e52abb5 100644 --- a/pkg/arvo/app/hood.hoon +++ b/pkg/arvo/app/hood.hoon @@ -81,8 +81,7 @@ :: ?+ mark (on-poke:def mark vase) %atom poke-helm(mark %helm-atom) - %dill-belt poke-drum(mark %drum-dill-belt) - %dill-blit poke-drum(mark %drum-dill-blit) + %dill-poke poke-drum %hood-sync poke-kiln(mark %kiln-sync) %write-sec-atom poke-helm(mark %helm-write-sec-atom) == @@ -95,7 +94,7 @@ |= =path ^- step:agent:gall ?+ path (on-watch:def +<) - [%drum *] =^(c drum.state (peer:drum-core +<) [c this]) + [%dill *] =^(c drum.state (peer:drum-core +<) [c this]) == :: ++ on-agent diff --git a/pkg/arvo/lib/hood/drum.hoon b/pkg/arvo/lib/hood/drum.hoon index 9b8aa85308..50d4f7131a 100644 --- a/pkg/arvo/lib/hood/drum.hoon +++ b/pkg/arvo/lib/hood/drum.hoon @@ -8,7 +8,7 @@ $: eel=(set gill:gall) :: connect to ray=(set well:gall) :: fur=(map dude:gall (unit server)) :: servers - bin=(map bone source) :: terminals + bin=(map @ source) :: terminals == :: :: :: ++ server :: running server @@ -155,18 +155,18 @@ ++ en-gill :: gill to wire |= gyl=gill:gall ^- wire + ::TODO include session? [%drum %phat (scot %p p.gyl) q.gyl ~] :: ++ de-gill :: gill from wire |= way=wire ^- gill:gall ?>(?=([@ @ ~] way) [(slav %p i.way) i.t.way]) -- -:: TODO: remove .ost :: |= [hid=bowl:gall state] =* sat +<+ -=/ ost 0 -=+ (~(gut by bin) ost *source) +=/ ses=@tas %$ +=+ (~(gut by bin) ses *source) =* dev - =| moz=(list card:agent:gall) =| biz=(list dill-blit:dill) @@ -176,6 +176,13 @@ +$ state ^state :: proxy +$ any-state ^any-state :: proxy ++ on-init se-abet:this(eel (deft-fish our.hid)) +:: +++ prep + |= s=@tas + =. ses ses + =. dev (~(gut by bin) ses *source) + this +:: ++ diff-sole-effect-phat :: app event |= [way=wire fec=sole-effect] =< se-abet =< se-view @@ -185,6 +192,8 @@ :: ++ peer :: |= pax=path + =? this ?=([%dill @ ~] pax) + (prep i.t.pax) ~| [%drum-unauthorized our+our.hid src+src.hid] :: ourself ?> (team:title our.hid src.hid) :: or our own moon =< se-abet =< se-view @@ -201,15 +210,15 @@ =. ray (deft-apes our.hid lit) [~ sat] :: +++ poke-dill + |= [ses=@tas bet=dill-belt:dill] + (poke-dill-belt:(prep ses) bet) +:: ++ poke-dill-belt :: terminal event |= bet=dill-belt:dill =< se-abet =< se-view (se-belt bet) :: -++ poke-dill-blit :: terminal output - |= bit=dill-blit:dill - se-abet:(se-blit-sys bit) -:: ++ poke-start :: start app |= wel=well:gall =< se-abet =< se-view @@ -241,8 +250,7 @@ ++ poke |= [=mark =vase] ?+ mark ~|([%poke-drum-bad-mark mark] !!) - %drum-dill-belt =;(f (f !<(_+<.f vase)) poke-dill-belt) - %drum-dill-blit =;(f (f !<(_+<.f vase)) poke-dill-blit) + %dill-poke =;(f (f !<(_+<.f vase)) poke-dill) %drum-exit =;(f (f !<(_+<.f vase)) poke-exit) %drum-link =;(f (f !<(_+<.f vase)) poke-link) %drum-put =;(f (f !<(_+<.f vase)) poke-put) @@ -256,7 +264,7 @@ |^ |= [hood-version=@ud old=any-state] =< se-abet =< se-view =. sat (load-state old) - =. dev (~(gut by bin) ost *source) + =. dev (~(gut by bin) ses *source) (load-apps hood-version) :: ++ load-state @@ -381,12 +389,13 @@ ++ se-abet :: resolve ^- (quip card:agent:gall state) =. . se-subze:se-adze:se-subit:se-adit - :_ sat(bin (~(put by bin) ost dev)) + :_ sat(bin (~(put by bin) ses dev)) ^- (list card:agent:gall) ?~ biz (flop moz) :_ (flop moz) =/ =dill-blit:dill ?~(t.biz i.biz [%mor (flop biz)]) - [%give %fact ~[/drum] %dill-blit !>(dill-blit)] + ::TODO remove /drum after dill cleans up + [%give %fact ~[/drum /dill/[ses]] %dill-blit !>(dill-blit)] :: ++ se-adit :: update servers ^+ this @@ -471,14 +480,14 @@ (se-peer gil) :: ++ se-subze :: downdate connections - =< .(dev (~(got by bin) ost)) - =. bin (~(put by bin) ost dev) + =< .(dev (~(got by bin) ses)) + =. bin (~(put by bin) ses dev) ^+ . %- ~(rep by bin) =< .(con +>) - |: $:,[[ost=bone dev=source] con=_.] ^+ con - =+ xeno=se-subze-local:%_(con ost ost, dev dev) - xeno(ost ost.con, dev dev.con, bin (~(put by bin) ost dev.xeno)) + |: $:,[[ses=@tas dev=source] con=_.] ^+ con + =+ xeno=se-subze-local:%_(con ses ses, dev dev) + xeno(ses ses.con, dev dev.con, bin (~(put by bin) ses dev.xeno)) :: ++ se-subze-local ^+ . @@ -493,7 +502,7 @@ ++ se-aint :: ignore result |= gyl=gill:gall ^- ? - ?. (~(has by bin) ost) & + ?. (~(has by bin) ses) & =+ gyr=(~(get by fug) gyl) |(?=(~ gyr) ?=(~ u.gyr)) :: @@ -660,7 +669,8 @@ :: ++ se-blit-sys :: output to system |= bil=dill-blit:dill ^+ +> - (se-emit %give %fact ~[/drum] %dill-blit !>(bil)) + ::TODO remove /drum after dill cleans up + (se-emit %give %fact ~[/drum /dill/[ses]] %dill-blit !>(bil)) :: ++ se-show :: show buffer, raw |= lin=(pair @ud stub) @@ -714,6 +724,7 @@ :: ++ se-peer :: send a peer |= gyl=gill:gall + ::TODO include session =/ =path /sole/(cat 3 'drum_' (scot %p our.hid)) %- se-emit(fug (~(put by fug) gyl ~)) [%pass (en-gill gyl) %agent gyl %watch path] diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index c622d5aff7..fce261bb4a 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -1055,9 +1055,9 @@ $% [%belt p=belt] :: terminal input [%blew p=blew] :: terminal config [%flee ~] :: unwatch session - [%flow p=@tas q=(list gill:gall)] :: terminal config [%hail ~] :: terminal refresh - [%hook ~] :: this term hung up + [%open p=dude:gall q=(list gill:gall)] :: setup session + [%shut ~] :: close session [%view ~] :: watch session blits == :: :: @@ -1111,6 +1111,11 @@ [%text p=tape] :: [%verb ~] :: verbose mode == :: + :: :: + +$ poke :: dill to userspace + $: ses=@tas :: target session + dill-belt :: input + == :: -- ::dill :: :::: :::: ++eyre :: (1e) http-server @@ -2133,9 +2138,6 @@ :: %ames: hear packet :: $>(%hear task:ames) - :: %dill: hangup - :: - $>(%hook task:dill) :: %clay: external edit :: $>(%into task:clay) @@ -2151,6 +2153,9 @@ :: %eyre: starts handling an backdoor http request :: $>(%request-local task:eyre) + :: %dill: close session + :: + $>(%shut task:dill) :: %behn: wakeup :: $>(%wake task:behn) diff --git a/pkg/arvo/sys/vane/dill.hoon b/pkg/arvo/sys/vane/dill.hoon index 952bfda934..5d54eb6af5 100644 --- a/pkg/arvo/sys/vane/dill.hoon +++ b/pkg/arvo/sys/vane/dill.hoon @@ -26,7 +26,7 @@ -- => :: |% :: protocol outward +$ mess :: - $% [%dill-belt p=(hypo dill-belt)] :: + $% [%dill-poke p=(hypo poke)] :: == :: +$ move [p=duct q=(wind note gift)] :: local move +$ note :: out request $-> @@ -97,7 +97,6 @@ |= kyz=task ^+ +> ?+ -.kyz ~& [%strange-kiss -.kyz] +> - %flow +> %hail (send %hey ~) %belt (send `dill-belt`p.kyz) %talk (talk p.kyz) @@ -220,18 +219,32 @@ =. tem `(turn gyl |=(a=gill [%yow a])) (pass / [%c %warp our %home `[%sing %y [%ud 1] /]]) :: + ++ open + |= gyl=(list gill) + =. +> peer + %+ roll gyl + |= [g=gill _..open] + (send [%yow g]) + :: + ++ shut + ::TODO send a %bye blit? + pull + :: ++ send :: send action |= bet=dill-belt ^+ +> ?^ tem +>(tem `[bet u.tem]) - (deal /send/[ses] [%poke [%dill-belt -:!>(bet) bet]]) + (deal /send/[ses] [%poke [%dill-poke !>([ses bet])]]) :: ++ hood-set-boot-apps (deal / [%poke %drum-set-boot-apps !>(lit.all)]) :: ++ peer - (deal /peer/[ses] [%watch /drum]) ::TODO rename subscription path + (deal /peer/[ses] %watch /dill/[ses]) + :: + ++ pull + (deal /peer/[ses] %leave ~) :: ++ show :: permit reads on desk |= des=desk @@ -352,6 +365,31 @@ ?: ?=(%knob -.task) =. veb.all (~(put by veb.all) tag.task level.task) [~ ..^$] + :: %open opens a new dill session + :: + ?: ?=(%open -.task) + ?: (~(has by dug.all) ses) + ::TODO should we allow, and just send the %yow blits? + ~| [%cannot-open-existing ses] + !! + =/ zon=axon [p.task ~ width=80] + =^ moz all abet:(~(open as hen ses zon) q.task) + ::REVIEW we might want a separate, explicit %view, + :: but then we could miss some initial blits... + :: do we care about that? + =. eye.all (~(put ju eye.all) ses hen) + [moz ..^$] + :: %shut closes an existing dill session + :: + ?: ?=(%shut -.task) + ?: =(%$ ses) + ~| %cannot-shut-default-session + !! + =/ nus + ~| [%no-session ses] + (need (ax hen ses)) + =^ moz all abet:shut:nus + [moz ..^$] :: %view opens a subscription to the target session, on the current duct :: ?: ?=(%view -.task) From d93e9c6dd4cf01b3ea04a56f150de9b31cf5d2ef Mon Sep 17 00:00:00 2001 From: fang Date: Mon, 5 Apr 2021 22:41:46 +0200 Subject: [PATCH 048/104] dill: store width for session when it changes --- pkg/arvo/sys/vane/dill.hoon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/arvo/sys/vane/dill.hoon b/pkg/arvo/sys/vane/dill.hoon index 5d54eb6af5..dfa9676029 100644 --- a/pkg/arvo/sys/vane/dill.hoon +++ b/pkg/arvo/sys/vane/dill.hoon @@ -103,7 +103,7 @@ %text (fore (tuba p.kyz) ~) %crud :: (send `dill-belt`[%cru p.kyz q.kyz]) (crud p.kyz q.kyz) - %blew (send %rez p.p.kyz q.p.kyz) + %blew (send(wid p.p.kyz) %rez p.p.kyz q.p.kyz) %heft (pass /whey %$ whey/~) %meld (dump kyz) %pack (dump kyz) From 33865ca87a7607ce4bf3a91d2f4d6265230a461a Mon Sep 17 00:00:00 2001 From: fang Date: Mon, 5 Apr 2021 22:42:07 +0200 Subject: [PATCH 049/104] dill: add scry endpoints for session discovery --- pkg/arvo/sys/vane/dill.hoon | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pkg/arvo/sys/vane/dill.hoon b/pkg/arvo/sys/vane/dill.hoon index dfa9676029..38b6451303 100644 --- a/pkg/arvo/sys/vane/dill.hoon +++ b/pkg/arvo/sys/vane/dill.hoon @@ -509,8 +509,13 @@ =(%$ syd) == ~ - ::TODO scry endpoints for /sessions - ~ + :: /dy/sessions (set @tas) all existing sessions + :: /du/sessions/[ses] ? does session ses exist? + :: + ?+ [ren tyl] ~ + [%y %sessions ~] ``noun+!>(~(key by dug.all)) + [%u %sessions @ ~] ``noun+!>((~(has by dug.all) (snag 1 tyl))) + == :: ++ stay all :: From 51492917d7bf1a13a7d1c97c7c84281e3044c831 Mon Sep 17 00:00:00 2001 From: fang Date: Mon, 5 Apr 2021 22:46:23 +0200 Subject: [PATCH 050/104] herm: support non-default dill sessions Notably keeps session "subscriptions" open until the session is deleted. Perhaps we should optimize that at some point? --- pkg/arvo/app/herm.hoon | 57 ++++++++++++++++++++------- pkg/arvo/mar/herm/task.hoon | 78 +++++++++++++++++++++++++++++++++++++ pkg/arvo/sur/herm.hoon | 9 +++++ 3 files changed, 130 insertions(+), 14 deletions(-) create mode 100644 pkg/arvo/mar/herm/task.hoon create mode 100644 pkg/arvo/sur/herm.hoon diff --git a/pkg/arvo/app/herm.hoon b/pkg/arvo/app/herm.hoon index 8d295d526c..8ef76daa78 100644 --- a/pkg/arvo/app/herm.hoon +++ b/pkg/arvo/app/herm.hoon @@ -1,5 +1,6 @@ :: herm: stand-in for term.c with http interface :: +/- herm /+ default-agent, dbug, verb =, jael |% @@ -23,6 +24,10 @@ [%next %c da+now /[from]/[to]] [%sing %c da+now /[from]/[to]] == + :: + ++ pass-session + |= [ses=@tas tas=session-task:dill] + [%pass /dill/[ses] %arvo %d %shot ses tas] -- |_ =bowl:gall +* this . @@ -31,12 +36,11 @@ ++ on-init ^- (quip card:agent:gall _this) :_ this - :: set up dill session subscription, - :: and ensure the tubes we use are in cache + :: ensure the tubes we use are in cache :: - :~ [%pass [%view %$ ~] %arvo %d %view ~] - (request-tube bowl %blit %json |) + :~ (request-tube bowl %blit %json |) (request-tube bowl %json %belt |) + (request-tube bowl %json %herm-task |) == :: ++ on-save !>([%0 ~]) @@ -48,25 +52,37 @@ ++ on-watch |= =path ^- (quip card:agent:gall _this) + :_ this ?> ?=([%session @ ~] path) - :: tell session to refresh, so new client knows what's on screen - ::TODO should client be responsible for this? - [[%pass [%view %$ ~] %arvo %d %hail ~]~ this] + =* ses i.t.path + :~ :: subscribe to the requested session + :: + ::NOTE multiple views do not result in multiple subscriptions + :: because they go over the same wire/duct + :: + (pass-session ses %view ~) + :: tell session to refresh, so new client knows what's on screen + ::TODO should client be responsible for this? + :: + (pass-session ses %hail ~) + == :: ++ on-arvo |= [=wire =sign-arvo] ^- (quip card:agent:gall _this) + ~| wire ?+ wire !! :: pass on dill blits for the session :: - [%view %$ ~] + [%dill @ ~] + =* ses i.t.wire ?. ?=([%dill %blit *] sign-arvo) ~| [%unexpected-sign [- +<]:sign-arvo] !! :_ this %+ turn p.sign-arvo |= =blit:dill - [%give %fact [%session %$ ~]~ %blit !>(blit)] + [%give %fact [%session ses ~]~ %blit !>(blit)] :: :: ensure the tubes we need remain in cache :: @@ -83,14 +99,27 @@ ++ on-poke |= [=mark =vase] ^- (quip card:agent:gall _this) - ?. ?=(%belt mark) - ~| [%unexpected-mark mark] - !! :_ this - [%pass [%belt %$ ~] %arvo %d %belt !<(belt:dill vase)]~ + :_ ~ + ?+ mark ~|([%unexpected-mark mark] !!) + %belt (pass-session %$ %belt !<(belt:dill vase)) + %herm-task (pass-session !<(task:herm vase)) + == +:: +++ on-peek + |= =path + ^- (unit (unit cage)) + ?+ path ~ + [%x %sessions ~] + :+ ~ ~ + :- %json + !> ^- json + =- a+(turn ~(tap in -) (lead %s)) + .^((set @tas) %dy /(scot %p our.bowl)//(scot %da now.bowl)/sessions) + == :: ++ on-leave on-leave:def -++ on-peek on-peek:def +:: ++ on-agent on-agent:def ++ on-fail on-fail:def -- diff --git a/pkg/arvo/mar/herm/task.hoon b/pkg/arvo/mar/herm/task.hoon new file mode 100644 index 0000000000..b147630fbd --- /dev/null +++ b/pkg/arvo/mar/herm/task.hoon @@ -0,0 +1,78 @@ +:: task: herm task for passthrough to dill +::TODO deduplicate with /mar/belt, or remove one or the other +:: +/- herm +:: +|_ =task:herm +++ grad %noun +:: +grab: convert from +:: +++ grab + |% + ++ noun task:herm + :: + ++ json + |= jon=^json + ^+ task + ~| jon + ?> ?=([%o *] jon) + =+ ses=(~(got by p.jon) 'session') + ?> ?=([%s *] ses) + :- ?: =('' p.ses) %$ + (slav %tas p.ses) + =. p.jon (~(del by p.jon) 'session') + %. jon + =, dejs:format + |^ task + ++ task + %- of + :~ belt+belt + blew+(ot 'w'^ni 'h'^ni ~) + hail+ul + open+(ot 'term'^(se %tas) 'apps'^(ar gill) ~) + shut+ul + == + :: + ++ gill + (ot 'who'^(se %p) 'app'^(se %tas) ~) + :: + ++ belt + |= j=json + ^- belt:dill + ?: ?=([%s *] j) + (taft p.j) + %. j + %- of + :* mod+(ot 'mod'^mod 'key'^bot ~) + txt+(ar (cu taft so)) + bol + == + :: + ++ bol + :~ aro+(su (perk %d %l %r %u ~)) + bac+ul + del+ul + hit+(ot 'r'^ni 'c'^ni ~) + ret+ul + == + :: + ++ bot + |= j=json + ^- bolt:dill + ?+ j !! + [%s *] (taft p.j) + [%o *] ((of bol) j) + == + :: + ++ mod + |= j=json + ((su (perk %ctl %met %hyp ~)) j) + -- + -- +:: +grow: convert to +:: +++ grow + |% + ++ noun task + -- +-- diff --git a/pkg/arvo/sur/herm.hoon b/pkg/arvo/sur/herm.hoon new file mode 100644 index 0000000000..eab8cbb1ba --- /dev/null +++ b/pkg/arvo/sur/herm.hoon @@ -0,0 +1,9 @@ +:: herm: stand-in for term.c with http interface +:: +|% ++$ task + $~ [%$ %hail ~] + $: session=@tas + task=$>(?(%open %shut %belt %blew %hail) session-task:dill) + == +-- From 1c6d5ea341efdf27b41f551076a3159864dcf1ea Mon Sep 17 00:00:00 2001 From: fang Date: Mon, 5 Apr 2021 22:49:28 +0200 Subject: [PATCH 051/104] dill: remove viewers when deleting a session We do not allow subscribing to non-existent sessions, so we should not allow staying subscribed to deleted sessions. --- pkg/arvo/sys/vane/dill.hoon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/arvo/sys/vane/dill.hoon b/pkg/arvo/sys/vane/dill.hoon index 38b6451303..37d3425460 100644 --- a/pkg/arvo/sys/vane/dill.hoon +++ b/pkg/arvo/sys/vane/dill.hoon @@ -228,7 +228,7 @@ :: ++ shut ::TODO send a %bye blit? - pull + pull(eye.all (~(del by eye.all) ses)) :: ++ send :: send action |= bet=dill-belt From 65602198fc3c33422355e3459009af9b554702b2 Mon Sep 17 00:00:00 2001 From: fang Date: Mon, 5 Apr 2021 22:54:49 +0200 Subject: [PATCH 052/104] aqua: use most-recent blit type --- pkg/arvo/gen/aqua/dojo.hoon | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/arvo/gen/aqua/dojo.hoon b/pkg/arvo/gen/aqua/dojo.hoon index 65f5ccf439..1ba8de81db 100644 --- a/pkg/arvo/gen/aqua/dojo.hoon +++ b/pkg/arvo/gen/aqua/dojo.hoon @@ -5,8 +5,8 @@ :- %aqua-events %+ turn ^- (list unix-event) - :~ [//term/1 %belt %key %ctl `@c`%e] - [//term/1 %belt %key %ctl `@c`%u] + :~ [//term/1 %belt %mod %ctl `@c`%e] + [//term/1 %belt %mod %ctl `@c`%u] [//term/1 %belt %txt ((list @c) command)] [//term/1 %belt %ret ~] == From 98d48913bf821a9e94efc951f4ae3aa24c3f1c82 Mon Sep 17 00:00:00 2001 From: fang Date: Wed, 14 Apr 2021 17:10:50 +0200 Subject: [PATCH 053/104] kh: improve term code style Based on feedback during review. --- pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs | 11 ++---- .../urbit-king/lib/Urbit/Vere/Term/Logic.hs | 36 ++++++++++--------- .../urbit-king/lib/Urbit/Vere/Term/Render.hs | 4 +-- 3 files changed, 23 insertions(+), 28 deletions(-) diff --git a/pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs b/pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs index d28bda7cdd..6eaa574b20 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs @@ -309,12 +309,7 @@ instance FromNoun Bolt where n -> $(deriveFromNounFunc ''Bolt) n instance FromNoun Belt where - parseNoun = \case - A c -> pure $ Bol $ Key $ C.chr $ fromIntegral c - n -> runParser ($(deriveFromNounFunc ''Bolt) n) [] belt bolt - where - belt p m = $(deriveFromNounFunc ''Belt) n - bolt !b = pure $ Bol b + parseNoun n = Bol <$> parseNoun n <|> $(deriveFromNounFunc ''Belt) n instance ToNoun Bolt where toNoun = \case @@ -323,9 +318,7 @@ instance ToNoun Bolt where instance ToNoun Belt where toNoun = \case - Bol b -> case b of - Key c -> A $ fromIntegral $ C.ord c - b -> $(deriveToNounFunc ''Bolt) b + Bol b -> toNoun b n -> $(deriveToNounFunc ''Belt) n data TermEv diff --git a/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Logic.hs b/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Logic.hs index 17a2f6c119..8a7d335ccc 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Logic.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Logic.hs @@ -84,15 +84,15 @@ step st@St{..} = \case EvSlog s -> st & recordSlog s EvSpin s -> st { sSpinner = s } EvMove p -> st { sCurPos = p } - EvEdit t -> if fst sCurPos == 0 then st { sLine = t } - else st - EvNewl -> if fst sCurPos == 0 then - st { sLine = "", sCurPos = (0, 0) } - & recordText (sLine <> "\n") - else - st { sCurPos = (((fst sCurPos) - 1), 0) } EvBell -> st EvDraw -> st + EvEdit t | (0, _) <- sCurPos -> st { sLine = t } + | otherwise -> st + EvNewl | (0, _) <- sCurPos -> + st { sLine = "", sCurPos = (0, 0) } + & recordText (sLine <> "\n") + | otherwise -> + st { sCurPos = (((fst sCurPos) - 1), 0) } where recordText :: Text -> St -> St recordText !t st@St{..} = st { @@ -113,8 +113,10 @@ drawState :: St -> [Ev] drawState St{..} = hist <> out <> cur <> spin where hist = drawHistory <$> toList sHistory - out = if null sLine then [] else [EvEdit sLine] - cur = if 0 == fst sCurPos then [] else [EvMove sCurPos] + out | null <- sLine = [] + | otherwise = [EvEdit sLine] + cur | (0, _) <- sCurPos = [] + | otherwise = [EvMove sCurPos] spin = maybe [] (singleton . EvSpin . Just) sSpinner drawHistory (HistoryText t) = EvLine t @@ -151,12 +153,12 @@ fromTermEv = \case toTermEv :: Ev -> Term.Ev toTermEv = \case - EvLine "" -> Term.Blank - EvLine t -> Term.Trace (Cord t) - EvSlog s -> Term.Slog s - EvSpin s -> Term.Spinr (fromCause <$> s) + EvLine "" -> Term.Blank + EvLine t -> Term.Trace (Cord t) + EvSlog s -> Term.Slog s + EvSpin s -> Term.Spinr (fromCause <$> s) EvMove (r, c) -> Term.Blits [Arvo.Hop $ Arvo.Roc (fromIntegral r) (fromIntegral c)] - EvBell -> Term.Blits [Arvo.Bel ()] - EvDraw -> Term.Blits [Arvo.Clr ()] - EvEdit t -> Term.Blits [Arvo.Put $ unpack t] - EvNewl -> Term.Blits [Arvo.Nel ()] + EvBell -> Term.Blits [Arvo.Bel ()] + EvDraw -> Term.Blits [Arvo.Clr ()] + EvEdit t -> Term.Blits [Arvo.Put $ unpack t] + EvNewl -> Term.Blits [Arvo.Nel ()] diff --git a/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Render.hs b/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Render.hs index 9742a6b697..853ca953c4 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Render.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Render.hs @@ -34,10 +34,10 @@ cursorMove :: MonadIO m => Int -> Int -> m () cursorMove r c = liftIO $ ANSI.setCursorPosition r c cursorSave :: MonadIO m => m () -cursorSave = liftIO $ ANSI.saveCursor +cursorSave = liftIO ANSI.saveCursor cursorRestore :: MonadIO m => m () -cursorRestore = liftIO $ ANSI.restoreCursor +cursorRestore = liftIO ANSI.restoreCursor putCSI :: MonadIO m => Char -> [Int] -> m () putCSI c a = liftIO do From c55ebf36a47e98c279022331b9d8c1ccf9dc6740 Mon Sep 17 00:00:00 2001 From: fang Date: Wed, 14 Apr 2021 20:35:17 +0200 Subject: [PATCH 054/104] kh: don't show spinner name for user inputs --- pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs | 30 +++++++++++------------ 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs b/pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs index 6eaa574b20..fb95f523d7 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs @@ -380,27 +380,25 @@ instance FromNoun Ev where -- Short Event Names ----------------------------------------------------------- {- - In the case of the user hitting enter, the cause is technically a - terminal event, but we don't display any name because the cause is - really the user. + In the case of user input, the cause is technically a terminal event, + but we don't display any name because the cause is really the user. -} ---REVIEW doesn't that hold for _any_ terminal event? getSpinnerNameForEvent :: Ev -> Maybe Text getSpinnerNameForEvent = \case EvBlip b -> case b of - BlipEvAmes _ -> Just "ames" - BlipEvArvo _ -> Just "arvo" - BlipEvBehn _ -> Just "behn" - BlipEvBoat _ -> Just "boat" - BlipEvHttpClient _ -> Just "iris" - BlipEvHttpServer _ -> Just "eyre" - BlipEvNewt _ -> Just "newt" - BlipEvSync _ -> Just "clay" - BlipEvTerm t | isRet t -> Nothing - BlipEvTerm t -> Just "term" + BlipEvAmes _ -> Just "ames" + BlipEvArvo _ -> Just "arvo" + BlipEvBehn _ -> Just "behn" + BlipEvBoat _ -> Just "boat" + BlipEvHttpClient _ -> Just "iris" + BlipEvHttpServer _ -> Just "eyre" + BlipEvNewt _ -> Just "newt" + BlipEvSync _ -> Just "clay" + BlipEvTerm t | isUser t -> Nothing + BlipEvTerm t -> Just "term" where - isRet (TermEvBelt _ (Bol (Ret ()))) = True - isRet _ = False + isUser (TermEvBelt _ _) = True + isUser _ = False summarizeEvent :: Ev -> Text summarizeEvent ev = From a09bb86cc6060c66fcef598df3e25ca71ec8e4a1 Mon Sep 17 00:00:00 2001 From: fang Date: Wed, 14 Apr 2021 20:35:47 +0200 Subject: [PATCH 055/104] dill: resolve review questions --- pkg/arvo/sys/vane/dill.hoon | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pkg/arvo/sys/vane/dill.hoon b/pkg/arvo/sys/vane/dill.hoon index 37d3425460..9099eb0f20 100644 --- a/pkg/arvo/sys/vane/dill.hoon +++ b/pkg/arvo/sys/vane/dill.hoon @@ -343,7 +343,6 @@ =/ zon=axon [app input=[~ ~] width=80] :: =^ moz all abet:(~(into as duc %$ zon) ~) - ::REVIEW can anything relevant happen between %boot and %init? =. eye.all (~(put ju eye.all) %$ duc) [moz ..^$] :: %flog tasks are unwrapped and sent back to us on our default duct @@ -374,9 +373,6 @@ !! =/ zon=axon [p.task ~ width=80] =^ moz all abet:(~(open as hen ses zon) q.task) - ::REVIEW we might want a separate, explicit %view, - :: but then we could miss some initial blits... - :: do we care about that? =. eye.all (~(put ju eye.all) ses hen) [moz ..^$] :: %shut closes an existing dill session From cbd6a919cb14b71ea2bcbc4b160ec189159c06c4 Mon Sep 17 00:00:00 2001 From: fang Date: Wed, 14 Apr 2021 20:50:42 +0200 Subject: [PATCH 056/104] term: remove unused %hook code --- pkg/urbit/vere/io/term.c | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index 5c33a71a66..a7c8a70452 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -95,39 +95,6 @@ _term_alloc(uv_handle_t* had_u, *buf = uv_buf_init(ptr_v, 123); } -// XX unused, but %hook is in %zuse. -// implement or remove -// -#if 0 -/* _term_close_cb(): free terminal. -*/ -static void -_term_close_cb(uv_handle_t* han_t) -{ - u3_utty* tty_u = (void*) han_t; - if ( u3_Host.uty_u == tty_u ) { - u3_Host.uty_u = tty_u->nex_u; - } - else { - u3_utty* uty_u; - for (uty_u = u3_Host.uty_u; uty_u; uty_u = uty_u->nex_u ) { - if ( uty_u->nex_u == tty_u ) { - uty_u->nex_u = tty_u->nex_u; - break; - } - } - } - - { - u3_noun tid = u3dc("scot", c3__ud, tty_u->tid_l); - u3_noun pax = u3nq(u3_blip, c3__term, tid, u3_nul); - u3_pier_plan(u3k(pax), u3nc(c3__hook, u3_nul)); - u3z(pax); - } - c3_free(tty_u); -} -#endif - /* u3_term_log_init(): initialize terminal for logging */ void From e93d50b3eecdd00fc4ccd49542f0089a37ed5f99 Mon Sep 17 00:00:00 2001 From: fang Date: Wed, 14 Apr 2021 20:53:22 +0200 Subject: [PATCH 057/104] term: remove legacy conditional --- pkg/urbit/vere/io/term.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index a7c8a70452..a1b9ea6e39 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -442,12 +442,9 @@ _term_it_free_line(u3_utty* uty_u) static void _term_it_clear_line(u3_utty* uty_u) { - //REVIEW why this conditional? - if ( uty_u->tat_u.siz.col_l ) { - _term_it_dump(uty_u, TERM_LIT("\r")); - _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.el_u); - _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.rc_u); - } + _term_it_dump(uty_u, TERM_LIT("\r")); + _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.el_u); + _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.rc_u); // if we're clearing the bottom line, clear our mirror of it too // From 32a5e9085cfe400f642f7d927af0fd5c473b6a0c Mon Sep 17 00:00:00 2001 From: fang Date: Thu, 15 Apr 2021 01:18:43 +0200 Subject: [PATCH 058/104] term: exclusive save cursor after explicit move In other words, don't issue the ANSI escape sequence for saving the cursor position at the start of a printf hijack sequence. Instead trust this was already done when the cursor position was last changes by a blit. --- pkg/urbit/vere/io/term.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index a1b9ea6e39..472e5d4d84 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -1519,12 +1519,10 @@ u3_term_io_hija(void) c3_assert(!"hija-fcntl"); } - // save cursor position, // set scroll region to exclude the prompt, // scroll up one line to make space, // and move the cursor onto that space. // - _term_it_send_csi(uty_u, 's', 0); _term_it_send_csi(uty_u, 'r', 2, 1, uty_u->tat_u.siz.row_l - 1); _term_it_send_csi(uty_u, 'S', 1, 1); _term_it_send_csi(uty_u, 'H', 2, uty_u->tat_u.siz.row_l - 1, 1); From cf93320cf00ac9d67c159625a533b3a11978f1cf Mon Sep 17 00:00:00 2001 From: fang Date: Thu, 15 Apr 2021 01:50:45 +0200 Subject: [PATCH 059/104] term: clean up escape sequence constants Use them for all zero-argument sequences, remove unused ones, and make their naming consistent. Also removes old, commented code around input sequences. --- pkg/urbit/include/vere/vere.h | 38 +++++++----------- pkg/urbit/vere/io/term.c | 73 ++++++++++++++--------------------- 2 files changed, 44 insertions(+), 67 deletions(-) diff --git a/pkg/urbit/include/vere/vere.h b/pkg/urbit/include/vere/vere.h index 4157e6ea6b..438beae372 100644 --- a/pkg/urbit/include/vere/vere.h +++ b/pkg/urbit/include/vere/vere.h @@ -182,32 +182,22 @@ struct _u3_usig* nex_u; } u3_usig; - /* u2_utfo: unix terminfo strings. + /* u2_utfo: terminal escape sequences */ typedef struct { - // disabled, currently unused + uv_buf_t mon_u; // mouse reporting on + uv_buf_t mof_u; // mouse reporting off // - // struct { - // uv_buf_t kcuu1_u; // key_up - // uv_buf_t kcud1_u; // key_down - // uv_buf_t kcub1_u; // key_back - // uv_buf_t kcuf1_u; // key_forward - // } inn; - struct { - uv_buf_t clear_u; // clear_screen - uv_buf_t el_u; // clr_bol clear to end of line - // uv_buf_t el1_u; // clr_eol clear to beginning of line - uv_buf_t ed_u; // clear to end of screen - uv_buf_t sc_u; // save cursor position - uv_buf_t rc_u; // restore cursor position - uv_buf_t bel_u; // bel sound bell - uv_buf_t cub1_u; // parm_left - uv_buf_t cuf1_u; // parm_right - uv_buf_t cuu1_u; // parm_up - uv_buf_t cud1_u; // parm_down - // uv_buf_t cub_u; // parm_left_cursor #num - // uv_buf_t cuf_u; // parm_right_cursor #num - } out; + uv_buf_t reg_u; // restore scroll region + // + uv_buf_t suc_u; // save cursor position + uv_buf_t ruc_u; // restore cursor position + uv_buf_t cub_u; // move cursor left one column + // + uv_buf_t clr_u; // clear screen + uv_buf_t cel_u; // clear to end of line + // + uv_buf_t bel_u; // bel sound bell } u3_utfo; #if 0 @@ -236,7 +226,7 @@ struct _u3_utty* nex_u; // next in host list c3_i fid_i; // file descriptor c3_w tid_l; // terminal identity number - u3_utfo ufo_u; // terminfo strings + u3_utfo ufo_u; // escape sequences c3_i cug_i; // blocking fcntl flags c3_i nob_i; // nonblocking fcntl flags u3_utat tat_u; // control state diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index 472e5d4d84..2fc60d150e 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -130,31 +130,20 @@ u3_term_log_init(void) // and simply use constant sequences. // { - uty_u->ufo_u.out.clear_u = TERM_LIT_BUF("\033[H\033[2J"); - uty_u->ufo_u.out.el_u = TERM_LIT_BUF("\033[K"); - // uty_u->ufo_u.out.el1_u = TERM_LIT_BUF("\033[1K"); - uty_u->ufo_u.out.ed_u = TERM_LIT_BUF("\033[J"); - uty_u->ufo_u.out.sc_u = TERM_LIT_BUF("\033[s"); - uty_u->ufo_u.out.rc_u = TERM_LIT_BUF("\033[u"); - uty_u->ufo_u.out.bel_u = TERM_LIT_BUF("\x7"); - uty_u->ufo_u.out.cub1_u = TERM_LIT_BUF("\x8"); - uty_u->ufo_u.out.cuf1_u = TERM_LIT_BUF("\033[C"); - uty_u->ufo_u.out.cuu1_u = TERM_LIT_BUF("\033[A"); - uty_u->ufo_u.out.cud1_u = TERM_LIT_BUF("\xa"); - // uty_u->ufo_u.out.cub_u = TERM_LIT_BUF("\033[%p1%dD"); - // uty_u->ufo_u.out.cuf_u = TERM_LIT_BUF("\033[%p1%dC"); - } + uty_u->ufo_u.mon_u = TERM_LIT_BUF("\033[?9h"); + uty_u->ufo_u.mof_u = TERM_LIT_BUF("\033[?9l"); - // configure input escape sequences - // - // NB: terminfo reports the wrong sequence for arrow keys on xterms. - // disabled, currently unused - // { - // uty_u->ufo_u.inn.kcuu1_u = TERM_LIT_BUF("\033[A"); // terminfo reports "\033OA" - // uty_u->ufo_u.inn.kcud1_u = TERM_LIT_BUF("\033[B"); // terminfo reports "\033OB" - // uty_u->ufo_u.inn.kcuf1_u = TERM_LIT_BUF("\033[C"); // terminfo reports "\033OC" - // uty_u->ufo_u.inn.kcub1_u = TERM_LIT_BUF("\033[D"); // terminfo reports "\033OD" - // } + uty_u->ufo_u.reg_u = TERM_LIT_BUF("\033[r"); + + uty_u->ufo_u.suc_u = TERM_LIT_BUF("\033[s"); + uty_u->ufo_u.ruc_u = TERM_LIT_BUF("\033[u"); + uty_u->ufo_u.cub_u = TERM_LIT_BUF("\x8"); + + uty_u->ufo_u.clr_u = TERM_LIT_BUF("\033[H\033[2J"); + uty_u->ufo_u.cel_u = TERM_LIT_BUF("\033[K"); + + uty_u->ufo_u.bel_u = TERM_LIT_BUF("\x7"); + } // Load old terminal state to restore. // @@ -443,8 +432,8 @@ static void _term_it_clear_line(u3_utty* uty_u) { _term_it_dump(uty_u, TERM_LIT("\r")); - _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.el_u); - _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.rc_u); + _term_it_dump_buf(uty_u, &uty_u->ufo_u.cel_u); + _term_it_dump_buf(uty_u, &uty_u->ufo_u.ruc_u); // if we're clearing the bottom line, clear our mirror of it too // @@ -458,8 +447,8 @@ _term_it_clear_line(u3_utty* uty_u) static void _term_it_show_blank(u3_utty* uty_u) { - _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.clear_u); - _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.rc_u); + _term_it_dump_buf(uty_u, &uty_u->ufo_u.clr_u); + _term_it_dump_buf(uty_u, &uty_u->ufo_u.ruc_u); } /* _term_it_move_cursor(): move cursor to row & column @@ -477,7 +466,7 @@ _term_it_move_cursor(u3_utty* uty_u, c3_w row_w, c3_w col_w) if ( col_w >= col_l ) { col_w = col_l - 1; } _term_it_send_csi(uty_u, 'H', 2, row_l - row_w, col_w + 1); - _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.sc_u); + _term_it_dump_buf(uty_u, &uty_u->ufo_u.suc_u); uty_u->tat_u.mir.rus_w = row_w; uty_u->tat_u.mir.cus_w = col_w; @@ -526,7 +515,7 @@ _term_it_show_line(u3_utty* uty_u, c3_w* lin_w, c3_w wor_w) //NOTE lin_w freed through hun_y by _send _term_it_send(uty_u, byt_w, hun_y); - _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.rc_u); + _term_it_dump_buf(uty_u, &uty_u->ufo_u.ruc_u); } /* _term_it_restore_line(): refresh current line. @@ -548,7 +537,7 @@ _term_it_restore_line(u3_utty* uty_u) memcpy(hun_w, lin_w, wor_w * sizeof(c3_w)); _term_it_send_csi(uty_u, 'H', 2, tat_u->siz.row_l, 0); - _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.el_u); + _term_it_dump_buf(uty_u, &uty_u->ufo_u.cel_u); _term_it_show_line(uty_u, hun_w, wor_w); } } @@ -614,7 +603,7 @@ _term_it_show_nel(u3_utty* uty_u) } else { _term_it_dump(uty_u, TERM_LIT("\r\n")); - _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.sc_u); + _term_it_dump_buf(uty_u, &uty_u->ufo_u.suc_u); } uty_u->tat_u.mir.cus_w = 0; @@ -756,7 +745,7 @@ _term_io_suck_char(u3_utty* uty_u, c3_y cay_y) if ( c3y == tat_u->esc.bra ) { switch ( cay_y ) { default: { - _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.bel_u); + _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; @@ -783,7 +772,7 @@ _term_io_suck_char(u3_utty* uty_u, c3_y cay_y) else { tat_u->esc.ape = c3n; - _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.bel_u); + _term_it_dump_buf(uty_u, &uty_u->ufo_u.bel_u); } } } @@ -830,7 +819,7 @@ _term_io_suck_char(u3_utty* uty_u, c3_y cay_y) _term_io_belt(uty_u, u3nt(c3__txt, cay_y, u3_nul)); } else if ( 0 == cay_y ) { - _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.bel_u); + _term_it_dump_buf(uty_u, &uty_u->ufo_u.bel_u); } else if ( 8 == cay_y || 127 == cay_y ) { _term_io_belt(uty_u, u3nc(c3__bac, u3_nul)); @@ -980,7 +969,7 @@ _term_spin_step(u3_utty* uty_u) // NB: we simply bail out if anything goes wrong // { - uv_buf_t lef_u = uty_u->ufo_u.out.cub1_u; + uv_buf_t lef_u = uty_u->ufo_u.cub_u; c3_i fid_i; if ( uv_fileno((uv_handle_t*)&uty_u->pop_u, &fid_i) ) { @@ -1425,7 +1414,7 @@ _term_ef_blit(u3_utty* uty_u, case c3__bel: { if ( c3n == u3_Host.ops_u.tem ) { - _term_it_dump_buf(uty_u, &uty_u->ufo_u.out.bel_u); + _term_it_dump_buf(uty_u, &uty_u->ufo_u.bel_u); } } break; @@ -1573,8 +1562,8 @@ u3_term_io_loja(int x) // clear the scrolling region we set previously, // and restore cursor to its original position. // - _term_it_send_csi(uty_u, 'r', 0); - _term_it_send_csi(uty_u, 'u', 0); + _term_it_dump_buf(uty_u, &uty_u->ufo_u.reg_u); + _term_it_dump_buf(uty_u, &uty_u->ufo_u.ruc_u); } } } @@ -1657,8 +1646,7 @@ _term_io_talk(u3_auto* car_u) // start mouse handling // - uv_buf_t mon_u = TERM_LIT_BUF("\033[?9h"); - _term_it_dump_buf(uty_u, &mon_u); + _term_it_dump_buf(uty_u, &uty_u->ufo_u.mon_u); uv_read_start((uv_stream_t*)&(uty_u->pop_u), _term_alloc, @@ -1822,8 +1810,7 @@ _term_io_exit(u3_auto* car_u) if ( c3n == u3_Host.ops_u.tem ) { // stop mouse handling // - uv_buf_t mof_u = TERM_LIT_BUF("\033[?9l"); - _term_it_dump_buf(uty_u, &mof_u); + _term_it_dump_buf(uty_u, &uty_u->ufo_u.mof_u); uv_timer_t* han_u = &(uty_u->tat_u.sun_u.tim_u); han_u->data = car_u; From 56f1ef3a4c9d6e1dd456ca084d5175e34164fda6 Mon Sep 17 00:00:00 2001 From: fang Date: Thu, 15 Apr 2021 16:35:05 +0200 Subject: [PATCH 060/104] term: simpler blit rendering during -t Separates blit rendering for logic for -t into a separate function. Ensures we don't overwrite any rendered content and always put newlines in between distinct pieces of output. Also stops storing the bottom line of output in the -t case, since it won't get re-rendered anyway. Hopefully this makes CI output look nice again. --- pkg/urbit/vere/io/term.c | 71 ++++++++++++++++++++++++++++++---------- 1 file changed, 54 insertions(+), 17 deletions(-) diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index 2fc60d150e..f85e0b3af7 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -550,9 +550,10 @@ _term_it_save_line(u3_utty* uty_u, c3_w* lin_w, c3_w wor_w) { u3_utat* tat_u = &uty_u->tat_u; - // keep track of changes to bottom-most line, to aid spinner drawing logic + // keep track of changes to bottom-most line, to aid spinner drawing logic. + // -t mode doesn't need this logic, because it doesn't render the spinner. // - if ( 0 == tat_u->mir.rus_w ) { + if ( (0 == tat_u->mir.rus_w) && (c3n == u3_Host.ops_u.tem)) { c3_w* nip_w = tat_u->mir.lin_w; c3_w wod_w = tat_u->mir.wor_w; c3_w off_w = tat_u->mir.cus_w; @@ -1413,26 +1414,20 @@ _term_ef_blit(u3_utty* uty_u, default: break; case c3__bel: { - if ( c3n == u3_Host.ops_u.tem ) { - _term_it_dump_buf(uty_u, &uty_u->ufo_u.bel_u); - } + _term_it_dump_buf(uty_u, &uty_u->ufo_u.bel_u); } break; case c3__clr: { - if ( c3n == u3_Host.ops_u.tem ) { - _term_it_show_blank(uty_u); - } + _term_it_show_blank(uty_u); } break; case c3__hop: { - if ( c3n == u3_Host.ops_u.tem ) { - u3_noun pos = u3t(blt); - if ( c3y == u3r_ud(pos) ) { - _term_it_move_cursor(uty_u, 0, pos); - } - else { - _term_it_move_cursor(uty_u, u3h(pos), u3t(pos)); - } + u3_noun pos = u3t(blt); + if ( c3y == u3r_ud(pos) ) { + _term_it_move_cursor(uty_u, 0, pos); + } + else { + _term_it_move_cursor(uty_u, u3h(pos), u3t(pos)); } } break; @@ -1475,6 +1470,43 @@ _term_ef_blit(u3_utty* uty_u, u3z(blt); } +/* _term_ef_blit_lame(): simplified output handling for -t +*/ +static void +_term_ef_blit_lame(u3_utty* uty_u, + u3_noun blt) +{ + switch ( u3h(blt) ) { + default: break; + + case c3__klr: { + _term_it_show_stub(uty_u, u3k(u3t(blt))); + _term_it_show_nel(uty_u); + } break; + + case c3__put: { + _term_it_show_tour(uty_u, u3k(u3t(blt))); + _term_it_show_nel(uty_u); + } break; + + case c3__sav: { + u3_noun pax, dat; + u3x_cell(u3t(blt), &pax, &dat); + + _term_it_save(u3k(pax), u3k(dat)); + } break; + + case c3__sag: { + u3_noun pax, dat; + u3x_cell(u3t(blt), &pax, &dat); + + _term_it_save(u3k(pax), u3qe_jam(dat)); + } break; + } + + u3z(blt); +} + /* u3_term_io_hija(): hijack console for fprintf, returning FILE*. */ FILE* @@ -1743,7 +1775,12 @@ _term_io_kick(u3_auto* car_u, u3_noun wir, u3_noun cad) u3_noun bis = dat; while ( c3y == u3du(bis) ) { - _term_ef_blit(uty_u, u3k(u3h(bis))); + if (c3n == u3_Host.ops_u.tem) { + _term_ef_blit(uty_u, u3k(u3h(bis))); + } + else { + _term_ef_blit_lame(uty_u, u3k(u3h(bis))); + } bis = u3t(bis); } } From fab0f65d58ed698bcdaa43d4c9ee563dd8961f72 Mon Sep 17 00:00:00 2001 From: fang Date: Thu, 15 Apr 2021 20:54:55 +0200 Subject: [PATCH 061/104] term: bump on-return spinner delay from 0 to 100ms Not drawing the spinner when the command gets processed nearly instantly makes things feel slightly better. --- pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs | 5 +++-- pkg/urbit/vere/io/term.c | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs b/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs index 8f3a80ebbc..b681e0029c 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs @@ -173,7 +173,8 @@ leftBracket, rightBracket :: Text leftBracket = "«" rightBracket = "»" -_spin_cool_us, _spin_warm_us, _spin_rate_us, _spin_idle_us :: Integral i => i +_spin_fast_us, _spin_cool_us, _spin_warm_us, _spin_rate_us, _spin_idle_us :: Integral i => i +_spin_fast_us = 100000 _spin_cool_us = 500000 _spin_warm_us = 50000 _spin_rate_us = 250000 @@ -330,7 +331,7 @@ localClient doneSignal = fst <$> mkRAcquire start stop current <- io $ now delay <- pure $ case mTxt of - Nothing -> 0 + Nothing -> _spin_fast_us Just _ -> if (gap current lsPrevEndTime ^. microSecs) < _spin_idle_us then _spin_warm_us diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index f85e0b3af7..561a72284b 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -1023,6 +1023,7 @@ _term_spin_timer_cb(uv_timer_t* tim_u) _term_spin_step(uty_u); } +#define _SPIN_FAST_US 100UL // spinner activation delay when expected #define _SPIN_COOL_US 500UL // spinner activation delay when cool #define _SPIN_WARM_US 50UL // spinner activation delay when warm #define _SPIN_RATE_US 250UL // spinner rate (ms/frame) @@ -1047,7 +1048,7 @@ u3_term_start_spinner(u3_atom say, c3_o del_o) { c3_d now_d = _term_msc_out_host(); c3_d end_d = tat_u->sun_u.end_d; - c3_d wen_d = (c3n == del_o) ? 0UL : + c3_d wen_d = (c3n == del_o) ? _SPIN_FAST_US : (now_d - end_d < _SPIN_IDLE_US) ? _SPIN_WARM_US : _SPIN_COOL_US; From 8716c49b4525cd59358167b2ba55185dd11e866f Mon Sep 17 00:00:00 2001 From: fang Date: Fri, 16 Apr 2021 14:55:34 +0200 Subject: [PATCH 062/104] kh: always draw spinner on bottom line Now always draws the spinner on the bottom line, regardless of the cursor position. --- pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs | 33 +++++++++++++----------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs b/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs index b681e0029c..248cb6ce23 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs @@ -286,7 +286,9 @@ localClient doneSignal = fst <$> mkRAcquire start stop writeTerminal :: TQueue [Term.Ev] -> TMVar () -> TVar TermSize -> RIO e () writeTerminal q spinner termSizeVar = do currentTime <- io $ now - loop (LineState "" (CurPos 0 0) Nothing Nothing True 0 currentTime) + loop + termSizeVar + (LineState "" (CurPos 0 0) Nothing Nothing True 0 currentTime) where writeBlank :: LineState -> RIO e LineState writeBlank ls = do @@ -324,7 +326,6 @@ localClient doneSignal = fst <$> mkRAcquire start stop event shortly after a previous spin, use a shorter delay to avoid giving the impression of a half-idle system. -} - --TODO this is too eager and does termRestoreLine on every keypress! doSpin :: LineState -> Maybe Text -> RIO e LineState doSpin ls@LineState{..} mTxt = do maybe (pure ()) cancel lsSpinTimer @@ -357,7 +358,7 @@ localClient doneSignal = fst <$> mkRAcquire start stop -- If we ever actually ran the spinner display callback, we need -- to force a redisplay of the command prompt. - if not lsSpinFirstRender || True + if not lsSpinFirstRender then termRestoreLine ls termSizeVar else pure () @@ -373,13 +374,20 @@ localClient doneSignal = fst <$> mkRAcquire start stop Term.Spinr (Just txt) -> doSpin ls (unCord <$> txt) Term.Spinr Nothing -> unspin ls - -- TODO What does this do? - spin :: LineState -> RIO e LineState - spin ls@LineState{..} = do + spin :: TVar TermSize -> LineState -> RIO e LineState + spin ts ls@LineState{..} = do let spinner = (spinners !! lsSpinFrame) ++ case lsSpinCause of Nothing -> "" Just str -> leftBracket ++ str ++ rightBracket + --NOTE even after first render, because cursor might have moved... + if row lsCurPos > 0 + then do + TermSize _ h <- readTVarIO ts + T.cursorMove (fromIntegral h - 1) 0 + else + T.cursorRestore + putStr (spinner <> pack (ANSI.cursorBackwardCode (length spinner))) let newFrame = (lsSpinFrame + 1) `mod` length spinners @@ -388,11 +396,11 @@ localClient doneSignal = fst <$> mkRAcquire start stop , lsSpinFrame = newFrame } - loop :: LineState -> RIO e () - loop ls = do + loop :: TVar TermSize -> LineState -> RIO e () + loop ts ls = do join $ atomically $ asum - [ readTQueue q >>= pure . (foldM execEv ls >=> loop) - , takeTMVar spinner >> pure (spin ls >>= loop) + [ readTQueue q >>= pure . (foldM execEv ls >=> loop ts) + , takeTMVar spinner >> pure (spin ts ls >>= loop ts) ] -- Writes an individual blit to the screen @@ -475,11 +483,6 @@ localClient doneSignal = fst <$> mkRAcquire start stop T.cursorSave pure ls { lsCurPos = CurPos row col } - -- Moves the cursor left without any mutation of the LineState. Used only - -- in cursor spinning. - _termSpinnerMoveLeft :: Int -> RIO e () - _termSpinnerMoveLeft = liftIO . ANSI.cursorBackward - -- Displays and sets the current line termShowLine :: LineState -> Text -> RIO e LineState termShowLine ls@LineState{lsCurPos} newStr = do From 95c3a51ba176eed6f3bae2d83bc566ba144fc505 Mon Sep 17 00:00:00 2001 From: fang Date: Sat, 17 Apr 2021 01:31:40 +0200 Subject: [PATCH 063/104] zuse: make +slag:klr:format match +slag's behavior Previously, if the given index was beyond the stub's content, it would return the entire stub. Now, it correctly returns the empty stub. --- pkg/arvo/sys/zuse.hoon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/arvo/sys/zuse.hoon b/pkg/arvo/sys/zuse.hoon index 47678da1a4..f6a409a175 100644 --- a/pkg/arvo/sys/zuse.hoon +++ b/pkg/arvo/sys/zuse.hoon @@ -3749,7 +3749,7 @@ ^- stub =+ c=(lnts-char b) =+ i=(brek a c) - ?~ i b + ?~ i ~ =+ r=(^slag +(p.u.i) b) ?: =(a q.u.i) r From 2c837da6fa28e1863447593b887929e2dc1d0bff Mon Sep 17 00:00:00 2001 From: fang Date: Sat, 17 Apr 2021 01:35:14 +0200 Subject: [PATCH 064/104] zuse: add additional stub utilities in +klr +wail, for overwriting part of a stub, starting at the given index, extending it using the specified character if the index is past the end of the stub. +pact, for merging sequential stub sections with identical style. --- bin/ivory.pill | 4 ++-- pkg/arvo/sys/zuse.hoon | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/bin/ivory.pill b/bin/ivory.pill index 7c2e8e4746..b1f14b13ec 100644 --- a/bin/ivory.pill +++ b/bin/ivory.pill @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:185ea5e76dc48695e55efc543377e0682e485f81b16e3b443f9be881d026d4f2 -size 2616564 +oid sha256:2800e4ff87369d6206daa96937d8a186a12da67aac2ab8cd74c6c359f26cddb8 +size 3952579 diff --git a/pkg/arvo/sys/zuse.hoon b/pkg/arvo/sys/zuse.hoon index f6a409a175..6bbe3ebd25 100644 --- a/pkg/arvo/sys/zuse.hoon +++ b/pkg/arvo/sys/zuse.hoon @@ -3744,6 +3744,15 @@ `[i c] $(i +(i), b t.b) :: + ++ pact :: condense stub + |= a=stub + ^- stub + ?~ a ~ + ?~ t.a a + ?. =(p.i.a p.i.t.a) [i.a $(a t.a)] + =. q.i.t.a (weld q.i.a q.i.t.a) + $(a t.a) + :: ++ slag :: slag stub |= [a=@ b=stub] ^- stub @@ -3774,6 +3783,20 @@ ++ swag :: swag stub |= [[a=@ b=@] c=stub] (scag b (slag a c)) + :: + ++ wail :: overlay stub + |= [a=stub b=@ c=stub d=@c] + ^- stub + ;: weld + (scag b a) + :: + =+ e=(lent-char a) + ?: (lth b e) ~ + [*stye (reap (sub b e) d)]~ + :: + c + (slag (add b (lent-char c)) a) + == -- :: klr -- :: :: From a8de23ca924ce385dd61fe2d41c039f6b497e932 Mon Sep 17 00:00:00 2001 From: fang Date: Sat, 17 Apr 2021 02:38:42 +0200 Subject: [PATCH 065/104] term: correctly (re)store styled lines We were storing the contents of the bottom line, but not accounting for style/escape characters when overwriting parts of it with new contents. Here, we switch to storing a +stub noun in state instead, letting us rely on the stdlib for the overwriting logic. This comes at the cost of having to re-render the stub into an escape sequence on every restore, but that has yet to prove itself slow enough to care about. --- pkg/urbit/include/vere/vere.h | 7 +-- pkg/urbit/vere/io/term.c | 103 ++++++++++++---------------------- 2 files changed, 39 insertions(+), 71 deletions(-) diff --git a/pkg/urbit/include/vere/vere.h b/pkg/urbit/include/vere/vere.h index 438beae372..f17fd12ad7 100644 --- a/pkg/urbit/include/vere/vere.h +++ b/pkg/urbit/include/vere/vere.h @@ -145,10 +145,9 @@ } siz; struct { - c3_w* lin_w; // bottom line (utf32) - c3_w wor_w; // utf32 line-length - c3_w rus_w; // cursor position (row) - c3_w cus_w; // cursor position (column) + u3_noun lin; // bottom line (stub) + c3_w rus_w; // cursor position (row) + c3_w cus_w; // cursor position (column) } mir; struct { // escape code control diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index 561a72284b..cd79a40134 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -26,6 +26,7 @@ static void _term_read_cb(uv_stream_t* tcp_u, ssize_t siz_i, const uv_buf_t* buf_u); static c3_i _term_tcsetattr(c3_i, c3_i, const struct termios*); +static void _term_it_send_stub(u3_utty* uty_u, u3_noun tub); /* _write(): retry interrupts, continue partial writes, assert errors. */ @@ -175,8 +176,7 @@ u3_term_log_init(void) // Initialize mirror and accumulator state. // { - uty_u->tat_u.mir.lin_w = 0; - uty_u->tat_u.mir.wor_w = 0; + uty_u->tat_u.mir.lin = u3_nul; uty_u->tat_u.mir.rus_w = 0; uty_u->tat_u.mir.cus_w = 0; @@ -416,14 +416,13 @@ _term_it_send_csi(u3_utty *uty_u, c3_c cmd_c, c3_w num_w, ...) va_end(ap); } -/* _term_it_free_line(): wipe line stored by _term_it_save_line +/* _term_it_free_line(): wipe line stored by _term_it_save_stub */ static void _term_it_free_line(u3_utty* uty_u) { - c3_free(uty_u->tat_u.mir.lin_w); - uty_u->tat_u.mir.lin_w = 0; - uty_u->tat_u.mir.wor_w = 0; + u3z(uty_u->tat_u.mir.lin); + uty_u->tat_u.mir.lin = u3_nul; } /* _term_it_clear_line(): clear line of cursor @@ -518,80 +517,37 @@ _term_it_show_line(u3_utty* uty_u, c3_w* lin_w, c3_w wor_w) _term_it_dump_buf(uty_u, &uty_u->ufo_u.ruc_u); } -/* _term_it_restore_line(): refresh current line. +/* _term_it_restore_line(): re-render original line at bottom of screen */ static void _term_it_restore_line(u3_utty* uty_u) { u3_utat* tat_u = &uty_u->tat_u; - c3_w* lin_w = tat_u->mir.lin_w; - c3_w wor_w = tat_u->mir.wor_w; - if ( (0 != lin_w) && (0 < wor_w) ) { - // we have to reallocate the current line on write, - // or we have a data race if a) the write is async, - // and b) a new output line arrives before the write completes. - // also, _show_line would free it. - // - c3_w* hun_w = c3_malloc( sizeof(c3_w) * wor_w ); - memcpy(hun_w, lin_w, wor_w * sizeof(c3_w)); - - _term_it_send_csi(uty_u, 'H', 2, tat_u->siz.row_l, 0); - _term_it_dump_buf(uty_u, &uty_u->ufo_u.cel_u); - _term_it_show_line(uty_u, hun_w, wor_w); - } + _term_it_send_csi(uty_u, 'H', 2, tat_u->siz.row_l, 0); + _term_it_dump_buf(uty_u, &uty_u->ufo_u.cel_u); + _term_it_send_stub(uty_u, u3k(tat_u->mir.lin)); + //NOTE send_stub restores cursor position } -/* _term_it_save_line(): store line if relevant to internal logic - * RETAINs lin_w +/* _term_it_save_stub(): store line if relevant to internal logic */ static void -_term_it_save_line(u3_utty* uty_u, c3_w* lin_w, c3_w wor_w) +_term_it_save_stub(u3_utty* uty_u, u3_noun tub) { u3_utat* tat_u = &uty_u->tat_u; + u3_noun lin = tat_u->mir.lin; // keep track of changes to bottom-most line, to aid spinner drawing logic. // -t mode doesn't need this logic, because it doesn't render the spinner. // if ( (0 == tat_u->mir.rus_w) && (c3n == u3_Host.ops_u.tem)) { - c3_w* nip_w = tat_u->mir.lin_w; - c3_w wod_w = tat_u->mir.wor_w; - c3_w off_w = tat_u->mir.cus_w; - c3_w wyd_w = off_w + wor_w; - - // if we have no buffer, make one - // - if ( 0 == nip_w ) { - nip_w = c3_malloc( sizeof(c3_w) * wyd_w ); - wod_w = wyd_w; - - // initialize offset with spaces - // - for ( c3_w i_w = 0; i_w < off_w; i_w++ ) { - nip_w[i_w] = ' '; - } - } - // if we have a buffer, but it's too short, make a bigger one - // - else if ( wyd_w > wod_w ) { - c3_w* nic_w = c3_malloc( sizeof(c3_w) * wyd_w ); - memcpy(nic_w, nip_w, wod_w); - - // initialize fresh offset with spaces - // - for ( c3_w i_w = wod_w; i_w < off_w; i_w++ ) { - nic_w[i_w] = ' '; - } - - c3_free(nip_w); - nip_w = nic_w; - wod_w = wyd_w; - } - - memcpy(nip_w + off_w, lin_w, sizeof(c3_w) * wor_w); - tat_u->mir.lin_w = nip_w; - tat_u->mir.wor_w = wod_w; + lin = u3dq("wail:klr:format", lin, tat_u->mir.cus_w, u3k(tub), ' '); + lin = u3do("pact:klr:format", lin); } + + tat_u->mir.lin = lin; + u3z(tub); } /* _term_it_show_nel(): render newline, moving cursor down @@ -1262,10 +1218,10 @@ _term_it_put_deco(c3_w* lin_w, } } -/* _term_it_show_stub(): send styled text to terminal as ansi escape sequences +/* _term_it_send_stub(): send styled text, without saving */ static void -_term_it_show_stub(u3_utty* uty_u, +_term_it_send_stub(u3_utty* uty_u, u3_noun tub) { c3_w tuc_w = u3qb_lent(tub); @@ -1376,12 +1332,21 @@ _term_it_show_stub(u3_utty* uty_u, } } - _term_it_save_line(uty_u, lin_w, i_w); _term_it_show_line(uty_u, lin_w, i_w); u3z(tub); } +/* _term_it_send_stub(): send styled text to terminal as ansi escape sequences +*/ +static void +_term_it_show_stub(u3_utty* uty_u, + u3_noun tub) +{ + _term_it_send_stub(uty_u, u3k(tub)); + _term_it_save_stub(uty_u, tub); +} + /* _term_it_show_tour(): send utf32 to terminal. */ static void @@ -1399,10 +1364,14 @@ _term_it_show_tour(u3_utty* uty_u, } } - _term_it_save_line(uty_u, lin_w, len_w); _term_it_show_line(uty_u, lin_w, len_w); - u3z(lin); + { + u3_noun tub = u3i_list(u3nc(u3nt(u3_nul, u3_nul, u3_nul), lin), u3_none); + _term_it_save_stub(uty_u, tub); + } + + //NOTE lin transferred to tub above } /* _term_ef_blit(): send blit to terminal. From d1fba5d740bdfaa2b9d0fa84019b5352e91552be Mon Sep 17 00:00:00 2001 From: fang Date: Tue, 20 Apr 2021 22:45:45 +0200 Subject: [PATCH 066/104] kh: correctly (re)store styled lines We weren't accounting for the cursor column when storing output, nor accounting for styled contents properly. See also a8de23ca9 for the equivalent change in Vere. --- pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs | 54 ++++++++++++++++++------ 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs b/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs index 248cb6ce23..91f683fc03 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs @@ -45,7 +45,7 @@ import qualified Urbit.Vere.Term.Render as T -- | All stateful data in the printing to stdOutput. data LineState = LineState - { lsLine :: Text + { lsLine :: [(Stye, [Char])] , lsCurPos :: CurPos , lsSpinTimer :: Maybe (Async ()) , lsSpinCause :: Maybe Text @@ -288,7 +288,7 @@ localClient doneSignal = fst <$> mkRAcquire start stop currentTime <- io $ now loop termSizeVar - (LineState "" (CurPos 0 0) Nothing Nothing True 0 currentTime) + (LineState [] (CurPos 0 0) Nothing Nothing True 0 currentTime) where writeBlank :: LineState -> RIO e LineState writeBlank ls = do @@ -464,15 +464,44 @@ localClient doneSignal = fst <$> mkRAcquire start stop styled = mconcat [escape, styles, "m", tape, escape, "0m"] + bareStub :: [Char] -> [(Stye, [Char])] + bareStub c = [(Stye (setToHoonSet mempty) TintNull TintNull, c)] + + -- overwrite substring of base with put, starting at index + overwriteStub :: [(Stye, [Char])] -> Int -> [(Stye, [Char])] -> [(Stye, [Char])] + overwriteStub base index put = + scagStub index base + ++ ( let l = lentStub base in + if index <= l then [] + else bareStub $ take (index - l) [' ',' '..] + ) + ++ put + ++ slagStub (index + lentStub put) base + where + lentStub :: [(Stye, [Char])] -> Int + lentStub s = sum $ map (length . snd) s + + scagStub :: Int -> [(Stye, [Char])] -> [(Stye, [Char])] + scagStub 0 _ = [] + scagStub _ [] = [] + scagStub i ((y,c):s) = + (y, take i c) : scagStub (i - min i (length c)) s + + slagStub :: Int -> [(Stye, [Char])] -> [(Stye, [Char])] + slagStub 0 s = s + slagStub _ [] = [] + slagStub i ((y,c):s) + | i > l = slagStub (i - l) s + | otherwise = (y, drop i c) : s + where l = length c + -- Displays styled text at the cursor termShowStub :: LineState -> Stub -> RIO e LineState - termShowStub ls@LineState{lsCurPos} (Stub s) = do - let outText = pack $ mconcat $ fmap (uncurry termRenderStubSegment) s - putStr outText + termShowStub ls@LineState{lsCurPos, lsLine} (Stub s) = do + putStr $ pack $ mconcat $ fmap (uncurry termRenderStubSegment) s T.cursorRestore case row lsCurPos of - 0 -> --TODO offset by col - pure ls { lsLine = outText } + 0 -> pure ls { lsLine = overwriteStub lsLine (col lsCurPos) s } _ -> pure ls -- Moves the cursor to the requested position @@ -485,12 +514,11 @@ localClient doneSignal = fst <$> mkRAcquire start stop -- Displays and sets the current line termShowLine :: LineState -> Text -> RIO e LineState - termShowLine ls@LineState{lsCurPos} newStr = do + termShowLine ls@LineState{lsCurPos, lsLine} newStr = do putStr newStr T.cursorRestore case row lsCurPos of - 0 -> --TODO offset by col - pure ls { lsLine = newStr } + 0 -> pure ls { lsLine = overwriteStub lsLine (col lsCurPos) (bareStub $ unpack newStr) } _ -> pure ls termShowClear :: LineState -> RIO e LineState @@ -499,7 +527,7 @@ localClient doneSignal = fst <$> mkRAcquire start stop T.clearLine T.cursorRestore case row lsCurPos of - 0 -> pure ls { lsLine = "" } + 0 -> pure ls { lsLine = [] } _ -> pure ls -- New Current Line @@ -507,7 +535,7 @@ localClient doneSignal = fst <$> mkRAcquire start stop termShowNewline ls@LineState{lsCurPos} = do putStr "\r\n" case row lsCurPos of - 0 -> pure ls { lsLine = "", lsCurPos = lsCurPos { col = 0 } } + 0 -> pure ls { lsLine = [], lsCurPos = lsCurPos { col = 0 } } r -> pure ls { lsCurPos = CurPos (r-1) 0 } -- Redraw the bottom LineState, maintaining the current curpos @@ -516,7 +544,7 @@ localClient doneSignal = fst <$> mkRAcquire start stop TermSize _ h <- readTVarIO ts T.cursorMove (fromIntegral h - 1) 0 T.clearLine - putStr lsLine + putStr $ pack $ mconcat $ fmap (uncurry termRenderStubSegment) lsLine T.cursorRestore -- ring my bell From ba3a62f95864ac703424da5bc56ba0190f31588e Mon Sep 17 00:00:00 2001 From: fang Date: Wed, 21 Apr 2021 00:50:11 +0200 Subject: [PATCH 067/104] zuse: fix off-by-one in +wail:klr:format --- bin/ivory.pill | 4 ++-- pkg/arvo/sys/zuse.hoon | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/ivory.pill b/bin/ivory.pill index b1f14b13ec..5bd9621166 100644 --- a/bin/ivory.pill +++ b/bin/ivory.pill @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2800e4ff87369d6206daa96937d8a186a12da67aac2ab8cd74c6c359f26cddb8 -size 3952579 +oid sha256:a1d3154858e1eaa9ab48dfe3ff24cfe1994e7e96379d1fd9cd971df4939ce220 +size 3952575 diff --git a/pkg/arvo/sys/zuse.hoon b/pkg/arvo/sys/zuse.hoon index 6bbe3ebd25..91bb82b769 100644 --- a/pkg/arvo/sys/zuse.hoon +++ b/pkg/arvo/sys/zuse.hoon @@ -3791,7 +3791,7 @@ (scag b a) :: =+ e=(lent-char a) - ?: (lth b e) ~ + ?: (lte b e) ~ [*stye (reap (sub b e) d)]~ :: c From f06471cb31f58de928f541287ee4a2154ae79a09 Mon Sep 17 00:00:00 2001 From: ~locpyl-tidnyd Date: Thu, 1 Apr 2021 13:18:38 +0000 Subject: [PATCH 068/104] vere: pipe serf stderr back to lord When uv_spawn creates a process and any standard fds are set to UV_INHERIT_FD, it ignores UV_PROCESS_WINDOWS_HIDE flags, and worker console pops up in -d mode. --- pkg/urbit/include/vere/vere.h | 1 + pkg/urbit/vere/lord.c | 47 +++++++++++++++++++++++++++++++++-- pkg/urbit/worker/main.c | 5 ++++ 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/pkg/urbit/include/vere/vere.h b/pkg/urbit/include/vere/vere.h index f17fd12ad7..2bc7d26c10 100644 --- a/pkg/urbit/include/vere/vere.h +++ b/pkg/urbit/include/vere/vere.h @@ -461,6 +461,7 @@ time_t wen_t; // process creation time u3_mojo inn_u; // client's stdin u3_moat out_u; // client's stdout + uv_pipe_t err_u; // client's stderr c3_w wag_w; // config flags c3_c* bin_c; // binary path c3_c* pax_c; // directory diff --git a/pkg/urbit/vere/lord.c b/pkg/urbit/vere/lord.c index 20fa660e54..6a81de2ab4 100644 --- a/pkg/urbit/vere/lord.c +++ b/pkg/urbit/vere/lord.c @@ -157,6 +157,8 @@ _lord_stop(u3_lord* god_u) u3_newt_moat_stop(&god_u->out_u, _lord_stop_cb); u3_newt_mojo_stop(&god_u->inn_u, _lord_bail_noop); + uv_read_stop((uv_stream_t*)&(god_u->err_u)); + uv_close((uv_handle_t*)&god_u->cub_u, 0); #if defined(LORD_TRACE_JAM) || defined(LORD_TRACE_CUE) @@ -1044,6 +1046,42 @@ u3_lord_halt(u3_lord* god_u) _lord_stop(god_u); } +/* _lord_serf_err_alloc(): libuv buffer allocator. +*/ +static void +_lord_serf_err_alloc(uv_handle_t* had_u, size_t len_i, uv_buf_t* buf) +{ + // error/info messages as a rule don't exceed one line + // + *buf = uv_buf_init(c3_malloc(80), 80); +} + +/* _lord_on_serf_err_cb(): subprocess stderr callback. +*/ +static void +_lord_on_serf_err_cb(uv_stream_t* pyp_u, + ssize_t siz_i, + const uv_buf_t* buf_u) +{ + if ( siz_i >= 0 ) { + // serf used to write to 2 directly + // this can't be any worse than that + // + u3_write_fd(2, buf_u->base, siz_i); + } else { + uv_read_stop(pyp_u); + + if ( siz_i != UV_EOF ) { + u3l_log("lord: serf stderr: %s\r\n", uv_strerror(siz_i)); + } + } + + if ( buf_u->base != NULL ) { + c3_free(buf_u->base); + } +} + + /* _lord_on_serf_exit(): handle subprocess exit. */ static void @@ -1156,6 +1194,7 @@ u3_lord_init(c3_c* pax_c, c3_w wag_w, c3_d key_d[4], u3_lord_cb cb_u) uv_pipe_init(u3L, &god_u->inn_u.pyp_u, 0); uv_timer_init(u3L, &god_u->out_u.tim_u); uv_pipe_init(u3L, &god_u->out_u.pyp_u, 0); + uv_pipe_init(u3L, &god_u->err_u, 0); god_u->cod_u[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE; god_u->cod_u[0].data.stream = (uv_stream_t *)&god_u->inn_u; @@ -1163,12 +1202,14 @@ u3_lord_init(c3_c* pax_c, c3_w wag_w, c3_d key_d[4], u3_lord_cb cb_u) god_u->cod_u[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; god_u->cod_u[1].data.stream = (uv_stream_t *)&god_u->out_u; - god_u->cod_u[2].flags = UV_INHERIT_FD; - god_u->cod_u[2].data.fd = 2; + god_u->cod_u[2].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; + god_u->cod_u[2].data.stream = (uv_stream_t *)&god_u->err_u; god_u->ops_u.stdio = god_u->cod_u; god_u->ops_u.stdio_count = 3; + // if any fds are inherited, libuv ignores UV_PROCESS_WINDOWS_HIDE* + god_u->ops_u.flags = UV_PROCESS_WINDOWS_HIDE; god_u->ops_u.exit_cb = _lord_on_serf_exit; god_u->ops_u.file = arg_c[0]; god_u->ops_u.args = arg_c; @@ -1178,6 +1219,8 @@ u3_lord_init(c3_c* pax_c, c3_w wag_w, c3_d key_d[4], u3_lord_cb cb_u) return 0; } + + uv_read_start((uv_stream_t *)&god_u->err_u, _lord_serf_err_alloc, _lord_on_serf_err_cb); } #if defined(LORD_TRACE_JAM) || defined(LORD_TRACE_CUE) diff --git a/pkg/urbit/worker/main.c b/pkg/urbit/worker/main.c index 46895f093b..9c37fd5d3d 100644 --- a/pkg/urbit/worker/main.c +++ b/pkg/urbit/worker/main.c @@ -155,6 +155,11 @@ _cw_serf_stdio(c3_i* inn_i, c3_i* out_i) dup2(2, 1); close(nul_i); + + // set stream I/O to unbuffered because it's now a pipe not a console + // + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); } /* _cw_serf_stdio(): cleanup on serf exit. From 0ddde0b0d6d46789e20863acc0d203bbfc865a55 Mon Sep 17 00:00:00 2001 From: ~locpyl-tidnyd Date: Mon, 29 Mar 2021 12:14:59 +0000 Subject: [PATCH 069/104] vere: export term.c:_write() as u3_write_fd(), use in dprintf() replacement --- pkg/urbit/include/vere/vere.h | 4 ++++ pkg/urbit/vere/io/term.c | 10 +++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/pkg/urbit/include/vere/vere.h b/pkg/urbit/include/vere/vere.h index 2bc7d26c10..8cf4567113 100644 --- a/pkg/urbit/include/vere/vere.h +++ b/pkg/urbit/include/vere/vere.h @@ -1364,6 +1364,10 @@ void u3_king_grab(void* ptr_v); + /* u3_write_fd(): retry interrupts, continue partial writes, assert errors. + */ + void + u3_write_fd(c3_i fid_i, const void* buf_v, size_t len_i); c3_w u3_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result); diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index cd79a40134..e204628676 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -28,10 +28,10 @@ static void _term_read_cb(uv_stream_t* tcp_u, static c3_i _term_tcsetattr(c3_i, c3_i, const struct termios*); static void _term_it_send_stub(u3_utty* uty_u, u3_noun tub); -/* _write(): retry interrupts, continue partial writes, assert errors. +/* u3_write_fd(): retry interrupts, continue partial writes, assert errors. */ -static void -_write(c3_i fid_i, const void* buf_v, size_t len_i) +void +u3_write_fd(c3_i fid_i, const void* buf_v, size_t len_i) { ssize_t ret_i; @@ -55,7 +55,7 @@ _write(c3_i fid_i, const void* buf_v, size_t len_i) // assert on true errors // - // NB: can't call u3l_log here or we would re-enter _write() + // NB: can't call u3l_log here or we would re-enter u3_write_fd() // if ( ret_i < 0 ) { fprintf(stderr, "term: write failed %s\r\n", strerror(errno)); @@ -253,7 +253,7 @@ u3_term_log_exit(void) if ( -1 == fcntl(uty_u->fid_i, F_SETFL, uty_u->cug_i) ) { c3_assert(!"exit-fcntl"); } - _write(uty_u->fid_i, "\r\n", 2); + u3_write_fd(uty_u->fid_i, "\r\n", 2); } } From 9d6db9baafe9e75b04f54a3376d6c0b04607d5da Mon Sep 17 00:00:00 2001 From: fang Date: Fri, 23 Apr 2021 19:52:17 +0200 Subject: [PATCH 070/104] term: fix ci output somehow During CI (specifically, urbit-tests), slogs and printf output would get interleaved, sometimes intermingling, mangling the resulting output. Best guess is this happens because of something weird we're doing with regards to pushing output. Additional scatter-shot fflush calls solve this. The fix herein also solves this. Unclear why, considering this commit should result in identical behavior for the -t case. Here be dragons. --- pkg/urbit/include/vere/vere.h | 2 +- pkg/urbit/vere/io/http.c | 10 ++++++---- pkg/urbit/vere/io/term.c | 14 +++++++------- pkg/urbit/vere/king.c | 2 +- pkg/urbit/vere/pier.c | 2 +- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/pkg/urbit/include/vere/vere.h b/pkg/urbit/include/vere/vere.h index 8cf4567113..1ea1627309 100644 --- a/pkg/urbit/include/vere/vere.h +++ b/pkg/urbit/include/vere/vere.h @@ -1084,7 +1084,7 @@ /* u3_term_io_loja(): release console from cooked print. */ void - u3_term_io_loja(int x); + u3_term_io_loja(int x, FILE* f); /* u3_term_log_init(): initialize terminal for logging */ diff --git a/pkg/urbit/vere/io/http.c b/pkg/urbit/vere/io/http.c index 973e0c763d..7d20fe4de8 100644 --- a/pkg/urbit/vere/io/http.c +++ b/pkg/urbit/vere/io/http.c @@ -1559,8 +1559,9 @@ _http_init_tls(uv_buf_t key_u, uv_buf_t cer_u) if( 0 == sas_i ) { u3l_log("http: load private key failed:"); - ERR_print_errors_fp(u3_term_io_hija()); - u3_term_io_loja(1); + FILE* fil_u = u3_term_io_hija(); + ERR_print_errors_fp(fil_u); + u3_term_io_loja(1, fil_u); SSL_CTX_free(tls_u); @@ -1577,8 +1578,9 @@ _http_init_tls(uv_buf_t key_u, uv_buf_t cer_u) if( 0 == sas_i ) { u3l_log("http: load certificate failed:"); - ERR_print_errors_fp(u3_term_io_hija()); - u3_term_io_loja(1); + FILE* fil_u = u3_term_io_hija(); + ERR_print_errors_fp(fil_u); + u3_term_io_loja(1,fil_u); BIO_free(bio_u); SSL_CTX_free(tls_u); diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index e204628676..10adf75d95 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -1527,7 +1527,7 @@ u3_term_io_hija(void) /* u3_term_io_loja(): release console from fprintf. */ void -u3_term_io_loja(int x) +u3_term_io_loja(int x, FILE* f) { u3_utty* uty_u = _term_main(); @@ -1540,8 +1540,8 @@ u3_term_io_loja(int x) } else { if ( c3y == u3_Host.ops_u.tem ) { - fprintf(stdout, "\n"); - fflush(stdout); + fprintf(f, "\n"); + fflush(f); } else { if ( 0 != _term_tcsetattr(1, TCSADRAIN, &uty_u->raw_u) ) { @@ -1570,7 +1570,7 @@ u3_term_io_loja(int x) } } else { - fprintf(stdout, "\r\n"); + fprintf(f, "\r\n"); } } @@ -1582,7 +1582,7 @@ u3_term_io_log(c3_c* line) FILE* stream = u3_term_io_hija(); int x = fprintf(stream, "%s", line); fflush(stream); - u3_term_io_loja(x); //TODO remove arg? unused... + u3_term_io_loja(x, stream); //TODO remove arg? unused... } /* u3_term_tape_to(): dump a tape to a file. @@ -1614,7 +1614,7 @@ u3_term_tape(u3_noun tep) u3_term_tape_to(fil_f, tep); - u3_term_io_loja(0); + u3_term_io_loja(0, fil_f); } /* u3_term_wall(): dump a wall to stdout. @@ -1633,7 +1633,7 @@ u3_term_wall(u3_noun wol) wal = u3t(wal); } - u3_term_io_loja(0); + u3_term_io_loja(0, fil_f); u3z(wol); } diff --git a/pkg/urbit/vere/king.c b/pkg/urbit/vere/king.c index 3f9d453cc4..040d34004b 100644 --- a/pkg/urbit/vere/king.c +++ b/pkg/urbit/vere/king.c @@ -938,7 +938,7 @@ u3_king_grab(void* vod_p) } #else { - u3_term_io_loja(0); + u3_term_io_loja(0, fil_u); } #endif } diff --git a/pkg/urbit/vere/pier.c b/pkg/urbit/vere/pier.c index 113164c4cb..27f362397c 100644 --- a/pkg/urbit/vere/pier.c +++ b/pkg/urbit/vere/pier.c @@ -2270,7 +2270,7 @@ u3_pier_tank(c3_l tab_l, c3_w pri_w, u3_noun tac) fflush(fil_u); - u3_term_io_loja(0); + u3_term_io_loja(0, fil_u); u3z(blu); u3z(tac); } From 9c0bae654b85c7b05d47c06f19277c3c92ff57d0 Mon Sep 17 00:00:00 2001 From: fang Date: Mon, 26 Apr 2021 17:01:24 +0200 Subject: [PATCH 071/104] webterm: include herm tasks in term api --- pkg/interface/src/logic/api/term.ts | 24 +++++++++++++++++++++-- pkg/interface/src/views/apps/term/app.tsx | 2 +- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/pkg/interface/src/logic/api/term.ts b/pkg/interface/src/logic/api/term.ts index 7d86c4d415..b5e6755a2f 100644 --- a/pkg/interface/src/logic/api/term.ts +++ b/pkg/interface/src/logic/api/term.ts @@ -14,8 +14,28 @@ export type Belt = | { mod: { mod: 'ctl' | 'met' | 'hyp', key: Bolt } } | { txt: Array }; +export type Task = + | { belt: Belt } + | { blew: { w: number, h: number } } + | { flow: { term: string, apps: Array<{ who: string, app: string }> } } + | { hail: null } + | { hook: null } + export default class TermApi extends BaseApi { - public sendBelt(belt: Belt) { - return this.action('herm', 'belt', belt); + public sendBelt(session: string, belt: Belt) { + if (session === '') { + //TODO remove? reduntant, probably minimal perf gains + return this.action('herm', 'belt', belt); + } else { + return this.sendTask(session, { 'belt': belt }); + } + } + + public sendTask(session: string, task: Task) { + return this.action('herm', 'herm-task', { 'session': session, ...task }); + } + + public getSessions(): Promise> { + return this.scry>('herm', '/sessions'); } } diff --git a/pkg/interface/src/views/apps/term/app.tsx b/pkg/interface/src/views/apps/term/app.tsx index 6469b040d4..fb830b6785 100644 --- a/pkg/interface/src/views/apps/term/app.tsx +++ b/pkg/interface/src/views/apps/term/app.tsx @@ -329,7 +329,7 @@ export default function TermApp(props: TermAppProps) { strap = ''; } belts.map(b => { //NOTE passing api.term.sendBelt makes `this` undefined! - api.term.sendBelt(b); + api.term.sendBelt(ses, b); }); }, [sessions, api.term]); From a13f19d6f973169951a8cf43dc5cfa49a472ad97 Mon Sep 17 00:00:00 2001 From: fang Date: Tue, 27 Apr 2021 22:52:38 +0200 Subject: [PATCH 072/104] webterm: send %blew on resize Also tweaks the layout a little bit to maintain consistency throughout resizing. --- pkg/interface/src/views/apps/term/app.tsx | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/pkg/interface/src/views/apps/term/app.tsx b/pkg/interface/src/views/apps/term/app.tsx index fb830b6785..d1d27d5d29 100644 --- a/pkg/interface/src/views/apps/term/app.tsx +++ b/pkg/interface/src/views/apps/term/app.tsx @@ -333,14 +333,21 @@ export default function TermApp(props: TermAppProps) { }); }, [sessions, api.term]); + const onResize = useCallback(() => { + //TODO debounce, if it ever becomes a problem + sessions[selected].fit.fit(); + }, [sessions, selected]); + // on-init, open slogstream // useEffect(() => { setupSlog(); + window.addEventListener('resize', onResize); return () => { //TODO clean up subs? + window.removeEventListener('resize', onResize); }; - }, []); + }, [onResize]); // on dark mode change, change terminals' theme // @@ -377,7 +384,9 @@ export default function TermApp(props: TermAppProps) { // term.onData((e) => onInput(selected, e)); term.onBinary((e) => onInput(selected, e)); - //TODO term.onResize + term.onResize((e) => { + api.term.sendTask(selected, { blew: { w: e.cols, h: e.rows } }); + }); ses = { term, fit }; @@ -401,7 +410,7 @@ export default function TermApp(props: TermAppProps) { if (container.current && !container.current.contains(ses.term.element || null)) { ses.term.open(container.current); - ses.fit.fit(); //TODO if not default, send %blew + ses.fit.fit(); ses.term.focus(); } @@ -421,16 +430,17 @@ export default function TermApp(props: TermAppProps) { From aa244a10ea4e83043799302e3c518ef37be6a54c Mon Sep 17 00:00:00 2001 From: fang Date: Wed, 28 Apr 2021 00:11:02 +0200 Subject: [PATCH 073/104] webterm: improve slogstream management Don't re-open the slog eventsource every time we navigate to webterm. --- pkg/interface/src/logic/state/term.ts | 4 +++- pkg/interface/src/views/apps/term/app.tsx | 8 +++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/pkg/interface/src/logic/state/term.ts b/pkg/interface/src/logic/state/term.ts index a0a7d81ad0..ceaf257c93 100644 --- a/pkg/interface/src/logic/state/term.ts +++ b/pkg/interface/src/logic/state/term.ts @@ -9,11 +9,13 @@ type Sessions = { [id: string]: Session; } export interface TermState extends BaseState { sessions: Sessions, selected: string, + slogstream: null | EventSource, }; const useTermState = createState('Term', { sessions: {}, selected: '', // empty string is default session -}, ['sessions']); //TODO consider persisting + slogstream: null, +}, ['sessions', 'slogstream']); //TODO consider persisting export default useTermState; \ No newline at end of file diff --git a/pkg/interface/src/views/apps/term/app.tsx b/pkg/interface/src/views/apps/term/app.tsx index d1d27d5d29..c57b79c424 100644 --- a/pkg/interface/src/views/apps/term/app.tsx +++ b/pkg/interface/src/views/apps/term/app.tsx @@ -128,7 +128,7 @@ export default function TermApp(props: TermAppProps) { const container = useRef(null); //TODO allow switching of selected - const { sessions, selected, set } = useTermState(); + const { sessions, selected, slogstream, set } = useTermState(); const osDark = useLocalState((state) => state.dark); const theme = useSettingsState(s => s.display.theme); @@ -246,6 +246,8 @@ export default function TermApp(props: TermAppProps) { }, 10000); } } + + set(state => { state.slogstream = slog }); }, [onSlog]); const onInput = useCallback((ses: string, e: string) => { @@ -341,13 +343,13 @@ export default function TermApp(props: TermAppProps) { // on-init, open slogstream // useEffect(() => { - setupSlog(); + if (!slogstream) setupSlog(); window.addEventListener('resize', onResize); return () => { //TODO clean up subs? window.removeEventListener('resize', onResize); }; - }, [onResize]); + }, [onResize, setupSlog]); // on dark mode change, change terminals' theme // From 52512ed4d422dc5ed56d27e10efc08fee191b673 Mon Sep 17 00:00:00 2001 From: fang Date: Wed, 28 Apr 2021 14:17:30 +0200 Subject: [PATCH 074/104] herm: factor mark conversion logic into lib --- pkg/arvo/lib/dill.hoon | 93 +++++++++++++++++++++++++++++++++++++ pkg/arvo/mar/belt.hoon | 36 ++------------ pkg/arvo/mar/blit.hoon | 50 ++------------------ pkg/arvo/mar/herm/task.hoon | 36 +------------- 4 files changed, 101 insertions(+), 114 deletions(-) create mode 100644 pkg/arvo/lib/dill.hoon diff --git a/pkg/arvo/lib/dill.hoon b/pkg/arvo/lib/dill.hoon new file mode 100644 index 0000000000..d4cecdf142 --- /dev/null +++ b/pkg/arvo/lib/dill.hoon @@ -0,0 +1,93 @@ +:: dill: utilities for dill's data structures +:: +=, dill +|% +++ enjs + |% + ++ blit + |= =blit:dill + ^- json + =, enjs:format + %+ frond -.blit + ?- -.blit + %bel b+& + %clr b+& + %hop ?@ p.blit (numb p.blit) + (pairs 'r'^(numb r.p.blit) 'c'^(numb c.p.blit) ~) + %put a+(turn p.blit |=(c=@c s+(tuft c))) + %nel b+& + %url s+p.blit + %wyp b+& + :: + %sag + %- pairs + :~ 'path'^(path p.blit) + 'file'^s+(en:base64:mimes:html (as-octs:mimes:html (jam q.blit))) + == + :: + %sav + %- pairs + :~ 'path'^(path p.blit) + 'file'^s+(en:base64:mimes:html (as-octs:mimes:html q.blit)) + == + :: + %klr + :- %a + %+ turn p.blit + |= [=stye text=(list @c)] + %- pairs + :~ 'text'^a+(turn text |=(c=@c s+(tuft c))) + :: + :- 'stye' + %- pairs + |^ :~ 'back'^(color p.q.stye) + 'fore'^(color q.q.stye) + 'deco'^a+(turn ~(tap in p.stye) |=(d=deco ?~(d ~ s+d))) + == + ++ color + |= =tint + ?@ tint ?~(tint ~ s+tint) + =, tint + (pairs r+(numb r) g+(numb g) b+(numb b) ~) + -- + == + == + -- +:: +++ dejs + |% + ++ belt + |= jon=json + ^- belt:dill + ?: ?=([%s *] jon) + (taft p.jon) + =, dejs:format + %. jon + %- of + |^ :* mod+(ot 'mod'^mod 'key'^bot ~) + txt+(ar (cu taft so)) + bol + == + :: + ++ bol + :~ aro+(su (perk %d %l %r %u ~)) + bac+ul + del+ul + hit+(ot 'r'^ni 'c'^ni ~) + ret+ul + == + :: + ++ bot + |= j=json + ^- bolt:dill + ?+ j !! + [%s *] (taft p.j) + [%o *] ((of bol) j) + == + :: + ++ mod + |= j=json + ((su (perk %ctl %met %hyp ~)) j) + -- + -- +-- \ No newline at end of file diff --git a/pkg/arvo/mar/belt.hoon b/pkg/arvo/mar/belt.hoon index 949f5aece7..acbf284c94 100644 --- a/pkg/arvo/mar/belt.hoon +++ b/pkg/arvo/mar/belt.hoon @@ -1,5 +1,7 @@ :: belt: runtime belt structure :: +/+ dill +:: |_ =belt:dill ++ grad %noun :: +grab: convert from @@ -7,39 +9,7 @@ ++ grab |% ++ noun belt:dill - ++ json - |= jon=^json - ^- belt:dill - ?: ?=([%s *] jon) - (taft p.jon) - =, dejs:format - %. jon - %- of - |^ :* mod+(ot 'mod'^mod 'key'^bot ~) - txt+(ar (cu taft so)) - bol - == - :: - ++ bol - :~ aro+(su (perk %d %l %r %u ~)) - bac+ul - del+ul - hit+(ot 'r'^ni 'c'^ni ~) - ret+ul - == - :: - ++ bot - |= j=json - ^- bolt:dill - ?+ j !! - [%s *] (taft p.j) - [%o *] ((of bol) j) - == - :: - ++ mod - |= j=json - ((su (perk %ctl %met %hyp ~)) j) - -- + ++ json belt:dejs:dill -- :: +grow: convert to :: diff --git a/pkg/arvo/mar/blit.hoon b/pkg/arvo/mar/blit.hoon index 232c8021a9..4b852aa606 100644 --- a/pkg/arvo/mar/blit.hoon +++ b/pkg/arvo/mar/blit.hoon @@ -1,5 +1,7 @@ :: blit: runtime blit structure :: +/+ dill +:: |_ =blit:dill ++ grad %noun :: +grab: convert from @@ -13,52 +15,6 @@ ++ grow |% ++ noun blit - ++ json - ^- ^json - =, enjs:format - %+ frond -.blit - ?- -.blit - %bel b+& - %clr b+& - %hop ?@ p.blit (numb p.blit) - (pairs 'r'^(numb r.p.blit) 'c'^(numb c.p.blit) ~) - %put a+(turn p.blit |=(c=@c s+(tuft c))) - %nel b+& - %url s+p.blit - %wyp b+& - :: - %sag - %- pairs - :~ 'path'^(path p.blit) - 'file'^s+(en:base64:mimes:html (as-octs:mimes:html (jam q.blit))) - == - :: - %sav - %- pairs - :~ 'path'^(path p.blit) - 'file'^s+(en:base64:mimes:html (as-octs:mimes:html q.blit)) - == - :: - %klr - :- %a - %+ turn p.blit - |= [=stye text=(list @c)] - %- pairs - :~ 'text'^a+(turn text |=(c=@c s+(tuft c))) - :: - :- 'stye' - %- pairs - |^ :~ 'back'^(color p.q.stye) - 'fore'^(color q.q.stye) - 'deco'^a+(turn ~(tap in p.stye) |=(d=deco ?~(d ~ s+d))) - == - ++ color - |= =tint - ?@ tint ?~(tint ~ s+tint) - =, tint - (pairs r+(numb r) g+(numb g) b+(numb b) ~) - -- - == - == + ++ json (blit:enjs:dill blit) -- -- diff --git a/pkg/arvo/mar/herm/task.hoon b/pkg/arvo/mar/herm/task.hoon index b147630fbd..93757418ec 100644 --- a/pkg/arvo/mar/herm/task.hoon +++ b/pkg/arvo/mar/herm/task.hoon @@ -1,7 +1,7 @@ :: task: herm task for passthrough to dill -::TODO deduplicate with /mar/belt, or remove one or the other :: /- herm +/+ dill :: |_ =task:herm ++ grad %noun @@ -26,7 +26,7 @@ |^ task ++ task %- of - :~ belt+belt + :~ belt+belt:dejs:^dill blew+(ot 'w'^ni 'h'^ni ~) hail+ul open+(ot 'term'^(se %tas) 'apps'^(ar gill) ~) @@ -35,38 +35,6 @@ :: ++ gill (ot 'who'^(se %p) 'app'^(se %tas) ~) - :: - ++ belt - |= j=json - ^- belt:dill - ?: ?=([%s *] j) - (taft p.j) - %. j - %- of - :* mod+(ot 'mod'^mod 'key'^bot ~) - txt+(ar (cu taft so)) - bol - == - :: - ++ bol - :~ aro+(su (perk %d %l %r %u ~)) - bac+ul - del+ul - hit+(ot 'r'^ni 'c'^ni ~) - ret+ul - == - :: - ++ bot - |= j=json - ^- bolt:dill - ?+ j !! - [%s *] (taft p.j) - [%o *] ((of bol) j) - == - :: - ++ mod - |= j=json - ((su (perk %ctl %met %hyp ~)) j) -- -- :: +grow: convert to From 97540ed6380421d07d0a45dac9a21b397927a111 Mon Sep 17 00:00:00 2001 From: fang Date: Wed, 28 Apr 2021 16:45:55 +0200 Subject: [PATCH 075/104] various: comments, clean-up --- pkg/arvo/lib/hood/drum.hoon | 6 ++--- .../urbit-king/lib/Urbit/Vere/Term/Render.hs | 4 +--- pkg/interface/src/views/apps/term/app.tsx | 1 - pkg/urbit/vere/io/http.c | 4 ++-- pkg/urbit/vere/io/term.c | 23 +++++++------------ 5 files changed, 14 insertions(+), 24 deletions(-) diff --git a/pkg/arvo/lib/hood/drum.hoon b/pkg/arvo/lib/hood/drum.hoon index 50d4f7131a..8cc908607e 100644 --- a/pkg/arvo/lib/hood/drum.hoon +++ b/pkg/arvo/lib/hood/drum.hoon @@ -676,9 +676,9 @@ |= lin=(pair @ud stub) ^+ +> ?: =(mir lin) +> - %+ se-blit(mir lin) %mor - ?: =(q.mir q.lin) [%hop p.lin]~ - [[%hop 0] [%wyp ~] [%klr q.lin] [%hop p.lin] ~] + %- se-blit(mir lin) + ?: =(q.mir q.lin) [%hop p.lin] + mor+[[%hop 0] [%wyp ~] [%klr q.lin] [%hop p.lin] ~] :: ++ se-just :: adjusted buffer |= [pom=stub lin=(pair @ud (list @c))] diff --git a/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Render.hs b/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Render.hs index 853ca953c4..1ebb990d36 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Render.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Render.hs @@ -49,11 +49,9 @@ hijack :: MonadIO m => Int -> m () hijack h = liftIO do putCSI 'r' [1, h-1] -- set scroll region to exclude bottom line putCSI 'S' [1] -- scroll up one line - cursorMove (h-2) 0 -- move cursor to empty space --TODO off-by-one? + cursorMove (h-2) 0 -- move cursor to empty space lojack :: MonadIO m => m () lojack = liftIO do putCSI 'r' [] -- reset scroll region cursorRestore -- restory cursor position - ---TODO consider ANSI.setSGR diff --git a/pkg/interface/src/views/apps/term/app.tsx b/pkg/interface/src/views/apps/term/app.tsx index c57b79c424..45074c636b 100644 --- a/pkg/interface/src/views/apps/term/app.tsx +++ b/pkg/interface/src/views/apps/term/app.tsx @@ -160,7 +160,6 @@ export default function TermApp(props: TermAppProps) { //TODO could be static function if we pass in Terminal explicitly? const onBlit = useCallback((ses: string, blit: Blit) => { - //TODO if (!sessions[ses]) { console.log('on blit: no such session', ses); return; diff --git a/pkg/urbit/vere/io/http.c b/pkg/urbit/vere/io/http.c index 7d20fe4de8..0ace6082ea 100644 --- a/pkg/urbit/vere/io/http.c +++ b/pkg/urbit/vere/io/http.c @@ -42,7 +42,7 @@ typedef struct _u3_h2o_serv { void* gen_u; // response generator struct _u3_hcon* hon_u; // connection backlink struct _u3_hreq* nex_u; // next in connection's list - struct _u3_hreq* pre_u; // next in connection's list + struct _u3_hreq* pre_u; // prev in connection's list } u3_hreq; /* u3_hcon: incoming http connection. @@ -57,7 +57,7 @@ typedef struct _u3_h2o_serv { struct _u3_http* htp_u; // server backlink struct _u3_hreq* req_u; // request list struct _u3_hcon* nex_u; // next in server's list - struct _u3_hcon* pre_u; // next in server's list + struct _u3_hcon* pre_u; // prev in server's list } u3_hcon; /* u3_http: http server. diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index 10adf75d95..adf2fc3c01 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -161,6 +161,9 @@ u3_term_log_init(void) // Construct raw termios configuration. // + // makes input available per-character, does not echo input, + // disables special input pre-processing, output post-processing. + // { uty_u->raw_u = uty_u->bak_u; @@ -680,7 +683,6 @@ _term_io_belt(u3_utty* uty_u, u3_noun blb) { u3_ovum* egg_u = _term_ovum_plan(uty_u->car_u, wir, cad); - //REVIEW do we not want even a small delay here? // no spinner delay on %ret // if ( c3__ret == u3h(blb) ) { @@ -772,23 +774,18 @@ _term_io_suck_char(u3_utty* uty_u, c3_y cay_y) // individual characters // else { - if ( (cay_y >= 32) && (cay_y < 127) ) { + if ( (cay_y >= 32) && (cay_y < 127) ) { // visual ascii _term_io_belt(uty_u, u3nt(c3__txt, cay_y, u3_nul)); } - else if ( 0 == cay_y ) { + 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 ) { + else if ( 8 == cay_y || 127 == cay_y ) { // backspace & delete _term_io_belt(uty_u, u3nc(c3__bac, u3_nul)); } - else if ( 13 == cay_y ) { + else if ( 10 == cay_y || 13 == cay_y ) { // newline & carriage return _term_io_belt(uty_u, u3nc(c3__ret, u3_nul)); } -#if 0 - else if ( 6 == cay_y ) { - _term_io_flow(uty_u); // XX hack - } -#endif else if ( cay_y <= 26 ) { _term_io_belt(uty_u, u3nt(c3__mod, c3__ctl, ('a' + (cay_y - 1)))); } @@ -1655,7 +1652,7 @@ _term_io_talk(u3_auto* car_u) _term_read_cb); } - // XX groace hardcoded terminal number + //TODO reevaluate wrt dill sessions // u3_noun wir = u3nt(c3__term, '1', u3_nul); u3_noun cad; @@ -1667,10 +1664,6 @@ _term_io_talk(u3_auto* car_u) _term_ovum_plan(car_u, u3k(wir), cad); } - // NB, term.c used to also start :dojo - // - // u3nq(c3__flow, c3__seat, c3__dojo, u3_nul) - // refresh terminal state // { From cc4a6f6f3763f0b94c74343a234ed173af67a3e8 Mon Sep 17 00:00:00 2001 From: fang Date: Tue, 18 May 2021 20:20:01 +0200 Subject: [PATCH 076/104] webterm: clean up react/state dependencies logic Changes here ensure we no longer work with stale data in our functions and callbacks, and have easier access to the currently selected session. Special thanks to @tylershuster for most of the improvements herein! --- pkg/interface/src/views/apps/term/app.tsx | 49 +++++++++-------------- 1 file changed, 20 insertions(+), 29 deletions(-) diff --git a/pkg/interface/src/views/apps/term/app.tsx b/pkg/interface/src/views/apps/term/app.tsx index 560e175f81..82dd5f2e7f 100644 --- a/pkg/interface/src/views/apps/term/app.tsx +++ b/pkg/interface/src/views/apps/term/app.tsx @@ -130,25 +130,23 @@ export default function TermApp(props: TermAppProps) { //TODO allow switching of selected const { sessions, selected, slogstream, set } = useTermState(); - //NOTE doesn't work? ): might be nice if it could - // const session = useTermState(useCallback( - // state => state.sessions[state.selected], - // [selected] - // )); + const session = useTermState(useCallback( + state => state.sessions[state.selected], + [selected, sessions] + )); const osDark = useLocalState((state) => state.dark); const theme = useSettingsState(s => s.display.theme); const dark = theme === 'dark' || (theme === 'auto' && osDark); - const onSlog = useCallback((slog) => { - //TODO why does using sessions[selected] not work? - let theSession = useTermState.getState().sessions['']; + const onSlog = (slog) => { + let session = useTermState.getState().sessions['']; - if (!theSession) { + if (!session) { console.log('default session mia!', 'slog:', slog); return; } - const term = theSession.term; + const term = session.term; // set scroll region to exclude the bottom line, // scroll up one line, @@ -165,19 +163,16 @@ export default function TermApp(props: TermAppProps) { + csi('m', 0) + csi('r') + csi('u')); - }, [sessions['']]); + }; - //TODO could be static function if we pass in Terminal explicitly? - const onBlit = useCallback((ses: string, blit: Blit) => { - //TODO why does using sessions[selected] not work? - let theSession = useTermState.getState().sessions[selected]; - - if (!theSession) { - console.log('on blit: no such session', selected); + const onBlit = (sesId: string, blit: Blit) => { + const ses = useTermState.getState().sessions[sesId]; + if (!ses) { + console.log('on blit: no such session', selected, sessions, useTermState.getState().sessions); return; } - const term = theSession.term; + const term = ses.term; let out = ''; if ('bel' in blit) { @@ -231,7 +226,7 @@ export default function TermApp(props: TermAppProps) { } term.write(out); - }, [sessions]); + }; const setupSlog = useCallback(() => { console.log('slog: setting up...'); @@ -259,10 +254,9 @@ export default function TermApp(props: TermAppProps) { } set(state => { state.slogstream = slog }); - }, [onSlog]); + }, [sessions]); const onInput = useCallback((ses: string, e: string) => { - //TODO just sessions[ses].term; const term = useTermState.getState().sessions[ses].term; let belts: Array = []; let strap = ''; @@ -349,8 +343,8 @@ export default function TermApp(props: TermAppProps) { const onResize = useCallback(() => { //TODO debounce, if it ever becomes a problem - sessions[selected].fit.fit(); - }, [sessions, selected]); + session?.fit.fit(); + }, [session]); // on-init, open slogstream // @@ -378,10 +372,7 @@ export default function TermApp(props: TermAppProps) { // on selected change, maybe setup the term, or put it into the container // useEffect(() => { - //TODO improve name, confusing wrt ses as session name - //TODO why doesn't sessions[selected] just work? - let ses = useTermState.getState().sessions[selected]; - + let ses = session; // initialize terminal // if (!ses) { @@ -436,7 +427,7 @@ export default function TermApp(props: TermAppProps) { //TODO unload term from container // but term.dispose is too powerful? maybe just empty the container? } - }, [set, sessions[selected], container.current]); + }, [set, session, container.current]); return ( <> From fa723b48f88f7b82e628199c3925c13c7b5d4754 Mon Sep 17 00:00:00 2001 From: fang Date: Wed, 19 May 2021 16:01:03 +0200 Subject: [PATCH 077/104] dill: ensure terminal app is started When opening a new session, start the specified terminal app, if it hadn't been already. --- pkg/arvo/sys/vane/dill.hoon | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/arvo/sys/vane/dill.hoon b/pkg/arvo/sys/vane/dill.hoon index 9099eb0f20..0ec49f3578 100644 --- a/pkg/arvo/sys/vane/dill.hoon +++ b/pkg/arvo/sys/vane/dill.hoon @@ -221,6 +221,7 @@ :: ++ open |= gyl=(list gill) + =. +> (pass / %g %conf ram) =. +> peer %+ roll gyl |= [g=gill _..open] From c3502a4a6fd9bd8c88a012e72517407e7ef3b060 Mon Sep 17 00:00:00 2001 From: fang Date: Wed, 19 May 2021 16:16:56 +0200 Subject: [PATCH 078/104] herm: use /$ to keep mark conversions cached Instead of hand-rolling logic to keep these warm. --- pkg/arvo/app/herm.hoon | 38 +++++++------------------------------- 1 file changed, 7 insertions(+), 31 deletions(-) diff --git a/pkg/arvo/app/herm.hoon b/pkg/arvo/app/herm.hoon index 8ef76daa78..cb1615ffb6 100644 --- a/pkg/arvo/app/herm.hoon +++ b/pkg/arvo/app/herm.hoon @@ -2,7 +2,12 @@ :: /- herm /+ default-agent, dbug, verb -=, jael +:: keep relevant mark conversions in cache for performance +:: +/$ bj %blit %json +/$ jb %json %belt +/$ jt %json %herm-task +:: |% +$ state-0 [%0 ~] -- @@ -13,18 +18,6 @@ %- agent:dbug ^- agent:gall => |% - ++ request-tube - |= [bowl:gall from=mark to=mark next=?] - ^- card:agent:gall - :* %pass /tube/[from]/[to] - %arvo %c %warp - our q.byk ~ - :: - ?: next - [%next %c da+now /[from]/[to]] - [%sing %c da+now /[from]/[to]] - == - :: ++ pass-session |= [ses=@tas tas=session-task:dill] [%pass /dill/[ses] %arvo %d %shot ses tas] @@ -35,13 +28,7 @@ :: ++ on-init ^- (quip card:agent:gall _this) - :_ this - :: ensure the tubes we use are in cache - :: - :~ (request-tube bowl %blit %json |) - (request-tube bowl %json %belt |) - (request-tube bowl %json %herm-task |) - == + [~ this] :: ++ on-save !>([%0 ~]) ++ on-load @@ -83,17 +70,6 @@ %+ turn p.sign-arvo |= =blit:dill [%give %fact [%session ses ~]~ %blit !>(blit)] - :: - :: ensure the tubes we need remain in cache - :: - [%tube @ @ ~] - =* from i.t.wire - =* to i.t.t.wire - ?. ?=([%clay %writ *] sign-arvo) - ~| [%unexpected-sign [- +<]:sign-arvo] - !! - :_ this - [(request-tube bowl from to &)]~ == :: ++ on-poke From 0f6c3c05cd8b8c133753600976bda353052bf3dc Mon Sep 17 00:00:00 2001 From: fang Date: Thu, 27 May 2021 20:26:12 +0200 Subject: [PATCH 079/104] term: best-effort compatibility with old blits Render old %lin and %mor blits, for backwards compatibility with old dill. --- pkg/hs/urbit-king/lib/Urbit/Arvo/Effect.hs | 6 ++++++ pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs | 5 +++++ pkg/urbit/vere/io/term.c | 5 +++++ 3 files changed, 16 insertions(+) diff --git a/pkg/hs/urbit-king/lib/Urbit/Arvo/Effect.hs b/pkg/hs/urbit-king/lib/Urbit/Arvo/Effect.hs index 2f9b3b7937..6037e02988 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Arvo/Effect.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Arvo/Effect.hs @@ -127,6 +127,9 @@ data Blit | Sav Path Atom | Url Cord | Wyp () + --TMP backwards compatibility + | Lin [Char] + | Mor () deriving (Eq, Ord) --NOTE bottom-left-0-based coordinates @@ -236,6 +239,9 @@ instance Show Blit where show (Sav path _) = "Sav " ++ (show path) show (Url c) = "Url " ++ (show c) show (Wyp ()) = "Wyp ()" + -- + show (Lin c) = "Lin " ++ (show c) + show (Mor ()) = "Mor ()" {-| %blip -- TODO diff --git a/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs b/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs index 91f683fc03..8176d95094 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs @@ -420,6 +420,11 @@ localClient doneSignal = fst <$> mkRAcquire start stop Sav path atom -> pure ls Url url -> pure ls Wyp () -> termShowClear ls + -- + Lin c -> do termShowCursor ls ts 0 0 + termShowClear ls + termShowLine ls (pack c) + Mor () -> termShowNewline ls termRenderDeco :: Deco -> Char termRenderDeco = \case diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index adf2fc3c01..7d78a70ec8 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -1402,10 +1402,15 @@ _term_ef_blit(u3_utty* uty_u, _term_it_show_stub(uty_u, u3k(u3t(blt))); } break; + case c3__lin: { //TMP backwards compatibility + _term_it_move_cursor(uty_u, 0, 0); + _term_it_clear_line(uty_u); + } // case c3__put: { _term_it_show_tour(uty_u, u3k(u3t(blt))); } break; + case c3__mor: //TMP backwards compatibility case c3__nel: { _term_it_show_nel(uty_u); } break; From ddf579bd750b8dc21a990d1ba35cca600d0d71d3 Mon Sep 17 00:00:00 2001 From: fang Date: Thu, 17 Jun 2021 20:23:38 +0200 Subject: [PATCH 080/104] kh: fail to parse invalid belts Previously we would allow the tags that were added Haskell-side for union type syntax. Now we explicitly reject those before falling back to the auto-generated noun parsing logic. --- pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs b/pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs index fb95f523d7..1d82c816aa 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs @@ -305,11 +305,14 @@ $(pure []) instance FromNoun Bolt where parseNoun = \case - A c -> pure $ Key $ C.chr $ fromIntegral c - n -> $(deriveFromNounFunc ''Bolt) n + A c -> pure $ Key $ C.chr $ fromIntegral c + C (A 7955819) _ -> fail "%key not valid bolt tag" + n -> $(deriveFromNounFunc ''Bolt) n instance FromNoun Belt where - parseNoun n = Bol <$> parseNoun n <|> $(deriveFromNounFunc ''Belt) n + parseNoun = \case + C (A 7106402) _ -> fail "%bol not valid belt tag" + n -> Bol <$> parseNoun n <|> $(deriveFromNounFunc ''Belt) n instance ToNoun Bolt where toNoun = \case From b3964c97a6d92bd16e6b359e8f48cb5e1082d4b4 Mon Sep 17 00:00:00 2001 From: fang Date: Thu, 17 Jun 2021 20:30:20 +0200 Subject: [PATCH 081/104] kh: implement null check correctly --- pkg/hs/urbit-king/lib/Urbit/Vere/Term/Logic.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Logic.hs b/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Logic.hs index 8a7d335ccc..fec141051b 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Logic.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Logic.hs @@ -113,8 +113,8 @@ drawState :: St -> [Ev] drawState St{..} = hist <> out <> cur <> spin where hist = drawHistory <$> toList sHistory - out | null <- sLine = [] - | otherwise = [EvEdit sLine] + out | null sLine = [] + | otherwise = [EvEdit sLine] cur | (0, _) <- sCurPos = [] | otherwise = [EvMove sCurPos] spin = maybe [] (singleton . EvSpin . Just) sSpinner From addcf42468525f0c523eb055f56bbb8cfa144fc6 Mon Sep 17 00:00:00 2001 From: fang Date: Thu, 17 Jun 2021 20:34:14 +0200 Subject: [PATCH 082/104] kh: improve code style Removes superfluous parens, makes better use of pattern matching, and respects project-wide capitalization style. --- pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs | 23 ++++++++----------- pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs | 4 ++-- .../urbit-king/lib/Urbit/Vere/Term/Logic.hs | 2 +- .../urbit-king/lib/Urbit/Vere/Term/Render.hs | 12 +++++----- 4 files changed, 19 insertions(+), 22 deletions(-) diff --git a/pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs b/pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs index 1d82c816aa..47f47d51d6 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs @@ -389,19 +389,16 @@ instance FromNoun Ev where getSpinnerNameForEvent :: Ev -> Maybe Text getSpinnerNameForEvent = \case EvBlip b -> case b of - BlipEvAmes _ -> Just "ames" - BlipEvArvo _ -> Just "arvo" - BlipEvBehn _ -> Just "behn" - BlipEvBoat _ -> Just "boat" - BlipEvHttpClient _ -> Just "iris" - BlipEvHttpServer _ -> Just "eyre" - BlipEvNewt _ -> Just "newt" - BlipEvSync _ -> Just "clay" - BlipEvTerm t | isUser t -> Nothing - BlipEvTerm t -> Just "term" - where - isUser (TermEvBelt _ _) = True - isUser _ = False + BlipEvAmes _ -> Just "ames" + BlipEvArvo _ -> Just "arvo" + BlipEvBehn _ -> Just "behn" + BlipEvBoat _ -> Just "boat" + BlipEvHttpClient _ -> Just "iris" + BlipEvHttpServer _ -> Just "eyre" + BlipEvNewt _ -> Just "newt" + BlipEvSync _ -> Just "clay" + BlipEvTerm (TermEvBelt _ _) -> Nothing + BlipEvTerm t -> Just "term" summarizeEvent :: Ev -> Text summarizeEvent ev = diff --git a/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs b/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs index 8176d95094..bc35372a96 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs @@ -313,9 +313,9 @@ localClient doneSignal = fst <$> mkRAcquire start stop -- TODO: Ignoring priority for now. Priority changes the color of, -- and adds a prefix of '>' to, the output. let lines = fmap unTape $ wash (WashCfg 0 width) $ tankTree $ snd slog - T.putCSI 'm' [90] --NOTE print slogs in grey + T.putCsi 'm' [90] --NOTE print slogs in grey forM (intersperse "\n" lines) $ \line -> putStr line - T.putCSI 'm' [0] + T.putCsi 'm' [0] T.lojack pure ls diff --git a/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Logic.hs b/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Logic.hs index fec141051b..748b3fa5a3 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Logic.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Logic.hs @@ -92,7 +92,7 @@ step st@St{..} = \case st { sLine = "", sCurPos = (0, 0) } & recordText (sLine <> "\n") | otherwise -> - st { sCurPos = (((fst sCurPos) - 1), 0) } + st { sCurPos = (fst sCurPos - 1, 0) } where recordText :: Text -> St -> St recordText !t st@St{..} = st { diff --git a/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Render.hs b/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Render.hs index 1ebb990d36..4a3ea4bad9 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Render.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Render.hs @@ -8,7 +8,7 @@ module Urbit.Vere.Term.Render , cursorMove , cursorSave , cursorRestore - , putCSI + , putCsi , hijack , lojack ) where @@ -39,19 +39,19 @@ cursorSave = liftIO ANSI.saveCursor cursorRestore :: MonadIO m => m () cursorRestore = liftIO ANSI.restoreCursor -putCSI :: MonadIO m => Char -> [Int] -> m () -putCSI c a = liftIO do +putCsi :: MonadIO m => Char -> [Int] -> m () +putCsi c a = liftIO do putStr "\x1b[" putStr $ pack $ mconcat $ intersperse ";" (fmap show a) putStr $ pack [c] hijack :: MonadIO m => Int -> m () hijack h = liftIO do - putCSI 'r' [1, h-1] -- set scroll region to exclude bottom line - putCSI 'S' [1] -- scroll up one line + putCsi 'r' [1, h-1] -- set scroll region to exclude bottom line + putCsi 'S' [1] -- scroll up one line cursorMove (h-2) 0 -- move cursor to empty space lojack :: MonadIO m => m () lojack = liftIO do - putCSI 'r' [] -- reset scroll region + putCsi 'r' [] -- reset scroll region cursorRestore -- restory cursor position From eadd7aad01084e4283f7d29ba196b20baa20910a Mon Sep 17 00:00:00 2001 From: fang Date: Thu, 17 Jun 2021 22:48:48 +0200 Subject: [PATCH 083/104] kh: rewrite hijack to guarantee lojacking No longer allow lojack to be called independently, instead requiring logic to be inserted between hi- and lojack's io. --- pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs | 22 ++++++++----------- .../urbit-king/lib/Urbit/Vere/Term/Render.hs | 13 +++++------ 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs b/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs index bc35372a96..0bd98511ae 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs @@ -294,29 +294,25 @@ localClient doneSignal = fst <$> mkRAcquire start stop writeBlank ls = do TermSize _ height <- readTVarIO termSizeVar --NOTE hijack creates a blank line - T.hijack $ fromIntegral height - T.lojack + T.hijack (fromIntegral height) $ pure () pure ls writeTrace :: LineState -> Text -> RIO e LineState writeTrace ls p = do TermSize _ height <- readTVarIO termSizeVar - T.hijack $ fromIntegral height - putStr p - T.lojack + T.hijack (fromIntegral height) $ putStr p pure ls writeSlog :: LineState -> (Atom, Tank) -> RIO e LineState writeSlog ls slog = do TermSize width height <- readTVarIO termSizeVar - T.hijack $ fromIntegral height - -- TODO: Ignoring priority for now. Priority changes the color of, - -- and adds a prefix of '>' to, the output. - let lines = fmap unTape $ wash (WashCfg 0 width) $ tankTree $ snd slog - T.putCsi 'm' [90] --NOTE print slogs in grey - forM (intersperse "\n" lines) $ \line -> putStr line - T.putCsi 'm' [0] - T.lojack + T.hijack (fromIntegral height) do + -- TODO: Ignoring priority for now. Priority changes the color of, + -- and adds a prefix of '>' to, the output. + let lines = fmap unTape $ wash (WashCfg 0 width) $ tankTree $ snd slog + T.putCsi 'm' [90] --NOTE print slogs in grey + forM (intersperse "\n" lines) $ \line -> putStr line + T.putCsi 'm' [0] pure ls {- diff --git a/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Render.hs b/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Render.hs index 4a3ea4bad9..c3b778f430 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Render.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Render.hs @@ -10,7 +10,6 @@ module Urbit.Vere.Term.Render , cursorRestore , putCsi , hijack - , lojack ) where import ClassyPrelude @@ -45,13 +44,11 @@ putCsi c a = liftIO do putStr $ pack $ mconcat $ intersperse ";" (fmap show a) putStr $ pack [c] -hijack :: MonadIO m => Int -> m () -hijack h = liftIO do +hijack :: MonadIO m => Int -> IO () -> m () +hijack h d = liftIO do putCsi 'r' [1, h-1] -- set scroll region to exclude bottom line putCsi 'S' [1] -- scroll up one line cursorMove (h-2) 0 -- move cursor to empty space - -lojack :: MonadIO m => m () -lojack = liftIO do - putCsi 'r' [] -- reset scroll region - cursorRestore -- restory cursor position + d + putCsi 'r' [] -- reset scroll region + cursorRestore -- restory cursor position From 288c2121d1261dd49406a85d523083ed44ac3c1a Mon Sep 17 00:00:00 2001 From: fang Date: Thu, 17 Jun 2021 23:48:48 +0200 Subject: [PATCH 084/104] kh: respect slog priority When printing slogs, if priority is greater than zero, prefix with '>' characters, and adjust the slog color. --- pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs b/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs index 0bd98511ae..ccd4c676df 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs @@ -307,13 +307,24 @@ localClient doneSignal = fst <$> mkRAcquire start stop writeSlog ls slog = do TermSize width height <- readTVarIO termSizeVar T.hijack (fromIntegral height) do - -- TODO: Ignoring priority for now. Priority changes the color of, - -- and adds a prefix of '>' to, the output. - let lines = fmap unTape $ wash (WashCfg 0 width) $ tankTree $ snd slog - T.putCsi 'm' [90] --NOTE print slogs in grey + let lines = fmap (pref . unTape) $ + wash (WashCfg 0 width) $ tankTree $ snd slog + T.putCsi 'm' styl forM (intersperse "\n" lines) $ \line -> putStr line T.putCsi 'm' [0] pure ls + where + prio = fromIntegral $ fst slog + maxp = 3 + styl + | prio == 3 = [31] + | prio == 2 = [33] + | prio == 1 = [32] + | otherwise = [90] + pref + | prio > 0 && prio <= maxp = + ((replicate prio '>' ++ replicate (1 + maxp - prio) ' ') ++) + | otherwise = id {- Figure out how long to wait to show the spinner. When we From 8cc813924391f1b202dc203c491c7e115fbbea43 Mon Sep 17 00:00:00 2001 From: fang Date: Tue, 22 Jun 2021 17:11:24 +0200 Subject: [PATCH 085/104] webterm: more idiomatic array type definitions --- pkg/interface/src/types/term-update.ts | 8 ++++---- pkg/interface/src/views/apps/term/app.tsx | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/interface/src/types/term-update.ts b/pkg/interface/src/types/term-update.ts index 3f85136539..2e9f09ba8c 100644 --- a/pkg/interface/src/types/term-update.ts +++ b/pkg/interface/src/types/term-update.ts @@ -10,22 +10,22 @@ export type Tint = export type Deco = null | 'br' | 'un' | 'bl'; export type Stye = { - deco: Array, + deco: Deco[], back: Tint, fore: Tint }; export type Stub = { stye: Stye, - text: Array + text: string[] } export type Blit = | { bel: null } // make a noise | { clr: null } // clear the screen | { hop: number | { r: number, c: number } } // set cursor col/pos - | { klr: Array } // put styled - | { put: Array } // put text at cursor + | { klr: Stub[] } // put styled + | { put: string[] } // put text at cursor | { nel: null } // newline | { sag: { path: string, file: string } } // save to jamfile | { sav: { path: string, file: string } } // save to file diff --git a/pkg/interface/src/views/apps/term/app.tsx b/pkg/interface/src/views/apps/term/app.tsx index 82dd5f2e7f..b5ebe7200e 100644 --- a/pkg/interface/src/views/apps/term/app.tsx +++ b/pkg/interface/src/views/apps/term/app.tsx @@ -67,7 +67,7 @@ const termConfig: ITerminalOptions = { macOptionClickForcesSelection: true, } -const csi = (cmd: string, ...args: Array) => { +const csi = (cmd: string, ...args: number[]) => { return '\x1b[' + args.join(';') + cmd; } @@ -92,7 +92,7 @@ const stye = (s: Stye) => { // text decorations // if (s.deco.length > 0) { - out += s.deco.reduce((decs: Array, deco: Deco) => { + out += s.deco.reduce((decs: number[], deco: Deco) => { switch (deco) { case null: decs.push(0); return decs; case 'br': decs.push(1); return decs; @@ -258,7 +258,7 @@ export default function TermApp(props: TermAppProps) { const onInput = useCallback((ses: string, e: string) => { const term = useTermState.getState().sessions[ses].term; - let belts: Array = []; + let belts: Belt[] = []; let strap = ''; while (e.length > 0) { From c7a714cd022e5b333e538c8f2f55b4b9b752cf70 Mon Sep 17 00:00:00 2001 From: fang Date: Tue, 22 Jun 2021 20:21:26 +0200 Subject: [PATCH 086/104] webterm: factor logic out into functions Moves a lot of the core logic around input and output handling into functions outside of the TermApp component, operating on a passed-in Terminal object instead of pulling that from state. --- pkg/interface/src/views/apps/term/app.tsx | 340 +++++++++++----------- 1 file changed, 171 insertions(+), 169 deletions(-) diff --git a/pkg/interface/src/views/apps/term/app.tsx b/pkg/interface/src/views/apps/term/app.tsx index b5ebe7200e..d308a4be04 100644 --- a/pkg/interface/src/views/apps/term/app.tsx +++ b/pkg/interface/src/views/apps/term/app.tsx @@ -123,6 +123,164 @@ const stye = (s: Stye) => { return '\x1b[' + out + 'm'; } +const showBlit = (term: Terminal, blit: Blit) => { + let out = ''; + + if ('bel' in blit) { + out += '\x07'; + } + else if ('clr' in blit) { + term.clear(); + out += csi('u'); + } + else if ('hop' in blit) { + if (typeof blit.hop === 'number') { + out += csi('H', term.rows, blit.hop + 1); + } + else { + out += csi('H', term.rows - blit.hop.r, blit.hop.c + 1); + } + out += csi('s'); // save cursor position + } + else if ('put' in blit) { + out += blit.put.join(''); + out += csi('u'); + } + else if ('klr' in blit) { + out += blit.klr.reduce((lin: string, p: Stub) => { + lin += stye(p.stye); + lin += p.text.join(''); + lin += csi('m', 0); + return lin; + }, ''); + out += csi('u'); + } + else if ('nel' in blit) { + out += '\n'; + } + else if ('sag' in blit || 'sav' in blit) { + const sav = ('sag' in blit) ? blit.sag : blit.sav; + let name = sav.path.split('/').slice(-2).join('.'); + let buff = new Buffer(sav.file, 'base64'); + let blob = new Blob([buff], {type: 'application/octet-stream'}); + saveAs(blob, name); + } + else if ('url' in blit) { + window.open(blit.url); + } + else if ('wyp' in blit) { + out += '\r' + csi('K'); + out += csi('u'); + } + else { + console.log('weird blit', blit); + } + + term.write(out); +}; + +//NOTE should generally only be passed the default terminal session +const showSlog = (term: Terminal, slog: string) => { + // set scroll region to exclude the bottom line, + // scroll up one line, + // move cursor to start of the newly created whitespace, + // set text to grey, + // print the slog, + // restore color, scroll region, and cursor. + // + term.write(csi('r', 1, term.rows - 1) + + csi('S', 1) + + csi('H', term.rows - 1, 1) + + csi('m', 90) + + slog + + csi('m', 0) + + csi('r') + + csi('u')); +}; + +const readInput = (term: Terminal, e: string): Belt[] => { + let belts: Belt[] = []; + let strap = ''; + + while (e.length > 0) { + let c = e.charCodeAt(0); + + // text input + // + if (c >= 32 && c !== 127) { + strap += e[0]; + e = e.slice(1); + continue; + } else if ('' !== strap) { + belts.push({ txt: strap.split('') }); + strap = ''; + } + + // special keys/characters + // + if (0 === c) { + term.write('\x07'); // bel + } + else if (8 === c || 127 === c) { + belts.push({ bac: null }); + } + else if (13 === c) { + belts.push({ ret: null }); + } + else if (c <= 26) { + belts.push({ mod: { mod: 'ctl', key: String.fromCharCode(96 + c) } }); + } + + // escape sequences + // + if (27 === c) { // ESC + e = e.slice(1); + c = e.charCodeAt(0); + if (91 === c || 79 === c) { // [ or O + e = e.slice(1); + c = e.charCodeAt(0); + switch (c) { + case 65: belts.push({ aro: 'u' }); break; + case 66: belts.push({ aro: 'd' }); break; + case 67: belts.push({ aro: 'r' }); break; + case 68: belts.push({ aro: 'l' }); break; + // + case 77: + const m = e.charCodeAt(1) - 31; + if (1 === m) { + const c = e.charCodeAt(2) - 32; + const r = e.charCodeAt(3) - 32; + belts.push({ hit: { r: term.rows - r, c: c - 1 } }); + } + e = e.slice(3); + break; + // + default: term.write('\x07'); break; // bel + } + } + else if (c >= 97 && c <= 122) { // a <= c <= z + belts.push({ mod: { mod: 'met', key: e[0] } }); + } + else if (c === 46) { // . + belts.push({ mod: { mod: 'met', key: '.' } }); + } + else if (c === 8 || c === 127) { + belts.push({ mod: { mod: 'met', key: { bac: null } } }); + } + else { + term.write('\x07'); break; // bel + } + } + + e = e.slice(1); + } + if ('' !== strap) { + belts.push({ txt: strap.split('') }); + strap = ''; + } + return belts; +} + export default function TermApp(props: TermAppProps) { const { api } = props; @@ -139,95 +297,6 @@ export default function TermApp(props: TermAppProps) { const theme = useSettingsState(s => s.display.theme); const dark = theme === 'dark' || (theme === 'auto' && osDark); - const onSlog = (slog) => { - let session = useTermState.getState().sessions['']; - - if (!session) { - console.log('default session mia!', 'slog:', slog); - return; - } - const term = session.term; - - // set scroll region to exclude the bottom line, - // scroll up one line, - // move cursor to start of the newly created whitespace, - // set text to grey, - // print the slog, - // restore color, scroll region, and cursor. - // - term.write(csi('r', 1, term.rows - 1) - + csi('S', 1) - + csi('H', term.rows - 1, 1) - + csi('m', 90) - + slog - + csi('m', 0) - + csi('r') - + csi('u')); - }; - - const onBlit = (sesId: string, blit: Blit) => { - const ses = useTermState.getState().sessions[sesId]; - if (!ses) { - console.log('on blit: no such session', selected, sessions, useTermState.getState().sessions); - return; - } - - const term = ses.term; - let out = ''; - - if ('bel' in blit) { - out += '\x07'; - } - else if ('clr' in blit) { - term.clear(); - out += csi('u'); - } - else if ('hop' in blit) { - if (typeof blit.hop === 'number') { - out += csi('H', term.rows, blit.hop + 1); - } - else { - out += csi('H', term.rows - blit.hop.r, blit.hop.c + 1); - } - out += csi('s'); // save cursor position - } - else if ('put' in blit) { - out += blit.put.join(''); - out += csi('u'); - } - else if ('klr' in blit) { - out += blit.klr.reduce((lin: string, p: Stub) => { - lin += stye(p.stye); - lin += p.text.join(''); - lin += csi('m', 0); - return lin; - }, ''); - out += csi('u'); - } - else if ('nel' in blit) { - out += '\n'; - } - else if ('sag' in blit || 'sav' in blit) { - const sav = ('sag' in blit) ? blit.sag : blit.sav; - let name = sav.path.split('/').slice(-2).join('.'); - let buff = new Buffer(sav.file, 'base64'); - let blob = new Blob([buff], {type: 'application/octet-stream'}); - saveAs(blob, name); - } - else if ('url' in blit) { - window.open(blit.url); - } - else if ('wyp' in blit) { - out += '\r' + csi('K'); - out += csi('u'); - } - else { - console.log('weird blit', blit); - } - - term.write(out); - }; - const setupSlog = useCallback(() => { console.log('slog: setting up...'); let available = false; @@ -239,7 +308,12 @@ export default function TermApp(props: TermAppProps) { } slog.onmessage = e => { - onSlog(e.data); + let session = useTermState.getState().sessions['']; + if (!session) { + console.log('default session mia!', 'slog:', slog); + return; + } + showSlog(session.term, e.data); } slog.onerror = e => { @@ -258,84 +332,7 @@ export default function TermApp(props: TermAppProps) { const onInput = useCallback((ses: string, e: string) => { const term = useTermState.getState().sessions[ses].term; - let belts: Belt[] = []; - let strap = ''; - - while (e.length > 0) { - let c = e.charCodeAt(0); - - // text input - // - if (c >= 32 && c !== 127) { - strap += e[0]; - e = e.slice(1); - continue; - } else if ('' !== strap) { - belts.push({ txt: strap.split('') }); - strap = ''; - } - - // special keys/characters - if (0 === c) { - term.write('\x07'); // bel - } - else if (8 === c || 127 === c) { - belts.push({ bac: null }); - } - else if (13 === c) { - belts.push({ ret: null }); - } - else if (c <= 26) { - belts.push({ mod: { mod: 'ctl', key: String.fromCharCode(96 + c) } }); - } - - // escape sequences - // - if (27 === c) { // ESC - e = e.slice(1); - c = e.charCodeAt(0); - if (91 === c || 79 === c) { // [ or O - e = e.slice(1); - c = e.charCodeAt(0); - switch (c) { - case 65: belts.push({ aro: 'u' }); break; - case 66: belts.push({ aro: 'd' }); break; - case 67: belts.push({ aro: 'r' }); break; - case 68: belts.push({ aro: 'l' }); break; - // - case 77: - const m = e.charCodeAt(1) - 31; - if (1 === m) { - const c = e.charCodeAt(2) - 32; - const r = e.charCodeAt(3) - 32; - belts.push({ hit: { r: term.rows - r, c: c - 1 } }); - } - e = e.slice(3); - break; - // - default: term.write('\x07'); break; // bel - } - } - else if (c >= 97 && c <= 122) { // a <= c <= z - belts.push({ mod: { mod: 'met', key: e[0] } }); - } - else if (c === 46) { // . - belts.push({ mod: { mod: 'met', key: '.' } }); - } - else if (c === 8 || c === 127) { - belts.push({ mod: { mod: 'met', key: { bac: null } } }); - } - else { - term.write('\x07'); break; // bel - } - } - - e = e.slice(1); - } - if ('' !== strap) { - belts.push({ txt: strap.split('') }); - strap = ''; - } + const belts = readInput(term, e); belts.map(b => { //NOTE passing api.term.sendBelt makes `this` undefined! api.term.sendBelt(ses, b); }); @@ -403,7 +400,12 @@ export default function TermApp(props: TermAppProps) { // once subscription refactor is in. api.subscribe('/session/'+selected, 'PUT', api.ship, 'herm', (e) => { - onBlit(selected, e.data); + const ses = useTermState.getState().sessions[selected]; + if (!ses) { + console.log('on blit: no such session', selected, sessions, useTermState.getState().sessions); + return; + } + showBlit(ses.term, e.data); }, (err) => { // fail console.log('sub error', selected, err); From 1eb4f350e80d0f3cf9ca5c3f6f44e3b49502d666 Mon Sep 17 00:00:00 2001 From: fang Date: Tue, 22 Jun 2021 22:35:48 +0200 Subject: [PATCH 087/104] webterm: improve container handling Properly pass as dependency, give more correct type. --- pkg/interface/src/views/apps/term/app.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pkg/interface/src/views/apps/term/app.tsx b/pkg/interface/src/views/apps/term/app.tsx index d308a4be04..0ab8f8ef16 100644 --- a/pkg/interface/src/views/apps/term/app.tsx +++ b/pkg/interface/src/views/apps/term/app.tsx @@ -284,7 +284,7 @@ const readInput = (term: Terminal, e: string): Belt[] => { export default function TermApp(props: TermAppProps) { const { api } = props; - const container = useRef(null); + const container = useRef(null); //TODO allow switching of selected const { sessions, selected, slogstream, set } = useTermState(); @@ -429,7 +429,7 @@ export default function TermApp(props: TermAppProps) { //TODO unload term from container // but term.dispose is too powerful? maybe just empty the container? } - }, [set, session, container.current]); + }, [set, session, container]); return ( <> @@ -450,8 +450,7 @@ export default function TermApp(props: TermAppProps) { borderRadius={['0','2']} border={['0','1']} p='1' - //@ts-ignore //NOTE fix in indigo Soon™ - ref={container} //TODO might somehow be undefined? + ref={container} > From 568e8e320b60ccf46c3c15736b73ee168c997048 Mon Sep 17 00:00:00 2001 From: fang Date: Wed, 23 Jun 2021 14:09:37 +0200 Subject: [PATCH 088/104] hood, pill: clean up merge artifacts --- bin/brass.pill | 4 +-- bin/solid.pill | 4 +-- pkg/arvo/app/hood.hoon | 17 ++++++------- pkg/arvo/lib/hood/drum.hoon | 50 ++----------------------------------- 4 files changed, 13 insertions(+), 62 deletions(-) diff --git a/bin/brass.pill b/bin/brass.pill index 2a4689f24a..c38a074d42 100644 --- a/bin/brass.pill +++ b/bin/brass.pill @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e0af91e5c51359719aaa943f37a1e953989c786412616b18fbaa0addb2cf0740 -size 10272514 +oid sha256:bca842e60a26a712bd1ea6217b13794a6ce0cffa46ec52f00d9bfe808cea6f38 +size 13196527 diff --git a/bin/solid.pill b/bin/solid.pill index 671dccc97a..25e2367d01 100644 --- a/bin/solid.pill +++ b/bin/solid.pill @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e0c05655f47ff81c8d4985a061d3ff57526a436adf25f667432a48c5cd10d438 -size 12190347 +oid sha256:5f62579d654a145904ffb0bc9bbda17dda091a2e28e2f1eecf6a7b29cef9189c +size 14866258 diff --git a/pkg/arvo/app/hood.hoon b/pkg/arvo/app/hood.hoon index 5807afa525..f4fbdf9352 100644 --- a/pkg/arvo/app/hood.hoon +++ b/pkg/arvo/app/hood.hoon @@ -2,7 +2,7 @@ /+ drum=hood-drum, helm=hood-helm, kiln=hood-kiln |% +$ state - $: %13 + $: %14 drum=state:drum helm=state:helm kiln=state:kiln @@ -10,16 +10,13 @@ +$ any-state $% state [ver=?(%1 %2 %3 %4 %5 %6) lac=(map @tas fin-any-state)] - [%7 drum=state:drum helm=state:helm kiln=state:kiln] - [%8 drum=state:drum helm=state:helm kiln=state:kiln] - [%9 drum=state:drum helm=state:helm kiln=state:kiln] - [%10 drum=state:drum helm=state:helm kiln=state:kiln] - [%11 drum=state:drum helm=state:helm kiln=state:kiln] -<<<<<<< HEAD + [%7 drum=any-state:drum helm=state:helm kiln=state:kiln] + [%8 drum=any-state:drum helm=state:helm kiln=state:kiln] + [%9 drum=any-state:drum helm=state:helm kiln=state:kiln] + [%10 drum=any-state:drum helm=state:helm kiln=state:kiln] + [%11 drum=any-state:drum helm=state:helm kiln=state:kiln] [%12 drum=any-state:drum helm=state:helm kiln=state:kiln] -======= - [%12 drum=state:drum helm=state:helm kiln=state:kiln] ->>>>>>> cd400dfa69059e211dc88f4ce5d53479b9da7542 + [%13 drum=any-state:drum helm=state:helm kiln=state:kiln] == +$ any-state-tuple $: drum=any-state:drum diff --git a/pkg/arvo/lib/hood/drum.hoon b/pkg/arvo/lib/hood/drum.hoon index 4dcf4c1a45..1dde21d496 100644 --- a/pkg/arvo/lib/hood/drum.hoon +++ b/pkg/arvo/lib/hood/drum.hoon @@ -262,7 +262,6 @@ == :: ++ on-load -<<<<<<< HEAD |^ |= [hood-version=@ud old=any-state] =< se-abet =< se-view =. sat (load-state old) @@ -340,55 +339,10 @@ => (se-born | %home %contact-pull-hook) => (se-born | %home %settings-store) (se-born | %home %group-view) + =? ..on-load (lte hood-version %13) + (se-born | %home %dm-hook) ..on-load -- -======= - |= [hood-version=@ud old=any-state] - =< se-abet =< se-view - =. sat old - =. dev (~(gut by bin) ost *source) - =? ..on-load (lte hood-version %4) - ~> %slog.0^leaf+"drum: starting os1 agents" - => (se-born | %home %s3-store) - => (se-born | %home %contact-view) - => (se-born | %home %contact-hook) - => (se-born | %home %contact-store) - => (se-born | %home %metadata-hook) - => (se-born | %home %metadata-store) - => (se-born | %home %goad) - ~> %slog.0^leaf+"drum: resubscribing to %dojo and %chat-cli" - => (se-drop:(se-pull our.hid %dojo) | our.hid %dojo) - (se-drop:(se-pull our.hid %chat-cli) | our.hid %chat-cli) - =? ..on-load (lte hood-version %5) - (se-born | %home %file-server) - =? ..on-load (lte hood-version %7) - (se-born | %home %glob) - =? ..on-load (lte hood-version %8) - => (se-born | %home %group-push-hook) - (se-born | %home %group-pull-hook) - =? ..on-load (lte hood-version %9) - (se-born | %home %graph-store) - =? ..on-load (lte hood-version %10) - => (se-born | %home %graph-push-hook) - (se-born | %home %graph-pull-hook) - =? ..on-load (lte hood-version %11) - => (se-born | %home %hark-graph-hook) - => (se-born | %home %hark-group-hook) - => (se-born | %home %hark-chat-hook) - => (se-born | %home %hark-store) - => (se-born | %home %observe-hook) - => (se-born | %home %metadata-pull-hook) - => (se-born | %home %metadata-push-hook) - (se-born | %home %herm) - =? ..on-load (lte hood-version %12) - => (se-born | %home %contact-push-hook) - => (se-born | %home %contact-pull-hook) - => (se-born | %home %settings-store) - (se-born | %home %group-view) - =? ..on-load (lte hood-version %13) - (se-born | %home %dm-hook) - ..on-load ->>>>>>> cd400dfa69059e211dc88f4ce5d53479b9da7542 :: ++ reap-phat :: ack connect |= [way=wire saw=(unit tang)] From 831e7dc603157c74adbbc2f9a787dcd494bbf586 Mon Sep 17 00:00:00 2001 From: fang Date: Wed, 23 Jun 2021 14:55:52 +0200 Subject: [PATCH 089/104] herm: accept old /view/* wires --- pkg/arvo/app/herm.hoon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/arvo/app/herm.hoon b/pkg/arvo/app/herm.hoon index cb1615ffb6..6bd9b7f3da 100644 --- a/pkg/arvo/app/herm.hoon +++ b/pkg/arvo/app/herm.hoon @@ -61,7 +61,7 @@ ?+ wire !! :: pass on dill blits for the session :: - [%dill @ ~] + [?(%view %dill) @ ~] ::NOTE /view for backwards compat =* ses i.t.wire ?. ?=([%dill %blit *] sign-arvo) ~| [%unexpected-sign [- +<]:sign-arvo] From cb10d46b888cb89e832b31e24def5da65e882de7 Mon Sep 17 00:00:00 2001 From: fang Date: Wed, 23 Jun 2021 15:08:53 +0200 Subject: [PATCH 090/104] webterm: include @urbit/api/term files --- pkg/npm/api/term/index.ts | 2 ++ pkg/npm/api/term/lib.ts | 22 ++++++++++++++ pkg/npm/api/term/types.ts | 63 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 pkg/npm/api/term/index.ts create mode 100644 pkg/npm/api/term/lib.ts create mode 100644 pkg/npm/api/term/types.ts diff --git a/pkg/npm/api/term/index.ts b/pkg/npm/api/term/index.ts new file mode 100644 index 0000000000..341e817115 --- /dev/null +++ b/pkg/npm/api/term/index.ts @@ -0,0 +1,2 @@ +export * from './types'; +export * from './lib'; \ No newline at end of file diff --git a/pkg/npm/api/term/lib.ts b/pkg/npm/api/term/lib.ts new file mode 100644 index 0000000000..86db547d89 --- /dev/null +++ b/pkg/npm/api/term/lib.ts @@ -0,0 +1,22 @@ +import _ from 'lodash'; + +import { Scry } from '../lib' +import { Enc, Path, Patp, PatpNoSig, Poke, Thread } from '../lib/types'; +import { Belt, Task, SessionTask } from './types'; + +export const pokeTask = (session: string, task: Task): Poke => ({ + app: 'herm', + mark: 'herm-task', + json: { session, task } +}); + +export const pokeBelt = ( + session: string, + belt: Belt +): Poke => pokeTask(session, { belt }); + +//NOTE scry will return string[] +export const scrySessions = (): Scry => ({ + app: 'herm', + path: `/sessions` +}); diff --git a/pkg/npm/api/term/types.ts b/pkg/npm/api/term/types.ts new file mode 100644 index 0000000000..5ffd920a6d --- /dev/null +++ b/pkg/npm/api/term/types.ts @@ -0,0 +1,63 @@ +// outputs +// + +export type TermUpdate = + | Blit; + +export type Tint = + | null + | 'r' | 'g' | 'b' | 'c' | 'm' | 'y' | 'k' | 'w' + | { r: number, g: number, b: number }; + +export type Deco = null | 'br' | 'un' | 'bl'; + +export type Stye = { + deco: Deco[], + back: Tint, + fore: Tint +}; + +export type Stub = { + stye: Stye, + text: string[] +} + +export type Blit = + | { bel: null } // make a noise + | { clr: null } // clear the screen + | { hop: number | { r: number, c: number } } // set cursor col/pos + | { klr: Stub[] } // put styled + | { put: string[] } // put text at cursor + | { nel: null } // newline + | { sag: { path: string, file: string } } // save to jamfile + | { sav: { path: string, file: string } } // save to file + | { url: string } // activate url + | { wyp: null } // wipe cursor line + +// inputs +// + +export type Bolt = + | string + | { aro: 'd' | 'l' | 'r' | 'u' } + | { bac: null } + | { del: null } + | { hit: { r: number, c: number } } + | { ret: null } + +export type Belt = + | Bolt + | { mod: { mod: 'ctl' | 'met' | 'hyp', key: Bolt } } + | { txt: Array }; + +export type Task = + | { belt: Belt } + | { blew: { w: number, h: number } } + | { flow: { term: string, apps: Array<{ who: string, app: string }> } } + | { hail: null } + | { hook: null } + +export type SessionTask = { + session: string, + task: Task +} From 1b95f934c7ca91bf208c474f6e88d83b7f0793a7 Mon Sep 17 00:00:00 2001 From: fang Date: Wed, 23 Jun 2021 15:24:42 +0200 Subject: [PATCH 091/104] herm: close old-style subscriptions --- pkg/arvo/app/herm.hoon | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pkg/arvo/app/herm.hoon b/pkg/arvo/app/herm.hoon index 6bd9b7f3da..7be319b952 100644 --- a/pkg/arvo/app/herm.hoon +++ b/pkg/arvo/app/herm.hoon @@ -61,7 +61,7 @@ ?+ wire !! :: pass on dill blits for the session :: - [?(%view %dill) @ ~] ::NOTE /view for backwards compat + [%dill @ ~] =* ses i.t.wire ?. ?=([%dill %blit *] sign-arvo) ~| [%unexpected-sign [- +<]:sign-arvo] @@ -70,6 +70,13 @@ %+ turn p.sign-arvo |= =blit:dill [%give %fact [%session ses ~]~ %blit !>(blit)] + :: + :: clean up old-style subscriptions + :: + [%view @ ~] + =* ses i.t.wire + :_ this + [%pass wire %arvo %d %shot ses %flee ~]~ == :: ++ on-poke From 329ec8ef3f87b743907fb57982e1bf1caad03787 Mon Sep 17 00:00:00 2001 From: Fang Date: Mon, 28 Jun 2021 14:44:35 +0200 Subject: [PATCH 092/104] webterm: fix broken api interactions We hadn't adapted to the new subscription event callback yet, and were sending a slightly misshapen herm task for pokes. --- pkg/interface/src/views/apps/term/app.tsx | 4 +--- pkg/npm/api/term/lib.ts | 4 ++-- pkg/npm/api/term/types.ts | 5 +---- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/pkg/interface/src/views/apps/term/app.tsx b/pkg/interface/src/views/apps/term/app.tsx index 69a2f82229..3524ee897e 100644 --- a/pkg/interface/src/views/apps/term/app.tsx +++ b/pkg/interface/src/views/apps/term/app.tsx @@ -393,8 +393,6 @@ export default function TermApp(props: TermAppProps) { // open subscription // - // TODO start default session alongside other landscape subscriptions, - // once subscription refactor is in. api.subscribe({ app: 'herm', path: '/session/'+selected, event: (e) => { const ses = useTermState.getState().sessions[selected]; @@ -402,7 +400,7 @@ export default function TermApp(props: TermAppProps) { console.log('on blit: no such session', selected, sessions, useTermState.getState().sessions); return; } - showBlit(ses.term, e.data); + showBlit(ses.term, e); }, quit: () => { // quit // TODO show user a message diff --git a/pkg/npm/api/term/lib.ts b/pkg/npm/api/term/lib.ts index 86db547d89..e6ae877eaa 100644 --- a/pkg/npm/api/term/lib.ts +++ b/pkg/npm/api/term/lib.ts @@ -1,13 +1,13 @@ import _ from 'lodash'; import { Scry } from '../lib' -import { Enc, Path, Patp, PatpNoSig, Poke, Thread } from '../lib/types'; +import { Poke } from '../lib/types'; import { Belt, Task, SessionTask } from './types'; export const pokeTask = (session: string, task: Task): Poke => ({ app: 'herm', mark: 'herm-task', - json: { session, task } + json: { session, ...task } }); export const pokeBelt = ( diff --git a/pkg/npm/api/term/types.ts b/pkg/npm/api/term/types.ts index 5ffd920a6d..8bcdd302f3 100644 --- a/pkg/npm/api/term/types.ts +++ b/pkg/npm/api/term/types.ts @@ -57,7 +57,4 @@ export type Task = | { hail: null } | { hook: null } -export type SessionTask = { - session: string, - task: Task -} +export type SessionTask = { session: string } & Task From d138ab254b9985a1fdf50cdbdcf78e6f7fd1479e Mon Sep 17 00:00:00 2001 From: Fang Date: Tue, 29 Jun 2021 16:03:21 +0200 Subject: [PATCH 093/104] webterm: clean up component state derivation --- pkg/interface/src/views/apps/term/app.tsx | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/pkg/interface/src/views/apps/term/app.tsx b/pkg/interface/src/views/apps/term/app.tsx index 3524ee897e..071aa5cc6a 100644 --- a/pkg/interface/src/views/apps/term/app.tsx +++ b/pkg/interface/src/views/apps/term/app.tsx @@ -6,8 +6,7 @@ import React, { import Helmet from 'react-helmet'; import useTermState from '~/logic/state/term'; -import useSettingsState from '~/logic/state/settings'; -import useLocalState from '~/logic/state/local'; +import { useDark } from '~/logic/state/join'; import { Terminal, ITerminalOptions, ITheme } from 'xterm'; import { FitAddon } from 'xterm-addon-fit'; @@ -278,15 +277,8 @@ export default function TermApp(props: TermAppProps) { const container = useRef(null); // TODO allow switching of selected const { sessions, selected, slogstream, set } = useTermState(); - - const session = useTermState(useCallback( - state => state.sessions[state.selected], - [selected, sessions] - )); - - const osDark = useLocalState(state => state.dark); - const theme = useSettingsState(s => s.display.theme); - const dark = theme === 'dark' || (theme === 'auto' && osDark); + const session = sessions[selected]; + const dark = useDark(); const setupSlog = useCallback(() => { console.log('slog: setting up...'); From 8b6b51b4da47c167ad699fa61329027c6295522e Mon Sep 17 00:00:00 2001 From: Fang Date: Fri, 13 Aug 2021 00:23:12 +0200 Subject: [PATCH 094/104] webterm: simpler TermState Extending BaseState has fallen out of fashion. --- pkg/interface/src/logic/state/term.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/interface/src/logic/state/term.ts b/pkg/interface/src/logic/state/term.ts index ceaf257c93..d0820cd87a 100644 --- a/pkg/interface/src/logic/state/term.ts +++ b/pkg/interface/src/logic/state/term.ts @@ -1,12 +1,12 @@ import { Terminal } from 'xterm'; import { FitAddon } from 'xterm-addon-fit'; -import { BaseState, createState } from "./base"; +import { createState } from "./base"; type Session = { term: Terminal, fit: FitAddon }; type Sessions = { [id: string]: Session; } -export interface TermState extends BaseState { +export interface TermState { sessions: Sessions, selected: string, slogstream: null | EventSource, From 42e8158be9a53d907c5141188cbd3d6760111632 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Thu, 9 Sep 2021 14:08:39 -0400 Subject: [PATCH 095/104] pill: all further propagating temporary space leak mitigation --- bin/brass.pill | 4 ++-- bin/ivory.pill | 4 ++-- bin/solid.pill | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bin/brass.pill b/bin/brass.pill index c38a074d42..034893638d 100644 --- a/bin/brass.pill +++ b/bin/brass.pill @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bca842e60a26a712bd1ea6217b13794a6ce0cffa46ec52f00d9bfe808cea6f38 -size 13196527 +oid sha256:f70a6e20ac6fd7dfb620f7ace725c5b031d040c0fe97caab251233ba31bc9819 +size 5155717 diff --git a/bin/ivory.pill b/bin/ivory.pill index 5bd9621166..0f39735894 100644 --- a/bin/ivory.pill +++ b/bin/ivory.pill @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a1d3154858e1eaa9ab48dfe3ff24cfe1994e7e96379d1fd9cd971df4939ce220 -size 3952575 +oid sha256:c871af4da5d779a2ccc8a8187ca06e2ccf19a984db9bede7f2d721fa43525210 +size 1259429 diff --git a/bin/solid.pill b/bin/solid.pill index af3e3f110a..2c88500aa9 100644 --- a/bin/solid.pill +++ b/bin/solid.pill @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2d96d97b5adb6896057d21557803a046eb6a7c024629ed03209f245df5c67d42 -size 13205353 +oid sha256:5f97a6c105b89973b6f7ee2bace9f0aff018efb65db7a3b90948761abb8c6b18 +size 6876039 From adfe71e4fecf1929c86d34565c6596094a984194 Mon Sep 17 00:00:00 2001 From: Edward Amsden Date: Mon, 13 Sep 2021 10:07:00 -0400 Subject: [PATCH 096/104] vere: use memset to wipe hashmaps --- pkg/urbit/include/ur/hashcons.h | 6 +-- pkg/urbit/ur/hashcons.c | 84 ++++++++++++++++++--------------- 2 files changed, 50 insertions(+), 40 deletions(-) diff --git a/pkg/urbit/include/ur/hashcons.h b/pkg/urbit/include/ur/hashcons.h index ea047e13f1..01e295ddf0 100644 --- a/pkg/urbit/include/ur/hashcons.h +++ b/pkg/urbit/include/ur/hashcons.h @@ -40,7 +40,6 @@ typedef uint32_t ur_mug; #define ur_pail_max 10 typedef struct ur_pail32_s { - uint8_t fill; ur_nref refs[ur_pail_max]; uint32_t vals[ur_pail_max]; } ur_pail32_t; @@ -48,11 +47,11 @@ typedef struct ur_pail32_s { typedef struct ur_dict32_s { uint64_t prev; uint64_t size; + uint8_t *fills; ur_pail32_t *buckets; } ur_dict32_t; typedef struct ur_pail64_s { - uint8_t fill; ur_nref refs[ur_pail_max]; uint64_t vals[ur_pail_max]; } ur_pail64_t; @@ -60,17 +59,18 @@ typedef struct ur_pail64_s { typedef struct ur_dict64_s { uint64_t prev; uint64_t size; + uint8_t *fills; ur_pail64_t *buckets; } ur_dict64_t; typedef struct ur_pail_s { - uint8_t fill; ur_nref refs[ur_pail_max]; } ur_pail_t; typedef struct ur_dict_s { uint64_t prev; uint64_t size; + uint8_t *fills; ur_pail_t *buckets; } ur_dict_t; diff --git a/pkg/urbit/ur/hashcons.c b/pkg/urbit/ur/hashcons.c index 8339a53010..4863ef6b72 100644 --- a/pkg/urbit/ur/hashcons.c +++ b/pkg/urbit/ur/hashcons.c @@ -33,15 +33,17 @@ void ur_dict32_grow(ur_root_t *r, ur_dict32_t *dict, uint64_t prev, uint64_t size) { ur_pail32_t *buckets, *old_buckets = dict->buckets; + uint8_t *fills, *old_fills = dict->fills; uint64_t old_size = dict->size; uint64_t i, next = prev + size; buckets = _oom("dict32_grow", calloc(next, sizeof(*buckets))); + fills = _oom("dict32_grow", calloc(next, sizeof(*fills))); if ( old_buckets ) { for ( i = 0; i < old_size; i++ ) { ur_pail32_t *old_bucket = &(old_buckets[i]); - uint8_t j, old_fill = old_bucket->fill; + uint8_t j, old_fill = old_fills[i]; for ( j = 0; j < old_fill; j++ ) { uint32_t val = old_bucket->vals[j]; @@ -50,24 +52,27 @@ ur_dict32_grow(ur_root_t *r, ur_dict32_t *dict, uint64_t prev, uint64_t size) uint64_t idx = ( mug % next ); ur_pail32_t *bucket = &(buckets[idx]); - uint8_t new_fill = bucket->fill; + uint8_t new_fill = fills[idx]; if ( ur_pail_max == new_fill ) { free(buckets); + free(fills); return ur_dict32_grow(r, dict, size, next); } bucket->refs[new_fill] = ref; bucket->vals[new_fill] = val; - bucket->fill = 1 + new_fill; + fills[idx] = 1 + new_fill; } } free(old_buckets); + free(old_fills); } dict->prev = size; dict->size = next; + dict->fills = fills; dict->buckets = buckets; } @@ -78,7 +83,7 @@ ur_dict32_get(ur_root_t *r, ur_dict32_t *dict, ur_nref ref, uint32_t *out) uint64_t idx = ( mug % dict->size ); ur_pail32_t *bucket = &(dict->buckets[idx]); - uint8_t i, fill = bucket->fill; + uint8_t i, fill = dict->fills[idx]; for ( i = 0; i < fill; i++ ) { if ( ref == bucket->refs[i] ) { @@ -98,7 +103,7 @@ ur_dict32_put(ur_root_t *r, ur_dict32_t *dict, ur_nref ref, uint32_t val) while ( 1 ) { uint64_t idx = ( mug % dict->size ); ur_pail32_t *bucket = &(dict->buckets[idx]); - uint8_t i, fill = bucket->fill; + uint8_t i, fill = dict->fills[idx]; for ( i = 0; i < fill; i++ ) { if ( ref == bucket->refs[i] ) { @@ -114,7 +119,7 @@ ur_dict32_put(ur_root_t *r, ur_dict32_t *dict, ur_nref ref, uint32_t val) bucket->refs[fill] = ref; bucket->vals[fill] = val; - bucket->fill = 1 + fill; + dict->fills[idx] = 1 + fill; break; } } @@ -122,27 +127,27 @@ ur_dict32_put(ur_root_t *r, ur_dict32_t *dict, ur_nref ref, uint32_t val) void ur_dict32_wipe(ur_dict32_t *dict) { - ur_pail32_t *buckets = dict->buckets; - uint64_t i, size = dict->size; + uint8_t *fills = dict->fills; + uint64_t size = dict->size; - for ( i = 0; i < size; i++ ) { - buckets[i].fill = 0; - } + memset(fills, 0, sizeof(*fills) * size); } void ur_dict64_grow(ur_root_t *r, ur_dict64_t *dict, uint64_t prev, uint64_t size) { ur_pail64_t *buckets, *old_buckets = dict->buckets; + uint8_t *fills, *old_fills = dict->fills; uint64_t old_size = dict->size; uint64_t i, next = prev + size; buckets = _oom("dict64_grow", calloc(next, sizeof(*buckets))); + fills = _oom("dict64_grow", calloc(next, sizeof(*fills))); if ( old_buckets ) { for ( i = 0; i < old_size; i++ ) { ur_pail64_t *old_bucket = &(old_buckets[i]); - uint8_t j, old_fill = old_bucket->fill; + uint8_t j, old_fill = old_fills[i]; for ( j = 0; j < old_fill; j++ ) { uint64_t val = old_bucket->vals[j]; @@ -151,24 +156,27 @@ ur_dict64_grow(ur_root_t *r, ur_dict64_t *dict, uint64_t prev, uint64_t size) uint64_t idx = ( mug % next ); ur_pail64_t *bucket = &(buckets[idx]); - uint8_t new_fill = bucket->fill; + uint8_t new_fill = fills[idx]; if ( ur_pail_max == new_fill ) { free(buckets); + free(fills); return ur_dict64_grow(r, dict, size, next); } bucket->refs[new_fill] = ref; bucket->vals[new_fill] = val; - bucket->fill = 1 + new_fill; + fills[idx] = 1 + new_fill; } } free(old_buckets); + free(old_fills); } dict->prev = size; dict->size = next; + dict->fills = fills; dict->buckets = buckets; } @@ -179,7 +187,7 @@ ur_dict64_get(ur_root_t *r, ur_dict64_t *dict, ur_nref ref, uint64_t *out) uint64_t idx = ( mug % dict->size ); ur_pail64_t *bucket = &(dict->buckets[idx]); - uint8_t i, fill = bucket->fill; + uint8_t i, fill = dict->fills[idx]; for ( i = 0; i < fill; i++ ) { if ( ref == bucket->refs[i] ) { @@ -199,7 +207,7 @@ ur_dict64_put(ur_root_t *r, ur_dict64_t *dict, ur_nref ref, uint64_t val) while ( 1 ) { uint64_t idx = ( mug % dict->size ); ur_pail64_t *bucket = &(dict->buckets[idx]); - uint8_t i, fill = bucket->fill; + uint8_t i, fill = dict->fills[idx]; for ( i = 0; i < fill; i++ ) { if ( ref == bucket->refs[i] ) { @@ -215,7 +223,7 @@ ur_dict64_put(ur_root_t *r, ur_dict64_t *dict, ur_nref ref, uint64_t val) bucket->refs[fill] = ref; bucket->vals[fill] = val; - bucket->fill = 1 + fill; + dict->fills[idx] = 1 + fill; break; } } @@ -223,27 +231,27 @@ ur_dict64_put(ur_root_t *r, ur_dict64_t *dict, ur_nref ref, uint64_t val) void ur_dict64_wipe(ur_dict64_t *dict) { - ur_pail64_t *buckets = dict->buckets; - uint64_t i, size = dict->size; + uint8_t *fills = dict->fills; + uint64_t size = dict->size; - for ( i = 0; i < size; i++ ) { - buckets[i].fill = 0; - } + memset(fills, 0, sizeof(*fills) * size); } void ur_dict_grow(ur_root_t *r, ur_dict_t *dict, uint64_t prev, uint64_t size) { ur_pail_t *buckets, *old_buckets = dict->buckets; + uint8_t *fills, *old_fills = dict->fills; uint64_t old_size = dict->size; uint64_t i, next = prev + size; buckets = _oom("dict_grow", calloc(next, sizeof(*buckets))); + fills = _oom("dict_grow", calloc(next, sizeof(*fills))); if ( old_buckets ) { for ( i = 0; i < old_size; i++ ) { ur_pail_t *old_bucket = &(old_buckets[i]); - uint8_t j, old_fill = old_bucket->fill; + uint8_t j, old_fill = old_fills[i]; for ( j = 0; j < old_fill; j++ ) { ur_nref ref = old_bucket->refs[j]; @@ -251,23 +259,26 @@ ur_dict_grow(ur_root_t *r, ur_dict_t *dict, uint64_t prev, uint64_t size) uint64_t idx = ( mug % next ); ur_pail_t *bucket = &(buckets[idx]); - uint8_t new_fill = bucket->fill; + uint8_t new_fill = fills[idx]; if ( ur_pail_max == new_fill ) { free(buckets); + free(fills); return ur_dict_grow(r, dict, size, next); } bucket->refs[new_fill] = ref; - bucket->fill = 1 + new_fill; + fills[idx] = 1 + new_fill; } } free(old_buckets); + free(old_fills); } dict->prev = size; dict->size = next; + dict->fills = fills; dict->buckets = buckets; } @@ -278,7 +289,7 @@ ur_dict_get(ur_root_t *r, ur_dict_t *dict, ur_nref ref) uint64_t idx = ( mug % dict->size ); ur_pail_t *bucket = &(dict->buckets[idx]); - uint8_t i, fill = bucket->fill; + uint8_t i, fill = dict->fills[idx]; for ( i = 0; i < fill; i++ ) { if ( ref == bucket->refs[i] ) { @@ -297,7 +308,7 @@ ur_dict_put(ur_root_t *r, ur_dict_t *dict, ur_nref ref) while ( 1 ) { uint64_t idx = ( mug % dict->size ); ur_pail_t *bucket = &(dict->buckets[idx]); - uint8_t i, fill = bucket->fill; + uint8_t i, fill = dict->fills[idx]; for ( i = 0; i < fill; i++ ) { if ( ref == bucket->refs[i] ) { @@ -311,7 +322,7 @@ ur_dict_put(ur_root_t *r, ur_dict_t *dict, ur_nref ref) } bucket->refs[fill] = ref; - bucket->fill = 1 + fill; + dict->fills[idx] = 1 + fill; break; } } @@ -319,18 +330,17 @@ ur_dict_put(ur_root_t *r, ur_dict_t *dict, ur_nref ref) void ur_dict_wipe(ur_dict_t *dict) { - ur_pail_t *buckets = dict->buckets; - uint64_t i, size = dict->size; + uint8_t *fills = dict -> fills; + uint64_t size = dict->size; - for ( i = 0; i < size; i++ ) { - buckets[i].fill = 0; - } + memset(fills, 0, sizeof(*fills) * size); } void ur_dict_free(ur_dict_t *dict) { free(dict->buckets); + free(dict->fills); dict->buckets = 0; } @@ -613,7 +623,7 @@ ur_coin_bytes_unsafe(ur_root_t *r, uint64_t len, uint8_t *byt) while ( 1 ) { uint64_t idx = ( mug % dict->size ); ur_pail_t *bucket = &(dict->buckets[idx]); - uint8_t i, b_fill = bucket->fill; + uint8_t i, b_fill = dict->fills[idx]; ur_nref tom; for ( i = 0; i < b_fill; i++ ) { @@ -642,7 +652,7 @@ ur_coin_bytes_unsafe(ur_root_t *r, uint64_t len, uint8_t *byt) tom = _coin_unsafe(atoms, mug, len, byt); bucket->refs[b_fill] = tom; - bucket->fill = 1 + b_fill; + dict->fills[idx] = 1 + b_fill; return tom; } @@ -712,7 +722,7 @@ ur_cons(ur_root_t *r, ur_nref hed, ur_nref tal) while ( 1 ) { uint64_t idx = ( mug % dict->size ); ur_pail_t *bucket = &(dict->buckets[idx]); - uint8_t i, b_fill = bucket->fill; + uint8_t i, b_fill = dict->fills[idx]; ur_nref cel; for ( i = 0; i < b_fill; i++ ) { @@ -737,7 +747,7 @@ ur_cons(ur_root_t *r, ur_nref hed, ur_nref tal) cel = _cons_unsafe(cells, mug, hed, tal); bucket->refs[b_fill] = cel; - bucket->fill = 1 + b_fill; + dict->fills[idx] = 1 + b_fill; return cel; } From 412bae2cd4735c3662073d84b732af0488abce93 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Mon, 13 Sep 2021 11:47:15 -0400 Subject: [PATCH 097/104] vere: suppress null writes in term.c --- pkg/urbit/vere/io/term.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index 1f97b430f3..a15f264547 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -298,7 +298,9 @@ static void _term_it_dump_buf(u3_utty* uty_u, uv_buf_t* buf_u) { - _term_it_write(uty_u, buf_u, 0); + if ( buf_u->len ) { + _term_it_write(uty_u, buf_u, 0); + } } /* _term_it_dump(): write static vector. @@ -315,12 +317,17 @@ _term_it_dump(u3_utty* uty_u, /* _term_it_send(): write dynamic vector, freeing pointer. */ static void -_term_it_send(u3_utty* uty_u, - c3_w len_w, - const c3_y* hun_y) +_term_it_send(u3_utty* uty_u, + c3_w len_w, + c3_y* hun_y) { - uv_buf_t buf_u = uv_buf_init((c3_c*)hun_y, len_w); - _term_it_write(uty_u, &buf_u, (void*)hun_y); + if ( len_w ) { + uv_buf_t buf_u = uv_buf_init((c3_c*)hun_y, len_w); + _term_it_write(uty_u, &buf_u, (void*)hun_y); + } + else { + c3_free(hun_y); + } } /* _term_it_send_csi(): send csi escape sequence From 9ada9861f63985dd7f9bcfa0a59dc555539243df Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Mon, 13 Sep 2021 11:52:40 -0400 Subject: [PATCH 098/104] vere: refactors _term_it_send_csi() --- pkg/urbit/vere/io/term.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index a15f264547..8a337fe6ee 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -342,25 +342,24 @@ _term_it_send_csi(u3_utty *uty_u, c3_c cmd_c, c3_w num_w, ...) // argument digits (5 per arg) and separators (1 per arg, minus 1). // freed via _term_it_write. // - c3_c* pas_c = malloc( sizeof(*pas_c) * (2 + num_w * 6) ); - c3_c was_c = 0; + c3_c* pas_c = c3_malloc( 2 + num_w * 6 ); + c3_y len_y = 0; - pas_c[was_c++] = '\033'; - pas_c[was_c++] = '['; + pas_c[len_y++] = '\033'; + pas_c[len_y++] = '['; - while ( num_w > 0 ) { + while ( num_w-- ) { c3_w par_w = va_arg(ap, c3_w); - was_c += sprintf(pas_c+was_c, "%d", par_w); + len_y += sprintf(pas_c+len_y, "%d", par_w); - if ( --num_w > 0 ) { - pas_c[was_c++] = ';'; + if ( num_w ) { + pas_c[len_y++] = ';'; } } - pas_c[was_c++] = cmd_c; + pas_c[len_y++] = cmd_c; - uv_buf_t pas_u = uv_buf_init(pas_c, was_c); - _term_it_write(uty_u, &pas_u, pas_c); + _term_it_send(uty_u, len_y, (c3_y*)pas_c); va_end(ap); } From 85b3dbcaa1cca6b61803b8b5f43fd98aa6252d10 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Tue, 14 Sep 2021 11:26:42 -0400 Subject: [PATCH 099/104] vere: renames terminal streams for clarity, removes unused uv_tcp_t --- pkg/urbit/compat/mingw/ptty.c | 8 ++++---- pkg/urbit/compat/posix/ptty.c | 8 ++++---- pkg/urbit/include/vere/vere.h | 5 ++--- pkg/urbit/vere/io/term.c | 6 +++--- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/pkg/urbit/compat/mingw/ptty.c b/pkg/urbit/compat/mingw/ptty.c index 063db564c5..7ad2962c44 100644 --- a/pkg/urbit/compat/mingw/ptty.c +++ b/pkg/urbit/compat/mingw/ptty.c @@ -126,10 +126,10 @@ u3_ptty_init(uv_loop_t* lup_u, const c3_c** err_c) uty_u->wsz_f = _ttyf_get_winsize; } } else { - if ( 0 == (e = uv_pipe_init(lup_u, &uty_u->pin_u.pop_u, 0)) && - 0 == (e = uv_pipe_init(lup_u, &uty_u->pop_u.pop_u, 0)) && - 0 == (e = uv_pipe_open(&uty_u->pin_u.pop_u, 0)) && - 0 == (e = uv_pipe_open(&uty_u->pop_u.pop_u, 1)) ) + if ( 0 == (e = uv_pipe_init(lup_u, &uty_u->pin_u.pip_u, 0)) && + 0 == (e = uv_pipe_init(lup_u, &uty_u->pop_u.pip_u, 0)) && + 0 == (e = uv_pipe_open(&uty_u->pin_u.pip_u, 0)) && + 0 == (e = uv_pipe_open(&uty_u->pop_u.pip_u, 1)) ) { fprintf(stderr, "vere: running interactive in a terminal emulator is experimental\r\n" " use -t to disable interactivity or use native Windows console\r\n") ; diff --git a/pkg/urbit/compat/posix/ptty.c b/pkg/urbit/compat/posix/ptty.c index 7623f9c403..7c1a17f009 100644 --- a/pkg/urbit/compat/posix/ptty.c +++ b/pkg/urbit/compat/posix/ptty.c @@ -147,10 +147,10 @@ u3_ptty_init(uv_loop_t* lup_u, const c3_c** err_c) return NULL; } - uv_pipe_init(lup_u, &uty_u->pin_u.pop_u, 0); - uv_pipe_init(lup_u, &uty_u->pop_u.pop_u, 0); - uv_pipe_open(&uty_u->pin_u.pop_u, 0); - uv_pipe_open(&uty_u->pop_u.pop_u, 1); + uv_pipe_init(lup_u, &uty_u->pin_u.pip_u, 0); + uv_pipe_init(lup_u, &uty_u->pop_u.pip_u, 0); + uv_pipe_open(&uty_u->pin_u.pip_u, 0); + uv_pipe_open(&uty_u->pop_u.pip_u, 1); // Load old terminal state to restore. // diff --git a/pkg/urbit/include/vere/vere.h b/pkg/urbit/include/vere/vere.h index 20e6b41c30..023635f35c 100644 --- a/pkg/urbit/include/vere/vere.h +++ b/pkg/urbit/include/vere/vere.h @@ -222,9 +222,8 @@ /* u3_ustm: uv stream. */ typedef union _u3_ustm { - uv_pipe_t pop_u; - uv_tcp_t wax_u; - uv_tty_t tty_u; + uv_pipe_t pip_u; + uv_tty_t tty_u; } u3_ustm; /* u3_ttyf: simple unix tty function. diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index 8a337fe6ee..32d0358097 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -97,9 +97,9 @@ u3_term_log_init(void) uty_u = c3_calloc(sizeof(u3_utty)); uty_u->fid_i = 1; - uv_pipe_init(u3L, &(uty_u->pin_u.pop_u), 0); - uv_pipe_init(u3L, &(uty_u->pop_u.pop_u), 0); - uv_pipe_open(&(uty_u->pop_u.pop_u), uty_u->fid_i); + uv_pipe_init(u3L, &(uty_u->pin_u.pip_u), 0); + uv_pipe_init(u3L, &(uty_u->pop_u.pip_u), 0); + uv_pipe_open(&(uty_u->pop_u.pip_u), uty_u->fid_i); } else { // Initialize event processing. Rawdog it. From ebc656d372034bebbb206a79bf3eab640c1522f9 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Tue, 14 Sep 2021 14:48:42 -0400 Subject: [PATCH 100/104] build: update pmnsh to support cachix text/x-nix-narinfo responses --- pkg/urbit/compat/poor-mans-nix-shell.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/urbit/compat/poor-mans-nix-shell.sh b/pkg/urbit/compat/poor-mans-nix-shell.sh index cc18fabc2e..dddff0305d 100644 --- a/pkg/urbit/compat/poor-mans-nix-shell.sh +++ b/pkg/urbit/compat/poor-mans-nix-shell.sh @@ -61,7 +61,7 @@ buildnixdep () { narinfo="$cache/${hash}.narinfo" if curl -fLI "$narinfo" then - url="$cache/$(curl -fL -H "Accept: application/json" "$narinfo"|jq -r '.url')" + url="$cache/$(curl -fL "$narinfo"|while IFS=: read k v; do if [ "$k" == "URL" ]; then echo $v; fi; done)" echo Found $url strip=0 hash= From 9527d8518c9d267157e938e718adecaaee9c872b Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Fri, 10 Sep 2021 17:12:42 -0400 Subject: [PATCH 101/104] build: patch windows uv_pipe impl to allow null writes --- pkg/urbit/compat/mingw/uv.patch | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pkg/urbit/compat/mingw/uv.patch b/pkg/urbit/compat/mingw/uv.patch index 1338b78355..1a0a6d6941 100644 --- a/pkg/urbit/compat/mingw/uv.patch +++ b/pkg/urbit/compat/mingw/uv.patch @@ -15,6 +15,14 @@ index 0f2bb869b..f81245ec6 100644 if (err == ERROR_ACCESS_DENIED) { /* * SetNamedPipeHandleState can fail if the handle doesn't have either +@@ -1054,7 +1054,6 @@ static DWORD WINAPI uv_pipe_writefile_thread_proc(void* parameter) { + assert(req != NULL); + assert(req->type == UV_WRITE); + assert(handle->type == UV_NAMED_PIPE); +- assert(req->write_buffer.base); + + result = WriteFile(handle->handle, + req->write_buffer.base, diff --git a/src/win/tty.c b/src/win/tty.c index c359d5601..1b9d4f853 100644 --- a/src/win/tty.c From 0d18b13cb918e175dd728f25508f7a8ca40e740f Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Tue, 14 Sep 2021 23:56:28 -0400 Subject: [PATCH 102/104] u3: replaces spurious bloq-size bail:exit's in +rap and +rep jets --- pkg/urbit/jets/c/rap.c | 2 +- pkg/urbit/jets/c/rep.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/urbit/jets/c/rap.c b/pkg/urbit/jets/c/rap.c index dbdf6f29fd..6daf6555c9 100644 --- a/pkg/urbit/jets/c/rap.c +++ b/pkg/urbit/jets/c/rap.c @@ -11,7 +11,7 @@ u3_noun b) { if ( !_(u3a_is_cat(a)) || (a >= 32) ) { - return u3m_bail(c3__exit); + return u3m_bail(c3__fail); } else { c3_g a_g = a; diff --git a/pkg/urbit/jets/c/rep.c b/pkg/urbit/jets/c/rep.c index b3e5a0d5f8..48ac5f8689 100644 --- a/pkg/urbit/jets/c/rep.c +++ b/pkg/urbit/jets/c/rep.c @@ -98,7 +98,7 @@ _block_rep(u3_atom a, u3_noun b) { if ( !_(u3a_is_cat(a)) || (a >= 32) ) { - return u3m_bail(c3__exit); + return u3m_bail(c3__fail); } else { c3_g a_g = a; From b0b2e3aec80a4fa5b7ef9eac7311b3577260fed1 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Wed, 15 Sep 2021 00:17:01 -0400 Subject: [PATCH 103/104] vere: adds backwards-compatibility to blit handling under -t --- pkg/urbit/vere/io/term.c | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index 32d0358097..c0fde1bce1 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -1392,6 +1392,7 @@ _term_ef_blit_lame(u3_utty* uty_u, _term_it_show_nel(uty_u); } break; + case c3__lin: //TMP backwards compatibility case c3__put: { _term_it_show_tour(uty_u, u3k(u3t(blt))); _term_it_show_nel(uty_u); From c270708b762a692710935f9b97cbfc572bab684d Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Wed, 15 Sep 2021 00:19:43 -0400 Subject: [PATCH 104/104] vere: adds backwards-compatibility TODO comments for terminal inputs --- pkg/urbit/vere/io/term.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index c0fde1bce1..e2b6376ca3 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -664,10 +664,15 @@ _term_io_suck_char(u3_utty* uty_u, c3_y cay_y) else { if ( (cay_y >= 'a') && (cay_y <= 'z') ) { tat_u->esc.ape = c3n; + // XX for backwards compatibility, check kelvin version + // and fallback to [%met @c] + // _term_io_belt(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)); } else if ( ('[' == cay_y) || ('O' == cay_y) ) { @@ -732,6 +737,8 @@ _term_io_suck_char(u3_utty* uty_u, c3_y cay_y) _term_io_belt(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)))); } else if ( 27 == cay_y ) {