#+TITLE: :app irc This module turns adds an IRC client to Emacs ([[https://github.com/jorgenschaefer/circe][~circe~)]] with native notifications ([[https://github.com/eqyiel/circe-notifications][circe-notifications]]). * Table of Contents :TOC: - [[Dependencies][Dependencies]] - [[Configure][Configure]] - [[Pass: the unix password manager][Pass: the unix password manager]] - [[Emacs' auth-source API][Emacs' auth-source API]] - [[Appendix][Appendix]] - [[Commands][Commands]] * Dependencies This module has no dependencies, besides =gnutls-cli= or =openssl= for secure connections. * Configure Use the ~:irc~ setting to configure IRC servers. Its second argument (a plist) takes the same arguments as ~circe-network-options~. #+BEGIN_SRC emacs-lisp :tangle no (set! :irc "chat.freenode.net" `(:tls t :nick "doom" :sasl-username "myusername" :sasl-password "mypassword" :channels ("#emacs"))) #+END_SRC *It is a obviously a bad idea to store auth-details in plaintext,* so here are some ways to avoid that: ** Pass: the unix password manager [[https://www.passwordstore.org/][Pass]] is my tool of choice. I use it to manage my passwords. If you activate the [[/modules/tools/password-store/README.org][:tools password-store]] module you get an elisp API through which to access your password store. ~:irc~'s plist can use functions instead of strings. ~+pass-get-user~ and ~+pass-get-secret~ can help here: #+BEGIN_SRC emacs-lisp :tangle no (set! :irc "chat.freenode.net" `(:tls t :nick "doom" :sasl-username ,(+pass-get-user "irc/freenode.net") :sasl-password ,(+pass-get-secret "irc/freenode.net") :channels ("#emacs"))) #+END_SRC But wait, there's more! This stores your password in a public variable which could be accessed or appear in backtraces. Not good! So we go a step further: #+BEGIN_SRC emacs-lisp :tangle no (set! :irc "chat.freenode.net" `(:tls t :nick "doom" :sasl-username ,(+pass-get-user "irc/freenode.net") :sasl-password (lambda (&rest _) (+pass-get-secret "irc/freenode.net")) :channels ("#emacs"))) #+END_SRC And you're good to go! Note that =+pass-get-user= tries to find your username by looking for the fields listed in =+pass-user-fields= (by default =login=, =user==, =username== and =email=)=). An example configuration looks like #+BEGIN_SRC txt :tangle no mysecretpassword username: myusername #+END_SRC ** Emacs' auth-source API ~auth-source~ is built into Emacs. As suggested [[https://github.com/jorgenschaefer/circe/wiki/Configuration#safer-password-management][in the circe wiki]], you can store (and retrieve) encrypted passwords with it. #+BEGIN_SRC emacs-lisp :tangle no (setq auth-sources '("~/.authinfo.gpg")) (defun my-fetch-password (&rest params) (require 'auth-source) (let ((match (car (apply #'auth-source-search params)))) (if match (let ((secret (plist-get match :secret))) (if (functionp secret) (funcall secret) secret)) (error "Password not found for %S" params)))) (defun my-nickserv-password (server) (my-fetch-password :user "forcer" :host "irc.freenode.net")) (set! :irc "chat.freenode.net" '(:tls t :nick "doom" :sasl-password my-nickserver-password :channels ("#emacs"))) #+END_SRC * Appendix ** Commands To connect to IRC you can invoke the ~=irc~ function using =M-x= or your own custom keybinding. | command | description | |---------+-------------------------------------------| | ~=irc~ | Connect to IRC and all configured servers | When in a circe buffer these keybindings will be available. | command | key | description | |------------------------+-----------+----------------------------------------------| | ~tracking-next-buffer~ | =SPC m a= | Switch to the next active buffer | | ~circe-command-JOIN~ | =SPC m j= | Join a channel | | ~+irc/send-message~ | =SPC m m= | Send a private message | | ~circe-command-NAMES~ | =SPC m n= | List the names of the current channel | | ~circe-command-PART~ | =SPC m p= | Part the current channel | | ~+irc/quit~ | =SPC m Q= | Kill the current circe session and workgroup | | ~circe-reconnect~ | =SPC m R= | Reconnect the current server |