emacs/lisp/acdw-erc.el

229 lines
7.5 KiB
EmacsLisp
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;;; acdw-erc.el -*- lexical-binding: t; coding: utf-8-unix -*-
;; Author: Case Duckworth <acdw@acdw.net>
;; 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
(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)
(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))))
(defun erc/reconnect ()
"Reconnect to all IRC servers."
(interactive)
(dolist (buffer (filter-server-buffers))
(with-current-buffer buffer
(ignore-errors
(erc-cmd-RECONNECT)))))
(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))))
;; TODO: kill all channel buffers
(force-mode-line-update))
(defun acdw-erc/prompt ()
"The prompt to show for ERC."
;; Rewrite s-truncate to avoid dependency.
(let ((name (buffer-name))
(ellipsis "~")
(len erc-fill-static-center))
(if (and len (> (length name) (- len 2)))
(format "%s%s>"
(substring name 0 (- len 2 (length ellipsis)))
ellipsis)
(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))))
(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 ?
(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))
(prefix (erc-get-user-mode-prefix nick))
(ellipsis "~")
(max-len (- erc-nick-truncate 2 ; one each for < and >
(length ellipsis)
(length prefix))))
(concat (erc-propertize
prefix
'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)))
;;; 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"))
(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)))))
(provide 'acdw-erc)
;;; acdw-erc.el ends here