srsh 0.8.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +12 -3
  3. data/README.md +446 -8
  4. data/bin/srsh +71 -0
  5. data/docs/assets/slut.txt +4 -0
  6. data/docs/assets/srsh-mark.svg +12 -0
  7. data/docs/css/style.css +696 -0
  8. data/docs/index.html +703 -0
  9. data/docs/js/app.js +203 -0
  10. data/examples/bridge.rsh +8 -0
  11. data/examples/calculator.rsh +253 -0
  12. data/examples/defer.rsh +14 -0
  13. data/examples/hot.rsh +14 -0
  14. data/examples/meta.rsh +20 -0
  15. data/examples/modules/text.rsh +6 -0
  16. data/examples/modules.rsh +6 -0
  17. data/examples/paste.rsh +15 -0
  18. data/examples/plugin.rb +8 -0
  19. data/examples/power.rsh +65 -0
  20. data/examples/tour.rsh +38 -0
  21. data/ext/srsh_native/extconf.rb +3 -0
  22. data/ext/srsh_native/srsh_native.c +48 -0
  23. data/language-docs/LANGUAGE.md +670 -0
  24. data/language-docs/MIGRATION.md +44 -0
  25. data/language-docs/SECURITY.md +44 -0
  26. data/lib/srsh/app.rb +261 -0
  27. data/lib/srsh/builtins.rb +492 -0
  28. data/lib/srsh/editor.rb +530 -0
  29. data/lib/srsh/errors.rb +23 -0
  30. data/lib/srsh/history.rb +74 -0
  31. data/lib/srsh/language/evaluator.rb +1175 -0
  32. data/lib/srsh/language/lexer.rb +316 -0
  33. data/lib/srsh/language/parser.rb +997 -0
  34. data/lib/srsh/language/token.rb +5 -0
  35. data/lib/srsh/language/values.rb +392 -0
  36. data/lib/srsh/paths.rb +29 -0
  37. data/lib/srsh/plugins.rb +59 -0
  38. data/lib/srsh/process_identity.rb +38 -0
  39. data/lib/srsh/security.rb +38 -0
  40. data/lib/srsh/shell/executor.rb +1182 -0
  41. data/lib/srsh/shell/job.rb +101 -0
  42. data/lib/srsh/shell/lexer.rb +114 -0
  43. data/lib/srsh/shell/terminal.rb +26 -0
  44. data/lib/srsh/state.rb +136 -0
  45. data/lib/srsh/theme.rb +108 -0
  46. data/lib/srsh/version.rb +3 -0
  47. data/lib/srsh.rb +11 -5
  48. metadata +61 -14
  49. data/exe/srsh +0 -6
  50. data/lib/srsh/runner.rb +0 -2416
