emacs/lisp/acdw-erc.el

229 lines
7.6 KiB
EmacsLisp
Raw Normal View History

;;; acdw-erc.el -*- lexical-binding: t; coding: utf-8-unix -*-
;; Author: Case Duckworth <(rot13-string "npqj@npqj.arg")>
;; Created: 24 May 2021
;; Keywords: configuration
;; URL: https://tildegit.org/acdw/emacs
;; This file is NOT part of GNU Emacs.
;;; License:
;; Everyone is permitted to do whatever with this software, without
;; limitation. This software comes without any warranty whatsoever,
;; but with two pieces of advice:
;; - Don't hurt yourself.
;; - Make good choices.
;;; Commentary:
;; `acdw-erc' is a dumping ground for functions and stuff for ERC, so they
;; don't clutter up `init.el'.
;;; Code:
(defgroup acdw-erc nil
"Customizations for ERC."
:group 'erc)
;;; Show a different header-line face when ERC is disconnected.
;; https://www.emacswiki.org/emacs/ErcModeline#h5o-1
(defface erc/header-line-disconnected
'((t (:foreground "black" :background "indianred")))
"Face to use when ERC has been disconnected.")
(defun erc/update-header-line-show-disconnected ()
"Use a different face in the header-line when disconnected."
(erc-with-server-buffer
2021-08-12 13:42:12 +00:00
(cond ((erc-server-process-alive) 'erc-header-line)
(t 'erc/header-line-disconnected))))
;;; Convenience functions
;; from Prelude:
;; https://github.com/bbatsov/prelude/blob/master/modules/prelude-erc.el#L114
(defcustom erc/servers nil
"The list of IRC servers to connect to with `erc/connect'."
:type '(list string))
(defcustom erc/bye-message "See You Space Cowpokes."
"Quit message sent when calling `erc/disconnect'."
:type 'string)
(defun connect-to-erc (server &optional use-tls port nick)
"Connects to IRC SERVER at PORT with NICK.
If USE-TLS is non-nil, use TLS."
(let* ((use-tls (or use-tls t))
(erc-fn (if use-tls #'erc-tls #'erc))
(port (or port (if use-tls 6697 6667)))
(nick (or nick erc-nick)))
(funcall erc-fn
:server server
:port port
:nick nick)))
(defun erc/connect ()
"Connect to all the servers in `erc/servers'."
(interactive)
2021-06-07 04:27:22 +00:00
(require 'erc)
(mapcar #'connect-to-erc erc/servers))
(defun filter-server-buffers ()
(delq nil (mapcar (lambda (x)
(and (erc-server-buffer-p x) x))
(buffer-list))))
2021-07-14 13:37:47 +00:00
(defun erc/reconnect ()
"Reconnect to all IRC servers."
(interactive)
(dolist (buffer (filter-server-buffers))
2021-08-29 04:09:06 +00:00
(with-current-buffer buffer
(ignore-errors
(erc-cmd-RECONNECT)))))
2021-07-14 13:37:47 +00:00
(defun erc/disconnect ()
"Disconnect from all IRC servers."
(interactive)
(dolist (buffer (filter-server-buffers))
(with-message (format "Killing server buffer: %s" (buffer-name buffer))
(with-current-buffer buffer
(erc-quit-server erc/bye-message))))
2021-07-14 13:37:47 +00:00
;; TODO: kill all channel buffers
(force-mode-line-update))
2021-06-07 04:27:50 +00:00
(defun acdw-erc/prompt ()
"The prompt to show for ERC."
;; Rewrite s-truncate to avoid dependency.
(let ((name (buffer-name))
2021-07-03 02:45:37 +00:00
(ellipsis "~")
2021-06-07 04:27:50 +00:00
(len erc-fill-static-center))
(if (and len (> (length name) (- len 2)))
(format "%s%s>"
(substring name 0 (- len 2 (length ellipsis)))
ellipsis)
2021-08-23 22:29:40 +00:00
(propertize
(format "%s%s>"
name
(let ((ss) ; Rewrite s-repeat to avoid dependency.
(num (- len 2 (length name))))
(while (> num 0)
(setq ss (cons " " ss))
(setq num (1- num)))
(apply #'concat ss)))
'read-only t
'intangible t
'cursor-intangible t))))
2021-07-23 02:15:12 +00:00
(defcustom erc-nick-truncate nil
"The width at which to truncate a nick with `erc-format-truncate-@nick'."
:group 'erc
:type 'integer)
(defalias 'erc-propertize 'propertize) ; I guess...taken out in 28 ?
2021-07-23 02:15:12 +00:00
(defun erc-format-truncate-@nick (&optional user channel-data)
"Format the nickname of USER as in `erc-format-@nick', with truncation.
Truncation is customized using the `erc-nick-truncate' variable.
See also `erc-format-nick-function'."
(when user
(let* ((nick (erc-server-user-nickname user))
2021-08-27 23:01:23 +00:00
(prefix (erc-get-user-mode-prefix nick))
2021-07-23 02:15:12 +00:00
(ellipsis "~")
2021-08-27 23:01:23 +00:00
(max-len (- erc-nick-truncate 2 ; one each for < and >
(length ellipsis)
(length prefix))))
2021-07-23 02:15:12 +00:00
(concat (erc-propertize
2021-08-27 23:01:23 +00:00
prefix
2021-07-23 02:15:12 +00:00
'font-lock-face 'erc-nick-prefix-face)
(if (and max-len (> (length nick) max-len))
(format "%s%s" (substring nick 0 max-len)
ellipsis)
nick)))))
;;; Uh
(defun acdw-erc/erc-switch-to-buffer (&optional arg)
"Prompt for ERC buffer to switch to.
Reverse prefix argument from `erc-switch-to-buffer'."
(interactive "P")
(erc-switch-to-buffer (not arg)))
2021-08-27 23:01:23 +00:00
;;; ERC-Bar
;; NEEDS MUCH WORK
(defun erc-bar-move-back (n)
"Moves back n message lines. Ignores wrapping, and server messages."
(interactive "nHow many lines ? ")
(re-search-backward "^.*<.*>" nil t n))
(defun erc-bar-update-overlay ()
"Update the overlay for current buffer, based on the content of
erc-modified-channels-alist. Should be executed on window change."
(interactive)
(let* ((info (assq (current-buffer) erc-modified-channels-alist))
(count (cadr info)))
(if (and info (> count erc-bar-threshold))
(save-excursion
(end-of-buffer)
(when (erc-bar-move-back count)
(let ((inhibit-field-text-motion t))
(move-overlay erc-bar-overlay
(line-beginning-position)
(line-end-position)
(current-buffer)))))
(delete-overlay erc-bar-overlay))))
(defvar erc-bar-threshold 0
"Display bar when there are more than erc-bar-threshold unread messages.")
(defvar erc-bar-overlay nil
"Overlay used to set bar")
(setq erc-bar-overlay (make-overlay 0 0))
(overlay-put erc-bar-overlay 'face '(:overline "gray"))
2021-08-27 23:01:23 +00:00
(with-eval-after-load 'erc-track
;;put the hook before erc-modified-channels-update
(defadvice erc-track-mode (after erc-bar-setup-hook
(&rest args) activate)
(add-hook 'window-configuration-change-hook 'erc-bar-update-overlay -90))
(add-hook 'erc-send-completed-hook (lambda (str)
(erc-bar-update-overlay))))
;;; ZNC babeee
;; needed variables are stored in private.el
(defun znc/connect (znc-server znc-port znc-nick irc-servers)
(interactive (let ((zserv (or znc/server
(read-string "ZNC Server: ")))
(zport (or znc/port
(read-number "ZNC Port: ")))
(znick (or znc/nick
(read-string "ZNC Nick: ")))
(servers (or znc/irc-servers
(list
(cons
(read-string "IRC Server to connect to: ")
(read-passwd "Password: "))))))
(list zserv zport znick servers)))
(let ((si 0))
(dolist (server irc-servers)
(run-at-time si nil
(lambda ()
(erc-tls :server znc-server
:port znc-port
:nick znc-nick
:password (format "%s/%s:%s"
znc-nick
(car server)
(cdr server)))))
(setq si (1+ si)))))
2021-08-27 23:01:23 +00:00
(provide 'acdw-erc)
;;; acdw-erc.el ends here