p3r7 / awesome-elisp

🏵️ A curated list of Emacs Lisp development resources
The Unlicense
743 stars 32 forks source link
awesome-list emacs emacs-lisp

+HTML:
Emacs Logo

+HTML:

Welcome to /Awesome Elisp/, a list of resources linked to Emacs Lisp (Elisp) development.

Its aim is to not be a simple index but a /compendium/: resources are not only listed but also commented.

It tries to be as exhaustive as possible.

For a more general index related to all-things Emacs, use [[https://github.com/emacs-tw/awesome-emacs][Awesome Emacs]].

** Entry-level

*** An Introduction to Programming in Emacs Lisp

[[https://www.gnu.org/software/emacs/manual/html_node/eintr/index.html][read online]]

Also comes bundled with Emacs.
Just =C-h i= (or =M-x info=) and open =Emacs Lisp Intro=.

A bit scholarly. Not the easiest read.

*** Emacs In A Box - Elisp Programming

[[http://caiorss.github.io/Emacs-Elisp-Programming/Elisp_Programming.html][read online]], [[https://github.com/caiorss/Emacs-Elisp-Programming/blob/master/Elisp_Programming.org][source]]

Very complete and gentle introduction.

Written by [[#caio-rordrigues-caiorss][Caio Rordrigues (@caiorss)]].

*** (Almost) All You Need to Know About Variables

[[https://opensource.com/article/20/3/variables-emacs][read online]]

A must read!

*** elisp-guide

[[https://github.com/chrisdone/elisp-guide][read online]]

Focused on introducing general concepts and terminology.

*** Emergency Elisp

[[http://steve-yegge.blogspot.com/2008/01/emergency-elisp.html][read online]]

Focused around data structures.
More like a cheat sheet.

*** ergoemacs - Practical Emacs Lisp

[[http://xahlee.info/emacs/emacs/elisp.html][read online]]

Not super up to date but generally well put together.

One of the first resources on the web introducing Elisp in a concise and comprehensible way.

Please note that the more complex examples follow a coding style regarded as not so great: big monolithic functions instead of multiple small functional ones.

To Xah's defense, some packages now considered standard are also written this way (we're looking at you =ediff=).

*** ElispCheatSheet

[[https://alhassy.github.io/ElispCheatSheet/][read online]], [[https://github.com/alhassy/ElispCheatSheet][source]]

Focused around data structures.

Author's Common Lisp background can be felt.

** Advanced

*** Emacs Lisp Reference Manual

[[https://www.gnu.org/software/emacs/manual/html_node/elisp/index.html][read online]]

Also comes bundled with Emacs.
Just =C-h i= (or =M-x info=) and open =Elisp=.

Comprehensive guide of core Elisp APIs.

Generally well written but needs you to understand its logic and be familiar with Emacs terminology.

*** The Emacs Lisp Style Guide

[[https://github.com/bbatsov/emacs-lisp-style-guide][read online]]

Provides solid guidelines on the dos and don'ts for quality Elisp code.

*** The Emacs Package Developer’s Handbook

[[https://alphapapa.github.io/emacs-package-dev-handbook/][read online]], [[https://github.com/alphapapa/emacs-package-dev-handbook][source]]

[[#alphapapa][@alphapapa]]'s organized notes about Elisp development.

List bunch of tools and libraries for helping package developers.

Also provides various snippets and best practices.

Lots of good insights.

*** nullprogram.com

[[#chris-wellons-skeeto][Chris Wellons (@skeeto)]]'s blog, especially the posts tagged [[https://nullprogram.com/tags/elisp/][#elisp]].

A few highlights:

- [[https://nullprogram.com/blog/2018/02/14/][Options for Structured Data in Emacs Lisp]]
- [[https://nullprogram.com/blog/2010/07/26/][Elisp Memoize]]
- [[https://nullprogram.com/blog/2017/10/27/][Make Flet Great Again]]
- [[https://nullprogram.com/blog/2013/01/22/][The Limits of Emacs Advice]]
- [[https://nullprogram.com/blog/2017/01/30/][How to Write Fast(er) Emacs Lisp]]

*** Emacs Lisp Programming Thoughts

[[https://www.nongnu.org/emacs-tiny-tools/elisp-coding/][read online]]

Pretty old but has very good insights, guidelines and real-world examples.

Byte compiler section is outdated but general coding style recommendations and sections about macros and profiling are still relevant to this day.

** Cookbooks

*** elisp-demos

[[https://github.com/xuchunyang/elisp-demos/blob/master/elisp-demos.org][read online]], [[https://github.com/xuchunyang/elisp-demos][source]]

Very good and beginner-friendly.

Almost complete list of single-liner examples of standard function.
Also packs examples for =dash= and =s=.

*** Emacs In A Box - Elisp Snippets

[[http://caiorss.github.io/Emacs-Elisp-Programming/Elisp_Snippets.html][read online]], [[https://github.com/caiorss/Emacs-Elisp-Programming/blob/master/Elisp_Snippets.org][source]]

Really nice selection of snippets with real-world use-cases.

*** EmacsWiki's Cookbook

[[https://www.emacswiki.org/emacs/ElispCookbook][read online]]

Community-driven snippets, beginner-friendly.

*** @alphapapa's unpackaged.el

[[https://alphapapa.github.io/unpackaged.el/][read online]], [[https://github.com/alphapapa/unpackaged.el][source]]

Real-world selection of snippets, not beginner-friendly.

** On Package Authoring

[[#the-emacs-lisp-styleguide][The Emacs Lisp Style Guide]] applies all the more in this context.

*** Article: Take Your Emacs to the Next Level by Writing Custom Packages

[[https://spin.atomicobject.com/2016/05/27/write-emacs-package/][read online]]

Real world experience of a user writing and submitting his first package.

*** MELPA recommandations

[[https://github.com/melpa/melpa/blob/master/CONTRIBUTING.org#making-your-package-ready-for-inclusion][read online]]

There's a high chance that you'll be uploading your package on [[https://melpa.org/][MELPA]].

They have clear recommandations.

Don't worry, for your first submissions, they will be very comprehensive and will help you fixing what's wrong.

** Contributing to Emacs

The [[https://www.gnu.org/software/emacs/CONTRIBUTE][CONTRIBUTE]] file is the official document describing the process. Additional development tips and coding conventions can be found in the [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Tips.html#Tips][Elisp Manual]].

=M-x view-emacs-todo= shows a lists of TODO items you might want to work on. You can also browse the bug archive using =M-x debbugs-gnu= using the [[https://elpa.gnu.org/packages/debbugs.html][debbugs]] package.

[[https://archive.casouri.cat/note/2020/contributing-to-emacs/][Contributing to Emacs]] gives some helpful background information and overview about the contribution workflow for newcomers.

** Interactive Development & Debugging

Emacs is built with interactive development in mind.

You could spend days developing Elisp code without ever having to restart Emacs.

Standard /commands/ used are:

**** IELM

 [[./rsc/icon/standard.png]]

 Stands for Inferior Emacs Lisp Mode.

 Provides a [[https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop][REPL]] for evaluating Elisp code.

**** edebug

 [[https://github.com/emacs-mirror/emacs/blob/master/lisp/emacs-lisp/edebug.el][source]], [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Edebug.html][doc]]

 [[./rsc/icon/standard.png]]

 edebug is the interactive Elisp debugger.

 The documentation is a bit rough to get started.
 I recommend reading this series of posts:
 - [[https://endlessparentheses.com/debugging-emacs-lisp-part-1-earn-your-independence.html][Endless Parentheses - Debugging Elisp Part 1: Earn your independence]]
 - [[https://endlessparentheses.com/debugging-elisp-part-2-advanced-topics.html][Endless Parentheses - Debugging Elisp Part 2: Advanced topics]]

 You can also read the dedicated [[https://www.gnu.org/software/emacs/manual/html_node/eintr/Debugging.html][chapter in book An Introduction to Programming in Emacs Lisp]].

**** trace

 [[https://github.com/emacs-mirror/emacs/blob/master/lisp/emacs-lisp/trace.el][source]]

 [[./rsc/icon/standard.png]]

 Provides a simple facility to output a trace of function calls into a buffer (=*trace-buffer*=).

 Please note that this trace is very basic and has no performance data. For more advanced tracing see [[#profiling][Profiling]].

 Tracing is switched on / off with /commands/ =trace-function=, =untrace-function= and =untrace-all=.

**** macrostep

 [[https://github.com/joddie/macrostep][source & doc]]

 Interactive macro expander.

 Expand nested macros one by one.

 Way better than using default =macroexpand=.

**** eval-expr

 [[https://github.com/jwiegley/eval-expr][source]]

 Provides =eval-expr=, an enhanced =eval-expression= command.

 Some highlights:
 - automatic display of output in temp buffer if too big
 - allows pretty printing of results (with =pp=)
 - invalid /s-expr/ don't have to be retyped on 2nd try

**** eval-sexp-fu

 [[https://github.com/emacsmirror/eval-sexp-fu][source]]

 Visual improvment.

 Flashes the sexps during the evaluation.

**** eros

 [[https://github.com/xiongtx/eros][source]]

 Show evaluation results inline.

** Documentation & Introspection

To get the documentation of a symbol, you could use one of the built-in:

*** helpful

[[https://github.com/Wilfred/helpful][source & doc]]

Provides more contextual information.

| helpful command     | default command     | comment                                                            |
|---------------------+---------------------+--------------------------------------------------------------------|
| =helpful-at-point=  | =describe-symbol=   |                                                                    |
| =helpful-callable=  | no equivalent       | like =helpful-function= but also works on macros and special forms |
| =helpful-function=  | =describe-function= |                                                                    |
| =helpful-macro=     | no equivalent       |                                                                    |
| =helpful-variable=  | =describe-variable= |                                                                    |
| =helpful-key=       | =describe-key=      |                                                                    |

*** elisp-demos

[[https://github.com/xuchunyang/elisp-demos][source]]

Provides usage examples in the =*Help*= buffer.

*** which-key

[[https://github.com/justbur/emacs-which-key][source & doc]]

=which-key= is like an always-on =describe-key=.

It displays automatically all the possible keybindings following a key prefix.

*** suggest

[[https://github.com/Wilfred/suggest.el][source]]

Discover elisp functions by specifying input and the desired output.

** Code Editing

*** Jump to definition

To jump to the definition of a symbol Emacs provides =xref-find-definitions=. In practice it works with nicely with functions but is kind of hit-or-miss with variables.

In addition, the following more specialised functions exist:

**** elisp-def

[[https://github.com/Wilfred/elisp-def][source & doc]]

Provides =elisp-def= that allows jumping to the definition of function / variable / feature.

Like a better =xref-find-definitions=.

Is able to distinguish between functions / variables / features depending on the context.

Also handles macros, functions defined through macros and let-bound variables.

*** Search & Replace

In Emacs regular expressions can make use of syntax information provided by the major-mode. This means that to some extend semantic searches are possible with =isearch= and =occur=.
To search and jump to toplevel definitions of a buffer you can use the built-in =imenu=. The [[https://github.com/vspinu/imenu-anywhere][imenu-anywhere]] package allows to extend the scope to buffers of the same project or mode.

**** elisp-refs

 [[https://github.com/Wilfred/elisp-refs][source]]

 Semantic code search for Elisp which parses the code instead of doing dump text searches.

**** el-search

 [[https://elpa.gnu.org/packages/el-search.html][source]]

 Lets you execute search and replace operations on symbolic expressions. For example you can search for things like defvars which don't specify an init value using the pattern `(defvar ,_)`.

*** Editing

Honorable mentions:
- [[https://github.com/joaotavora/yasnippet][YASnippet]]: generic (not Elisp-specific) powerful abreviation-based snippet expander.  Even though it could be used in the place of =speed-of-thought-lisp=, it is less context-aware and requires a specific key combination to trigger. It offers other features, though, and can be used complementarily.

**** speed-of-thought-lisp

 [[https://github.com/Malabarba/speed-of-thought-lisp][source]]

 Allows writting Elisp blazingly fast with the use of context-aware abbreviations triggered after =<SPACE>= keypress.

**** elisp-docstring

 [[https://github.com/Fuco1/elisp-docstring-mode][source]]

 Enriched syntax highlighting for docstring contents. Together with [[https://github.com/magnars/string-edit.el][string-edit]] you can edit docstrings in a temporary buffer and get automated special character escaping.

*** Editing S-exps

Elisp is a Lisp and Lisps are written using a structure of nested lists called [[https://en.wikipedia.org/wiki/S-expression][S-expressions]].

Mastering how to navigate and manipulate this structure with ease is essential.

By default Emacs doesn't offer much apart from =forward-list= / =backward-list= and =forward-sexp= / =backward-sexp=.

Luckily, powerful minor-modes are available to give you the power you deserve.

**** lispy

 [[https://github.com/abo-abo/lispy][source & doc]], [[http://oremacs.com/lispy/][cheat sheet]], [[https://www.youtube.com/user/abo5abo/videos][video demos]]

 Easiest to learn yet most powerful solution in that list.

 Like =paxedit=, /commands/ are context-aware.

 The killing feature is that shortcuts are single characters and not key combinations.

 The trick is that commands get triggered only when the point is at a delimiter (e.g. a parenthesis) or the region is active.

 Provides a powerful /command/ combination system and refactoring commands.

**** symex

 [[https://github.com/drym-org/symex.el][source & doc]]

 Builds on =paredit=, =lispy= and =evil-cleverparens= to provide a consistent vim-style modal way of editing trees.

 Offers a hydra interface to aid learning, and an =evil= state (also works in vanilla emacs).

**** paxedit

 [[https://github.com/promethial/paxedit][source & doc]]

 Heavily inspired by =paredit=.

 The major difference with the latter is that /commands/ are context-aware, they behave differently depending on what the cursor is hovering on.

 The direct consequence is that fewer /commands/ / shortcuts needs to be learned to perform the same amount of things.

**** paredit

 [[http://danmidwood.com/content/2014/11/21/animated-paredit.html][tutorial]], [[https://github.com/emacsmirror/paredit][source]]

 The first powerful S-exp editing mode for Emacs.

 Learning curve is a bit steep.

 Still actively maintained and very popular.

*** Refactoring

**** elisp-depmap

 [[https://github.com/mtekman/elisp-depmap.el][source & doc]]

 Aids the refactoring process by presenting a graphical visualization of project dependencies.

**** emacs-refactor

 [[https://github.com/Wilfred/emacs-refactor][source & doc]]

 Contains various refactoring commands for Elisp.

*** Formatting

**** aggressive-indent-mode

 [[https://github.com/Malabarba/aggressive-indent-mode][source & doc]]

 Auto-indents code as you type.

**** elfmt

 [[https://github.com/riscy/elfmt][source]]

 Focuses on placement of lists and tries to break lines at =fill-column=

** Testing

For simulating interactive user input, consider using libraries such as [[#with-simulated-input][with-simulated-input]] (launch /commands/) and [[#dokey][dokey]] (simulated keyboard shortcut presses). To test behavior and interactive usage in a clean and temporary environment [[https://github.com/alphapapa/emacs-sandbox.sh][emacs-sandbox.sh]] is useful.

**** ERT

 [[https://www.gnu.org/software/emacs/manual/html_node/ert/index.html][doc]], [[https://nullprogram.com/blog/2012/08/15/][blog post on nullprogram.com]]

 [[./rsc/icon/standard.png]]

 Stands for /"Emacs Lisp Regression Testing"/.

 Featureful and easy to use.

 Suitable for [[https://en.wikipedia.org/wiki/Unit_testing][unit tests]] with /mocking/.

**** Buttercup

 [[https://github.com/jorgenschaefer/emacs-buttercup][source & doc]]

 /Behavior-Driven Emacs Lisp Testing/

 Especially suitable for [[https://en.wikipedia.org/wiki/Integration_testing][integration tests]].

 Allows defining test suites (i.e. goups of related tests) with a shared context (through /set-up/ and /tear-down/ phases).

 Also provides mocking capabilities.

 For a complete example of integration w/ =undercover= and =coverage=:
 - [[https://sachachua.com/blog/2022/01/coverage-reporting-in-emacs-with-buttercup-undercover-coverage-and-a-makefile/][Sacha Chua - Coverage reporting in Emacs with Buttercup, Undercover, Coverage, and a Makefile]]

**** director

 [[https://github.com/bard/emacs-director][source & doc]]

 Program sequence of user interactions. Useful for end-to-end testing.

 Inspired by Selenium Webdriver.

**** undercover

 [[https://github.com/undercover-el/undercover.el][source & doc]]

 Track test coverage and integrate w/ coverage reporting solutions.

 For in-Emacs reporting, use the [[https://github.com/trezona-lecomte/coverage][coverage]] package.

** Profiling

Emacs provides 2 Elips profilers:

*** etrace

[[https://github.com/aspiers/etrace][source & doc]]

Wrapper around =elp.el= outputting a report in the /Chromium Catapult Trace Event Format/.

This allows opening them in external applications to explore them as /flame graphs/.

** Validation

Emacs provides various functions to validate an Elisp file / project:

**** melpazoid

 [[https://github.com/riscy/melpazoid][source & doc]]

 In addition to standard validation, it adds a license checker and some [[https://github.com/riscy/melpazoid/blob/master/melpazoid/melpazoid.el][additional checks]].

 Created by MELPA member [[https://github.com/riscy][@riscy]] to validate submissions.

 Does not run tests.

 Provides recipes for integration with /GitHub actions/ or /Travis/.

**** makem.sh

 [[https://github.com/alphapapa/makem.sh][source & doc]]

 Very straightforward way to validate an Emacs package folder / repository.

 Provides a makefile with different targets to run.

 Implemented in bash with a makefile wrapper.

 Performs linting (=make lint=), tests (=make test=) or everything (=make all=).

 In addition to standard checks, also validates indentation and optionally [[#elsa][elsa]] checks.

 Supports both ERT and buttercup tests.

 One drawback is that this makem.sh sources have to be dropped in each of your package source repository.

 Provides recipes for integration with /GitHub actions/.

**** makel

 [[https://gitea.petton.fr/DamienCassou/makel][source & doc]]

 Provides a makefile with different targets to run.

 Implemented completely as a makefile.

 Requires a bit of configuration for each package.

 One drawback is that this makel sources have to be dropped in each of your package source repository.

 No CI integration recipes.

**** elisp-check

 [[https://github.com/leotaku/elisp-check][source]]

 A zero config github action to validate packages.

**** auto-compile

 [[https://github.com/emacscollective/auto-compile][source]]

 Compiles current file on save and display compile errors/warnings in the mode-line.

**** elisp-lint

 [[https://github.com/gonewest818/elisp-lint][elisp-lint]]

 Performs standard validation of specified file. Also checks for indentation.

 No CI integration recipes.

**** elsa

 [[https://github.com/emacs-elsa/Elsa][source]]

 Static Elisp code analyzer providing helpful hints.

 Can be launched directly from [[#makem.sh][makem.sh]].

**** package-lint

 [[https://github.com/purcell/package-lint][source]]

 Lints Elisp files for requirements of packages. Can be integrated with flycheck (a general linter framework) by installing [[https://github.com/purcell/flycheck-package][flyspell-package]].

** Building

Those tools, in addition to what those in the [[#validation][Validation]] section provide, are full-fledged build-definition tools, allowing to make complex CI/CD chains.

They require a fair amount of configuration and are not for the faint of heart.

They only seem necessary when building larger packages with exotic dependencies.

**** Eldev

 [[https://github.com/doublep/eldev][source & doc]]

 Stands for /"Elisp Development Tool"/.

 Certainly the most modern of the lot.

 100% written in Elisp.

 One small drawback is that it does not run in a dedicated isolated Emacs process.

**** cask

[[https://cask.readthedocs.io/en/latest/][doc]], [[https://github.com/cask/cask][source]]

Pretty advanced and hard to get into.

Implemented in python.

Runs in a dedicated isolated Emacs process

**** emake

 [[https://github.com/vermiculus/emake.el][source & doc]]

 The most simple to use from this list.

 Implemented in Elisp with a makefile wrapper.

 Easier to integrate with CI tools such as /Travis/.

**** Elisp Repo Kit

 [[https://github.com/positron-solutions/elisp-repo-kit][elisp-repo-kit]]

 Create new fully-featured Github repositories with minimal effort, including doc generation and CI.

 Integrates common development & distribution workflows such as testing & package reloading.

 Designed to work out of the box but also appropriate for complex 3rd party and non-Elisp module integrations.

** Syntax Highlighting & Visual Enhancements

Several packages provide visual improvements and extend default syntax highlighting (/font locking/ in Emacs lingo).

All those listed bellow are complementary.

Honorable mentions:

*** lisp-extra-font-lock

[[https://github.com/Lindydancer/lisp-extra-font-lock][source & doc]]

Various additional syntax highlightings.

Killer feature is having different faces for /special/ vars (global) VS /normal/ ones (local).

*** highlight-function-calls

[[https://github.com/alphapapa/highlight-function-calls][source & doc]]

Make functions calls stand out with a specific face.

*** cl-lib-highlight

[[https://github.com/skeeto/cl-lib-highlight][source & doc]]

Provides additional / alternative font-locking for =cl-lib= symbols, to make them stand out in your code.

Also highlights deprecated =cl= symbols with a different face. Useful when reading legacy code.

*** easy-escape

[[https://github.com/cpitclaudel/easy-escape][source & doc]]

Make regular expression strings more readable.

*** nameless

[[https://github.com/Malabarba/Nameless][source & doc]]

Hide prefix in symbols of a package.

** Pretty Printing

**** pp

 [[https://github.com/emacs-mirror/emacs/blob/master/lisp/emacs-lisp/pp.el][source]]

 [[./rsc/icon/standard.png]]

 Standard Emacs pretty-printing util.

**** ppp

 [[https://github.com/conao3/ppp.el][source & doc]]

 Advanced pretty-printing utils.

** Core / General Purpose

**** cl-lib

 [[./rsc/icon/standard.png]]

 Lib extending Elisp with functionalities inherited from Common Lisp. Replaces the deprecated =cl= package which did not use name prefixes. To help with updating the code from =cl= to =cl-lib= there is [[https://github.com/purcell/cl-libify][cl-libify]].

 Just do a =(require 'cl-lib)= to use it.

**** subr-x

 [[https://github.com/emacs-mirror/emacs/blob/master/lisp/emacs-lisp/subr-x.el][source]]

 [[./rsc/icon/standard.png]]

 Intended as an extension to [[https://github.com/emacs-mirror/emacs/blob/master/lisp/subr.el][subr.el]], the core library of basic functions written in Elisp.

 Provides:
 - threading macros (/a la/ Clojure, =thread-first= and =thread-last=)
 - additional binding helpers (=if-let=, =if-let*=, =when-let=, =when-let*= and =and-let*=)    - hash-table manipulation helper (=hash-table-empty-p=, =hash-table-keys= and =hash-table-values=)
 - string manipulation helper (=string-empty-p=, =string-blank-p=, =string-join=, =string-trim=, =string-trim-left=, =string-trim-right=, =string-remove-prefix= and =string-remove-suffix=)
 - region manipulation helpers (=replace-region-contents=)

**** dash

 [[https://github.com/magnars/dash.el][source & doc]]

 [[./rsc/icon/informal-standard.png]]

 Even though this lib revolves primarily around list manipulation, it also offers for general purpose utils.

 Those are:
 - [[https://github.com/magnars/dash.el#threading-macros][threading macros]]
 - [[https://github.com/magnars/dash.el#function-combinators][function combinators]]
 - [[https://github.com/magnars/dash.el#binding][additional binding helpers]]

 They all seem to be heavily inspired by Clojure.

**** el-patch

 [[https://github.com/raxod502/el-patch][source and doc]]

 More perene advices, get notified when they break.

**** anaphora

 [[https://github.com/rolandwalker/anaphora][source & doc]]

 Allows the definition of anaphoric functions (as can be found in Common Lisp, Clojure...).

**** with-simulated-input

 [[https://github.com/DarwinAwardWinner/with-simulated-input][source & doc]]

 [[./rsc/icon/informal-standard.png]]

 Simulate user interactions (i.e. launch /commands/).

 Mostly usefull for writing tests.

**** dokey

 [[https://github.com/ernstvanderlinden/emacs-dokey][source & doc]]

 Trigger keyboard events.

**** contract

 [[https://github.com/langston-barrett/contract.el][source & doc]]

 Provides data structure defintions as contracts (essentially interface description).

 Port of [[https://docs.racket-lang.org/reference/contracts.html][Racket's contract]] to Elisp.

 Akin to [[https://clojure.org/about/spec][Clojure's spec]].

**** signal

 [[https://github.com/Mola-T/signal][source & doc]]

 Reimplementation of hooks, with more advanced features.

**** weak-ref

 [[https://github.com/skeeto/elisp-weak-ref][source & doc]]

 Allows creating weak reference to vars.
 Weak reference offer better performance but can be garbage collected.

**** predd

 [[https://github.com/skeeto/predd][source & doc]], [[https://nullprogram.com/blog/2013/12/18/][blog post]]

 Provides Clojure-style /multimethods/ (multiple dispatch over an ad hoc type hierarchy).

**** cats

 [[https://github.com/Fuco1/emacs-cats][source & doc]]

 Provices Haskell-inspired Category Theory abstractions.

**** fn

 [[https://github.com/troyp/fn.el][source & doc]]

 Provides macros for a more concise lambda syntax, /a la/ Clojure.

** Data Structures

*** Strings

**** subr-x

 [[https://github.com/emacs-mirror/emacs/blob/master/lisp/emacs-lisp/subr-x.el][source]]

 [[./rsc/icon/standard.png]]

 Provide the following helpers: =string-empty-p=, =string-blank-p=, =string-join=, =string-trim=, =string-trim-left=, =string-trim-right=, =string-remove-prefix= and =string-remove-suffix=.

**** s

 [[https://github.com/magnars/s.el][source & doc]]

 [[./rsc/icon/informal-standard.png]]

 Advanced yet easy to use string manipulation helpers.

**** rx

 [[https://francismurillo.github.io/2017-03-30-Exploring-Emacs-rx-Macro/][tutorial]], [[https://github.com/emacs-mirror/emacs/blob/master/lisp/emacs-lisp/rx.el][source]]

 [[./rsc/icon/standard.png]]

 Macro for helping writing Elisp regexp.

**** xr

 [[https://github.com/mattiase/xr][source & doc]]

 Convert regexp to their more human-readable =rx= macro form.

 Also provides regexp linting, detecting mistakes and bad practices.

 Relies on its own internal [[#parsers--parse-trees][parser]].

*** Sequences

**** seq

 [[https://github.com/emacs-mirror/emacs/blob/master/lisp/emacs-lisp/seq.el][source]], [[https://github.com/NicolasPetton/seq.el][doc]]

 [[./rsc/icon/standard.png]] (since version 25)

**** dash

 [[https://github.com/magnars/dash.el][source & doc]]

 [[./rsc/icon/informal-standard.png]]

 Advanced yet easy to use list manipulation helpers.
 Lots of them also have alternative anaphoric forms.

**** stream

 [[https://github.com/NicolasPetton/stream][source & doc]]

 Allows defining streams of data as data sequences.
 Compatible w/ seq.el.

**** trie

 [[http://www.dr-qubit.org/predictive/trie.el][source]]

 Provides APIs for building and manipulating /tries/, sequence-like data structures where both storage and retrieval are space- and time-efficient.

 Stored elements must be ordered sequences, i.e. strings (most common use-case), lists or vectors.

**** lister

 [[https://github.com/publicimageltd/lister][source & doc]]

 Provides =lister-mode=, major mode for building and manipulating list-based user-interfaces.

 Inspired by =tablist= (for tables) and =hierarchy= (for trees).

*** Maps

(Hash)maps are a special type of sequences that allow representing a list of key / value pairs.
In other languages they can also be called associative arrays or dictionaries.

In Elisp, a map can be represented as:
- an [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Association-Lists.html][alist]] (association list, preserving element order)
- a [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Property-Lists.html][plist]] (property list, more human-readable)
- an [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Hash-Tables.html][hash-table]]

| data structure | human-readability | insert speed | lookup speed         | ordered? |
|----------------+-------------------+--------------+----------------------+----------|
| alist          | meh               | fastest      | slower as data grows | yes      |
| plist          | very good         | ok           | fast                 | no       |
| hash-table     | ok                | ok           | very fast            | no       |

The official doc also has [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Plists-and-Alists.html][a nice section comparing plists and alists]].

tl;dr:
- planning on doing lots of inserts and a few lookups (or mostly on recent elements), use an alist
- planning on having a big number of elements and lookup speed is critical, use an hash-map
- every other case, use a plist

Older Emacs packages tend to rely mostly on alists, sometimes for no good reason.

Each data structure has its own APIs to get/insert/update.

Thankfully, some libraries provide an abstraction layer that allows having a single API for multiple data structures.

I would recommend sticking with the default =map.el= library, unless you really enjoy the Clojure syntax in which case =a.el= is also a nice choice.
If you know for sure that you want to stick with an alist or a hash-table,  =asoc.el= and =ht= are high quality choices.

**** map

 [[https://github.com/emacs-mirror/emacs/blob/master/lisp/emacs-lisp/map.el][source]]

 [[./rsc/icon/standard.png]] (since version 25)

 supports: alists, plists and hash-tables.

 Shared API for all 3 Elisp map objects (+ [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Arrays.html][arrays]]).

 No documentation other than what is inlined in source.

**** asoc

 [[https://github.com/troyp/asoc.el][source & doc]]

 [[./rsc/icon/informal-standard.png]]

 supports: only alists.

 Nice set of additional APIs for alists.

**** ht

 [[https://github.com/Wilfred/ht.el][source & doc]]

 [[./rsc/icon/informal-standard.png]]

 supports: only hash-tables, but allow converting from/to alists and plists.

 Nice set of additional APIs for hash-tables.

**** a

 [[https://github.com/plexus/a.el][source & doc]]

 supports: alists and hash-tables.

 Shared API for alists and hash-tables.
 Like =map.el=, but in a more "Clojurey" syntax.

**** kv

 [[https://github.com/nicferrier/emacs-kv][source & doc]]

 support: mostly alists, but allow converting from/to alists and plists.

**** dict-tree

 [[http://www.dr-qubit.org/predictive/dict-tree.el][source]]

 Provides APIs for building and manipulating /Dictionary trees/, hybrid between [[#trie][tries]] and hash tables.

 Think about it as a more storage-efficient hash tables.

*** Custom Types & OOP

Can be done natively using [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Records.html#Records][records]], additional custom user-defined types.

**** cl-lib (defstruct API)

 [[https://www.gnu.org/software/emacs/manual/html_node/cl/Structures.html][API documentation]]

 [[./rsc/icon/standard.png]]

 One part of =cl-lib= is APIs to define and manipulate C-like data structures, strongly typed.

 Provides the =cl-defstruct= macro.

 Built on top of the native [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Records.html#Records][records]] system.

 See also this blog post from @skeeto: [[https://nullprogram.com/blog/2018/02/14/][Options for Structured Data in Emacs Lisp]]

**** EIEIO

 [[https://www.gnu.org/software/emacs/manual/html_mono/eieio.html][doc]]

 [[./rsc/icon/standard.png]]

 Stands for /Enhanced Implementation of Emacs Interpreted Objects/.

 Brings an OOP layer to Elisp, based upon the /Common Lisp Object System/ (CLOS).

 Provides the =defclass= macro.

 Built on top of the native [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Records.html#Records][records]] system.

*** Date & Time

**** ts

 [[https://github.com/alphapapa/ts.el][source & doc]]

 [[./rsc/icon/informal-standard.png]]

 Advanced yet easy to use datetime / timestamp library.

**** datetime

 [[https://github.com/doublep/datetime][source & doc]]

 Library for parsing, formatting, matching and recoding timestamps and date-time format strings.

**** datetime-format

 [[https://github.com/emacs-php/emacs-datetime][source & doc]]

 Provides =datetime-format=, inspired by PHP’s =Datetime::format= method.

*** Tables

**** tabulated-list

 [[./rsc/icon/standard.png]]

 Library for defining, manipulating and displaying tables.

**** tablist

 [[https://github.com/politza/tablist][source & doc]]

 [[./rsc/icon/informal-standard.png]]

 Extension to =tabulated-list=, adding possibility to mark and filter items.

**** navigel

 [[https://github.com/DamienCassou/navigel][source]]

 Facilitate the creation of =tabulated-list=-based UIs.

 Also relies on =tablist=.

**** gridlock

 [[https://github.com/articuluxe/gridlock][source & doc]]

 Provides =gridlock-mode=, major mode for building and manipulating spreadsheet-based user-interfaces

 Also provides =gridlock-csv-mode= and =gridlock-fix-mode= minor modes, backporting the API to CSV and FIX files.

**** cell

 [[http://xelf.me/cell.html][doc]], [[https://gitlab.com/dto/mosaic-el/blob/master/cell.el][source]]

 Provides =cell-mode=, major mode for building and manipulating spreadsheet-based user-interfaces.

**** ctable

 [[https://github.com/kiwanami/emacs-ctable][source & doc]]

 Library for defining, manipulating and displaying tables.

*** Queues

**** queue

 [[http://www.dr-qubit.org/predictive/queue.el][source]]

 [[./rsc/icon/standard.png]]

 Provides FIFO / FILO queue APIs.

**** fifo-class

 [[https://github.com/mola-T/fifo-class][source & doc]]

 An EIEIO abstract class class to provide FIFO methods to /[[https://www.gnu.org/software/emacs/manual/html_node/eieio/Slot-Options.html][slots]]/.

*** Rings

Even though =ring= is the standard implementation, some core libs use their own internal implementation (e.g. the [[https://www.gnu.org/software/emacs/manual/html_node/eintr/ring-file.html][kill-ring]]).

**** ring

 [[https://github.com/emacs-mirror/emacs/blob/master/lisp/emacs-lisp/ring.el][source]]

 [[./rsc/icon/standard.png]]

 Provides APIs to create and manipulate a ring data structure.

 Used by: =ERC=

**** dynaring

 [[https://github.com/countvajhula/dynaring][source]]

 Similar to =ring=, but w/ a dynamic size.

*** Trees

Escaped and nested S-exps is the most straightforward way to encode a tree in (E)lisp.

Some libraries deliver higherèlevel data structure with manipulation functions for improved performance and convenience.

**** heap

 [[http://www.dr-qubit.org/predictive/heap.el][source]]

 Provides APIs to build and manipulate a /ternary/ (at most 3 children per node) /heap/ (self-sorting tree).

**** avl-tree

 [[http://www.dr-qubit.org/predictive/avl-tree.el][source]]

 [[./rsc/icon/standard.png]]

 Provides APIs to build and manipulate a self-balancing binary tree.

**** hierarchy

 [[https://github.com/DamienCassou/hierarchy][source & doc]], [[https://emacs.cafe/emacs/guest-post/2017/06/26/hierarchy.html][blog post]]

 Allows defining trees as well as building user interfaces displaying them.

**** treepy

 [[https://github.com/volrath/treepy.el][source & doc]]

 Allows defining and traversing trees.

**** taxy

 [[https://github.com/alphapapa/taxy.el][source & doc]]

 Allows defining hierarchical taxonomies, i.e. trees w/ automatic classification based on (nested) rules.

**** rbit

 [[http://elpa.gnu.org/packages/rbit.html][source]]

 Self-balancing interval trees.

 Implementation of Chris Okasaki's algorithm from [[https://dl.acm.org/citation.cfm?id=968578.968583&coll=DL&dl=GUIDE]["Red-black trees in a functional setting", JFP'99]].

**** pair-tree

 [[https://github.com/zainab-ali/pair-tree.el][source & doc]]

 Visualize and explore nested S-exps as a tree.

*** Parsers & Parse Trees

Those libraries allow parsing a document in a format / language and converting it to an tree, called an an [[https://en.wikipedia.org/wiki/Abstract_syntax_tree][AST]].

**** parse-it

 [[https://github.com/jcs-elpa/parse-it][source & doc]]

 Regexp-based parser, supporting a bunch of languages.

**** tree-sitter

 [[https://ubolonton.github.io/emacs-tree-sitter/][doc]], [[https://github.com/ubolonton/emacs-tree-sitter/][source]], [[https://www.reddit.com/r/emacs/comments/chnxzm/dynamic_module_binding_for_treesitter_an/][reddit post]], [[https://blog.meain.io/2022/more-treesitter-emacs/][example usage article]]

 Implemented as a module, binding with the [[https://tree-sitter.github.io/tree-sitter/][tree-sitter]] parser (written in Rust).

 For a concrete use-case, have a look at [[https://github.com/ethan-leba/tree-edit][tree-edit]].

 For a better sitter grammar for elisp (distinguishing between var, functions and macros), use [[https://github.com/Wilfred/tree-sitter-elisp][tree-sitter-elisp]].

**** moldable-emacs

 [[https://github.com/ag91/moldable-emacs][source & doc]], [[Moldable Emacs, a step towards sustainable software][presentation @ EmacsConf21]]

 Powerful parser and transformer library, relying on the concept of composable functional *molds*.

 Also support asynchronous processing (relying on [[#async][async]]).

**** tNFA

 [[http://www.dr-qubit.org/predictive/tNFA.el][source]]

 Provides APIs to build and manipulate NFA (/Nondeterministic Finite Automaton/), i.e. a state machine / decision tree.

 It was built manily with regexp parsing in mind.

**** parsec

 [[https://github.com/cute-jumper/parsec.el][source & doc]]

 Parsing library in the spirit of Haskell's parsec.

**** pl

 [[https://github.com/jwiegley/emacs-pl][source & doc]]

 Parsing library in the spirit of Haskell's parsec. Somewhat limited.

*** XML/HTML

**** dom

 [[./rsc/icon/standard.png]]

 DOM manipulation and searching functions.

**** xml-query

 [[https://github.com/skeeto/elfeed/blob/master/xml-query.el][source]]

 List-based XML selectors. Part of the elfeed package.

*** Org-mode outlines

=org-mode= outlines ([[https://orgmode.org/worg/dev/org-syntax.html][spec]]) can be considered both a file format and a tree format.

**** org-element

[[https://code.orgmode.org/bzg/org-mode/src/master/lisp/org-element.el][source]], [[https://orgmode.org/worg/dev/org-element-api.html][doc]], [[http://xahlee.info/emacs/emacs/elisp_parse_org_mode.html][tutorial on ergoemacs]]

[[./rsc/icon/standard.png]]

=org-mode='s internal parser, used to convert a text buffer into a tree structure (/parse-tree/).

**** org-ml

 [[https://github.com/ndwarshuis/org-ml][source & doc]]

 Functional manipulation of an org parse-tree.

**** org-ql

 [[https://github.com/alphapapa/org-ql][source & doc]]

 Query language ([[https://en.wikipedia.org/wiki/Domain-specific_language][DSL]]) for parsing, searching and filtering an org outline.

**** org-ba

 [[https://github.com/Fuco1/orgba][source & doc]]

 More user-friendly APIs for writting code for interacting with org documents.

*** Faces

/Faces/ are a group of attributes controlling the formatting of text in Emacs.

It's akin to CSS for HTML or styling [[https://en.wikipedia.org/wiki/ANSI_escape_code][ANSI escape sequences]] for terminal text.

You can read more about /faces/ in the [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Faces.html][Emacs manual]] or the [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Faces.html][Emacs Lisp Reference Manual]].

**** engrave-faces

 [[https://github.com/tecosaur/engrave-faces][source & doc]]

 Convert faces to other formats.

 Currently, only LaTeX is supported.

*** Color Codes

**** color

 [[https://github.com/emacs-mirror/emacs/blob/master/lisp/color.el][source]]

 [[./rsc/icon/standard.png]]

**** color-tools

 [[https://github.com/neeasade/color-tools.el][source & doc]], [[https://notes.neeasade.net/color-spaces.html][blog post]]

 Color codes manipulation, with support for various color spaces.

**** yk-color

 [[https://github.com/yurikhan/yk-color][source]]

 Color codes manipulation.

** Concurrency / Asynchronicity

Concurrency in Elisp / Emacs is a hot topic.

Due to its single-threaded nature, we can't do parallel processing unless using some dirty tricks (see [[#async][async]]).

But that doesn't prevent us from doing concurrent processing, with say /timers/.

Emacs recently extended this support with [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Generators.html][generators]] (since 25.1) and [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Threads.html][native threads]] (not what you might be thinking of, since 26.1).

For more info on those subject, read:

*** Timers

**** timer

 [[https://github.com/emacs-mirror/emacs/blob/master/lisp/emacs-lisp/timer.el][source]]

 [[./rsc/icon/standard.png]]

 Default timer lib.

**** named-timer

 [[https://github.com/DarwinAwardWinner/emacs-named-timer][source & doc]]

 Easier to use timer lib.

*** Promises & Delays

**** thunk.el

 [[https://github.com/emacs-mirror/emacs/blob/master/lisp/emacs-lisp/thunk.el][source]]

 [[./rsc/icon/standard.png]]

 Provides an API for creating and dereferencing / evaluating /delays/.

**** promise.el

 [[https://github.com/chuntaro/emacs-promise][source & doc]]

 Reimplementation of the [[https://promisesaplus.com/][Promises/A+]] open standard (originally targeting Javascript).

**** aio

 [[https://github.com/skeeto/emacs-aio][source & doc]], [[https://nullprogram.com/blog/2019/03/10/][blog post]]

 Mostly an async/await lib but implements its own promise system internally.

*** Async Elisp function calls

**** deferred

 [[https://github.com/kiwanami/emacs-deferred][source & doc]]

 [[./rsc/icon/informal-standard.png]]

 Not super-actively maintained, but quite stable and featureful.

 Achieves concurrency through the use of timers.

 Also allows handling async (sub-)processes and HTTP calls with [[https://github.com/tkf/emacs-request][request.el bindings]].

**** concurrent

 [[https://github.com/kiwanami/emacs-deferred/blob/master/concurrent.el][source]], [[https://github.com/kiwanami/emacs-deferred/blob/master/README-concurrent.markdown][doc]]

 Higher-level wrapper around =deferred=.

 Provides various syntaxes inspired by those of other programming languages, such as:
 - Clojure / Java / Lua's coroutines (=threads=)
 - Python's asyncio coroutines (=generators=)
 - Clojure's [[https://github.com/clojure/core.async][core.async]] pipelines (=signals= / =channels=).

**** async

 [[https://github.com/jwiegley/emacs-async][source & doc]]

 [[./rsc/icon/informal-standard.png]]

 Achieves true parallel processing by spawning a child Emacs sub-process.
 As such, necessary context needs to be passed w/ =async-inject-variables=.

 Supports defining callbacks.

 Offers bindings w/ =dired=, =bytecomp= and =smtp-mail=.

**** timp

 [[https://github.com/mola-T/timp][source & doc]]

 Multithreading through sub-processes with over-the-wire payload capabilities.

 Achieves true parallel processing by spawning a child Emacs sub-process for each thread.

**** aio

 [[https://github.com/skeeto/emacs-aio][source & doc]], [[https://nullprogram.com/blog/2019/03/10/][blog post]]

 Short for =async-io=.

 Allows writing coroutines with the async/await syntax found in Python's [[https://docs.python.org/3/library/asyncio.html][asyncio]].

 Internal representation relies on its own promise implementation and [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Generators.html][generators]].

**** async-await

 [[https://github.com/chuntaro/emacs-async-await][source & doc]]

 Simple implementation of Async/Await, based on the TypeScript syntax.

 Relies on =promise.el= and [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Generators.html][generators]].

**** lcr

 [[https://github.com/jyp/lcr][source]]

 lcr stands for Lightweight CoRoutines.

 Seems to rely on timers.

*** Async sub-processes

These libs only allow to run asynchronously command processes (as opposed to Elisp function calls).

It can be done in standard with low-level function =make-process= or derivatives =start-process=, =make-pipe-process= and =start-process-shell-command=.

Some advanced behaviours are hard to program, that's why wrapper libraries can help you.

Notably:
- ensuring the process is launched asynchronously (not blocking Emacs)
- configuring callbacks (by binding a [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Sentinels.html][sentinel]] to the process)

**** deferred

 [[https://github.com/kiwanami/emacs-deferred][source & doc]]

 Not super-actively maintained, but featureful.

 Also allows handling async Elisp function calls and HTTP calls with [[https://github.com/tkf/emacs-request][request.el bindings]].

**** bpr

 [[https://github.com/ilya-babanov/emacs-bpr][source & doc]]

 Stands for Background Process Runner.
 Allows running a command process in the background.

 Allows advanced callback behaviours.

 It relies on =start-process-shell-command=.

**** pfuture

 [[https://github.com/Alexander-Miller/pfuture][source & doc]]

 Allows running a command process in the background.

 Result can be handled either with a future (=pfuture-new=, =pfuture-result=) or a callback (=pfuture-callback=).

 It relies on =make-pipe-process= for the future-based implementation and =make-process= for the callback one.

*** Async interpreter commands

Emacs provides a layer on top of =make-process= for spawning commands from a shell interpreter (i.e. =bash= or =zsh=).

These are provided by =simple.el= ([[https://github.com/emacs-mirror/emacs/blob/master/lisp/simple.el][source]]).

The async version of these command is =async-shell-command=.

Some advanced behaviours are hard to program, that's why wrapper libraries can help you.

**** dtache

 [[https://gitlab.com/niklaseklund/dtache][source & doc]]

 Provides =dtache-shell-command=, a drop-in replacement for =async-shell-command= that allows command execution to persist even after the Emacs process exits.

 Also works on remote hosts.

 Relies on [[https://github.com/crigler/dtach][dtach]] to create a persistent session.

**** friendly-shell-command

 [[https://github.com/p3r7/friendly-shell][source & doc]]

 =friendly-shell-command= provides =friendly-shell-command-async=, a wrapper around =async-shell-command= with easier access to advanced behaviours thanks to optional keyword arguments.

 It notably eases associating a callback to the end of the execution, running on remote hosts and launching with alternative interpreters.

** Buffer Manipulation

**** b

 [[https://github.com/emacs-php/b.el][source & doc]]

 Utility functions for buffer manipulation.

**** tp

 [[https://github.com/alphapapa/tp.el][source]]

 Utilities for helping with manipulating a buffer's [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Text-Properties.html][text properties]].

**** m-buffer

 [[http://phillord.github.io/m-buffer-el/][doc]], [[https://github.com/phillord/m-buffer-el][source]]

 List-oriented functions for accessing and manipulating the contents of Emacs buffers.

** Filesystem Interactions

*** f

[[https://github.com/rejeep/f.el][source & doc]]

[[./rsc/icon/informal-standard.png]]

Modern API for working with files and directories.

** Networking

*** HTTP client

Emacs comes already with an HTTP client, =url.el=, written in pure Elisp ([[https://github.com/emacs-mirror/emacs/blob/master/lisp/url/url.el][source]]), which has a few limitations.
It exposes functions =url-retrieve-synchronously= and =url-retrieve= (async).

**** request

 [[https://github.com/tkf/emacs-request][source & doc]]

 [[./rsc/icon/informal-standard.png]]

 If found on the system, uses the /cURL/ binary instead of =url.el=.
 Can be customized with =request-backend=.

 Supports a bunch of options exposed clearly with keyword arguments.

 Advanced asynchronicity via bindings with =deferred=.

**** plz

 [[https://github.com/alphapapa/plz.el][source & doc]]

 Uses the /cURL/ binary (=curl=) instead of =url.el=.

 Supports a bunch of options exposed clearly with keyword arguments.

 Supports both synchronous & asynchronous calls, as well as queuing.

 When doing async request, the returned handler is a =curl= process object.

 Strong contender for a lightweight alternative to =request=.

**** mb-url

 [[https://github.com/dochang/mb-url][source & doc]]

 Stands for "Multiple Backends for URL package".

 Provides API-compatible replacements to =url-retrieve= and =url-retrieve-synchronously= using /cURL/ and /HTTPie/.

**** websocket

 [[https://github.com/ahyatt/emacs-websocket][source]]

 [[./rsc/icon/informal-standard.png]]

 Websocket (peristent HTTP connection) client for Emacs.

**** apiwrap

 [[https://github.com/vermiculus/apiwrap.el][source & doc]]

 Macros to ease the definition of binding functions to HTTP APIs.

**** with-proxy

 [[https://github.com/twlz0ne/with-proxy.el][source & doc]]

 Wrapper for let-binding HTTP proxies.

*** HTTP server

**** simple-httpd

 [[https://github.com/skeeto/emacs-web-server][source & doc]]

 A web server written in pure Elisp, serving HTTP.

**** web-server

 [[https://github.com/eschulte/emacs-web-server][source & doc]]

 A web server written in pure Elisp, serving HTTP APIs bound to Elisp functions (/handlers/).

*** RPC server

A [[https://en.wikipedia.org/wiki/Remote_procedure_call][Remote Procedure Call]] server allows Emacs to receive commands from a remote process through a messaging system.

It's a common strategy of [[https://en.wikipedia.org/wiki/Inter-process_communication][inter-process communication]] (IPC).

**** porthole

 [[https://github.com/jcaw/porthole][source & doc]]

 Start a HTTP-based RPC server under Emacs.

 Commands are direct Elisp code to be executed. They can (by default) only be called synchronously.

 Messages are encoded in JSON (following the [[https://www.jsonrpc.org/specification][JSON-RPC 2.0 Specification]]) which makes it support client libraries of almost any language.

 Relies on =web-server=.

**** EPC

 [[https://github.com/kiwanami/emacs-epc][source & doc]]

 Start a RPC client & server under Emacs.

 It implements its own protocol (over TCP) and support both synchronous & asynchronous execution (via bindings with =deferred=).

 Commands are explicitly defined (akin to handlers bound to /routes/ in an HTTP API).

 Messages are encoded as Lisp / S-exprs, which makes it more challenging to implement client libraries in non-Lisp languages.

*** D-Bus

D-Bus is the most popular [[https://en.wikipedia.org/wiki/Inter-process_communication][inter-process communication]] (IPC) protocol under Linux.

Emacs supports it by default.

**** dbus

 [[https://www.gnu.org/software/emacs/manual/html_mono/dbus.html][doc]], [[https://github.com/emacs-mirror/emacs/blob/master/lisp/net/dbus.el][source]]

 [[./rsc/icon/standard.png]]

 Very boilerplate-y to use.

**** debase

 [[https://github.com/ieure/debase][source & doc]]

 EIEIO abstractions over =dbus= for writting easier interaction code.

** Database Access

*** SQL

**** sql

 [[./rsc/icon/standard.png]]

 [[https://repo.or.cz/w/emacs.git/blob/HEAD:/lisp/progmodes/sql.el][source]], [[https://www.emacswiki.org/emacs/SqlMode][emacswiki]]

 Not a client /per se/.

 Provides =sql-mode=, a comint-based REPL wrapper supporting various CLI client interpreters.

**** sqlite

 [[./rsc/icon/standard.png]] (since version 29)

 Recent Emacs now embbeds a native SQLite3 database & the accompagnying client.

**** emacsql

 [[https://github.com/skeeto/emacsql][source & doc]]

 High-level client to SQLite, PostgreSQL & MySQL.

 Queries and schema definitions are written in specific tree-based DSLs, allowing easy programmatic manipulation.

**** closql

 [[https://github.com/emacscollective/closql][source]]

 [[https://en.wikipedia.org/wiki/Object%E2%80%93relational_mapping][ORM]] providing mapping between [[#eieio][EIEIO]] and SQLite tables.

 Relies on =emacsql=.

**** edbi

 [[https://github.com/kiwanami/emacs-edbi][source & doc]]

 Client to SQL dialects, using [[https://dbi.perl.org/][Perl's Database Interface]] (/DBI/) as a connection interface.

 In addition to programmatic querying capabilities, provides several major modes for user interactions with database instances.

**** triples

 [[https://github.com/ahyatt/triples][source & doc]]

 Abstraction on top of SQL clients (either =emacsql= or =sqlite=) to represent & store a graph database.

** GUI

Honorable mention: [[https://github.com/sabof/magic-buffer][magic-buffer]], an executable cookbook on how to use & abuse Emacs' buffer display engine.

*** Popups

**** frog-menu

 [[https://github.com/clemera/frog-menu][source & doc]]

 User selection menu in the form of a popup.

*** Overlays

**** ov

 [[https://github.com/emacsorphanage/ov][source & doc]]

 Helpers to manipulate overlays.
 Originally authored by [[https://github.com/ShingoFukuyama][@ShingoFukuyama]]. Unmaintained.

*** Charts & diagrams

**** chart

 [[https://francismurillo.github.io/2017-04-15-Exploring-Emacs-chart-Library/][tutorial]]

 [[./rsc/icon/standard.png]]

** @alphapapa

[[https://github.com/alphapapa][github]]

Contributed to Elisp development with:

** Bozhidar Batsov (@bbatsov)

[[https://github.com/bbatsov][github]], [[https://emacsredux.com/][Emacs-related blog]], [[https://github.com/sponsors/bbatsov][open to sponsoring]]

Known for:

** Caio Rordrigues (@caiorss)

[[https://github.com/caiorss][github]]

Contributed to Elisp development with:

** Chris Wellons (@skeeto)

[[https://github.com/skeeto][github]], [[https://nullprogram.com/][blog]]

Known for:

** John Wiegley (@jwiegley)

[[http://newartisans.com/][blog]], [[https://github.com/jwiegley][github]], [[https://github.com/jwiegley/dot-emacs/blob/master/init.el][dot emacs]]

Known for:

** Jonas Bernoulli (@tarsius)

[[https://emacsair.me/][blog]], [[https://github.com/tarsius][github]], [[https://magit.vc/donate/][open to sponsoring]]

Known for:

** Magnar Sveen (@magnars)

[[https://github.com/magnars][github]], [[http://twitter.com/magnars][twitter]]

Contributed to Elisp development with:

** Nicolas Petton

[[https://nicolas.petton.fr/][portfolio]], [[https://emacs.cafe/][blog]], [[https://github.com/NicolasPetton][github]]

Known for:

** Oleh Krehel (@abo-abo)

[[https://oremacs.com/][blog]], [[https://github.com/abo-abo][github]], [[https://github.com/sponsors/abo-abo][open to sponsoring]]

Author of many high-quality packages such as [[https://github.com/abo-abo/swiper][ivy]], [[https://github.com/abo-abo/hydra][hydra]], [[https://github.com/abo-abo/lispy][lispy]]...

** Toby 'qubit' Cubitt

[[http://www.dr-qubit.org/][website]]

Known for:

** Xah Lee

[[http://xahlee.info/emacs/index.html][website]], [[https://www.patreon.com/xahlee][open to sponsoring]]

A controversial figure in the Emacs community (he is [[http://xahlee.info/emacs/emacs/_p/KickbanXahLeeFromEmacsChannel.htm][notorious for trolling]]), Xah nethertheless created the first online digestible resource for learning Elisp.

His contribution to the Emacs world is unquestionable and as such he deserves his place in this list.

** Guidelines

*** PR and Issues

Open one issue or PR / subject matter.

Don't go submit a gazillion unrelated changes that would conflict with other's submitted PRs.

*** Opinions

Try to not be too opinionated.

Some solutions are objectively better in some regards than others and that can be stated but don't go launch a flame war.

Descriptions of libraries and tools expressed in this document are always subject to change. If a description feels too negative, don't hesitate to open an issue to discuss it.

*** Scope

The aim of this document is to (loosely) follow the style of other [[https://github.com/sindresorhus/awesome][awesome lists]].

Content should be concise and always follow the same format.

In this spirit, no block quotes, no code snippets and no in-depth explanation of concepts should appear here.

This is no cookbook, no manual, no article.

Section can have small introduction to contextualize things (e.g. built-in libs) but should remain succinct, instead favoring links to external articles.

The introduction of the [[#concurrency--asynchronicity][Concurrency / Asynchronicity]] is a good example of concisely presenting the necessary information and linking to external resources.

On the contrary, the [[#maps][Maps]] section goes into too much details and should instead link to an article.

**** Relevant Content: Development Tools

 In [[#development-tools][Development Tools]], only list tools and package that are specific to Elisp development.

 It's very tempting to list stuff such as =projectile= or =treemacs= but those packages apply not only to Elisp development and should not be listed.

 Don't create a sub-section for tools that have modern counterpart and are deprecated / no more maintained. You could eventually mention them like it's done for =highlight-defined= in [[#syntax-highlighting--visual-enhancements][Syntax Highlighting & Visual Enhancements]].

**** Relevant Content: Libraries

 In [[#libraries][Libraries]], only list packages that were created to be used as libraries and generic enough to target a broad range of applications.

 E.g. HTTP client libs such as =request= have their place, wrappers targeting a specific API (such as =ghub= or =pocket-lib=) don't.

*** Comments

Each linked resource / tool / library should be commented.

This comment is a short intro and analysis and must not be copy-pasted directly from the linked resource page.

Instead it should provide insights as to how it compares to other links in a similar category: what are the differences, advantages, drawbacks.

This description should be short and ideally not exceed a few lines.

*** Order of Tools & Libraries

Try to put the most "standard" entries first.

By standard we mean, in order: embedded in Emacs, most sane or used by the most people / projects.

*** Order of Categories

Don't submit a PR single-handedly deciding to reorganize the whole document structure.

Open an issue and provoke conversation.

What can feel natural to you can be counter-intuitive to others.

[[https://creativecommons.org/publicdomain/zero/1.0/][https://licensebuttons.net/p/zero/1.0/88x31.png]]

Ribbon icons courtesy of [[https://icons8.com][icons8]].