diff -uNr a/yrc/codemap.txt b/yrc/codemap.txt --- a/yrc/codemap.txt 2782c85d3fb82c2633b790aa0d6ff05fe4357652015cbdd6c90b0f31354ee20b2c21d3ec696968730c95390abbe7fb4033da19142eb4b0f2edd890cc7130843d +++ b/yrc/codemap.txt 0e94d9aa6d76e3fb86f020d2e9dda5aa8a772c0ec01844cea75eb9c53e70b0c8c24ce5af1c3a9bb8336e8d974b45011d805ac6cdf109a18623d8e5edd8ee8ac3 @@ -140,7 +140,6 @@ variant_args(val) -> list matcher(vtype, cases: iterable of (constructor, receiver: function of (*args -> x))) -> function of (val: vtype -> x) sequence(*thunks) -> thunk -char_range(pair) -> str partition(list, pred) -> (left: list, right: list) split_pair(str, sep=' ': str) -> [str, str] make_encoder(function of chr -> str) -> function of (str -> str) @@ -172,6 +171,8 @@ add_scroll_coords(lines: list of str, coords: (int, int), delta: int) -> (int, int) sub_scroll_coords(lines: list of str, coords: (int, int), delta: int) -> (int, int) render_lines(lines: list of str, vscroll: (int, int), row_limit: int) -> (list, int) +is_nick_start(chr) -> bool +is_nick_body(chr) -> bool build_msg(prefix, cmd, params) -> str max_param_len(cmd, prefix=None) -> int parse_msg(msg) -> (prefix: str | None, cmd: str, params: list of str) / ProtocolError diff -uNr a/yrc/manifest b/yrc/manifest --- a/yrc/manifest a6d6ef544b68b096039990e51d0e492fc2a6e2de387d32331cdf0408a22c741b5466166b3ccb48601e921546fe1c1111f7e69dd89ffc369d868d8bcbad20b13a +++ b/yrc/manifest aa28414c9b81b228d2eb2972d968fba0c03b9bc2e621cc3bc390e8e65b580015602fcd07f990ea546042512dd4ec558599ad1ac4f36be9119fc61a72941c6c5e @@ -8,3 +8,4 @@ 768777 yrc_minor_command_reorder_2 jfw Reverse presentation order of back/forward prompt commands for consistency; also comment on possibly confusing differences between ctrl/meta functions. 768777 yrc_word_level_commands jfw Implement word-level motions and kills. A new global flag is needed for state tracking to coalesce multiple sequential kills into one. kill_start and kill_end are rebased on a common kill_range routine which also supports the new word-level variants. 768778 yrc_reindent_docs jfw Reindent spaces to tabs in documentation. (In README.txt, indentation levels are reduced across the board.) +769932 yrc_minor_char_refactors jfw Use backspace character code from yterm rather than showing it in long form. Replace char_range() with simple character classifier functions (consistent with the existing ones and potentially faster than string membership tests). Add citations for some strange IRC character classifications (which came up when looking into how to delimit completion prefixes). diff -uNr a/yrc/yrc.py b/yrc/yrc.py --- a/yrc/yrc.py 017a6a4667f1a9b6a1a0b3a9ef272b70cef6c8943bf9cb674d849071bd7374a8c4ce98a5fc850106200971ae2ff3b60a32ce6e64fabe6cef0dc6e62f908ed3e1 +++ b/yrc/yrc.py cbeab6de181f2551f99c55c00e787be652adf191a06e937a98c3a01ba4086737c6d193843e5cd6d51f65e5688d0e90256fd00f99a61d404148e93e9b2cdb9f1e @@ -102,7 +102,7 @@ ctrl('N'): 'history-next', DOWN: 'history-next', - ctrl('H'): 'prompt-backspace', + BS: 'prompt-backspace', ctrl('?'): 'prompt-backspace', ctrl('D'): 'prompt-delete', @@ -112,7 +112,7 @@ ctrl('K'): 'kill-end', - meta(ctrl('H')): 'kill-back-word', + meta(BS): 'kill-back-word', meta(ctrl('?')): 'kill-back-word', meta('d'): 'kill-forward-word', @@ -286,10 +286,6 @@ f() return run -def char_range(pair): - a, b = pair - return ''.join(map(chr, range(ord(a), ord(b) + 1))) - def partition(l, pred): left = [] right = [] @@ -1669,14 +1665,16 @@ MAX_NICK_LEN = 31 IRC_ILLEGAL = NUL + CR + LF +# Oddly, HT or other controls are allowed in chan names by both rfc1459 and rfc2812. CHAN_ILLEGAL = IRC_ILLEGAL + BEL + ' ,:' +# '+!' are found in rfc2812 but not rfc1459. CHAN_START = '&#+!' +# rfc1459 allows -[]\`^{} in nicks but requires a letter to start. +# rfc2812 allows specials at start too except for '-', and adds '_|'. IRC_SPECIAL = '[]\\`_^{|}' -LETTER = char_range('AZ') + char_range('az') -DIGIT = char_range('09') -NICK_START = LETTER + IRC_SPECIAL -NICK_BODY = NICK_START + DIGIT + '-' +is_nick_start = lambda c: is_alpha(c) or c in IRC_SPECIAL +is_nick_body = lambda c: is_nick_start(c) or is_digit(c) or c == '-' class ProtocolError(Exception): pass @@ -1740,8 +1738,8 @@ def valid_nick(n): return 0 < len(n) <= MAX_NICK_LEN \ - and n[0] in NICK_START \ - and all(c in NICK_BODY for c in n[1:]) + and is_nick_start(n[0]) \ + and all(is_nick_body(c) for c in n[1:]) def valid_password(p): return p is None or (