diff -uNr a/yrc/manifest b/yrc/manifest --- a/yrc/manifest 5ad53d0721b60a070f835e28a56823c617ecf4b7d14878cad6f391ef3410b9b1cbd3a3d3b4133f1878ee7efcab58608f80f24a07112ee81ab53daee03fddae55 +++ b/yrc/manifest edaf7788db3a0a461b684665d5f4305e706a50d74f204adbc447d5034bb2d34ebccdda3d0f9ce42d2b0545422a9f682638a420f28a2eda491b3933136af30e15 @@ -11,3 +11,4 @@ 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). 769934 yrc_completion jfw Implement tab completion for nicks, channels and slash commands. Relatedly: factor out the now common case of inserting multiple characters into the prompt at once, as insert_multi; correct rfind_word_start and find_word_end to always return a valid cursor position (empty returns previously happened to work due to obscure details of None handling); turn the leading slash into a proper part of slash command names, facilitating completion and better distinguishing them from keyboard commands. (Slash commands without parameters could in theory still be given key mappings, but the normal keyboard editing & scrolling commands make little sense to type at the prompt and are no longer recognized there.) 769938 yrc_net_level_commands jfw Implement /close-net and /reconnect commands, and straighten out which commands can take a part/quit message. A reliable QUIT message *could* be implemented for /disconnect and /close-net (unlike for /quit), so make space to add it there by dropping the optional network name argument from /disconnect, which I found to be more confusing than helpful anyway. +769940 yrc_connect_join_streamlining jfw Switch to network window on connect and channel window on join. Remove self-generated join/part info messages which route distractingly to the network window (the more useful server confirmations still show in the channel's own window and log). Send a new USER command when changing nick in the connected-unregistered state, since I found it necessary for multiple server implementations when nick is in use. diff -uNr a/yrc/yrc.py b/yrc/yrc.py --- a/yrc/yrc.py 8c8be23b92366ffdfe83aa47802ff738e43be93a40495265e1303eecd35fb84cdcd1b3ba8796da2264d4ea82dd8257d02513b8eb6f1794a85d1024efa106292b +++ b/yrc/yrc.py 754c6f8cb82674313eaa78bdd8d7736dd6fc7340c69526518ec7d53550719913a1c9bd338610eb342bd790cb4343937da4942f532a331345fd42fc3c66568e22 @@ -1561,7 +1561,9 @@ raise CommandError( 'connect: illegal character in password for %s' % net) - conn_start(new_conn(net, addrs, nick, pw)) + c = new_conn(net, addrs, nick, pw) + conn_start(c) + buflist_select(get_buf(conn_network(c), None)) @command('/disconnect') def disconnect_cmd(): @@ -1574,7 +1576,9 @@ def join_cmd(chan, key=None): if not valid_chan(chan): raise CommandError('join: bad channel name: %s' % chan) - conn_join(buf_registered_conn(cur_buf), chan, key) + c = buf_registered_conn(cur_buf) + conn_join(c, chan, key) + buflist_select(get_buf(chan, conn_network(c))) @command('/kick', 1, extended_arg=True) def kick_cmd(user, msg=''): @@ -1616,13 +1620,16 @@ conn_set_nick(c, nick) conn_info(c, 'nick changed to %s for next reconnection' % nick) else: + conn_send(c, 'NICK', [nick]) if not conn_registered(c): + # Undocumented, but in practice the first USER gets ignored if the NICK was rejected, so we have to resend when changing nick or else we get stuck with incomplete registration (no welcome). + conn_send(c, 'USER', [nick, '0', '*', nick]) schedule_status_draw() conn_set_nick(c, nick) conn_info(c, 'nick changed to %s' % nick) conn_set_ping_ts(c, mono_time()) conn_run_in(c, PING_TIMEOUT, conn_reg_timeout) - conn_send(c, 'NICK', [nick]) + # If we *are* registered then don't update nick internally yet, rather wait for server acknowlegement. Unfortunately until then we don't know which nick our messages will be seen to come from (because the change can be rejected). For figuring the message length limit we could use the longer of the two. @command('/part', extended_arg=True) def part_cmd(msg=''): @@ -2176,7 +2183,6 @@ try: if me: del channels_dict[chan_lc] - conn_info(c, 'parted %s' % chan) schedule_status_draw() else: channels_dict[chan_lc].remove(sender_lc) @@ -2309,7 +2315,6 @@ }.get(cmd, unknown_command)() def conn_join(c, chan, key=None): - conn_info(c, 'joining %s' % chan) conn_send(c, 'JOIN', [chan] if key is None else [chan, key]) def conn_privmsg(c, target, msg):