+(defvar lirc-prompt-marker nil
+ "Marker for prompt position in LIRC buffer.")
+
+(defvar lirc-input-marker nil
+ "Marker for prompt position in LIRC buffer.")
+
+(defun lirc-setup-buffer ()
+ (with-current-buffer (get-buffer-create "*lirc*")
+ (if (markerp lirc-prompt-marker)
+ (set-marker lirc-prompt-marker (point-max))
+ (setq lirc-prompt-marker (point-max-marker)))
+ (if (markerp lirc-input-marker)
+ (set-marker lirc-input-marker (point-max))
+ (setq lirc-input-marker (point-max-marker)))
+ (lirc-render-prompt)
+ (goto-char (point-max))
+ (recenter -1)))
+
+;;; Message evaluation
+;;
+
+(defun lirc-eval-msg-string (string)
+ (lirc-display-string string)
+ (let* ((msg (lirc-string->msg string)))
+ (pcase (lirc-msg-cmd msg)
+ ("PING"
+ (lirc-send-msg
+ (lirc-msg nil nil "PONG" (lirc-msg-params msg))))
+ ;; ((rx (= 3 digit))
+ ;; (lirc-display-string (string-join (cdr (lirc-msg-params msg)) " ")))
+
+ ("353" ; NAMEREPLY
+ (let* ((params (lirc-msg-params msg))
+ (channel (elt params 2))
+ (names (split-string (elt params 3))))
+ (apply #'lirc-add-channel-users (cons channel names))))
+
+ ((and "JOIN"
+ (guard (equal lirc-nick (lirc-msg-src msg))))
+ (let ((channel (car (lirc-msg-params msg))))
+ (setq lirc-current-channel channel)
+ (lirc-add-channel channel)
+ (lirc-render-prompt)))
+
+ ("JOIN"
+ (let ((channel (car (lirc-msg-params msg)))
+ (nick (lirc-msg-src msg)))
+ (lirc-add-channel-users channel nick)))
+
+ ((and "PART"
+ (guard (equal lirc-nick (lirc-msg-src msg))))
+ (setq lirc-current-channel nil)
+ (lirc-del-channel (car (lirc-msg-params msg))))
+
+ ("PART"
+ (let ((channel (car (lirc-msg-params msg)))
+ (nick (lirc-msg-src msg)))
+ (lirc-del-channel-users channel nick)))
+
+ ((and "NICK"
+ (guard (equal lirc-nick (lirc-msg-src msg))))
+ (setq lirc-nick (car (lirc-msg-params msg)))
+ (lirc-display-string (concat "*** Set nick to " lirc-nick)))
+
+ ("PRIVMSG"
+ (let ((nick (lirc-msg-src msg))
+ (channel (car (lirc-msg-params msg)))
+ (text (cadr (lirc-msg-params msg))))
+ (lirc-display-string (concat channel " <" nick "> " text))))
+ (_
+ (lirc-display-string (lirc-msg->string msg))))))
+
+
+;;; Command entering
+;;
+
+(defun lirc-enter-string (string)
+ (if (string-prefix-p "/" string)
+ (pcase (substring string 1)
+ (cmd-str
+ (lirc-send-msg (lirc-msg nil nil cmd-str))))
+ (error "Not implemented.")))
+
+(defun lirc-enter ()
+ "Enter current contents of line after prompt."
+ (interactive)
+ (with-current-buffer "*lirc*"
+ (lirc-enter-string
+ (buffer-substring lirc-input-marker (point-max)))
+ (let ((inhibit-read-only t))
+ (delete-region lirc-input-marker (point-max)))))
+
+
+
+;;; Mode
+;;
+
+(defvar lirc-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "RET") 'lirc-enter)
+ map))
+
+(define-derived-mode lirc-mode text-mode "lirc"
+ "Major mode for LIRC.")
+
+(when (fboundp 'evil-set-initial-state)
+ (evil-set-initial-state 'lirc-mode 'insert))
+
+;;; Main start procedure
+;;