summaryrefslogtreecommitdiff
path: root/modules/erc-config.el
diff options
context:
space:
mode:
Diffstat (limited to 'modules/erc-config.el')
-rw-r--r--modules/erc-config.el180
1 files changed, 125 insertions, 55 deletions
diff --git a/modules/erc-config.el b/modules/erc-config.el
index 03c89aca..55b4c9a7 100644
--- a/modules/erc-config.el
+++ b/modules/erc-config.el
@@ -9,28 +9,65 @@
;; - C-c e C : Select and connect to a specific server
;; - C-c e c : Join a channel on current server
;; - C-c e b : Switch between ERC buffers across all servers
-;; - C-c C-q : Quit current channel
-;; - C-c C-Q : Quit ERC altogether
+;; - C-c e l : List connected servers
+;; - C-c e q : Quit current channel
+;; - C-c e Q : Quit ERC server
;;; Code:
-;; Keymap for ERC commands
+;; Load cl-lib at compile time and runtime (lightweight, already loaded in most configs)
+(require 'cl-lib)
+
+;; Declare ERC functions to avoid byte-compiler warnings
+(declare-function erc-part-from-channel "erc" (&optional reason))
+(declare-function erc-quit-server "erc" (reason))
+(declare-function erc-buffer-list "erc" (&optional predicate proc))
+(declare-function erc-server-process-alive "erc" (&optional buffer))
+(declare-function erc-server-buffer-p "erc" (&optional buffer))
+(declare-function erc-current-nick "erc" ())
+(declare-function erc-join-channel "erc" (channel &optional key))
+(declare-function erc-tls "erc" (&rest r))
+(declare-function erc "erc" (&rest r))
+(declare-function erc-update-modules "erc" ())
+(declare-function erc-get-color-for-nick "erc" (nick))
+
+;; Declare ERC variables
+(defvar erc-server-process)
+(defvar erc-mode-abbrev-table)
+(defvar erc-log-channels-directory)
+(defvar erc-unique-buffers)
+(defvar erc-generate-buffer-name-function)
+(defvar erc-track-exclude-types)
+(defvar erc-track-exclude-server-buffer)
+(defvar erc-track-visibility)
+(defvar erc-track-switch-direction)
+(defvar erc-track-showcount)
+(defvar erc-nick-color-alist)
+(defvar erc-nick-color-function)
+(defvar erc-modules)
+(defvar erc-mode-map)
+(defvar user-whole-name)
+(defvar erc-image-inline-rescale)
+
+;; Keymap for ERC commands (bound in use-package :config to defer loading)
(defvar cj/erc-command-map
(let ((map (make-sparse-keymap)))
- (define-key map "C" 'cj/erc-connect-server-with-completion) ;; Connect to server (capital C)
- (define-key map "c" 'cj/erc-join-channel-with-completion) ;; join channel (lowercase c)
- (define-key map "b" 'cj/erc-switch-to-buffer-with-completion) ;; switch Buffer
- (define-key map "l" 'cj/erc-connected-servers) ;; print connected servers in echo area
- (define-key map "q" 'erc-part-from-channel) ;; quit channel
- (define-key map "Q" 'erc-quit-server) ;; Quit ERC entirely
+ (keymap-set map "C" #'cj/erc-connect-server-with-completion) ;; Connect to server (capital C)
+ (keymap-set map "c" #'cj/erc-join-channel-with-completion) ;; join channel (lowercase c)
+ (keymap-set map "b" #'cj/erc-switch-to-buffer-with-completion) ;; switch Buffer
+ (keymap-set map "l" #'cj/erc-connected-servers) ;; print connected servers in echo area
+ (keymap-set map "q" #'erc-part-from-channel) ;; quit channel
+ (keymap-set map "Q" #'erc-quit-server) ;; Quit ERC entirely
map)
"Keymap for ERC-related commands.")
-(global-set-key (kbd "C-c e") cj/erc-command-map)
-
;; ------------------------------------ ERC ------------------------------------
;; Server definitions and connection settings
+(defvar cj/erc-nick "craigjennings"
+ "Default IRC nickname for ERC connections.
+Change this value to use a different nickname.")
+
(defvar cj/erc-server-alist
'(("Libera.Chat"
:host "irc.libera.chat"
@@ -57,22 +94,26 @@
:channels ("#general" "#lounge")))
"Alist of IRC servers and their connection details.")
+;;;###autoload
(defun cj/erc-connect-server (server-name)
- "Connect to a server specified by SERVER-NAME from =cj/erc-server-alist=."
- (let* ((server-info (assoc server-name cj/erc-server-alist))
- (host (plist-get (cdr server-info) :host))
- (port (plist-get (cdr server-info) :port))
- (tls (plist-get (cdr server-info) :tls)))
- (if tls
- (erc-tls :server host
- :port port
- :nick "craigjennings"
- :full-name user-whole-name)
- (erc :server host
- :port port
- :nick "craigjennings"
- :full-name user-whole-name))))
-
+ "Connect to a server specified by SERVER-NAME from `cj/erc-server-alist'."
+ (let ((server-info (assoc server-name cj/erc-server-alist)))
+ (if (not server-info)
+ (error "Server '%s' not found in cj/erc-server-alist" server-name)
+ (let ((host (plist-get (cdr server-info) :host))
+ (port (plist-get (cdr server-info) :port))
+ (tls (plist-get (cdr server-info) :tls)))
+ (if tls
+ (erc-tls :server host
+ :port port
+ :nick cj/erc-nick
+ :full-name user-whole-name)
+ (erc :server host
+ :port port
+ :nick cj/erc-nick
+ :full-name user-whole-name))))))
+
+;;;###autoload
(defun cj/erc-connect-server-with-completion ()
"Connect to a server using completion for server selection."
(interactive)
@@ -80,6 +121,7 @@
(mapcar #'car cj/erc-server-alist))))
(cj/erc-connect-server server-name)))
+;;;###autoload
(defun cj/erc-connected-servers ()
"Return a list of currently connected servers and display them in echo area."
(interactive)
@@ -94,28 +136,51 @@
(when (called-interactively-p 'any)
(if server-buffers
(message "Connected ERC servers: %s"
- (mapconcat 'identity server-buffers ", "))
+ (mapconcat #'identity server-buffers ", "))
(message "No active ERC server connections")))
server-buffers))
+;;;###autoload
(defun cj/erc-switch-to-buffer-with-completion ()
- "Switch to an ERC buffer using completion."
+ "Switch to an ERC buffer using completion.
+If no ERC buffers exist, prompt to connect to a server.
+Buffer names are shown with server context for clarity."
(interactive)
- (let* ((erc-buffers (mapcar 'buffer-name (erc-buffer-list)))
- (selected (completing-read "Switch to buffer: " erc-buffers)))
- (switch-to-buffer selected)))
-
+ (let* ((erc-buffers (erc-buffer-list))
+ (buffer-names (mapcar #'buffer-name erc-buffers)))
+ (if buffer-names
+ (let ((selected (completing-read "Switch to ERC buffer: " buffer-names nil t)))
+ (switch-to-buffer selected))
+ (message "No ERC buffers found.")
+ (when (y-or-n-p "Connect to an IRC server? ")
+ (call-interactively 'cj/erc-connect-server-with-completion)))))
+
+;;;###autoload
(defun cj/erc-server-buffer-active-p ()
"Return t if the current buffer is an active ERC server buffer."
(and (derived-mode-p 'erc-mode)
(erc-server-process-alive)
(erc-server-buffer-p)))
+;;;###autoload
+(defun cj/erc-get-channels-for-current-server ()
+ "Get list of channels for the currently connected server."
+ (when (and (derived-mode-p 'erc-mode) erc-server-process)
+ (let* ((server-host (process-name erc-server-process))
+ (matching-server (cl-find-if
+ (lambda (server)
+ (string-match-p (plist-get (cdr server) :host) server-host))
+ cj/erc-server-alist)))
+ (when matching-server
+ (plist-get (cdr matching-server) :channels)))))
+
+;;;###autoload
(defun cj/erc-join-channel-with-completion ()
"Join a channel on the current server.
-If not in an active ERC server buffer, reconnect first."
+If not in an active ERC server buffer, reconnect first.
+Auto-adds # prefix if missing. Offers completion from configured channels."
(interactive)
(unless (cj/erc-server-buffer-active-p)
(if (erc-buffer-list)
@@ -138,15 +203,20 @@ If not in an active ERC server buffer, reconnect first."
;; At this point we should have an active connection
(if (cj/erc-server-buffer-active-p)
- (let ((channel (read-string "Join channel: ")))
- (when (string-prefix-p "#" channel)
+ (let* ((channels (cj/erc-get-channels-for-current-server))
+ (channel (if channels
+ (completing-read "Join channel: " channels nil nil "#")
+ (read-string "Join channel: " "#"))))
+ ;; Auto-add # prefix if missing
+ (unless (string-prefix-p "#" channel)
+ (setq channel (concat "#" channel)))
+ (when (> (length channel) 1) ; Must have more than just #
(erc-join-channel channel)))
(message "Failed to establish an active ERC connection")))
;; Main ERC configuration
(use-package erc
- :defer 1
:ensure nil ;; built-in
:commands (erc erc-tls)
:hook
@@ -175,18 +245,20 @@ If not in an active ERC server buffer, reconnect first."
(plist-get (cdr server) :channels)))
cj/erc-server-alist))
- (erc-nick "craigjennings")
+ (erc-nick cj/erc-nick)
(erc-user-full-name user-whole-name)
(erc-use-auth-source-for-nickserv-password t)
(erc-kill-buffer-on-part t)
(erc-kill-queries-on-quit t)
(erc-kill-server-buffer-on-quit t)
(erc-fill-column 120)
- (erc-fill-function 'erc-fill-static)
+ (erc-fill-function #'erc-fill-static)
(erc-fill-static-center 20)
:config
+ ;; Bind global keymap
+ (keymap-global-set "C-c e" cj/erc-command-map)
;; use all text mode abbrevs in ercmode
(abbrev-table-put erc-mode-abbrev-table :parents (list text-mode-abbrev-table))
@@ -197,7 +269,7 @@ If not in an active ERC server buffer, reconnect first."
(mkdir erc-log-channels-directory t))
;; Configure buffer naming to include server name
- (setq erc-rename-buffers t)
+ ;; Note: erc-rename-buffers is obsolete as of Emacs 29.1 (old behavior is now permanent)
(setq erc-unique-buffers t)
;; Custom buffer naming function
@@ -217,7 +289,11 @@ If not in an active ERC server buffer, reconnect first."
erc-track-exclude-server-buffer t
erc-track-visibility 'selected-visible
erc-track-switch-direction 'importance
- erc-track-showcount t))
+ erc-track-showcount t)
+
+ ;; Add hooks for notifications and colorization
+ (add-hook 'erc-text-matched-hook #'cj/erc-notify-on-mention)
+ (add-hook 'erc-mode-hook #'cj/erc-colorize-setup))
;; -------------------------------- ERC Track ---------------------------------
;; Better tracking of activity across channels (already included in modules above)
@@ -244,7 +320,7 @@ If not in an active ERC server buffer, reconnect first."
;; Implementation for desktop notifications
(defun cj/erc-notify-on-mention (match-type nick message)
- "Display a notification when MATCH-TYPE is 'current-nick.
+ "Display a notification when MATCH-TYPE is \\='current-nick.
NICK is the sender and MESSAGE is the message text."
(when (and (eq match-type 'current-nick)
@@ -261,8 +337,6 @@ NICK is the sender and MESSAGE is the message text."
:app-name "Emacs ERC"
:sound-name 'message))))))
-(add-hook 'erc-text-matched-hook 'cj/erc-notify-on-mention)
-
;; ------------------------------ ERC Colorize -------------------------------
;; Better color management with built-in functionality
@@ -276,30 +350,26 @@ NICK is the sender and MESSAGE is the message text."
"light blue" "light green" "light red"
"light brown" "light purple" "yellow" "white")
collect (cons i color)))
- (setq erc-nick-color-function 'erc-get-color-for-nick))
-
-(add-hook 'erc-mode-hook 'cj/erc-colorize-setup)
+ (setq erc-nick-color-function #'erc-get-color-for-nick))
;; -------------------------------- ERC Image ---------------------------------
;; show inlined images (png/jpg/gif/svg) in erc buffers.
(use-package erc-image
- :defer 1
+ :if (locate-library "erc-image")
:after erc
:config
(setq erc-image-inline-rescale 300)
(add-to-list 'erc-modules 'image)
(erc-update-modules))
-;; -------------------------------- ERC Hl Nicks -------------------------------
-;; uniquely identify names in ERC
+;; -------------------------------- ERC Nicks ---------------------------------
+;; Nickname highlighting (built-in to Emacs 29+)
-(use-package erc-hl-nicks
- :defer 1
+(use-package erc-nicks
+ :ensure nil ;; built-in
:after erc
- :config
- (add-to-list 'erc-modules 'hl-nicks)
- (erc-update-modules))
+ :hook (erc-mode . erc-nicks-mode))
;; ------------------------------ ERC Yank To Gist -----------------------------
;; automatically create a Gist if pasting more than 5 lines
@@ -307,7 +377,7 @@ NICK is the sender and MESSAGE is the message text."
;; via ruby: 'gem install gist' via the aur: yay -S gist
(use-package erc-yank
- :defer 1
+ :if (locate-library "erc-yank")
:after erc
:bind
(:map erc-mode-map