summary refs log tree commit diff stats
path: root/lisp/acdw-erc.el
blob: 09fa335353ebdd278afd55816a0832ede4896a10 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
;;; 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-message (format "Reconnecting to server: %s" (buffer-name buffer))
      (with-current-buffer buffer
        (erc-server-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)
      (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))))))

(defcustom erc-nick-truncate nil
  "The width at which to truncate a nick with `erc-format-truncate-@nick'."
  :group 'erc
  :type 'integer)

(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))
           (ellipsis "~")
           (max-len (- erc-nick-truncate 2 (length ellipsis))))
      (concat (erc-propertize
               (erc-get-user-mode-prefix nick)
               '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)))

(provide 'acdw-erc)
;;; acdw-erc.el ends here