summaryrefslogtreecommitdiffstats
path: root/2021/captions/ui.md
blob: c9991e91ee54fb77affe859d643d4c234c19c09a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
<a name="transcript"></a>
# Transcript

[[!template text="Hi! I'm Erik Anderson," start="00:00:07.600" video="mainVideo" id=subtitle]]
[[!template text="and I'll be talking about tui," start="00:00:09.120" video="mainVideo" id=subtitle]]
[[!template text="a user interface framework" start="00:00:10.559" video="mainVideo" id=subtitle]]
[[!template text="that I've written in Emacs Lisp." start="00:00:11.840" video="mainVideo" id=subtitle]]
[[!template text="First, I want to talk a bit about" start="00:00:15.040" video="mainVideo" id=subtitle]]
[[!template text="the problem space of" start="00:00:16.196" video="mainVideo" id=subtitle]]
[[!template text="user interface development," start="00:00:17.296" video="mainVideo" id=subtitle]]
[[!template text="specifically, I want to quickly illustrate" start="00:00:18.728" video="mainVideo" id=subtitle]]
[[!template text="some of the complexities involved" start="00:00:20.880" video="mainVideo" id=subtitle]]
[[!template text="with UI implementation in Emacs." start="00:00:22.320" video="mainVideo" id=subtitle]]
[[!template text="In Emacs, we have the ubiquitous" start="00:00:26.480" video="mainVideo" id=subtitle]]
[[!template text="buffer object type that forms the container" start="00:00:27.920" video="mainVideo" id=subtitle]]
[[!template text="for most content in Emacs." start="00:00:29.920" video="mainVideo" id=subtitle]]
[[!template text="Most interfaces we interact with" start="00:00:31.920" video="mainVideo" id=subtitle]]
[[!template text="consist of character based content" start="00:00:34.079" video="mainVideo" id=subtitle]]
[[!template text="in a buffer that's presented" start="00:00:36.239" video="mainVideo" id=subtitle]]
[[!template text="in a window in frame." start="00:00:38.239" video="mainVideo" id=subtitle]]
[[!template text="Although the underlying content" start="00:00:40.079" video="mainVideo" id=subtitle]]
[[!template text="may be textual, Emacs has capable APIs" start="00:00:41.520" video="mainVideo" id=subtitle]]
[[!template text="to present rich content." start="00:00:44.320" video="mainVideo" id=subtitle]]
[[!template text="The pervasiveness of buffers" start="00:00:47.680" video="mainVideo" id=subtitle]]
[[!template text="affords us wonderful flexibility." start="00:00:49.200" video="mainVideo" id=subtitle]]
[[!template text="This presentation, for instance," start="00:00:50.879" video="mainVideo" id=subtitle]]
[[!template text="is running in an Emacs buffer." start="00:00:52.559" video="mainVideo" id=subtitle]]
[[!template text="Using Emacs's built-in basic" start="00:00:55.520" video="mainVideo" id=subtitle]]
[[!template text="button library, we can insert" start="00:00:57.420" video="mainVideo" id=subtitle]]
[[!template text="an interactive button" start="00:00:59.199" video="mainVideo" id=subtitle]]
[[!template text="that shows a message" start="00:01:00.884" video="mainVideo" id=subtitle]]
[[!template text="in the minibuffer when clicked." start="00:01:01.760" video="mainVideo" id=subtitle]]
[[!template text="What about UIs that express application state?" start="00:01:06.080" video="mainVideo" id=subtitle]]
[[!template text="Most applications don't have a static UI." start="00:01:09.200" video="mainVideo" id=subtitle]]
[[!template text="As application state changes," start="00:01:11.439" video="mainVideo" id=subtitle]]
[[!template text="the UI should change" start="00:01:13.280" video="mainVideo" id=subtitle]]
[[!template text="to display the desired content." start="00:01:14.320" video="mainVideo" id=subtitle]]
[[!template text="One simplifying strategy is to simply" start="00:01:18.479" video="mainVideo" id=subtitle]]
[[!template text="re-render the entire UI upon any change." start="00:01:20.320" video="mainVideo" id=subtitle]]
[[!template text="First erase the contents of the buffer," start="00:01:23.600" video="mainVideo" id=subtitle]]
[[!template text="and then reinsert your UI again" start="00:01:25.680" video="mainVideo" id=subtitle]]
[[!template text="with desired changes," start="00:01:27.600" video="mainVideo" id=subtitle]]
[[!template text="and restore things like point and region." start="00:01:29.040" video="mainVideo" id=subtitle]]
[[!template text="Basic composition is possible" start="00:01:33.040" video="mainVideo" id=subtitle]]
[[!template text="with this approach." start="00:01:34.560" video="mainVideo" id=subtitle]]
[[!template text="Simply insert the elements" start="00:01:35.759" video="mainVideo" id=subtitle]]
[[!template text="of the UI in sequence." start="00:01:37.200" video="mainVideo" id=subtitle]]
[[!template text="Complex elements can be" start="00:01:39.280" video="mainVideo" id=subtitle]]
[[!template text="composed of multiple sub-elements." start="00:01:40.640" video="mainVideo" id=subtitle]]
[[!template text="UIs can be made extensible," start="00:01:44.320" video="mainVideo" id=subtitle]]
[[!template text="and expose this composition," start="00:01:45.840" video="mainVideo" id=subtitle]]
[[!template text="for example, with insertion hooks" start="00:01:47.040" video="mainVideo" id=subtitle]]
[[!template text="like magit's status sections hook." start="00:01:49.360" video="mainVideo" id=subtitle]]
[[!template text="This generally relies on elements" start="00:01:52.320" video="mainVideo" id=subtitle]]
[[!template text="being well-behaved inserting themselves," start="00:01:54.159" video="mainVideo" id=subtitle]]
[[!template text="not affecting the rest of the buffer." start="00:01:56.640" video="mainVideo" id=subtitle]]
[[!template text="If we find ourselves with complex UIs," start="00:02:00.399" video="mainVideo" id=subtitle]]
[[!template text="large buffers, long lines," start="00:02:02.960" video="mainVideo" id=subtitle]]
[[!template text="or poor rendering performance," start="00:02:04.640" video="mainVideo" id=subtitle]]
[[!template text="we might consider partial UI updates" start="00:02:06.320" video="mainVideo" id=subtitle]]
[[!template text="rather than re-rendering completely." start="00:02:09.039" video="mainVideo" id=subtitle]]
[[!template text="In that case, the complexity" start="00:02:11.360" video="mainVideo" id=subtitle]]
[[!template text="for maintaining the UI quickly increases." start="00:02:12.800" video="mainVideo" id=subtitle]]
[[!template text="As accessible as buffers are," start="00:02:15.840" video="mainVideo" id=subtitle]]
[[!template text="we don't have high level abstractions" start="00:02:17.360" video="mainVideo" id=subtitle]]
[[!template text="for managing portions of a UI" start="00:02:19.120" video="mainVideo" id=subtitle]]
[[!template text="rendered to a buffer." start="00:02:20.879" video="mainVideo" id=subtitle]]
[[!template text="(It) is left up to the programmers" start="00:02:22.160" video="mainVideo" id=subtitle]]
[[!template text="to track and update UI state." start="00:02:23.520" video="mainVideo" id=subtitle]]
[[!template text="This is generally done by" start="00:02:25.440" video="mainVideo" id=subtitle]]
[[!template text="one of two methods, reflection," start="00:02:26.540" video="mainVideo" id=subtitle]]
[[!template text="searching for strings or text properties" start="00:02:28.959" video="mainVideo" id=subtitle]]
[[!template text="within the buffer, or tracking segments" start="00:02:30.800" video="mainVideo" id=subtitle]]
[[!template text="of a UI buffer manually" start="00:02:34.239" video="mainVideo" id=subtitle]]
[[!template text="using numeric offsets, or marker," start="00:02:36.080" video="mainVideo" id=subtitle]]
[[!template text="or overlay objects." start="00:02:38.959" video="mainVideo" id=subtitle]]
[[!template text="Here we have a basic timer component" start="00:02:45.280" video="mainVideo" id=subtitle]]
[[!template text="that shows elapsed time" start="00:02:47.280" video="mainVideo" id=subtitle]]
[[!template text="after it's inserted." start="00:02:48.720" video="mainVideo" id=subtitle]]
[[!template text="It works, but has several problems." start="00:02:50.319" video="mainVideo" id=subtitle]]
[[!template text="It doesn't restore the user's point or mark," start="00:02:52.160" video="mainVideo" id=subtitle]]
[[!template text="so it snaps back after every render," start="00:02:55.519" video="mainVideo" id=subtitle]]
[[!template text="after every update." start="00:02:59.120" video="mainVideo" id=subtitle]]
[[!template text="It relies on singleton global state," start="00:03:01.040" video="mainVideo" id=subtitle]]
[[!template text="so isn't designed to coexist" start="00:03:03.360" video="mainVideo" id=subtitle]]
[[!template text="with other instances of itself." start="00:03:05.124" video="mainVideo" id=subtitle]]
[[!template text="It doesn't use a marker," start="00:03:12.000" video="mainVideo" id=subtitle]]
[[!template text="so it's sensitive to content" start="00:03:13.200" video="mainVideo" id=subtitle]]
[[!template text="proceeding it, that's following it," start="00:03:14.640" video="mainVideo" id=subtitle]]
[[!template text="changing in the buffer." start="00:03:16.239" video="mainVideo" id=subtitle]]
[[!template text="The update logic doesn't even consider" start="00:03:23.519" video="mainVideo" id=subtitle]]
[[!template text="which buffer it's trying to update." start="00:03:25.120" video="mainVideo" id=subtitle]]
[[!template text="If I switch buffers," start="00:03:26.799" video="mainVideo" id=subtitle]]
[[!template text="it will insert into another buffer," start="00:03:27.840" video="mainVideo" id=subtitle]]
[[!template text="or even the minibuffer." start="00:03:29.360" video="mainVideo" id=subtitle]]
[[!template text="It can't remove itself, or re-render" start="00:03:31.519" video="mainVideo" id=subtitle]]
[[!template text="if it gets corrupted, as you see." start="00:03:33.360" video="mainVideo" id=subtitle]]
[[!template text="All in all, it's not" start="00:03:34.879" video="mainVideo" id=subtitle]]
[[!template text="a readily composable component." start="00:03:35.920" video="mainVideo" id=subtitle]]
[[!template text="Addressing these components" start="00:03:38.400" video="mainVideo" id=subtitle]]
[[!template text="within this logic further increases" start="00:03:39.519" video="mainVideo" id=subtitle]]
[[!template text="the implementation complexity" start="00:03:41.920" video="mainVideo" id=subtitle]]
[[!template text="of this component," start="00:03:43.936" video="mainVideo" id=subtitle]]
[[!template text="and still this component" start="00:03:45.680" video="mainVideo" id=subtitle]]
[[!template text="would likely have" start="00:03:46.640" video="mainVideo" id=subtitle]]
[[!template text="various subtle differences" start="00:03:47.280" video="mainVideo" id=subtitle]]
[[!template text="with other components" start="00:03:49.120" video="mainVideo" id=subtitle]]
[[!template text="implemented by other authors." start="00:03:52.480" video="mainVideo" id=subtitle]]
[[!template text="For those of you unfamiliar" start="00:03:58.959" video="mainVideo" id=subtitle]]
[[!template text="with this term Yak Shaving," start="00:04:00.319" video="mainVideo" id=subtitle]]
[[!template text="that is a quite technical term" start="00:04:02.159" video="mainVideo" id=subtitle]]
[[!template text="for any seemingly pointless activity," start="00:04:04.080" video="mainVideo" id=subtitle]]
[[!template text="which is actually necessary" start="00:04:07.599" video="mainVideo" id=subtitle]]
[[!template text="to solve a problem," start="00:04:09.680" video="mainVideo" id=subtitle]]
[[!template text="which solves a problem," start="00:04:10.879" video="mainVideo" id=subtitle]]
[[!template text="which, several levels of recursion later," start="00:04:11.920" video="mainVideo" id=subtitle]]
[[!template text="solves the real problem you're working on." start="00:04:14.799" video="mainVideo" id=subtitle]]
[[!template text="The itch that led to this project" start="00:04:18.239" video="mainVideo" id=subtitle]]
[[!template text="was the desire to display a dense summary" start="00:04:19.943" video="mainVideo" id=subtitle]]
[[!template text="of local Git repository statuses." start="00:04:21.840" video="mainVideo" id=subtitle]]
[[!template text="Encountering various implementation" start="00:04:24.400" video="mainVideo" id=subtitle]]
[[!template text="complexity for building UI elements," start="00:04:26.560" video="mainVideo" id=subtitle]]
[[!template text="it led to the yak shaving endeavor" start="00:04:30.080" video="mainVideo" id=subtitle]]
[[!template text="that produced tui." start="00:04:31.680" video="mainVideo" id=subtitle]]
[[!template text="When I wrote the library," start="00:04:33.680" video="mainVideo" id=subtitle]]
[[!template text="I had recently played with" start="00:04:35.440" video="mainVideo" id=subtitle]]
[[!template text="a popular UI framework called React," start="00:04:36.479" video="mainVideo" id=subtitle]]
[[!template text="and had an interest in learning" start="00:04:39.360" video="mainVideo" id=subtitle]]
[[!template text="about the internal architecture of React." start="00:04:41.840" video="mainVideo" id=subtitle]]
[[!template text="So, rather than implement" start="00:04:44.080" video="mainVideo" id=subtitle]]
[[!template text="a string caching layer" start="00:04:45.680" video="mainVideo" id=subtitle]]
[[!template text="on top of tabulated list mode," start="00:04:46.960" video="mainVideo" id=subtitle]]
[[!template text="I was rather inclined" start="00:04:49.280" video="mainVideo" id=subtitle]]
[[!template text="to go down the path of implementing" start="00:04:50.360" video="mainVideo" id=subtitle]]
[[!template text="the React API for Emacs Lisp." start="00:04:52.400" video="mainVideo" id=subtitle]]
[[!template text="I'll offer a brief view of" start="00:04:58.960" video="mainVideo" id=subtitle]]
[[!template text="the tui Emacs Lisp API." start="00:05:00.896" video="mainVideo" id=subtitle]]
[[!template text="Inserting component content" start="00:05:05.120" video="mainVideo" id=subtitle]]
[[!template text="is pretty straightforward." start="00:05:07.360" video="mainVideo" id=subtitle]]
[[!template text="You take a component tree" start="00:05:08.320" video="mainVideo" id=subtitle]]
[[!template text="and render it in an Emacs buffer." start="00:05:10.160" video="mainVideo" id=subtitle]]
[[!template text="If any elements in that tree are updated," start="00:05:16.240" video="mainVideo" id=subtitle]]
[[!template text="their respective content on the tree" start="00:05:18.639" video="mainVideo" id=subtitle]]
[[!template text="is updated automatically." start="00:05:21.039" video="mainVideo" id=subtitle]]
[[!template text="Here's a basic re-implementation" start="00:05:26.320" video="mainVideo" id=subtitle]]
[[!template text="of the straw man timer from earlier," start="00:05:27.919" video="mainVideo" id=subtitle]]
[[!template text="using a macro for syntactic trigger." start="00:05:29.919" video="mainVideo" id=subtitle]]
[[!template text="You'll notice that" start="00:05:32.400" video="mainVideo" id=subtitle]]
[[!template text="the signature includes its own" start="00:05:34.404" video="mainVideo" id=subtitle]]
[[!template text="object reference, arguments, and state." start="00:05:36.164" video="mainVideo" id=subtitle]]
[[!template text="Associating arguments in the state" start="00:05:44.560" video="mainVideo" id=subtitle]]
[[!template text="with a component instance out of the box," start="00:05:46.400" video="mainVideo" id=subtitle]]
[[!template text="makes it easy to design reusable components," start="00:05:51.360" video="mainVideo" id=subtitle]]
[[!template text="and forms the basis for partial UI updates." start="00:05:54.400" video="mainVideo" id=subtitle]]
[[!template text="The component rendering anchors" start="00:06:06.080" video="mainVideo" id=subtitle]]
[[!template text="are durable, so content can be" start="00:06:07.840" video="mainVideo" id=subtitle]]
[[!template text="added and removed surrounding content," start="00:06:09.199" video="mainVideo" id=subtitle]]
[[!template text="or even within the region" start="00:06:11.360" video="mainVideo" id=subtitle]]
[[!template text="of the component," start="00:06:12.479" video="mainVideo" id=subtitle]]
[[!template text="and replaced when it re-renders." start="00:06:13.280" video="mainVideo" id=subtitle]]
[[!template text="Components will also" start="00:06:16.319" video="mainVideo" id=subtitle]]
[[!template text="cleanly remove themselves from a buffer" start="00:06:17.600" video="mainVideo" id=subtitle]]
[[!template text="when instructed to." start="00:06:20.880" video="mainVideo" id=subtitle]]
[[!template text="tui contains the core implementation" start="00:06:28.400" video="mainVideo" id=subtitle]]
[[!template text="of the React API, so components," start="00:06:30.160" video="mainVideo" id=subtitle]]
[[!template text="their constituent props, state," start="00:06:33.440" video="mainVideo" id=subtitle]]
[[!template text="and all of the lifecycle methods" start="00:06:35.840" video="mainVideo" id=subtitle]]
[[!template text="associated with them," start="00:06:38.000" video="mainVideo" id=subtitle]]
[[!template text="as well as keys, refs," start="00:06:39.440" video="mainVideo" id=subtitle]]
[[!template text="and the fundamental" start="00:06:41.120" video="mainVideo" id=subtitle]]
[[!template text="reconciliation algorithm of React." start="00:06:43.228" video="mainVideo" id=subtitle]]
[[!template text="A variety of other React APIs" start="00:06:47.520" video="mainVideo" id=subtitle]]
[[!template text="that haven't been implemented yet." start="00:06:52.188" video="mainVideo" id=subtitle]]
[[!template text="It contains some useful features so far," start="00:06:58.080" video="mainVideo" id=subtitle]]
[[!template text="such as hot reloading, reflection," start="00:07:00.080" video="mainVideo" id=subtitle]]
[[!template text="and various debugging tools," start="00:07:02.639" video="mainVideo" id=subtitle]]
[[!template text="and some reconciliation logging." start="00:07:06.164" video="mainVideo" id=subtitle]]
[[!template text="Lastly, I'd like to give you some quick" start="00:07:12.639" video="mainVideo" id=subtitle]]
[[!template text="visual taste of components built with tui." start="00:07:14.880" video="mainVideo" id=subtitle]]
[[!template text="The grid view that motivated" start="00:07:19.039" video="mainVideo" id=subtitle]]
[[!template text="my development of this package" start="00:07:20.240" video="mainVideo" id=subtitle]]
[[!template text="is very similar to Magit's" start="00:07:21.520" video="mainVideo" id=subtitle]]
[[!template text="list repositories functionality." start="00:07:23.039" video="mainVideo" id=subtitle]]
[[!template text="Essentially, tabulated list mode" start="00:07:30.720" video="mainVideo" id=subtitle]]
[[!template text="but portable and has a separated model" start="00:07:36.080" video="mainVideo" id=subtitle]]
[[!template text="and presentation layers." start="00:07:39.440" video="mainVideo" id=subtitle]]
[[!template text="Here's a basic xkcd comic viewer" start="00:07:49.360" video="mainVideo" id=subtitle]]
[[!template text="showing a couple classics." start="00:07:51.840" video="mainVideo" id=subtitle]]
[[!template text="A long-standing React tutorial is" start="00:08:07.360" video="mainVideo" id=subtitle]]
[[!template text="building a tic-tac-toe game" start="00:08:10.080" video="mainVideo" id=subtitle]]
[[!template text="as a bit of a gimmick," start="00:08:13.280" video="mainVideo" id=subtitle]]
[[!template text="and I'm not quite satisfied with" start="00:08:14.879" video="mainVideo" id=subtitle]]
[[!template text="the buffering direction," start="00:08:17.039" video="mainVideo" id=subtitle]]
[[!template text="but it got me thinking about" start="00:08:25.599" video="mainVideo" id=subtitle]]
[[!template text="layout engines with text," start="00:08:27.120" video="mainVideo" id=subtitle]]
[[!template text="so it was interesting." start="00:08:28.639" video="mainVideo" id=subtitle]]
[[!template text="And here's a small" start="00:08:35.120" video="mainVideo" id=subtitle]]
[[!template text="Unicode character viewer" start="00:08:38.560" video="mainVideo" id=subtitle]]
[[!template text="capable of showing a bunch of characters." start="00:08:46.080" video="mainVideo" id=subtitle]]
[[!template text="If this piques your interest," start="00:08:55.279" video="mainVideo" id=subtitle]]
[[!template text="I would encourage you to check it out." start="00:08:57.279" video="mainVideo" id=subtitle]]
[[!template text="tui should be usable by anyone" start="00:08:59.200" video="mainVideo" id=subtitle]]
[[!template text="with some basic Elisp familiarity," start="00:09:01.440" video="mainVideo" id=subtitle]]
[[!template text="no prior knowledge about JavaScript" start="00:09:04.640" video="mainVideo" id=subtitle]]
[[!template text="or React is necessary." start="00:09:09.680" video="mainVideo" id=subtitle]]
[[!template text="I'd absolutely love to talk with people" start="00:09:12.080" video="mainVideo" id=subtitle]]
[[!template text="about the tui package," start="00:09:13.732" video="mainVideo" id=subtitle]]
[[!template text="textual user interfaces in general," start="00:09:14.880" video="mainVideo" id=subtitle]]
[[!template text="and really anything in Emacs." start="00:09:17.440" video="mainVideo" id=subtitle]]
[[!template text="If you have any ideas, feedback," start="00:09:19.040" video="mainVideo" id=subtitle]]
[[!template text="or want to contribute," start="00:09:20.693" video="mainVideo" id=subtitle]]
[[!template text="please reach out." start="00:09:21.680" video="mainVideo" id=subtitle]]
[[!template text="Thank you all for listening." start="00:09:23.360" video="mainVideo" id=subtitle]]
[[!template text="captions by bhavin192 (Bhavin Gandhi)" start="00:09:24.360" video="mainVideo" id=subtitle]]