;;; acdw-irc.el -*- lexical-binding: t; coding: utf-8-unix -*- (require 's nil :noerror) (defgroup acdw-irc nil "Customizations for IRC." :group 'applications) (defcustom acdw-irc/left-margin 16 "The size of the margin for nicks, etc. on the left." :type 'integer) (defcustom acdw-irc/pre-nick "" "What to show before a nick." :type 'string) (defcustom acdw-irc/post-nick " | " "What to show after a nick." :type 'string) (defcustom acdw-irc/pre-my-nick "-" "What to show before the current user's nick." :type 'string) (defcustom acdw-irc/post-my-nick "-> " "What to show after the current user's nick." :type 'string) (defcustom acdw-irc/ellipsis "~" "The ellipsis for when a string is too long." :type 'string) ;;; Convenience functions (I don't want to /depend/ on s.el) (if (fboundp 's-repeat) (defalias 'repeat-string 's-repeat) (defun repeat-string (num s) "Make a string of STR repeated NUM times. Stolen from s.el." (declare (pure t) (side-effect-free t)) (let (ss) (while (> num 0) (setq ss (cons s ss)) (setq num (1- num))) (apply 'concat ss)))) ;;; IRC stuff (defun acdw-irc/margin-format (str &optional before after alignment) "Print STR to fit in `acdw-irc/left-margin'. Optional arguments BEFORE and AFTER specify strings to go ... before and after the string. ALIGNMENT aligns left on nil and right on t." (let* ((before (or before "")) (after (or after "")) (str-length (length str)) (before-length (length before)) (after-length (length after)) (max-length (- acdw-irc/left-margin 1 (+ before-length after-length))) (left-over (max 0 (- max-length str-length)))) (format "%s%s%s%s%s" before (if alignment (repeat-string left-over " ") "") (truncate-string max-length str acdw-irc/ellipsis) (if alignment "" (repeat-string left-over " ")) after))) (defun irc () "Connect to all IRC networks in `circe-network-options'." (interactive) (dolist (network (mapcar #'car circe-network-options)) (circe-maybe-connect network))) (el-patch-feature circe) (with-eval-after-load 'circe (defvar circe-server-buffer-action 'pop-to-buffer-same-window "What to do with `circe-server' buffers when created.") (el-patch-defun circe (network-or-server &rest server-options) "Connect to IRC. Connect to the given network specified by NETWORK-OR-SERVER. When this function is called, it collects options from the SERVER-OPTIONS argument, the user variable `circe-network-options', and the defaults found in `circe-network-defaults', in this order. If NETWORK-OR-SERVER is not found in any of these variables, the argument is assumed to be the host name for the server, and all relevant settings must be passed via SERVER-OPTIONS. All SERVER-OPTIONS are treated as variables by getting the string \"circe-\" prepended to their name. This variable is then set locally in the server buffer. See `circe-network-options' for a list of common options." (interactive (circe--read-network-and-options)) (let* ((options (circe--server-get-network-options network-or-server server-options)) (buffer (circe--server-generate-buffer options))) (with-current-buffer buffer (circe-server-mode) (circe--server-set-variables options) (circe-reconnect)) (el-patch-swap (pop-to-buffer-same-window buffer) (funcall circe-server-buffer-action buffer))))) (defun circe-network-connected-p (network) "Return non-nil if there's any Circe server-buffer whose `circe-server-netwok' is NETWORK." (catch 'return (dolist (buffer (circe-server-buffers)) (with-current-buffer buffer (if (string= network circe-server-network) (throw 'return t)))))) (defun circe-maybe-connect (network) "Connect to NETWORK, but ask user for confirmation if it's already been connected to." (interactive "sNetwork: ") (if (or (not (circe-network-connected-p network)) (y-or-n-p (format "Already connected to %s, reconnect?" network))) (circe network))) ;; the most important command ever. (defun circe-command-SLAP (nick) "Slap NICK around with a large trout." (interactive "sNick: ") (if (not circe-chat-target) (circe-display-server-message "No target for current buffer") (let ((line (concat "slaps " nick " around a bit with a large trout"))) (circe-display 'circe-format-self-action :body line :nick (circe-nick)) (irc-send-ctcp (circe-server-process) circe-chat-target "ACTION" line)))) (provide 'acdw-irc) ;;; acdw-irc.el ends here