;;; MURK --- Multiserver Unibuffer iRc Klient -*- lexical-binding:t -*- ;; Copyright (C) 2024 plugd ;; Author: plugd ;; Created: 11 May 2024 ;; Version: 0.0 ;; Keywords: network ;; Homepage: http://thelambdalab.xyz/metalurk ;; Package-Requires: ((emacs "26")) ;; This file is not part of GNU Emacs. ;; This program is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this file. If not, see . ;;; Commentary: ;;; Code: (provide 'murk) ;;; Customizations (defgroup murk nil "Multiserver Unibuffer iRc Klient" :group 'network) (defcustom murk-nick "plugd" "Default nick.") (defcustom murk-default-quit-msg "Bye" "Default quit message when none supplied.") (defcustom murk-networks '(("libera" "irc.libera.chat" 6697) ("tilde" "tilde.chat" 6697)) "IRC networks.") ;;; Faces ;; ;;; Global variables ;; (defvar murk-version "Murk v0.0" "Value of this string is used in response to CTCP version queries.") (defvar murk-notice-prefix "-!-") (defvar murk-error-prefix "!!!") (defvar murk-prompt-string ">") ;;; Utility procedures ;; (defun murk--filtered-join (&rest args) (string-join (seq-filter (lambda (el) el) args) " ")) (defun murk--as-string (obj) (if obj (with-output-to-string (princ obj)) nil)) ;;; Network processes ;; (defvar murk-connection-table nil "An alist associating servers to connection information. This includes the process and the response string.") (defun murk-connection-process (server) (elt (assoc server murk-connection-table) 1)) (defun murk-connection-response (server) (elt (assoc server murk-connection-table) 2)) (defun murk-set-connection-response (server string) (setf (elt (assoc server murk-connection-table) 2) string)) (defun murk-connection-close (server) (setq murk-connection-table (assoc-delete-all server murk-connection-table))) (defun murk-make-server-filter (server) (lambda (proc string) (dolist (line (split-string (concat (murk-connection-response server) string) "\n")) (if (string-suffix-p "\r" line) (murk-eval-msg-string server (string-trim line)) (murk-set-connection-response line))))) (defun murk-make-server-sentinel (server) (lambda (proc string) (unless (equal "open" (string-trim string)) (murk-display-error "Disconnected from server.") (murk-remove-contexts-for-server server) (murk-render-prompt) (murk-connection-close server)))) (defun murk-start-process (server) (let* ((row (assoc server murk-networks)) (host (elt row 1)) (port (elt row 2)) (flags (seq-drop row 3))) (make-network-process :name (concat "murk-" server) :host host :service port :family nil :filter (murk-make-server-filter server) :sentinel (murk-make-server-sentinel server) :nowait nil :tls-parameters (if (memq :notls flags) nil (cons 'gnutls-x509pki (gnutls-boot-parameters :type 'gnutls-x509pki :hostname host))) :buffer "*lurk*"))) (defvar murk-ping-period 60) ;; IDEA: Have a single ping timer which pings all connected hosts (defun murk-connect (server) (if (assoc server murk-connection-table) (murk-display-error "Already connected to this network.") (if (not (assoc server murk-networks)) (murk-display-error "Network '" server "' is unknown.") (let ((proc (murk-start-process server))) (add-to-list murk-connection-table (list server proc ""))) (murk-send-msg (murk-msg nil nil "USER" murk-nick 0 "*" murk-nick)) (murk-send-msg (murk-msg nil nil "NICK" murk-nick))))) ;;; Contexts and Servers ;; ;; A context is a list (server name ...) where name is a string ;; representing either a channel name or nick, and server is a symbol ;; identifying the server. ;; ;; Each server has a special context (server) used for messages ;; to/from the server itself. (defvar murk-current-context nil) (defvar murk-context-members nil) ;;; Main start procedure ;; (defun metalurk) ;;; metalurk.el ends here