+ ("001" ; RPL_WELCOME
+ (let* ((params (murk-msg-params msg))
+ (nick (elt params 0))
+ (text (string-join (seq-drop params 1) " ")))
+ (murk-set-connection-nick server nick)
+ (murk-display-notice nil text)))
+
+ ("353" ; NAMEREPLY
+ (let* ((params (murk-msg-params msg))
+ (channel (elt params 2))
+ (names (split-string (elt params 3)))
+ (ctx (murk-get-context server channel)))
+ (if ctx
+ (murk-add-context-users ctx names)
+ (murk-display-notice nil "Users in " channel
+ ": " (string-join names " ")))))
+
+ ("366" ; ENDOFNAMES
+ (let* ((params (murk-msg-params msg))
+ (channel (elt params 1))
+ (ctx (murk-get-context server channel)))
+ (if ctx
+ (murk-display-notice
+ ctx
+ (murk--as-string (length (murk-context-users ctx)))
+ " users in " channel)
+ (murk-display-notice nil "End of " channel " names list."))))
+
+ ("331" ; RPL_NOTOPIC
+ (let* ((params (murk-msg-params msg))
+ (channel (elt params 1))
+ (ctx (murk-get-context server channel)))
+ (murk-display-notice ctx "No topic set.")))
+
+ ("332" ; RPL_TOPIC
+ (let* ((params (murk-msg-params msg))
+ (channel (elt params 1))
+ (topic (elt params 2))
+ (ctx (murk-get-context server channel)))
+ (murk-display-notice ctx "Topic: " topic)))
+
+ ((rx (= 3 (any digit)))
+ (murk-display-notice nil (mapconcat 'identity (cdr (murk-msg-params msg)) " ")))
+
+ ((and "JOIN"
+ (guard (equal (murk-connection-nick server)
+ (murk-msg-src msg))))
+ (let ((channel (car (murk-msg-params msg))))
+ (murk-add-context (list server channel nil))
+ (murk-display-notice (murk-current-context)
+ "Joining channel " channel " on " server)
+ (murk-render-prompt)))
+
+ ("JOIN"
+ (let* ((channel (car (murk-msg-params msg)))
+ (nick (murk-msg-src msg))
+ (ctx (murk-get-context server channel)))
+ (murk-add-context-users ctx (list nick))
+ (if murk-show-joins
+ (murk-display-notice ctx nick " joined channel " channel
+ " on " server))))
+
+ ((and "PART"
+ (guard (equal (murk-connection-nick server)
+ (murk-msg-src msg))))
+ (let ((channel (car (murk-msg-params msg))))
+ (murk-display-notice (murk-current-context) "Left channel " channel)
+ (murk-remove-context (list server channel))
+ (murk-render-prompt)))
+
+ ("PART"
+ (let* ((channel (car (murk-msg-params msg)))
+ (nick (murk-msg-src msg))
+ (ctx (murk-get-context server channel)))
+ (murk-del-context-user ctx nick)
+ (if murk-show-joins
+ (murk-display-notice ctx nick " left channel " channel
+ " on " server))))
+
+ ((and "NICK"
+ (guard (equal (murk-connection-nick server)
+ (murk-msg-src msg))))
+ (let ((new-nick (car (murk-msg-params msg)))
+ (old-nick (murk-connection-nick server)))
+ (murk-set-connection-nick server new-nick)
+ (murk-rename-server-user server old-nick new-nick)
+ (murk-display-notice nil "Nick set to " new-nick " on " server)))
+
+ ("NICK"
+ (let ((old-nick (murk-msg-src msg))
+ (new-nick (car (murk-msg-params msg))))
+ (murk-display-notice nil old-nick " is now known as " new-nick
+ " on " server)
+ (murk-rename-server-user server old-nick new-nick)))
+
+ ("TOPIC"
+ (let ((channel (car (murk-msg-params msg)))
+ (nick (murk-msg-src msg))
+ (topic (cadr (murk-msg-params msg))))
+ (murk-display-notice (murk-get-context server channel)
+ nick " set the topic: " topic)))
+
+ ("QUIT"
+ (let ((nick (murk-msg-src msg))
+ (reason (mapconcat 'identity (murk-msg-params msg) " ")))
+ (murk-del-server-user server nick)
+ (if murk-show-joins
+ (murk-display-notice nil nick " quit: " reason))))
+
+ ("PRIVMSG"
+ (let* ((from (murk-msg-src msg))
+ (params (murk-msg-params msg))
+ (to (car params))
+ (text (cadr params)))
+ (pcase text
+ ("\01VERSION\01"
+ (let ((version-string (concat murk-version " - running on GNU Emacs " emacs-version)))
+ (murk-send-msg server
+ (murk-msg nil nil "NOTICE"
+ (list from (concat "\01VERSION "
+ version-string
+ "\01")))))
+ (murk-display-notice nil "CTCP version request received from "
+ from " on " server))
+
+ ((rx (let ping (: "\01PING " (* (not "\01")) "\01")))
+ (murk-send-msg server (murk-msg nil nil "NOTICE" (list from ping)))
+ (murk-display-notice nil "CTCP ping received from " from " on " server))
+
+ ("\01USERINFO\01"
+ (murk-display-notice nil "CTCP userinfo request from " from
+ " on " server " (no response sent)"))
+
+ ("\01CLIENTINFO\01"
+ (murk-display-notice nil "CTCP clientinfo request from " from
+ " on " server " (no response sent)"))
+
+ ((rx (: "\01ACTION " (let action-text (* (not "\01"))) "\01"))
+ (murk-display-action server from to action-text))
+
+ (_
+ (murk-display-message server from to text)))))
+