1 | ---
|
2 | default_highlighter: oils-sh
|
3 | ---
|
4 |
|
5 | Oils Headless Mode: For Alternative UIs
|
6 | =======================================
|
7 |
|
8 | A GUI or [TUI][] process can start Oils like this:
|
9 |
|
10 | osh --headless
|
11 |
|
12 | and send messages to it over a Unix domain socket. In this mode, the language
|
13 | and shell state are **decoupled** from the user interface.
|
14 |
|
15 | This is a unique feature that other shells don't have!
|
16 |
|
17 | [TUI]: https://en.wikipedia.org/wiki/Text-based_user_interface
|
18 |
|
19 | Note: This doc is **in progress**. Join the `#shell-gui` channel on
|
20 | [Zulip]($xref:zulip) for current information.
|
21 |
|
22 | <div id="toc">
|
23 | </div>
|
24 |
|
25 | ## The General Idea
|
26 |
|
27 | The UI process should handle these things:
|
28 |
|
29 | - Auto-completion. It should use Oils for parsing, and not try to parse shell
|
30 | itself!
|
31 | - History: Allow the user to retrieve commands typed in the past.
|
32 | - Cancelling commands in progress.
|
33 | - Optional: multiplexing among multiple headless shells.
|
34 |
|
35 | The shell process handles these things:
|
36 |
|
37 | - Parsing and evaluating the language
|
38 | - Maintaining state (shell options, variables, etc.)
|
39 |
|
40 | ## How to Write a Client for a Headless Shell
|
41 |
|
42 | ### Implement the FANOS Protocol
|
43 |
|
44 | FANOS stands for *File descriptors and Netstrings Over Sockets*. It's a
|
45 | **control** protocol that already has 2 implementations, which are very small:
|
46 |
|
47 | - [client/py_fanos.py]($oils-src): 102 lines of code
|
48 | - [native/fanos.c]($oils-src): 294 lines of code
|
49 |
|
50 | ### Send Commands and File Descriptors to the "Server"
|
51 |
|
52 | List of commands:
|
53 |
|
54 | - `EVAL`. Parse and evaluate a shell command. The logic is similar to the
|
55 | `eval` and `source` builtins.
|
56 | - It can be used for both user-entered commands and "behind the scenes"
|
57 | functions for the shell UI.
|
58 | - The stdin, stdout, and stderr of **the shell and its child processes** will
|
59 | be redirected to the descriptors you pass.
|
60 | - There's no history expansion for now. The UI can implement this itself,
|
61 | and Oils may be able to help.
|
62 |
|
63 | TODO: More commands.
|
64 |
|
65 | ### Query Shell State and Render it in the UI
|
66 |
|
67 | You may want to use commands like these to draw the UI:
|
68 |
|
69 | - `echo ${PS1@P}` -- render the prompt
|
70 | - `echo $PWD $_` -- get the current directory and current status
|
71 |
|
72 | You can redirect them to a pipe, rather than displaying them in the terminal.
|
73 |
|
74 | Remember that a fundamental difference between a REPL and a GUI is that a GUI
|
75 | **shows state** explicitly. This is a good thing and you should take advantage
|
76 | of it!
|
77 |
|
78 | ### Example Code
|
79 |
|
80 | See [client/headless_demo.py]($oils-src). This is pure Python code that's
|
81 | divorced from the rest of Oils.
|
82 |
|
83 | ## Related Links
|
84 |
|
85 | Feel free to edit these pages:
|
86 |
|
87 | - [Headless Mode][] on the wiki. We want there to be a rich ecosystem of
|
88 | interactive shells built upon Oils.
|
89 | - [Interactive Shell][] on the wiki. Be inspired by these nice projects, many
|
90 | of which have screenshots!
|
91 |
|
92 | [Headless Mode]: https://github.com/oilshell/oil/wiki/Headless-Mode
|
93 |
|
94 | [Interactive Shell]: https://github.com/oilshell/oil/wiki/Interactive-Shell
|