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 |