Software

Overview

Emacs packages

I'm the author and maintainer of the following Emacs packages:

Democratize See in Helpful all usage examples of libraries read proj repo todo
Exemplify-ERT Clean examples that double as ERT declarations read proj repo todo
Fancy Joiner Join/split lines like a pro in Bash, Org, and more read proj repo todo
Fold and Focus Focused navigation of Org and Emacs Lisp files read proj repo todo
Org B64 Base64-encode files into Org for easy sharing read proj repo todo
Org Reflect Mirror source code from files into Org Src blocks read proj repo todo
OrgReadme-fy README.org from your library's functions and tests read proj repo todo
XHT The extensive hash table library read proj repo todo

You can also see them in my projects page on SourceHut.

Other

Posts-related repositories:

binsch Slow but concise binary search in Bash read repo
countwords Bash and Emacs Lisp solutions to a word-counting exercise read repo
fizzbuzz Lots of fizzbuzzing: Haskell, Emacs Lisp, Bash read repo
int-abs Absolute integers in Bash read repo
phones2words Emacs Lisp and Bash solutions to phones-to-words challenge read repo
playcards A deck of cards and interactive proto-game in Bash read repo

Emacs packages

Downloading and installing

I'll use xht for the examples you'll see below.
The instruction is the same for any of the other packages — just replace xht with it.

Installation options:

  1. Using straight-use-package
  2. Manual installation

Option 1: Using straight-use-package

To download and install xht, add this recipe to your init.el file.

