mirror of
https://github.com/urbit/shrub.git
synced 2024-12-20 01:01:37 +03:00
Merge pull request #6194 from urbit/next/416
next: zuse 416 (terminal edition)
This commit is contained in:
commit
23dcad2394
32
.github/actions/glob/entrypoint.sh
vendored
32
.github/actions/glob/entrypoint.sh
vendored
@ -1,32 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
cd "$GITHUB_WORKSPACE" || exit
|
|
||||||
|
|
||||||
echo "$2" | base64 -d > service-account
|
|
||||||
echo "$3" | base64 -d > id_ssh
|
|
||||||
echo "$4" | base64 -d > id_ssh.pub
|
|
||||||
|
|
||||||
chmod 600 service-account
|
|
||||||
chmod 600 id_ssh
|
|
||||||
chmod 600 id_ssh.pub
|
|
||||||
|
|
||||||
janeway release glob-all --dev --no-pill \
|
|
||||||
--credentials service-account \
|
|
||||||
--ssh-key id_ssh \
|
|
||||||
--ci \
|
|
||||||
| bash
|
|
||||||
|
|
||||||
SHORTHASH=$(git rev-parse --short HEAD)
|
|
||||||
|
|
||||||
janeway release prepare-ota arvo-glob-"$SHORTHASH" "$1" \
|
|
||||||
--credentials service-account \
|
|
||||||
--ssh-key id_ssh \
|
|
||||||
--ci \
|
|
||||||
| bash
|
|
||||||
|
|
||||||
janeway release perform-ota "$1" \
|
|
||||||
--credentials service-account \
|
|
||||||
--ssh-key id_ssh \
|
|
||||||
--ci \
|
|
||||||
| bash
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
FROM tloncorp/janeway:v0.15.4
|
FROM tloncorp/janeway:v0.17.0
|
||||||
COPY entrypoint.sh /entrypoint.sh
|
COPY entrypoint.sh /entrypoint.sh
|
||||||
EXPOSE 22/tcp
|
EXPOSE 22/tcp
|
||||||
ENTRYPOINT ["/entrypoint.sh"]
|
ENTRYPOINT ["/entrypoint.sh"]
|
@ -1,18 +1,21 @@
|
|||||||
name: 'glob'
|
name: 'ota'
|
||||||
description: 'Create a glob and deploy it to a moon'
|
description: 'perform an OTA update of arvo on a remote ship'
|
||||||
inputs:
|
inputs:
|
||||||
ship:
|
ship:
|
||||||
description: "Ship to deploy to"
|
description: "target ship"
|
||||||
required: true
|
required: true
|
||||||
credentials:
|
credentials:
|
||||||
description: "base64-encoded GCP Service Account credentials"
|
description: "base64-encoded GCP Service Account credentials"
|
||||||
required: true
|
required: true
|
||||||
ssh-sec-key:
|
ssh-sec-key:
|
||||||
description: "A base64-encoded SSH secret key for the container to use"
|
description: "base64-encoded SSH secret key for the container to use"
|
||||||
required: true
|
required: true
|
||||||
ssh-pub-key:
|
ssh-pub-key:
|
||||||
description: "The corresponding base64-encoded SSH public key"
|
description: "base64-encoded corresponding SSH public key"
|
||||||
required: true
|
required: true
|
||||||
|
ref:
|
||||||
|
description: "git ref of arvo source to check out"
|
||||||
|
required: false
|
||||||
|
|
||||||
runs:
|
runs:
|
||||||
using: 'docker'
|
using: 'docker'
|
||||||
@ -22,4 +25,4 @@ runs:
|
|||||||
- ${{ inputs.credentials }}
|
- ${{ inputs.credentials }}
|
||||||
- ${{ inputs.ssh-sec-key }}
|
- ${{ inputs.ssh-sec-key }}
|
||||||
- ${{ inputs.ssh-pub-key }}
|
- ${{ inputs.ssh-pub-key }}
|
||||||
|
- ${{ inputs.ref }}
|
20
.github/actions/ota/entrypoint.sh
vendored
Executable file
20
.github/actions/ota/entrypoint.sh
vendored
Executable file
@ -0,0 +1,20 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
echo "$2" | base64 -d > /service-account
|
||||||
|
echo "$3" | base64 -d > /id_ssh
|
||||||
|
echo "$4" | base64 -d > /id_ssh.pub
|
||||||
|
|
||||||
|
chmod 600 /service-account
|
||||||
|
chmod 600 /id_ssh
|
||||||
|
chmod 600 /id_ssh.pub
|
||||||
|
|
||||||
|
janeway \
|
||||||
|
--ci \
|
||||||
|
--verbose \
|
||||||
|
--credentials /service-account \
|
||||||
|
--ssh-key /id_ssh \
|
||||||
|
release ota \
|
||||||
|
arvo \
|
||||||
|
"$1" \
|
||||||
|
${5:+"--ref"} ${5:+"$5"} \
|
||||||
|
| bash
|
27
.github/workflows/chromatic.yml
vendored
27
.github/workflows/chromatic.yml
vendored
@ -1,27 +0,0 @@
|
|||||||
name: Chromatic Deployment
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
paths:
|
|
||||||
- 'pkg/interface/**'
|
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- 'pkg/interface/**'
|
|
||||||
branches:
|
|
||||||
- 'release/next-userspace'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
chromatic-deployment:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: "Deploy Chromatic"
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- run: npm i && npm run bootstrap
|
|
||||||
- name: Publish to Chromatic
|
|
||||||
uses: chromaui/action@v1
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
|
|
||||||
workingDir: pkg/interface
|
|
20
.github/workflows/glob.yml
vendored
20
.github/workflows/glob.yml
vendored
@ -1,20 +0,0 @@
|
|||||||
name: glob
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- 'release/next-userspace'
|
|
||||||
jobs:
|
|
||||||
glob:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: "Create and deploy a glob to ~hanruc-nalfus-nidsut-tomdun"
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
lfs: true
|
|
||||||
- uses: ./.github/actions/glob
|
|
||||||
with:
|
|
||||||
ship: 'hanruc-nalfus-nidsut-tomdun'
|
|
||||||
credentials: ${{ secrets.JANEWAY_SERVICE_KEY }}
|
|
||||||
ssh-sec-key: ${{ secrets.JANEWAY_SSH_SEC_KEY }}
|
|
||||||
ssh-pub-key: ${{ secrets.JANEWAY_SSH_PUB_KEY }}
|
|
||||||
|
|
27
.github/workflows/merge-master.yml
vendored
27
.github/workflows/merge-master.yml
vendored
@ -1,27 +0,0 @@
|
|||||||
name: merge
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- 'master'
|
|
||||||
jobs:
|
|
||||||
merge-to-next-js:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: "Merge master to release/next-userspace"
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: devmasx/merge-branch@v1.3.1
|
|
||||||
with:
|
|
||||||
type: now
|
|
||||||
target_branch: release/next-userspace
|
|
||||||
github_token: ${{ secrets.JANEWAY_BOT_TOKEN }}
|
|
||||||
|
|
||||||
merge-to-group-timer:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: "Merge master to ops/group-timer"
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: devmasx/merge-branch@v1.3.1
|
|
||||||
with:
|
|
||||||
type: now
|
|
||||||
target_branch: ops/group-timer
|
|
||||||
github_token: ${{ secrets.JANEWAY_BOT_TOKEN }}
|
|
17
.github/workflows/merge-release.yml
vendored
17
.github/workflows/merge-release.yml
vendored
@ -1,17 +0,0 @@
|
|||||||
name: ops-merge
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- 'release/*'
|
|
||||||
jobs:
|
|
||||||
merge-release-to-ops:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: "Merge to ops-tlon"
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: devmasx/merge-branch@v1.3.1
|
|
||||||
with:
|
|
||||||
type: now
|
|
||||||
target_branch: ops-tlon
|
|
||||||
github_token: ${{ secrets.JANEWAY_BOT_TOKEN }}
|
|
||||||
|
|
19
.github/workflows/ota.yml
vendored
Normal file
19
.github/workflows/ota.yml
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
name: ota
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'next/arvo'
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: "make an OTA update to arvo on ~binnec-dozzod-marzod"
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: ./.github/actions/ota
|
||||||
|
with:
|
||||||
|
ship: 'canary'
|
||||||
|
credentials: ${{ secrets.JANEWAY_SERVICE_KEY }}
|
||||||
|
ssh-sec-key: ${{ secrets.JANEWAY_SSH_SEC_KEY }}
|
||||||
|
ssh-pub-key: ${{ secrets.JANEWAY_SSH_PUB_KEY }}
|
||||||
|
ref: 'next/arvo'
|
@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:c4247c64a7d9fc0c0f1d2f017c21dd3464ddfe56529c7d6eef0e64554bd453e8
|
oid sha256:bd487cdb8294fdef6878f623bceb893553b36b2a616d22d30017b430361586fb
|
||||||
size 7611162
|
size 3889185
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:5123a1ac30b83ec026587574df1ce13a73e72d06588ff68b5c41c09e1bebb5b7
|
oid sha256:26ff86808886beb831e4a135f478e42ce83ef4a09ad24808b3fe97248ce7a6b7
|
||||||
size 949962
|
size 1136643
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:40bc203b8a2d2ebad81723da6fc946ee32d2f8a204884f50f9710177ae257d08
|
oid sha256:f4d585474b6df173dc1c172f343192ac88bd3ced1a9c7cf6877402722ac139de
|
||||||
size 5712264
|
size 5748201
|
||||||
|
70
doc/spec/nock/10.txt
Normal file
70
doc/spec/nock/10.txt
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
Author: Mencius Moldbug [moldbug@gmail.com]
|
||||||
|
Date: 9/15/2008
|
||||||
|
Version: 10K
|
||||||
|
|
||||||
|
1. Introduction
|
||||||
|
|
||||||
|
This file defines one function, "nock."
|
||||||
|
|
||||||
|
nock is in the public domain.
|
||||||
|
|
||||||
|
2. Data
|
||||||
|
|
||||||
|
A "noun" is either an "atom" or a "cell." An "atom" is an unsigned
|
||||||
|
integer of any size. A "cell" is an ordered pair of any two nouns,
|
||||||
|
the "head" and "tail."
|
||||||
|
|
||||||
|
3. Semantics
|
||||||
|
|
||||||
|
nock maps one noun to another. It doesn't always terminate.
|
||||||
|
|
||||||
|
4. Pseudocode
|
||||||
|
|
||||||
|
nock is defined in a pattern-matching pseudocode, below.
|
||||||
|
|
||||||
|
Brackets enclose cells. [a b c] is [a [b c]].
|
||||||
|
|
||||||
|
5. Definition
|
||||||
|
|
||||||
|
5.1 Transformations
|
||||||
|
|
||||||
|
*[a [b c] d] => [*[a b c] *[a d]]
|
||||||
|
*[a 0 b] => /[b a]
|
||||||
|
*[a 1 b] => [b]
|
||||||
|
*[a 2 b c d] => *[a 3 [0 1] 3 [1 c d] [1 0] 3 [1 2 3] [1 0] 5 5 b]
|
||||||
|
*[a 3 b] => **[a b]
|
||||||
|
*[a 4 b] => &*[a b]
|
||||||
|
*[a 5 b] => ^*[a b]
|
||||||
|
*[a 6 b] => =*[a b]
|
||||||
|
*[a] => *[a]
|
||||||
|
|
||||||
|
5.2 Operators
|
||||||
|
|
||||||
|
5.2.1 Goto [*]
|
||||||
|
|
||||||
|
*[a] -> nock[a]
|
||||||
|
|
||||||
|
5.2.2 Deep [&]
|
||||||
|
|
||||||
|
&[a b] -> 0
|
||||||
|
&[a] -> 1
|
||||||
|
|
||||||
|
5.2.4 Bump [^]
|
||||||
|
|
||||||
|
^[a b] -> ^[a b]
|
||||||
|
^[a] -> (a + 1)
|
||||||
|
|
||||||
|
5.2.5 Like [=]
|
||||||
|
|
||||||
|
=[a a] -> 0
|
||||||
|
=[a b] -> 1
|
||||||
|
=[a] -> =[a]
|
||||||
|
|
||||||
|
5.2.6 Snip [/]
|
||||||
|
|
||||||
|
/[1 a] -> a
|
||||||
|
/[2 a b] -> a
|
||||||
|
/[3 a b] -> b
|
||||||
|
/[(a + a) b] -> /[2 /[a b]]
|
||||||
|
/[(a + a + 1) b] -> /[3 /[a b]]
|
||||||
|
/[a] -> /[a]
|
74
doc/spec/nock/11.txt
Normal file
74
doc/spec/nock/11.txt
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
Author: Mencius Moldbug (moldbug@gmail.com)
|
||||||
|
Date: 5/25/2008
|
||||||
|
Version: 11K
|
||||||
|
|
||||||
|
1. Introduction
|
||||||
|
|
||||||
|
This file defines one function, "nock."
|
||||||
|
|
||||||
|
nock is in the public domain.
|
||||||
|
|
||||||
|
2. Data
|
||||||
|
|
||||||
|
A "noun" is either an "atom" or a "cell." An "atom" is an unsigned
|
||||||
|
integer of any size. A "cell" is an ordered pair of any two nouns,
|
||||||
|
the "head" and "tail."
|
||||||
|
|
||||||
|
3. Semantics
|
||||||
|
|
||||||
|
nock maps one noun to another. It doesn't always terminate.
|
||||||
|
|
||||||
|
4. Pseudocode
|
||||||
|
|
||||||
|
nock is defined in a pattern-matching pseudocode, below.
|
||||||
|
|
||||||
|
Parentheses enclose cells. (a b c) is (a (b c)).
|
||||||
|
|
||||||
|
5. Definition
|
||||||
|
|
||||||
|
5.1 Transformations
|
||||||
|
|
||||||
|
*(a (b c) d) => (*(a b c) *(a d))
|
||||||
|
*(a 0 b) => /(b a)
|
||||||
|
*(a 1 b) => (b)
|
||||||
|
*(a 2 b c d) => *(a 3 (0 1) 3 (1 c d) (1 0) 3 (1 2 3) (1 0) 5 5 b)
|
||||||
|
*(a 3 b) => **(a b)
|
||||||
|
*(a 4 b) => &*(a b)
|
||||||
|
*(a 5 b) => ^*(a b)
|
||||||
|
*(a 6 b) => =*(a b)
|
||||||
|
|
||||||
|
*(a 7 b c) => *(a 3 (((1 0) b) c) 1 0 3)
|
||||||
|
*(a 8 b c) => *(a c)
|
||||||
|
|
||||||
|
*(a) => *(a)
|
||||||
|
|
||||||
|
5.2 Operators
|
||||||
|
|
||||||
|
5.2.1 Goto (*)
|
||||||
|
|
||||||
|
*(a) -> nock(a)
|
||||||
|
|
||||||
|
5.2.2 Deep (&)
|
||||||
|
|
||||||
|
&(a b) -> 0
|
||||||
|
&(a) -> 1
|
||||||
|
|
||||||
|
5.2.4 Bump (^)
|
||||||
|
|
||||||
|
^(a b) -> ^(a b)
|
||||||
|
^(a) -> a + 1
|
||||||
|
|
||||||
|
5.2.5 Same (=)
|
||||||
|
|
||||||
|
=(a a) -> 0
|
||||||
|
=(a b) -> 1
|
||||||
|
=(a) -> =(a)
|
||||||
|
|
||||||
|
5.2.6 Snip (/)
|
||||||
|
|
||||||
|
/(1 a) -> a
|
||||||
|
/(2 a b) -> a
|
||||||
|
/(3 a b) -> b
|
||||||
|
/((a + a) b) -> /(2 /(a b))
|
||||||
|
/((a + a + 1) b) -> /(3 /(a b))
|
||||||
|
/(a) -> /(a)
|
75
doc/spec/nock/12.txt
Normal file
75
doc/spec/nock/12.txt
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
Author: Curtis Yarvin (curtis.yarvin@gmail.com)
|
||||||
|
Date: 3/28/2008
|
||||||
|
Version: 0.12
|
||||||
|
|
||||||
|
1. Introduction
|
||||||
|
|
||||||
|
This file defines one function, "nock."
|
||||||
|
|
||||||
|
nock is in the public domain.
|
||||||
|
|
||||||
|
2. Data
|
||||||
|
|
||||||
|
A "noun" is either an "atom" or a "cell." An "atom" is an unsigned
|
||||||
|
integer of any size. A "cell" is an ordered pair of any two nouns,
|
||||||
|
the "head" and "tail."
|
||||||
|
|
||||||
|
3. Semantics
|
||||||
|
|
||||||
|
nock maps one noun to another. It doesn't always terminate.
|
||||||
|
|
||||||
|
4. Pseudocode
|
||||||
|
|
||||||
|
nock is defined in a pattern-matching pseudocode, below.
|
||||||
|
|
||||||
|
Parentheses enclose cells. (a b c) is (a (b c)).
|
||||||
|
|
||||||
|
5. Definition
|
||||||
|
|
||||||
|
5.1 Transformations
|
||||||
|
|
||||||
|
*(a (b c) d) => (*(a b c) *(a d))
|
||||||
|
*(a 0 b) => /(b a)
|
||||||
|
*(a 1 b) => (b)
|
||||||
|
*(a 2 b c) => *(*(a b) c)
|
||||||
|
*(a 3 b) => **(a b)
|
||||||
|
*(a 4 b) => &*(a b)
|
||||||
|
*(a 5 b) => ^*(a b)
|
||||||
|
*(a 6 b) => =*(a b)
|
||||||
|
|
||||||
|
*(a 7 b c d) => *(a 3 (0 1) 3 (1 c d) (1 0) 3 (1 2 3) (1 0) 5 5 b)
|
||||||
|
*(a 8 b c) => *(a 2 (((1 0) b) c) 0 3)
|
||||||
|
*(a 9 b c) => *(a c)
|
||||||
|
|
||||||
|
*(a) => *(a)
|
||||||
|
|
||||||
|
5.2 Operators
|
||||||
|
|
||||||
|
5.2.1 Goto (*)
|
||||||
|
|
||||||
|
*(a) -> nock(a)
|
||||||
|
|
||||||
|
5.2.2 Deep (&)
|
||||||
|
|
||||||
|
&(a b) -> 0
|
||||||
|
&(a) -> 1
|
||||||
|
|
||||||
|
5.2.4 Bump (^)
|
||||||
|
|
||||||
|
^(a b) -> ^(a b)
|
||||||
|
^(a) -> a + 1
|
||||||
|
|
||||||
|
5.2.5 Same (=)
|
||||||
|
|
||||||
|
=(a a) -> 0
|
||||||
|
=(a b) -> 1
|
||||||
|
=(a) -> =(a)
|
||||||
|
|
||||||
|
5.2.6 Snip (/)
|
||||||
|
|
||||||
|
/(1 a) -> a
|
||||||
|
/(2 a b) -> a
|
||||||
|
/(3 a b) -> b
|
||||||
|
/((a + a) b) -> /(2 /(a b))
|
||||||
|
/((a + a + 1) b) -> /(3 /(a b))
|
||||||
|
/(a) -> /(a)
|
71
doc/spec/nock/13.txt
Normal file
71
doc/spec/nock/13.txt
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
Author: Curtis Yarvin (curtis.yarvin@gmail.com)
|
||||||
|
Date: 3/8/2008
|
||||||
|
Version: 0.13
|
||||||
|
|
||||||
|
1. Manifest
|
||||||
|
|
||||||
|
This file defines one Turing-complete function, "nock."
|
||||||
|
|
||||||
|
nock is in the public domain. So far as I know, it is
|
||||||
|
neither patentable nor patented. Use it at your own risk.
|
||||||
|
|
||||||
|
2. Data
|
||||||
|
|
||||||
|
Both the domain and range of nock are "nouns."
|
||||||
|
|
||||||
|
A "noun" is either an "atom" or a "cell." An "atom" is an unsigned
|
||||||
|
integer of any size. A "cell" is an ordered pair of any two nouns,
|
||||||
|
the "head" and "tail."
|
||||||
|
|
||||||
|
3. Pseudocode
|
||||||
|
|
||||||
|
nock is defined in a pattern-matching pseudocode.
|
||||||
|
|
||||||
|
Match precedence is top-down. Operators are prefix. Parens
|
||||||
|
denote cells, and group right: (a b c) is (a (b c)).
|
||||||
|
|
||||||
|
4. Definition
|
||||||
|
|
||||||
|
4.1 Transformations
|
||||||
|
|
||||||
|
*(a 0 b c) => *(*(a b) c)
|
||||||
|
*(a 0 b) => /(b a)
|
||||||
|
*(a 1 b) => (b)
|
||||||
|
*(a 2 b) => **(a b)
|
||||||
|
*(a 3 b) => &*(a b)
|
||||||
|
*(a 4 b) => ^*(a b)
|
||||||
|
*(a 5 b) => =*(a b)
|
||||||
|
*(a 6 b c d) => *(a 2 (0 1) 2 (1 c d) (1 0) 2 (1 2 3) (1 0) 4 4 b)
|
||||||
|
*(a b c) => (*(a b) *(a c))
|
||||||
|
*(a) => *(a)
|
||||||
|
|
||||||
|
4.2 Operators
|
||||||
|
|
||||||
|
4.2.1 Goto (*)
|
||||||
|
|
||||||
|
*(a) -> nock(a)
|
||||||
|
|
||||||
|
4.2.2 Deep (&)
|
||||||
|
|
||||||
|
&(a b) -> 0
|
||||||
|
&(a) -> 1
|
||||||
|
|
||||||
|
4.2.3 Bump (^)
|
||||||
|
|
||||||
|
^(a b) -> ^(a b)
|
||||||
|
^(a) -> a + 1
|
||||||
|
|
||||||
|
4.2.4 Same (=)
|
||||||
|
|
||||||
|
=(a a) -> 0
|
||||||
|
=(a b) -> 1
|
||||||
|
=(a) -> =(a)
|
||||||
|
|
||||||
|
4.2.5 Snip (/)
|
||||||
|
|
||||||
|
/(1 a) -> a
|
||||||
|
/(2 a b) -> a
|
||||||
|
/(3 a b) -> b
|
||||||
|
/((a + a) b) -> /(2 /(a b))
|
||||||
|
/((a + a + 1) b) -> /(3 /(a b))
|
||||||
|
/(a) -> /(a)
|
42
doc/spec/nock/6.txt
Normal file
42
doc/spec/nock/6.txt
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
1 Structures
|
||||||
|
|
||||||
|
A noun is an atom or a cell. An atom is any natural number.
|
||||||
|
A cell is an ordered pair of nouns.
|
||||||
|
|
||||||
|
2 Reductions
|
||||||
|
|
||||||
|
nock(a) *a
|
||||||
|
[a b c] [a [b c]]
|
||||||
|
|
||||||
|
?[a b] 0
|
||||||
|
?a 1
|
||||||
|
+a 1 + a
|
||||||
|
=[a a] 0
|
||||||
|
=[a b] 1
|
||||||
|
|
||||||
|
/[1 a] a
|
||||||
|
/[2 a b] a
|
||||||
|
/[3 a b] b
|
||||||
|
/[(a + a) b] /[2 /[a b]]
|
||||||
|
/[(a + a + 1) b] /[3 /[a b]]
|
||||||
|
|
||||||
|
*[a [b c] d] [*[a b c] *[a d]]
|
||||||
|
|
||||||
|
*[a 0 b] /[b a]
|
||||||
|
*[a 1 b] b
|
||||||
|
*[a 2 b c] *[*[a b] *[a c]]
|
||||||
|
*[a 3 b] ?*[a b]
|
||||||
|
*[a 4 b] +*[a b]
|
||||||
|
*[a 5 b] =*[a b]
|
||||||
|
|
||||||
|
*[a 6 b c d] *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
|
||||||
|
*[a 7 b c] *[a 2 b 1 c]
|
||||||
|
*[a 8 b c] *[a 7 [[0 1] b] c]
|
||||||
|
*[a 9 b c] *[a 7 c 0 b]
|
||||||
|
*[a 10 b c] *[a c]
|
||||||
|
*[a 10 [b c] d] *[a 8 c 7 [0 2] d]
|
||||||
|
|
||||||
|
+[a b] +[a b]
|
||||||
|
=a =a
|
||||||
|
/a /a
|
||||||
|
*a *a
|
42
doc/spec/nock/7.txt
Normal file
42
doc/spec/nock/7.txt
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
1 Structures
|
||||||
|
|
||||||
|
A noun is an atom or a cell. An atom is any natural number.
|
||||||
|
A cell is any ordered pair of nouns.
|
||||||
|
|
||||||
|
2 Pseudocode
|
||||||
|
|
||||||
|
[a b c] [a [b c]]
|
||||||
|
nock(a) *a
|
||||||
|
|
||||||
|
?[a b] 0
|
||||||
|
?a 1
|
||||||
|
^a 1 + a
|
||||||
|
=[a a] 0
|
||||||
|
=[a b] 1
|
||||||
|
|
||||||
|
/[1 a] a
|
||||||
|
/[2 a b] a
|
||||||
|
/[3 a b] b
|
||||||
|
/[(a + a) b] /[2 /[a b]]
|
||||||
|
/[(a + a + 1) b] /[3 /[a b]]
|
||||||
|
|
||||||
|
*[a [b c] d] [*[a b c] *[a d]]
|
||||||
|
|
||||||
|
*[a 0 b] /[b a]
|
||||||
|
*[a 1 b] b
|
||||||
|
*[a 2 b c] *[*[a b] *[a c]]
|
||||||
|
*[a 3 b] ?*[a b]
|
||||||
|
*[a 4 b] ^*[a b]
|
||||||
|
*[a 5 b] =*[a b]
|
||||||
|
|
||||||
|
*[a 6 b c d] *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
|
||||||
|
*[a 7 b c] *[a 2 b 1 c]
|
||||||
|
*[a 8 b c] *[a 7 [[7 [0 1] b] 0 1] c]
|
||||||
|
*[a 9 b c] *[a 7 c 0 b]
|
||||||
|
*[a 10 b c] *[a c]
|
||||||
|
*[a 10 [b c] d] *[a 8 c 7 [0 3] d]
|
||||||
|
|
||||||
|
^[a b] ^[a b]
|
||||||
|
=a =a
|
||||||
|
/a /a
|
||||||
|
*a *a
|
45
doc/spec/nock/8.txt
Normal file
45
doc/spec/nock/8.txt
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
1 Structures
|
||||||
|
|
||||||
|
A noun is an atom or a cell. An atom is any unsigned integer.
|
||||||
|
A cell is an ordered pair of nouns.
|
||||||
|
|
||||||
|
2 Pseudocode
|
||||||
|
|
||||||
|
[a b c] is [a [b c]]; *a is nock(a). Reductions match top-down.
|
||||||
|
|
||||||
|
3 Reductions
|
||||||
|
|
||||||
|
?[a b] 0
|
||||||
|
?a 1
|
||||||
|
^a (a + 1)
|
||||||
|
=[a a] 0
|
||||||
|
=[a b] 1
|
||||||
|
|
||||||
|
/[1 a] a
|
||||||
|
/[2 a b] a
|
||||||
|
/[3 a b] b
|
||||||
|
/[(a + a) b] /[2 /[a b]]
|
||||||
|
/[(a + a + 1) b] /[3 /[a b]]
|
||||||
|
|
||||||
|
*[a [b c] d] [*[a b c] *[a d]]
|
||||||
|
*[a 0 b] /[b a]
|
||||||
|
*[a 1 b] b
|
||||||
|
*[a 2 b c] *[*[a b] *[a c]]
|
||||||
|
*[a 3 b] ?*[a b]
|
||||||
|
*[a 4 b] ^*[a b]
|
||||||
|
*[a 5 b] =*[a b]
|
||||||
|
|
||||||
|
*[a 6 b c d] *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
|
||||||
|
*[a 7 b c] *[a 2 b 1 c]
|
||||||
|
*[a 8 b c] *[a 7 [7 b [0 1]] c]
|
||||||
|
*[a 9 b c] *[a 8 b 2 [[7 [0 3] d] [0 5]] 0 5]
|
||||||
|
*[a 10 b c] *[a 8 b 8 [7 [0 3] c] 0 2]
|
||||||
|
*[a 11 b c] *[a 8 b 7 [0 3] c]
|
||||||
|
*[a 12 b c] *[a [1 0] 1 c]
|
||||||
|
|
||||||
|
^[a b] ^[a b]
|
||||||
|
=a =a
|
||||||
|
/a /a
|
||||||
|
*a *a
|
||||||
|
|
||||||
|
|
43
doc/spec/nock/9.txt
Normal file
43
doc/spec/nock/9.txt
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
1 Context
|
||||||
|
|
||||||
|
This spec defines one function, Nock.
|
||||||
|
|
||||||
|
2 Structures
|
||||||
|
|
||||||
|
A noun is an atom or a cell. An atom is any unsigned integer.
|
||||||
|
A cell is an ordered pair of any two nouns.
|
||||||
|
|
||||||
|
3 Pseudocode
|
||||||
|
|
||||||
|
Brackets enclose cells. [a b c] is [a [b c]].
|
||||||
|
|
||||||
|
*a is Nock(a). Reductions match top-down.
|
||||||
|
|
||||||
|
4 Reductions
|
||||||
|
|
||||||
|
?[a b] => 0
|
||||||
|
?a => 1
|
||||||
|
|
||||||
|
^[a b] => ^[a b]
|
||||||
|
^a => (a + 1)
|
||||||
|
|
||||||
|
=[a a] => 0
|
||||||
|
=[a b] => 1
|
||||||
|
=a => =a
|
||||||
|
|
||||||
|
/[1 a] => a
|
||||||
|
/[2 a b] => a
|
||||||
|
/[3 a b] => b
|
||||||
|
/[(a + a) b] => /[2 /[a b]]
|
||||||
|
/[(a + a + 1) b] => /[3 /[a b]]
|
||||||
|
/a => /a
|
||||||
|
|
||||||
|
*[a 0 b] => /[b a]
|
||||||
|
*[a 1 b] => b
|
||||||
|
*[a 2 b c d] => *[a 3 [0 1] 3 [1 c d] [1 0] 3 [1 2 3] [1 0] 5 5 b]
|
||||||
|
*[a 3 b] => **[a b]
|
||||||
|
*[a 4 b] => ?*[a b]
|
||||||
|
*[a 5 b] => ^*[a b]
|
||||||
|
*[a 6 b] => =*[a b]
|
||||||
|
*[a [b c] d] => [*[a b c] *[a d]]
|
||||||
|
*a => *a
|
@ -716,7 +716,7 @@
|
|||||||
'rtt'^(numb (div rtt ~s1))
|
'rtt'^(numb (div rtt ~s1))
|
||||||
'rttvar'^(numb (div rttvar ~s1))
|
'rttvar'^(numb (div rttvar ~s1))
|
||||||
'ssthresh'^(numb ssthresh)
|
'ssthresh'^(numb ssthresh)
|
||||||
'num-live'^(numb num-live)
|
'num-live'^(numb ~(wyt by live))
|
||||||
'cwnd'^(numb cwnd)
|
'cwnd'^(numb cwnd)
|
||||||
'counter'^(numb counter)
|
'counter'^(numb counter)
|
||||||
==
|
==
|
||||||
|
File diff suppressed because one or more lines are too long
@ -10,9 +10,9 @@
|
|||||||
:::: :: ::::
|
:::: :: ::::
|
||||||
:: :: ::
|
:: :: ::
|
||||||
=> |% :: external structures
|
=> |% :: external structures
|
||||||
+$ id @tasession :: session id
|
+$ id sole-id :: session id
|
||||||
+$ house :: all state
|
+$ house :: all state
|
||||||
$: %8
|
$: %9
|
||||||
egg=@u :: command count
|
egg=@u :: command count
|
||||||
hoc=(map id session) :: conversations
|
hoc=(map id session) :: conversations
|
||||||
acl=(set ship) :: remote access whitelist
|
acl=(set ship) :: remote access whitelist
|
||||||
@ -820,12 +820,23 @@
|
|||||||
=/ poz=vase (dy-sore p.cig)
|
=/ poz=vase (dy-sore p.cig)
|
||||||
=/ kev=vase
|
=/ kev=vase
|
||||||
=/ kuv=(unit vase) (slew 7 som)
|
=/ kuv=(unit vase) (slew 7 som)
|
||||||
?: =(~ q.cig)
|
|
||||||
(fall kuv !>(~))
|
|
||||||
=/ soz=(list [var=term vax=vase])
|
=/ soz=(list [var=term vax=vase])
|
||||||
%~ tap by
|
%~ tap by
|
||||||
%- ~(run by q.cig)
|
%- ~(run by q.cig)
|
||||||
|=(val=(unit dojo-source) ?~(val !>([~ ~]) (dy-vase p.u.val)))
|
|=(val=(unit dojo-source) ?~(val !>([~ ~]) (dy-vase p.u.val)))
|
||||||
|
:: if the generator takes a named argument "drum-session",
|
||||||
|
:: then if a value isn't already supplied, we set it to the session
|
||||||
|
:: that this dojo instance is being run in.
|
||||||
|
:: (dojo is, indeed, quite coupled with drum.)
|
||||||
|
::
|
||||||
|
=? soz
|
||||||
|
?& ?=(^ kuv)
|
||||||
|
(slab %both %drum-session p.u.kuv)
|
||||||
|
!(~(has by q.cig) %drum-session)
|
||||||
|
==
|
||||||
|
[[%drum-session !>(ses.id)] soz] ::TODO does the who matter?
|
||||||
|
?: =(~ soz)
|
||||||
|
(fall kuv !>(~))
|
||||||
~| keyword-arg-failure+~(key by q.cig)
|
~| keyword-arg-failure+~(key by q.cig)
|
||||||
%+ slap
|
%+ slap
|
||||||
(with-faces kuv+(need kuv) rep+(with-faces soz) ~)
|
(with-faces kuv+(need kuv) rep+(with-faces soz) ~)
|
||||||
@ -1018,13 +1029,14 @@
|
|||||||
|= =card:agent:gall
|
|= =card:agent:gall
|
||||||
^+ +>
|
^+ +>
|
||||||
=? card ?=(%pass -.card)
|
=? card ?=(%pass -.card)
|
||||||
card(p [id p.card])
|
^- card:agent:gall
|
||||||
|
card(p [(scot %p who.id) ses.id p.card])
|
||||||
%_(+> moz [card moz])
|
%_(+> moz [card moz])
|
||||||
::
|
::
|
||||||
++ he-diff :: emit update
|
++ he-diff :: emit update
|
||||||
|= fec=sole-effect
|
|= fec=sole-effect
|
||||||
^+ +>
|
^+ +>
|
||||||
(he-card %give %fact ~[/sole/[id]] %sole-effect !>(fec))
|
(he-card %give %fact ~[(id-to-path:sole id)] %sole-effect !>(fec))
|
||||||
::
|
::
|
||||||
++ he-stop :: abort work
|
++ he-stop :: abort work
|
||||||
^+ .
|
^+ .
|
||||||
@ -1532,21 +1544,47 @@
|
|||||||
::
|
::
|
||||||
++ on-load
|
++ on-load
|
||||||
|= ole=vase
|
|= ole=vase
|
||||||
|
^- (quip card:agent:gall _..on-init)
|
||||||
|^ =+ old=!<(house-any ole)
|
|^ =+ old=!<(house-any ole)
|
||||||
=? old ?=(%5 -.old)
|
=? old ?=(%5 -.old)
|
||||||
|
^- house-any
|
||||||
|
^- house-6
|
||||||
(house-5-to-6 old)
|
(house-5-to-6 old)
|
||||||
=? old ?=(?(%6 %7) -.old)
|
=? old ?=(?(%6 %7) -.old)
|
||||||
(house-6-7-to-8 +.old)
|
(house-6-7-to-8 +.old)
|
||||||
?> ?=(%8 -.old)
|
=^ caz old
|
||||||
`..on-init(state old)
|
?. ?=(%8 -.old) [~ old]
|
||||||
|
(house-8-to-9 old)
|
||||||
|
?> ?=(%9 -.old)
|
||||||
|
[caz ..on-init(state old)]
|
||||||
::
|
::
|
||||||
+$ house-any $%(house house-7 house-6 house-5)
|
+$ house-any $%(house house-8 house-7 house-6 house-5)
|
||||||
|
::
|
||||||
|
+$ id-8 @tasession
|
||||||
|
+$ house-8
|
||||||
|
$: %8
|
||||||
|
egg=@u
|
||||||
|
hoc=(map id-8 session)
|
||||||
|
acl=(set ship)
|
||||||
|
==
|
||||||
|
++ house-8-to-9
|
||||||
|
|= old=house-8
|
||||||
|
^- (quip card:agent:gall house)
|
||||||
|
:- %+ turn ~(tap in ~(key by hoc.old))
|
||||||
|
|= id=@ta
|
||||||
|
^- card:agent:gall
|
||||||
|
[%give %kick ~[/sole/[id]] ~]
|
||||||
|
=- [%9 egg.old - acl.old]
|
||||||
|
%- ~(gas by *(map sole-id session))
|
||||||
|
%+ murn ~(tap by hoc.old)
|
||||||
|
|= [id=@ta s=session]
|
||||||
|
(bind (upgrade-id:sole id) (late s))
|
||||||
::
|
::
|
||||||
+$ house-7 [%7 house-6-7]
|
+$ house-7 [%7 house-6-7]
|
||||||
+$ house-6 [%6 house-6-7]
|
+$ house-6 [%6 house-6-7]
|
||||||
+$ house-6-7
|
+$ house-6-7
|
||||||
$: egg=@u :: command count
|
$: egg=@u :: command count
|
||||||
hoc=(map id session-6) :: conversations
|
hoc=(map id-8 session-6) :: conversations
|
||||||
acl=(set ship) :: remote access whitelist
|
acl=(set ship) :: remote access whitelist
|
||||||
== ::
|
== ::
|
||||||
+$ session-6 :: per conversation
|
+$ session-6 :: per conversation
|
||||||
@ -1573,9 +1611,10 @@
|
|||||||
old(poy ~, -.dir [our.hid %base ud+0])
|
old(poy ~, -.dir [our.hid %base ud+0])
|
||||||
::
|
::
|
||||||
+$ house-5
|
+$ house-5
|
||||||
[%5 egg=@u hoc=(map id session)]
|
[%5 egg=@u hoc=(map id-8 session-6)]
|
||||||
++ house-5-to-6
|
++ house-5-to-6
|
||||||
|= old=house-5
|
|= old=house-5
|
||||||
|
^- house-6
|
||||||
[%6 egg.old hoc.old *(set ship)]
|
[%6 egg.old hoc.old *(set ship)]
|
||||||
--
|
--
|
||||||
::
|
::
|
||||||
@ -1591,7 +1630,8 @@
|
|||||||
he-abet:(~(he-type he hid id.act ~ (~(got by hoc) id.act)) act)
|
he-abet:(~(he-type he hid id.act ~ (~(got by hoc) id.act)) act)
|
||||||
::
|
::
|
||||||
%lens-command
|
%lens-command
|
||||||
=+ !<([=id =command:lens] vase)
|
=+ !<([ses=@ta =command:lens] vase)
|
||||||
|
=/ =id [our.hid ses]
|
||||||
he-abet:(~(he-lens he hid id ~ (~(got by hoc) id)) command)
|
he-abet:(~(he-lens he hid id ~ (~(got by hoc) id)) command)
|
||||||
::
|
::
|
||||||
%allow-remote-login
|
%allow-remote-login
|
||||||
@ -1629,8 +1669,7 @@
|
|||||||
?> ?| (team:title our.hid src.hid)
|
?> ?| (team:title our.hid src.hid)
|
||||||
(~(has in acl) src.hid)
|
(~(has in acl) src.hid)
|
||||||
==
|
==
|
||||||
?> ?=([%sole @ ~] path)
|
=/ =id (need (path-to-id:sole path))
|
||||||
=/ id i.t.path
|
|
||||||
=? hoc (~(has by hoc) id)
|
=? hoc (~(has by hoc) id)
|
||||||
~& [%dojo-peer-replaced id]
|
~& [%dojo-peer-replaced id]
|
||||||
(~(del by hoc) id)
|
(~(del by hoc) id)
|
||||||
@ -1642,7 +1681,7 @@
|
|||||||
++ on-leave
|
++ on-leave
|
||||||
|= =path
|
|= =path
|
||||||
?> ?=([%sole *] path)
|
?> ?=([%sole *] path)
|
||||||
=. hoc (~(del by hoc) t.path)
|
=. hoc (~(del by hoc) (need (path-to-id:sole path)))
|
||||||
[~ ..on-init]
|
[~ ..on-init]
|
||||||
::
|
::
|
||||||
++ on-peek
|
++ on-peek
|
||||||
@ -1651,13 +1690,15 @@
|
|||||||
::
|
::
|
||||||
++ on-agent
|
++ on-agent
|
||||||
|= [=wire =sign:agent:gall]
|
|= [=wire =sign:agent:gall]
|
||||||
?> ?=([@ @ *] wire)
|
^- (quip card:agent:gall _..on-init)
|
||||||
=/ =session (~(got by hoc) i.wire)
|
?> ?=([@ @ @ *] wire)
|
||||||
=/ he-full ~(. he hid i.wire ~ session)
|
=/ =id [(slav %p i.wire) i.t.wire]
|
||||||
|
=/ =session (~(got by hoc) id)
|
||||||
|
=/ he-full ~(. he hid id ~ session)
|
||||||
=^ moves state
|
=^ moves state
|
||||||
=< he-abet
|
=< he-abet
|
||||||
^+ he
|
^+ he
|
||||||
?+ i.t.wire ~|([%dojo-bad-on-agent wire -.sign] !!)
|
?+ i.t.t.wire ~|([%dojo-bad-on-agent wire -.sign] !!)
|
||||||
%poke (he-unto:he-full t.wire sign)
|
%poke (he-unto:he-full t.wire sign)
|
||||||
%wool (he-wool:he-full t.wire sign)
|
%wool (he-wool:he-full t.wire sign)
|
||||||
==
|
==
|
||||||
@ -1665,14 +1706,16 @@
|
|||||||
::
|
::
|
||||||
++ on-arvo
|
++ on-arvo
|
||||||
|= [=wire =sign-arvo]
|
|= [=wire =sign-arvo]
|
||||||
?> ?=([@ *] wire)
|
^- (quip card:agent:gall _..on-init)
|
||||||
=/ =session (~(got by hoc) i.wire)
|
?> ?=([@ @ *] wire)
|
||||||
=/ he-full ~(. he hid i.wire ~ session)
|
=/ =id [(slav %p i.wire) i.t.wire]
|
||||||
|
=/ =session (~(got by hoc) id)
|
||||||
|
=/ he-full ~(. he hid id ~ session)
|
||||||
=^ moves state
|
=^ moves state
|
||||||
=< he-abet
|
=< he-abet
|
||||||
?+ +<.sign-arvo ~|([%dojo-bad-take +<.sign-arvo] !!)
|
?+ +<.sign-arvo ~|([%dojo-bad-take +<.sign-arvo] !!)
|
||||||
%writ (he-writ:he-full t.wire +>.sign-arvo)
|
%writ (he-writ:he-full t.t.wire +>.sign-arvo)
|
||||||
%http-response (he-http-response:he-full t.wire +>.sign-arvo)
|
%http-response (he-http-response:he-full t.t.wire +>.sign-arvo)
|
||||||
==
|
==
|
||||||
[moves ..on-init]
|
[moves ..on-init]
|
||||||
:: if dojo fails unexpectedly, kill whatever each session is working on
|
:: if dojo fails unexpectedly, kill whatever each session is working on
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
:: herm: stand-in for term.c with http interface
|
:: herm: stand-in for term.c with http interface
|
||||||
::
|
::
|
||||||
|
/- herm
|
||||||
/+ default-agent, dbug, verb
|
/+ default-agent, dbug, verb
|
||||||
|
:: keep relevant mark conversions in cache for performance
|
||||||
|
::
|
||||||
/$ blit-to-json %blit %json
|
/$ blit-to-json %blit %json
|
||||||
/$ json-to-blit %json %blit
|
/$ json-to-blit %json %blit
|
||||||
|
/$ json-to-task %json %herm-task
|
||||||
|
::
|
||||||
=, jael
|
=, jael
|
||||||
|%
|
|%
|
||||||
+$ state-0 [%0 ~]
|
+$ state-0 [%0 ~]
|
||||||
@ -13,15 +18,18 @@
|
|||||||
%+ verb |
|
%+ verb |
|
||||||
%- agent:dbug
|
%- agent:dbug
|
||||||
^- agent:gall
|
^- agent:gall
|
||||||
|
=> |%
|
||||||
|
++ pass-session
|
||||||
|
|= [ses=@tas tas=session-task:dill]
|
||||||
|
[%pass /dill/[ses] %arvo %d %shot ses tas]
|
||||||
|
--
|
||||||
|_ =bowl:gall
|
|_ =bowl:gall
|
||||||
+* this .
|
+* this .
|
||||||
def ~(. (default-agent this %|) bowl)
|
def ~(. (default-agent this %|) bowl)
|
||||||
::
|
::
|
||||||
++ on-init
|
++ on-init
|
||||||
^- (quip card:agent:gall _this)
|
^- (quip card:agent:gall _this)
|
||||||
:: set up dill session subscription
|
[~ this]
|
||||||
::
|
|
||||||
[[%pass [%view %$ ~] %arvo %d %view ~]~ this]
|
|
||||||
::
|
::
|
||||||
++ on-save !>([%0 ~])
|
++ on-save !>([%0 ~])
|
||||||
++ on-load
|
++ on-load
|
||||||
@ -32,47 +40,68 @@
|
|||||||
++ on-watch
|
++ on-watch
|
||||||
|= =path
|
|= =path
|
||||||
^- (quip card:agent:gall _this)
|
^- (quip card:agent:gall _this)
|
||||||
?> =(our src):bowl
|
|
||||||
?> ?=([%session @ %view ~] path)
|
|
||||||
:_ this
|
:_ this
|
||||||
:: scry prompt and cursor position out of dill for initial response
|
~| path
|
||||||
|
?> ?=([%session @ %view ~] path)
|
||||||
|
=* ses i.t.path
|
||||||
|
:: subscribe to the requested session
|
||||||
::
|
::
|
||||||
=/ base=^path
|
::NOTE multiple views do not result in multiple subscriptions
|
||||||
/dx/(scot %p our.bowl)//(scot %da now.bowl)/sessions
|
:: because they go over the same wire/duct
|
||||||
:~ [%give %fact ~ %blit !>(.^(blit:dill (weld base //line)))]
|
::
|
||||||
[%give %fact ~ %blit !>(`blit:dill`hop+.^(@ud (weld base //cursor)))]
|
[(pass-session ses %view ~)]~
|
||||||
==
|
|
||||||
::
|
::
|
||||||
++ on-arvo
|
++ on-arvo
|
||||||
|= [=wire =sign-arvo]
|
|= [=wire =sign-arvo]
|
||||||
^- (quip card:agent:gall _this)
|
^- (quip card:agent:gall _this)
|
||||||
|
~| wire
|
||||||
?+ wire (on-arvo:def wire sign-arvo)
|
?+ wire (on-arvo:def wire sign-arvo)
|
||||||
[%tube *] [~ this] :: we no longer care about these
|
[%tube *] [~ this] :: we no longer care about these
|
||||||
::
|
::
|
||||||
:: pass on dill blits for the session
|
:: pass on dill blits for the session
|
||||||
::
|
::
|
||||||
[%view %$ ~]
|
[%dill @ ~]
|
||||||
|
=* ses i.t.wire
|
||||||
?. ?=([%dill %blit *] sign-arvo)
|
?. ?=([%dill %blit *] sign-arvo)
|
||||||
~| [%unexpected-sign [- +<]:sign-arvo]
|
~| [%unexpected-sign [- +<]:sign-arvo]
|
||||||
!!
|
!!
|
||||||
:_ this
|
:_ this
|
||||||
%+ turn p.sign-arvo
|
%+ turn p.sign-arvo
|
||||||
|= =blit:dill
|
|= =blit:dill
|
||||||
[%give %fact [%session %$ %view ~]~ %blit !>(blit)]
|
[%give %fact [%session ses %view ~]~ %blit !>(blit)]
|
||||||
|
::
|
||||||
|
:: clean up old-style subscriptions
|
||||||
|
::
|
||||||
|
[%view @ ~]
|
||||||
|
=* ses i.t.wire
|
||||||
|
:_ this
|
||||||
|
[%pass wire %arvo %d %shot ses %flee ~]~
|
||||||
==
|
==
|
||||||
::
|
::
|
||||||
++ on-poke
|
++ on-poke
|
||||||
|= [=mark =vase]
|
|= [=mark =vase]
|
||||||
^- (quip card:agent:gall _this)
|
^- (quip card:agent:gall _this)
|
||||||
?> =(our src):bowl
|
|
||||||
?. ?=(%belt mark)
|
|
||||||
~| [%unexpected-mark mark]
|
|
||||||
!!
|
|
||||||
:_ this
|
:_ 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-leave on-leave:def
|
||||||
++ on-peek on-peek:def
|
::
|
||||||
++ on-agent on-agent:def
|
++ on-agent on-agent:def
|
||||||
++ on-fail on-fail:def
|
++ on-fail on-fail:def
|
||||||
--
|
--
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
/+ drum=hood-drum, helm=hood-helm, kiln=hood-kiln
|
/+ drum=hood-drum, helm=hood-helm, kiln=hood-kiln
|
||||||
|%
|
|%
|
||||||
+$ state
|
+$ state
|
||||||
$~ [%24 *state:drum *state:helm *state:kiln]
|
$~ [%25 *state:drum *state:helm *state:kiln]
|
||||||
$>(%24 any-state)
|
$>(%25 any-state)
|
||||||
::
|
::
|
||||||
+$ any-state
|
+$ any-state
|
||||||
$% [ver=?(%1 %2 %3 %4 %5 %6) lac=(map @tas fin-any-state)]
|
$% [ver=?(%1 %2 %3 %4 %5 %6) lac=(map @tas fin-any-state)]
|
||||||
@ -25,6 +25,7 @@
|
|||||||
[%22 drum=state-4:drum helm=state-1:helm kiln=state-9:kiln]
|
[%22 drum=state-4:drum helm=state-1:helm kiln=state-9:kiln]
|
||||||
[%23 drum=state-4:drum helm=state-2:helm kiln=state-9:kiln]
|
[%23 drum=state-4:drum helm=state-2:helm kiln=state-9:kiln]
|
||||||
[%24 drum=state-4:drum helm=state-2:helm kiln=state-10:kiln]
|
[%24 drum=state-4:drum helm=state-2:helm kiln=state-10:kiln]
|
||||||
|
[%25 drum=state-5:drum helm=state-2:helm kiln=state-10:kiln]
|
||||||
==
|
==
|
||||||
+$ any-state-tuple
|
+$ any-state-tuple
|
||||||
$: drum=any-state:drum
|
$: drum=any-state:drum
|
||||||
@ -92,8 +93,7 @@
|
|||||||
::
|
::
|
||||||
?+ mark (on-poke:def mark vase)
|
?+ mark (on-poke:def mark vase)
|
||||||
%atom poke-helm(mark %helm-atom)
|
%atom poke-helm(mark %helm-atom)
|
||||||
%dill-belt poke-drum(mark %drum-dill-belt)
|
%dill-poke poke-drum
|
||||||
%dill-blit poke-drum(mark %drum-dill-blit)
|
|
||||||
%hood-sync poke-kiln(mark %kiln-sync)
|
%hood-sync poke-kiln(mark %kiln-sync)
|
||||||
%write-sec-atom poke-helm(mark %helm-write-sec-atom)
|
%write-sec-atom poke-helm(mark %helm-write-sec-atom)
|
||||||
==
|
==
|
||||||
@ -108,6 +108,7 @@
|
|||||||
?+ path (on-watch:def +<)
|
?+ path (on-watch:def +<)
|
||||||
[%drum *] =^(c drum.state (peer:drum-core t.path) [c this])
|
[%drum *] =^(c drum.state (peer:drum-core t.path) [c this])
|
||||||
[%kiln *] =^(c kiln.state (peer:kiln-core t.path) [c this])
|
[%kiln *] =^(c kiln.state (peer:kiln-core t.path) [c this])
|
||||||
|
[%dill *] =^(c drum.state (peer:drum-core +<) [c this])
|
||||||
==
|
==
|
||||||
::
|
::
|
||||||
++ on-agent
|
++ on-agent
|
||||||
|
@ -83,7 +83,8 @@
|
|||||||
::
|
::
|
||||||
?+ -.source.com
|
?+ -.source.com
|
||||||
:_ this(job.state (some [eyre-id com]))
|
:_ this(job.state (some [eyre-id com]))
|
||||||
[%pass /sole %agent [our.bowl %dojo] %watch /sole/[eyre-id]]~
|
=/ =path /sole/(scot %p our.bowl)/[eyre-id]
|
||||||
|
[%pass /sole %agent [our.bowl %dojo] %watch path]~
|
||||||
::
|
::
|
||||||
%export
|
%export
|
||||||
:_ this(job.state (some [eyre-id com]))
|
:_ this(job.state (some [eyre-id com]))
|
||||||
|
@ -43,13 +43,13 @@
|
|||||||
++ on-fail on-fail:def
|
++ on-fail on-fail:def
|
||||||
::
|
::
|
||||||
++ command-parser
|
++ command-parser
|
||||||
|= sole-id=@ta
|
|= =sole-id:shoe
|
||||||
^+ |~(nail *(like [? command]))
|
^+ |~(nail *(like [? command]))
|
||||||
%+ stag &
|
%+ stag &
|
||||||
(perk %demo %row %table ~)
|
(perk %demo %row %table ~)
|
||||||
::
|
::
|
||||||
++ tab-list
|
++ tab-list
|
||||||
|= sole-id=@ta
|
|= =sole-id:shoe
|
||||||
^- (list [@t tank])
|
^- (list [@t tank])
|
||||||
:~ ['demo' leaf+"run example command"]
|
:~ ['demo' leaf+"run example command"]
|
||||||
['row' leaf+"print a row"]
|
['row' leaf+"print a row"]
|
||||||
@ -57,7 +57,7 @@
|
|||||||
==
|
==
|
||||||
::
|
::
|
||||||
++ on-command
|
++ on-command
|
||||||
|= [sole-id=@ta =command]
|
|= [=sole-id:shoe =command]
|
||||||
^- (quip card _this)
|
^- (quip card _this)
|
||||||
=; [to=(list _sole-id) fec=shoe-effect:shoe]
|
=; [to=(list _sole-id) fec=shoe-effect:shoe]
|
||||||
[[%shoe to fec]~ this]
|
[[%shoe to fec]~ this]
|
||||||
@ -87,7 +87,7 @@
|
|||||||
==
|
==
|
||||||
::
|
::
|
||||||
++ can-connect
|
++ can-connect
|
||||||
|= sole-id=@ta
|
|= =sole-id:shoe
|
||||||
^- ?
|
^- ?
|
||||||
?| =(~zod src.bowl)
|
?| =(~zod src.bowl)
|
||||||
(team:title [our src]:bowl)
|
(team:title [our src]:bowl)
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
:- %aqua-events
|
:- %aqua-events
|
||||||
%+ turn
|
%+ turn
|
||||||
^- (list unix-event)
|
^- (list unix-event)
|
||||||
:~ [/d/term/1 %belt %ctl `@c`%e]
|
:~ [/d/term/1 %belt %mod %ctl `@c`%e]
|
||||||
[/d/term/1 %belt %ctl `@c`%u]
|
[/d/term/1 %belt %mod %ctl `@c`%u]
|
||||||
[/d/term/1 %belt %txt ((list @c) command)]
|
[/d/term/1 %belt %txt ((list @c) command)]
|
||||||
[/d/term/1 %belt %ret ~]
|
[/d/term/1 %belt %ret ~]
|
||||||
==
|
==
|
||||||
|
@ -8,9 +8,11 @@
|
|||||||
::
|
::
|
||||||
:- %say
|
:- %say
|
||||||
|= $: [now=@da eny=@uvJ byk=beak]
|
|= $: [now=@da eny=@uvJ byk=beak]
|
||||||
[arg=$?([dap=term ~] [who=ship dap=term ~]) ~]
|
arg=$?([dap=term ~] [who=ship dap=term ~])
|
||||||
|
drum-session=@ta
|
||||||
==
|
==
|
||||||
:- %drum-link
|
:- %drum-link
|
||||||
|
:- drum-session
|
||||||
?~ +.arg
|
?~ +.arg
|
||||||
[p.byk dap.arg]
|
[p.byk dap.arg]
|
||||||
[who.arg dap.arg]
|
[who.arg dap.arg]
|
||||||
|
@ -8,9 +8,11 @@
|
|||||||
::
|
::
|
||||||
:- %say
|
:- %say
|
||||||
|= $: [now=@da eny=@uvJ byk=beak]
|
|= $: [now=@da eny=@uvJ byk=beak]
|
||||||
[arg=$?([dap=term ~] [who=ship dap=term ~]) ~]
|
arg=$?([dap=term ~] [who=ship dap=term ~])
|
||||||
|
drum-session=@ta
|
||||||
==
|
==
|
||||||
:- %drum-unlink
|
:- %drum-unlink
|
||||||
|
:- drum-session
|
||||||
?~ +.arg
|
?~ +.arg
|
||||||
[p.byk dap.arg]
|
[p.byk dap.arg]
|
||||||
[who.arg dap.arg]
|
[who.arg dap.arg]
|
||||||
|
1
pkg/arvo/lib/dill.hoon
Symbolic link
1
pkg/arvo/lib/dill.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/lib/dill.hoon
|
@ -1,34 +1,66 @@
|
|||||||
/- *sole
|
/- *sole
|
||||||
/+ sole
|
/+ sole
|
||||||
|%
|
|%
|
||||||
+$ state state-4
|
+$ state state-5
|
||||||
+$ any-state
|
+$ any-state
|
||||||
$~ *state
|
$~ *state
|
||||||
$% state-4
|
$% state-5
|
||||||
|
state-4
|
||||||
state-3
|
state-3
|
||||||
state-2
|
state-2
|
||||||
==
|
==
|
||||||
|
+$ state-5 [%5 pith-5]
|
||||||
+$ state-4 [%4 pith-4]
|
+$ state-4 [%4 pith-4]
|
||||||
+$ state-3 [%3 pith-3]
|
+$ state-3 [%3 pith-3]
|
||||||
+$ state-2 [%2 pith-2]
|
+$ state-2 [%2 pith-2]
|
||||||
::
|
::
|
||||||
|
+$ pith-5
|
||||||
|
$: bin=(map @ source) :: terminals
|
||||||
|
==
|
||||||
|
::
|
||||||
+$ pith-4
|
+$ pith-4
|
||||||
$: eel=(set gill:gall) :: connect to
|
$: eel=(set gill:gall) :: connect to
|
||||||
bin=(map bone source) :: terminals
|
bin=(map bone source-4) :: terminals
|
||||||
== ::
|
== ::
|
||||||
::
|
::
|
||||||
|
+$ source-4
|
||||||
|
$: edg=_80
|
||||||
|
off=@ud
|
||||||
|
kil=kill
|
||||||
|
inx=@ud
|
||||||
|
fug=(map gill:gall (unit target-4))
|
||||||
|
mir=(pair @ud stub)
|
||||||
|
==
|
||||||
|
::
|
||||||
|
+$ target-4
|
||||||
|
$: $= blt
|
||||||
|
%+ pair
|
||||||
|
(unit dill-belt-4)
|
||||||
|
(unit dill-belt-4)
|
||||||
|
ris=(unit search)
|
||||||
|
hit=history
|
||||||
|
pom=sole-prompt
|
||||||
|
inp=sole-command
|
||||||
|
==
|
||||||
|
::
|
||||||
|
+$ dill-belt-4
|
||||||
|
$% [%ctl p=@c]
|
||||||
|
[%met p=@c]
|
||||||
|
dill-belt:dill
|
||||||
|
==
|
||||||
|
::
|
||||||
++ pith-3 ::
|
++ pith-3 ::
|
||||||
$: eel=(set gill:gall) :: connect to
|
$: eel=(set gill:gall) :: connect to
|
||||||
ray=(map dude:gall desk) ::
|
ray=(map dude:gall desk) ::
|
||||||
fur=(map dude:gall (unit *)) :: servers
|
fur=(map dude:gall (unit *)) :: servers
|
||||||
bin=(map bone source) :: terminals
|
bin=(map bone source-4) :: terminals
|
||||||
== ::
|
== ::
|
||||||
:: ::
|
:: ::
|
||||||
++ pith-2 ::
|
++ pith-2 ::
|
||||||
$: eel=(set gill:gall) :: connect to
|
$: eel=(set gill:gall) :: connect to
|
||||||
ray=(set well:gall) ::
|
ray=(set well:gall) ::
|
||||||
fur=(map dude:gall (unit *)) :: servers
|
fur=(map dude:gall (unit *)) :: servers
|
||||||
bin=(map bone source) :: terminals
|
bin=(map bone source-4) :: terminals
|
||||||
== ::
|
== ::
|
||||||
:: ::
|
:: ::
|
||||||
++ kill :: kill ring
|
++ kill :: kill ring
|
||||||
@ -42,6 +74,7 @@
|
|||||||
off=@ud :: window offset
|
off=@ud :: window offset
|
||||||
kil=kill :: kill buffer
|
kil=kill :: kill buffer
|
||||||
inx=@ud :: ring index
|
inx=@ud :: ring index
|
||||||
|
eel=(set gill:gall) :: connect to
|
||||||
fug=(map gill:gall (unit target)) :: connections
|
fug=(map gill:gall (unit target)) :: connections
|
||||||
mir=(pair @ud stub) :: mirrored terminal
|
mir=(pair @ud stub) :: mirrored terminal
|
||||||
== ::
|
== ::
|
||||||
@ -65,52 +98,74 @@
|
|||||||
pom=sole-prompt :: static prompt
|
pom=sole-prompt :: static prompt
|
||||||
inp=sole-command :: input state
|
inp=sole-command :: input state
|
||||||
== ::
|
== ::
|
||||||
|
::
|
||||||
--
|
--
|
||||||
:: :: ::
|
:: :: ::
|
||||||
:::: :: ::
|
:::: :: ::
|
||||||
:: :: ::
|
:: :: ::
|
||||||
|%
|
|%
|
||||||
++ en-gill :: gill to wire
|
++ en-gill :: gill to wire
|
||||||
|= gyl=gill:gall
|
|= [ses=@tas gyl=gill:gall]
|
||||||
^- wire
|
^- wire
|
||||||
[%drum %phat (scot %p p.gyl) q.gyl ~]
|
[%drum %phat (scot %p p.gyl) q.gyl ?:(=(%$ ses) ~ [ses ~])]
|
||||||
::
|
::
|
||||||
++ de-gill :: gill from wire
|
++ de-gill :: gill from wire
|
||||||
|= way=wire ^- gill:gall
|
|= way=wire
|
||||||
~| way
|
^- [@tas gill:gall]
|
||||||
?>(?=([@ @ *] way) [(slav %p i.way) i.t.way])
|
~| wire=way
|
||||||
|
?> ?=([@ @ ?(~ [@ ~])] way)
|
||||||
|
:- ?~(t.t.way %$ i.t.t.way)
|
||||||
|
[(slav %p i.way) i.t.way]
|
||||||
--
|
--
|
||||||
:: TODO: remove .ost
|
|
||||||
::
|
::
|
||||||
|= [hid=bowl:gall state]
|
|= [hid=bowl:gall state]
|
||||||
=* sat +<+
|
=* sat +<+
|
||||||
=/ ost 0
|
=/ ses=@tas %$
|
||||||
=+ (~(gut by bin) ost *source)
|
=+ (~(gut by bin) ses *source)
|
||||||
=* dev -
|
=* dev -
|
||||||
=| moz=(list card:agent:gall)
|
=| moz=(list card:agent:gall)
|
||||||
=| biz=(list dill-blit:dill)
|
=| biz=(list blit:dill) ::TODO should be per-session
|
||||||
|%
|
|%
|
||||||
++ this .
|
++ this .
|
||||||
|
++ klr klr:format
|
||||||
+$ state ^state :: proxy
|
+$ state ^state :: proxy
|
||||||
+$ any-state ^any-state :: proxy
|
+$ any-state ^any-state :: proxy
|
||||||
++ on-init (poke-link our.hid %dojo)
|
++ on-init (poke-link %$ our.hid %dojo)
|
||||||
|
::
|
||||||
|
++ prep
|
||||||
|
|= s=@tas
|
||||||
|
=. ses s
|
||||||
|
=. dev (~(gut by bin) ses *source)
|
||||||
|
this
|
||||||
|
::
|
||||||
|
++ open
|
||||||
|
%+ cork de-gill
|
||||||
|
|= [s=@tas g=gill:gall]
|
||||||
|
[g (prep s)]
|
||||||
|
::
|
||||||
++ diff-sole-effect-phat :: app event
|
++ diff-sole-effect-phat :: app event
|
||||||
|= [way=wire fec=sole-effect]
|
|= [way=wire fec=sole-effect]
|
||||||
=< se-abet =< se-view
|
=< se-abet
|
||||||
=+ gyl=(de-gill way)
|
=^ gyl this (open way)
|
||||||
?: (se-aint gyl) +>.$
|
?: (se-aint gyl) +>.$
|
||||||
(se-diff gyl fec)
|
(se-diff gyl fec)
|
||||||
::
|
::
|
||||||
++ peer ::
|
++ peer ::
|
||||||
|= pax=path
|
|= pax=path
|
||||||
|
=? this ?=([%dill @ ~] pax)
|
||||||
|
(prep i.t.pax)
|
||||||
~| [%drum-unauthorized our+our.hid src+src.hid] :: ourself
|
~| [%drum-unauthorized our+our.hid src+src.hid] :: ourself
|
||||||
?> (team:title our.hid src.hid) :: or our own moon
|
?> (team:title our.hid src.hid) :: or our own moon
|
||||||
=< se-abet =< se-view
|
=< se-abet
|
||||||
(se-text "[{<src.hid>}, driving {<our.hid>}]")
|
(se-text "[{<src.hid>}, driving {<our.hid>}]")
|
||||||
::
|
::
|
||||||
|
++ poke-dill
|
||||||
|
|= [ses=@tas bet=dill-belt:dill]
|
||||||
|
(poke-dill-belt:(prep ses) bet)
|
||||||
|
::
|
||||||
++ poke-dill-belt :: terminal event
|
++ poke-dill-belt :: terminal event
|
||||||
|= bet=dill-belt:dill
|
|= bet=dill-belt:dill
|
||||||
=< se-abet =< se-view
|
=< se-abet
|
||||||
(se-belt bet)
|
(se-belt bet)
|
||||||
::
|
::
|
||||||
++ poke-dill-blit :: terminal output
|
++ poke-dill-blit :: terminal output
|
||||||
@ -118,29 +173,29 @@
|
|||||||
se-abet:(se-blit-sys bit)
|
se-abet:(se-blit-sys bit)
|
||||||
::
|
::
|
||||||
++ poke-link :: connect app
|
++ poke-link :: connect app
|
||||||
|= gyl=gill:gall
|
|= [ses=@tas gyl=gill:gall]
|
||||||
=< se-abet =< se-view
|
=< se-abet
|
||||||
(se-link gyl)
|
(se-link:(prep ses) gyl)
|
||||||
::
|
::
|
||||||
++ poke-unlink :: disconnect app
|
++ poke-unlink :: disconnect app
|
||||||
|= gyl=gill:gall
|
|= [ses=@ta gyl=gill:gall]
|
||||||
=< se-abet =< se-view
|
=< se-abet
|
||||||
(se-drop:(se-pull gyl) & gyl)
|
(se-drop:(se-pull:(prep ses) gyl) & gyl)
|
||||||
::
|
::
|
||||||
++ poke-exit :: shutdown
|
++ poke-exit :: shutdown
|
||||||
|= ~
|
|= ~
|
||||||
se-abet:(se-blit-sys `dill-blit:dill`[%qit ~])
|
se-abet:(se-blit-sys `dill-blit:dill`[%qit ~])
|
||||||
::
|
::
|
||||||
++ poke-put :: write file
|
++ poke-put :: write file
|
||||||
|= [pax=path txt=@]
|
|= [pax=path arg=$@(@ [@tas @])]
|
||||||
|
=^ txt +> ?@(arg [arg +>] [+.arg (prep -.arg)])
|
||||||
se-abet:(se-blit-sys [%sav pax txt]) ::
|
se-abet:(se-blit-sys [%sav pax txt]) ::
|
||||||
::
|
::
|
||||||
++ poke
|
++ poke
|
||||||
|= [=mark =vase]
|
|= [=mark =vase]
|
||||||
?> =(our src):hid
|
?> =(our src):hid
|
||||||
?+ mark ~|([%poke-drum-bad-mark mark] !!)
|
?+ mark ~|([%poke-drum-bad-mark mark] !!)
|
||||||
%drum-dill-belt =;(f (f !<(_+<.f vase)) poke-dill-belt)
|
%dill-poke =;(f (f !<(_+<.f vase)) poke-dill)
|
||||||
%drum-dill-blit =;(f (f !<(_+<.f vase)) poke-dill-blit)
|
|
||||||
%drum-exit =;(f (f !<(_+<.f vase)) poke-exit)
|
%drum-exit =;(f (f !<(_+<.f vase)) poke-exit)
|
||||||
%drum-link =;(f (f !<(_+<.f vase)) poke-link)
|
%drum-link =;(f (f !<(_+<.f vase)) poke-link)
|
||||||
%drum-put =;(f (f !<(_+<.f vase)) poke-put)
|
%drum-put =;(f (f !<(_+<.f vase)) poke-put)
|
||||||
@ -149,19 +204,40 @@
|
|||||||
::
|
::
|
||||||
++ on-load
|
++ on-load
|
||||||
|= [hood-version=@ud old=any-state]
|
|= [hood-version=@ud old=any-state]
|
||||||
=< se-abet =< se-view
|
=< se-abet
|
||||||
=? old ?=(%2 -.old) [%4 [eel bin]:old]
|
=? old ?=(%2 -.old) [%4 [eel bin]:old]
|
||||||
=? old ?=(%3 -.old) [%4 [eel bin]:old]
|
=? old ?=(%3 -.old) [%4 [eel bin]:old]
|
||||||
|
=? old ?=(%4 -.old)
|
||||||
|
|^ 5+(~(run by bin.old) source-4-to-5)
|
||||||
|
++ source-4-to-5
|
||||||
|
|= source-4
|
||||||
|
^- source
|
||||||
|
=; fug [edg off kil inx eel.old fug mir]
|
||||||
|
(~(run by fug) |=(t=(unit target-4) (bind t target-4-to-5)))
|
||||||
|
::
|
||||||
|
++ target-4-to-5
|
||||||
|
|= t=target-4
|
||||||
|
^- target
|
||||||
|
:_ +.t
|
||||||
|
:- (bind p.blt.t belt-4-to-5)
|
||||||
|
(bind q.blt.t belt-4-to-5)
|
||||||
|
::
|
||||||
|
++ belt-4-to-5
|
||||||
|
|= b=dill-belt-4
|
||||||
|
^- dill-belt:dill
|
||||||
|
?. ?=(?(%ctl %met) -.b) b
|
||||||
|
[%mod -.b p.b]
|
||||||
|
--
|
||||||
::
|
::
|
||||||
?> ?=(%4 -.old)
|
?> ?=(%5 -.old)
|
||||||
=. sat old
|
=. sat old
|
||||||
=. dev (~(gut by bin) ost *source)
|
=. dev (~(gut by bin) ses *source)
|
||||||
this
|
this
|
||||||
::
|
::
|
||||||
++ reap-phat :: ack connect
|
++ reap-phat :: ack connect
|
||||||
|= [way=wire saw=(unit tang)]
|
|= [way=wire saw=(unit tang)]
|
||||||
=< se-abet =< se-view
|
=< se-abet
|
||||||
=+ gyl=(de-gill way)
|
=^ gyl this (open way)
|
||||||
?~ saw
|
?~ saw
|
||||||
(se-join gyl)
|
(se-join gyl)
|
||||||
:: Don't print stack trace because we probably just crashed to
|
:: Don't print stack trace because we probably just crashed to
|
||||||
@ -171,9 +247,9 @@
|
|||||||
::
|
::
|
||||||
++ take-coup-phat :: ack poke
|
++ take-coup-phat :: ack poke
|
||||||
|= [way=wire saw=(unit tang)]
|
|= [way=wire saw=(unit tang)]
|
||||||
=< se-abet =< se-view
|
=< se-abet
|
||||||
?~ saw +>
|
?~ saw +>
|
||||||
=+ gyl=(de-gill way)
|
=^ gyl this (open way)
|
||||||
?: (se-aint gyl) +>.$
|
?: (se-aint gyl) +>.$
|
||||||
%- se-dump:(se-drop:(se-pull gyl) & gyl)
|
%- se-dump:(se-drop:(se-pull gyl) & gyl)
|
||||||
:_ u.saw
|
:_ u.saw
|
||||||
@ -196,8 +272,8 @@
|
|||||||
::
|
::
|
||||||
++ quit-phat ::
|
++ quit-phat ::
|
||||||
|= way=wire
|
|= way=wire
|
||||||
=< se-abet =< se-view
|
=< se-abet
|
||||||
=+ gyl=(de-gill way)
|
=^ gyl this (open way)
|
||||||
~& [%drum-quit src.hid gyl]
|
~& [%drum-quit src.hid gyl]
|
||||||
(se-drop %| gyl)
|
(se-drop %| gyl)
|
||||||
:: :: ::
|
:: :: ::
|
||||||
@ -205,13 +281,18 @@
|
|||||||
:: :: ::
|
:: :: ::
|
||||||
++ se-abet :: resolve
|
++ se-abet :: resolve
|
||||||
^- (quip card:agent:gall state)
|
^- (quip card:agent:gall state)
|
||||||
=. . se-subze:se-adze
|
=. . se-view:se-subze:se-adze
|
||||||
:_ sat(bin (~(put by bin) ost dev))
|
:_ sat(bin (~(put by bin) ses dev))
|
||||||
^- (list card:agent:gall)
|
^- (list card:agent:gall)
|
||||||
?~ biz (flop moz)
|
?~ biz (flop moz)
|
||||||
:_ (flop moz)
|
:_ (flop moz)
|
||||||
=/ =dill-blit:dill ?~(t.biz i.biz [%mor (flop biz)])
|
=/ =blit:dill ?~(t.biz i.biz [%mor (flop biz)])
|
||||||
[%give %fact ~[/drum] %dill-blit !>(dill-blit)]
|
::TODO remove /drum after dill cleans up
|
||||||
|
::TODO but once we remove it, the empty trailing segment of
|
||||||
|
:: /dill/[ses] would prevent outsiders from subscribing
|
||||||
|
:: to the default session...
|
||||||
|
=/ to=(list path) [/dill/[ses] ?~(ses ~[/drum] ~)]
|
||||||
|
[%give %fact to %dill-blit !>(blit)]
|
||||||
::
|
::
|
||||||
++ se-adze :: update connections
|
++ se-adze :: update connections
|
||||||
^+ .
|
^+ .
|
||||||
@ -230,14 +311,14 @@
|
|||||||
(se-peer gil)
|
(se-peer gil)
|
||||||
::
|
::
|
||||||
++ se-subze :: downdate connections
|
++ se-subze :: downdate connections
|
||||||
=< .(dev (~(got by bin) ost))
|
=< .(dev (~(got by bin) ses))
|
||||||
=. bin (~(put by bin) ost dev)
|
=. bin (~(put by bin) ses dev)
|
||||||
^+ .
|
^+ .
|
||||||
%- ~(rep by bin)
|
%- ~(rep by bin)
|
||||||
=< .(con +>)
|
=< .(con +>)
|
||||||
|: $:,[[ost=bone dev=source] con=_.] ^+ con
|
|: $:,[[ses=@tas dev=source] con=_.] ^+ con
|
||||||
=+ xeno=se-subze-local:%_(con ost ost, dev dev)
|
=+ xeno=se-subze-local:%_(con ses ses, dev dev)
|
||||||
xeno(ost ost.con, dev dev.con, bin (~(put by bin) ost dev.xeno))
|
xeno(ses ses.con, dev dev.con, bin (~(put by bin.xeno) ses dev.xeno))
|
||||||
::
|
::
|
||||||
++ se-subze-local
|
++ se-subze-local
|
||||||
^+ .
|
^+ .
|
||||||
@ -252,7 +333,7 @@
|
|||||||
++ se-aint :: ignore result
|
++ se-aint :: ignore result
|
||||||
|= gyl=gill:gall
|
|= gyl=gill:gall
|
||||||
^- ?
|
^- ?
|
||||||
?. (~(has by bin) ost) &
|
?. (~(has by bin) ses) &
|
||||||
=+ gyr=(~(get by fug) gyl)
|
=+ gyr=(~(get by fug) gyl)
|
||||||
|(?=(~ gyr) ?=(~ u.gyr))
|
|(?=(~ gyr) ?=(~ u.gyr))
|
||||||
::
|
::
|
||||||
@ -290,7 +371,7 @@
|
|||||||
[%cru *] (se-dump:(se-text (trip p.bet)) q.bet)
|
[%cru *] (se-dump:(se-text (trip p.bet)) q.bet)
|
||||||
[%hey *] +>(mir [0 ~]) :: refresh
|
[%hey *] +>(mir [0 ~]) :: refresh
|
||||||
[%rez *] +>(edg (dec p.bet)) :: resize window
|
[%rez *] +>(edg (dec p.bet)) :: resize window
|
||||||
[%yow *] ~&([%no-yow -.bet] +>)
|
[%yow *] (se-link p.bet)
|
||||||
==
|
==
|
||||||
=+ gul=se-agon
|
=+ gul=se-agon
|
||||||
?: |(?=(~ gul) (se-aint u.gul))
|
?: |(?=(~ gul) (se-aint u.gul))
|
||||||
@ -341,6 +422,21 @@
|
|||||||
leaf+(weld (scag (sub edg 3) tape) "...")
|
leaf+(weld (scag (sub edg 3) tape) "...")
|
||||||
leaf+tape
|
leaf+tape
|
||||||
::
|
::
|
||||||
|
++ se-blin :: print and newline
|
||||||
|
|= $= lin
|
||||||
|
$~ [%put ~]
|
||||||
|
$>(?(%put %klr) dill-blit:dill)
|
||||||
|
^+ +>
|
||||||
|
:: newline means we need to redraw the prompt,
|
||||||
|
:: so update the prompt mirror accordingly.
|
||||||
|
::
|
||||||
|
=. mir [0 ~]
|
||||||
|
::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
|
++ se-dump :: print tanks
|
||||||
|= tac=(list tank)
|
|= tac=(list tank)
|
||||||
^+ +>
|
^+ +>
|
||||||
@ -351,7 +447,7 @@
|
|||||||
?. ((sane %t) (crip i.wol)) :: XX upstream validation
|
?. ((sane %t) (crip i.wol)) :: XX upstream validation
|
||||||
~& bad-text+<`*`i.wol>
|
~& bad-text+<`*`i.wol>
|
||||||
$(wol t.wol)
|
$(wol t.wol)
|
||||||
$(wol t.wol, +>.^$ (se-blit %out (tuba i.wol)))
|
$(wol t.wol, +>.^$ (se-blin %put (tuba i.wol)))
|
||||||
::
|
::
|
||||||
++ se-join :: confirm connection
|
++ se-join :: confirm connection
|
||||||
|= gyl=gill:gall
|
|= gyl=gill:gall
|
||||||
@ -379,20 +475,21 @@
|
|||||||
+>(eel (~(put in eel) gyl))
|
+>(eel (~(put in eel) gyl))
|
||||||
::
|
::
|
||||||
++ se-blit :: give output
|
++ se-blit :: give output
|
||||||
|= bil=dill-blit:dill
|
|= bil=blit:dill
|
||||||
+>(biz [bil biz])
|
+>(biz [bil biz])
|
||||||
::
|
::
|
||||||
++ se-blit-sys :: output to system
|
++ se-blit-sys :: output to system
|
||||||
|= bil=dill-blit:dill ^+ +>
|
|= 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
|
++ se-show :: show buffer, raw
|
||||||
|= lin=(pair @ud stub)
|
|= lin=(pair @ud stub)
|
||||||
^+ +>
|
^+ +>
|
||||||
?: =(mir lin) +>
|
?: =(mir lin) +>
|
||||||
=. +> ?:(=(p.mir p.lin) +> (se-blit %hop p.lin))
|
%- se-blit(mir lin)
|
||||||
=. +> ?:(=(q.mir q.lin) +> (se-blit %pom q.lin))
|
?: =(q.mir q.lin) [%hop p.lin]
|
||||||
+>(mir lin)
|
mor+[[%hop 0] [%wyp ~] [%klr q.lin] [%hop p.lin] ~]
|
||||||
::
|
::
|
||||||
++ se-just :: adjusted buffer
|
++ se-just :: adjusted buffer
|
||||||
|= [pom=stub lin=(pair @ud (list @c))]
|
|= [pom=stub lin=(pair @ud (list @c))]
|
||||||
@ -430,22 +527,22 @@
|
|||||||
?. ((sane %t) (crip txt)) :: XX upstream validation
|
?. ((sane %t) (crip txt)) :: XX upstream validation
|
||||||
~& bad-text+<`*`txt>
|
~& bad-text+<`*`txt>
|
||||||
+>
|
+>
|
||||||
(se-blit %out (tuba txt))
|
(se-blin %put (tuba txt))
|
||||||
::
|
::
|
||||||
++ se-poke :: send a poke
|
++ se-poke :: send a poke
|
||||||
|= [gyl=gill:gall par=cage]
|
|= [gyl=gill:gall par=cage]
|
||||||
(se-emit %pass (en-gill gyl) %agent gyl %poke par)
|
(se-emit %pass (en-gill ses gyl) %agent gyl %poke par)
|
||||||
::
|
::
|
||||||
++ se-peer :: send a peer
|
++ se-peer :: send a peer
|
||||||
|= gyl=gill:gall
|
|= gyl=gill:gall
|
||||||
~> %slog.0^leaf/"drum: link {<[p q]:gyl>}"
|
~> %slog.0^leaf/"drum: link {<[p q]:gyl>}"
|
||||||
=/ =path /sole/(cat 3 'drum_' (scot %p our.hid))
|
=/ =path (id-to-path:sole our.hid ses)
|
||||||
%- se-emit(fug (~(put by fug) gyl ~))
|
%- se-emit(fug (~(put by fug) gyl ~))
|
||||||
[%pass (en-gill gyl) %agent gyl %watch path]
|
[%pass (en-gill ses gyl) %agent gyl %watch path]
|
||||||
::
|
::
|
||||||
++ se-pull :: cancel subscription
|
++ se-pull :: cancel subscription
|
||||||
|= gyl=gill:gall
|
|= gyl=gill:gall
|
||||||
(se-emit %pass (en-gill gyl) %agent gyl %leave ~)
|
(se-emit %pass (en-gill ses gyl) %agent gyl %leave ~)
|
||||||
::
|
::
|
||||||
++ se-tame :: switch connection
|
++ se-tame :: switch connection
|
||||||
|= gyl=gill:gall
|
|= gyl=gill:gall
|
||||||
@ -470,7 +567,7 @@
|
|||||||
^+ +>
|
^+ +>
|
||||||
(ta-poke %sole-action !>(act))
|
(ta-poke %sole-action !>(act))
|
||||||
::
|
::
|
||||||
++ ta-id (cat 3 'drum_' (scot %p our.hid)) :: per-ship duct id
|
++ ta-id [our.hid ses] :: per-ship-session id
|
||||||
::
|
::
|
||||||
++ ta-aro :: hear arrow
|
++ ta-aro :: hear arrow
|
||||||
|= key=?(%d %l %r %u)
|
|= key=?(%d %l %r %u)
|
||||||
@ -499,13 +596,19 @@
|
|||||||
?< ?=([?(%cru %hey %rez %yow) *] bet) :: target-specific
|
?< ?=([?(%cru %hey %rez %yow) *] bet) :: target-specific
|
||||||
=. blt [q.blt `bet] :: remember belt
|
=. blt [q.blt `bet] :: remember belt
|
||||||
?- bet
|
?- bet
|
||||||
|
@ (ta-txt bet ~)
|
||||||
[%aro *] (ta-aro p.bet)
|
[%aro *] (ta-aro p.bet)
|
||||||
[%bac *] ta-bac
|
[%bac *] ta-bac
|
||||||
[%ctl *] (ta-ctl p.bet)
|
|
||||||
[%del *] ta-del
|
[%del *] ta-del
|
||||||
[%met *] (ta-met p.bet)
|
[%hit *] (ta-hit +.bet)
|
||||||
[%ret *] ta-ret
|
[%ret *] ta-ret
|
||||||
[%txt *] (ta-txt p.bet)
|
[%txt *] (ta-txt p.bet)
|
||||||
|
::
|
||||||
|
[%mod *]
|
||||||
|
?+ mod.bet $(bet key.bet)
|
||||||
|
%ctl (ta-ctl key.bet)
|
||||||
|
%met (ta-met key.bet)
|
||||||
|
==
|
||||||
==
|
==
|
||||||
::
|
::
|
||||||
++ ta-det :: send edit
|
++ ta-det :: send edit
|
||||||
@ -529,7 +632,7 @@
|
|||||||
(ta-hom %del (dec pos.inp))
|
(ta-hom %del (dec pos.inp))
|
||||||
::
|
::
|
||||||
++ ta-ctl :: hear control
|
++ ta-ctl :: hear control
|
||||||
|= key=@ud
|
|= key=bolt:dill
|
||||||
^+ +>
|
^+ +>
|
||||||
=. ris ?.(?=(?(%g %r) key) ~ ris)
|
=. ris ?.(?=(?(%g %r) key) ~ ris)
|
||||||
?+ key ta-bel
|
?+ key ta-bel
|
||||||
@ -539,7 +642,7 @@
|
|||||||
%d ?^ buf.say.inp
|
%d ?^ buf.say.inp
|
||||||
ta-del
|
ta-del
|
||||||
?: =([our.hid %dojo] gyl)
|
?: =([our.hid %dojo] gyl)
|
||||||
+>(..ta (se-blit qit+~)) :: quit pier
|
+>(..ta (se-blit-sys %qit ~)) :: quit pier
|
||||||
+>(..ta (se-klin gyl)) :: unlink app
|
+>(..ta (se-klin gyl)) :: unlink app
|
||||||
%e +>(pos.inp (lent buf.say.inp))
|
%e +>(pos.inp (lent buf.say.inp))
|
||||||
%f (ta-aro %r)
|
%f (ta-aro %r)
|
||||||
@ -550,7 +653,7 @@
|
|||||||
?: =(pos.inp len)
|
?: =(pos.inp len)
|
||||||
ta-bel
|
ta-bel
|
||||||
(ta-kil %r [pos.inp (sub len pos.inp)])
|
(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)
|
%n (ta-aro %d)
|
||||||
%p (ta-aro %u)
|
%p (ta-aro %u)
|
||||||
%r ?~ ris
|
%r ?~ ris
|
||||||
@ -583,6 +686,14 @@
|
|||||||
ta-bel
|
ta-bel
|
||||||
(ta-hom %del pos.inp)
|
(ta-hom %del pos.inp)
|
||||||
::
|
::
|
||||||
|
++ ta-hit :: hear click
|
||||||
|
|= [x=@ud y=@ud]
|
||||||
|
^+ +>
|
||||||
|
=/ pol=@ud
|
||||||
|
(lent-char:klr (make:klr cad.pom))
|
||||||
|
=? x (lth x pol) pol
|
||||||
|
+>.$(pos.inp (min (sub x pol) (lent buf.say.inp)))
|
||||||
|
::
|
||||||
++ ta-erl :: hear local error
|
++ ta-erl :: hear local error
|
||||||
|= pos=@ud
|
|= pos=@ud
|
||||||
ta-bel(pos.inp (min pos (lent buf.say.inp)))
|
ta-bel(pos.inp (min pos (lent buf.say.inp)))
|
||||||
@ -594,14 +705,13 @@
|
|||||||
++ ta-fec :: apply effect
|
++ ta-fec :: apply effect
|
||||||
|= fec=sole-effect
|
|= fec=sole-effect
|
||||||
^+ +>
|
^+ +>
|
||||||
?- fec
|
?+ fec +>(..ta (se-blit fec))
|
||||||
[%bel *] ta-bel
|
[%bel *] ta-bel
|
||||||
[%blk *] +>
|
[%blk *] +>
|
||||||
[%bye *] +>(..ta (se-klin gyl))
|
[%bye *] +>(..ta (se-klin gyl))
|
||||||
[%clr *] +>(..ta (se-blit fec))
|
|
||||||
[%det *] (ta-got +.fec)
|
[%det *] (ta-got +.fec)
|
||||||
[%err *] (ta-err p.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 *] |- ^+ +>.^$
|
[%mor *] |- ^+ +>.^$
|
||||||
?~ p.fec +>.^$
|
?~ p.fec +>.^$
|
||||||
$(p.fec t.p.fec, +>.^$ ^$(fec i.p.fec))
|
$(p.fec t.p.fec, +>.^$ ^$(fec i.p.fec))
|
||||||
@ -609,10 +719,8 @@
|
|||||||
[%pro *] (ta-pro +.fec)
|
[%pro *] (ta-pro +.fec)
|
||||||
[%tab *] +>(..ta (se-tab p.fec))
|
[%tab *] +>(..ta (se-tab p.fec))
|
||||||
[%tan *] +>(..ta (se-dump p.fec))
|
[%tan *] +>(..ta (se-dump p.fec))
|
||||||
[%sag *] +>(..ta (se-blit fec))
|
|
||||||
[%sav *] +>(..ta (se-blit fec))
|
|
||||||
[%txt *] +>(..ta (se-text p.fec))
|
[%txt *] +>(..ta (se-text p.fec))
|
||||||
[%url *] +>(..ta (se-blit fec))
|
[%url *] +>(..ta (se-text:(se-blit fec) (trip p.fec)))
|
||||||
==
|
==
|
||||||
::
|
::
|
||||||
++ ta-dog :: change cursor
|
++ ta-dog :: change cursor
|
||||||
@ -664,8 +772,8 @@
|
|||||||
kil
|
kil
|
||||||
?. ?& ?=(^ old.kil)
|
?. ?& ?=(^ old.kil)
|
||||||
?=(^ p.blt)
|
?=(^ p.blt)
|
||||||
?| ?=([%ctl ?(%k %u %w)] u.p.blt)
|
?| ?=([%mod %ctl ?(%k %u %w)] u.p.blt)
|
||||||
?=([%met ?(%d %bac)] u.p.blt)
|
?=([%mod %met ?(%d [%bac ~])] u.p.blt)
|
||||||
== ==
|
== ==
|
||||||
%= kil :: prepend
|
%= kil :: prepend
|
||||||
num +(num.kil)
|
num +(num.kil)
|
||||||
@ -682,17 +790,18 @@
|
|||||||
==
|
==
|
||||||
::
|
::
|
||||||
++ ta-met :: meta key
|
++ ta-met :: meta key
|
||||||
|= key=@ud
|
|= key=bolt:dill
|
||||||
^+ +>
|
^+ +>
|
||||||
=. ris ~
|
=. ris ~
|
||||||
?+ key ta-bel
|
?+ key ta-bel
|
||||||
%dot ?. &(?=(^ old.hit) ?=(^ i.old.hit)) :: last "arg" from hist
|
%'.' ?. &(?=(^ old.hit) ?=(^ i.old.hit)) :: last "arg" from hist
|
||||||
ta-bel
|
ta-bel
|
||||||
=+ old=`(list @c)`i.old.hit
|
=+ old=`(list @c)`i.old.hit
|
||||||
=+ sop=(ta-jump(buf.say.inp old) %l %ace (lent old))
|
=+ sop=(ta-jump(buf.say.inp old) %l %ace (lent old))
|
||||||
(ta-hom (cat:edit pos.inp (slag sop 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
|
ta-bel
|
||||||
=+ sop=(ta-pos %l %edg pos.inp)
|
=+ sop=(ta-pos %l %edg pos.inp)
|
||||||
(ta-kil %l [(sub pos.inp sop) sop])
|
(ta-kil %l [(sub pos.inp sop) sop])
|
||||||
@ -748,8 +857,8 @@
|
|||||||
::
|
::
|
||||||
%y ?. ?& ?=(^ old.kil) :: rotate & yank
|
%y ?. ?& ?=(^ old.kil) :: rotate & yank
|
||||||
?=(^ p.blt)
|
?=(^ p.blt)
|
||||||
?| ?=([%ctl %y] u.p.blt)
|
?| ?=([%mod %ctl %y] u.p.blt)
|
||||||
?=([%met %y] u.p.blt)
|
?=([%mod %met %y] u.p.blt)
|
||||||
== ==
|
== ==
|
||||||
ta-bel
|
ta-bel
|
||||||
=+ las=(lent ta-yan)
|
=+ las=(lent ta-yan)
|
||||||
@ -927,82 +1036,4 @@
|
|||||||
?: |(?=(~ a) (alnm i.a)) i
|
?: |(?=(~ a) (alnm i.a)) i
|
||||||
$(i +(i), a t.a)
|
$(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))
|
|
||||||
--
|
|
||||||
--
|
--
|
||||||
|
@ -504,7 +504,7 @@
|
|||||||
[%x %kiln %pikes ~]
|
[%x %kiln %pikes ~]
|
||||||
=+ .^(=rock:tire %cx /(scot %p our)//(scot %da now)/tire)
|
=+ .^(=rock:tire %cx /(scot %p our)//(scot %da now)/tire)
|
||||||
:^ ~ ~ %kiln-pikes
|
:^ ~ ~ %kiln-pikes
|
||||||
!> ^- pikes
|
!> ^- pikes
|
||||||
%- ~(rut by rock)
|
%- ~(rut by rock)
|
||||||
|= [=desk =zest wic=(set weft)]
|
|= [=desk =zest wic=(set weft)]
|
||||||
^- pike
|
^- pike
|
||||||
|
@ -45,8 +45,8 @@
|
|||||||
=+ cha=(tuba (trip q.kev))
|
=+ cha=(tuba (trip q.kev))
|
||||||
?> ?=([@ ~] cha) :: of a single character
|
?> ?=([@ ~] cha) :: of a single character
|
||||||
?+ mod !! :: modified by one buckykey
|
?+ mod !! :: modified by one buckykey
|
||||||
[%ctrl ~ ~] [%ctl i.cha]
|
[%ctrl ~ ~] [%mod %ctl i.cha]
|
||||||
[%alt ~ ~] [%met i.cha]
|
[%alt ~ ~] [%mod %met i.cha]
|
||||||
==
|
==
|
||||||
?@ q.kev
|
?@ q.kev
|
||||||
[%txt (tuba (trip q.kev))]
|
[%txt (tuba (trip q.kev))]
|
||||||
|
@ -19,8 +19,10 @@
|
|||||||
^- ^json
|
^- ^json
|
||||||
?+ -.dib ~|(unsupported-blit+-.dib !!)
|
?+ -.dib ~|(unsupported-blit+-.dib !!)
|
||||||
%mor [%a (turn p.dib |=(a=dill-blit:dill json(dib a)))]
|
%mor [%a (turn p.dib |=(a=dill-blit:dill json(dib a)))]
|
||||||
%hop (frond %hop (numb p.dib))
|
%hop %+ frond %hop
|
||||||
?(%pro %out) (frond -.dib (tape (tufa p.dib)))
|
?@ p.dib (numb p.dib)
|
||||||
|
(pairs 'x'^(numb x.p.dib) 'y'^(numb y.p.dib) ~)
|
||||||
|
%put (frond -.dib (tape (tufa p.dib)))
|
||||||
?(%bel %clr) (frond %act %s -.dib)
|
?(%bel %clr) (frond %act %s -.dib)
|
||||||
==
|
==
|
||||||
--
|
--
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
|
:: %drum-put: download into host system
|
||||||
::
|
::
|
||||||
:::: /hoon/do-claim/womb/mar
|
|
||||||
::
|
|
||||||
/? 310
|
/? 310
|
||||||
|_ [path @]
|
|_ [path $@(@ [@ta @])]
|
||||||
::
|
::
|
||||||
++ grad %noun
|
++ grad %noun
|
||||||
++ grow
|
++ grow
|
||||||
@ -11,6 +10,6 @@
|
|||||||
--
|
--
|
||||||
++ grab :: convert from
|
++ grab :: convert from
|
||||||
|%
|
|%
|
||||||
+$ noun [path @] :: clam from %noun
|
+$ noun [path $@(@ [@ta @])] :: clam from %noun
|
||||||
--
|
--
|
||||||
--
|
--
|
||||||
|
46
pkg/arvo/mar/herm/task.hoon
Normal file
46
pkg/arvo/mar/herm/task.hoon
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
:: task: herm task for passthrough to dill
|
||||||
|
::
|
||||||
|
/- herm
|
||||||
|
/+ dill
|
||||||
|
::
|
||||||
|
|_ =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:dejs:^dill
|
||||||
|
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) ~)
|
||||||
|
--
|
||||||
|
--
|
||||||
|
:: +grow: convert to
|
||||||
|
::
|
||||||
|
++ grow
|
||||||
|
|%
|
||||||
|
++ noun task
|
||||||
|
--
|
||||||
|
--
|
9
pkg/arvo/sur/herm.hoon
Normal file
9
pkg/arvo/sur/herm.hoon
Normal file
@ -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)
|
||||||
|
==
|
||||||
|
--
|
@ -1 +1 @@
|
|||||||
[%zuse 417]
|
[%zuse 416]
|
||||||
|
@ -415,7 +415,7 @@
|
|||||||
==
|
==
|
||||||
--
|
--
|
||||||
::
|
::
|
||||||
:: |de: axal engine
|
:: |of: axal engine
|
||||||
::
|
::
|
||||||
++ of
|
++ of
|
||||||
=| fat=(axal)
|
=| fat=(axal)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
!:
|
!:
|
||||||
=> ..part
|
=> ..part
|
||||||
|%
|
|%
|
||||||
++ lull %328
|
++ lull %327
|
||||||
:: :: ::
|
:: :: ::
|
||||||
:::: :: :: (1) models
|
:::: :: :: (1) models
|
||||||
:: :: ::
|
:: :: ::
|
||||||
@ -752,7 +752,6 @@
|
|||||||
[%hill p=(list @tas)] :: mount points
|
[%hill p=(list @tas)] :: mount points
|
||||||
[%done error=(unit error:ames)] :: ames message (n)ack
|
[%done error=(unit error:ames)] :: ames message (n)ack
|
||||||
[%mere p=(each (set path) (pair term tang))] :: merge result
|
[%mere p=(each (set path) (pair term tang))] :: merge result
|
||||||
[%note p=@tD q=tank] :: debug message
|
|
||||||
[%ogre p=@tas] :: delete mount point
|
[%ogre p=@tas] :: delete mount point
|
||||||
[%rule red=dict wit=dict] :: node r+w permissions
|
[%rule red=dict wit=dict] :: node r+w permissions
|
||||||
[%tire p=(each rock:tire wave:tire)] :: app state
|
[%tire p=(each rock:tire wave:tire)] :: app state
|
||||||
@ -1160,9 +1159,7 @@
|
|||||||
++ dill ^?
|
++ dill ^?
|
||||||
|%
|
|%
|
||||||
+$ gift :: out result <-$
|
+$ gift :: out result <-$
|
||||||
$% [%bbye ~] :: reset prompt
|
$% [%blit p=(list blit)] :: terminal output
|
||||||
[%blit p=(list blit)] :: terminal output
|
|
||||||
[%burl p=@t] :: activate url
|
|
||||||
[%logo ~] :: logout
|
[%logo ~] :: logout
|
||||||
[%meld ~] :: unify memory
|
[%meld ~] :: unify memory
|
||||||
[%pack ~] :: compact memory
|
[%pack ~] :: compact memory
|
||||||
@ -1170,29 +1167,32 @@
|
|||||||
== ::
|
== ::
|
||||||
+$ task :: in request ->$
|
+$ task :: in request ->$
|
||||||
$~ [%vega ~] ::
|
$~ [%vega ~] ::
|
||||||
$% [%belt p=belt] :: terminal input
|
$% [%boot lit=? p=*] :: weird %dill boot
|
||||||
[%blew p=blew] :: terminal config
|
|
||||||
[%boot lit=? p=*] :: weird %dill boot
|
|
||||||
[%crop p=@ud] :: trim kernel state
|
[%crop p=@ud] :: trim kernel state
|
||||||
[%crud p=@tas q=(list tank)] :: print error
|
[%crud p=@tas q=(list tank)] :: print error
|
||||||
[%flee session=~] :: unwatch session
|
|
||||||
[%flog p=flog] :: wrapped error
|
[%flog p=flog] :: wrapped error
|
||||||
[%flow p=@tas q=(list gill:gall)] :: terminal config
|
|
||||||
[%hail ~] :: terminal refresh
|
|
||||||
[%heft ~] :: memory report
|
[%heft ~] :: memory report
|
||||||
[%hook ~] :: this term hung up
|
|
||||||
[%harm ~] :: all terms hung up
|
|
||||||
$>(%init vane-task) :: after gall ready
|
$>(%init vane-task) :: after gall ready
|
||||||
[%meld ~] :: unify memory
|
[%meld ~] :: unify memory
|
||||||
[%noop ~] :: no operation
|
|
||||||
[%pack ~] :: compact memory
|
[%pack ~] :: compact memory
|
||||||
[%talk p=tank] ::
|
[%shot ses=@tas task=session-task] :: task for session
|
||||||
[%text p=tape] ::
|
[%talk p=(list tank)] :: print tanks
|
||||||
[%view session=~] :: watch session blits
|
[%text p=tape] :: print tape
|
||||||
$>(%trim vane-task) :: trim state
|
$>(%trim vane-task) :: trim state
|
||||||
$>(%vega vane-task) :: report upgrade
|
$>(%vega vane-task) :: report upgrade
|
||||||
[%verb ~] :: verbose mode
|
[%verb ~] :: verbose mode
|
||||||
[%knob tag=term level=?(%hush %soft %loud)] :: error verbosity
|
[%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
|
||||||
|
[%hail ~] :: terminal refresh
|
||||||
|
[%open p=dude:gall q=(list gill:gall)] :: setup session
|
||||||
|
[%shut ~] :: close session
|
||||||
|
[%view ~] :: watch session blits
|
||||||
== ::
|
== ::
|
||||||
::
|
::
|
||||||
:::: :: (1d2)
|
:::: :: (1d2)
|
||||||
@ -1200,59 +1200,41 @@
|
|||||||
+$ blew [p=@ud q=@ud] :: columns rows
|
+$ blew [p=@ud q=@ud] :: columns rows
|
||||||
+$ belt :: client input
|
+$ belt :: client input
|
||||||
$? bolt :: simple input
|
$? bolt :: simple input
|
||||||
$% [%mod mod=?(%ctl %met %hyp) key=bolt] :: w/ modifier
|
[%mod mod=?(%ctl %met %hyp) key=bolt] :: w/ modifier
|
||||||
[%txt p=(list @c)] :: utf32 text
|
[%txt p=(list @c)] :: utf32 text
|
||||||
::TODO consider moving %hey, %rez, %yow here ::
|
::TODO consider moving %hey, %rez, %yow here ::
|
||||||
::TMP forward backwards-compatibility ::
|
== ::
|
||||||
:: ::
|
|
||||||
[%ctl p=@c] ::
|
|
||||||
[%met p=@c] ::
|
|
||||||
== == ::
|
|
||||||
+$ bolt :: simple input
|
+$ bolt :: simple input
|
||||||
$@ @c :: simple keystroke
|
$@ @c :: simple keystroke
|
||||||
$% [%aro p=?(%d %l %r %u)] :: arrow key
|
$% [%aro p=?(%d %l %r %u)] :: arrow key
|
||||||
[%bac ~] :: true backspace
|
[%bac ~] :: true backspace
|
||||||
[%del ~] :: true delete
|
[%del ~] :: true delete
|
||||||
[%hit r=@ud c=@ud] :: mouse click
|
[%hit x=@ud y=@ud] :: mouse click
|
||||||
[%ret ~] :: return
|
[%ret ~] :: return
|
||||||
== ::
|
== ::
|
||||||
+$ blit :: old blit
|
+$ blit :: client output
|
||||||
$% [%bel ~] :: make a noise
|
$% [%bel ~] :: make a noise
|
||||||
[%clr ~] :: clear the screen
|
[%clr ~] :: clear the screen
|
||||||
[%hop p=@ud] :: set cursor position
|
[%hop p=$@(@ud [x=@ud y=@ud])] :: set cursor col/pos
|
||||||
[%klr p=stub] :: set styled line
|
[%klr p=stub] :: put styled
|
||||||
[%lin p=(list @c)] :: set current line
|
[%mor p=(list blit)] :: multiple blits
|
||||||
[%mor ~] :: newline
|
[%nel ~] :: newline
|
||||||
|
[%put p=(list @c)] :: put text at cursor
|
||||||
[%sag p=path q=*] :: save to jamfile
|
[%sag p=path q=*] :: save to jamfile
|
||||||
[%sav p=path q=@] :: save to file
|
[%sav p=path q=@] :: save to file
|
||||||
[%url p=@t] :: activate url
|
[%url p=@t] :: activate url
|
||||||
|
[%wyp ~] :: wipe cursor line
|
||||||
== ::
|
== ::
|
||||||
+$ dill-belt :: new belt
|
+$ dill-belt :: arvo input
|
||||||
$% [%aro p=?(%d %l %r %u)] :: arrow key
|
$% belt :: client input
|
||||||
[%bac ~] :: true backspace
|
|
||||||
[%cru p=@tas q=(list tank)] :: echo error
|
[%cru p=@tas q=(list tank)] :: echo error
|
||||||
[%ctl p=@] :: control-key
|
|
||||||
[%del ~] :: true delete
|
|
||||||
[%hey ~] :: refresh
|
[%hey ~] :: refresh
|
||||||
[%met p=@] :: meta-key
|
|
||||||
[%ret ~] :: return
|
|
||||||
[%rez p=@ud q=@ud] :: resize, cols, rows
|
[%rez p=@ud q=@ud] :: resize, cols, rows
|
||||||
[%txt p=(list @c)] :: utf32 text
|
|
||||||
[%yow p=gill:gall] :: connect to app
|
[%yow p=gill:gall] :: connect to app
|
||||||
== ::
|
== ::
|
||||||
+$ dill-blit :: new blit
|
+$ dill-blit :: arvo output
|
||||||
$% [%bel ~] :: make a noise
|
$% blit :: client output
|
||||||
[%clr ~] :: clear the screen
|
|
||||||
[%hop p=@ud] :: set cursor position
|
|
||||||
[%klr p=stub] :: styled text
|
|
||||||
[%mor p=(list dill-blit)] :: multiple blits
|
|
||||||
[%pom p=stub] :: styled prompt
|
|
||||||
[%pro p=(list @c)] :: show as cursor+line
|
|
||||||
[%qit ~] :: close console
|
[%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
|
+$ flog :: sent to %dill
|
||||||
$% [%crop p=@ud] :: trim kernel state
|
$% [%crop p=@ud] :: trim kernel state
|
||||||
@ -1263,6 +1245,11 @@
|
|||||||
[%text p=tape] ::
|
[%text p=tape] ::
|
||||||
[%verb ~] :: verbose mode
|
[%verb ~] :: verbose mode
|
||||||
== ::
|
== ::
|
||||||
|
:: ::
|
||||||
|
+$ poke :: dill to userspace
|
||||||
|
$: ses=@tas :: target session
|
||||||
|
dill-belt :: input
|
||||||
|
== ::
|
||||||
-- ::dill
|
-- ::dill
|
||||||
:: ::::
|
:: ::::
|
||||||
:::: ++eyre :: (1e) http-server
|
:::: ++eyre :: (1e) http-server
|
||||||
@ -1763,7 +1750,6 @@
|
|||||||
+$ gift :: outgoing result
|
+$ gift :: outgoing result
|
||||||
$% [%boon payload=*] :: ames response
|
$% [%boon payload=*] :: ames response
|
||||||
[%done error=(unit error:ames)] :: ames message (n)ack
|
[%done error=(unit error:ames)] :: ames message (n)ack
|
||||||
[%onto p=(each suss tang)] :: about agent
|
|
||||||
[%unto p=unto] ::
|
[%unto p=unto] ::
|
||||||
== ::
|
== ::
|
||||||
+$ task :: incoming request
|
+$ task :: incoming request
|
||||||
@ -2531,9 +2517,6 @@
|
|||||||
:: %ames: hear packet
|
:: %ames: hear packet
|
||||||
::
|
::
|
||||||
$>(%hear task:ames)
|
$>(%hear task:ames)
|
||||||
:: %dill: hangup
|
|
||||||
::
|
|
||||||
$>(%hook task:dill)
|
|
||||||
:: %clay: external edit
|
:: %clay: external edit
|
||||||
::
|
::
|
||||||
$>(%into task:clay)
|
$>(%into task:clay)
|
||||||
@ -2554,6 +2537,9 @@
|
|||||||
:: %eyre: starts handling an backdoor http request
|
:: %eyre: starts handling an backdoor http request
|
||||||
::
|
::
|
||||||
$>(%request-local task:eyre)
|
$>(%request-local task:eyre)
|
||||||
|
:: %dill: close session
|
||||||
|
::
|
||||||
|
$>(%shut task:dill)
|
||||||
:: %behn: wakeup
|
:: %behn: wakeup
|
||||||
::
|
::
|
||||||
$>(%wake task:behn)
|
$>(%wake task:behn)
|
||||||
|
@ -733,6 +733,7 @@
|
|||||||
$% [%private-keys ~]
|
$% [%private-keys ~]
|
||||||
[%public-keys ships=(set ship)]
|
[%public-keys ships=(set ship)]
|
||||||
[%turf ~]
|
[%turf ~]
|
||||||
|
[%ruin ships=(set ship)]
|
||||||
== ==
|
== ==
|
||||||
$: @tas
|
$: @tas
|
||||||
$% [%plea =ship =plea]
|
$% [%plea =ship =plea]
|
||||||
@ -1247,7 +1248,7 @@
|
|||||||
=(%$ syd)
|
=(%$ syd)
|
||||||
==
|
==
|
||||||
?. for.veb.bug.ames-state ~
|
?. for.veb.bug.ames-state ~
|
||||||
~> %slog.0^leaf/"ames: scry-fail {<[why=why lot=lot now=now syd=syd]>}"
|
~> %slog.0^leaf/"ames: scry-fail {<why=why lot=lot now=now syd=syd>}"
|
||||||
~
|
~
|
||||||
:: /ax/protocol/version @
|
:: /ax/protocol/version @
|
||||||
:: /ax/peers (map ship ?(%alien %known))
|
:: /ax/peers (map ship ?(%alien %known))
|
||||||
@ -1774,28 +1775,30 @@
|
|||||||
|. ^- tape
|
|. ^- tape
|
||||||
=/ sndr [our our-life.channel]
|
=/ sndr [our our-life.channel]
|
||||||
=/ rcvr [ship her-life.channel]
|
=/ rcvr [ship her-life.channel]
|
||||||
"plea {<sndr^rcvr^bone=bone^vane.plea^path.plea>}"
|
"plea {<sndr rcvr bone=bone vane.plea path.plea>}"
|
||||||
abet:(on-memo:(make-peer-core peer-state channel) bone plea %plea)
|
abet:(on-memo:(make-peer-core peer-state channel) bone plea %plea)
|
||||||
:: +on-cork: handle request to kill a flow
|
:: +on-cork: handle request to kill a flow
|
||||||
::
|
::
|
||||||
++ on-cork
|
++ on-cork
|
||||||
|= =ship
|
|= =ship
|
||||||
^+ event-core
|
^+ event-core
|
||||||
|
=/ =plea [%$ /flow [%cork ~]]
|
||||||
=/ ship-state (~(get by peers.ames-state) ship)
|
=/ ship-state (~(get by peers.ames-state) ship)
|
||||||
::
|
?. ?=([~ %known *] ship-state)
|
||||||
?> ?=([~ %known *] ship-state)
|
%+ enqueue-alien-todo ship
|
||||||
|
|= todos=alien-agenda
|
||||||
|
todos(messages [[duct plea] messages.todos])
|
||||||
=/ =peer-state +.u.ship-state
|
=/ =peer-state +.u.ship-state
|
||||||
=/ =channel [[our ship] now channel-state -.peer-state]
|
=/ =channel [[our ship] now channel-state -.peer-state]
|
||||||
::
|
::
|
||||||
=^ =bone ossuary.peer-state (bind-duct ossuary.peer-state duct)
|
=^ =bone ossuary.peer-state (bind-duct ossuary.peer-state duct)
|
||||||
=/ =plea [%$ /flow [%cork ~]]
|
|
||||||
::
|
::
|
||||||
=. closing.peer-state (~(put in closing.peer-state) bone)
|
=. closing.peer-state (~(put in closing.peer-state) bone)
|
||||||
%- %^ trace msg.veb ship
|
%- %^ trace msg.veb ship
|
||||||
|. ^- tape
|
|. ^- tape
|
||||||
=/ sndr [our our-life.channel]
|
=/ sndr [our our-life.channel]
|
||||||
=/ rcvr [ship her-life.channel]
|
=/ rcvr [ship her-life.channel]
|
||||||
"cork plea {<sndr^rcvr^bone=bone^vane.plea^path.plea>}"
|
"cork plea {<sndr rcvr bone=bone vane.plea path.plea>}"
|
||||||
abet:(on-memo:(make-peer-core peer-state channel) bone plea %plea)
|
abet:(on-memo:(make-peer-core peer-state channel) bone plea %plea)
|
||||||
:: +on-take-wake: receive wakeup or error notification from behn
|
:: +on-take-wake: receive wakeup or error notification from behn
|
||||||
::
|
::
|
||||||
@ -1923,14 +1926,14 @@
|
|||||||
:: we shouldn't be hearing about ships we don't care about
|
:: we shouldn't be hearing about ships we don't care about
|
||||||
::
|
::
|
||||||
?~ ship-state
|
?~ ship-state
|
||||||
~> %slog.0^leaf/"ames: breach unknown {<our^ship>}"
|
~> %slog.0^leaf/"ames: breach unknown {<our ship>}"
|
||||||
event-core
|
event-core
|
||||||
:: if an alien breached, this doesn't affect us
|
:: if an alien breached, this doesn't affect us
|
||||||
::
|
::
|
||||||
?: ?=([~ %alien *] ship-state)
|
?: ?=([~ %alien *] ship-state)
|
||||||
~> %slog.0^leaf/"ames: breach alien {<our^ship>}"
|
~> %slog.0^leaf/"ames: breach alien {<our ship>}"
|
||||||
event-core
|
event-core
|
||||||
~> %slog.0^leaf/"ames: breach peer {<our^ship>}"
|
~> %slog.0^leaf/"ames: breach peer {<our ship>}"
|
||||||
:: a peer breached; drop messaging state
|
:: a peer breached; drop messaging state
|
||||||
::
|
::
|
||||||
=/ =peer-state +.u.ship-state
|
=/ =peer-state +.u.ship-state
|
||||||
@ -2063,6 +2066,8 @@
|
|||||||
=. event-core
|
=. event-core
|
||||||
%+ reel messages.todos
|
%+ reel messages.todos
|
||||||
|= [[=^duct =plea] core=_event-core]
|
|= [[=^duct =plea] core=_event-core]
|
||||||
|
?: ?=(%$ -.plea)
|
||||||
|
(on-cork:core(duct duct) ship)
|
||||||
(on-plea:core(duct duct) ship plea)
|
(on-plea:core(duct duct) ship plea)
|
||||||
:: apply outgoing packet blobs
|
:: apply outgoing packet blobs
|
||||||
::
|
::
|
||||||
@ -2141,10 +2146,27 @@
|
|||||||
::
|
::
|
||||||
(emit unix-duct.ames-state %give %turf turfs)
|
(emit unix-duct.ames-state %give %turf turfs)
|
||||||
:: +on-vega: handle kernel reload
|
:: +on-vega: handle kernel reload
|
||||||
:: +on-trim: handle request to free memory
|
|
||||||
::
|
::
|
||||||
++ on-vega event-core
|
++ on-vega event-core
|
||||||
++ on-trim event-core
|
:: +on-trim: handle request to free memory
|
||||||
|
::
|
||||||
|
:: %ruin comets not seen for six months
|
||||||
|
::
|
||||||
|
++ on-trim
|
||||||
|
^+ event-core
|
||||||
|
=; rui=(set @p)
|
||||||
|
(emit duct %pass /ruin %j %ruin rui)
|
||||||
|
=- (silt (turn - head))
|
||||||
|
%+ skim
|
||||||
|
~(tap by peers.ames-state)
|
||||||
|
|= [=ship s=ship-state]
|
||||||
|
?. &(?=(%known -.s) =(%pawn (clan:title ship))) %.n
|
||||||
|
?& (gth (sub now ~d180) last-contact.qos.s)
|
||||||
|
::
|
||||||
|
%- ~(any by snd.s)
|
||||||
|
|= m=message-pump-state
|
||||||
|
!=(~ unsent-fragments.m)
|
||||||
|
==
|
||||||
:: +enqueue-alien-todo: helper to enqueue a pending request
|
:: +enqueue-alien-todo: helper to enqueue a pending request
|
||||||
::
|
::
|
||||||
:: Also requests key and life from Jael on first request.
|
:: Also requests key and life from Jael on first request.
|
||||||
@ -2590,12 +2612,12 @@
|
|||||||
=(~ unsent-fragments.pum)
|
=(~ unsent-fragments.pum)
|
||||||
=(~ live.packet-pump-state.pum)
|
=(~ live.packet-pump-state.pum)
|
||||||
==
|
==
|
||||||
~> %slog.0^leaf/"ames: bad pump state {<[her.channel i.boz]>}"
|
~> %slog.0^leaf/"ames: bad pump state {<her.channel i.boz>}"
|
||||||
$(boz t.boz)
|
$(boz t.boz)
|
||||||
:: no outstanding messages, so send a new %cork
|
:: no outstanding messages, so send a new %cork
|
||||||
::
|
::
|
||||||
:: TODO use +trace
|
:: TODO use +trace
|
||||||
~> %slog.0^leaf/"ames: recork {<[her.channel i.boz]>}"
|
~> %slog.0^leaf/"ames: recork {<her.channel i.boz>}"
|
||||||
=/ =plea [%$ /flow [%cork ~]]
|
=/ =plea [%$ /flow [%cork ~]]
|
||||||
(on-memo i.boz plea %plea)
|
(on-memo i.boz plea %plea)
|
||||||
:: +got-duct: look up $duct by .bone, asserting already bound
|
:: +got-duct: look up $duct by .bone, asserting already bound
|
||||||
@ -2768,11 +2790,18 @@
|
|||||||
::
|
::
|
||||||
(emit [/ames]~ %pass wire %b %rest next-wake)
|
(emit [/ames]~ %pass wire %b %rest next-wake)
|
||||||
=/ nax-bone=^bone (mix 0b10 bone)
|
=/ nax-bone=^bone (mix 0b10 bone)
|
||||||
|
=? peer-core (~(has by snd.peer-state) nax-bone)
|
||||||
|
%. peer-core
|
||||||
|
%+ trace odd.veb
|
||||||
|
=/ dat [her.channel bone=nax-bone message-num=message-num -.task]
|
||||||
|
|.("remove naxplanation flow {<dat>}")
|
||||||
=. peer-state
|
=. peer-state
|
||||||
=, peer-state
|
=, peer-state
|
||||||
%_ peer-state
|
%_ peer-state
|
||||||
|
:: preemptively delete nax flows (e.g. nacks for initial %watches)
|
||||||
|
::
|
||||||
|
snd (~(del by (~(del by snd) bone)) nax-bone)
|
||||||
rcv (~(del by rcv) bone)
|
rcv (~(del by rcv) bone)
|
||||||
snd (~(del by snd) bone)
|
|
||||||
corked (~(put in corked) bone)
|
corked (~(put in corked) bone)
|
||||||
closing (~(del in closing) bone)
|
closing (~(del in closing) bone)
|
||||||
krocs (~(del in krocs) bone)
|
krocs (~(del in krocs) bone)
|
||||||
@ -3196,9 +3225,14 @@
|
|||||||
++ packet-queue
|
++ packet-queue
|
||||||
%- (ordered-map live-packet-key live-packet-val)
|
%- (ordered-map live-packet-key live-packet-val)
|
||||||
lte-packets
|
lte-packets
|
||||||
|
:: +live-packets: number of sent packets awaiting ack
|
||||||
|
::
|
||||||
|
++ live-packets
|
||||||
|
^- @ud
|
||||||
|
~(wyt by live.state)
|
||||||
:: +gauge: inflate a |pump-gauge to track congestion control
|
:: +gauge: inflate a |pump-gauge to track congestion control
|
||||||
::
|
::
|
||||||
++ gauge (make-pump-gauge now.channel metrics.state [her bug]:channel)
|
++ gauge (make-pump-gauge metrics.state live-packets [now her bug]:channel)
|
||||||
:: +work: handle $packet-pump-task request
|
:: +work: handle $packet-pump-task request
|
||||||
::
|
::
|
||||||
++ work
|
++ work
|
||||||
@ -3253,7 +3287,7 @@
|
|||||||
=? packet-pump ?=(^ static-fragment)
|
=? packet-pump ?=(^ static-fragment)
|
||||||
%- %+ trace snd.veb
|
%- %+ trace snd.veb
|
||||||
=/ nums [message-num fragment-num]:u.static-fragment.res
|
=/ nums [message-num fragment-num]:u.static-fragment.res
|
||||||
|.("dead {<nums^show:gauge>}")
|
|.("dead {<nums show:gauge>}")
|
||||||
(give %send u.static-fragment.res)
|
(give %send u.static-fragment.res)
|
||||||
packet-pump
|
packet-pump
|
||||||
::
|
::
|
||||||
@ -3312,7 +3346,6 @@
|
|||||||
:: update .live and .metrics
|
:: update .live and .metrics
|
||||||
::
|
::
|
||||||
=. live.state (gas:packet-queue live.state send-list)
|
=. live.state (gas:packet-queue live.state send-list)
|
||||||
=. metrics.state (on-sent:gauge (lent send-list))
|
|
||||||
:: TMI
|
:: TMI
|
||||||
::
|
::
|
||||||
=> .(sent `(list static-fragment)`sent)
|
=> .(sent `(list static-fragment)`sent)
|
||||||
@ -3374,7 +3407,7 @@
|
|||||||
=(0 (mod counter.metrics.state 20))
|
=(0 (mod counter.metrics.state 20))
|
||||||
==
|
==
|
||||||
same
|
same
|
||||||
(trace snd.veb |.("send: {<[fragment=fragment-num show:gauge]>}"))
|
(trace snd.veb |.("send: {<fragment=fragment-num show:gauge>}"))
|
||||||
:: .resends is backward, so fold backward and emit
|
:: .resends is backward, so fold backward and emit
|
||||||
::
|
::
|
||||||
=. packet-pump
|
=. packet-pump
|
||||||
@ -3398,7 +3431,7 @@
|
|||||||
==
|
==
|
||||||
^- [new-val=(unit live-packet-val) stop=? _acc]
|
^- [new-val=(unit live-packet-val) stop=? _acc]
|
||||||
::
|
::
|
||||||
=/ gauge (make-pump-gauge now.channel metrics.acc [her bug]:channel)
|
=/ gauge (make-pump-gauge metrics.acc live-packets [now her bug]:channel)
|
||||||
:: is this the acked packet?
|
:: is this the acked packet?
|
||||||
::
|
::
|
||||||
?: =(key [message-num fragment-num])
|
?: =(key [message-num fragment-num])
|
||||||
@ -3433,7 +3466,7 @@
|
|||||||
=- =. metrics.state metrics.-
|
=- =. metrics.state metrics.-
|
||||||
=. live.state live.-
|
=. live.state live.-
|
||||||
::
|
::
|
||||||
%- (trace snd.veb |.("done {<message-num=message-num^show:gauge>}"))
|
%- (trace snd.veb |.("done {<message-num=message-num show:gauge>}"))
|
||||||
(fast-resend-after-ack message-num `fragment-num`0)
|
(fast-resend-after-ack message-num `fragment-num`0)
|
||||||
::
|
::
|
||||||
^+ [metrics=metrics.state live=live.state]
|
^+ [metrics=metrics.state live=live.state]
|
||||||
@ -3445,7 +3478,7 @@
|
|||||||
==
|
==
|
||||||
^- [new-val=(unit live-packet-val) stop=? pump-metrics]
|
^- [new-val=(unit live-packet-val) stop=? pump-metrics]
|
||||||
::
|
::
|
||||||
=/ gauge (make-pump-gauge now.channel metrics [her bug]:channel)
|
=/ gauge (make-pump-gauge metrics live-packets [now her bug]:channel)
|
||||||
:: if we get an out-of-order ack for a message, skip until it
|
:: if we get an out-of-order ack for a message, skip until it
|
||||||
::
|
::
|
||||||
?: (lth message-num.key message-num)
|
?: (lth message-num.key message-num)
|
||||||
@ -3493,9 +3526,10 @@
|
|||||||
:: +make-pump-gauge: construct |pump-gauge congestion control core
|
:: +make-pump-gauge: construct |pump-gauge congestion control core
|
||||||
::
|
::
|
||||||
++ make-pump-gauge
|
++ make-pump-gauge
|
||||||
|= [now=@da pump-metrics =ship =bug]
|
|= [pump-metrics live-packets=@ud now=@da =ship =bug]
|
||||||
|
:: TODO rename live-packets num-live
|
||||||
=* veb veb.bug
|
=* veb veb.bug
|
||||||
=* metrics +<+<
|
=* metrics +<-
|
||||||
|%
|
|%
|
||||||
++ trace
|
++ trace
|
||||||
|= [verb=? print=(trap tape)]
|
|= [verb=? print=(trap tape)]
|
||||||
@ -3515,15 +3549,7 @@
|
|||||||
::
|
::
|
||||||
++ num-slots
|
++ num-slots
|
||||||
^- @ud
|
^- @ud
|
||||||
(sub-safe cwnd num-live)
|
(sub-safe cwnd live-packets)
|
||||||
:: +on-sent: adjust metrics based on sending .num-sent fresh packets
|
|
||||||
::
|
|
||||||
++ on-sent
|
|
||||||
|= num-sent=@ud
|
|
||||||
^- pump-metrics
|
|
||||||
::
|
|
||||||
=. num-live (add num-live num-sent)
|
|
||||||
metrics
|
|
||||||
:: +on-ack: adjust metrics based on a packet getting acknowledged
|
:: +on-ack: adjust metrics based on a packet getting acknowledged
|
||||||
::
|
::
|
||||||
++ on-ack
|
++ on-ack
|
||||||
@ -3531,7 +3557,6 @@
|
|||||||
^- pump-metrics
|
^- pump-metrics
|
||||||
::
|
::
|
||||||
=. counter +(counter)
|
=. counter +(counter)
|
||||||
=. num-live (dec num-live)
|
|
||||||
:: if below congestion threshold, add 1; else, add avg. 1 / cwnd
|
:: if below congestion threshold, add 1; else, add avg. 1 / cwnd
|
||||||
::
|
::
|
||||||
=. cwnd
|
=. cwnd
|
||||||
@ -3571,7 +3596,7 @@
|
|||||||
::
|
::
|
||||||
=? cwnd !in-recovery (max 2 (div cwnd 2))
|
=? cwnd !in-recovery (max 2 (div cwnd 2))
|
||||||
%- %+ trace snd.veb
|
%- %+ trace snd.veb
|
||||||
|.("skip {<[resend=resend in-recovery=in-recovery show]>}")
|
|.("skip {<resend=resend in-recovery=in-recovery show>}")
|
||||||
metrics
|
metrics
|
||||||
:: +on-timeout: (re)enter slow-start mode on packet loss
|
:: +on-timeout: (re)enter slow-start mode on packet loss
|
||||||
::
|
::
|
||||||
@ -3597,12 +3622,12 @@
|
|||||||
(lth cwnd ssthresh)
|
(lth cwnd ssthresh)
|
||||||
:: +in-recovery: %.y iff we're recovering from a skipped packet
|
:: +in-recovery: %.y iff we're recovering from a skipped packet
|
||||||
::
|
::
|
||||||
:: We finish recovering when .num-live finally dips back down to
|
:: We finish recovering when .live-packets finally dips back down to
|
||||||
:: .cwnd.
|
:: .cwnd.
|
||||||
::
|
::
|
||||||
++ in-recovery
|
++ in-recovery
|
||||||
^- ?
|
^- ?
|
||||||
(gth num-live cwnd)
|
(gth live-packets cwnd)
|
||||||
:: +sub-safe: subtract with underflow protection
|
:: +sub-safe: subtract with underflow protection
|
||||||
::
|
::
|
||||||
++ sub-safe
|
++ sub-safe
|
||||||
@ -3619,7 +3644,7 @@
|
|||||||
rttvar=(div rttvar ms)
|
rttvar=(div rttvar ms)
|
||||||
ssthresh=ssthresh
|
ssthresh=ssthresh
|
||||||
cwnd=cwnd
|
cwnd=cwnd
|
||||||
num-live=num-live
|
num-live=live-packets
|
||||||
counter=counter
|
counter=counter
|
||||||
==
|
==
|
||||||
--
|
--
|
||||||
@ -3665,7 +3690,7 @@
|
|||||||
::
|
::
|
||||||
?: (gte seq (add 10 last-acked.state))
|
?: (gte seq (add 10 last-acked.state))
|
||||||
%- %+ trace odd.veb
|
%- %+ trace odd.veb
|
||||||
|.("future %hear {<seq=seq^last-acked=last-acked.state>}")
|
|.("future %hear {<seq=seq last-acked=last-acked.state>}")
|
||||||
message-sink
|
message-sink
|
||||||
::
|
::
|
||||||
=/ is-last-fragment=? =(+(fragment-num) num-fragments)
|
=/ is-last-fragment=? =(+(fragment-num) num-fragments)
|
||||||
@ -3676,7 +3701,7 @@
|
|||||||
:: single packet ack
|
:: single packet ack
|
||||||
::
|
::
|
||||||
%- %+ trace rcv.veb
|
%- %+ trace rcv.veb
|
||||||
|.("send dupe ack {<seq=seq^fragment-num=fragment-num>}")
|
|.("send dupe ack {<seq=seq fragment-num>}")
|
||||||
(give %send seq %& fragment-num)
|
(give %send seq %& fragment-num)
|
||||||
:: whole message (n)ack
|
:: whole message (n)ack
|
||||||
::
|
::
|
||||||
@ -3696,8 +3721,8 @@
|
|||||||
%- %+ trace rcv.veb
|
%- %+ trace rcv.veb
|
||||||
|. ^- tape
|
|. ^- tape
|
||||||
=/ data
|
=/ data
|
||||||
:* her.channel seq=seq bone=bone
|
:* her.channel seq=seq bone=bone.shut-packet
|
||||||
fragment-num=fragment-num num-fragments=num-fragments
|
fragment-num num-fragments
|
||||||
la=last-acked.state lh=last-heard.state
|
la=last-acked.state lh=last-heard.state
|
||||||
==
|
==
|
||||||
"hear last in-progress {<data>}"
|
"hear last in-progress {<data>}"
|
||||||
@ -3706,8 +3731,8 @@
|
|||||||
::
|
::
|
||||||
%- %+ trace rcv.veb |.
|
%- %+ trace rcv.veb |.
|
||||||
=/ data
|
=/ data
|
||||||
:* seq=seq fragment-num=fragment-num
|
:* seq=seq fragment-num
|
||||||
num-fragments=num-fragments closing=closing
|
num-fragments closing=closing
|
||||||
==
|
==
|
||||||
"send ack-1 {<data>}"
|
"send ack-1 {<data>}"
|
||||||
(give %send seq %& fragment-num)
|
(give %send seq %& fragment-num)
|
||||||
@ -3737,7 +3762,7 @@
|
|||||||
"hear last dupe {<data>}"
|
"hear last dupe {<data>}"
|
||||||
message-sink
|
message-sink
|
||||||
%- %+ trace rcv.veb
|
%- %+ trace rcv.veb
|
||||||
|.("send dupe ack {<her.channel^seq=seq^fragment-num=fragment-num>}")
|
|.("send dupe ack {<her.channel seq=seq fragment-num>}")
|
||||||
(give %send seq %& fragment-num)
|
(give %send seq %& fragment-num)
|
||||||
:: new fragment; store in state and check if message is done
|
:: new fragment; store in state and check if message is done
|
||||||
::
|
::
|
||||||
@ -3754,7 +3779,7 @@
|
|||||||
=? message-sink !is-last-fragment
|
=? message-sink !is-last-fragment
|
||||||
%- %+ trace rcv.veb |.
|
%- %+ trace rcv.veb |.
|
||||||
=/ data
|
=/ data
|
||||||
[seq=seq fragment-num=fragment-num num-fragments=num-fragments]
|
[seq=seq fragment-num num-fragments]
|
||||||
"send ack-2 {<data>}"
|
"send ack-2 {<data>}"
|
||||||
(give %send seq %& fragment-num)
|
(give %send seq %& fragment-num)
|
||||||
:: enqueue all completed messages starting at +(last-heard.state)
|
:: enqueue all completed messages starting at +(last-heard.state)
|
||||||
|
@ -432,7 +432,10 @@
|
|||||||
task ::
|
task ::
|
||||||
== ::
|
== ::
|
||||||
$: %d :: to %dill
|
$: %d :: to %dill
|
||||||
$>(%flog task:dill) ::
|
$> $? %flog ::
|
||||||
|
%text ::
|
||||||
|
== ::
|
||||||
|
task:dill ::
|
||||||
== ::
|
== ::
|
||||||
$: %g :: to %gall
|
$: %g :: to %gall
|
||||||
$> $? %deal
|
$> $? %deal
|
||||||
@ -460,14 +463,12 @@
|
|||||||
== == ::
|
== == ::
|
||||||
$: %clay ::
|
$: %clay ::
|
||||||
$> $? %mere ::
|
$> $? %mere ::
|
||||||
%note ::
|
|
||||||
%writ ::
|
%writ ::
|
||||||
== ::
|
== ::
|
||||||
gift ::
|
gift ::
|
||||||
== ::
|
== ::
|
||||||
$: %gall
|
$: %gall
|
||||||
$> $? %onto
|
$> $? %unto
|
||||||
%unto
|
|
||||||
==
|
==
|
||||||
gift:gall
|
gift:gall
|
||||||
==
|
==
|
||||||
@ -2209,7 +2210,8 @@
|
|||||||
|= [prefix=@tD paths=(set path)]
|
|= [prefix=@tD paths=(set path)]
|
||||||
%+ turn ~(tap in paths)
|
%+ turn ~(tap in paths)
|
||||||
|= =path
|
|= =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-to-tank
|
||||||
|= =path
|
|= =path
|
||||||
@ -5774,8 +5776,6 @@
|
|||||||
?^ dud
|
?^ dud
|
||||||
~|(%clay-take-dud (mean tang.u.dud))
|
~|(%clay-take-dud (mean tang.u.dud))
|
||||||
?: ?=([%lu %load *] tea)
|
?: ?=([%lu %load *] tea)
|
||||||
?: ?=(%onto +<.hin)
|
|
||||||
[~ ..^$]
|
|
||||||
?> ?=(%unto +<.hin)
|
?> ?=(%unto +<.hin)
|
||||||
?> ?=(%poke-ack -.p.hin)
|
?> ?=(%poke-ack -.p.hin)
|
||||||
?~ p.p.hin
|
?~ p.p.hin
|
||||||
@ -5950,7 +5950,6 @@
|
|||||||
q.p.p.+.hin
|
q.p.p.+.hin
|
||||||
[~ ..^$]
|
[~ ..^$]
|
||||||
::
|
::
|
||||||
%note [[hen %give +.hin]~ ..^$]
|
|
||||||
%wake
|
%wake
|
||||||
:: TODO: handle behn errors
|
:: TODO: handle behn errors
|
||||||
::
|
::
|
||||||
@ -5973,7 +5972,6 @@
|
|||||||
::
|
::
|
||||||
%boon !!
|
%boon !!
|
||||||
%lost !!
|
%lost !!
|
||||||
%onto !!
|
|
||||||
%unto !!
|
%unto !!
|
||||||
%writ
|
%writ
|
||||||
%- (slog leaf+"clay: strange writ (expected on upgrade to Fusion)" ~)
|
%- (slog leaf+"clay: strange writ (expected on upgrade to Fusion)" ~)
|
||||||
|
@ -8,27 +8,26 @@
|
|||||||
-- ::
|
-- ::
|
||||||
=> |% :: console protocol
|
=> |% :: console protocol
|
||||||
+$ axle ::
|
+$ axle ::
|
||||||
$: %4 ::TODO replace ducts with session ids ::
|
$: %6 ::
|
||||||
hey=(unit duct) :: default duct
|
hey=(unit duct) :: default duct
|
||||||
dug=(map duct axon) :: conversations
|
dug=(map @tas axon) :: conversations
|
||||||
eye=(jug duct duct) :: outside listeners
|
eye=(jug @tas duct) :: outside listeners
|
||||||
lit=? :: boot in lite mode
|
lit=? :: boot in lite mode
|
||||||
$= veb :: vane verbosities
|
$= veb :: vane verbosities
|
||||||
$~ (~(put by *(map @tas log-level)) %hole %soft) :: quiet packet crashes
|
$~ (~(put by *(map @tas log-level)) %hole %soft) :: quiet packet crashes
|
||||||
(map @tas log-level) ::
|
(map @tas log-level) ::
|
||||||
|
egg=_| :: see +take, removeme
|
||||||
== ::
|
== ::
|
||||||
+$ axon :: dill per duct
|
+$ axon :: dill session
|
||||||
$: ram=term :: console program
|
$: ram=term :: console program
|
||||||
tem=(unit (list dill-belt)) :: pending, reverse
|
tem=(unit (list dill-belt)) :: pending, reverse
|
||||||
wid=_80 :: terminal width
|
wid=_80 :: terminal width
|
||||||
pos=@ud :: cursor position
|
|
||||||
see=$%([%lin (list @c)] [%klr stub]) :: current line
|
|
||||||
== ::
|
== ::
|
||||||
+$ log-level ?(%hush %soft %loud) :: none, line, full
|
+$ log-level ?(%hush %soft %loud) :: none, line, full
|
||||||
-- => ::
|
-- => ::
|
||||||
|% :: protocol outward
|
|% :: protocol outward
|
||||||
+$ mess ::
|
+$ mess ::
|
||||||
$% [%dill-belt p=(hypo dill-belt)] ::
|
$% [%dill-poke p=(hypo poke)] ::
|
||||||
== ::
|
== ::
|
||||||
+$ move [p=duct q=(wind note gift)] :: local move
|
+$ move [p=duct q=(wind note gift)] :: local move
|
||||||
+$ note :: out request $->
|
+$ note :: out request $->
|
||||||
@ -69,7 +68,6 @@
|
|||||||
== == ::
|
== == ::
|
||||||
$: %clay ::
|
$: %clay ::
|
||||||
$> $? %mere ::
|
$> $? %mere ::
|
||||||
%note ::
|
|
||||||
%writ ::
|
%writ ::
|
||||||
== ::
|
== ::
|
||||||
gift:clay ::
|
gift:clay ::
|
||||||
@ -78,10 +76,7 @@
|
|||||||
$>(%blit gift:dill) ::
|
$>(%blit gift:dill) ::
|
||||||
== ::
|
== ::
|
||||||
$: %gall ::
|
$: %gall ::
|
||||||
$> $? %onto ::
|
$>(%unto gift:gall) ::
|
||||||
%unto ::
|
|
||||||
== ::
|
|
||||||
gift:gall ::
|
|
||||||
== == ::
|
== == ::
|
||||||
:::::::: :: dill tiles
|
:::::::: :: dill tiles
|
||||||
--
|
--
|
||||||
@ -91,39 +86,27 @@
|
|||||||
|%
|
|%
|
||||||
++ as :: per cause
|
++ as :: per cause
|
||||||
=| moz=(list move)
|
=| moz=(list move)
|
||||||
|_ [hen=duct axon]
|
|_ [hen=duct ses=@tas axon]
|
||||||
++ abet :: resolve
|
++ abet :: resolve
|
||||||
^- [(list move) axle]
|
^- [(list move) axle]
|
||||||
[(flop moz) all(dug (~(put by dug.all) hen +<+))]
|
[(flop moz) all(dug (~(put by dug.all) ses +<+>))]
|
||||||
::
|
::
|
||||||
++ call :: receive input
|
++ call :: receive input
|
||||||
|= kyz=task
|
|= kyz=task
|
||||||
^+ +>
|
^+ +>
|
||||||
?+ -.kyz ~& [%strange-kiss -.kyz] +>
|
?+ -.kyz ~& [%strange-kiss -.kyz] +>
|
||||||
%flow +>
|
%hail (send %hey ~)
|
||||||
%harm +>
|
%belt (send `dill-belt`p.kyz)
|
||||||
%hail (send %hey ~)
|
%talk (talk p.kyz)
|
||||||
%text (from %out (tuba p.kyz))
|
%text (fore (tuba p.kyz) ~)
|
||||||
%crud :: (send `dill-belt`[%cru p.kyz q.kyz])
|
%crud :: (send `dill-belt`[%cru p.kyz q.kyz])
|
||||||
(crud 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/~)
|
%heft (pass /whey %$ whey/~)
|
||||||
%meld (dump kyz)
|
%meld (dump kyz)
|
||||||
%pack (dump kyz)
|
%pack (dump kyz)
|
||||||
%crop (dump trim+p.kyz)
|
%crop (dump trim+p.kyz)
|
||||||
%verb (pass /verb %$ kyz)
|
%verb (pass /verb %$ kyz)
|
||||||
%noop +>
|
|
||||||
%belt
|
|
||||||
%- send
|
|
||||||
::TMP forwards compatibility with next-dill
|
|
||||||
::
|
|
||||||
?@ p.kyz [%txt p.kyz ~]
|
|
||||||
?: ?=(%hit -.p.kyz) [%txt ~]
|
|
||||||
?. ?=(%mod -.p.kyz) p.kyz
|
|
||||||
=/ =@c
|
|
||||||
?@ key.p.kyz key.p.kyz
|
|
||||||
?:(?=(?(%bac %del %ret) -.key.p.kyz) `@`-.key.p.kyz ~-)
|
|
||||||
?:(?=(%met mod.p.kyz) [%met c] [%ctl c])
|
|
||||||
==
|
==
|
||||||
::
|
::
|
||||||
++ crud
|
++ crud
|
||||||
@ -133,30 +116,30 @@
|
|||||||
=/ lev=log-level (~(gut by veb.all) err %loud)
|
=/ lev=log-level (~(gut by veb.all) err %loud)
|
||||||
:: apply log level for this error tag
|
:: apply log level for this error tag
|
||||||
::
|
::
|
||||||
=/ =wall
|
?- lev
|
||||||
?- lev
|
%hush +>.$
|
||||||
%hush ~
|
%soft (fore (tuba "crud: %{(trip err)} event failed") ~)
|
||||||
%soft ~["crud: %{(trip err)} event failed"]
|
%loud (talk leaf+"crud: %{(trip err)} event failed" (flop tac))
|
||||||
%loud :- "crud: %{(trip err)} event failed"
|
==
|
||||||
%- zing
|
::
|
||||||
%+ turn (flop tac)
|
++ talk
|
||||||
|=(a=tank (~(win re a) [0 wid]))
|
|= tac=(list tank)
|
||||||
==
|
%- fore
|
||||||
|- ^+ +>.^$
|
%- zing
|
||||||
?~ wall +>.^$
|
%+ turn tac
|
||||||
$(wall t.wall, +>.^$ (from %out (tuba i.wall)))
|
|= a=tank
|
||||||
|
(turn (~(win re a) [0 wid]) tuba)
|
||||||
::
|
::
|
||||||
++ dump :: pass down to hey
|
++ dump :: pass down to hey
|
||||||
|= git=gift
|
|= git=gift
|
||||||
?> ?=(^ hey.all)
|
?> ?=(^ hey.all)
|
||||||
+>(moz [[u.hey.all %give git] moz])
|
+>(moz [[u.hey.all %give git] moz])
|
||||||
::
|
::
|
||||||
++ done :: return gift
|
++ done :: gift to viewers
|
||||||
|= git=gift
|
|= git=gift
|
||||||
=- +>.$(moz (weld - moz))
|
=- +>.$(moz (weld - moz))
|
||||||
%+ turn
|
%+ turn
|
||||||
:- hen
|
~(tap in (~(get ju eye.all) ses))
|
||||||
~(tap in (~(get ju eye.all) hen))
|
|
||||||
|=(=duct [duct %give git])
|
|=(=duct [duct %give git])
|
||||||
::
|
::
|
||||||
++ deal :: pass to %gall
|
++ deal :: pass to %gall
|
||||||
@ -167,44 +150,37 @@
|
|||||||
|= [=wire =note]
|
|= [=wire =note]
|
||||||
+>(moz :_(moz [hen %pass 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))
|
||||||
|
~? !=(%$ ses) [%d %foreing-in-session ses]
|
||||||
|
^+ +>
|
||||||
|
=. +>
|
||||||
|
=| biz=(list blit)
|
||||||
|
|- ^+ +>.^$
|
||||||
|
?~ liz (done %blit [%hop 0] [%wyp ~] biz)
|
||||||
|
$(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.
|
||||||
|
::
|
||||||
|
(send %hey ~)
|
||||||
|
::
|
||||||
++ from :: receive blit
|
++ from :: receive blit
|
||||||
|= bit=dill-blit
|
|= bit=dill-blit
|
||||||
^+ +>
|
^+ +>
|
||||||
?: ?=(%mor -.bit)
|
|
||||||
|- ^+ +>.^$
|
|
||||||
?~ p.bit +>.^$
|
|
||||||
$(p.bit t.p.bit, +>.^$ ^$(bit i.p.bit))
|
|
||||||
?: ?=(%out -.bit)
|
|
||||||
%+ done %blit
|
|
||||||
:~ [%lin p.bit]
|
|
||||||
[%mor ~]
|
|
||||||
see
|
|
||||||
[%hop pos]
|
|
||||||
==
|
|
||||||
?: ?=(%klr -.bit)
|
|
||||||
%+ done %blit
|
|
||||||
:~ [%klr p.bit]
|
|
||||||
[%mor ~]
|
|
||||||
see
|
|
||||||
[%hop pos]
|
|
||||||
==
|
|
||||||
?: ?=(%pro -.bit)
|
|
||||||
=. 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)
|
|
||||||
(done(pos p.bit) %blit [bit ~])
|
|
||||||
?: ?=(%qit -.bit)
|
?: ?=(%qit -.bit)
|
||||||
(dump %logo ~)
|
(dump %logo ~)
|
||||||
(done %blit [bit ~])
|
::TODO so why is this a (list blit) again?
|
||||||
|
(done %blit bit ~)
|
||||||
::
|
::
|
||||||
++ sponsor
|
++ sponsor
|
||||||
^- ship
|
^- ship
|
||||||
@ -221,7 +197,7 @@
|
|||||||
=. tem ~
|
=. tem ~
|
||||||
=. ..mere (pass /zest %c %zest %base %live)
|
=. ..mere (pass /zest %c %zest %base %live)
|
||||||
=. ..mere (show-desk %kids)
|
=. ..mere (show-desk %kids)
|
||||||
=. ..mere drum-watch
|
=. ..mere (open ~)
|
||||||
|- ^+ ..mere
|
|- ^+ ..mere
|
||||||
?~ myt ..mere
|
?~ myt ..mere
|
||||||
$(myt t.myt, ..mere (send i.myt))
|
$(myt t.myt, ..mere (send i.myt))
|
||||||
@ -231,15 +207,27 @@
|
|||||||
=. tem `(turn gyl |=(a=gill [%yow a]))
|
=. tem `(turn gyl |=(a=gill [%yow a]))
|
||||||
(pass / [%c %warp our %base `[%sing %y [%ud 1] /]])
|
(pass / [%c %warp our %base `[%sing %y [%ud 1] /]])
|
||||||
::
|
::
|
||||||
|
++ open
|
||||||
|
|= gyl=(list gill)
|
||||||
|
::TODO should allow handlers from non-base desks
|
||||||
|
::TODO maybe ensure :ram is running?
|
||||||
|
=. +> peer
|
||||||
|
%+ roll gyl
|
||||||
|
|= [g=gill _..open]
|
||||||
|
(send [%yow g])
|
||||||
|
::
|
||||||
++ send :: send action
|
++ send :: send action
|
||||||
|= bet=dill-belt
|
|= bet=dill-belt
|
||||||
^+ +>
|
^+ +>
|
||||||
?^ tem
|
?^ tem
|
||||||
+>(tem `[bet u.tem])
|
+>(tem `[bet u.tem])
|
||||||
(deal / [%poke [%dill-belt -:!>(bet) bet]])
|
(deal /send/[ses] [%poke [%dill-poke !>([ses bet])]])
|
||||||
::
|
::
|
||||||
++ drum-watch
|
++ peer
|
||||||
(deal / [%watch /drum])
|
(deal /peer/[ses] %watch /dill/[ses])
|
||||||
|
::
|
||||||
|
++ pull
|
||||||
|
(deal /peer/[ses] %leave ~)
|
||||||
::
|
::
|
||||||
++ show-desk :: permit reads on desk
|
++ show-desk :: permit reads on desk
|
||||||
|= des=desk
|
|= des=desk
|
||||||
@ -249,21 +237,11 @@
|
|||||||
|= [tea=wire sih=sign]
|
|= [tea=wire sih=sign]
|
||||||
^+ +>
|
^+ +>
|
||||||
?- sih
|
?- sih
|
||||||
[%gall %onto *]
|
|
||||||
:: NOTE effects during initial boot sequence are ignored,
|
|
||||||
:: so :hood compilation errors will not print; slog if desired
|
|
||||||
::
|
|
||||||
:: ~& [%take-gall-onto +>.sih]
|
|
||||||
?- -.+>.sih
|
|
||||||
%| (crud %onto p.p.+>.sih)
|
|
||||||
%& (done %blit [%lin (tuba "{<p.p.sih>}")]~)
|
|
||||||
==
|
|
||||||
::
|
|
||||||
[%gall %unto *]
|
[%gall %unto *]
|
||||||
:: ~& [%take-gall-unto +>.sih]
|
:: ~& [%take-gall-unto +>.sih]
|
||||||
?- -.+>.sih
|
?- -.+>.sih
|
||||||
%raw-fact !!
|
%raw-fact !!
|
||||||
%kick drum-watch
|
%kick peer
|
||||||
%poke-ack ?~(p.p.+>.sih +>.$ (crud %coup u.p.p.+>.sih))
|
%poke-ack ?~(p.p.+>.sih +>.$ (crud %coup u.p.p.+>.sih))
|
||||||
%watch-ack
|
%watch-ack
|
||||||
?~ p.p.+>.sih
|
?~ p.p.+>.sih
|
||||||
@ -275,9 +253,6 @@
|
|||||||
+>.$
|
+>.$
|
||||||
(from ;;(dill-blit q.q.cage.p.+>.sih))
|
(from ;;(dill-blit q.q.cage.p.+>.sih))
|
||||||
==
|
==
|
||||||
::
|
|
||||||
[%clay %note *]
|
|
||||||
(from %out (tuba p.sih ' ' ~(ram re q.sih)))
|
|
||||||
::
|
::
|
||||||
[?(%behn %clay) %writ *]
|
[?(%behn %clay) %writ *]
|
||||||
init
|
init
|
||||||
@ -292,12 +267,20 @@
|
|||||||
==
|
==
|
||||||
--
|
--
|
||||||
::
|
::
|
||||||
++ ax :: make ++as
|
++ ax :: make ++as from name
|
||||||
|= hen=duct
|
|= [hen=duct ses=@tas]
|
||||||
^- (unit _as)
|
^- (unit _as)
|
||||||
=/ nux (~(get by dug.all) hen)
|
=/ nux (~(get by dug.all) ses)
|
||||||
?~ nux ~
|
?~ 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
|
|% :: poke+peek pattern
|
||||||
++ call :: handle request
|
++ call :: handle request
|
||||||
@ -308,7 +291,10 @@
|
|||||||
^+ [*(list move) ..^$]
|
^+ [*(list move) ..^$]
|
||||||
~| wrapped-task
|
~| wrapped-task
|
||||||
=/ task=task ((harden task) 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
|
:: error notifications "downcast" to %crud
|
||||||
::
|
::
|
||||||
=? task ?=(^ dud)
|
=? task ?=(^ dud)
|
||||||
@ -338,10 +324,11 @@
|
|||||||
::
|
::
|
||||||
=* duc (need hey.all)
|
=* duc (need hey.all)
|
||||||
=/ app %hood
|
=/ app %hood
|
||||||
=/ see (tuba "<awaiting {(trip app)}, this may take a minute>")
|
=/ say (tuba "<awaiting {(trip app)}, this may take a minute>")
|
||||||
=/ zon=axon [app input=[~ ~] width=80 cursor=(lent see) lin+see]
|
=/ zon=axon [app input=[~ ~] width=80]
|
||||||
::
|
::
|
||||||
=^ moz all abet:(~(into as duc zon) ~)
|
=^ moz all abet:(~(into as duc %$ zon) ~)
|
||||||
|
=. eye.all (~(put ju eye.all) %$ duc)
|
||||||
[moz ..^$]
|
[moz ..^$]
|
||||||
:: %flog tasks are unwrapped and sent back to us on our default duct
|
:: %flog tasks are unwrapped and sent back to us on our default duct
|
||||||
::
|
::
|
||||||
@ -362,35 +349,60 @@
|
|||||||
?: ?=(%knob -.task)
|
?: ?=(%knob -.task)
|
||||||
=. veb.all (~(put by veb.all) tag.task level.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)
|
||||||
|
=. 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))
|
||||||
|
::NOTE we do deletion from state outside of the core,
|
||||||
|
:: because +abet would re-insert.
|
||||||
|
::TODO send a %bye blit? xx
|
||||||
|
=^ moz all abet:pull:nus
|
||||||
|
=. dug.all (~(del by dug.all) ses)
|
||||||
|
=. eye.all (~(del by eye.all) ses)
|
||||||
|
[moz ..^$]
|
||||||
|
:: %view opens a subscription to the target session, on the current duct
|
||||||
::
|
::
|
||||||
?: ?=(%view -.task)
|
?: ?=(%view -.task)
|
||||||
:: crash on viewing non-existent 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
|
||||||
::
|
::
|
||||||
~| [%no-session session.task]
|
=^ moz all
|
||||||
?> =(~ session.task)
|
abet:(send:nus %hey ~)
|
||||||
=/ session (need hey.all)
|
:- moz
|
||||||
=/ =axon (~(got by dug.all) session)
|
..^$(eye.all (~(put ju eye.all) ses hen))
|
||||||
:: register the viewer and send them the prompt line
|
:: %flee closes a subscription to the target session, from the current duct
|
||||||
::
|
|
||||||
:- [hen %give %blit [see.axon]~]~
|
|
||||||
..^$(eye.all (~(put ju eye.all) session hen))
|
|
||||||
::
|
::
|
||||||
?: ?=(%flee -.task)
|
?: ?=(%flee -.task)
|
||||||
:- ~
|
:- ~
|
||||||
~| [%no-session session.task]
|
..^$(eye.all (~(del ju eye.all) ses hen))
|
||||||
?> =(~ session.task)
|
|
||||||
=/ session (need hey.all)
|
|
||||||
..^$(eye.all (~(del ju eye.all) session hen))
|
|
||||||
::
|
::
|
||||||
=/ nus (ax hen)
|
=/ nus
|
||||||
=? nus &(?=(~ nus) ?=(^ hey.all))
|
(ax hen ses)
|
||||||
::TODO allow specifying target session in task
|
|
||||||
(ax u.hey.all)
|
|
||||||
?~ nus
|
?~ nus
|
||||||
:: :hen is an unrecognized duct
|
:: session :ses does not exist
|
||||||
:: could be before %boot (or %boot failed)
|
:: 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 ~)
|
=/ tan ?:(?=(%crud -.task) q.task ~)
|
||||||
[((slog (flop tan)) ~) ..^$]
|
[((slog (flop tan)) ~) ..^$]
|
||||||
::
|
::
|
||||||
@ -398,8 +410,79 @@
|
|||||||
[moz ..^$]
|
[moz ..^$]
|
||||||
::
|
::
|
||||||
++ load :: import old state
|
++ load :: import old state
|
||||||
|= old=axle
|
=< |= old=any-axle
|
||||||
..^$(all old)
|
?- -.old
|
||||||
|
%6 ..^$(all old)
|
||||||
|
%5 $(old (axle-5-to-6 old))
|
||||||
|
%4 $(old (axle-4-to-5 old))
|
||||||
|
==
|
||||||
|
|%
|
||||||
|
+$ any-axle $%(axle axle-5 axle-4)
|
||||||
|
::
|
||||||
|
+$ axle-5
|
||||||
|
$: %5
|
||||||
|
hey=(unit duct) :: default duct
|
||||||
|
dug=(map @tas axon) :: conversations
|
||||||
|
eye=(jug @tas duct) :: outside listeners
|
||||||
|
lit=? :: boot in lite mode
|
||||||
|
veb=(map @tas log-level)
|
||||||
|
==
|
||||||
|
::
|
||||||
|
++ axle-5-to-6
|
||||||
|
|= a=axle-5
|
||||||
|
^- axle
|
||||||
|
:: [%6 hey `(map @tas axon)`dug eye lit veb |]
|
||||||
|
a(- %6, veb [veb.a &])
|
||||||
|
::
|
||||||
|
+$ 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-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-5
|
||||||
|
:- %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
|
||||||
|
=; tem [ram tem wid]
|
||||||
|
?~ tem ~
|
||||||
|
%- some
|
||||||
|
%+ turn u.tem
|
||||||
|
|= b=dill-belt-4
|
||||||
|
^- dill-belt
|
||||||
|
?. ?=(?(%ctl %met) -.b) b
|
||||||
|
[%mod -.b p.b]
|
||||||
|
--
|
||||||
::
|
::
|
||||||
++ scry
|
++ scry
|
||||||
^- roon
|
^- roon
|
||||||
@ -428,19 +511,12 @@
|
|||||||
=(%$ syd)
|
=(%$ syd)
|
||||||
==
|
==
|
||||||
~
|
~
|
||||||
:: /dx/sessions//line blit current line (prompt) of default session
|
:: /dy/sessions (set @tas) all existing sessions
|
||||||
:: /dx/sessions//cursor @ud current cursor position of default session
|
:: /du/sessions/[ses] ? does session ses exist?
|
||||||
::TODO support asking for specific sessions once session ids are real
|
|
||||||
::
|
::
|
||||||
?. ?=(%x ren) ~
|
?+ [ren tyl] ~
|
||||||
?+ tyl ~
|
[%y %sessions ~] ``noun+!>(~(key by dug.all))
|
||||||
[%sessions %$ *]
|
[%u %sessions @ ~] ``noun+!>((~(has by dug.all) (snag 1 tyl)))
|
||||||
?~ hey.all [~ ~]
|
|
||||||
?~ session=(~(get by dug.all) u.hey.all) [~ ~]
|
|
||||||
?+ t.t.tyl ~
|
|
||||||
[%line ~] ``blit+!>(`blit`see.u.session)
|
|
||||||
[%cursor ~] ``atom+!>(pos.u.session)
|
|
||||||
==
|
|
||||||
==
|
==
|
||||||
::
|
::
|
||||||
++ stay all
|
++ stay all
|
||||||
@ -451,12 +527,27 @@
|
|||||||
?^ dud
|
?^ dud
|
||||||
~|(%dill-take-dud (mean tang.u.dud))
|
~|(%dill-take-dud (mean tang.u.dud))
|
||||||
::
|
::
|
||||||
=/ nus (ax hen)
|
=; [moz=(list move) lax=_..^$]
|
||||||
|
=? moz egg.all.lax
|
||||||
|
:: dill pre-release (version %5) in some cases ended up in a state
|
||||||
|
:: where it had both an old-style and new-style subscription open
|
||||||
|
:: for the default session. here, we obliterate both and establish
|
||||||
|
:: only the new-style subscription.
|
||||||
|
::
|
||||||
|
=/ hey (need hey.all.lax)
|
||||||
|
:* [hey %pass / %g %deal [our our] %hood %leave ~]
|
||||||
|
[hey %pass [%peer %$ ~] %g %deal [our our] %hood %leave ~]
|
||||||
|
[hey %pass [%peer %$ ~] %g %deal [our our] %hood %watch [%dill %$ ~]]
|
||||||
|
moz
|
||||||
|
==
|
||||||
|
=. egg.all.lax |
|
||||||
|
[moz lax]
|
||||||
|
::
|
||||||
|
=/ nus (aw hen tea)
|
||||||
?~ nus
|
?~ nus
|
||||||
:: :hen is an unrecognized duct
|
:: :tea points to an unrecognized session
|
||||||
:: could be before %boot (or %boot failed)
|
|
||||||
::
|
::
|
||||||
~& [%dill-take-no-flow hen -.hin +<.hin]
|
~& [%dill-take-no-session tea -.hin +<.hin]
|
||||||
[~ ..^$]
|
[~ ..^$]
|
||||||
=^ moz all abet:(take:u.nus tea hin)
|
=^ moz all abet:(take:u.nus tea hin)
|
||||||
[moz ..^$]
|
[moz ..^$]
|
||||||
|
@ -198,11 +198,21 @@
|
|||||||
:: +mo-abet: finalize, reversing moves
|
:: +mo-abet: finalize, reversing moves
|
||||||
:: +mo-pass: prepend a standard %pass to the current list of 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-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-core .
|
||||||
++ mo-abed |=(hun=duct mo-core(hen hun))
|
++ mo-abed |=(hun=duct mo-core(hen hun))
|
||||||
++ mo-abet [(flop moves) gall-payload]
|
++ mo-abet [(flop moves) gall-payload]
|
||||||
++ mo-give |=(g=gift mo-core(moves [[hen give+g] 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-pass |=(p=[wire note-arvo] mo-core(moves [[hen pass+p] moves]))
|
++ mo-pass |=(p=[wire note-arvo] mo-core(moves [[hen pass+p] moves]))
|
||||||
++ mo-slip |=(p=note-arvo mo-core(moves [[hen slip+p] moves]))
|
++ mo-slip |=(p=note-arvo mo-core(moves [[hen slip+p] moves]))
|
||||||
++ mo-past
|
++ mo-past
|
||||||
@ -303,12 +313,12 @@
|
|||||||
=/ ap-core +.wag
|
=/ ap-core +.wag
|
||||||
?^ maybe-tang
|
?^ maybe-tang
|
||||||
=. mo-core old
|
=. 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 ap-abet:ap-core
|
||||||
=. mo-core (mo-clear-queue dap)
|
=. mo-core (mo-clear-queue dap)
|
||||||
=/ =suss [dap %boot now]
|
=/ =suss [dap %boot now]
|
||||||
(mo-give %onto [%.y suss])
|
(mo-pass (mo-talk %.y suss))
|
||||||
:: +mo-send-foreign-request: handle local request to .ship
|
:: +mo-send-foreign-request: handle local request to .ship
|
||||||
::
|
::
|
||||||
++ mo-send-foreign-request
|
++ mo-send-foreign-request
|
||||||
@ -523,6 +533,11 @@
|
|||||||
?~ error=error.sign-arvo
|
?~ error=error.sign-arvo
|
||||||
~
|
~
|
||||||
`[[%leaf (trip tag.u.error)] tang.u.error]
|
`[[%leaf (trip tag.u.error)] tang.u.error]
|
||||||
|
:: send a %cork if we get a nack upon initial subscription
|
||||||
|
::
|
||||||
|
=? mo-core
|
||||||
|
&(?=(^ err) |(?=(%watch-as remote-request) ?=(%watch remote-request)))
|
||||||
|
(mo-pass [%sys wire] %a %cork ship)
|
||||||
::
|
::
|
||||||
?- remote-request
|
?- remote-request
|
||||||
%watch-as (mo-give %unto %watch-ack err)
|
%watch-as (mo-give %unto %watch-ack err)
|
||||||
@ -899,8 +914,8 @@
|
|||||||
::
|
::
|
||||||
=/ running (~(put by yokes.state) agent-name yoke)
|
=/ running (~(put by yokes.state) agent-name yoke)
|
||||||
=/ moves
|
=/ moves
|
||||||
=/ giver |=(report=(each suss tang) [hen %give %onto report])
|
=/ talker |=(report=(each suss tang) [hen %pass (mo-talk report)])
|
||||||
=/ from-suss (turn agent-config giver)
|
=/ from-suss (turn agent-config talker)
|
||||||
:(weld agent-moves from-suss moves)
|
:(weld agent-moves from-suss moves)
|
||||||
::
|
::
|
||||||
%_ mo-core
|
%_ mo-core
|
||||||
|
@ -105,11 +105,8 @@
|
|||||||
$>(%wake gift:behn) ::
|
$>(%wake gift:behn) ::
|
||||||
== ::
|
== ::
|
||||||
$: %gall ::
|
$: %gall ::
|
||||||
$> $? %onto ::
|
$>(%unto gift:gall) ::
|
||||||
%unto ::
|
== ::
|
||||||
== ::
|
|
||||||
gift:gall ::
|
|
||||||
==
|
|
||||||
== ::
|
== ::
|
||||||
-- ::
|
-- ::
|
||||||
:: ::::
|
:: ::::
|
||||||
@ -462,12 +459,12 @@
|
|||||||
:: [%vega ~]
|
:: [%vega ~]
|
||||||
::
|
::
|
||||||
%vega
|
%vega
|
||||||
+>.$::
|
+>.$
|
||||||
|
::
|
||||||
:: in response to memory pressure
|
:: in response to memory pressure
|
||||||
:: [%trim p=@ud]
|
:: [%trim p=@ud]
|
||||||
::
|
::
|
||||||
%trim
|
%trim
|
||||||
::TODO consider %ruin-ing long-offline comets
|
|
||||||
+>.$
|
+>.$
|
||||||
::
|
::
|
||||||
:: watch private keys
|
:: watch private keys
|
||||||
@ -507,7 +504,7 @@
|
|||||||
%ruin
|
%ruin
|
||||||
::NOTE we blast this out to _all_ known ducts, because the common
|
::NOTE we blast this out to _all_ known ducts, because the common
|
||||||
:: use case for this is comets, about who nobody cares.
|
:: use case for this is comets, about who nobody cares.
|
||||||
=/ dus ~(key by yen.zim.pki)
|
=/ dus (~(uni in nel.zim.pki) ~(key by yen.zim.pki))
|
||||||
=/ sus ~(. su hen now pki etn)
|
=/ sus ~(. su hen now pki etn)
|
||||||
=/ sis ~(tap in ships.tac)
|
=/ sis ~(tap in ships.tac)
|
||||||
|-
|
|-
|
||||||
@ -550,10 +547,6 @@
|
|||||||
=/ ships (~(get ju ship-sources-reverse.etn) source-id)
|
=/ ships (~(get ju ship-sources-reverse.etn) source-id)
|
||||||
%- curd =< abet
|
%- curd =< abet
|
||||||
(sources:~(feel su hen now pki etn) ships source)
|
(sources:~(feel su hen now pki etn) ships source)
|
||||||
::
|
|
||||||
[%gall %onto *]
|
|
||||||
~& [%jael-onto tea hin]
|
|
||||||
+>.$
|
|
||||||
::
|
::
|
||||||
[%gall %unto *]
|
[%gall %unto *]
|
||||||
?- +>-.hin
|
?- +>-.hin
|
||||||
@ -736,12 +729,10 @@
|
|||||||
++ subscribers-on-ship
|
++ subscribers-on-ship
|
||||||
|= =ship
|
|= =ship
|
||||||
^- (set duct)
|
^- (set duct)
|
||||||
=/ specific-subs (~(get ju ney.zim) ship)
|
:: union of general and ship-specific subs
|
||||||
=/ general-subs=(set duct)
|
::
|
||||||
?: ?=(?(%czar %king %duke) (clan:title ship))
|
%- ~(uni in nel.zim)
|
||||||
nel.zim
|
(~(get ju ney.zim) ship)
|
||||||
~
|
|
||||||
(~(uni in specific-subs) general-subs)
|
|
||||||
::
|
::
|
||||||
++ feed
|
++ feed
|
||||||
|_ :: hen: subscription source
|
|_ :: hen: subscription source
|
||||||
@ -997,7 +988,7 @@
|
|||||||
=| lex=state-2
|
=| lex=state-2
|
||||||
|= $: :: now: current time
|
|= $: :: now: current time
|
||||||
:: eny: unique entropy
|
:: eny: unique entropy
|
||||||
:: ski: namespace resolver
|
:: rof: namespace resolver
|
||||||
::
|
::
|
||||||
now=@da
|
now=@da
|
||||||
eny=@uvJ
|
eny=@uvJ
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
=> ..lull
|
=> ..lull
|
||||||
~% %zuse ..part ~
|
~% %zuse ..part ~
|
||||||
|%
|
|%
|
||||||
++ zuse %417
|
++ zuse %416
|
||||||
:: :: ::
|
:: :: ::
|
||||||
:::: :: :: (2) engines
|
:::: :: :: (2) engines
|
||||||
:: :: ::
|
:: :: ::
|
||||||
@ -3843,6 +3843,102 @@
|
|||||||
~
|
~
|
||||||
(some (~(run by lum) need))
|
(some (~(run by lum) need))
|
||||||
-- ::dejs-soft
|
-- ::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)
|
||||||
|
::
|
||||||
|
++ 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
|
||||||
|
?: =(0 a) b
|
||||||
|
?~ b ~
|
||||||
|
=+ c=(lent q.i.b)
|
||||||
|
?: =(c a) t.b
|
||||||
|
?: (gth c a)
|
||||||
|
[[p.i.b (^slag a q.i.b)] t.b]
|
||||||
|
$(a (sub a c), b t.b)
|
||||||
|
::
|
||||||
|
++ scag :: scag stub
|
||||||
|
|= [a=@ b=stub]
|
||||||
|
^- stub
|
||||||
|
?: =(0 a) ~
|
||||||
|
?~ b ~
|
||||||
|
=+ c=(lent q.i.b)
|
||||||
|
?: (gth c a)
|
||||||
|
[p.i.b (^scag a q.i.b)]~
|
||||||
|
:- i.b
|
||||||
|
$(a (sub a c), b t.b)
|
||||||
|
::
|
||||||
|
++ 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)
|
||||||
|
?: (lte b e) ~
|
||||||
|
[*stye (reap (sub b e) d)]~
|
||||||
|
::
|
||||||
|
c
|
||||||
|
(slag (add b (lent-char c)) a)
|
||||||
|
==
|
||||||
|
-- :: klr
|
||||||
--
|
--
|
||||||
:: |cloy: clay helpers
|
:: |cloy: clay helpers
|
||||||
::
|
::
|
||||||
@ -4928,7 +5024,7 @@
|
|||||||
=< q.q %- need %- need
|
=< q.q %- need %- need
|
||||||
(rof ~ %j `beam`[[our %sein %da now] /(scot %p who)])
|
(rof ~ %j `beam`[[our %sein %da now] /(scot %p who)])
|
||||||
--
|
--
|
||||||
:: middle core: for userspace use, with .^
|
:: middle core: stateless queries for default numeric sponsorship
|
||||||
::
|
::
|
||||||
=> |%
|
=> |%
|
||||||
:: :: ++clan:title
|
:: :: ++clan:title
|
||||||
@ -4968,7 +5064,7 @@
|
|||||||
%pawn (end 4 who)
|
%pawn (end 4 who)
|
||||||
==
|
==
|
||||||
--
|
--
|
||||||
:: surface core: stateless queries for default numeric sponsorship
|
:: surface core: for userspace use, with .^
|
||||||
::
|
::
|
||||||
|%
|
|%
|
||||||
:: :: ++cite:title
|
:: :: ++cite:title
|
||||||
@ -5003,13 +5099,25 @@
|
|||||||
%j
|
%j
|
||||||
/(scot %p our)/sein/(scot %da now)/(scot %p who)
|
/(scot %p our)/sein/(scot %da now)/(scot %p who)
|
||||||
==
|
==
|
||||||
|
:: +team was created with two meanings:
|
||||||
|
:: A. her / her moon
|
||||||
|
:: B. whoever should be able to control her ship
|
||||||
|
::
|
||||||
|
:: these two things aren't obviously equal anymore,
|
||||||
|
:: and it's more important for +team to satisfy B than A,
|
||||||
|
:: so now +team just means "her".
|
||||||
|
::
|
||||||
|
:: (ships can definitely be trusted to control themselves)
|
||||||
:: :: ++team:title
|
:: :: ++team:title
|
||||||
++ team :: our / our moon
|
++ team :: her
|
||||||
|= [our=ship who=ship]
|
|= [her=ship who=ship]
|
||||||
^- ?
|
^- ?
|
||||||
?| =(our who)
|
=(her who)
|
||||||
&(?=(%earl (clan who)) =(our (^sein who)))
|
:: :: ++moon:title
|
||||||
==
|
++ moon :: her moon
|
||||||
|
|= [her=ship who=ship]
|
||||||
|
^- ?
|
||||||
|
&(=(%earl (clan who)) =(her (^sein who)))
|
||||||
-- ::title
|
-- ::title
|
||||||
:: ::
|
:: ::
|
||||||
:::: ++milly :: (2k) milliseconds
|
:::: ++milly :: (2k) milliseconds
|
||||||
|
@ -17,15 +17,16 @@
|
|||||||
%+ roll blits
|
%+ roll blits
|
||||||
|= [b=blit:dill line=tape]
|
|= [b=blit:dill line=tape]
|
||||||
?- -.b
|
?- -.b
|
||||||
%lin (tape p.b)
|
%put (tape p.b)
|
||||||
%klr (tape (zing (turn p.b tail)))
|
%klr (tape (zing (turn p.b tail)))
|
||||||
%mor ~& "{<who>}: {line}" ""
|
%nel ~& "{<who>}: {line}" ""
|
||||||
%hop line
|
%hop line
|
||||||
%bel line
|
%bel line
|
||||||
%clr ""
|
%clr ""
|
||||||
%sag ~& [%save-jamfile-to p.b] line
|
%sag ~& [%save-jamfile-to p.b] line
|
||||||
%sav ~& [%save-file-to p.b] line
|
%sav ~& [%save-file-to p.b] line
|
||||||
%url ~& [%activate-url p.b] line
|
%url ~& [%activate-url p.b] line
|
||||||
|
%wyp ""
|
||||||
==
|
==
|
||||||
~? !=(~ last-line) last-line
|
~? !=(~ last-line) last-line
|
||||||
~
|
~
|
||||||
|
@ -143,6 +143,7 @@
|
|||||||
|= a=@
|
|= a=@
|
||||||
^- hexb
|
^- hexb
|
||||||
=/ l=@ (met 3 a)
|
=/ l=@ (met 3 a)
|
||||||
|
?: =(l 0) 1^a
|
||||||
?: =(l 1) 1^a
|
?: =(l 1) 1^a
|
||||||
?: =(l 2) (cat:byt ~[1^0xfd (flip:byt 2^a)])
|
?: =(l 2) (cat:byt ~[1^0xfd (flip:byt 2^a)])
|
||||||
?: (lte l 4) (cat:byt ~[1^0xfe (flip:byt 4^a)])
|
?: (lte l 4) (cat:byt ~[1^0xfe (flip:byt 4^a)])
|
||||||
@ -162,7 +163,7 @@
|
|||||||
%0xfe 2
|
%0xfe 2
|
||||||
%0xff 3
|
%0xff 3
|
||||||
==
|
==
|
||||||
:_ (drop:byt (add 1 len) h)
|
:_ (drop:byt (add 1 (bex len)) h)
|
||||||
%- flip:byt
|
%- flip:byt
|
||||||
(take:byt (bex len) (drop:byt 1 h))
|
(take:byt (bex len) (drop:byt 1 h))
|
||||||
:: +dea: atom instead of hexb for parsed CompactSize
|
:: +dea: atom instead of hexb for parsed CompactSize
|
||||||
|
94
pkg/base-dev/lib/dill.hoon
Normal file
94
pkg/base-dev/lib/dill.hoon
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
:: 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 'x'^(numb x.p.blit) 'y'^(numb y.p.blit) ~)
|
||||||
|
%put a+(turn p.blit |=(c=@c s+(tuft c)))
|
||||||
|
%nel b+&
|
||||||
|
%url s+p.blit
|
||||||
|
%wyp b+&
|
||||||
|
%mor a+(turn p.blit ^blit)
|
||||||
|
::
|
||||||
|
%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 'x'^ni 'y'^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)
|
||||||
|
--
|
||||||
|
--
|
||||||
|
--
|
@ -3,7 +3,8 @@
|
|||||||
::
|
::
|
||||||
=/ debug |
|
=/ debug |
|
||||||
|%
|
|%
|
||||||
+* option [item]
|
++ option
|
||||||
|
|$ [item]
|
||||||
[term=cord detail=item]
|
[term=cord detail=item]
|
||||||
::
|
::
|
||||||
:: Like +rose except also produces line number
|
:: Like +rose except also produces line number
|
||||||
|
@ -28,8 +28,8 @@
|
|||||||
%+ send-events-to who
|
%+ send-events-to who
|
||||||
^- (list unix-event)
|
^- (list unix-event)
|
||||||
:~
|
:~
|
||||||
[/d/term/1 %belt %ctl `@c`%e]
|
[/d/term/1 %belt %mod %ctl `@c`%e]
|
||||||
[/d/term/1 %belt %ctl `@c`%u]
|
[/d/term/1 %belt %mod %ctl `@c`%u]
|
||||||
[/d/term/1 %belt %txt ((list @c) what)]
|
[/d/term/1 %belt %txt ((list @c) what)]
|
||||||
[/d/term/1 %belt %ret ~]
|
[/d/term/1 %belt %ret ~]
|
||||||
==
|
==
|
||||||
@ -40,7 +40,7 @@
|
|||||||
|= [who=ship what=term]
|
|= [who=ship what=term]
|
||||||
^- (list ph-event)
|
^- (list ph-event)
|
||||||
%+ send-events-to who
|
%+ send-events-to who
|
||||||
:~ [/d/term/1 %belt %ctl (,@c what)]
|
:~ [/d/term/1 %belt %mod %ctl (,@c what)]
|
||||||
==
|
==
|
||||||
::
|
::
|
||||||
:: Inject a file into a ship
|
:: Inject a file into a ship
|
||||||
@ -67,7 +67,7 @@
|
|||||||
::
|
::
|
||||||
%+ lien p.q.uf
|
%+ lien p.q.uf
|
||||||
|= =blit:dill
|
|= =blit:dill
|
||||||
?. ?=(%lin -.blit)
|
?. ?=(%put -.blit)
|
||||||
|
|
|
|
||||||
!=(~ (find what p.blit))
|
!=(~ (find what p.blit))
|
||||||
==
|
==
|
||||||
|
@ -13,15 +13,15 @@
|
|||||||
/- *sole
|
/- *sole
|
||||||
/+ sole, auto=language-server-complete
|
/+ sole, auto=language-server-complete
|
||||||
|%
|
|%
|
||||||
+$ state-0
|
+$ state-1
|
||||||
$: %0
|
$: %1
|
||||||
soles=(map @ta sole-share)
|
soles=(map sole-id sole-share)
|
||||||
==
|
==
|
||||||
:: $card: standard gall cards plus shoe effects
|
:: $card: standard gall cards plus shoe effects
|
||||||
::
|
::
|
||||||
+$ card
|
+$ card
|
||||||
$% card:agent:gall
|
$% card:agent:gall
|
||||||
[%shoe sole-ids=(list @ta) effect=shoe-effect] :: ~ sends to all soles
|
[%shoe sole-ids=(list sole-id) effect=shoe-effect] :: ~ sends to all
|
||||||
==
|
==
|
||||||
:: $shoe-effect: easier sole-effects
|
:: $shoe-effect: easier sole-effects
|
||||||
::
|
::
|
||||||
@ -47,30 +47,30 @@
|
|||||||
:: if the head of the result is true, instantly run the command
|
:: if the head of the result is true, instantly run the command
|
||||||
::
|
::
|
||||||
++ command-parser
|
++ command-parser
|
||||||
|~ sole-id=@ta
|
|~ =sole-id
|
||||||
|~(nail *(like [? command-type]))
|
|~(nail *(like [? command-type]))
|
||||||
:: +tab-list: autocomplete options for the session (to match +command-parser)
|
:: +tab-list: autocomplete options for the session (to match +command-parser)
|
||||||
::
|
::
|
||||||
++ tab-list
|
++ tab-list
|
||||||
|~ sole-id=@ta
|
|~ =sole-id
|
||||||
:: (list [@t tank])
|
:: (list [@t tank])
|
||||||
*(list (option:auto tank))
|
*(list (option:auto tank))
|
||||||
:: +on-command: called when a valid command is run
|
:: +on-command: called when a valid command is run
|
||||||
::
|
::
|
||||||
++ on-command
|
++ on-command
|
||||||
|~ [sole-id=@ta command=command-type]
|
|~ [=sole-id command=command-type]
|
||||||
*(quip card _^|(..on-init))
|
*(quip card _^|(..on-init))
|
||||||
::
|
::
|
||||||
++ can-connect
|
++ can-connect
|
||||||
|~ sole-id=@ta
|
|~ =sole-id
|
||||||
*?
|
*?
|
||||||
::
|
::
|
||||||
++ on-connect
|
++ on-connect
|
||||||
|~ sole-id=@ta
|
|~ =sole-id
|
||||||
*(quip card _^|(..on-init))
|
*(quip card _^|(..on-init))
|
||||||
::
|
::
|
||||||
++ on-disconnect
|
++ on-disconnect
|
||||||
|~ sole-id=@ta
|
|~ =sole-id
|
||||||
*(quip card _^|(..on-init))
|
*(quip card _^|(..on-init))
|
||||||
::
|
::
|
||||||
::NOTE standard gall agent arms below, though they may produce %shoe cards
|
::NOTE standard gall agent arms below, though they may produce %shoe cards
|
||||||
@ -119,27 +119,27 @@
|
|||||||
|* [shoe=* command-type=mold]
|
|* [shoe=* command-type=mold]
|
||||||
|_ =bowl:gall
|
|_ =bowl:gall
|
||||||
++ command-parser
|
++ command-parser
|
||||||
|= sole-id=@ta
|
|= =sole-id
|
||||||
(easy *[? command-type])
|
(easy *[? command-type])
|
||||||
::
|
::
|
||||||
++ tab-list
|
++ tab-list
|
||||||
|= sole-id=@ta
|
|= =sole-id
|
||||||
~
|
~
|
||||||
::
|
::
|
||||||
++ on-command
|
++ on-command
|
||||||
|= [sole-id=@ta command=command-type]
|
|= [=sole-id command=command-type]
|
||||||
[~ shoe]
|
[~ shoe]
|
||||||
::
|
::
|
||||||
++ can-connect
|
++ can-connect
|
||||||
|= sole-id=@ta
|
|= =sole-id
|
||||||
(team:title [our src]:bowl)
|
(team:title [our src]:bowl)
|
||||||
::
|
::
|
||||||
++ on-connect
|
++ on-connect
|
||||||
|= sole-id=@ta
|
|= =sole-id
|
||||||
[~ shoe]
|
[~ shoe]
|
||||||
::
|
::
|
||||||
++ on-disconnect
|
++ on-disconnect
|
||||||
|= sole-id=@ta
|
|= =sole-id
|
||||||
[~ shoe]
|
[~ shoe]
|
||||||
--
|
--
|
||||||
:: +agent: creates wrapper core that handles sole events and calls shoe arms
|
:: +agent: creates wrapper core that handles sole events and calls shoe arms
|
||||||
@ -147,7 +147,7 @@
|
|||||||
++ agent
|
++ agent
|
||||||
|* command-type=mold
|
|* command-type=mold
|
||||||
|= =(shoe command-type)
|
|= =(shoe command-type)
|
||||||
=| state-0
|
=| state-1
|
||||||
=* state -
|
=* state -
|
||||||
^- agent:gall
|
^- agent:gall
|
||||||
=>
|
=>
|
||||||
@ -164,8 +164,7 @@
|
|||||||
%+ turn
|
%+ turn
|
||||||
?^ sole-ids.card sole-ids.card
|
?^ sole-ids.card sole-ids.card
|
||||||
~(tap in ~(key by soles))
|
~(tap in ~(key by soles))
|
||||||
|= sole-id=@ta
|
id-to-path:sole
|
||||||
/sole/[sole-id]
|
|
||||||
::
|
::
|
||||||
%table
|
%table
|
||||||
=; fez=(list sole-effect)
|
=; fez=(list sole-effect)
|
||||||
@ -202,9 +201,36 @@
|
|||||||
?. ?=([%shoe-app ^] q.old-state)
|
?. ?=([%shoe-app ^] q.old-state)
|
||||||
=^ cards shoe (on-load:og old-state)
|
=^ cards shoe (on-load:og old-state)
|
||||||
[(deal cards) this]
|
[(deal cards) this]
|
||||||
=^ old-inner state +:!<([%shoe-app vase state-0] old-state)
|
|^ =| old-outer=state-any
|
||||||
=^ cards shoe (on-load:og old-inner)
|
=^ old-inner old-outer
|
||||||
[(deal cards) this]
|
+:!<([%shoe-app vase state-any] old-state)
|
||||||
|
:: ~! q.old-state
|
||||||
|
:: ?+ +>.q.old-state !!
|
||||||
|
:: [%0 *] +:!<([%shoe-app vase state-0] old-state)
|
||||||
|
:: [%1 *] +:!<([%shoe-app vase state-1] old-state)
|
||||||
|
:: ==
|
||||||
|
=^ caz shoe (on-load:og old-inner)
|
||||||
|
=^ cuz old-outer
|
||||||
|
?. ?=(%0 -.old-outer) [~ old-outer]
|
||||||
|
(state-0-to-1 old-outer)
|
||||||
|
?> ?=(%1 -.old-outer)
|
||||||
|
[(weld cuz (deal caz)) this(state old-outer)]
|
||||||
|
::
|
||||||
|
+$ state-any $%(state-1 state-0)
|
||||||
|
+$ state-0 [%0 soles=(map @ta sole-share)]
|
||||||
|
++ state-0-to-1
|
||||||
|
|= old=state-0
|
||||||
|
^- (quip card:agent:gall state-1)
|
||||||
|
:- %+ turn ~(tap in ~(key by soles.old))
|
||||||
|
|= id=@ta
|
||||||
|
^- card:agent:gall
|
||||||
|
[%give %kick ~[/sole/[id]] ~]
|
||||||
|
:- %1
|
||||||
|
%- ~(gas by *(map sole-id sole-share))
|
||||||
|
%+ murn ~(tap by soles.old)
|
||||||
|
|= [id=@ta s=sole-share]
|
||||||
|
(bind (upgrade-id:sole id) (late s))
|
||||||
|
--
|
||||||
::
|
::
|
||||||
++ on-poke
|
++ on-poke
|
||||||
|= [=mark =vase]
|
|= [=mark =vase]
|
||||||
@ -326,19 +352,18 @@
|
|||||||
++ on-watch
|
++ on-watch
|
||||||
|= =path
|
|= =path
|
||||||
^- (quip card:agent:gall agent:gall)
|
^- (quip card:agent:gall agent:gall)
|
||||||
?. ?=([%sole @ ~] path)
|
?~ sole-id=(path-to-id:sole path)
|
||||||
=^ cards shoe
|
=^ cards shoe
|
||||||
(on-watch:og path)
|
(on-watch:og path)
|
||||||
[(deal cards) this]
|
[(deal cards) this]
|
||||||
=* sole-id i.t.path
|
?> (can-connect:og u.sole-id)
|
||||||
?> (can-connect:og sole-id)
|
=. soles (~(put by soles) u.sole-id *sole-share)
|
||||||
=. soles (~(put by soles) sole-id *sole-share)
|
|
||||||
=^ cards shoe
|
=^ cards shoe
|
||||||
(on-connect:og sole-id)
|
(on-connect:og u.sole-id)
|
||||||
:_ this
|
:_ this
|
||||||
%- deal
|
%- deal
|
||||||
:_ cards
|
:_ cards
|
||||||
[%shoe [sole-id]~ %sole %pro & dap.bowl "> "]
|
[%shoe [u.sole-id]~ %sole %pro & dap.bowl "> "]
|
||||||
::
|
::
|
||||||
++ on-leave
|
++ on-leave
|
||||||
|= =path
|
|= =path
|
||||||
|
@ -136,4 +136,28 @@
|
|||||||
=+ dat=(transmute [%mor leg] [%ins pos `@c`0])
|
=+ dat=(transmute [%mor leg] [%ins pos `@c`0])
|
||||||
?> ?=(%ins -.dat)
|
?> ?=(%ins -.dat)
|
||||||
p.dat
|
p.dat
|
||||||
|
::
|
||||||
|
::
|
||||||
|
++ path-to-id
|
||||||
|
|= =path
|
||||||
|
^- (unit sole-id)
|
||||||
|
?. ?=([%sole @ ?(~ [@ ~])] path) ~
|
||||||
|
?~ who=(slaw %p i.t.path) ~
|
||||||
|
`[u.who ?~(t.t.path %$ i.t.t.path)]
|
||||||
|
::
|
||||||
|
++ id-to-path
|
||||||
|
|= sole-id
|
||||||
|
^- path
|
||||||
|
::TODO this whole "no empty path ending" business feels icky.
|
||||||
|
:: do we want default session to be ~.~ ?
|
||||||
|
:: concern here is that outsiders cannot subscribe to the default
|
||||||
|
:: session, because /sole/~zod/ isn't a valid path...
|
||||||
|
[%sole (scot %p who) ?~(ses ~ /[ses])]
|
||||||
|
::
|
||||||
|
++ upgrade-id
|
||||||
|
|= old=@ta
|
||||||
|
^- (unit sole-id)
|
||||||
|
%+ rush old
|
||||||
|
%+ cook (late %$)
|
||||||
|
;~(pfix (jest 'drum_~') fed:ag)
|
||||||
--
|
--
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
:: belt: runtime belt structure
|
:: belt: runtime belt structure
|
||||||
::
|
::
|
||||||
|
/+ dill
|
||||||
|
::
|
||||||
|_ =belt:dill
|
|_ =belt:dill
|
||||||
++ grad %noun
|
++ grad %noun
|
||||||
:: +grab: convert from
|
:: +grab: convert from
|
||||||
@ -7,18 +9,7 @@
|
|||||||
++ grab
|
++ grab
|
||||||
|%
|
|%
|
||||||
++ noun belt:dill
|
++ noun belt:dill
|
||||||
++ json
|
++ json belt:dejs:dill
|
||||||
^- $-(^json belt:dill)
|
|
||||||
=, dejs:format
|
|
||||||
%- of
|
|
||||||
:~ aro+(su (perk %d %l %r %u ~))
|
|
||||||
bac+ul
|
|
||||||
ctl+(cu taft so)
|
|
||||||
del+ul
|
|
||||||
met+(cu taft so)
|
|
||||||
ret+ul
|
|
||||||
txt+(ar (cu taft so))
|
|
||||||
==
|
|
||||||
--
|
--
|
||||||
:: +grow: convert to
|
:: +grow: convert to
|
||||||
::
|
::
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
:: blit: runtime blit structure
|
:: blit: runtime blit structure
|
||||||
::
|
::
|
||||||
|
/+ dill
|
||||||
|
::
|
||||||
|_ =blit:dill
|
|_ =blit:dill
|
||||||
++ grad %noun
|
++ grad %noun
|
||||||
:: +grab: convert from
|
:: +grab: convert from
|
||||||
@ -13,49 +15,6 @@
|
|||||||
++ grow
|
++ grow
|
||||||
|%
|
|%
|
||||||
++ noun blit
|
++ noun blit
|
||||||
++ json
|
++ json (blit:enjs:dill blit)
|
||||||
^- ^json
|
|
||||||
=, enjs:format
|
|
||||||
%+ frond -.blit
|
|
||||||
?- -.blit
|
|
||||||
%bel b+&
|
|
||||||
%clr b+&
|
|
||||||
%hop (numb p.blit)
|
|
||||||
%lin a+(turn p.blit |=(c=@c s+(tuft c)))
|
|
||||||
%mor b+&
|
|
||||||
%url s+p.blit
|
|
||||||
::
|
|
||||||
%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)
|
|
||||||
s+(crip ((x-co:co 6) (rep 3 ~[b g r]:tint)))
|
|
||||||
--
|
|
||||||
==
|
|
||||||
==
|
|
||||||
--
|
--
|
||||||
--
|
--
|
||||||
|
@ -20,7 +20,9 @@
|
|||||||
|= jon=^json ^- sole-action
|
|= jon=^json ^- sole-action
|
||||||
%- need %. jon
|
%- need %. jon
|
||||||
=> [dejs-soft:format ..sole-action]
|
=> [dejs-soft:format ..sole-action]
|
||||||
|^ (ot id+so dat+(fo %ret (of det+change tab+ni ~)) ~)
|
|^ (ot id+id dat+(fo %ret (of det+change tab+ni ~)) ~)
|
||||||
|
++ id
|
||||||
|
(ot who+(su ;~(pfix sig fed:ag)) ses+so ~)
|
||||||
++ fo
|
++ fo
|
||||||
|* [a=term b=fist]
|
|* [a=term b=fist]
|
||||||
|=(c=json ?.(=([%s a] c) (b c) (some [a ~])))
|
|=(c=json ?.(=([%s a] c) (b c) (some [a ~])))
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
::
|
::
|
||||||
^?
|
^?
|
||||||
|%
|
|%
|
||||||
|
+$ sole-id [who=@p ses=@ta]
|
||||||
+$ sole-action :: sole to app
|
+$ sole-action :: sole to app
|
||||||
$: id=@ta :: duct id
|
$: id=sole-id :: session id
|
||||||
$= dat
|
$= dat
|
||||||
$% :: [%abo ~] :: reset interaction
|
$% :: [%abo ~] :: reset interaction
|
||||||
[%det sole-change] :: command line edit
|
[%det sole-change] :: command line edit
|
||||||
|
@ -1 +1,2 @@
|
|||||||
[%zuse 417]
|
[%zuse 417]
|
||||||
|
[%zuse 416]
|
||||||
|
@ -1 +1 @@
|
|||||||
[%zuse 417]
|
[%zuse 416]
|
||||||
|
@ -119,15 +119,25 @@ deriveNoun ''BehnEf
|
|||||||
data Blit
|
data Blit
|
||||||
= Bel ()
|
= Bel ()
|
||||||
| Clr ()
|
| Clr ()
|
||||||
| Hop Word64
|
| Hop HopTarget
|
||||||
| Klr Stub
|
| Klr Stub
|
||||||
| Lin [Char]
|
| Put [Char]
|
||||||
| Mor ()
|
| Nel ()
|
||||||
| Sag Path Noun
|
| Sag Path Noun
|
||||||
| Sav Path Atom
|
| Sav Path Atom
|
||||||
| Url Cord
|
| Url Cord
|
||||||
|
| Wyp ()
|
||||||
|
--TMP backwards compatibility
|
||||||
|
| Lin [Char]
|
||||||
|
| Mor ()
|
||||||
deriving (Eq, Ord)
|
deriving (Eq, Ord)
|
||||||
|
|
||||||
|
--NOTE bottom-left-0-based coordinates
|
||||||
|
data HopTarget
|
||||||
|
= Col Word64
|
||||||
|
| Roc Word64 Word64 -- row, col
|
||||||
|
deriving (Eq, Ord, Show)
|
||||||
|
|
||||||
data Deco
|
data Deco
|
||||||
= DecoBl
|
= DecoBl
|
||||||
| DecoBr
|
| DecoBr
|
||||||
@ -205,18 +215,33 @@ instance FromNoun Tint where
|
|||||||
"w" -> pure TintW
|
"w" -> pure TintW
|
||||||
t -> fail ("invalid: " <> unpack t)
|
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
|
-- Manual instance to not save the noun/atom in Sag/Sav, because these can be
|
||||||
-- megabytes and makes king hang.
|
-- megabytes and makes king hang.
|
||||||
instance Show Blit where
|
instance Show Blit where
|
||||||
show (Bel ()) = "Bel ()"
|
show (Bel ()) = "Bel ()"
|
||||||
show (Clr ()) = "Clr ()"
|
show (Clr ()) = "Clr ()"
|
||||||
show (Hop x) = "Hop " ++ (show x)
|
show (Hop t) = "Hop " ++ (show t)
|
||||||
show (Klr s) = "Klr " ++ (show s)
|
show (Klr s) = "Klr " ++ (show s)
|
||||||
show (Lin c) = "Lin " ++ (show c)
|
show (Put c) = "Put " ++ (show c)
|
||||||
show (Mor ()) = "Mor ()"
|
show (Nel ()) = "Nel ()"
|
||||||
show (Sag path _) = "Sag " ++ (show path)
|
show (Sag path _) = "Sag " ++ (show path)
|
||||||
show (Sav path _) = "Sav " ++ (show path)
|
show (Sav path _) = "Sav " ++ (show path)
|
||||||
show (Url c) = "Url " ++ (show c)
|
show (Url c) = "Url " ++ (show c)
|
||||||
|
show (Wyp ()) = "Wyp ()"
|
||||||
|
--
|
||||||
|
show (Lin c) = "Lin " ++ (show c)
|
||||||
|
show (Mor ()) = "Mor ()"
|
||||||
|
|
||||||
{-|
|
{-|
|
||||||
%blip -- TODO
|
%blip -- TODO
|
||||||
|
@ -20,6 +20,7 @@ import Urbit.Arvo.Common (ReOrg(..), reorgThroughNoun)
|
|||||||
|
|
||||||
import qualified Crypto.Sign.Ed25519 as Ed
|
import qualified Crypto.Sign.Ed25519 as Ed
|
||||||
import qualified Data.ByteString as BS
|
import qualified Data.ByteString as BS
|
||||||
|
import qualified Data.Char as C
|
||||||
import qualified Data.ByteString.Char8 as C
|
import qualified Data.ByteString.Char8 as C
|
||||||
import qualified Network.HTTP.Types.Method as H
|
import qualified Network.HTTP.Types.Method as H
|
||||||
|
|
||||||
@ -318,19 +319,52 @@ data LegacyBootEvent
|
|||||||
| Dawn Dawn
|
| Dawn Dawn
|
||||||
deriving (Eq, Show)
|
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)
|
deriving (Eq, Ord, Show)
|
||||||
|
|
||||||
data Belt
|
data Belt
|
||||||
= Aro ArrowKey
|
= Bol Bolt
|
||||||
| Bac ()
|
| Mod Modifier Bolt
|
||||||
| Ctl Cord
|
|
||||||
| Del ()
|
|
||||||
| Met Cord
|
|
||||||
| Ret ()
|
|
||||||
| Txt Tour
|
| Txt Tour
|
||||||
deriving (Eq, Ord, Show)
|
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
|
||||||
|
C (A 7955819) _ -> fail "%key not valid bolt tag"
|
||||||
|
n -> $(deriveFromNounFunc ''Bolt) n
|
||||||
|
|
||||||
|
instance FromNoun Belt where
|
||||||
|
parseNoun = \case
|
||||||
|
C (A 7106402) _ -> fail "%bol not valid belt tag"
|
||||||
|
n -> Bol <$> parseNoun n <|> $(deriveFromNounFunc ''Belt) n
|
||||||
|
|
||||||
|
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 -> toNoun b
|
||||||
|
n -> $(deriveToNounFunc ''Belt) n
|
||||||
|
|
||||||
data TermEv
|
data TermEv
|
||||||
= TermEvBelt (UD, ()) Belt
|
= TermEvBelt (UD, ()) Belt
|
||||||
| TermEvBlew (UD, ()) Word Word
|
| TermEvBlew (UD, ()) Word Word
|
||||||
@ -341,7 +375,7 @@ data TermEv
|
|||||||
|
|
||||||
deriveNoun ''LegacyBootEvent
|
deriveNoun ''LegacyBootEvent
|
||||||
deriveNoun ''ArrowKey
|
deriveNoun ''ArrowKey
|
||||||
deriveNoun ''Belt
|
deriveNoun ''Modifier
|
||||||
deriveNoun ''TermEv
|
deriveNoun ''TermEv
|
||||||
|
|
||||||
|
|
||||||
@ -392,27 +426,23 @@ instance FromNoun Ev where
|
|||||||
-- Short Event Names -----------------------------------------------------------
|
-- Short Event Names -----------------------------------------------------------
|
||||||
|
|
||||||
{-
|
{-
|
||||||
In the case of the user hitting enter, the cause is technically a
|
In the case of user input, the cause is technically a terminal event,
|
||||||
terminal event, but we don't display any name because the cause is
|
but we don't display any name because the cause is really the user.
|
||||||
really the user.
|
|
||||||
-}
|
-}
|
||||||
getSpinnerNameForEvent :: Ev -> Maybe Text
|
getSpinnerNameForEvent :: Ev -> Maybe Text
|
||||||
getSpinnerNameForEvent = \case
|
getSpinnerNameForEvent = \case
|
||||||
EvBlip b -> case b of
|
EvBlip b -> case b of
|
||||||
BlipEvAmes _ -> Just "ames"
|
BlipEvAmes _ -> Just "ames"
|
||||||
BlipEvArvo _ -> Just "arvo"
|
BlipEvArvo _ -> Just "arvo"
|
||||||
BlipEvBehn _ -> Just "behn"
|
BlipEvBehn _ -> Just "behn"
|
||||||
BlipEvBoat _ -> Just "boat"
|
BlipEvBoat _ -> Just "boat"
|
||||||
BlipEvHttpClient _ -> Just "iris"
|
BlipEvHttpClient _ -> Just "iris"
|
||||||
BlipEvHttpServer _ -> Just "eyre"
|
BlipEvHttpServer _ -> Just "eyre"
|
||||||
BlipEvJael _ -> Just "jael"
|
BlipEvJael _ -> Just "jael"
|
||||||
BlipEvNewt _ -> Just "newt"
|
BlipEvNewt _ -> Just "newt"
|
||||||
BlipEvSync _ -> Just "clay"
|
BlipEvSync _ -> Just "clay"
|
||||||
BlipEvTerm t | isRet t -> Nothing
|
BlipEvTerm (TermEvBelt _ _) -> Nothing
|
||||||
BlipEvTerm t -> Just "term"
|
BlipEvTerm t -> Just "term"
|
||||||
where
|
|
||||||
isRet (TermEvBelt _ (Ret ())) = True
|
|
||||||
isRet _ = False
|
|
||||||
|
|
||||||
summarizeEvent :: Ev -> Text
|
summarizeEvent :: Ev -> Text
|
||||||
summarizeEvent ev =
|
summarizeEvent ev =
|
||||||
|
@ -333,7 +333,7 @@ pier (serf, log) vSlog startedSig injected = do
|
|||||||
io $ readTVarIO siteSlog >>= ($ s)
|
io $ readTVarIO siteSlog >>= ($ s)
|
||||||
logOther "serf" (display $ T.strip $ tankToText tank)
|
logOther "serf" (display $ T.strip $ tankToText tank)
|
||||||
|
|
||||||
let err = atomically . Term.trace muxed . (<> "\r\n")
|
let err = atomically . Term.trace muxed
|
||||||
(bootEvents, startDrivers) <- do
|
(bootEvents, startDrivers) <- do
|
||||||
env <- ask
|
env <- ask
|
||||||
siz <- atomically $ Term.curDemuxSize demux
|
siz <- atomically $ Term.curDemuxSize demux
|
||||||
|
@ -45,8 +45,8 @@ import qualified Urbit.Vere.Term.Render as T
|
|||||||
|
|
||||||
-- | All stateful data in the printing to stdOutput.
|
-- | All stateful data in the printing to stdOutput.
|
||||||
data LineState = LineState
|
data LineState = LineState
|
||||||
{ lsLine :: Text
|
{ lsLine :: [(Stye, [Char])]
|
||||||
, lsCurPos :: Int
|
, lsCurPos :: CurPos
|
||||||
, lsSpinTimer :: Maybe (Async ())
|
, lsSpinTimer :: Maybe (Async ())
|
||||||
, lsSpinCause :: Maybe Text
|
, lsSpinCause :: Maybe Text
|
||||||
, lsSpinFirstRender :: Bool
|
, lsSpinFirstRender :: Bool
|
||||||
@ -54,11 +54,19 @@ data LineState = LineState
|
|||||||
, lsPrevEndTime :: Wen
|
, lsPrevEndTime :: Wen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data CurPos = CurPos
|
||||||
|
{ row :: Int
|
||||||
|
, col :: Int
|
||||||
|
}
|
||||||
|
|
||||||
-- | A record used in reading data from stdInput.
|
-- | A record used in reading data from stdInput.
|
||||||
data ReadData = ReadData
|
data ReadData = ReadData
|
||||||
{ rdBuf :: Ptr Word8
|
{ rdBuf :: Ptr Word8
|
||||||
, rdEscape :: Bool
|
, rdEscape :: Bool
|
||||||
, rdBracket :: Bool
|
, rdBracket :: Bool
|
||||||
|
, rdMouse :: Bool
|
||||||
|
, rdMouseBut :: Word8
|
||||||
|
, rdMouseCol :: Word8
|
||||||
, rdUTF8 :: ByteString
|
, rdUTF8 :: ByteString
|
||||||
, rdUTF8width :: Int
|
, rdUTF8width :: Int
|
||||||
}
|
}
|
||||||
@ -165,7 +173,8 @@ leftBracket, rightBracket :: Text
|
|||||||
leftBracket = "«"
|
leftBracket = "«"
|
||||||
rightBracket = "»"
|
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_cool_us = 500000
|
||||||
_spin_warm_us = 50000
|
_spin_warm_us = 50000
|
||||||
_spin_rate_us = 250000
|
_spin_rate_us = 250000
|
||||||
@ -201,6 +210,9 @@ localClient doneSignal = fst <$> mkRAcquire start stop
|
|||||||
-- to the muxing client.
|
-- to the muxing client.
|
||||||
putTMVar tsSizeChange ts)
|
putTMVar tsSizeChange ts)
|
||||||
|
|
||||||
|
-- start mouse reporting
|
||||||
|
putStr "\x1b[?9h"
|
||||||
|
|
||||||
pWriterThread <- asyncBound
|
pWriterThread <- asyncBound
|
||||||
(writeTerminal tsWriteQueue spinnerMVar tsizeTVar)
|
(writeTerminal tsWriteQueue spinnerMVar tsizeTVar)
|
||||||
|
|
||||||
@ -217,7 +229,7 @@ localClient doneSignal = fst <$> mkRAcquire start stop
|
|||||||
|
|
||||||
tsReadQueue <- newTQueueIO
|
tsReadQueue <- newTQueueIO
|
||||||
pReaderThread <- asyncBound
|
pReaderThread <- asyncBound
|
||||||
(readTerminal tsReadQueue tsWriteQueue (bell tsWriteQueue))
|
(readTerminal tsReadQueue tsWriteQueue tsizeTVar (bell tsWriteQueue))
|
||||||
|
|
||||||
let client = Client { take = Just <$> asum
|
let client = Client { take = Just <$> asum
|
||||||
[ readTQueue tsReadQueue <&> ClientTakeBelt,
|
[ readTQueue tsReadQueue <&> ClientTakeBelt,
|
||||||
@ -238,6 +250,9 @@ localClient doneSignal = fst <$> mkRAcquire start stop
|
|||||||
-- at shutdown, just leak the file descriptor.
|
-- at shutdown, just leak the file descriptor.
|
||||||
cancel pWriterThread
|
cancel pWriterThread
|
||||||
|
|
||||||
|
-- stop mouse reporting
|
||||||
|
putStr "\x1b[?9l"
|
||||||
|
|
||||||
-- inject one final newline, as we're usually on the prompt.
|
-- inject one final newline, as we're usually on the prompt.
|
||||||
putStr "\r\n"
|
putStr "\r\n"
|
||||||
|
|
||||||
@ -266,31 +281,50 @@ localClient doneSignal = fst <$> mkRAcquire start stop
|
|||||||
|
|
||||||
-- Writes data to the terminal. Both the terminal reading, normal logging,
|
-- Writes data to the terminal. Both the terminal reading, normal logging,
|
||||||
-- and effect handling can all emit bytes which go to the terminal.
|
-- 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 :: TQueue [Term.Ev] -> TMVar () -> TVar TermSize -> RIO e ()
|
||||||
writeTerminal q spinner termSizeVar = do
|
writeTerminal q spinner termSizeVar = do
|
||||||
currentTime <- io $ now
|
currentTime <- io $ now
|
||||||
loop (LineState "" 0 Nothing Nothing True 0 currentTime)
|
loop
|
||||||
|
termSizeVar
|
||||||
|
(LineState [] (CurPos 0 0) Nothing Nothing True 0 currentTime)
|
||||||
where
|
where
|
||||||
writeBlank :: LineState -> RIO e LineState
|
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) $ pure ()
|
||||||
|
pure ls
|
||||||
|
|
||||||
writeTrace :: LineState -> Text -> RIO e LineState
|
writeTrace :: LineState -> Text -> RIO e LineState
|
||||||
writeTrace ls p = do
|
writeTrace ls p = do
|
||||||
putStr "\r"
|
TermSize _ height <- readTVarIO termSizeVar
|
||||||
T.clearLine
|
T.hijack (fromIntegral height) $ putStr p
|
||||||
putStr p
|
pure ls
|
||||||
termRefreshLine ls
|
|
||||||
|
|
||||||
writeSlog :: LineState -> (Atom, Tank) -> RIO e LineState
|
writeSlog :: LineState -> (Atom, Tank) -> RIO e LineState
|
||||||
writeSlog ls slog = do
|
writeSlog ls slog = do
|
||||||
putStr "\r"
|
TermSize width height <- readTVarIO termSizeVar
|
||||||
T.clearLine
|
T.hijack (fromIntegral height) do
|
||||||
TermSize width _ <- atomically $ readTVar termSizeVar
|
let lines = fmap (pref . unTape) $
|
||||||
-- TODO: Ignoring priority for now. Priority changes the color of,
|
wash (WashCfg 0 width) $ tankTree $ snd slog
|
||||||
-- and adds a prefix of '>' to, the output.
|
T.putCsi 'm' styl
|
||||||
let lines = fmap unTape $ wash (WashCfg 0 width) $ tankTree $ snd slog
|
forM (intersperse "\n" lines) $ \line -> putStr line
|
||||||
forM lines $ \line -> putStr (line <> "\r\n")
|
T.putCsi 'm' [0]
|
||||||
termRefreshLine ls
|
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
|
Figure out how long to wait to show the spinner. When we
|
||||||
@ -305,7 +339,7 @@ localClient doneSignal = fst <$> mkRAcquire start stop
|
|||||||
|
|
||||||
current <- io $ now
|
current <- io $ now
|
||||||
delay <- pure $ case mTxt of
|
delay <- pure $ case mTxt of
|
||||||
Nothing -> 0
|
Nothing -> _spin_fast_us
|
||||||
Just _ ->
|
Just _ ->
|
||||||
if (gap current lsPrevEndTime ^. microSecs) < _spin_idle_us
|
if (gap current lsPrevEndTime ^. microSecs) < _spin_idle_us
|
||||||
then _spin_warm_us
|
then _spin_warm_us
|
||||||
@ -326,34 +360,41 @@ localClient doneSignal = fst <$> mkRAcquire start stop
|
|||||||
maybe (pure ()) cancel lsSpinTimer
|
maybe (pure ()) cancel lsSpinTimer
|
||||||
-- We do a final flush of the spinner mvar to ensure we don't
|
-- We do a final flush of the spinner mvar to ensure we don't
|
||||||
-- have a lingering signal which will redisplay the spinner after
|
-- have a lingering signal which will redisplay the spinner after
|
||||||
-- we call termRefreshLine below.
|
-- we call termRestoreLine below.
|
||||||
atomically $ tryTakeTMVar spinner
|
atomically $ tryTakeTMVar spinner
|
||||||
|
|
||||||
-- If we ever actually ran the spinner display callback, we need
|
-- If we ever actually ran the spinner display callback, we need
|
||||||
-- to force a redisplay of the command prompt.
|
-- to force a redisplay of the command prompt.
|
||||||
ls <- if not lsSpinFirstRender || True
|
if not lsSpinFirstRender
|
||||||
then termRefreshLine ls
|
then termRestoreLine ls termSizeVar
|
||||||
else pure ls
|
else pure ()
|
||||||
|
|
||||||
endTime <- io $ now
|
endTime <- io $ now
|
||||||
pure $ ls { lsSpinTimer = Nothing, lsPrevEndTime = endTime }
|
pure $ ls { lsSpinTimer = Nothing, lsPrevEndTime = endTime }
|
||||||
|
|
||||||
execEv :: LineState -> Term.Ev -> RIO e LineState
|
execEv :: LineState -> Term.Ev -> RIO e LineState
|
||||||
execEv ls = \case
|
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.Trace p -> writeTrace ls (unCord p)
|
||||||
Term.Slog s -> writeSlog ls s
|
Term.Slog s -> writeSlog ls s
|
||||||
Term.Blank -> writeBlank ls
|
Term.Blank -> writeBlank ls
|
||||||
Term.Spinr (Just txt) -> doSpin ls (unCord <$> txt)
|
Term.Spinr (Just txt) -> doSpin ls (unCord <$> txt)
|
||||||
Term.Spinr Nothing -> unspin ls
|
Term.Spinr Nothing -> unspin ls
|
||||||
|
|
||||||
-- TODO What does this do?
|
spin :: TVar TermSize -> LineState -> RIO e LineState
|
||||||
spin :: LineState -> RIO e LineState
|
spin ts ls@LineState{..} = do
|
||||||
spin ls@LineState{..} = do
|
|
||||||
let spinner = (spinners !! lsSpinFrame) ++ case lsSpinCause of
|
let spinner = (spinners !! lsSpinFrame) ++ case lsSpinCause of
|
||||||
Nothing -> ""
|
Nothing -> ""
|
||||||
Just str -> leftBracket ++ str ++ rightBracket
|
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)))
|
putStr (spinner <> pack (ANSI.cursorBackwardCode (length spinner)))
|
||||||
|
|
||||||
let newFrame = (lsSpinFrame + 1) `mod` length spinners
|
let newFrame = (lsSpinFrame + 1) `mod` length spinners
|
||||||
@ -362,28 +403,35 @@ localClient doneSignal = fst <$> mkRAcquire start stop
|
|||||||
, lsSpinFrame = newFrame
|
, lsSpinFrame = newFrame
|
||||||
}
|
}
|
||||||
|
|
||||||
loop :: LineState -> RIO e ()
|
loop :: TVar TermSize -> LineState -> RIO e ()
|
||||||
loop ls = do
|
loop ts ls = do
|
||||||
join $ atomically $ asum
|
join $ atomically $ asum
|
||||||
[ readTQueue q >>= pure . (foldM execEv ls >=> loop)
|
[ readTQueue q >>= pure . (foldM execEv ls >=> loop ts)
|
||||||
, takeTMVar spinner >> pure (spin ls >>= loop)
|
, takeTMVar spinner >> pure (spin ts ls >>= loop ts)
|
||||||
]
|
]
|
||||||
|
|
||||||
-- Writes an individual blit to the screen
|
-- Writes an individual blit to the screen
|
||||||
writeBlit :: LineState -> Blit -> RIO e LineState
|
writeBlit :: TVar TermSize -> LineState -> Blit -> RIO e LineState
|
||||||
writeBlit ls = \case
|
writeBlit ts ls = \case
|
||||||
Bel () -> T.soundBell $> ls
|
Bel () -> T.soundBell $> ls
|
||||||
Clr () -> do T.clearScreen
|
Clr () -> do T.clearScreen
|
||||||
termRefreshLine ls
|
T.cursorRestore
|
||||||
Hop w -> termShowCursor ls (fromIntegral w)
|
pure ls
|
||||||
Klr s -> do ls2 <- termShowClear ls
|
Hop t -> case t of
|
||||||
termShowStub ls2 s
|
Col c -> termShowCursor ls ts 0 (fromIntegral c)
|
||||||
Lin c -> do ls2 <- termShowClear ls
|
Roc r c -> termShowCursor ls ts (fromIntegral r) (fromIntegral c)
|
||||||
termShowLine ls2 (pack c)
|
Klr s -> termShowStub ls s
|
||||||
Mor () -> termShowMore ls
|
Put c -> termShowLine ls (pack c)
|
||||||
|
Nel () -> termShowNewline ls
|
||||||
Sag path noun -> pure ls
|
Sag path noun -> pure ls
|
||||||
Sav path atom -> pure ls
|
Sav path atom -> pure ls
|
||||||
Url url -> 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 :: Deco -> Char
|
||||||
termRenderDeco = \case
|
termRenderDeco = \case
|
||||||
@ -428,55 +476,88 @@ localClient doneSignal = fst <$> mkRAcquire start stop
|
|||||||
|
|
||||||
styled = mconcat [escape, styles, "m", tape, escape, "0m"]
|
styled = mconcat [escape, styles, "m", tape, escape, "0m"]
|
||||||
|
|
||||||
-- Displays and sets styled text as the current line
|
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 :: LineState -> Stub -> RIO e LineState
|
||||||
termShowStub ls (Stub s) = do
|
termShowStub ls@LineState{lsCurPos, lsLine} (Stub s) = do
|
||||||
let visualLength = sum $ fmap (length . snd) s
|
putStr $ pack $ mconcat $ fmap (uncurry termRenderStubSegment) s
|
||||||
let outText = pack $ mconcat $ fmap (uncurry termRenderStubSegment) s
|
T.cursorRestore
|
||||||
putStr outText
|
case row lsCurPos of
|
||||||
pure ls { lsLine = outText, lsCurPos = visualLength }
|
0 -> pure ls { lsLine = overwriteStub lsLine (col lsCurPos) s }
|
||||||
|
_ -> pure ls
|
||||||
|
|
||||||
-- Moves the cursor to the requested position
|
-- Moves the cursor to the requested position
|
||||||
termShowCursor :: LineState -> Int -> RIO e LineState
|
termShowCursor :: LineState -> TVar TermSize -> Int -> Int -> RIO e LineState
|
||||||
termShowCursor ls@LineState{..} {-line pos)-} newPos = do
|
termShowCursor ls ts row col = do
|
||||||
if newPos < lsCurPos then do
|
TermSize _ h <- readTVarIO ts
|
||||||
T.cursorLeft (lsCurPos - newPos)
|
T.cursorMove (max 0 (fromIntegral h - row - 1)) col
|
||||||
pure ls { lsCurPos = newPos }
|
T.cursorSave
|
||||||
else if newPos > lsCurPos then do
|
pure ls { lsCurPos = CurPos row col }
|
||||||
T.cursorRight (newPos - lsCurPos)
|
|
||||||
pure ls { lsCurPos = newPos }
|
|
||||||
else
|
|
||||||
pure ls
|
|
||||||
|
|
||||||
-- Moves the cursor left without any mutation of the LineState. Used only
|
|
||||||
-- in cursor spinning.
|
|
||||||
_termSpinnerMoveLeft :: Int -> RIO e ()
|
|
||||||
_termSpinnerMoveLeft = T.cursorLeft
|
|
||||||
|
|
||||||
-- Displays and sets the current line
|
-- Displays and sets the current line
|
||||||
termShowLine :: LineState -> Text -> RIO e LineState
|
termShowLine :: LineState -> Text -> RIO e LineState
|
||||||
termShowLine ls newStr = do
|
termShowLine ls@LineState{lsCurPos, lsLine} newStr = do
|
||||||
putStr newStr
|
putStr newStr
|
||||||
pure ls { lsLine = newStr, lsCurPos = (length newStr) }
|
T.cursorRestore
|
||||||
|
case row lsCurPos of
|
||||||
|
0 -> pure ls { lsLine = overwriteStub lsLine (col lsCurPos) (bareStub $ unpack newStr) }
|
||||||
|
_ -> pure ls
|
||||||
|
|
||||||
termShowClear :: LineState -> RIO e LineState
|
termShowClear :: LineState -> RIO e LineState
|
||||||
termShowClear ls = do
|
termShowClear ls@LineState{lsCurPos} = do
|
||||||
putStr "\r"
|
putStr "\r"
|
||||||
T.clearLine
|
T.clearLine
|
||||||
pure ls { lsLine = "", lsCurPos = 0 }
|
T.cursorRestore
|
||||||
|
case row lsCurPos of
|
||||||
|
0 -> pure ls { lsLine = [] }
|
||||||
|
_ -> pure ls
|
||||||
|
|
||||||
-- New Current Line
|
-- New Current Line
|
||||||
termShowMore :: LineState -> RIO e LineState
|
termShowNewline :: LineState -> RIO e LineState
|
||||||
termShowMore ls = do
|
termShowNewline ls@LineState{lsCurPos} = do
|
||||||
putStr "\r\n"
|
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
|
-- Redraw the bottom LineState, maintaining the current curpos
|
||||||
termRefreshLine :: LineState -> RIO e LineState
|
termRestoreLine :: LineState -> TVar TermSize -> RIO e ()
|
||||||
termRefreshLine ls@LineState{lsCurPos,lsLine} = do
|
termRestoreLine ls@LineState{lsLine} ts = do
|
||||||
ls <- termShowClear ls
|
TermSize _ h <- readTVarIO ts
|
||||||
ls <- termShowLine ls lsLine
|
T.cursorMove (fromIntegral h - 1) 0
|
||||||
termShowCursor ls lsCurPos
|
T.clearLine
|
||||||
|
putStr $ pack $ mconcat $ fmap (uncurry termRenderStubSegment) lsLine
|
||||||
|
T.cursorRestore
|
||||||
|
|
||||||
-- ring my bell
|
-- ring my bell
|
||||||
bell :: TQueue [Term.Ev] -> RIO e ()
|
bell :: TQueue [Term.Ev] -> RIO e ()
|
||||||
@ -491,9 +572,14 @@ localClient doneSignal = fst <$> mkRAcquire start stop
|
|||||||
-- A better way to do this would be to get some sort of epoll on stdInput,
|
-- 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?
|
-- since that's kinda closer to what libuv does?
|
||||||
readTerminal :: forall e. HasLogFunc e
|
readTerminal :: forall e. HasLogFunc e
|
||||||
=> TQueue Belt -> TQueue [Term.Ev] -> (RIO e ()) -> RIO e ()
|
=> TQueue Belt
|
||||||
readTerminal rq wq bell =
|
-> TQueue [Term.Ev]
|
||||||
rioAllocaBytes 1 $ \ buf -> loop (ReadData buf False False mempty 0)
|
-> 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
|
where
|
||||||
loop :: ReadData -> RIO e ()
|
loop :: ReadData -> RIO e ()
|
||||||
loop rd@ReadData{..} = do
|
loop rd@ReadData{..} = do
|
||||||
@ -513,26 +599,41 @@ localClient doneSignal = fst <$> mkRAcquire start stop
|
|||||||
if rdEscape then
|
if rdEscape then
|
||||||
if rdBracket then do
|
if rdBracket then do
|
||||||
case c of
|
case c of
|
||||||
'A' -> sendBelt $ Aro U
|
'A' -> sendBelt $ Bol $ Aro U
|
||||||
'B' -> sendBelt $ Aro D
|
'B' -> sendBelt $ Bol $ Aro D
|
||||||
'C' -> sendBelt $ Aro R
|
'C' -> sendBelt $ Bol $ Aro R
|
||||||
'D' -> sendBelt $ Aro L
|
'D' -> sendBelt $ Bol $ Aro L
|
||||||
|
'M' -> pure ()
|
||||||
_ -> bell
|
_ -> 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
|
else if isAsciiLower c then do
|
||||||
sendBelt $ Met $ Cord $ pack [c]
|
sendBelt $ Mod Met $ Key c
|
||||||
loop rd { rdEscape = False }
|
|
||||||
else if c == '.' then do
|
|
||||||
sendBelt $ Met $ Cord "dot"
|
|
||||||
loop rd { rdEscape = False }
|
loop rd { rdEscape = False }
|
||||||
else if w == 8 || w == 127 then do
|
else if w == 8 || w == 127 then do
|
||||||
sendBelt $ Met $ Cord "bac"
|
sendBelt $ Mod Met $ Bac ()
|
||||||
loop rd { rdEscape = False }
|
loop rd { rdEscape = False }
|
||||||
else if c == '[' || c == '0' then do
|
else if c == '[' || c == '0' then do
|
||||||
loop rd { rdBracket = True }
|
loop rd { rdBracket = True }
|
||||||
else do
|
else do
|
||||||
bell
|
bell
|
||||||
loop rd { rdEscape = False }
|
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
|
else if rdUTF8width /= 0 then do
|
||||||
-- continue reading into the utf8 accumulation buffer
|
-- continue reading into the utf8 accumulation buffer
|
||||||
rd@ReadData{..} <- pure rd { rdUTF8 = snoc rdUTF8 w }
|
rd@ReadData{..} <- pure rd { rdUTF8 = snoc rdUTF8 w }
|
||||||
@ -543,30 +644,31 @@ localClient doneSignal = fst <$> mkRAcquire start stop
|
|||||||
error "empty utf8 accumulation buffer"
|
error "empty utf8 accumulation buffer"
|
||||||
Just (c, bytes) | bytes /= rdUTF8width ->
|
Just (c, bytes) | bytes /= rdUTF8width ->
|
||||||
error "utf8 character size mismatch?!"
|
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 }
|
loop rd { rdUTF8 = mempty, rdUTF8width = 0 }
|
||||||
else if w >= 32 && w < 127 then do
|
else if w >= 32 && w < 127 then do
|
||||||
sendBelt $ Txt $ Tour $ [c]
|
sendBelt $ Bol $ Key c
|
||||||
loop rd
|
loop rd
|
||||||
else if w == 0 then do
|
else if w == 0 then do
|
||||||
bell
|
bell
|
||||||
loop rd
|
loop rd
|
||||||
else if w == 8 || w == 127 then do
|
else if w == 8 || w == 127 then do
|
||||||
sendBelt $ Bac ()
|
sendBelt $ Bol $ Bac ()
|
||||||
loop rd
|
loop rd
|
||||||
else if w == 13 then do
|
else if w == 13 then do
|
||||||
sendBelt $ Ret ()
|
sendBelt $ Bol $ Ret ()
|
||||||
loop rd
|
loop rd
|
||||||
else if w == 3 then do
|
else if w == 3 then do
|
||||||
-- ETX (^C)
|
-- ETX (^C)
|
||||||
logInfo $ "Ctrl-c interrupt"
|
logInfo $ "Ctrl-c interrupt"
|
||||||
atomically $ do
|
atomically $ do
|
||||||
writeTQueue wq [Term.Trace "interrupt\r\n"]
|
writeTQueue wq [Term.Trace "interrupt"]
|
||||||
writeTQueue rq $ Ctl $ Cord "c"
|
writeTQueue rq $ Mod Ctl $ Key 'c'
|
||||||
loop rd
|
loop rd
|
||||||
else if w <= 26 then do
|
else if w <= 26 then do
|
||||||
case pack [BS.w2c (w + 97 - 1)] of
|
case BS.w2c (w + 97 - 1) of
|
||||||
c -> do sendBelt $ Ctl $ Cord c
|
'd' -> atomically doneSignal
|
||||||
|
c -> do sendBelt $ Mod Ctl $ Key c
|
||||||
loop rd
|
loop rd
|
||||||
else if w == 27 then do
|
else if w == 27 then do
|
||||||
loop rd { rdEscape = True }
|
loop rd { rdEscape = True }
|
||||||
@ -643,7 +745,7 @@ term env (tsize, Client{..}) plan stat serfSIGINT = runTerm
|
|||||||
atomically take >>= \case
|
atomically take >>= \case
|
||||||
Nothing -> pure ()
|
Nothing -> pure ()
|
||||||
Just (ClientTakeBelt b) -> do
|
Just (ClientTakeBelt b) -> do
|
||||||
when (b == Ctl (Cord "c")) $ do
|
when (b == Mod Ctl (Key 'c')) $ do
|
||||||
io serfSIGINT
|
io serfSIGINT
|
||||||
let beltEv = EvBlip $ BlipEvTerm $ TermEvBelt (UD 1, ()) $ b
|
let beltEv = EvBlip $ BlipEvTerm $ TermEvBelt (UD 1, ()) $ b
|
||||||
let beltFailed _ = pure ()
|
let beltFailed _ = pure ()
|
||||||
|
@ -22,7 +22,7 @@ import Urbit.TermSize
|
|||||||
Input Event for terminal driver:
|
Input Event for terminal driver:
|
||||||
|
|
||||||
%blits -- list of blits from arvo.
|
%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
|
%slog -- nock worker logging with priority
|
||||||
%blank -- print a blank line
|
%blank -- print a blank line
|
||||||
%spinr -- Start or stop the spinner
|
%spinr -- Start or stop the spinner
|
||||||
|
@ -39,11 +39,11 @@ data Ev
|
|||||||
= EvLine Text
|
= EvLine Text
|
||||||
| EvSlog (Atom, Tank)
|
| EvSlog (Atom, Tank)
|
||||||
| EvSpin SpinnerState
|
| EvSpin SpinnerState
|
||||||
| EvMove Word
|
| EvMove (Word, Word)
|
||||||
| EvBell
|
| EvBell
|
||||||
| EvDraw
|
| EvDraw
|
||||||
| EvEdit Text
|
| EvEdit Text
|
||||||
| EvMore
|
| EvNewl
|
||||||
deriving (Show)
|
deriving (Show)
|
||||||
|
|
||||||
data Ef
|
data Ef
|
||||||
@ -62,7 +62,7 @@ data History
|
|||||||
data St = St
|
data St = St
|
||||||
{ sHistory :: !(Seq History)
|
{ sHistory :: !(Seq History)
|
||||||
, sLine :: !Text
|
, sLine :: !Text
|
||||||
, sCurPos :: !Word
|
, sCurPos :: !(Word, Word)
|
||||||
, sSpinner :: !SpinnerState
|
, sSpinner :: !SpinnerState
|
||||||
}
|
}
|
||||||
deriving (Show)
|
deriving (Show)
|
||||||
@ -70,10 +70,10 @@ data St = St
|
|||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
init :: 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
|
the current line. During normal play, the ENTER key inserts the
|
||||||
newline for us, so we need to recreate that newline when we rebuild
|
newline for us, so we need to recreate that newline when we rebuild
|
||||||
the state for a new terminal connection.
|
the state for a new terminal connection.
|
||||||
@ -83,15 +83,17 @@ step st@St{..} = \case
|
|||||||
EvLine t -> st & recordText t
|
EvLine t -> st & recordText t
|
||||||
EvSlog s -> st & recordSlog s
|
EvSlog s -> st & recordSlog s
|
||||||
EvSpin s -> st { sSpinner = s }
|
EvSpin s -> st { sSpinner = s }
|
||||||
EvMove w -> st { sCurPos = min w (word $ length sLine) }
|
EvMove p -> st { sCurPos = p }
|
||||||
EvEdit t -> st { sLine = t, sCurPos = word (length t) }
|
|
||||||
EvMore -> st { sLine = "", sCurPos = 0 } & recordText (sLine <> "\n")
|
|
||||||
EvBell -> st
|
EvBell -> st
|
||||||
EvDraw -> 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
|
where
|
||||||
word :: Integral i => i -> Word
|
|
||||||
word = fromIntegral
|
|
||||||
|
|
||||||
recordText :: Text -> St -> St
|
recordText :: Text -> St -> St
|
||||||
recordText !t st@St{..} = st {
|
recordText !t st@St{..} = st {
|
||||||
sHistory = trim (sHistory |> (HistoryText t))
|
sHistory = trim (sHistory |> (HistoryText t))
|
||||||
@ -111,8 +113,10 @@ drawState :: St -> [Ev]
|
|||||||
drawState St{..} = hist <> out <> cur <> spin
|
drawState St{..} = hist <> out <> cur <> spin
|
||||||
where
|
where
|
||||||
hist = drawHistory <$> toList sHistory
|
hist = drawHistory <$> toList sHistory
|
||||||
out = if null sLine then [] else [EvEdit sLine]
|
out | null sLine = []
|
||||||
cur = if 0 == sCurPos then [] else [EvMove $ fromIntegral $ sCurPos]
|
| otherwise = [EvEdit sLine]
|
||||||
|
cur | (0, _) <- sCurPos = []
|
||||||
|
| otherwise = [EvMove sCurPos]
|
||||||
spin = maybe [] (singleton . EvSpin . Just) sSpinner
|
spin = maybe [] (singleton . EvSpin . Just) sSpinner
|
||||||
|
|
||||||
drawHistory (HistoryText t) = EvLine t
|
drawHistory (HistoryText t) = EvLine t
|
||||||
@ -123,12 +127,13 @@ drawState St{..} = hist <> out <> cur <> spin
|
|||||||
|
|
||||||
fromBlit :: Arvo.Blit -> Maybe Ev
|
fromBlit :: Arvo.Blit -> Maybe Ev
|
||||||
fromBlit = \case
|
fromBlit = \case
|
||||||
Arvo.Hop w -> Just $ EvMove $ fromIntegral w
|
Arvo.Hop (Arvo.Col c) -> Just $ EvMove (0, fromIntegral c)
|
||||||
Arvo.Bel () -> Just EvBell
|
Arvo.Hop (Arvo.Roc r c) -> Just $ EvMove (fromIntegral r, fromIntegral c)
|
||||||
Arvo.Clr () -> Just EvDraw
|
Arvo.Bel () -> Just EvBell
|
||||||
Arvo.Lin s -> Just $ EvEdit (pack s)
|
Arvo.Clr () -> Just EvDraw
|
||||||
Arvo.Mor () -> Just EvMore
|
Arvo.Put s -> Just $ EvEdit (pack s)
|
||||||
_ -> Nothing
|
Arvo.Nel () -> Just EvNewl
|
||||||
|
_ -> Nothing
|
||||||
|
|
||||||
toCause :: Maybe Cord -> SpinnerCause
|
toCause :: Maybe Cord -> SpinnerCause
|
||||||
toCause Nothing = User
|
toCause Nothing = User
|
||||||
@ -148,12 +153,12 @@ fromTermEv = \case
|
|||||||
|
|
||||||
toTermEv :: Ev -> Term.Ev
|
toTermEv :: Ev -> Term.Ev
|
||||||
toTermEv = \case
|
toTermEv = \case
|
||||||
EvLine "" -> Term.Blank
|
EvLine "" -> Term.Blank
|
||||||
EvLine t -> Term.Trace (Cord t)
|
EvLine t -> Term.Trace (Cord t)
|
||||||
EvSlog s -> Term.Slog s
|
EvSlog s -> Term.Slog s
|
||||||
EvSpin s -> Term.Spinr (fromCause <$> s)
|
EvSpin s -> Term.Spinr (fromCause <$> s)
|
||||||
EvMove w -> Term.Blits [Arvo.Hop $ fromIntegral w]
|
EvMove (r, c) -> Term.Blits [Arvo.Hop $ Arvo.Roc (fromIntegral r) (fromIntegral c)]
|
||||||
EvBell -> Term.Blits [Arvo.Bel ()]
|
EvBell -> Term.Blits [Arvo.Bel ()]
|
||||||
EvDraw -> Term.Blits [Arvo.Clr ()]
|
EvDraw -> Term.Blits [Arvo.Clr ()]
|
||||||
EvEdit t -> Term.Blits [Arvo.Lin $ unpack t]
|
EvEdit t -> Term.Blits [Arvo.Put $ unpack t]
|
||||||
EvMore -> Term.Blits [Arvo.Mor ()]
|
EvNewl -> Term.Blits [Arvo.Nel ()]
|
||||||
|
@ -4,9 +4,12 @@
|
|||||||
module Urbit.Vere.Term.Render
|
module Urbit.Vere.Term.Render
|
||||||
( clearScreen
|
( clearScreen
|
||||||
, clearLine
|
, clearLine
|
||||||
, cursorRight
|
|
||||||
, cursorLeft
|
|
||||||
, soundBell
|
, soundBell
|
||||||
|
, cursorMove
|
||||||
|
, cursorSave
|
||||||
|
, cursorRestore
|
||||||
|
, putCsi
|
||||||
|
, hijack
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Urbit.Prelude
|
import Urbit.Prelude
|
||||||
@ -25,8 +28,27 @@ clearLine = liftIO $ ANSI.clearLine
|
|||||||
soundBell :: MonadIO m => m ()
|
soundBell :: MonadIO m => m ()
|
||||||
soundBell = liftIO $ putStr "\a"
|
soundBell = liftIO $ putStr "\a"
|
||||||
|
|
||||||
cursorLeft :: MonadIO m => Int -> m ()
|
--NOTE top-left-0-based coordinates
|
||||||
cursorLeft = liftIO . ANSI.cursorBackward
|
cursorMove :: MonadIO m => Int -> Int -> m ()
|
||||||
|
cursorMove r c = liftIO $ ANSI.setCursorPosition r c
|
||||||
|
|
||||||
cursorRight :: MonadIO m => Int -> m ()
|
cursorSave :: MonadIO m => m ()
|
||||||
cursorRight = liftIO . ANSI.cursorForward
|
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 -> 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
|
||||||
|
d
|
||||||
|
putCsi 'r' [] -- reset scroll region
|
||||||
|
cursorRestore -- restory cursor position
|
||||||
|
@ -158,6 +158,7 @@ a {
|
|||||||
@media all and (prefers-color-scheme: dark) {
|
@media all and (prefers-color-scheme: dark) {
|
||||||
body {
|
body {
|
||||||
background-color: #333;
|
background-color: #333;
|
||||||
|
color: white;
|
||||||
}
|
}
|
||||||
.bg-black-d {
|
.bg-black-d {
|
||||||
background-color: black;
|
background-color: black;
|
||||||
|
23
pkg/interface/webterm/.eslintrc.js
Normal file
23
pkg/interface/webterm/.eslintrc.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
module.exports = exports = {
|
||||||
|
"rules": {
|
||||||
|
"spaced-comment": 0,
|
||||||
|
},
|
||||||
|
"extends": [
|
||||||
|
"eslint:recommended",
|
||||||
|
"plugin:import/errors",
|
||||||
|
"plugin:react/recommended",
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"react": {
|
||||||
|
"version": "detect"
|
||||||
|
},
|
||||||
|
"import/resolver": {
|
||||||
|
typescript: {} // this loads <rootdir>/tsconfig.json to eslint
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"es6": true
|
||||||
|
},
|
||||||
|
"plugins": ["import", "react-hooks"]
|
||||||
|
}
|
1
pkg/interface/webterm/.nvmrc
Normal file
1
pkg/interface/webterm/.nvmrc
Normal file
@ -0,0 +1 @@
|
|||||||
|
16.14.0
|
94
pkg/interface/webterm/App.tsx
Normal file
94
pkg/interface/webterm/App.tsx
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import React, {
|
||||||
|
useCallback, useEffect
|
||||||
|
} from 'react';
|
||||||
|
|
||||||
|
import useTermState from './state';
|
||||||
|
import { useDark } from './lib/useDark';
|
||||||
|
import api from './api';
|
||||||
|
|
||||||
|
import { _dark, _light } from '@tlon/indigo-react';
|
||||||
|
|
||||||
|
import 'xterm/css/xterm.css';
|
||||||
|
|
||||||
|
import {
|
||||||
|
scrySessions
|
||||||
|
} from '@urbit/api/term';
|
||||||
|
|
||||||
|
import { ThemeProvider } from 'styled-components';
|
||||||
|
import { Tabs } from './Tabs';
|
||||||
|
import Buffer from './Buffer';
|
||||||
|
import { DEFAULT_SESSION } from './constants';
|
||||||
|
import { showSlog } from './lib/blit';
|
||||||
|
import { InfoButton } from './InfoButton';
|
||||||
|
|
||||||
|
const initSessions = async () => {
|
||||||
|
const response = await api.scry(scrySessions());
|
||||||
|
|
||||||
|
useTermState.getState().set((state) => {
|
||||||
|
state.names = response.sort();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function TermApp() {
|
||||||
|
const { names, selected } = useTermState();
|
||||||
|
const dark = useDark();
|
||||||
|
|
||||||
|
const setupSlog = useCallback(() => {
|
||||||
|
console.log('slog: setting up...');
|
||||||
|
let available = false;
|
||||||
|
const slog = new EventSource('/~_~/slog', { withCredentials: true });
|
||||||
|
|
||||||
|
slog.onopen = () => {
|
||||||
|
console.log('slog: opened stream');
|
||||||
|
available = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
slog.onmessage = (e) => {
|
||||||
|
const session = useTermState.getState().sessions[DEFAULT_SESSION];
|
||||||
|
if (!session) {
|
||||||
|
console.log('slog: default session mia!', 'msg:', e.data);
|
||||||
|
console.log(Object.keys(useTermState.getState().sessions), session);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
showSlog(session.term, 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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useTermState.getState().set((state) => {
|
||||||
|
state.slogstream = slog;
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
initSessions();
|
||||||
|
setupSlog();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ThemeProvider theme={dark ? _dark : _light}>
|
||||||
|
<div className="header">
|
||||||
|
<Tabs />
|
||||||
|
<InfoButton />
|
||||||
|
</div>
|
||||||
|
<div className="buffer-container">
|
||||||
|
{names.map((name) => {
|
||||||
|
return <Buffer key={name} name={name} selected={name === selected} dark={dark} />;
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</ThemeProvider>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
350
pkg/interface/webterm/Buffer.tsx
Normal file
350
pkg/interface/webterm/Buffer.tsx
Normal file
@ -0,0 +1,350 @@
|
|||||||
|
import { Terminal, ITerminalOptions } from 'xterm';
|
||||||
|
import { FitAddon } from 'xterm-addon-fit';
|
||||||
|
import { debounce } from 'lodash';
|
||||||
|
import bel from './lib/bel';
|
||||||
|
import api from './api';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Belt, pokeTask, pokeBelt
|
||||||
|
} from '@urbit/api/term';
|
||||||
|
import { Session } from './state';
|
||||||
|
import { useCallback, useEffect, useRef } from 'react';
|
||||||
|
import useTermState from './state';
|
||||||
|
import React from 'react';
|
||||||
|
import { Box, Col } from '@tlon/indigo-react';
|
||||||
|
import { makeTheme } from './lib/theme';
|
||||||
|
import { showBlit, csi, hasBell } from './lib/blit';
|
||||||
|
import { DEFAULT_SESSION, RESIZE_DEBOUNCE_MS, RESIZE_THRESHOLD_PX } from './constants';
|
||||||
|
import { retry } from './lib/retry';
|
||||||
|
|
||||||
|
const termConfig: ITerminalOptions = {
|
||||||
|
logLevel: 'warn',
|
||||||
|
//
|
||||||
|
convertEol: true,
|
||||||
|
//
|
||||||
|
rows: 24,
|
||||||
|
cols: 80,
|
||||||
|
scrollback: 10000,
|
||||||
|
//
|
||||||
|
fontFamily: '"Source Code Pro", "Roboto mono", "Courier New", monospace',
|
||||||
|
fontWeight: 400,
|
||||||
|
// NOTE theme colors configured dynamically
|
||||||
|
//
|
||||||
|
bellStyle: 'sound',
|
||||||
|
bellSound: bel,
|
||||||
|
//
|
||||||
|
// allows text selection by holding modifier (option, or shift)
|
||||||
|
macOptionClickForcesSelection: true,
|
||||||
|
// prevent insertion of simulated arrow keys on-altclick
|
||||||
|
altClickMovesCursor: false
|
||||||
|
};
|
||||||
|
|
||||||
|
const readInput = (term: Terminal, e: string): Belt[] => {
|
||||||
|
const 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); //TODO revisit wrt (list @c) & unicode characters
|
||||||
|
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) {
|
||||||
|
const k = String.fromCharCode(96 + c);
|
||||||
|
//NOTE prevent remote shut-downs
|
||||||
|
if ('d' !== k) {
|
||||||
|
belts.push({ mod: { mod: 'ctl', key: k } });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
/* eslint-disable max-statements-per-line */
|
||||||
|
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: { y: r - 1, x: 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) {
|
||||||
|
if (1 === strap.length) {
|
||||||
|
belts.push(strap);
|
||||||
|
} else {
|
||||||
|
belts.push({ txt: strap.split('') });
|
||||||
|
}
|
||||||
|
strap = '';
|
||||||
|
}
|
||||||
|
return belts;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onResize = async (name: string, session: Session) => {
|
||||||
|
if (session) {
|
||||||
|
session.fit.fit();
|
||||||
|
useTermState.getState().set((state) => {
|
||||||
|
state.sessions[name].pending++;
|
||||||
|
});
|
||||||
|
api.poke(pokeTask(name, { blew: { w: session.term.cols, h: session.term.rows } })).then(() => {
|
||||||
|
useTermState.getState().set((state) => {
|
||||||
|
state.sessions[name].pending--;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onInput = (name: string, session: Session, e: string) => {
|
||||||
|
if (!session) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const term = session.term;
|
||||||
|
const belts = readInput(term, e);
|
||||||
|
belts.forEach((b) => {
|
||||||
|
useTermState.getState().set((state) => {
|
||||||
|
state.sessions[name].pending++;
|
||||||
|
});
|
||||||
|
api.poke(pokeBelt(name, b)).then(() => {
|
||||||
|
useTermState.getState().set((state) => {
|
||||||
|
state.sessions[name].pending--;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
interface BufferProps {
|
||||||
|
name: string,
|
||||||
|
selected: boolean,
|
||||||
|
dark: boolean,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Buffer({ name, selected, dark }: BufferProps) {
|
||||||
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
|
||||||
|
const session: Session = useTermState(s => s.sessions[name]);
|
||||||
|
|
||||||
|
const initSession = useCallback(async (name: string, dark: boolean) => {
|
||||||
|
console.log('setting up', name === DEFAULT_SESSION ? 'default' : name);
|
||||||
|
|
||||||
|
// set up xterm terminal
|
||||||
|
//
|
||||||
|
const term = new Terminal(termConfig);
|
||||||
|
term.options.theme = makeTheme(dark);
|
||||||
|
const fit = new FitAddon();
|
||||||
|
term.loadAddon(fit);
|
||||||
|
fit.fit();
|
||||||
|
term.focus();
|
||||||
|
|
||||||
|
// start mouse reporting
|
||||||
|
//
|
||||||
|
term.write(csi('?9h'));
|
||||||
|
|
||||||
|
const ses: Session = {
|
||||||
|
term,
|
||||||
|
fit,
|
||||||
|
hasBell: false,
|
||||||
|
pending: 0,
|
||||||
|
subscriptionId: null
|
||||||
|
};
|
||||||
|
|
||||||
|
// set up event handlers
|
||||||
|
//
|
||||||
|
term.attachCustomKeyEventHandler((e: KeyboardEvent) => {
|
||||||
|
//NOTE ctrl+shift keypresses never make it into term.onData somehow,
|
||||||
|
// so we handle them specially ourselves.
|
||||||
|
// we may be able to remove this once xterm.js fixes #3382 & co.
|
||||||
|
if (e.shiftKey
|
||||||
|
&& e.ctrlKey
|
||||||
|
&& e.type === 'keydown'
|
||||||
|
&& e.key.length === 1
|
||||||
|
) {
|
||||||
|
api.poke(pokeBelt(name, { mod: { mod: 'ctl', key: e.key } }));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
term.onData(e => onInput(name, ses, e));
|
||||||
|
term.onBinary(e => onInput(name, ses, e));
|
||||||
|
|
||||||
|
// open subscription
|
||||||
|
//
|
||||||
|
const initSubscription = async () => {
|
||||||
|
const subscriptionId = await api.subscribe({
|
||||||
|
app: 'herm', path: '/session/' + name + '/view',
|
||||||
|
event: (e) => {
|
||||||
|
showBlit(ses.term, e);
|
||||||
|
//NOTE getting selected from state because selected prop is stale
|
||||||
|
if (hasBell(e) && (useTermState.getState().selected !== name)) {
|
||||||
|
useTermState.getState().set((state) => {
|
||||||
|
state.sessions[name].hasBell = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//TODO should handle %bye on this higher level though, for deletion
|
||||||
|
},
|
||||||
|
err: (e, id) => {
|
||||||
|
console.log(`subscription error, id ${id}:`, e);
|
||||||
|
},
|
||||||
|
quit: async () => { // quit
|
||||||
|
console.error('quit, reconnecting...');
|
||||||
|
try {
|
||||||
|
const newSubscriptionId = await retry(initSubscription, () => {
|
||||||
|
console.log('attempting to reconnect ...');
|
||||||
|
}, 5);
|
||||||
|
useTermState.getState().set((state) => {
|
||||||
|
state.sessions[name].subscriptionId = newSubscriptionId;
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log('unable to reconnect', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return subscriptionId;
|
||||||
|
};
|
||||||
|
|
||||||
|
ses.subscriptionId = await initSubscription();
|
||||||
|
|
||||||
|
useTermState.getState().set((state) => {
|
||||||
|
state.sessions[name] = ses;
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const shouldResize = useCallback(() => {
|
||||||
|
if(!session) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const containerHeight = document.querySelector('.buffer-container')?.clientHeight || Infinity;
|
||||||
|
const terminalHeight = session.term.element?.clientHeight || 0;
|
||||||
|
|
||||||
|
return (containerHeight - terminalHeight) >= RESIZE_THRESHOLD_PX;
|
||||||
|
}, [session]);
|
||||||
|
|
||||||
|
const onSelect = useCallback(async () => {
|
||||||
|
if (session && selected && shouldResize()) {
|
||||||
|
session.fit.fit();
|
||||||
|
await api.poke(pokeTask(name, { blew: { w: session.term.cols, h: session.term.rows } }));
|
||||||
|
session.term.focus();
|
||||||
|
}
|
||||||
|
}, [session?.term, selected]);
|
||||||
|
|
||||||
|
// Effects
|
||||||
|
// init session
|
||||||
|
useEffect(() => {
|
||||||
|
if(session) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
initSession(name, dark);
|
||||||
|
}, [name]);
|
||||||
|
|
||||||
|
// attach to DOM when ref is available
|
||||||
|
useEffect(() => {
|
||||||
|
if(session && containerRef.current && !session.term.element) {
|
||||||
|
session.term.open(containerRef.current);
|
||||||
|
}
|
||||||
|
}, [session, containerRef]);
|
||||||
|
|
||||||
|
// initialize resize listeners
|
||||||
|
//
|
||||||
|
useEffect(() => {
|
||||||
|
if(!session) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: use ResizeObserver for improved performance?
|
||||||
|
const debouncedResize = debounce(() => onResize(name, session), RESIZE_DEBOUNCE_MS);
|
||||||
|
window.addEventListener('resize', debouncedResize);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('resize', debouncedResize);
|
||||||
|
};
|
||||||
|
}, [session]);
|
||||||
|
|
||||||
|
// on dark mode change, change terminals' theme
|
||||||
|
//
|
||||||
|
useEffect(() => {
|
||||||
|
const theme = makeTheme(dark);
|
||||||
|
if (session) {
|
||||||
|
session.term.options.theme = theme;
|
||||||
|
}
|
||||||
|
if (containerRef.current) {
|
||||||
|
containerRef.current.style.backgroundColor = theme.background || '';
|
||||||
|
}
|
||||||
|
}, [session, dark]);
|
||||||
|
|
||||||
|
// On select, resize, focus, and poke herm with updated cols and rows
|
||||||
|
useEffect(() => {
|
||||||
|
onSelect();
|
||||||
|
}, [onSelect]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
!session && !selected ?
|
||||||
|
<p>Loading...</p>
|
||||||
|
:
|
||||||
|
<Box
|
||||||
|
width='100%'
|
||||||
|
height='100%'
|
||||||
|
bg='white'
|
||||||
|
fontFamily='mono'
|
||||||
|
overflow='hidden'
|
||||||
|
className="terminal-container"
|
||||||
|
style={selected ? { zIndex: 999 } : {}}
|
||||||
|
>
|
||||||
|
<Col
|
||||||
|
width='100%'
|
||||||
|
height='100%'
|
||||||
|
minHeight='0'
|
||||||
|
px={['0', '2']}
|
||||||
|
pb={['0', '2']}
|
||||||
|
ref={containerRef}
|
||||||
|
>
|
||||||
|
</Col>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
24
pkg/interface/webterm/InfoButton.tsx
Normal file
24
pkg/interface/webterm/InfoButton.tsx
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import React, { useCallback } from 'react';
|
||||||
|
import { Icon } from '@tlon/indigo-react';
|
||||||
|
import { useDetectOS } from './lib/useDetectOS';
|
||||||
|
|
||||||
|
export const InfoButton = () => {
|
||||||
|
const { isMacOS } = useDetectOS();
|
||||||
|
|
||||||
|
const onInfoClick = useCallback(() => {
|
||||||
|
const key = isMacOS ? 'alt' : 'shift';
|
||||||
|
|
||||||
|
alert(`To select text in the terminal, hold down the ${key} key.`);
|
||||||
|
}, [isMacOS]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<button className="info-btn" onClick={onInfoClick}>
|
||||||
|
<Icon
|
||||||
|
icon="Info"
|
||||||
|
size="18px"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
55
pkg/interface/webterm/Spinner.tsx
Normal file
55
pkg/interface/webterm/Spinner.tsx
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import useIsMounted from './lib/useIsMounted';
|
||||||
|
import React from 'react';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
const DELAY_MS = 1000;
|
||||||
|
const FRAME_MS = 250;
|
||||||
|
const CHARS = '|/-\\';
|
||||||
|
|
||||||
|
const Spinner = () => {
|
||||||
|
const [index, setIndex] = useState(0);
|
||||||
|
const [intervalTimer, setIntervalTimer] = useState<ReturnType<typeof setInterval> | undefined>();
|
||||||
|
const isMounted = useIsMounted();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setIntervalTimer(
|
||||||
|
setInterval(() => {
|
||||||
|
if (isMounted()) {
|
||||||
|
setIndex(idx => idx === CHARS.length - 1 ? 0 : idx + 1);
|
||||||
|
}
|
||||||
|
}, FRAME_MS)
|
||||||
|
);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (intervalTimer) {
|
||||||
|
clearInterval(intervalTimer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return <span> {CHARS[index]}</span>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const DelayedSpinner = () => {
|
||||||
|
const [showSpinner, setShowSpinner] = useState(false);
|
||||||
|
const [delayTimer, setDelayTimer] = useState<ReturnType<typeof setTimeout> | undefined>();
|
||||||
|
const isMounted = useIsMounted();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setDelayTimer(
|
||||||
|
setTimeout(() => {
|
||||||
|
if (isMounted()) {
|
||||||
|
setShowSpinner(true);
|
||||||
|
}
|
||||||
|
}, DELAY_MS)
|
||||||
|
);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (delayTimer) {
|
||||||
|
clearTimeout(delayTimer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return showSpinner ? <Spinner /> : null;
|
||||||
|
};
|
55
pkg/interface/webterm/Tab.tsx
Normal file
55
pkg/interface/webterm/Tab.tsx
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import { DEFAULT_SESSION } from './constants';
|
||||||
|
import React, { useCallback, useEffect } from 'react';
|
||||||
|
import useTermState, { Session } from './state';
|
||||||
|
import api from './api';
|
||||||
|
import { pokeTask } from '@urbit/api/term';
|
||||||
|
import { DelayedSpinner as Spinner } from './Spinner';
|
||||||
|
|
||||||
|
interface TabProps {
|
||||||
|
session: Session;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Tab = ( { session, name }: TabProps ) => {
|
||||||
|
const isSelected = useTermState().selected === name;
|
||||||
|
|
||||||
|
const onClick = () => {
|
||||||
|
useTermState.getState().set((state) => {
|
||||||
|
state.selected = name;
|
||||||
|
state.sessions[name].hasBell = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDelete = useCallback(async (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
// clean up subscription
|
||||||
|
if(session && session.subscriptionId) {
|
||||||
|
await api.unsubscribe(session.subscriptionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE
|
||||||
|
await api.poke(pokeTask(name, { shut: null }));
|
||||||
|
|
||||||
|
// remove from zustand
|
||||||
|
useTermState.getState().set((state) => {
|
||||||
|
if (state.selected === name) {
|
||||||
|
state.selected = DEFAULT_SESSION;
|
||||||
|
}
|
||||||
|
state.names = state.names.filter(n => n !== name);
|
||||||
|
delete state.sessions[name];
|
||||||
|
});
|
||||||
|
}, [session]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={'tab ' + (isSelected ? 'selected' : '')} onClick={onClick}>
|
||||||
|
<a className='session-name'>
|
||||||
|
{session?.hasBell ? '🔔 ' : ''}
|
||||||
|
{name === DEFAULT_SESSION ? 'default' : name}
|
||||||
|
{session && session.pending > 0 ? <Spinner /> : null}
|
||||||
|
{' '}
|
||||||
|
</a>
|
||||||
|
{name === DEFAULT_SESSION ? null : <a className="delete-session" onClick={onDelete}>x</a>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
26
pkg/interface/webterm/Tabs.tsx
Normal file
26
pkg/interface/webterm/Tabs.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import useTermState from './state';
|
||||||
|
import { Tab } from './Tab';
|
||||||
|
import { useAddSession } from './lib/useAddSession';
|
||||||
|
import { Icon } from '@tlon/indigo-react';
|
||||||
|
|
||||||
|
export const Tabs = () => {
|
||||||
|
const { sessions, names } = useTermState();
|
||||||
|
const addSession = useAddSession();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="tabs">
|
||||||
|
{names.map((n, i) => {
|
||||||
|
return (
|
||||||
|
<Tab session={sessions[n]} name={n} key={i} />
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
<button className="tab" onClick={addSession}>
|
||||||
|
<Icon
|
||||||
|
icon="Plus"
|
||||||
|
size="18px"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -1,475 +0,0 @@
|
|||||||
/* eslint-disable max-lines */
|
|
||||||
import React, {
|
|
||||||
useEffect,
|
|
||||||
useRef,
|
|
||||||
useCallback
|
|
||||||
} from 'react';
|
|
||||||
|
|
||||||
import useTermState from './state';
|
|
||||||
import { useDark } from './join';
|
|
||||||
import api from './api';
|
|
||||||
|
|
||||||
import { Terminal, ITerminalOptions, ITheme } from 'xterm';
|
|
||||||
import { FitAddon } from 'xterm-addon-fit';
|
|
||||||
import { saveAs } from 'file-saver';
|
|
||||||
|
|
||||||
import { Box, Col, Reset, _dark, _light } from '@tlon/indigo-react';
|
|
||||||
|
|
||||||
import 'xterm/css/xterm.css';
|
|
||||||
|
|
||||||
import {
|
|
||||||
Belt, Blit, Stye, Stub, Tint, Deco,
|
|
||||||
pokeTask, pokeBelt
|
|
||||||
} from '@urbit/api/term';
|
|
||||||
|
|
||||||
import bel from './lib/bel';
|
|
||||||
import { ThemeProvider } from 'styled-components';
|
|
||||||
|
|
||||||
type TermAppProps = {
|
|
||||||
ship: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const makeTheme = (dark: boolean): ITheme => {
|
|
||||||
let fg, bg: string;
|
|
||||||
if (dark) {
|
|
||||||
fg = 'white';
|
|
||||||
bg = 'rgb(26,26,26)';
|
|
||||||
} 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,
|
|
||||||
cursorAccent: bg,
|
|
||||||
selection: fg
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const termConfig: ITerminalOptions = {
|
|
||||||
logLevel: 'warn',
|
|
||||||
//
|
|
||||||
convertEol: true,
|
|
||||||
//
|
|
||||||
rows: 24,
|
|
||||||
cols: 80,
|
|
||||||
scrollback: 10000,
|
|
||||||
//
|
|
||||||
fontFamily: '"Source Code Pro", "Roboto mono", "Courier New", monospace',
|
|
||||||
fontWeight: 400,
|
|
||||||
// NOTE theme colors configured dynamically
|
|
||||||
//
|
|
||||||
bellStyle: 'sound',
|
|
||||||
bellSound: bel,
|
|
||||||
//
|
|
||||||
// allows text selection by holding modifier (option, or shift)
|
|
||||||
macOptionClickForcesSelection: true,
|
|
||||||
// prevent insertion of simulated arrow keys on-altclick
|
|
||||||
altClickMovesCursor: false
|
|
||||||
};
|
|
||||||
|
|
||||||
const csi = (cmd: string, ...args: number[]) => {
|
|
||||||
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: number[], deco: Deco) => {
|
|
||||||
/* eslint-disable max-statements-per-line */
|
|
||||||
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';
|
|
||||||
};
|
|
||||||
|
|
||||||
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) {
|
|
||||||
//TODO remove for new backend
|
|
||||||
{
|
|
||||||
out += csi('H', term.rows, 1);
|
|
||||||
out += csi('K');
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
const name = sav.path.split('/').slice(-2).join('.');
|
|
||||||
const buff = Buffer.from(sav.file, 'base64');
|
|
||||||
const 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');
|
|
||||||
//
|
|
||||||
//TODO remove for new backend
|
|
||||||
} else if ('lin' in blit) {
|
|
||||||
out += csi('H', term.rows, 1);
|
|
||||||
out += csi('K');
|
|
||||||
out += blit.lin.join('');
|
|
||||||
} else if ('mor' in blit) {
|
|
||||||
out += '\n';
|
|
||||||
} 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[] => {
|
|
||||||
const 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) {
|
|
||||||
let k = String.fromCharCode(96 + c);
|
|
||||||
//NOTE prevent remote shut-downs
|
|
||||||
if ('d' !== k) {
|
|
||||||
belts.push({ ctl: k });
|
|
||||||
//TODO for new backend
|
|
||||||
// belts.push({ mod: { mod: 'ctl', key: k } });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
/* eslint-disable max-statements-per-line */
|
|
||||||
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;
|
|
||||||
//TODO re-enable for new backend
|
|
||||||
// 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 container = useRef<HTMLDivElement>(null);
|
|
||||||
// TODO allow switching of selected
|
|
||||||
const { sessions, selected, slogstream, set } = useTermState();
|
|
||||||
const session = sessions[selected];
|
|
||||||
const dark = useDark();
|
|
||||||
|
|
||||||
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) => {
|
|
||||||
const session = useTermState.getState().sessions[''];
|
|
||||||
if (!session) {
|
|
||||||
console.log('default session mia!', 'slog:', slog);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
showSlog(session.term, 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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
set((state) => {
|
|
||||||
state.slogstream = slog;
|
|
||||||
});
|
|
||||||
}, [sessions]);
|
|
||||||
|
|
||||||
const onInput = useCallback((ses: string, e: string) => {
|
|
||||||
const term = useTermState.getState().sessions[ses].term;
|
|
||||||
const belts = readInput(term, e);
|
|
||||||
belts.map((b) => { // NOTE passing api.poke(pokeBelt makes `this` undefined!
|
|
||||||
//TODO pokeBelt(ses, b);
|
|
||||||
api.poke({
|
|
||||||
app: 'herm',
|
|
||||||
mark: 'belt',
|
|
||||||
json: b
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}, [sessions]);
|
|
||||||
|
|
||||||
const onResize = useCallback(() => {
|
|
||||||
// TODO debounce, if it ever becomes a problem
|
|
||||||
session?.fit.fit();
|
|
||||||
}, [session]);
|
|
||||||
|
|
||||||
// on-init, open slogstream
|
|
||||||
//
|
|
||||||
useEffect(() => {
|
|
||||||
if (!slogstream) {
|
|
||||||
setupSlog();
|
|
||||||
}
|
|
||||||
window.addEventListener('resize', onResize);
|
|
||||||
return () => {
|
|
||||||
// TODO clean up subs?
|
|
||||||
window.removeEventListener('resize', onResize);
|
|
||||||
};
|
|
||||||
}, [onResize, setupSlog]);
|
|
||||||
|
|
||||||
// on dark mode change, change terminals' theme
|
|
||||||
//
|
|
||||||
useEffect(() => {
|
|
||||||
const theme = makeTheme(dark);
|
|
||||||
for (const 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 = session;
|
|
||||||
// initialize terminal
|
|
||||||
//
|
|
||||||
if (!ses) {
|
|
||||||
// set up terminal
|
|
||||||
//
|
|
||||||
const term = new Terminal(termConfig);
|
|
||||||
term.setOption('theme', makeTheme(dark));
|
|
||||||
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));
|
|
||||||
term.onResize((e) => {
|
|
||||||
//TODO re-enable once new backend lands
|
|
||||||
// api.poke(pokeTask(selected, { blew: { w: e.cols, h: e.rows } }));
|
|
||||||
});
|
|
||||||
|
|
||||||
ses = { term, fit };
|
|
||||||
|
|
||||||
// open subscription
|
|
||||||
//
|
|
||||||
api.subscribe({ app: 'herm', path: '/session/'+selected+'/view',
|
|
||||||
event: (e) => {
|
|
||||||
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);
|
|
||||||
},
|
|
||||||
quit: () => { // quit
|
|
||||||
// TODO show user a message
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (container.current && !container.current.contains(ses.term.element || null)) {
|
|
||||||
ses.term.open(container.current);
|
|
||||||
ses.fit.fit();
|
|
||||||
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, session, container]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<ThemeProvider theme={dark ? _dark : _light}>
|
|
||||||
<Reset />
|
|
||||||
<Box
|
|
||||||
width='100%'
|
|
||||||
height='100%'
|
|
||||||
bg='white'
|
|
||||||
fontFamily='mono'
|
|
||||||
overflow='hidden'
|
|
||||||
>
|
|
||||||
<Col
|
|
||||||
width='100%'
|
|
||||||
height='100%'
|
|
||||||
minHeight='0'
|
|
||||||
px={['0','2']}
|
|
||||||
pb={['0','2']}
|
|
||||||
ref={container}
|
|
||||||
>
|
|
||||||
</Col>
|
|
||||||
</Box>
|
|
||||||
</ThemeProvider>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
28
pkg/interface/webterm/constants.ts
Normal file
28
pkg/interface/webterm/constants.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
export const DEFAULT_SESSION = '';
|
||||||
|
export const DEFAULT_HANDLER = 'hood';
|
||||||
|
export const RESIZE_DEBOUNCE_MS = 100;
|
||||||
|
export const RESIZE_THRESHOLD_PX = 15;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Session ID validity:
|
||||||
|
*
|
||||||
|
* - must start with an alphabetical
|
||||||
|
* - can be composed of alphanumerics with hyphens
|
||||||
|
* - can be length 1 or longer
|
||||||
|
*/
|
||||||
|
export const SESSION_ID_REGEX = /(^[a-z]{1}[a-z\d-]*$)/;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a session with a given agent using `[agent]![session_name]`
|
||||||
|
*
|
||||||
|
* For example:
|
||||||
|
* ```
|
||||||
|
* book!my-session
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* This will create a new session in webterm for the `%book` agent.
|
||||||
|
*
|
||||||
|
* Note that the second capture group after the ! is composed of the session ID
|
||||||
|
* regex above.
|
||||||
|
*/
|
||||||
|
export const AGENT_SESSION_REGEX = /^([a-z]{1}[a-z\d-]*)!([a-z]{1}[a-z\d-]*$)/;
|
@ -23,10 +23,113 @@
|
|||||||
<link href="https://fonts.googleapis.com/css2?family=Source+Code+Pro&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Source+Code+Pro&display=swap" rel="stylesheet">
|
||||||
<style>
|
<style>
|
||||||
body, #root {
|
body, #root {
|
||||||
height: 100vh;
|
height: 99vh; /* prevent scrollbar on outer frame */
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.buffer-container {
|
||||||
|
height: calc(100% - 40px);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-container {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.header {
|
||||||
|
display: grid;
|
||||||
|
grid-template-areas: "tabs info";
|
||||||
|
grid-template-columns: auto min-content;
|
||||||
|
grid-template-rows: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.info {
|
||||||
|
grid-area: info;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.tabs {
|
||||||
|
grid-area: tabs;
|
||||||
|
height: 40px;
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row nowrap;
|
||||||
|
justify-content: flex-start;
|
||||||
|
padding: 5px 5px 0 5px;
|
||||||
|
border-bottom: 1px solid black;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.tabs > * {
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-right: 5px;
|
||||||
|
border: solid 1px black;
|
||||||
|
padding: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.tab, button.tab {
|
||||||
|
margin-bottom: -1px; /** To overlay the selected tab on the tabs container bottom border */
|
||||||
|
border-top-left-radius: 5px;
|
||||||
|
border-top-right-radius: 5px;
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.tabs > div.selected {
|
||||||
|
border-bottom: white solid 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.tabs > div.selected > a.session-name {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.tabs > a.delete-session {
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.info-btn {
|
||||||
|
border: none;
|
||||||
|
border-bottom: solid black 1px;
|
||||||
|
background: transparent;
|
||||||
|
padding: 10px;
|
||||||
|
line-height: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
html {
|
||||||
|
background-color: rgb(26,26,26);
|
||||||
|
}
|
||||||
|
|
||||||
|
div.tabs {
|
||||||
|
background-color: rgb(26, 26, 26);
|
||||||
|
color: rgba(255, 255, 255, 0.9);
|
||||||
|
border-bottom-color: rgba(255, 255, 255, 0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
div.tab {
|
||||||
|
background-color: rgb(26, 26, 26);
|
||||||
|
color: rgba(255, 255, 255, 0.9);
|
||||||
|
border-color: rgba(255, 255, 255, 0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
button.tab {
|
||||||
|
background-color: rgb(42, 42, 42);
|
||||||
|
color: rgba(255, 255, 255, 0.9);
|
||||||
|
border-color: rgba(255, 255, 255, 0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
div.tabs > div.selected {
|
||||||
|
border-bottom: rgb(26,26,26) solid 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.info-btn {
|
||||||
|
border-bottom: solid rgba(255, 255, 255, 0.9) 1px;
|
||||||
|
background: rgb(26, 26, 26);
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
129
pkg/interface/webterm/lib/blit.ts
Normal file
129
pkg/interface/webterm/lib/blit.ts
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
import { Terminal } from 'xterm';
|
||||||
|
import { saveAs } from 'file-saver';
|
||||||
|
import { Blit, Stub, Stye } from '@urbit/api/term';
|
||||||
|
import { stye } from '../lib/stye';
|
||||||
|
|
||||||
|
export const csi = (cmd: string, ...args: number[]) => {
|
||||||
|
return '\x1b[' + args.join(';') + cmd;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const showBlit = (term: Terminal, blit: Blit) => {
|
||||||
|
let out = '';
|
||||||
|
|
||||||
|
if ('mor' in blit) {
|
||||||
|
return blit.mor.map(b => showBlit(term, b));
|
||||||
|
} else 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', blit.hop.y + 1, blit.hop.x + 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;
|
||||||
|
const name = sav.path.split('/').slice(-2).join('.');
|
||||||
|
const buff = Buffer.from(sav.file, 'base64');
|
||||||
|
const 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);
|
||||||
|
};
|
||||||
|
|
||||||
|
export 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'));
|
||||||
|
};
|
||||||
|
|
||||||
|
export const hasBell = (blit: Blit) => {
|
||||||
|
if ('bel' in blit) {
|
||||||
|
return true;
|
||||||
|
} else if ('mor' in blit) {
|
||||||
|
return blit.mor.some(hasBell);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// debug rendering
|
||||||
|
//NOTE doesn't behave nicely in the presence of eob %nel blits,
|
||||||
|
// because those aren't idempotent
|
||||||
|
|
||||||
|
const blotStye: Stye = { deco: [], back: { r: 255, g: 0, b: 255 }, fore: 'k' };
|
||||||
|
const blitToBlot = (blit: Blit): Blit => {
|
||||||
|
if ('mor' in blit) {
|
||||||
|
return { mor: blit.mor.map(blitToBlot) };
|
||||||
|
} else if ('put' in blit) {
|
||||||
|
return { klr: [{ text: blit.put, stye: blotStye }] };
|
||||||
|
} else if ('klr' in blit) {
|
||||||
|
return { klr: blit.klr.map((s: Stub) => {
|
||||||
|
return { text: s.text, stye: blotStye };
|
||||||
|
}) };
|
||||||
|
} else {
|
||||||
|
return blit;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const queue: {term: Terminal, blit: Blit}[] = [];
|
||||||
|
const renderFromQueue = () => {
|
||||||
|
const next = queue.shift();
|
||||||
|
if (!next) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
showBlit(next.term, next.blit);
|
||||||
|
if (0 === queue.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setTimeout(renderFromQueue, 200);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const showBlitDebug = (term: Terminal, blit: Blit) => {
|
||||||
|
const blot = blitToBlot(blit);
|
||||||
|
if (0 === queue.length) {
|
||||||
|
showBlit(term, blot);
|
||||||
|
queue.push({ term, blit });
|
||||||
|
setTimeout(renderFromQueue, 200);
|
||||||
|
} else {
|
||||||
|
queue.push({ term, blit: blot });
|
||||||
|
queue.push({ term, blit });
|
||||||
|
}
|
||||||
|
};
|
39
pkg/interface/webterm/lib/retry.ts
Normal file
39
pkg/interface/webterm/lib/retry.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* Wait for the given milliseconds
|
||||||
|
* @param {number} milliseconds The given time to wait
|
||||||
|
* @returns {Promise} A fulfiled promise after the given time has passed
|
||||||
|
*/
|
||||||
|
function waitFor(milliseconds) {
|
||||||
|
return new Promise(resolve => setTimeout(resolve, milliseconds));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute a promise and retry with exponential backoff
|
||||||
|
* based on the maximum retry attempts it can perform
|
||||||
|
* @param {Promise} promise promise to be executed
|
||||||
|
* @param {function} onRetry callback executed on every retry
|
||||||
|
* @param {number} maxRetries The maximum number of retries to be attempted
|
||||||
|
* @returns {Promise} The result of the given promise passed in
|
||||||
|
*/
|
||||||
|
export function retry(promise, onRetry, maxRetries) {
|
||||||
|
async function retryWithBackoff(retries) {
|
||||||
|
try {
|
||||||
|
if (retries > 0) {
|
||||||
|
const timeToWait = 2 ** retries * 100;
|
||||||
|
console.log(`waiting for ${timeToWait}ms...`);
|
||||||
|
await waitFor(timeToWait);
|
||||||
|
}
|
||||||
|
return await promise();
|
||||||
|
} catch (e) {
|
||||||
|
if (retries < maxRetries) {
|
||||||
|
onRetry();
|
||||||
|
return retryWithBackoff(retries + 1);
|
||||||
|
} else {
|
||||||
|
console.warn('Max retries reached. Bubbling the error up');
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return retryWithBackoff(0);
|
||||||
|
}
|
60
pkg/interface/webterm/lib/stye.ts
Normal file
60
pkg/interface/webterm/lib/stye.ts
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import { Deco, Stye, Tint } from '@urbit/api/term';
|
||||||
|
|
||||||
|
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}`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const stye = (s: Stye) => {
|
||||||
|
let out = '';
|
||||||
|
|
||||||
|
// text decorations
|
||||||
|
//
|
||||||
|
if (s.deco.length > 0) {
|
||||||
|
out += s.deco.reduce((decs: number[], deco: Deco) => {
|
||||||
|
/* eslint-disable max-statements-per-line */
|
||||||
|
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';
|
||||||
|
};
|
23
pkg/interface/webterm/lib/theme.ts
Normal file
23
pkg/interface/webterm/lib/theme.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { ITheme } from 'xterm';
|
||||||
|
|
||||||
|
export const makeTheme = (dark: boolean): ITheme => {
|
||||||
|
let fg, bg: string;
|
||||||
|
if (dark) {
|
||||||
|
fg = 'white';
|
||||||
|
bg = 'rgb(26,26,26)';
|
||||||
|
} 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,
|
||||||
|
cursorAccent: bg,
|
||||||
|
selection: fg
|
||||||
|
};
|
||||||
|
};
|
66
pkg/interface/webterm/lib/useAddSession.ts
Normal file
66
pkg/interface/webterm/lib/useAddSession.ts
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import {
|
||||||
|
DEFAULT_HANDLER,
|
||||||
|
AGENT_SESSION_REGEX,
|
||||||
|
SESSION_ID_REGEX
|
||||||
|
} from '../constants';
|
||||||
|
import useTermState from '../state';
|
||||||
|
import api from '../api';
|
||||||
|
import { pokeTask } from '@urbit/api/term';
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
export const useAddSession = () => {
|
||||||
|
const { names } = useTermState();
|
||||||
|
|
||||||
|
const addSession = useCallback(async () => {
|
||||||
|
let agent = DEFAULT_HANDLER;
|
||||||
|
let sessionName: string;
|
||||||
|
|
||||||
|
const userInput = prompt('Please enter an alpha-numeric session name.');
|
||||||
|
// user canceled or did not enter a value
|
||||||
|
if (null === userInput) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for custom agent session syntax
|
||||||
|
if (AGENT_SESSION_REGEX.test(userInput)) {
|
||||||
|
const match = AGENT_SESSION_REGEX.exec(userInput);
|
||||||
|
if (!match) {
|
||||||
|
alert('Invalid format. Valid syntax: agent!session-name');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
agent = match[1];
|
||||||
|
sessionName = match[2];
|
||||||
|
// else, use the default session creation regex
|
||||||
|
} else if (SESSION_ID_REGEX.test(userInput)) {
|
||||||
|
const match = SESSION_ID_REGEX.exec(userInput);
|
||||||
|
if (!match) {
|
||||||
|
alert('Invalid format. Valid syntax: session-name');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sessionName = match[1];
|
||||||
|
} else {
|
||||||
|
alert('Invalid format. Valid syntax: session-name');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// prevent duplicate sessions
|
||||||
|
if(names.includes(sessionName)) {
|
||||||
|
alert(`Session name must be unique ("${sessionName}" already in use)`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
//TODO eventually, customizable app pre-linking?
|
||||||
|
await api.poke(pokeTask(sessionName, { open: { term: agent, apps: [{ who: '~' + (window as any).ship, app: 'dojo' }] } }));
|
||||||
|
useTermState.getState().set((state) => {
|
||||||
|
state.names = [sessionName, ...state.names].sort();
|
||||||
|
state.selected = sessionName;
|
||||||
|
state.sessions[sessionName] = null;
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log('unable to create session:', error);
|
||||||
|
}
|
||||||
|
}, [names]);
|
||||||
|
|
||||||
|
return addSession;
|
||||||
|
};
|
@ -1,6 +1,5 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useTheme } from './settings';
|
import useTermState from '../state';
|
||||||
import useTermState from './state';
|
|
||||||
|
|
||||||
export function useDark() {
|
export function useDark() {
|
||||||
const [osDark, setOsDark] = useState(false);
|
const [osDark, setOsDark] = useState(false);
|
||||||
@ -11,12 +10,11 @@ export function useDark() {
|
|||||||
setOsDark(e.matches);
|
setOsDark(e.matches);
|
||||||
};
|
};
|
||||||
setOsDark(themeWatcher.matches);
|
setOsDark(themeWatcher.matches);
|
||||||
themeWatcher.addListener(update);
|
themeWatcher.addEventListener('change', update);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
themeWatcher.removeListener(update);
|
themeWatcher.removeEventListener('change', update);
|
||||||
}
|
};
|
||||||
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const theme = useTermState(s => s.theme);
|
const theme = useTermState(s => s.theme);
|
44
pkg/interface/webterm/lib/useDetectOS.ts
Normal file
44
pkg/interface/webterm/lib/useDetectOS.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/* eslint-disable no-useless-escape */
|
||||||
|
// Regex patterns inspired by:
|
||||||
|
// https://github.com/faisalman/ua-parser-js/blob/master/src/ua-parser.js
|
||||||
|
const LINUX = [
|
||||||
|
/\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i,
|
||||||
|
/(mint)[\/\(\) ]?(\w*)/i,
|
||||||
|
/(mageia|vectorlinux)[; ]/i,
|
||||||
|
/([kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire)(?: gnu\/linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i,
|
||||||
|
/(hurd|linux) ?([\w\.]*)/i,
|
||||||
|
/(gnu) ?([\w\.]*)/i,
|
||||||
|
/\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i,
|
||||||
|
/(haiku) (\w+)/i,
|
||||||
|
/(sunos) ?([\w\.\d]*)/i,
|
||||||
|
/((?:open)?solaris)[-\/ ]?([\w\.]*)/i,
|
||||||
|
/(aix) ((\d)(?=\.|\)| )[\w\.])*/i,
|
||||||
|
/\b(beos|os\/2|amigaos|morphos|openvms|fuchsia|hp-ux)/i,
|
||||||
|
/(unix) ?([\w\.]*)/i
|
||||||
|
];
|
||||||
|
|
||||||
|
const MAC_OS = [
|
||||||
|
/(mac os x) ?([\w\. ]*)/i,
|
||||||
|
/(macintosh|mac_powerpc\b)(?!.+haiku)/i
|
||||||
|
];
|
||||||
|
|
||||||
|
const WINDOWS = [
|
||||||
|
/microsoft (windows) (vista|xp)/i,
|
||||||
|
/(windows) nt 6\.2; (arm)/i,
|
||||||
|
/(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i,
|
||||||
|
/(windows)[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i
|
||||||
|
];
|
||||||
|
|
||||||
|
export const useDetectOS = () => {
|
||||||
|
const userAgent = navigator.userAgent;
|
||||||
|
|
||||||
|
const isLinux = LINUX.some(regex => regex.test(userAgent));
|
||||||
|
const isMacOS = MAC_OS.some(regex => regex.test(userAgent));
|
||||||
|
const isWindows = WINDOWS.some(regex => regex.test(userAgent));
|
||||||
|
|
||||||
|
return {
|
||||||
|
isLinux,
|
||||||
|
isMacOS,
|
||||||
|
isWindows
|
||||||
|
};
|
||||||
|
};
|
17
pkg/interface/webterm/lib/useIsMounted.ts
Normal file
17
pkg/interface/webterm/lib/useIsMounted.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { useCallback, useEffect, useRef } from 'react';
|
||||||
|
|
||||||
|
function useIsMounted() {
|
||||||
|
const isMounted = useRef(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
isMounted.current = true;
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
isMounted.current = false;
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return useCallback(() => isMounted.current, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useIsMounted;
|
716
pkg/interface/webterm/package-lock.json
generated
716
pkg/interface/webterm/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -11,6 +11,7 @@
|
|||||||
"@urbit/api": "^1.1.1",
|
"@urbit/api": "^1.1.1",
|
||||||
"@urbit/http-api": "^1.2.1",
|
"@urbit/http-api": "^1.2.1",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
"react": "^16.14.0",
|
"react": "^16.14.0",
|
||||||
"react-dom": "^16.14.0",
|
"react-dom": "^16.14.0",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
@ -36,7 +37,7 @@
|
|||||||
"@types/styled-system": "^5.1.10",
|
"@types/styled-system": "^5.1.10",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.15.0",
|
"@typescript-eslint/eslint-plugin": "^4.15.0",
|
||||||
"@typescript-eslint/parser": "^4.24.0",
|
"@typescript-eslint/parser": "^4.24.0",
|
||||||
"@urbit/eslint-config": "^1.0.0",
|
"@urbit/eslint-config": "^1.0.3",
|
||||||
"@welldone-software/why-did-you-render": "^6.1.0",
|
"@welldone-software/why-did-you-render": "^6.1.0",
|
||||||
"babel-eslint": "^10.1.0",
|
"babel-eslint": "^10.1.0",
|
||||||
"babel-jest": "^26.6.3",
|
"babel-jest": "^26.6.3",
|
||||||
@ -45,7 +46,9 @@
|
|||||||
"clean-webpack-plugin": "^3.0.0",
|
"clean-webpack-plugin": "^3.0.0",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"eslint": "^7.26.0",
|
"eslint": "^7.26.0",
|
||||||
"eslint-plugin-react": "^7.22.0",
|
"eslint-import-resolver-typescript": "^2.5.0",
|
||||||
|
"eslint-plugin-import": "^2.25.4",
|
||||||
|
"eslint-plugin-react-hooks": "^4.3.0",
|
||||||
"file-loader": "^6.2.0",
|
"file-loader": "^6.2.0",
|
||||||
"html-webpack-plugin": "^4.5.1",
|
"html-webpack-plugin": "^4.5.1",
|
||||||
"husky": "^6.0.0",
|
"husky": "^6.0.0",
|
||||||
@ -58,7 +61,8 @@
|
|||||||
"webpack-dev-server": "^3.11.2"
|
"webpack-dev-server": "^3.11.2"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "eslint ./src/**/*.{ts,tsx}",
|
"lint": "eslint ./**/*.{ts,tsx}",
|
||||||
|
"lint-fix": "eslint --fix ./**/*.{ts,tsx}",
|
||||||
"lint-file": "eslint",
|
"lint-file": "eslint",
|
||||||
"tsc": "tsc",
|
"tsc": "tsc",
|
||||||
"tsc:watch": "tsc --watch",
|
"tsc:watch": "tsc --watch",
|
||||||
|
@ -3,21 +3,33 @@ import { FitAddon } from 'xterm-addon-fit';
|
|||||||
import create from 'zustand';
|
import create from 'zustand';
|
||||||
import produce from 'immer';
|
import produce from 'immer';
|
||||||
|
|
||||||
type Session = { term: Terminal, fit: FitAddon };
|
export type Session = {
|
||||||
type Sessions = { [id: string]: Session; }
|
term: Terminal,
|
||||||
|
fit: FitAddon,
|
||||||
|
hasBell: boolean,
|
||||||
|
pending: number,
|
||||||
|
subscriptionId: number | null,
|
||||||
|
} | null;
|
||||||
|
export type Sessions = { [id: string]: Session; }
|
||||||
|
|
||||||
export interface TermState {
|
export interface TermState {
|
||||||
sessions: Sessions,
|
sessions: Sessions,
|
||||||
|
names: string[],
|
||||||
selected: string,
|
selected: string,
|
||||||
slogstream: null | EventSource,
|
slogstream: null | EventSource,
|
||||||
theme: 'auto' | 'light' | 'dark'
|
theme: 'auto' | 'light' | 'dark',
|
||||||
};
|
//TODO: figure out the type
|
||||||
|
set: any,
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
const useTermState = create<TermState>((set, get) => ({
|
const useTermState = create<TermState>((set, get) => ({
|
||||||
sessions: {} as Sessions,
|
sessions: {} as Sessions,
|
||||||
|
names: [''],
|
||||||
selected: '', // empty string is default session
|
selected: '', // empty string is default session
|
||||||
slogstream: null,
|
slogstream: null,
|
||||||
theme: 'auto',
|
theme: 'auto',
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
set: (f: (draft: TermState) => void) => {
|
set: (f: (draft: TermState) => void) => {
|
||||||
set(produce(f));
|
set(produce(f));
|
||||||
}
|
}
|
||||||
|
26
pkg/interface/webterm/tsconfig.json
Normal file
26
pkg/interface/webterm/tsconfig.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"noUnusedParameters": false,
|
||||||
|
"noImplicitReturns": false,
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"noUnusedLocals": false,
|
||||||
|
"noImplicitAny": false,
|
||||||
|
"noEmit": true,
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "ESNext",
|
||||||
|
"strict": false,
|
||||||
|
"strictNullChecks": true,
|
||||||
|
"jsx": "react",
|
||||||
|
"baseUrl": "."
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"**/*"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"dist"
|
||||||
|
]
|
||||||
|
}
|
@ -16,15 +16,15 @@
|
|||||||
+$ card card:shoe
|
+$ card card:shoe
|
||||||
::
|
::
|
||||||
+$ versioned-state
|
+$ versioned-state
|
||||||
$% state-3
|
$% state-4
|
||||||
|
state-3
|
||||||
state-2
|
state-2
|
||||||
state-1
|
state-1
|
||||||
state-0
|
state-0
|
||||||
==
|
==
|
||||||
::
|
::
|
||||||
+$ state-3
|
+$ state-4
|
||||||
$: %3
|
$: %4
|
||||||
::TODO support multiple sessions
|
|
||||||
sessions=(map sole-id session) :: sole sessions
|
sessions=(map sole-id session) :: sole sessions
|
||||||
bound=(map resource glyph) :: bound resource glyphs
|
bound=(map resource glyph) :: bound resource glyphs
|
||||||
binds=(jug glyph resource) :: resource glyph lookup
|
binds=(jug glyph resource) :: resource glyph lookup
|
||||||
@ -33,7 +33,17 @@
|
|||||||
timez=(pair ? @ud) :: timezone adjustment
|
timez=(pair ? @ud) :: timezone adjustment
|
||||||
==
|
==
|
||||||
::
|
::
|
||||||
+$ sole-id @ta
|
+$ state-3
|
||||||
|
$: %3
|
||||||
|
sessions=(map @ta session)
|
||||||
|
bound=(map resource glyph)
|
||||||
|
binds=(jug glyph resource)
|
||||||
|
settings=(set term)
|
||||||
|
width=@ud
|
||||||
|
timez=(pair ? @ud)
|
||||||
|
==
|
||||||
|
::
|
||||||
|
+$ sole-id sole-id:shoe
|
||||||
+$ session
|
+$ session
|
||||||
$: viewing=(set resource) :: connected graphs
|
$: viewing=(set resource) :: connected graphs
|
||||||
history=(list uid:post) :: scrollback pointers
|
history=(list uid:post) :: scrollback pointers
|
||||||
@ -115,7 +125,7 @@
|
|||||||
== ::
|
== ::
|
||||||
::
|
::
|
||||||
--
|
--
|
||||||
=| state-3
|
=| state-4
|
||||||
=* state -
|
=* state -
|
||||||
::
|
::
|
||||||
%- agent:dbug
|
%- agent:dbug
|
||||||
@ -258,14 +268,14 @@
|
|||||||
settings width timez
|
settings width timez
|
||||||
==
|
==
|
||||||
::
|
::
|
||||||
=^ cards u.old
|
=^ cards-1 u.old
|
||||||
?. ?=(%2 -.u.old) [~ u.old]
|
?. ?=(%2 -.u.old) [~ u.old]
|
||||||
:- :~ [%pass /chat-store %agent [our-self %chat-store] %leave ~]
|
:- :~ [%pass /chat-store %agent [our-self %chat-store] %leave ~]
|
||||||
[%pass /invites %agent [our.bowl %invite-store] %leave ~]
|
[%pass /invites %agent [our.bowl %invite-store] %leave ~]
|
||||||
==
|
==
|
||||||
^- state-3
|
^- state-3
|
||||||
:- %3
|
:- %3
|
||||||
:* %+ ~(put in *(map sole-id session))
|
:* %+ ~(put in *(map @ta session))
|
||||||
(cat 3 'drum_' (scot %p our.bowl))
|
(cat 3 'drum_' (scot %p our.bowl))
|
||||||
:* ~ ~ 0
|
:* ~ ~ 0
|
||||||
::
|
::
|
||||||
@ -290,14 +300,29 @@
|
|||||||
timez.u.old
|
timez.u.old
|
||||||
==
|
==
|
||||||
::
|
::
|
||||||
?> ?=(%3 -.u.old)
|
=^ cards-2 u.old
|
||||||
|
?. ?=(%3 -.u.old) [~ u.old]
|
||||||
|
:- %+ turn ~(tap in ~(key by sessions.u.old))
|
||||||
|
|= id=@ta
|
||||||
|
^- card:agent:gall
|
||||||
|
[%give %kick ~[/sole/[id]] ~]
|
||||||
|
=- u.old(- %4, sessions -)
|
||||||
|
%- ~(gas by *(map sole-id session))
|
||||||
|
%+ murn ~(tap by sessions.u.old)
|
||||||
|
|= [id=@ta s=session]
|
||||||
|
(bind (upgrade-id:sole:shoe id) (late s))
|
||||||
|
::
|
||||||
|
?> ?=(%4 -.u.old)
|
||||||
:_ u.old
|
:_ u.old
|
||||||
%+ welp
|
;: welp
|
||||||
cards
|
cards-1
|
||||||
?: %- ~(has by wex.bowl)
|
cards-2
|
||||||
[/graph-store our-self %graph-store]
|
::
|
||||||
~
|
?: %- ~(has by wex.bowl)
|
||||||
~[connect]
|
[/graph-store our-self %graph-store]
|
||||||
|
~
|
||||||
|
~[connect]
|
||||||
|
==
|
||||||
:: +connect: connect to the graph-store
|
:: +connect: connect to the graph-store
|
||||||
::
|
::
|
||||||
++ connect
|
++ connect
|
||||||
|
1
pkg/landscape/lib/dill.hoon
Symbolic link
1
pkg/landscape/lib/dill.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/lib/dill.hoon
|
@ -1 +1 @@
|
|||||||
[%zuse 417]
|
[%zuse 416]
|
||||||
|
@ -24,7 +24,7 @@ With:
|
|||||||
import UrbitInterface from '@urbit/http-api';
|
import UrbitInterface from '@urbit/http-api';
|
||||||
import { settings } from '@urbit/api';
|
import { settings } from '@urbit/api';
|
||||||
const api: UrbitInterface = useApi();
|
const api: UrbitInterface = useApi();
|
||||||
api.poke(setings.putEntry(bucket, key, value));
|
api.poke(settings.putEntry(bucket, key, value));
|
||||||
```
|
```
|
||||||
|
|
||||||
You may import single functions
|
You may import single functions
|
||||||
@ -38,4 +38,4 @@ import { settings } from '@urbit/api';
|
|||||||
|
|
||||||
This package also provides types and utilities for working with Urbit's internal data structures, such as Nouns, Das, Tas, and so forth.
|
This package also provides types and utilities for working with Urbit's internal data structures, such as Nouns, Das, Tas, and so forth.
|
||||||
|
|
||||||
This package was originally developed as part of Tlon's Landscape client and therefore the best reference material exists [there](https://github.com/urbit/urbit/tree/master/pkg/interface/src).
|
This package was originally developed as part of Tlon's Landscape client and therefore the best reference material exists [there](https://github.com/urbit/urbit/tree/master/pkg/interface/src).
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { Poke } from '../lib'
|
import { Scry } from '../../http-api/src'
|
||||||
|
import { Poke } from '../../http-api/src/types';
|
||||||
import { Belt, Task, SessionTask } from './types';
|
import { Belt, Task, SessionTask } from './types';
|
||||||
|
|
||||||
export const pokeTask = (session: string, task: Task): Poke<SessionTask> => ({
|
export const pokeTask = (session: string, task: Task): Poke<SessionTask> => ({
|
||||||
@ -13,9 +14,7 @@ export const pokeBelt = (
|
|||||||
): Poke<SessionTask> => pokeTask(session, { belt });
|
): Poke<SessionTask> => pokeTask(session, { belt });
|
||||||
|
|
||||||
//NOTE scry will return string[]
|
//NOTE scry will return string[]
|
||||||
// export const scrySessions = (): Scry => ({
|
export const scrySessions = (): Scry => ({
|
||||||
// app: 'herm',
|
app: 'herm',
|
||||||
// path: `/sessions`
|
path: `/sessions`
|
||||||
// });
|
});
|
||||||
//TODO remove stub once new backend lands
|
|
||||||
export const scrySessions = (): string[] => [''];
|
|
||||||
|
@ -25,17 +25,15 @@ export type Stub = {
|
|||||||
export type Blit =
|
export type Blit =
|
||||||
| { bel: null } // make a noise
|
| { bel: null } // make a noise
|
||||||
| { clr: null } // clear the screen
|
| { clr: null } // clear the screen
|
||||||
| { hop: number | { r: number, c: number } } // set cursor col/pos
|
| { hop: number | { x: number, y: number } } // set cursor col/pos
|
||||||
| { klr: Stub[] } // put styled
|
| { klr: Stub[] } // put styled
|
||||||
| { put: string[] } // put text at cursor
|
| { mor: Blit[] } // multiple blits
|
||||||
| { nel: null } // newline
|
| { nel: null } // newline
|
||||||
|
| { put: string[] } // put text at cursor
|
||||||
| { sag: { path: string, file: string } } // save to jamfile
|
| { sag: { path: string, file: string } } // save to jamfile
|
||||||
| { sav: { path: string, file: string } } // save to file
|
| { sav: { path: string, file: string } } // save to file
|
||||||
| { url: string } // activate url
|
| { url: string } // activate url
|
||||||
| { wyp: null } // wipe cursor line
|
| { wyp: null } // wipe cursor line
|
||||||
//
|
|
||||||
| { lin: string[] } // legacy put
|
|
||||||
| { mor: true } // legacy nel
|
|
||||||
|
|
||||||
// inputs
|
// inputs
|
||||||
//
|
//
|
||||||
@ -45,21 +43,19 @@ export type Bolt =
|
|||||||
| { aro: 'd' | 'l' | 'r' | 'u' }
|
| { aro: 'd' | 'l' | 'r' | 'u' }
|
||||||
| { bac: null }
|
| { bac: null }
|
||||||
| { del: null }
|
| { del: null }
|
||||||
| { hit: { r: number, c: number } }
|
| { hit: { x: number, y: number } }
|
||||||
| { ret: null }
|
| { ret: null }
|
||||||
|
|
||||||
export type Belt =
|
export type Belt =
|
||||||
| Bolt
|
| Bolt
|
||||||
| { mod: { mod: 'ctl' | 'met' | 'hyp', key: Bolt } }
|
| { mod: { mod: 'ctl' | 'met' | 'hyp', key: Bolt } }
|
||||||
| { txt: Array<string> }
|
| { txt: Array<string> }
|
||||||
//
|
|
||||||
| { ctl: string }; // legacy mod
|
|
||||||
|
|
||||||
export type Task =
|
export type Task =
|
||||||
| { belt: Belt }
|
| { belt: Belt }
|
||||||
| { blew: { w: number, h: number } }
|
| { blew: { w: number, h: number } }
|
||||||
| { flow: { term: string, apps: Array<{ who: string, app: string }> } }
|
|
||||||
| { hail: null }
|
| { hail: null }
|
||||||
| { hook: null }
|
| { open: { term: string, apps: Array<{ who: string, app: string }> } }
|
||||||
|
| { shut: null }
|
||||||
|
|
||||||
export type SessionTask = { session: string } & Task
|
export type SessionTask = { session: string } & Task
|
||||||
|
@ -167,6 +167,9 @@ u3_ptty_init(uv_loop_t* lup_u, const c3_c** err_c)
|
|||||||
|
|
||||||
// Construct raw termios configuration.
|
// Construct raw termios configuration.
|
||||||
//
|
//
|
||||||
|
// makes input available per-character, does not echo input,
|
||||||
|
// disables special input pre-processing, output post-processing.
|
||||||
|
//
|
||||||
{
|
{
|
||||||
pty_u->raw_u = pty_u->bak_u;
|
pty_u->raw_u = pty_u->bak_u;
|
||||||
|
|
||||||
|
2
pkg/urbit/configure
vendored
2
pkg/urbit/configure
vendored
@ -211,7 +211,7 @@ for citem in $compat; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
cat >config.mk <<EOF
|
cat >config.mk <<EOF
|
||||||
CFLAGS := $CFLAGS -funsigned-char -ffast-math -fcommon -std=gnu99
|
CFLAGS := $CFLAGS -funsigned-char -ffast-math -fcommon -std=gnu99 -Wno-format-zero-length
|
||||||
LDFLAGS := $LDFLAGS
|
LDFLAGS := $LDFLAGS
|
||||||
CC := ${CC-cc}
|
CC := ${CC-cc}
|
||||||
compat := $compat
|
compat := $compat
|
||||||
|
@ -572,7 +572,7 @@ _setup_cert_store()
|
|||||||
{
|
{
|
||||||
BIO* cbio = BIO_new_mem_buf(include_ca_bundle_crt, include_ca_bundle_crt_len);
|
BIO* cbio = BIO_new_mem_buf(include_ca_bundle_crt, include_ca_bundle_crt_len);
|
||||||
if ( !cbio || !(_cert_store = PEM_X509_INFO_read_bio(cbio, NULL, NULL, NULL)) ) {
|
if ( !cbio || !(_cert_store = PEM_X509_INFO_read_bio(cbio, NULL, NULL, NULL)) ) {
|
||||||
u3l_log("boot: failed to decode embedded CA certificates\r\n");
|
u3l_log("boot: failed to decode embedded CA certificates");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1267,7 +1267,7 @@ _cw_eval(c3_i argc, c3_c* argv[])
|
|||||||
}
|
}
|
||||||
u3s_cue_xeno_done(sil_u);
|
u3s_cue_xeno_done(sil_u);
|
||||||
if ( c3n == u3v_boot_lite(pil) ) {
|
if ( c3n == u3v_boot_lite(pil) ) {
|
||||||
u3l_log("lite: boot failed\r\n");
|
u3l_log("lite: boot failed");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1858,7 +1858,7 @@ _cw_vere(c3_i argc, c3_c* argv[])
|
|||||||
// initialize curl
|
// initialize curl
|
||||||
//
|
//
|
||||||
if ( 0 != curl_global_init(CURL_GLOBAL_DEFAULT) ) {
|
if ( 0 != curl_global_init(CURL_GLOBAL_DEFAULT) ) {
|
||||||
u3l_log("boot: curl initialization failed\r\n");
|
u3l_log("boot: curl initialization failed");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1888,11 +1888,11 @@ _cw_vere(c3_i argc, c3_c* argv[])
|
|||||||
|
|
||||||
|
|
||||||
if ( u3_king_vere(pac_c, ver_c, arc_c, dir_c, 0) ) {
|
if ( u3_king_vere(pac_c, ver_c, arc_c, dir_c, 0) ) {
|
||||||
u3l_log("vere: download failed\r\n");
|
u3l_log("vere: download failed");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
u3l_log("vere: download succeeded\r\n");
|
u3l_log("vere: download succeeded");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _cw_vile(): generatoe/print keyfile
|
/* _cw_vile(): generatoe/print keyfile
|
||||||
@ -2138,7 +2138,7 @@ main(c3_i argc,
|
|||||||
sigemptyset(&set);
|
sigemptyset(&set);
|
||||||
sigaddset(&set, SIGPROF);
|
sigaddset(&set, SIGPROF);
|
||||||
if ( 0 != pthread_sigmask(SIG_BLOCK, &set, NULL) ) {
|
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);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2230,7 +2230,7 @@ main(c3_i argc,
|
|||||||
{
|
{
|
||||||
SECURITY_ATTRIBUTES sa = {sizeof(sa), NULL, TRUE};
|
SECURITY_ATTRIBUTES sa = {sizeof(sa), NULL, TRUE};
|
||||||
if ( NULL == (u3_Host.cev_u = CreateEvent(&sa, FALSE, FALSE, NULL)) ) {
|
if ( NULL == (u3_Host.cev_u = CreateEvent(&sa, FALSE, FALSE, NULL)) ) {
|
||||||
u3l_log("boot: failed to create Ctrl-C event: %d\r\n", GetLastError());
|
u3l_log("boot: failed to create Ctrl-C event: %d", GetLastError());
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2251,7 +2251,7 @@ main(c3_i argc,
|
|||||||
// initialize curl
|
// initialize curl
|
||||||
//
|
//
|
||||||
if ( 0 != curl_global_init(CURL_GLOBAL_DEFAULT) ) {
|
if ( 0 != curl_global_init(CURL_GLOBAL_DEFAULT) ) {
|
||||||
u3l_log("boot: curl initialization failed\r\n");
|
u3l_log("boot: curl initialization failed");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user