I want to write a function that does one thing if erc is running and starts erc (using command erc
) if not.
I tried to write it myself, but I couldn't find out how to check if erc is running. How can I do this in elisp?
I want to write a function that does one thing if erc is running and starts erc (using command erc
) if not.
I tried to write it myself, but I couldn't find out how to check if erc is running. How can I do this in elisp?
There are two aspects: is there an erc
process running in the buffer? and if there is such a process, is there an established network connection to the server?
If you look in erc.el
, you will see how erc
itself determines the process status to add to the mode line (line 6438 in the file):
...
(let ( ...
(process-status (cond ((and (erc-server-process-alive)
(not erc-server-connected))
":connecting")
((erc-server-process-alive)
"")
(t
": CLOSED")))
IOW, it uses the function erc-server-process-alive
to check whether the process is alive and the value of the variable erc-server-connected
to see if it is connected to the server: if it is alive but not connected to the server, it reports "connecting"; else if it is alive, it reports nothing (i.e. everything is good); else it reports "CLOSED".
You should check the doc strings of the function above (C-h f erc-server-process-alive
) and the variable (C-h v erc-server-connected
) and read them carefully, but this should allow you to determine the state of erc
.
erc-server-connected
is a variable, not a function, so that should read: (if erc-server-connected ...)
with no parens (unless you have defined your own erc-server-connected
function). It might be possible for the value of the variable to be t
, but the process might have died (I don't know if that's possilble, but it is at least a theoretical possibility): it would behoove you to check the state of the process as well IMO.
Based on @NickD's answer, my own research, and my not-so-great understanding of the ERC API, I put together a little helper that might solve the task you're working on—or at least, it might inspire future explorers to experiment further:
(defun my/erc-buffer-connected-p (buffer)
"Check if ERC BUFFER is connected."
(with-current-buffer buffer
(and (erc-server-process-alive)
erc-server-connected)))
(defun my/erc-start-or-switch ()
"Connects to ERC, or switch to last active buffer.
This function serves multiple purposes:
1. Check Active Buffers: It iterates through a predefined list of ERC buffers
to determine if any of them are actively connected to an IRC server.
2. Verify Connection Status: For each buffer, it checks whether the associated
ERC process is alive and whether there is an established network connection
to the server. This is done using the `erc-server-process-alive' function and
the `erc-server-connected' variable.
3. Switch to Active Buffer: If any buffer is found to be actively connected,
the function switches to that buffer using `erc-track-switch-buffer'.
4. Reconnect if Disconnected: If none of the checked buffers are connected,
the function prompts the user to reconnect to the IRC server. If the user
confirms, a new connection is initiated using the `erc' command with the
server and port specified (`irc.libera.chat` on port 6667)."
(interactive)
(let ((erc-buffers '("Libera.Chat" "irc.libera.chat" "irc.libera.chat:6667"))
(connected nil))
(dolist (buffer erc-buffers)
(when (and (get-buffer buffer)
(my/erc-buffer-connected-p buffer))
(setq connected t)))
(if connected
(erc-track-switch-buffer 1)
(when (y-or-n-p "Start ERC? ")
(erc :server "irc.libera.chat" :port 6667)))))