@@ -0,0 +1,696 @@
1
+ :root {
2
+ --page: #e9e4d7;
3
+ --paper: #fffef8;
4
+ --ink: #20231f;
5
+ --muted: #5f625b;
6
+ --rule: #aaa58f;
7
+ --rule-dark: #777360;
8
+ --nav: #293f3b;
9
+ --nav-light: #d8e0d4;
10
+ --link: #153f75;
11
+ --visited: #5d356f;
12
+ --code: #efeee6;
13
+ --accent: #7c2f24;
14
+ --warning: #fff4c9;
15
+ --sans: Verdana, Geneva, Tahoma, sans-serif;
16
+ --serif: Georgia, "Times New Roman", serif;
17
+ --mono: "Courier New", Courier, monospace;
18
+ }
19
+
20
+ * {
21
+ box-sizing: border-box;
22
+ }
23
+
24
+ html {
25
+ min-height: 100%;
26
+ scroll-behavior: smooth;
27
+ }
28
+
29
+ body {
30
+ min-height: 100%;
31
+ margin: 0;
32
+ color: var(--ink);
33
+ background: var(--page);
34
+ font: 13px/1.6 var(--sans);
35
+ }
36
+
37
+ a {
38
+ color: var(--link);
39
+ text-decoration: underline;
40
+ text-underline-offset: 2px;
41
+ }
42
+
43
+ a:visited {
44
+ color: var(--visited);
45
+ }
46
+
47
+ a:hover,
48
+ a:focus {
49
+ color: var(--accent);
50
+ }
51
+
52
+ code,
53
+ pre,
54
+ kbd {
55
+ font-family: var(--mono);
56
+ }
57
+
58
+ code {
59
+ font-size: 1.03em;
60
+ }
61
+
62
+ h1,
63
+ h2,
64
+ h3 {
65
+ color: #28312e;
66
+ font-family: var(--serif);
67
+ font-weight: normal;
68
+ line-height: 1.25;
69
+ }
70
+
71
+ h1 {
72
+ margin: 0 0 14px;
73
+ padding-bottom: 6px;
74
+ border-bottom: 1px solid var(--rule);
75
+ font-size: 28px;
76
+ }
77
+
78
+ h2 {
79
+ margin: 28px 0 9px;
80
+ font-size: 20px;
81
+ }
82
+
83
+ h3 {
84
+ margin: 22px 0 7px;
85
+ font-size: 16px;
86
+ }
87
+
88
+ p {
89
+ margin: 8px 0 13px;
90
+ }
91
+
92
+ ul,
93
+ ol {
94
+ margin: 8px 0 14px;
95
+ padding-left: 25px;
96
+ }
97
+
98
+ li {
99
+ margin: 3px 0;
100
+ }
101
+
102
+ .site-width {
103
+ width: min(960px, calc(100% - 28px));
104
+ margin: 0 auto;
105
+ }
106
+
107
+ .skip-link {
108
+ position: absolute;
109
+ left: -10000px;
110
+ top: 6px;
111
+ z-index: 100;
112
+ padding: 6px 9px;
113
+ color: #000;
114
+ background: #fff;
115
+ border: 2px solid #000;
116
+ }
117
+
118
+ .skip-link:focus {
119
+ left: 6px;
120
+ }
121
+
122
+ .site-header {
123
+ border-bottom: 1px solid #1b2b28;
124
+ background: #f7f4ea;
125
+ }
126
+
127
+ .masthead {
128
+ display: flex;
129
+ min-height: 86px;
130
+ align-items: center;
131
+ gap: 16px;
132
+ }
133
+
134
+ .site-name {
135
+ display: inline-block;
136
+ color: var(--accent);
137
+ font: bold 35px/1 var(--serif);
138
+ letter-spacing: 2px;
139
+ text-decoration: none;
140
+ }
141
+
142
+ .site-name:visited {
143
+ color: var(--accent);
144
+ }
145
+
146
+ .site-title {
147
+ display: flex;
148
+ flex: 1;
149
+ flex-direction: column;
150
+ padding-left: 16px;
151
+ border-left: 1px solid var(--rule);
152
+ line-height: 1.35;
153
+ }
154
+
155
+ .site-title strong {
156
+ font-family: var(--serif);
157
+ font-size: 17px;
158
+ font-weight: normal;
159
+ }
160
+
161
+ .site-title span {
162
+ color: var(--muted);
163
+ font-size: 11px;
164
+ }
165
+
166
+ .version-box {
167
+ padding: 5px 8px;
168
+ color: #373a35;
169
+ background: #e3e0d3;
170
+ border: 1px solid var(--rule);
171
+ font: 11px var(--mono);
172
+ }
173
+
174
+ .main-nav {
175
+ color: #fff;
176
+ background: var(--nav);
177
+ border-top: 1px solid #172522;
178
+ }
179
+
180
+ .main-nav .site-width {
181
+ display: flex;
182
+ align-items: stretch;
183
+ }
184
+
185
+ .main-nav a,
186
+ .main-nav a:visited {
187
+ display: block;
188
+ padding: 8px 13px;
189
+ color: #fff;
190
+ border-right: 1px solid #546761;
191
+ text-decoration: none;
192
+ font-size: 12px;
193
+ }
194
+
195
+ .main-nav a:first-child {
196
+ border-left: 1px solid #546761;
197
+ }
198
+
199
+ .main-nav a:hover,
200
+ .main-nav a:focus,
201
+ .main-nav a.current {
202
+ color: #16221f;
203
+ background: var(--nav-light);
204
+ }
205
+
206
+ .status-line {
207
+ padding: 5px 9px;
208
+ color: #5c5c52;
209
+ background: #dedacc;
210
+ border-right: 1px solid var(--rule);
211
+ border-bottom: 1px solid var(--rule);
212
+ border-left: 1px solid var(--rule);
213
+ font: 10px/1.4 var(--mono);
214
+ }
215
+
216
+ .site-body {
217
+ min-height: 620px;
218
+ padding: 24px 26px 38px;
219
+ background: var(--paper);
220
+ border-right: 1px solid var(--rule);
221
+ border-bottom: 1px solid var(--rule);
222
+ border-left: 1px solid var(--rule);
223
+ }
224
+
225
+ .page {
226
+ display: none;
227
+ }
228
+
229
+ .page.active {
230
+ display: block;
231
+ }
232
+
233
+ .page-heading {
234
+ margin-bottom: 22px;
235
+ }
236
+
237
+ .page-heading p {
238
+ max-width: 72ch;
239
+ color: var(--muted);
240
+ }
241
+
242
+ .lead {
243
+ margin-top: 2px;
244
+ font: 17px/1.5 var(--serif);
245
+ }
246
+
247
+ .home-layout {
248
+ display: grid;
249
+ grid-template-columns: minmax(0, 1fr) 230px;
250
+ gap: 28px;
251
+ }
252
+
253
+ .home-layout > * {
254
+ min-width: 0;
255
+ }
256
+
257
+ .home-side h2,
258
+ .side-box h2 {
259
+ margin-top: 0;
260
+ font-size: 17px;
261
+ }
262
+
263
+ .side-box {
264
+ margin-bottom: 16px;
265
+ padding: 12px;
266
+ background: #f2f0e7;
267
+ border: 1px solid var(--rule);
268
+ }
269
+
270
+ .side-box p:last-child,
271
+ .side-box ul:last-child,
272
+ .side-box pre:last-child {
273
+ margin-bottom: 0;
274
+ }
275
+
276
+ .side-box pre {
277
+ overflow-x: auto;
278
+ margin: 8px 0;
279
+ padding: 8px;
280
+ background: #fff;
281
+ border: 1px solid #c6c2b3;
282
+ font-size: 11px;
283
+ line-height: 1.45;
284
+ }
285
+
286
+ .download-box {
287
+ border-top: 4px solid var(--accent);
288
+ }
289
+
290
+ .download-link,
291
+ .download-link:visited {
292
+ display: block;
293
+ margin: 8px 0;
294
+ padding: 8px 10px;
295
+ color: #fff;
296
+ background: #6b2d25;
297
+ border: 1px solid #4e1c17;
298
+ text-align: center;
299
+ text-decoration: none;
300
+ font-weight: bold;
301
+ }
302
+
303
+ .download-link:hover,
304
+ .download-link:focus {
305
+ color: #fff;
306
+ background: #823b30;
307
+ }
308
+
309
+ .download-link.secondary,
310
+ .download-link.secondary:visited {
311
+ color: #1f2b27;
312
+ background: #dfe4db;
313
+ border-color: #89928a;
314
+ }
315
+
316
+ .download-link.secondary:hover,
317
+ .download-link.secondary:focus {
318
+ color: #000;
319
+ background: #eef1ea;
320
+ }
321
+
322
+ .small {
323
+ font-size: 10px;
324
+ }
325
+
326
+ .plain-links {
327
+ margin: 0;
328
+ padding: 0;
329
+ list-style: none;
330
+ }
331
+
332
+ .plain-links li {
333
+ padding: 3px 0;
334
+ border-bottom: 1px dotted #b8b4a4;
335
+ }
336
+
337
+ .plain-links li:last-child {
338
+ border-bottom: 0;
339
+ }
340
+
341
+ .columns {
342
+ display: grid;
343
+ grid-template-columns: 1fr 1fr;
344
+ gap: 24px;
345
+ }
346
+
347
+ .columns ul {
348
+ margin-top: 0;
349
+ }
350
+
351
+ .listing {
352
+ position: relative;
353
+ max-width: 100%;
354
+ margin: 12px 0 18px;
355
+ border: 1px solid #aaa99f;
356
+ background: var(--code);
357
+ }
358
+
359
+ .listing-title {
360
+ padding: 4px 8px;
361
+ color: #fff;
362
+ background: #5f665e;
363
+ border-bottom: 1px solid #444a44;
364
+ font: 10px/1.4 var(--sans);
365
+ text-transform: uppercase;
366
+ letter-spacing: .6px;
367
+ }
368
+
369
+ .listing pre {
370
+ overflow: auto;
371
+ margin: 0;
372
+ padding: 12px 13px;
373
+ font-size: 12px;
374
+ line-height: 1.55;
375
+ tab-size: 2;
376
+ }
377
+
378
+ .copy-button {
379
+ position: absolute;
380
+ top: 5px;
381
+ right: 5px;
382
+ padding: 2px 6px;
383
+ color: #242722;
384
+ background: #deddd4;
385
+ border: 1px solid #77776f;
386
+ font: 10px var(--sans);
387
+ cursor: pointer;
388
+ }
389
+
390
+ .listing-title + pre + .copy-button {
391
+ color: #fff;
392
+ background: #737a72;
393
+ border-color: #babdb8;
394
+ }
395
+
396
+ .copy-button:hover,
397
+ .copy-button:focus {
398
+ background: #fff;
399
+ color: #000;
400
+ }
401
+
402
+ .reference-table {
403
+ width: 100%;
404
+ margin: 12px 0 19px;
405
+ border-collapse: collapse;
406
+ font-size: 12px;
407
+ }
408
+
409
+ .reference-table th,
410
+ .reference-table td {
411
+ padding: 7px 9px;
412
+ border: 1px solid #aaa99f;
413
+ text-align: left;
414
+ vertical-align: top;
415
+ }
416
+
417
+ .reference-table thead th,
418
+ .reference-table tbody th {
419
+ background: #e3e2d9;
420
+ font-weight: bold;
421
+ }
422
+
423
+ .reference-table tbody tr:nth-child(even) td {
424
+ background: #f7f6ef;
425
+ }
426
+
427
+ .reference-table.compact tbody th {
428
+ width: 180px;
429
+ }
430
+
431
+ .project-links tbody th {
432
+ width: 130px;
433
+ }
434
+
435
+ .doc-search {
436
+ display: flex;
437
+ align-items: center;
438
+ gap: 7px;
439
+ padding: 9px;
440
+ background: #eeece2;
441
+ border: 1px solid var(--rule);
442
+ }
443
+
444
+ .doc-search label {
445
+ font-weight: bold;
446
+ }
447
+
448
+ .doc-search input {
449
+ min-width: 120px;
450
+ flex: 1;
451
+ padding: 5px 6px;
452
+ background: #fff;
453
+ border: 1px solid #77776f;
454
+ border-radius: 0;
455
+ font: 12px var(--sans);
456
+ }
457
+
458
+ .doc-search button {
459
+ padding: 5px 10px;
460
+ background: #deddd4;
461
+ border: 1px solid #77776f;
462
+ border-radius: 0;
463
+ font: 12px var(--sans);
464
+ cursor: pointer;
465
+ }
466
+
467
+ .search-results {
468
+ margin-top: 8px;
469
+ padding: 8px 10px;
470
+ background: #fff;
471
+ border: 1px solid var(--rule);
472
+ }
473
+
474
+ .search-results strong {
475
+ display: block;
476
+ margin-bottom: 3px;
477
+ }
478
+
479
+ .search-results ul {
480
+ margin: 3px 0;
481
+ }
482
+
483
+ .manual-layout {
484
+ display: grid;
485
+ grid-template-columns: 190px minmax(0, 1fr);
486
+ gap: 25px;
487
+ align-items: start;
488
+ }
489
+
490
+ .toc {
491
+ position: sticky;
492
+ top: 12px;
493
+ padding: 10px;
494
+ background: #efede4;
495
+ border: 1px solid var(--rule);
496
+ font-size: 10px;
497
+ line-height: 1.35;
498
+ }
499
+
500
+ .toc strong {
501
+ display: block;
502
+ margin-bottom: 6px;
503
+ padding-bottom: 5px;
504
+ border-bottom: 1px solid var(--rule);
505
+ font-size: 11px;
506
+ }
507
+
508
+ .toc a {
509
+ display: block;
510
+ padding: 3px 2px;
511
+ text-decoration: none;
512
+ }
513
+
514
+ .toc a:hover,
515
+ .toc a:focus,
516
+ .toc a.current {
517
+ color: var(--accent);
518
+ text-decoration: underline;
519
+ }
520
+
521
+ .manual {
522
+ min-width: 0;
523
+ }
524
+
525
+ .manual section {
526
+ scroll-margin-top: 12px;
527
+ padding: 0 0 22px;
528
+ border-bottom: 1px solid #c2bead;
529
+ }
530
+
531
+ .manual section:first-child h2 {
532
+ margin-top: 0;
533
+ }
534
+
535
+ .word-list {
536
+ margin: 10px 0 15px;
537
+ padding: 8px 10px;
538
+ background: #efeee6;
539
+ border: 1px solid #c0beb3;
540
+ line-height: 1.8;
541
+ }
542
+
543
+ .warning {
544
+ margin: 10px 0 15px;
545
+ padding: 8px 10px;
546
+ background: var(--warning);
547
+ border: 1px solid #b7a66a;
548
+ }
549
+
550
+ .back-top {
551
+ text-align: right;
552
+ font-size: 11px;
553
+ }
554
+
555
+ .download-panel {
556
+ margin: 16px 0 28px;
557
+ padding: 15px;
558
+ background: #f0eee4;
559
+ border: 1px solid var(--rule-dark);
560
+ border-top: 5px solid var(--accent);
561
+ }
562
+
563
+ .download-panel h2 {
564
+ margin-top: 0;
565
+ }
566
+
567
+ .download-buttons {
568
+ display: flex;
569
+ flex-wrap: wrap;
570
+ gap: 9px;
571
+ }
572
+
573
+ .download-buttons .download-link {
574
+ display: inline-block;
575
+ min-width: 150px;
576
+ margin: 0;
577
+ }
578
+
579
+ .site-footer {
580
+ padding: 18px 0 28px;
581
+ color: #55574f;
582
+ font-size: 10px;
583
+ text-align: center;
584
+ }
585
+
586
+ .site-footer .site-width {
587
+ display: flex;
588
+ flex-wrap: wrap;
589
+ justify-content: center;
590
+ gap: 8px;
591
+ }
592
+
593
+ .copy-notice {
594
+ position: fixed;
595
+ right: 12px;
596
+ bottom: 12px;
597
+ padding: 6px 10px;
598
+ color: #fff;
599
+ background: #222;
600
+ border: 1px solid #000;
601
+ font-size: 11px;
602
+ }
603
+
604
+ @media (max-width: 760px) {
605
+ .site-width {
606
+ width: min(100% - 16px, 960px);
607
+ }
608
+
609
+ .masthead {
610
+ min-height: 70px;
611
+ }
612
+
613
+ .site-title {
614
+ display: none;
615
+ }
616
+
617
+ .main-nav .site-width {
618
+ flex-wrap: wrap;
619
+ }
620
+
621
+ .main-nav a {
622
+ flex: 1 0 auto;
623
+ text-align: center;
624
+ }
625
+
626
+ .status-line {
627
+ overflow-x: auto;
628
+ white-space: nowrap;
629
+ }
630
+
631
+ .site-body {
632
+ padding: 19px 16px 30px;
633
+ }
634
+
635
+ .home-layout,
636
+ .manual-layout,
637
+ .columns {
638
+ grid-template-columns: 1fr;
639
+ }
640
+
641
+ .home-side {
642
+ border-top: 1px solid var(--rule);
643
+ padding-top: 20px;
644
+ }
645
+
646
+ .toc {
647
+ position: static;
648
+ display: grid;
649
+ grid-template-columns: 1fr 1fr;
650
+ gap: 1px 10px;
651
+ }
652
+
653
+ .toc strong {
654
+ grid-column: 1 / -1;
655
+ }
656
+
657
+ .doc-search {
658
+ align-items: stretch;
659
+ flex-direction: column;
660
+ }
661
+
662
+ .reference-table {
663
+ display: block;
664
+ overflow-x: auto;
665
+ }
666
+ }
667
+
668
+ @media (max-width: 440px) {
669
+ .site-name {
670
+ font-size: 29px;
671
+ }
672
+
673
+ .version-box {
674
+ font-size: 9px;
675
+ }
676
+
677
+ .main-nav a,
678
+ .main-nav a:visited {
679
+ width: 50%;
680
+ border-bottom: 1px solid #546761;
681
+ }
682
+
683
+ .toc {
684
+ grid-template-columns: 1fr;
685
+ }
686
+
687
+ .listing pre {
688
+ font-size: 11px;
689
+ }
690
+ }
691
+
692
+ @media (prefers-reduced-motion: reduce) {
693
+ html {
694
+ scroll-behavior: auto;
695
+ }
696
+ }