Muto - Blog - Feed


My Emacs Configuration

Emacs is neat and does everything. I want to talk about how I use Emacs.


Speeding things up with the daemon

Emacs takes a long time to start. I use emacs --daemon, which runs Emacs in the background all the time. I can connect to it using emacsclient -c!

Since emacsclient -c is long to type, I add an alias for it in my .bashrc

# Make the 'em' command launch Emacs.
alias em='emacsclient -c'

# This version runs emacsclient, and starts the
# daemon if it isn't already running:
alias em='emacsclient -a "" -c'

I also compile my init.el file with M-x byte-compile-file.

If I want to completely kill emacs, I run M-x kill-emacs.


Keyboard shortcuts

The C-c binding is reserved for the user, so you don't have to worry about erasing an existing binding!

My current bindings look like this in my .emacs file:

(global-set-key "\C-ci" 'ibuffer) ; List of buffers
(global-set-key "\C-cm" 'rmail)   ; Mail client
(global-set-key "\C-cs" 'eshell)  ; Shell
(global-set-key "\C-cw" 'eww)     ; Web browser

(global-set-key "\C-ck" 'kill-emacs)        ; shutdown emacs-daemon
(global-set-key "\C-cb" 'byte-compile-file) ; compile a .el file
(global-set-key "\C-cn" 'indent-region)     ; auto-indent region

;; Remove unecessary whitespace characters.
(global-set-key ("C-<backspace>") 'whitespace-cleanup)

Reading email with rmail

Rmail is an adorable mail client. Screenshot

  • To send mail I use SMTP.
  • To fetch mail I use IMAP.
  • You need mailutils on your computer for rmail to work right.

Here's what my email config looks like in my init.el:

;; Email config for rmail

(setq
  rmail-primary-inbox-list '("imaps://me%40muto.ca:p4ss@mail.muto.ca")
  send-mail-function       'smtpmail-send-it
  rmail-preserve-inbox     t
  rmail-file-name          "~/mail/inbox"
  message-default-headers  "Fcc: ~/mail/sent"
  user-mail-address        "me@muto.ca"
  user-full-name           "Muto")

rmail-primary-inbox-list points to a remote mailbox using the URL scheme:

  • imaps:// - The protocol to use, can also be pop:// or pops://
  • me%40muto.ca - Our address. %40 is the standard URI way to type @
  • p4ss - Our password. The username & password are separated by a colon :.
  • mail.muto.ca - The server where our mail comes from.

The rest of the options are easier:

  • send-mail-function - Tell Emacs to send mail using SMTP.
  • rmail-preserve-inbox - Keep mail on the server, instead of deleting after fetching.
  • rmail-file-name - Where our inbox file is.
  • message-default-headers - Tell Emacs to copy all sent mail to a local file.
  • user-mail-address - Your email address as shown in the "From" header.
  • user-full-name - Your name as shown in the "From" header.

After all that, I can do M-x rmail, which will collect all my mail from my remote inbox. Very nice! Read more about rmail here!

Also here's a short cheatsheet:

  • p/n - Previous / Next mail
  • d - Mark for deletion
  • u - Unmark
  • r - Reply
  • m - Compose a new email
  • o - Output mail to an mbox file
  • i - Open an mbox file
  • a - Add label to current message
  • l - Filter inbox by label
  • M-s - Search all mail

dired, the file manager

Dired is a file manager. This is my config for dired: Screenshot

;; Use extra dired features.
(require 'dired-x)

;; Allow ommiting dotfiles from listing.
(setq dired-omit-files (concat dired-omit-files "\\|^\\..+$"))

;; Open dired in current file's directory.
(global-set-key "\Cd" 'dired-jump)

;; Auto load extra dired features.
(add-hook 'dired-load-hook (lambda () (load "dired-x")))

;; Sort directories first
(require 'ls-lisp)
(setq ls-lisp-dirs-first t)
(setq ls-lisp-use-insert-directory-program nil)

;; Make dired comfy with easy keybindingns & watnot.
(add-hook 'dired-mode-hook
          (lambda ()
            (local-set-key (kbd "/") 'dired-omit-mode)
            (local-set-key (kbd "h") 'dired-hide-details-mode)
            (local-set-key (kbd "b") 'dired-up-directory)
            (local-set-key (kbd "e") 'dired-do-async-shell-command)
            (dired-hide-details-mode 1)
            (dired-omit-mode 1)))

Now dired won't show you a lot of garbage, but if we want garbage, we can toggle it!

  • f - Open folder / file
  • b - Go back a directory
  • v - View file (q to go back to dired)
  • / - Toggle dotfiles
  • h - Toggle long listing
  • d - Mark for deletion
  • x - Delete all marked files
  • R - Rename file
  • ? - Quick help menu
  • e - Run a shell command on this file

(note that b, /, h, and e are all bound in the config above. They are not defaults)


Web Browsing With eww

Eww is the Emacs Web browser. I use eww regularly to quickly find information. Emacs can also be compiled with WebKit support, but I prefer the smolness of Eww. Screenshot

Start eww with M-x eww and you'll be prompted to make a websearch (in DuckDuckGo by default). There are a few handy features of eww that I use regularly:

  • b - Add bookmark
  • B - View bookmarks
  • d - Download link under point
  • l - Go back
  • r - Go forward
  • H - View history
  • g - reload the page
  • G - Enter a new URL
  • R - Attempt to remove trash to improve readability
  • w - Copy the current URL
  • M-<RET> - Open link in new tab
  • s - Get a list of eww tabs

I also have some config options for Eww:

;; General functions
(setq
 browse-url-browser-function 'eww-browse-url ; Use eww by default
 shr-use-fonts  nil                          ; No special fonts
 shr-use-colors nil                          ; No colours
 shr-indentation 2                           ; Left-side margin
 shr-width 70                                ; Fold text for comfiness
 eww-search-prefix "https://ddg.gg/html?q=") ; Use light DuckDuckGo

;; Some keyboard shortcuts
(add-hook 'eww-mode-hook
          (lambda ()
           (local-set-key "n" 'shr-next-link)
           (local-set-key "p" 'shr-previous-link)
           (local-set-key "u" 'eww-back-url)))

Eww doesn't support gopher:// or gemini://. For that, I'd suggest Elpher!

This blog is text browser compatible, and I encourage you to read it with M-x eww!


Manage buffers with ibuffer

ibuffer is a comf way to manage your buffers. Screenshot

Here's my ibuffer config:

;; Load up the ibuffer facility
(require 'ibuffer)
(require 'ibuf-ext)

;; Some variables
(setq
 ibuffer-expert t
 ibuffer-show-empty-filter-groups nil
 ibuffer-saved-filter-groups
 '(("default"
    ("Erc"   (mode . erc-mode))
    ("Eww"   (mode . eww-mode))
    ("Dired" (mode . dired-mode))
    ("Meta"  (name . "\\*"))
    ("Code" (filename . "~/prog/"))
    ("Help" (or (name . "\*Help\*")
                (name . "\*Info\*"))))))

;; Function that collapses / de-collapses all entries.
(defun ibuffer-toggle-all ()
  (interactive)
  (if ibuffer-hidden-filter-groups
      (setq ibuffer-hidden-filter-groups '())
    (setq ibuffer-hidden-filter-groups
          (mapcar #'car (ibuffer-current-filter-groups-with-position))))
  (ibuffer-update nil t))

;; Hooks
 (add-hook 'ibuffer-mode-hook
           (lambda ()
               (local-set-key (kbd "M-<RET>") 'ibuffer-toggle-all)
               (ibuffer-switch-to-saved-filter-groups "default")))

This is a bit more complicated, if just because of my ibuffer-toggle-all function, but I'll go through it:

  • ibuffer-expert - Remove warnings and messages
  • ibuffer-show-empty-filter-groups - Don't show a group if there's no buffer in it
  • ibuffer-saved-filter-group - Break ibuffer up into sections, so that you have a collapsible menu for "Erc" buffers, and another menu for files in the "/prog directory!
  • ibuffer-toggle-all - Collapse or expand all submenus
  • ibuffer-switch-to-saved-filter-groups - Needed to enable filters properly

I've used ibuffer for a long time, but only just started to really use it. It's fun!


IRC with erc

erc is an IRC client. Screenshot

(require 'erc)
(require 'tls)

(setq
 erc-autojoin-channels-alist '(("irc.serv1.com" "#chan1" "#chan2")
                               ("irc.serv2.com" "#chan3" "#chan4"))
 erc-fill-function   'erc-fill-static         ; Nicks in their own column
 erc-fill-static-center 20                    ; Nick column width
 erc-hide-list       '("JOIN" "PART" "QUIT")  ; Ignore joins/quits 
 erc-nick "cowgirl"                           ; Our IRC nick
 erc-full-name "moo moo"                      ; Our /whois name

You can also add a shortcut to connect to a server in your init.el file like so:

;; Define a keyboard shortcut that connects to a server
(global-set-key "\C-cea"
                (lambda ()
                  (interactive)
                  (erc :server "irc.serv1.com"
                       :port   "6667")))

;; Connect to a second server with SSL.
(global-set-key "\C-ceb"
                (lambda ()
                  (interactive)
                  (erc-tls :server "irc.serv2.com"
                           :port   "6697")))

Newsgroups with gnus

Gnus is an NNTP news reader for emacs. Screenshot

(setq
 gnus-select-method '(nnmbox "")
 gnus-secondary-select-methods '((nntp "news.tilde.club")
                                 (nntp "news.gnus.org"))

 gnus-thread-hide-subtree t
 gnus-newsgroup-maximum-articles 50
 gnus-summary-line-format "%U%R%z %d  %-15,15n  %B%s\n")

(add-hook 'gnus-summary-mode-hook
          (lambda ()
            (local-set-key "h" 'gnus-summary-hide-thread)
            (local-set-key "s" 'gnus-summary-show-thread)))
  • gnus-select-method - I set this to my inbox. It defaults to /var/mail/user.
  • gnus-secondary-select-methods - A list of NNTP news servers.
  • gnus-thread-hide-subtree - Threads are collapsed by default.
  • gnus-newsgroup-maximum-articles - Don't download more than 50 posts per group.
  • gnus-summary-line-format - How messages appear in a group (see below).
  • gnus-summary-mode-hook - We bind h and s to "hide thread" and "show thred".

The weird gnus-summary-line-format with all the % symbols defines how group entries appear. You can read about it here, but my format is:

  • U - Display a letter U if this message is new.
  • R - Dislay a letter R if you have replied to this message.
  • d - The date.
  • -15,15n - Name of sender in 15 columns, and cut off at the end if longer.
  • B - Make the thread pretty by adding little arrows and stuff.
  • s - Subject of the message.

My Gnus workflow looks pretty simple:

  1. Open Gnus with M-x gnus
  2. Go to my server list with ^
  3. Select a server to browse
  4. Look at some of the content, maybe post something
  5. Subscribe to interesting groups with k
  6. Check my email (in the nnmbox entry)

Now, when you subscribe to a group with k, the next time you run Gnus, it will show up instead of the splash screen!


Other little things

  • ielm - An Emacs Lisp REPL
  • eshell - A shell, though I prefer dired and M-&
  • ansi-term - An ncurses-compatible terminal emulator
  • visual-line-mode - Makes working with longlines comf
  • auto-fill-mode - If you'd rather hardwrap your files
  • proced - A top-like process viewer
  • nero.el - An Emacs interface to the Lynx browser
  • trmail.el - External pacakge for rmail threads. No luck so far