+ (concat
+ (if (murk-network-context-p ctx)
+ ""
+ (concat (murk-context-channel ctx) "@"))
+ (murk-context-network ctx)))
+
+(defun murk-string->context (string)
+ (if (not (string-prefix-p "#" string))
+ (murk-get-context string)
+ (let* ((parts (string-split string "@"))
+ (channel (elt parts 0))
+ (network (elt parts 1)))
+ (murk-get-context network channel))))
+
+(defun murk-get-context (network &optional channel)
+ (if (and channel (string-prefix-p "#" channel))
+ (let ((test-ctx (list network channel)))
+ (seq-find (lambda (ctx)
+ (equal (seq-take ctx 2) test-ctx))
+ murk-contexts))
+ (car (member (list network) murk-contexts))))
+
+(defun murk-cycle-contexts (&optional reverse)
+ (setq murk-contexts
+ (if reverse
+ (let ((nminus1 (- (length murk-contexts) 1)))
+ (cons
+ (elt murk-contexts nminus1)
+ (seq-take murk-contexts nminus1)))
+ (append (cdr murk-contexts) (list (car murk-contexts))))))
+
+(defun murk-switch-to-context (ctx)
+ (setq murk-contexts
+ (let* ((new-head (memq ctx murk-contexts))
+ (new-tail (take (- (length murk-contexts)
+ (length new-head))
+ murk-contexts)))
+ (append new-head new-tail))))
+
+;;; Context users
+;;
+
+(defvar murk-context-users nil
+ "Association list between channel contexts and users.")
+
+(defun murk-get-context-users (ctx)
+ (cdr (assoc ctx murk-context-users)))
+
+(defun murk-set-context-users (ctx users)
+ (setq murk-context-users
+ (cons (cons ctx users) (assoc-delete-all ctx murk-context-users))))
+
+(defun murk-add-context-users (ctx users)
+ (murk-set-context-users
+ ctx
+ (cl-union users (murk-get-context-users ctx))))
+
+(defun murk-del-context-user (ctx user)
+ (murk-set-context-users
+ ctx
+ (delete user (murk-get-context-users ctx))))
+
+(defun murk-del-all-context-users (ctx)
+ (murk-set-context-users ctx nil))
+
+(defun murk-del-network-user (network user)
+ (dolist (ctx murk-contexts)
+ (if (and (equal (murk-context-network ctx) network)
+ (not (murk-network-context-p ctx)))
+ (murk-del-context-user ctx user))))
+
+(defun murk-del-all-network-users (network)
+ (dolist (ctx murk-contexts)
+ (if (and (equal (murk-context-network ctx) network)
+ (not (murk-network-context-p ctx)))
+ (murk-del-all-context-users ctx))))
+
+(defun murk-rename-network-user (network old-nick new-nick)
+ (dolist (ctx murk-contexts)
+ (when (and (equal (murk-context-network ctx) network)
+ (member old-nick (murk-get-context-users ctx)))
+ (murk-del-context-user ctx old-nick)
+ (murk-add-context-users ctx (list new-nick)))))
+