ofs | hex dump | ascii |
---|
0000 | 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 02 00 03 00 01 00 00 00 4f 5d 00 09 34 00 00 00 | .ELF....................O]..4... |
0020 | 00 00 00 00 00 00 00 00 34 00 20 00 02 00 00 00 00 00 00 00 01 00 00 00 74 00 00 00 74 00 00 09 | ........4...............t...t... |
0040 | 74 00 00 09 bb 65 00 00 bb 65 00 00 05 00 00 00 00 10 00 00 01 00 00 00 2f 66 00 00 2f 06 00 0a | t....e...e............../f../... |
0060 | 2f 06 00 0a 87 36 00 00 87 36 00 00 06 00 00 00 00 10 00 00 b8 01 00 00 00 cd 80 b8 03 00 00 00 | /....6...6...................... |
0080 | cd 80 c3 b8 04 00 00 00 cd 80 c3 b8 05 00 00 00 cd 80 c3 b8 06 00 00 00 cd 80 c3 b8 08 00 00 00 | ................................ |
00a0 | cd 80 c3 b8 0a 00 00 00 cd 80 c3 b8 26 00 00 00 cd 80 c3 b8 5a 00 00 00 cd 80 c3 bb 00 00 00 00 | ............&.......Z........... |
00c0 | b8 01 00 00 00 cd 80 55 89 e5 50 51 52 53 8b 5d 08 8b 4d 0c 81 c1 04 00 00 00 8b 55 0c 8b 12 b8 | .......U..PQRS.]..M........U.... |
00e0 | 04 00 00 00 cd 80 3d 00 00 00 00 0f 8c 08 00 00 00 5b 5a 59 58 89 ec 5d c3 bb ff 00 00 00 b8 01 | ......=..........[ZYX..]........ |
0100 | 00 00 00 cd 80 68 53 0b 00 0a 68 34 00 00 00 68 34 00 00 00 e8 12 00 00 00 81 c4 0c 00 00 00 bb | .....hS...h4...h4............... |
0120 | 00 00 00 00 b8 01 00 00 00 cd 80 55 89 e5 50 51 53 8b 45 08 8b 5d 0c 39 d8 75 17 68 70 0b 00 0a | ...........U..PQS.E..].9.u.hp... |
0140 | 68 02 00 00 00 e8 7d ff ff ff 81 c4 08 00 00 00 eb 2f 8b 4d 10 51 68 02 00 00 00 e8 67 ff ff ff | h.....}........../.M.Qh.....g... |
0160 | 81 c4 08 00 00 00 68 2f 06 00 0a 68 02 00 00 00 e8 52 ff ff ff 81 c4 08 00 00 00 ff 05 34 06 00 | ......h/...h.....R...........4.. |
0180 | 0a 5b 59 58 89 ec 5d c3 e8 fa 60 00 00 8b 1d 34 06 00 0a b8 01 00 00 00 cd 80 55 89 e5 51 52 53 | .[YX..]...`....4..........U..QRS |
01a0 | 56 57 8b 7d 08 8b 55 0c 8b 12 8b 75 0c 81 c6 04 00 00 00 b9 00 00 00 00 b8 00 00 00 00 bb 00 00 | VW.}..U....u.................... |
01c0 | 00 00 39 d1 7d 14 8a 07 8a 1e 3d 00 00 00 00 74 19 39 d8 75 15 41 47 46 eb e8 8a 07 3d 00 00 00 | ..9.}.....=....t.9.u.AGF....=... |
01e0 | 00 75 07 b8 01 00 00 00 eb 05 b8 00 00 00 00 5f 5e 5b 5a 59 89 ec 5d c3 68 75 0b 00 0a 68 42 06 | .u............._^[ZY..].hu...hB. |
0200 | 00 0a e8 93 ff ff ff 81 c4 08 00 00 00 68 79 0b 00 0a 68 01 00 00 00 50 e8 0e ff ff ff 81 c4 0c | .............hy...h....P........ |
0220 | 00 00 00 c3 68 b1 0b 00 0a 68 42 06 00 0a e8 67 ff ff ff 81 c4 08 00 00 00 68 b8 0b 00 0a 68 00 | ....h....hB....g.........h....h. |
0240 | 00 00 00 50 e8 e2 fe ff ff 81 c4 0c 00 00 00 c3 68 f4 0b 00 0a 68 43 06 00 0a e8 3b ff ff ff 81 | ...P............h....hC....;.... |
0260 | c4 08 00 00 00 68 fb 0b 00 0a 68 01 00 00 00 50 e8 b6 fe ff ff 81 c4 0c 00 00 00 c3 68 2e 0c 00 | .....h....h....P............h... |
0280 | 0a 68 43 06 00 0a e8 0f ff ff ff 81 c4 08 00 00 00 68 35 0c 00 0a 68 00 00 00 00 50 e8 8a fe ff | .hC..............h5...h....P.... |
02a0 | ff 81 c4 0c 00 00 00 c3 68 68 0c 00 0a 68 43 06 00 0a e8 e3 fe ff ff 81 c4 08 00 00 00 68 6c 0c | ........hh...hC..............hl. |
02c0 | 00 0a 68 00 00 00 00 50 e8 5e fe ff ff 81 c4 0c 00 00 00 c3 68 9f 0c 00 0a 68 43 06 00 0a e8 b7 | ..h....P.^..........h....hC..... |
02e0 | fe ff ff 81 c4 08 00 00 00 68 a5 0c 00 0a 68 00 00 00 00 50 e8 32 fe ff ff 81 c4 0c 00 00 00 c3 | .........h....h....P.2.......... |
0300 | 68 da 0c 00 0a 68 43 06 00 0a e8 8b fe ff ff 81 c4 08 00 00 00 68 e2 0c 00 0a 68 00 00 00 00 50 | h....hC..............h....h....P |
0320 | e8 06 fe ff ff 81 c4 0c 00 00 00 c3 68 00 00 00 00 68 00 00 00 00 89 e1 51 68 00 10 00 00 e8 17 | ............h....h......Qh...... |
0340 | 00 00 00 81 c4 08 00 00 00 8b 01 c7 00 34 00 00 00 89 c3 b8 01 00 00 00 cd 80 55 89 e5 50 53 8b | .............4............U..PS. |
0360 | 45 08 89 05 4b 06 00 0a bb 47 06 00 0a b8 5a 00 00 00 cd 80 8b 5d 0c 89 03 03 45 08 89 43 04 5b | E...K....G....Z......]....E..C.[ |
0380 | 58 89 ec 5d c3 e8 fd 5e 00 00 8b 1d 34 06 00 0a b8 01 00 00 00 cd 80 55 89 e5 51 52 56 57 8b 75 | X..]...^....4..........U..QRVW.u |
03a0 | 08 8b 7d 0c 8b 0e 39 0f 75 29 81 c6 04 00 00 00 01 f1 81 c7 04 00 00 00 31 c0 31 d2 39 ce 73 0c | ..}...9.u)..............1.1.9.s. |
03c0 | 8a 06 8a 17 39 d0 75 0b 46 47 eb f0 b8 01 00 00 00 eb 05 b8 00 00 00 00 5f 5e 5a 59 89 ec 5d c3 | ....9.u.FG.............._^ZY..]. |
03e0 | 68 16 0d 00 0a 68 1a 0d 00 0a e8 a8 ff ff ff 81 c4 08 00 00 00 68 1e 0d 00 0a 68 01 00 00 00 50 | h....h...............h....h....P |
0400 | e8 26 fd ff ff 81 c4 0c 00 00 00 c3 68 4a 0d 00 0a 68 51 0d 00 0a e8 7c ff ff ff 81 c4 08 00 00 | .&..........hJ...hQ....|........ |
0420 | 00 68 55 0d 00 0a 68 00 00 00 00 50 e8 fa fc ff ff 81 c4 0c 00 00 00 c3 68 85 0d 00 0a 68 8c 0d | .hU...h....P............h....h.. |
0440 | 00 0a e8 50 ff ff ff 81 c4 08 00 00 00 68 93 0d 00 0a 68 01 00 00 00 50 e8 ce fc ff ff 81 c4 0c | ...P.........h....h....P........ |
0460 | 00 00 00 c3 68 b5 0d 00 0a 68 bc 0d 00 0a e8 24 ff ff ff 81 c4 08 00 00 00 68 c3 0d 00 0a 68 00 | ....h....h.....$.........h....h. |
0480 | 00 00 00 50 e8 a2 fc ff ff 81 c4 0c 00 00 00 c3 55 89 e5 50 ff 75 0c ff 75 08 e8 f8 fe ff ff 81 | ...P............U..P.u..u....... |
04a0 | c4 08 00 00 00 ff 75 10 68 01 00 00 00 50 e8 78 fc ff ff 81 c4 0c 00 00 00 58 89 ec 5d c3 68 f5 | ......u.h....P.x.........X..].h. |
04c0 | 0d 00 0a 68 fc 0d 00 0a e8 c3 ff ff ff 81 c4 08 00 00 00 c3 55 89 e5 50 51 8b 45 08 8b 48 08 8d | ...h................U..PQ.E..H.. |
04e0 | 4c 08 0c c7 00 00 00 00 00 c7 40 04 00 00 00 00 81 c0 0c 00 00 00 39 c8 73 06 c6 00 00 40 eb f6 | L.........@...........9.s....@.. |
0500 | 59 58 89 ec 5d c3 55 89 e5 50 8b 45 08 c7 40 04 00 00 00 00 58 89 ec 5d c3 55 89 e5 50 51 8b 4d | YX..].U..P.E..@.....X..].U..PQ.M |
0520 | 08 68 63 06 00 0a 51 e8 2e fe ff ff 81 c4 08 00 00 00 8b 05 63 06 00 0a 89 05 5f 06 00 0a 81 e9 | .hc...Q.............c....._..... |
0540 | 0c 00 00 00 89 48 08 59 58 89 ec 5d c3 55 89 e5 50 51 52 53 56 57 8b 3d 5f 06 00 0a 8b 75 08 8b | .....H.YX..].U..PQRSVW.=_....u.. |
0560 | 0f 8b 57 08 56 8d 5c 17 0c 53 8d 5c 0f 0c 53 e8 2d 05 00 00 81 c4 0c 00 00 00 3d 00 00 00 00 74 | ..W.V.\..S.\..S.-.........=....t |
0580 | 20 01 07 8b 0f 68 2f 06 00 0a 8d 5c 17 0c 53 8d 5c 0f 0c 53 e8 08 05 00 00 81 c4 0c 00 00 00 01 | .....h/....\..S.\..S............ |
05a0 | 07 5f 5e 5b 5a 59 58 89 ec 5d c3 ff 35 5f 06 00 0a b8 6b 06 00 0a 89 05 5f 06 00 0a e8 c8 04 00 | ._^[ZYX..]..5_....k....._....... |
05c0 | 00 68 03 0e 00 0a e8 82 ff ff ff 81 c4 04 00 00 00 68 09 0e 00 0a 68 41 62 0a 00 b8 6b 06 00 0a | .h...............h....hAb...k... |
05e0 | ff 70 0c e8 43 fb ff ff 81 c4 0c 00 00 00 8f 05 5f 06 00 0a c3 ff 35 5f 06 00 0a b8 6b 06 00 0a | .p..C..........._.....5_....k... |
0600 | 89 05 5f 06 00 0a e8 7e 04 00 00 68 22 0e 00 0a e8 38 ff ff ff 81 c4 04 00 00 00 68 27 0e 00 0a | .._....~...h"....8.........h'... |
0620 | e8 28 ff ff ff 81 c4 04 00 00 00 68 2c 0e 00 0a 68 43 0a 44 0a b8 6b 06 00 0a ff 70 0c e8 e9 fa | .(.........h,...hC.D..k....p.... |
0640 | ff ff 81 c4 0c 00 00 00 8f 05 5f 06 00 0a c3 ff 35 5f 06 00 0a b8 6b 06 00 0a 89 05 5f 06 00 0a | .........._.....5_....k....._... |
0660 | e8 24 04 00 00 68 46 0e 00 0a e8 de fe ff ff 81 c4 04 00 00 00 68 4a 0e 00 0a 68 00 00 00 00 b8 | .$...hF..............hJ...h..... |
0680 | 6b 06 00 0a ff 70 0c e8 9f fa ff ff 81 c4 0c 00 00 00 8f 05 5f 06 00 0a c3 55 89 e5 ff 35 5f 06 | k....p.............._....U...5_. |
06a0 | 00 0a e8 5f fe ff ff 81 c4 04 00 00 00 ff 75 0c ff 75 08 e8 0a 00 00 00 81 c4 08 00 00 00 89 ec | ..._..........u..u.............. |
06c0 | 5d c3 55 89 e5 50 ff 75 08 e8 1f 00 00 00 81 c4 04 00 00 00 ff 75 0c 68 01 00 00 00 50 e8 49 fa | ].U..P.u.............u.h....P.I. |
06e0 | ff ff 81 c4 0c 00 00 00 58 89 ec 5d c3 55 89 e5 51 56 8b 35 5f 06 00 0a 8b 0e ff 76 04 39 4e 04 | ........X..].U..QV.5_......v.9N. |
0700 | 7d 3d ff 75 08 56 e8 d1 01 00 00 81 c4 08 00 00 00 3d 00 00 00 00 74 19 56 e8 d2 02 00 00 81 c4 | }=.u.V...........=....t.V....... |
0720 | 04 00 00 00 81 c4 04 00 00 00 b8 01 00 00 00 eb 16 56 e8 b9 02 00 00 81 c4 04 00 00 00 eb be 8f | .................V.............. |
0740 | 46 04 b8 00 00 00 00 59 89 ec 5d c3 ff 35 5f 06 00 0a b8 6b 06 00 0a 89 05 5f 06 00 0a e8 27 03 | F......Y..]..5_....k....._....'. |
0760 | 00 00 68 67 0e 00 0a e8 e1 fd ff ff 81 c4 04 00 00 00 68 6d 0e 00 0a e8 71 ff ff ff 81 c4 04 00 | ..hg..............hm....q....... |
0780 | 00 00 68 73 0e 00 0a 68 01 00 00 00 50 e8 99 f9 ff ff 81 c4 0c 00 00 00 8f 05 5f 06 00 0a c3 ff | ..hs...h....P............._..... |
07a0 | 35 5f 06 00 0a b8 6b 06 00 0a 89 05 5f 06 00 0a e8 d4 02 00 00 68 90 0e 00 0a e8 8e fd ff ff 81 | 5_....k....._........h.......... |
07c0 | c4 04 00 00 00 68 96 0e 00 0a e8 7e fd ff ff 81 c4 04 00 00 00 68 9c 0e 00 0a e8 0e ff ff ff 81 | .....h.....~.........h.......... |
07e0 | c4 04 00 00 00 68 a2 0e 00 0a 68 01 00 00 00 50 e8 36 f9 ff ff 81 c4 0c 00 00 00 8f 05 5f 06 00 | .....h....h....P.6..........._.. |
0800 | 0a c3 ff 35 5f 06 00 0a b8 6b 06 00 0a 89 05 5f 06 00 0a e8 71 02 00 00 68 d1 0e 00 0a e8 2b fd | ...5_....k....._....q...h.....+. |
0820 | ff ff 81 c4 04 00 00 00 68 d7 0e 00 0a e8 bb fe ff ff 81 c4 04 00 00 00 68 dd 0e 00 0a e8 ab fe | ........h...............h....... |
0840 | ff ff 81 c4 04 00 00 00 68 e3 0e 00 0a 68 00 00 00 00 50 e8 d3 f8 ff ff 81 c4 0c 00 00 00 8f 05 | ........h....h....P............. |
0860 | 5f 06 00 0a c3 ff 35 5f 06 00 0a b8 6b 06 00 0a 89 05 5f 06 00 0a e8 0e 02 00 00 68 1d 0f 00 0a | _.....5_....k....._........h.... |
0880 | e8 c8 fc ff ff 81 c4 04 00 00 00 68 23 0f 00 0a 68 00 00 00 00 b8 6b 06 00 0a ff 70 04 e8 89 f8 | ...........h#...h.....k....p.... |
08a0 | ff ff 81 c4 0c 00 00 00 68 72 0f 00 0a e8 3b fe ff ff 81 c4 04 00 00 00 68 78 0f 00 0a 68 00 00 | ........hr....;.........hx...h.. |
08c0 | 00 00 b8 6b 06 00 0a ff 70 04 e8 5c f8 ff ff 81 c4 0c 00 00 00 8f 05 5f 06 00 0a c3 55 89 e5 51 | ...k....p..\..........._....U..Q |
08e0 | 52 53 56 57 8b 55 0c 8d 72 04 8b 02 8d 0c 06 8b 7d 08 8d 5f 0c 8b 07 8d 14 03 8b 47 04 8d 3c 03 | RSVW.U..r.......}.._.......G..<. |
0900 | 39 ce 73 1e b8 00 00 00 00 39 d7 73 2a 31 c0 31 db 8a 07 8a 1e 39 d8 b8 00 00 00 00 75 19 47 46 | 9.s......9.s*1.1.....9......u.GF |
0920 | eb de 31 c0 8a 07 3d 0a 00 00 00 b8 01 00 00 00 74 05 b8 00 00 00 00 5f 5e 5b 5a 59 89 ec 5d c3 | pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */## the basic editor data structure, and how it displays text to the screen
# temporary main for this layer: just render the given text at the given
# screen dimensions, then stop
def main text:text [
local-scope
load-inputs
open-console
clear-screen null/screen # non-scrolling app
e:&:editor <- new-editor text, 0/left, 5/right
render null/screen, e
wait-for-event null/console
close-console
]
scenario editor-renders-text-to-screen [
local-scope
assume-screen 10/width, 5/height
e:&:editor <- new-editor [abc], 0/left, 10/right
run [
render screen, e
]
screen-should-contain [
# top line of screen reserved for menu
. .
.abc .
. .
]
]
container editor [
# editable text: doubly linked list of characters (head contains a special sentinel)
data:&:duplex-list:char
top-of-screen:&:duplex-list:char
bottom-of-screen:&:duplex-list:char
# location before cursor inside data
before-cursor:&:duplex-list:char
# raw bounds of display area on screen
# always displays from row 1 (leaving row 0 for a menu) and at most until bottom of screen
left:num
right:num
bottom:num
# raw screen coordinates of cursor
cursor-row:num
cursor-column:num
]
# creates a new editor widget
# right is exclusive
def new-editor s:text, left:num, right:num -> result:&:editor [
local-scope
load-inputs
# no clipping of bounds
right <- subtract right, 1
result <- new editor:type
# initialize screen-related fields
*result <- put *result, left:offset, left
*result <- put *result, right:offset, right
# initialize cursor coordinates
*result <- put *result, cursor-row:offset, 1/top
*result <- put *result, cursor-column:offset, left
# initialize empty contents
init:&:duplex-list:char <- push 167/§, null
*result <- put *result, data:offset, init
*result <- put *result, top-of-screen:offset, init
*result <- put *result, before-cursor:offset, init
result <- insert-text result, s
<editor-initialization>
]
def insert-text editor:&:editor, text:text -> editor:&:editor [
local-scope
load-inputs
curr:&:duplex-list:char <- get *editor, data:offset
insert curr, text
]
scenario editor-initializes-without-data [
local-scope
assume-screen 5/width, 3/height
run [
e:&:editor <- new-editor null/data, 2/left, 5/right
1:editor/raw <- copy *e
]
memory-should-contain [
# 1,2 (data) <- just the § sentinel
# 3,4 (top of screen) <- the § sentinel
# 5 (bottom of screen) <- null since text fits on screen
5 <- 0
6 <- 0
# 7,8 (before cursor) <- the § sentinel
9 <- 2 # left
10 <- 4 # right (inclusive)
11 <- 0 # bottom (not set until render)
12 <- 1 # cursor row
13 <- 2 # cursor column
]
screen-should-contain [
. .
. .
. .
]
]
# Assumes cursor should be at coordinates (cursor-row, cursor-column) and
# updates before-cursor to match. Might also move coordinates if they're
# outside text.
def render screen:&:screen, editor:&:editor -> last-row:num, last-column:num, screen:&:screen, editor:&:editor [
local-scope
load-inputs
return-unless editor, 1/top, 0/left
left:num <- get *editor, left:offset
screen-height:num <- screen-height screen
right:num <- get *editor, right:offset
# traversing editor
curr:&:duplex-list:char <- get *editor, top-of-screen:offset
prev:&:duplex-list:char <- copy curr # just in case curr becomes null and we can't compute prev
curr <- next curr
# traversing screen
color:num <- copy 7/white
row:num <- copy 1/top
column:num <- copy left
cursor-row:num <- get *editor, cursor-row:offset
cursor-column:num <- get *editor, cursor-column:offset
before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
screen <- move-cursor screen, row, column
{
+next-character
break-unless curr
off-screen?:bool <- greater-or-equal row, screen-height
break-if off-screen?
# update editor.before-cursor
# Doing so at the start of each iteration ensures it stays one step behind
# the current character.
{
at-cursor-row?:bool <- equal row, cursor-row
break-unless at-cursor-row?
at-cursor?:bool <- equal column, cursor-column
break-unless at-cursor?
before-cursor <- copy prev
}
c:char <- get *curr, value:offset
<character-c-received>
{
# newline? move to left rather than 0
newline?:bool <- equal c, 10/newline
break-unless newline?
# adjust cursor if necessary
{
at-cursor-row?:bool <- equal row, cursor-row
break-unless at-cursor-row?
left-of-cursor?:bool <- lesser-than column, cursor-column
break-unless left-of-cursor?
cursor-column <- copy column
before-cursor <- prev curr
}
# clear rest of line in this window
clear-line-until screen, right
# skip to next line
row <- add row, 1
column <- copy left
screen <- move-cursor screen, row, column
curr <- next curr
prev <- next prev
loop +next-character
}
{
# at right? wrap. even if there's only one more letter left; we need
# room for clicking on the cursor after it.
at-right?:bool <- equal column, right
break-unless at-right?
# print wrap icon
wrap-icon:char <- copy 8617/loop-back-to-left
print screen, wrap-icon, 245/grey
column <- copy left
row <- add row, 1
screen <- move-cursor screen, row, column
# don't increment curr
loop +next-character
}
print screen, c, color
curr <- next curr
prev <- next prev
column <- add column, 1
loop
}
# save first character off-screen
*editor <- put *editor, bottom-of-screen:offset, curr
# is cursor to the right of the last line? move to end
{
at-cursor-row?:bool <- equal row, cursor-row
cursor-outside-line?:bool <- lesser-or-equal column, cursor-column
before-cursor-on-same-line?:bool <- and at-cursor-row?, cursor-outside-line?
above-cursor-row?:bool <- lesser-than row, cursor-row
before-cursor?:bool <- or before-cursor-on-same-line?, above-cursor-row?
break-unless before-cursor?
cursor-row <- copy row
cursor-column <- copy column
before-cursor <- copy prev
}
*editor <- put *editor, bottom:offset, row
*editor <- put *editor, cursor-row:offset, cursor-row
*editor <- put *editor, cursor-column:offset, cursor-column
*editor <- put *editor, before-cursor:offset, before-cursor
clear-line-until screen, right
row <- add row, 1
return row, left/column
]
def clear-screen-from screen:&:screen, row:num, column:num, left:num, right:num -> screen:&:screen [
local-scope
load-inputs
# if it's the real screen, use the optimized primitive
{
break-if screen
clear-display-from row, column, left, right
return
}
# if not, go the slower route
screen <- move-cursor screen, row, column
clear-line-until screen, right
clear-rest-of-screen screen, row, left, right
]
def clear-rest-of-screen screen:&:screen, row:num, left:num, right:num -> screen:&:screen [
local-scope
load-inputs
row <- add row, 1
# if it's the real screen, use the optimized primitive
{
break-if screen
clear-display-from row, left, left, right
return
}
screen <- move-cursor screen, row, left
screen-height:num <- screen-height screen
{
at-bottom-of-screen?:bool <- greater-or-equal row, screen-height
break-if at-bottom-of-screen?
screen <- move-cursor screen, row, left
clear-line-until screen, right
row <- add row, 1
loop
}
]
scenario editor-prints-multiple-lines [
local-scope
assume-screen 5/width, 5/height
s:text <- new [abc
def]
e:&:editor <- new-editor s, 0/left, 5/right
run [
render screen, e
]
screen-should-contain [
. .
.abc .
.def .
. .
]
]
scenario editor-handles-offsets [
local-scope
assume-screen 5/width, 5/height
e:&:editor <- new-editor [abc], 1/left, 5/right
run [
render screen, e
]
screen-should-contain [
. .
. abc .
. .
]
]
scenario editor-prints-multiple-lines-at-offset [
local-scope
assume-screen 5/width, 5/height
s:text <- new [abc
def]
e:&:editor <- new-editor s, 1/left, 5/right
run [
render screen, e
]
screen-should-contain [
. .
. abc .
. def .
. .
]
]
scenario editor-wraps-long-lines [
local-scope
assume-screen 5/width, 5/height
e:&:editor <- new-editor [abc def], 0/left, 5/right
run [
render screen, e
]
screen-should-contain [
. .
.abc ↩.
.def .
. .
]
screen-should-contain-in-color 245/grey [
. .
. ↩.
. .
. .
]
]
scenario editor-wraps-barely-long-lines [
local-scope
assume-screen 5/width, 5/height
e:&:editor <- new-editor [abcde], 0/left, 5/right
run [
render screen, e
]
# still wrap, even though the line would fit. We need room to click on the
# end of the line
screen-should-contain [
. .
.abcd↩.
.e .
. .
]
screen-should-contain-in-color 245/grey [
. .
. ↩.
. .
. .
]
]
scenario editor-with-empty-text [
local-scope
assume-screen 5/width, 5/height
e:&:editor <- new-editor [], 0/left, 5/right
run [
render screen, e
3:num/raw <- get *e, cursor-row:offset
4:num/raw <- get *e, cursor-column:offset
]
screen-should-contain [
. .
. .
. .
]
memory-should-contain [
3 <- 1 # cursor row
4 <- 0 # cursor column
]
]
# just a little color for Mu code
scenario render-colors-comments [
local-scope
assume-screen 5/width, 5/height
s:text <- new [abc
# de
f]
e:&:editor <- new-editor s, 0/left, 5/right
run [
render screen, e
]
screen-should-contain [
. .
.abc .
.# de .
.f .
. .
]
screen-should-contain-in-color 12/lightblue, [
. .
. .
.# de .
. .
. .
]
screen-should-contain-in-color 7/white, [
. .
.abc .
. .
.f .
. .
]
]
after <character-c-received> [
color <- get-color color, c
]
# so far the previous color is all the information we need; that may change
def get-color color:num, c:char -> color:num [
local-scope
load-inputs
color-is-white?:bool <- equal color, 7/white
# if color is white and next character is '#', switch color to blue
{
break-unless color-is-white?
starting-comment?:bool <- equal c, 35/#
break-unless starting-comment?
trace 90, [app], [switch color back to blue]
return 12/lightblue
}
# if color is blue and next character is newline, switch color to white
{
color-is-blue?:bool <- equal color, 12/lightblue
break-unless color-is-blue?
ending-comment?:bool <- equal c, 10/newline
break-unless ending-comment?
trace 90, [app], [switch color back to white]
return 7/white
}
# if color is white (no comments) and next character is '<', switch color to red
{
break-unless color-is-white?
starting-assignment?:bool <- equal c, 60/<
break-unless starting-assignment?
return 1/red
}
# if color is red and next character is space, switch color to white
{
color-is-red?:bool <- equal color, 1/red
break-unless color-is-red?
ending-assignment?:bool <- equal c, 32/space
break-unless ending-assignment?
return 7/white
}
# otherwise no change
return color
]
scenario render-colors-assignment [
local-scope
assume-screen 8/width, 5/height
s:text <- new [abc
d <- e
f]
e:&:editor <- new-editor s, 0/left, 8/right
run [
render screen, e
]
screen-should-contain [
. .
.abc .
.d <- e .
.f .
. .
]
screen-should-contain-in-color 1/red, [
. .
. .
. <- .
. .
. .
]
]
|