Projects : yrc : yrc_genesis
1 | Record types |
2 | ============ |
3 | |
4 | conn |
5 | - network: file-safe str |
6 | - sock: socket |
7 | - rdbuf: str |
8 | - wrbuf: str |
9 | - addrs: non-empty list of (host: str, port: int) (first entry is current) |
10 | - nick: str |
11 | - password: str | None |
12 | - registered: bool |
13 | - channels: dict of (channel: casemapped str) => (set of nick: casemapped str) |
14 | - casemapper: function of (str -> casemapped str) |
15 | - reconn_delay: int |
16 | - count: int (number of times connected) |
17 | - ping_ts: float (monotonic time of last sent ping) |
18 | - pong_ts: float (monotonic time of last received pong) |
19 | |
20 | buf |
21 | - name: str |
22 | - parent: buf |
23 | - title: str |
24 | - vscroll: int |
25 | - lines: list of str |
26 | - num_read: int |
27 | - at_end: bool |
28 | |
29 | buflist (singleton) |
30 | - vscroll: int |
31 | - width: int |
32 | - selection: buf |
33 | - cursor: buf |
34 | - last: buf |
35 | |
36 | prompt (singleton) |
37 | - chars: list of str |
38 | - cursor: int |
39 | - hscroll: int |
40 | |
41 | flags (singleton) |
42 | - refresh |
43 | - redraw |
44 | - buflist_draw |
45 | - buf_draw |
46 | - prompt_draw |
47 | - status_draw |
48 | - quit |
49 | - buflist |
50 | - prompt |
51 | - ping_draw |
52 | |
53 | Enumerations |
54 | ============ |
55 | |
56 | kbd_state: ks_start ks_cx ks_esc ks_cseq ks_cs_intermed |
57 | |
58 | Variant types |
59 | ============= |
60 | |
61 | message: (args all str unless noted) |
62 | - m_privmsg(sender, msg) |
63 | - m_notice(sender, msg) |
64 | - m_join(sender, chan) |
65 | - m_part(sender, chan, msg) |
66 | - m_quit(sender, msg) |
67 | - m_nick(sender, nick) |
68 | - m_kick(sender, chan, name, msg) |
69 | - m_kicked(sender, chan, msg) |
70 | - m_topic(sender, topic: str | None) |
71 | - m_chantopic(sender, chan, topic: str | None) |
72 | - m_mode(sender, modes) |
73 | - m_chanmode(sender, chan, modes) |
74 | - m_names(sender, chan, names) |
75 | - m_endnames(sender, chan) |
76 | - m_error(sender, msg) |
77 | - m_client(msg) |
78 | - m_server(sender, msg) |
79 | |
80 | Quasiconstants |
81 | ============== |
82 | |
83 | self_pipe_rd: int |
84 | self_pipe_wr: int |
85 | |
86 | Global state |
87 | ============ |
88 | |
89 | cur_buf: buf |
90 | scr_height: int |
91 | scr_width: int |
92 | mono_last: float |
93 | mono_offset: float |
94 | out_buf: bytearray |
95 | kbd_accum: bytearray |
96 | kbd_state: function |
97 | |
98 | Collections |
99 | =========== |
100 | |
101 | commands: (name: str) => function |
102 | buffers: non-empty list of buf |
103 | buffer_index: (name: str, parent_name: str) => buf |
104 | opening_conns: (fileno: int) => conn |
105 | open_conns: (fileno: int) => conn |
106 | network_conns: (network: str) => conn : all enabled networks, whether TCP alive or not |
107 | schedule: min-heap of (time: float) => thunk |
108 | |
109 | Functions |
110 | ========= |
111 | |
112 | Excluding record constructors, accessors and basic mutators. |
113 | |
114 | Startup only: |
115 | command(name: str, min_args=0: int, max_args=None: int | None, extended_arg=False: bool)(function) -> function |
116 | check_command_dicts(keymap) |
117 | make_casemapper(int) -> function of (str -> casemapped str) |
118 | |
119 | Boring: |
120 | set_nonblock |
121 | |
122 | Pure functions: |
123 | format_time(time_tuple) -> str |
124 | is_ctrl(chr) -> bool |
125 | ctrl(chr) -> chr |
126 | is_meta(chr) -> bool |
127 | meta(chr) -> chr |
128 | variant_name(val) -> str |
129 | variant_args(val) -> list |
130 | matcher(vtype, cases: iterable of (constructor, receiver: function of (*args -> x))) -> function of (val: vtype -> x) |
131 | sequence(*thunks) -> thunk |
132 | flatten(iterable of iterable) -> iterable |
133 | char_range(pair) -> str |
134 | partition(list, pred) -> (left: list, right: list) |
135 | split_pair(str, sep=' ': str) -> [str, str] |
136 | make_encoder(function of chr -> str) -> function of (str -> str) |
137 | asciify(str) -> str |
138 | fs_encode(str) -> str |
139 | casemap_ascii(str) -> str |
140 | clip(min: comparable, max: comparable, comparable) -> comparable |
141 | clip_to(list, int) -> int |
142 | get_clipped(list, int) -> element of list |
143 | clip_str(str, width: int) -> str |
144 | pad_or_clip_str(str, width: int, pad=' ': chr) -> str |
145 | wrap(line, width, indent=0) -> list of str |
146 | is_digit(chr) -> bool |
147 | parse_address(addr) -> (host: str, port: int) / ValueError |
148 | format_address((host: str, port: int)) -> str |
149 | int_of_bytes(str) -> int |
150 | heap_peek(heap: list) -> (key, value) / IndexError |
151 | safe_filename(name) -> bool |
152 | config_lines(text) -> non-empty list of non-empty str | None |
153 | format_buf_msg(val: message) -> str |
154 | render_lines(lines: list of str, width: int, start: int, row_limit: int) -> (list of list, int) |
155 | build_msg(prefix, cmd, params) -> str |
156 | max_param_len(cmd, prefix=None) -> int |
157 | parse_msg(msg) -> (prefix: str | None, cmd: str, params: list of str) / ProtocolError |
158 | is_chan(str) -> bool |
159 | valid_chan(str) -> bool |
160 | valid_nick(str) -> bool |
161 | valid_password(str) -> bool |
162 | conn_nick_lc(conn) -> casemapped str |
163 | sender_nick(str) -> str |
164 | arg2 |
165 | arg3 |
166 | empty2 |
167 | lterr / TypeError |
168 | format_log_msg(val: message except (m_chantopic | m_mode | m_client)) -> str |
169 | |
170 | Pure I/O: |
171 | write_all(blocking fd, str|bytearray) / EnvironmentError |
172 | read_all(nonblocking fd) -> str / EOFError, EnvironmentError : may return empty |
173 | |
174 | Pure drawing: |
175 | buf_draw(buf) |
176 | prompt_draw |
177 | draw_status(y: int) |
178 | buflist_draw |
179 | buflist_vline_draw |
180 | place_cursor |
181 | refresh_if_needed |
182 | |
183 | "Queries": |
184 | find_buf(buf) -> int : find buf's index in buffers list |
185 | #buf_network(buf) -> str |
186 | buf_conn(buf) -> conn / CommandError |
187 | buf_registered_conn(buf) -> conn / CommandError |
188 | get_config(key, paths=(()), default=None) -> str | default |
189 | |
190 | Side effects on data: |
191 | write_out(str) : stores for write to terminal |
192 | flush_out : sends full terminal output buffer |
193 | variant(vtype, name: str, nargs: int) -> constructor: function of (*args -> (tag, args)) |
194 | rand_int(int) -> int |
195 | heap_insert(heap: list, key: comparable, value) |
196 | heap_extract(heap: list) -> (key, value) / IndexError |
197 | run_command(line: str) -> * / CommandError |
198 | buf_log_msg(buf, m: message) |
199 | buf_privmsg(buf, msg: str) : buf_parent ; buf_registered_conn ; conn_privmsg / CommandError |
200 | check_buf_at_end : buf_set_at_end(cur_buf) | buf_clr_at_end(cur_buf) |
201 | is_child_of(buf) -> function of (buf -> bool) |
202 | sort_buffers : sorts buffers & generates buffer_index |
203 | get_buf(name, parent_name) -> buf : buffer_index lookup but creates if not found |
204 | close_buf(buf) |
205 | prompt_insert(chr) |
206 | prompt_delete |
207 | prompt_backspace |
208 | prompt_submit |
209 | info(msg: str, buf=None) : buf_log_msg to buf or buffers[0] |
210 | error(msg_or_exc: str | Exception, buf=None) : buf_log_msg to buf or buffers[0] |
211 | kaccum(str) |
212 | kaccept(str) |
213 | ktrans(kbd_state) |
214 | ks_start(chr) |
215 | ks_cx(chr) |
216 | ks_esc(chr) |
217 | ks_cseq(chr) |
218 | ks_cs_intermed(chr) |
219 | conn_run_in(conn, seconds: float, method: function of (conn), run_if_down=False) : run_in |
220 | conn_log_msg(conn, venue: casemapped str | None, m: message) : get_buf ; buf_log_msg ; file_log_msg |
221 | conn_info(conn, str) : uses conn_log_msg |
222 | conn_error(conn, str) : uses conn_log_msg |
223 | conn_start(conn) : starts connecting; bumps count; rotates addrs; adds to opening_conns and network_conns |
224 | conn_write(conn, str) : stores for nonblocking write by main loop |
225 | conn_send(conn, cmd: str, params: list of str, prefix=None: str) : build_msg ;conn_write (TODO check msg well-formedness) |
226 | conn_handle_connected(conn) : if successful, moves c from opening_conns to open_conns & sends login |
227 | conn_close(conn) : shuts down and removes from open_conns |
228 | conn_handle_data(conn, data: str) : does input buffering; extracts messages and calls... |
229 | conn_handle_msg(conn, msg: str) : mega-function for handling IRC commands |
230 | conn_join(conn, chan: str, key=None) : conn_info ; conn_send |
231 | conn_privmsg(conn, target: str, msg: str) : conn_log_msg ; conn_send |
232 | conn_ping(conn) |
233 | conn_timeout(conn) |
234 | conn_reg_timeout(conn) |
235 | file_log_msg(network: file-safe str, venue: casemapped str | None, m: message) |
236 | handle_resize |
237 | mono_time -> float |
238 | run_in(seconds, thunk) |
239 | |
240 | Slash commands: |
241 | quit_cmd |
242 | connect_cmd |
243 | disconnect_cmd |
244 | join_cmd |
245 | kick_cmd |
246 | mode_cmd |
247 | nick_cmd |
248 | part_cmd |
249 | send_cmd |
250 | |
251 | Lifecycle: |
252 | main |
253 | crash_handler |
254 | |
255 | MVP: |
256 | finish commands |
257 | close/close-net debug |
258 | prefix case sensitivity in conn_handle_msg? |
259 | |
260 | TODO: |
261 | nick fallback |
262 | buflist vscroll |
263 | modes |
264 | date changes |
265 | prompt history, kill ring |
266 | tab completion (but how to focus buf/prompt?) |
267 | username, realname |
268 | logging |
269 | bold nicks (generally: formatted wrap) |
270 | search in scrollback |
271 | channel key (config, persist across reconnect) |
272 | buffer cleanup by category |
273 | help |
274 | scripting |
275 | self-ping to find user@host to calc max privmsg length |
276 | Proliferation of casemapping is bound to be buggy. |
277 | Recognize WHOIS/WHOWAS/LIST responses |
278 | bracketed paste |
279 | |
280 | Possible cleanups: |
281 | more use of lambda/sequence for trivial functions |
282 | rename buf* to wind* to match manual's terminology (nobody but emacs uses "buffer" to mean "window"...) |
283 | move cur_buf global to a buflist attribute |
284 | use the new scheduler for schedule_*; use delayed redraw to perform well under message floods |