emacs/lisp/+circe.el

149 lines
4.8 KiB
EmacsLisp

;;; +circe.el -*- lexical-binding: t; -*-
;;; Code:
(require '+util)
(require 'circe)
(defgroup +circe nil
"Extra customizations for Circe."
:group 'circe)
(defcustom +circe-left-margin 16
"The size of the margin on the left."
:type 'integer)
(defcustom +circe-network-inhibit-autoconnect nil
"Servers to inhibit autoconnecting from `circe-network-options'."
:type '(repeat string))
;;; Connecting to IRC
;;;###autoload
(defun +irc ()
"Connect to all IRC networks in `circe-network-options'."
(interactive)
(dolist (network (mapcar 'car circe-network-options))
(unless (member network +circe-network-inhibit-autoconnect)
(+circe-maybe-connect network))))
(defun +circe-network-connected-p (network)
"Return t if connected to NETWORK, nil otherwise."
(catch 'return
(dolist (buffer (circe-server-buffers))
(with-current-buffer buffer
(when (string= network circe-server-network)
(throw 'return t))))))
(defun +circe-maybe-connect (network)
"Connect to NETWORK, asking for confirmation to reconnect."
(interactive ("sNetwork: "))
(when (or (not (+circe-network-connected-p network))
(yes-or-no-p (format "Already connected to %s, reconnect? "
network)))
(circe network)))
;;; Channel information
(defun +circe-current-topic (&optional message)
"Return the topic of the current channel.
When called with optional MESSAGE non-nil, or interactively, also
message the current topic.")
;;; Formatting messages
(defun +circe-format-meta (string)
"Return a format string for `lui-format' for metadata messages."
(format "{nick:%1$d.%1$ds} *** %s" (- +circe-left-margin 3) string))
;;; Hooks & Advice
(defun +circe-chat@set-prompt ()
"Set the prompt to the (shortened) buffer name."
(interactive)
(lui-set-prompt (propertize (+string-align (buffer-name) +circe-left-margin
:after " > "
:ellipsis "~"
:alignment 'right))))
(defun +circe-kill-buffer (&rest _)
"Kill a circe buffer without confirmation, and after a delay."
(let ((circe-channel-killed-confirmation nil)
(circe-server-killed-confirmation nil))
(run-with-timer 0.25 nil 'kill-buffer)))
(defun +circe-quit@kill-buffer (&rest _)
"ADVICE: kill all buffers of a server after `circe-command-QUIT'."
(with-circe-server-buffer
(dolist (buf (circe-server-buffers))
(with-current-buffer buf
(+circe-kill-buffer)))
(+circe-kill-buffer)))
(defun +circe-gquit@kill-buffer (&rest _)
"ADVICE: kill all Circe buffers after `circe-command-GQUIT'."
(dolist (buf (circe-server-buffers))
(with-current-buffer buf
(+circe-quit@kill-buffer))))
;;; Patches
(require 'el-patch)
(el-patch-feature 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))))
;;; Chat commands
(defun circe-command-SHORTEN (url)
"Shorten URL using `0x0-shorten-uri'.")
(defun circe-command-SLAP (nick)
"Slap NICK around a bit with a large trout.")
;;; Pure idiocy
(define-minor-mode circe-cappy-hour-mode
"ENABLE CAPPY HOUR IN CIRCE!"
:lighter "CAPPY HOUR"
(when (derived-mode-p 'circe-chat-mode)
(if circe-cappy-hour-mode
(setq-local lui-input-function
(lambda (input) (circe--input (upcase input))))
;; XXX: It'd be better if this were more general, but whatever.
(setq-local lui-input-function #'circe--input))))
(provide '+circe)
;;; +circe.el ends here