(straight-use-package
 '(:package "xht" :type git :host nil :repo "https://git.sr.ht/~flandrew/xht"))

It seems that newer versions of straight have SourceHut as host. Check yours.
In this case, it could also be:

(straight-use-package
 '(:package "xht" :type git :host sourcehut :repo "flandrew/xht"))

You can also use its integrated syntax with use-package. For that, first do this:

(straight-use-package 'use-package)

Any other use-package customization (as I usually suggest on my packages' README) can then also be added to the use-package declaration. In xht's case, for example:

(use-package xht
  :straight ("xht" :type git :host nil :repo
             "https://git.sr.ht/~flandrew/xht")
  :commands (global-xht-fontify-mode
             global-xht-do-mode
             xht-fontify-mode
             xht-do-mode)
  :config
  (global-xht-fontify-mode)
  (global-xht-do-mode))

Note that these recipes of straight-use-package fetch the latest version from the master branch of the repository, which might or not coincide with a tagged release.

Option 2: Manual installation

Simplified 1
  1. Download the package's main .el.
  2. Open the file and: M-x package-install-from-buffer.
  3. Download the package's README.org and put it in the directory it installed to.
  4. Repeat steps above to install an update.

This should take care of autoloads and dependencies.

Simplified 2
  1. Download the package's main .el and the README.org.
  2. Put them somewhere in your load path, sharing the same directory.
  3. Open the file and: M-x emacs-lisp-byte-compile-and-load.
  4. Repeat steps above to install an update.

This generates no autoloads. You'll probably want to require the file.
In which case, add to your init.el:

(require 'name-of-the-package-here)

This also assumes you have all the dependencies.

Detailed

Here's when you don't want to use package-install but would rather have things a bit more organized than just dumping the files in a single directory. It takes more work, though.

I'll err here on the side of too much detail because some of these steps aren't self-evident.

(As an example, I remember once struggling for what probably amounted to hours to understand why on Earth a newly-downloaded package wasn't being found even though its parent directory was in load-path. "Ah, it's not automatically recursive? What, every subdir must be added, really? Oh, but there's an obscure function that can fix that?")

Have all the Package-Requires

The following table lists the dependencies (and their respective minimal versions) for the most recent version of each of my Emacs packages:

democratize (emacs "25.1") (dash "2.14") (s "1.12") (f "0.20") (xht "1.0.5")
exemplify-ert (emacs "25.1") (dash "2.14") (s "1.12") (f "0.20")
fancy-joiner (emacs "25.1")
fold-and-focus (emacs "25.1")
org-b64 (emacs "25.1")
org-reflect (emacs "25.1") (dash "2.12") (s "1.7")
orgreadme-fy (emacs "25.1") (dash "2.14") (s "1.12") (f "0.20") (xht "1.0.5")
xht (emacs "25.1") (dash "2.15") (s "1.12") (ht "2.3")

So the only dependencies for all of my packages are: dash, s, f, ht — and xht itself.

Maybe you have them all already? Check:

(when (mapc #'require '(dash s f ht))
  "You have them all!")

If no errors, then you have them all.

(Well, except that maybe your versions are older than the specified above? Let's have a look:

(require 'lisp-mnt)
(let (versions libstrg libfile libvers)
  (dolist (lib '(dash s f ht) (reverse versions))
    (setq libstrg (format "%s.el" lib)
          libfile (locate-library libstrg nil (reverse load-path))
          libvers (lm-version libfile))
    (push (list lib libvers libfile) versions)))

Paste the above in an org src block and you'll see the results of C-c C-c as an org table:

#+begin_src emacs-lisp
(require 'lisp-mnt)
(let (versions libstrg libfile libvers)
  ...
#+end_src

So now you know your versions.)

If, however, you got a Cannot open load file error, then some of these are missing: you'd need to get it.

You can either manually download them or get them from MELPA.

To get them from MELPA, add something like this to your .emacs.d/init.el:

(require 'package)
(add-to-list 'package-archives
             '("melpa" . "https://melpa.org/packages/")
             t)

It'll be executed when you restart Emacs.
So either restart Emacs or run it now with C-x C-e at the end of both expressions above.

Done? Then run: M-x package-install RET dash RET.

Repeat the above for ht, s, f — and you're done: you have the dependencies for all of my packages. You're then ready to download and install any of them.

Download the package
The load-path

Where do you keep your extra Emacs packages? For the examples below, let's suppose it's in ~/.emacs.d/packages. Change it to what you use. Make sure it's in Emacs' load-path, so it can be found on startup.

Options

Ok, so let's say you want to download xht. How?

Option A

Get the latest release:

  • Navigate to its repository root or refs.
  • Check which is the latest release.
  • Click on the corresponding .tar.gz to download it.
  • Done!

Then decompress its contents:

last="1.0.42" # (probably not)
tar xf xht-"$last".tar.gz -C ~/.emacs.d/packages
Option B

Get the master:

cd ~/.emacs.d/packages

# Use either of the below
git clone https://git.sr.ht/~flandrew/xht   # To clone it read-only
git clone     git@git.sr.ht:~flandrew/xht   # To clone it read-write
A symlink
Install the package
Options

We have two options.

Option A
  • Use package-install

    Run this:

    (package-install-file "~/.emacs.d/packages/xht/xht.el")
    

    Or open the file and: M-x package-install-from-buffer.

    It will copy the file to a separate directory, create and evaluate autoloads, and compile it.

    Run this:

    (package-list-packages 'no-fetch)
    

    and it would show on the list.

    Copy the README.org to the directory it installed to. This is needed for some packages' commands that use the README.

    You're done!

Option B

You do it by hand.

  • The load-path again

    Your can make init.el add to load-path all the subdirectories that are under a path you specify:

    ;; "packages" here being the example we're using, but use whatever you like:
    (eval-and-compile
      (setq load-path
            (append (delete-dups load-path)
                    '("~/.emacs.d/packages")))
    
      (let ((default-directory "~/.emacs.d/packages"))
        (normal-top-level-add-to-load-path '("."))
        (normal-top-level-add-subdirs-to-load-path)
        (add-to-list 'load-path default-directory))
    

    So you can add subdirectories to that folder, each of which representing a package. When init.el loads, they'll all be added.

    But until you restart Emacs, the package you've just downloaded won't be found! Why? Because the newly-created subdirectory has not been added there yet.

    So you may want to immediately evaluate this to make it findable:

    (add-to-list 'load-path "~/.emacs.d/packages/xht")
    
  • Byte-compile it

    Ok, it's in the load path.

    Open the main .el file in Emacs. In our example here, this would be ~/.emacs.d/packages/xht/xht.el.

    Now run this:
    M-x eval-buffer
    M-x emacs-lisp-byte-compile-and-load

    This will create xht.elc in the same directory.

    And you're done!

Load it on startup

Now add to your init.el either

this (preferable):

(use-package xht
  (add here the configs specific to the package
       as suggested in its README.org))

or this:

(require 'xht)

Customizing

The above applies to any of my Emacs packages, but customizations are specific to each package. It usually involves adding a use-package expression to your init.el. Check its README.org.

Contributing

You can contribute by:

  • reporting bugs
  • sending patches
  • sending suggestions of how the package can be improved
  • commenting about your experience using it

You find information about a package's current issues and ideas:

  • in the TODO.org file at the project's git repository's root
  • in the project's issue tracker