[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Controlling ERC from elsewhere

From: J.P.
Subject: Controlling ERC from elsewhere
Date: Fri, 05 Jan 2024 07:13:37 -0800
User-agent: Gnus/5.13 (Gnus v5.13)

Someone recently asked how to go about controlling ERC from a shell or
other process. The short answer is: the same way you'd do it for any
other Emacs library. IOW, ERC doesn't provide special facilities to
assist users in this regard. However, the following approaches all seem
more or less doable:

1. A custom protocol over any Emacs-supported transport. Generally
   speaking, this means an async (network) process (client or server)
   and glue for your protocol to talk to ERC

2. A hand-rolled DBus service (info "(dbus) Register Objects")

3. A user .desktop file to handle irc:// URLs through Emacs (bug#56514)

4. A built-in framework, like org-protocol (example below)

Of these, it's Org Protocol I'm least familiar with, so there's likely a
much simpler way to achieve what I've managed to cobble together from
(info "(org) Protocols") and org-protocol.el to address the OP's use
case of sending IRC messages from the command line. In any event:

1. Put an executable helper script like this somewhere in your PATH

   # Usage: $ ./this.sh "#emacs" ,yow
   #        $ echo привет, мир | ./this.sh "#chan" -
   #        $ ./this.sh "##spam" - <<'EOF'
   #        > ;;; my-thing.el --- My thing -*- lexical-binding: t; -*-
   #        > ...
   #        > (provide 'my-thing)
   #        > EOF
   set -e
   (( $# == 2 ))
   [[ $msg == -* ]] && msg=$(emacs -Q -batch -eval '
     (let (out)
       (while-let ((s (condition-case _ (read-string "") (end-of-file))))
         (push s out))
       (princ (url-hexify-string (string-join (nreverse out) "\n"))))'
   buf=${1/###/%23%23} ##chan
   buf=${1/##/%23} #chan
   buf=${buf/#&/%26} # &chan
   [[ $msg && $buf ]]
   exec >/dev/null
   exec emacsclient "org-protocol://my-erc-msg?buf=$buf&msg=$msg"

2. Add some config items to your init

   (setq org-protocol-protocol-alist
            :protocol "my-erc-msg"
            :function my-erc-msg-handle-org-protocol-msg
            :kill-client t)))

   (defun my-erc-msg-handle-org-protocol-msg (string)
     "Parse query STRING and send message to specified buffer.
   Expect both values to be percent-encoded."
     (pcase (org-protocol-parse-parameters string 'new-style '(:buf :msg))
       (`(:buf ,buf :msg ,msg) (with-current-buffer buf
                                 (erc-send-message msg)))
       (_ (error "Failed to parse %S" string)))
     nil) ; inhibit `server-visit-files'.

3. Start an Emacs server instance and an ERC session

reply via email to

[Prev in Thread] Current Thread [Next in Thread]