+(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)
+ (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)) " ")))
+ ((and "JOIN" (let (rx (: (literal lirc-nick) "!" (* anychar))) (lirc-msg-src msg)))
+ (let ((channel (car (lirc-msg-params msg))))
+ (setq lirc-current-channel channel)
+ (add-to-list 'lirc-channel-list channel)
+ (lirc-render-prompt)))
+ (_
+ (lirc-display-string (lirc-msg->string msg))))))
+
+
+;;; Command entering
+;;
+
+(defun lirc-enter-string (string)
+ (cond ((string-prefix-p "/" string)
+ (let ((cmd-str (substring string 1)))
+ (lirc-send-msg (lirc-msg nil nil cmd-str))))
+ (t
+ (error "Unknown command" string))))
+
+(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
+;;