@@ -10,9 +10,10 @@ In this walkthrough we will go in-depth on how to build command line interface (
1010applications in Urbit using the `shoe` library.
1111
1212There are three CLI apps that currently ship with urbit - `%dojo`, `%chat-cli`,
13−and `%shoe`. You should be familiar with the former two, the latter is an example
14−app that shows off how the `shoe` library works that we will be looking at
15−closely. These are all Gall apps, and as such their source can be found in the `app/` folder of your `%home` desk.
13+and `%shoe`. You should be familiar with the former two, the latter is an
14+example app that shows off how the `shoe` library works that we will be looking
15+at closely. These are all Gall apps, and their source can be found in the `app/`
16+folder of your `%base` desk.
1617
1718In [the `shoe` library](#the-shoe-library) we take a closer look at the `shoe` library and its
1819cores and how they are utilized in CLI apps. Then in [the `sole`
@@ -26,7 +27,6 @@ lesson](/docs/hoon/hoon-school/generators#ask) on `sole` and `%ask`
2627generators, which only covers the bare minimum necessary to write generators
2728that take user input.
2829
29−
3030## The `shoe` library {#the-shoe-library}
3131
3232Here we describe how sessions are identified, the specialized `card`s that Gall agents
@@ -44,9 +44,11 @@ ship and which session on that ship if there are multiple.
4444
4545Gall agents with the `shoe` library are able to utilize `%shoe` `card`s. These
4646additions to the standard set of `cards` have the following shape:
47+
4748```hoon
4849[%shoe sole-ids=(list @ta) effect=shoe-effect]`
4950```
51+
5052`sole-ids` is the `list` of session ids that the following `effect` is
5153emitted to. An empty `sole-ids` sends the effect to all connected sessions.
5254`shoe-effect`s, for now, are always of the shape `[%sole effect=sole-effect]`, where
@@ -144,14 +146,13 @@ This is a function for wrapping a `shoe` core, which has too many
144146arms to be a valid Gall agent core. This turns it into a standard Gall agent core by
145147integrating the additional arms into the standard ones.
146148
147−
148149## The `sole` library {#the-sole-library}
149150
150−`shoe` apps may create specialized `card`s of the `[%shoe
151−(list @ta) shoe-effect]` shape, where `shoe-effect` currently just wrap `sole-effect`s, i.e. instructions for displaying text and producing other effects in the console.
151+`shoe` apps may create specialized `card`s of the `[%shoe (list @ta) shoe-effect]` shape, where `shoe-effect` currently just wrap `sole-effect`s, i.e. instructions for displaying text and producing other effects in the console.
152152
153153The list of possible `sole-effects` can be found in `/sur/sole.hoon`. A few
154154commonly used ones are as follows.
155+
155156- `[%txt tape]` is used to display a line of text.
156157- `[%bel ~]` is used to emit a beep.
157158- `[%pro sole-prompt]` is used to set the prompt.
@@ -159,6 +160,7 @@ commonly used ones are as follows.
159160
160161For example, a `sole-effect` that beeps and displays `This is some text.` would
161162be structured as
163+
162164```hoon
163165[%mor [%txt "This is some text."] [%bel ~] ~]
164166```
@@ -180,20 +182,23 @@ intention is to connect their `%shoe` apps.
180182On each fake ship start `%shoe` by entering `|start %shoe` into dojo. This will
181183automatically
182184change the prompt to `~zod:shoe>` and `~nus:shoe>`. Type `demo` and watch the following appear:
185+
183186```
184187~zod ran the command
185188~zod:shoe>
186189```
190+
187191`~zod ran the command` should be displayed in bold green text, signifying that
188192the command originated locally.
189193
190−Now we will connect the sessions. Switch `~zod` back to dojo with `Ctrl-X` and enter `|link
191−~nus %shoe`. If this succeeds you will see the following.
194+Now we will connect the sessions. Switch `~zod` back to dojo with `Ctrl-X` and enter `|link ~nus %shoe`. If this succeeds you will see the following.
195+
192196```
193197>=
194198; ~nus is your neighbor
195199[linked to [p=~nus q=%shoe]]
196200```
201+
197202Now `~zod` will have two `%shoe` sessions running - one local one on `~zod` and
198203one remote one on `~nus`, which you can access by pressing `Ctrl-X` until you see
199204`~nus:shoe>` from `~zod`'s console. On the other hand, you should not see
@@ -207,10 +212,12 @@ bold green text.
207212
208213Now try to link to `~zod`'s `%shoe` session from `~nus` by switching to the dojo
209214on `~nus` and entering `|link ~zod %shoe`. You should see
215+
210216```
211217>=
212218[unlinked from [p=~zod q=%shoe]]
213219```
220+
214221and if you press `Ctrl-X` you will not get a `~zod:shoe>` prompt. This is
215222because the example app is set up to always allow `~zod` to connect (as well as
216223subject moons if the ship happens to be a planet) but not `~nus`, so this
@@ -229,11 +236,12 @@ message means that `~nus` failed to connect to `~zod`'s `%shoe` session.
229236
230237`/+` is the Ford rune which imports libraries from the `/lib` directory into
231238the subject.
232− * `shoe` is the `shoe` library.
233− * `verb` is a library used to print what a Gall agent is doing.
234− * `dbug` is a library of debugging tools.
235− * `default-agent` contains a Gall agent core with minimal implementations of
236− required Gall arms.
239+
240+- `shoe` is the `shoe` library.
241+- `verb` is a library used to print what a Gall agent is doing.
242+- `dbug` is a library of debugging tools.
243+- `default-agent` contains a Gall agent core with minimal implementations of
244+ required Gall arms.
237245
238246```hoon
239247|%
@@ -243,6 +251,7 @@ the subject.
243251+$ card card:shoe
244252--
245253```
254+
246255The types used by the app.
247256
248257`state-0` stores the state of the app, which is null as there is no state to
@@ -254,8 +263,7 @@ commands that can be entered by the user. Since this app only supports one
254263command, it is unnecessary for it to have any associated data, thus the command
255264is represented by `~`.
256265
257−In a non-trivial context, a `command` is commonly given by `[%name
258−data]`, where `%name` is the identifier for the type of command and `data` is
266+In a non-trivial context, a `command` is commonly given by `[%name data]`, where `%name` is the identifier for the type of command and `data` is
259267a type or list of types that contain data needed to execute the command. See
260268`app/chat-cli.hoon` for examples of commands, such as `[%say letter:store]` and
261269`[%delete path]`. This is not required though, and you could use something like
@@ -264,7 +272,7 @@ a type or list of types that contain data needed to execute the command. See
264272`card` is either an ordinary Gall agent `card` or a `%shoe` `card`, which takes
265273the shape `[%shoe sole-ids=(list @ta) effect=shoe-effect]`. A `%shoe` `card` is
266274sent to all `sole`s listed in `sole-ids`, imaking them run the `sole-effect`
267−specified by `effect` (i.e. printing some text). Here we can
275+specified by `effect` (i.e. printing some text). Here we can
268276reference `card:shoe` because of `/+ shoe` at the beginning of the app.
269277
270278```hoon
@@ -272,6 +280,7 @@ reference `card:shoe` because of `/+ shoe` at the beginning of the app.
272280=* state -
273281::
274282```
283+
275284Add the bunt value of `state-0` to the head of the subject, then give it the
276285macro `state`. The `-` here is a lark expression referring to the head of the
277286subject. This allows us to use `state` to refer to the state elsewhere in the
@@ -293,13 +302,13 @@ producing a standard Gall agent core. Then we call wrap the Gall agent core with
293302`agent:dbug`, endowing it with additional arms useful for debugging, and then
294303wrap again with `verb`.
295304
296−
297305```hoon
298306|_ =bowl:gall
299307+* this .
300308 def ~(. (default-agent this %|) bowl)
301309 des ~(. (default:shoe this command) bowl)
302310```
311+
303312This is boilerplate Gall agent core code. We set `this` to be a macro for the
304313subject, which is the Gall agent core itself. We set `def` and `des` to be
305314macros for initialized `default-agent` and `default:shoe` doors respectively.
@@ -323,23 +332,25 @@ the standard Gall arms:
323332++ on-arvo on-arvo:def
324333++ on-fail on-fail:def
325334```
335+
326336These are minimalist Gall app arm implementations using the default behavior found in `def`.
327337
328338Here begins the implementation of the additional arms required by the
329339`(shoe:shoe command)` interface.
340+
330341```hoon
331342++ command-parser
332343 |= sole-id=@ta
333344 ^+ |~(nail *(like [? command]))
334345 (cold [& ~] (jest 'demo'))
335346```
347+
336348`+command-parser` is of central importance - it is what is used to parse user
337349input and transform it into `command`s for the app to execute. Writing a proper
338350command parser requires understanding of the Hoon parsing functions found in the
339351standard library. How to do so may be found in the [parsing tutorial](/docs/hoon/guides/parsing). For now, it is sufficient to know that this arm matches the text "demo" and
340352produces a `[? command]`-shaped noun in response. Note how the `&` signifies that the command will be run as soon as it has been entered, without waiting for the user to press return.
341353
342−
343354```hoon
344355++ tab-list
345356 |= sole-id=@ta
@@ -347,47 +358,57 @@ produces a `[? command]`-shaped noun in response. Note how the `&` signifies tha
347358 :~ ['demo' leaf+"run example command"]
348359 ==
349360```
361+
350362`+tab-list` is pretty much plug-n-play. For each command you want to be tab
351−completed, add an entry to the `list` begun by `:~` of the form `[%command
352−leaf+"description"]`. Now whenever the user types a partial command and presses
363+completed, add an entry to the `list` begun by `:~` of the form `[%command leaf+"description"]`. Now whenever the user types a partial command and presses
353364tab, the console will display the list of commmands that match the partial
354365command as well as the descriptions given here.
355366
356367Thus here we have that starting to type `demo` and pressing tab will result in
357368the following output in the console:
369+
358370```
359371demo run example command
360372~zod:shoe> demo
361373```
374+
362375with the remainder of `demo` now added to the input line.
363376
364377Next we have `+on-command`, which is called whenever `+command-parser`
365378recognizes that `demo` has been entered by a user.
379+
366380```hoon
367381++ on-command
368382 |= [sole-id=@ta =command]
369383 ^- (quip card _this)
370384```
385+
371386This is a gate that takes in the `sole-id` corresponding to the session and the
372387`command` noun parsed by `+command-parser` and returns a `list` of `card`s and
373388`_this`, which is our shoe agent core including its state.
389+
374390```hoon
375391 =- [[%shoe ~ %sole -]~ this]
376392```
393+
377394This creates a cell of a `%shoe` card that triggers a `sole-effect` given by the head of
378395the subject `-`, then the Gall agent core `this` - i.e. the return result of
379396this gate. The use of the `=-` rune means that what follows this
380397expression is actually run first, which puts the desired `sole-effect` into the
381398head of the subject.
399+
382400```hoon
383401 =/ =tape "{(scow %p src.bowl)} ran the command"
384402```
403+
385404We define the `tape` that we want to be printed.
405+
386406```hoon
387407 ?. =(src our):bowl
388408 [%txt tape]
389409 [%klr [[`%br ~ `%g] [(crip tape)]~]~]
390410```
411+
391412We cannot just produce the `tape` we want printed, - it needs to fit the
392413`sole-effect` type. This tells us that if the
393414origin of the command is not our ship to just print it normally with the `%txt`
@@ -396,6 +417,7 @@ makes the text green and bold).
396417
397418The following allows either `~zod`, or the host ship and its moons, to connect to
398419this app's command line interface using `|link`.
420+
399421```hoon
400422++ can-connect
401423 |= sole-id=@ta
@@ -407,6 +429,7 @@ this app's command line interface using `|link`.
407429
408430We use the minimal implementations for the final two `shoe` arms, since we don't
409431want to do anything special when users connect or disconnect.
432+
410433```hoon
411434++ on-connect on-connect:des
412435++ on-disconnect on-disconnect:des