All Projects → p3r7 → Awesome Elisp

p3r7 / Awesome Elisp

Licence: unlicense
A curated list of emacs-lisp development resources

Projects that are alternatives of or similar to Awesome Elisp

Hackernews.el
Hacker News client for Emacs
Stars: ✭ 200 (-9.5%)
Mutual labels:  emacs
Uncledavesemacs
My personal ~/.emacs.d
Stars: ✭ 204 (-7.69%)
Mutual labels:  emacs
Modalka
Modal editing your way
Stars: ✭ 212 (-4.07%)
Mutual labels:  emacs
Evil Multiedit
Multiple cursors for evil-mode, based on iedit
Stars: ✭ 200 (-9.5%)
Mutual labels:  emacs
Emacs Module Rs
Rust binding and tools for emacs-module (Emacs's dynamic module support)
Stars: ✭ 203 (-8.14%)
Mutual labels:  emacs
Dotfiles
Ninrod's sharpened dotfiles for emacs, vim, zsh, tmux. Since '15.
Stars: ✭ 208 (-5.88%)
Mutual labels:  emacs
Emacs Direnv
direnv integration for emacs
Stars: ✭ 194 (-12.22%)
Mutual labels:  emacs
Emacs Bash Completion
Add programmable bash completion to Emacs shell-mode
Stars: ✭ 217 (-1.81%)
Mutual labels:  emacs
Elfeed Org
Configure the Elfeed RSS reader with an Orgmode file
Stars: ✭ 203 (-8.14%)
Mutual labels:  emacs
Github Review
Github code reviews with Emacs.
Stars: ✭ 210 (-4.98%)
Mutual labels:  emacs
Literate Calc Mode.el
🧮 Literate programming for M-x calc
Stars: ✭ 201 (-9.05%)
Mutual labels:  emacs
Toc Org
toc-org is an Emacs utility to have an up-to-date table of contents in the org files without exporting (useful primarily for readme files on GitHub)
Stars: ✭ 202 (-8.6%)
Mutual labels:  emacs
Fsautocomplete
F# language server using Language Server Protocol
Stars: ✭ 208 (-5.88%)
Mutual labels:  emacs
Lsp Treemacs
lsp-mode ❤️ treemacs
Stars: ✭ 200 (-9.5%)
Mutual labels:  emacs
Homebrew Emacs Head
GNU Emacs formula for the Homebrew package manager
Stars: ✭ 214 (-3.17%)
Mutual labels:  emacs
Evil Snipe
2-char searching ala vim-sneak & vim-seek, for evil-mode
Stars: ✭ 196 (-11.31%)
Mutual labels:  emacs
Verb
Organize and send HTTP requests from Emacs
Stars: ✭ 205 (-7.24%)
Mutual labels:  emacs
Vimish Fold
Vim-like text folding for Emacs
Stars: ✭ 220 (-0.45%)
Mutual labels:  emacs
Atom One Dark Theme
Atom One Dark - An Emacs port of the Atom One Dark theme from Atom.io.
Stars: ✭ 217 (-1.81%)
Mutual labels:  emacs
Doct
DOCT: Declarative Org Capture Templates for Emacs
Stars: ✭ 210 (-4.98%)
Mutual labels:  emacs

#+HTML:

Emacs Logo
  • Awesome Elisp

#+HTML:

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

It's 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]].

  • Table of Contents :TOC_5:QUOTE: #+BEGIN_QUOTE
  • [[#what-is-elisp][What is Elisp?]]
  • [[#resources][Resources]]
    • [[#entry-level][Entry-level]]
    • [[#advanced][Advanced]]
    • [[#cookbooks][Cookbooks]]
    • [[#on-package-authoring][On Package Authoring]]
    • [[#contributing-to-emacs][Contributing to Emacs]]
  • [[#development-tools][Development Tools]]
    • [[#interactive-development--debugging][Interactive Development & Debugging]]
    • [[#documentation--introspection][Documentation & Introspection]]
    • [[#code-editing][Code Editing]]
      • [[#jump-to-definition][Jump to definition]]
      • [[#search--replace][Search & Replace]]
      • [[#editing][Editing]]
      • [[#editing-s-exps][Editing S-exps]]
      • [[#refactoring][Refactoring]]
      • [[#formatting][Formatting]]
    • [[#testing][Testing]]
    • [[#profiling][Profiling]]
    • [[#validation][Validation]]
    • [[#building][Building]]
    • [[#syntax-highlighting--visual-enhancements][Syntax Highlighting & Visual Enhancements]]
    • [[#pretty-printing][Pretty Printing]]
  • [[#libraries][Libraries]]
    • [[#core--general-purpose][Core / General Purpose]]
    • [[#data-structures][Data Structures]]
      • [[#strings][Strings]]
      • [[#sequences][Sequences]]
      • [[#maps][Maps]]
      • [[#custom-types--oop][Custom Types & OOP]]
      • [[#date--time][Date & Time]]
      • [[#tables][Tables]]
      • [[#queues][Queues]]
      • [[#rings][Rings]]
      • [[#trees][Trees]]
      • [[#parsers--parse-trees][Parsers & Parse Trees]]
      • [[#xmlhtml][XML/HTML]]
      • [[#org-mode-outlines][Org-mode outlines]]
      • [[#color-codes][Color Codes]]
    • [[#concurrency--asynchronicity][Concurrency / Asynchronicity]]
      • [[#timers][Timers]]
      • [[#promises--delays][Promises & Delays]]
      • [[#async-elisp-function-calls][Async Elisp function calls]]
      • [[#async-sub-processes][Async sub-processes]]
      • [[#async-interpreter-commands][Async interpreter commands]]
    • [[#buffer-manipulation][Buffer Manipulation]]
    • [[#filesystem-interactions][Filesystem Interactions]]
    • [[#networking][Networking]]
      • [[#http-client][HTTP client]]
      • [[#http-server][HTTP server]]
    • [[#database-access][Database Access]]
    • [[#gui][GUI]]
      • [[#popups][Popups]]
      • [[#overlays][Overlays]]
      • [[#charts--diagrams][Charts & diagrams]]
  • [[#heroes][Heroes]]
  • [[#contributing][Contributing]]
  • [[#license][License]] #+END_QUOTE
  • What is Elisp?

    Elisp is short for /Emacs Lisp/, a dialect of [[https://en.wikipedia.org/wiki/Lisp_programming_language][Lisp]] specific to Emacs.

    If you're a fresh Emacs user, you've certainly practiced it a bit by editing your =init.el= (i.e. configuration).

    You may also have spotted that most /packages/ (i.e. plugins) available to Emacs are written in pure Elisp.

    In fact, Elisp is not limited to extending Emacs functionalities: a good chunk (and [[https://archive.fosdem.org/2020/schedule/event/emacsthoughts/][admittedly not enough]]) of Emacs is written in it.

    This means that any user can browse, extend or even override core Emacs functionalities at runtime.

    As such, at its core, Emacs is [[https://www.eigenbahn.com/2020/01/12/emacs-is-no-editor][not an editor]] but more a platform allowing users to write text-based apps.

    Being an editor is not its intrinsic nature but merely a feature.

    Learning Elisp will up your Emacs game tremendously, unlocking its full potential by writing functionalities either for your personal needs or to share with the world.

    As an added bonus, it's great fun.

  • Resources

** 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://with-emacs.com/posts/tutorials/almost-all-you-need-to-know-about-variables/][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://ergoemacs.org/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.

  • Development Tools

    By default, Emacs is already pretty well set up for Elisp development.

    But some features can be hard to learn and some stuff can be improved with additinal packages.

    See also those talks [[https://github.com/p3r7/awesome-elisp#john-wiegley-jwiegley][John Wiegley]] gave about hist setup for Elisp development:

    • [[https://www.youtube.com/watch?v=QFClYrhV1z4][Emacs Lisp Development - @ Emacs Conference 2013]]
    • [[https://sachachua.com/blog/2015/04/2015-04-08-emacs-lisp-development-tips-with-john-wiegley/][Emacs Lisp Development Tips - Sacha Chua Emacs Chat 2015-04-08]].

** 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:

  • =eval-last-sexp= (=C-x C-e=)
  • =eval-defun= (=C-M-x=)
  • =eval-buffer=
  • =eval-region=

The =scratch= buffer also provides a temporary zone to try and test ideas. In it can be used =eval-print-last-sexp= (=C-j=) which acts like =eval-last-sexp= but also prints the result after the /s-exp/ in the buffer.

=eval-expression= (=M-:=) allows quickly evaluating a /s-exp/ from anywhere by entering it in the /minibuffer/.

For logging, function =(message "")= allows printing into the =Messages= buffer.

For debugging, the most basic command is =toggle-debug-on-error= to get a stacktrace.

See also:

  • [[https://www.masteringemacs.org/article/evaluating-elisp-emacs][Mastering Emacs - Evaluating Elisp in Emacs]]

**** IELM

 /standard/ (bundled with every Emacs install)

 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]]

 /standard/ (bundled with every Emacs install)

 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]]

 /standard/ (bundled with every Emacs install)

 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:

  • =describe-symbol=: get documentation of symbol
  • =describe-function=: get documentation of function
  • =describe-variable=: get documentation of variable
  • =describe-key=: get documentation of /command/ associated with keybinding

These would spawn a =Help= buffer. Hence documentation in Emacs is often referred to as the /help/. For searching through symbols Emacs also comes with various =apropos-*= commands which populate a buffer with your search results.

Some packages improve on these.

*** 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:

  • =find-function=: go to the definition of function
  • =find-variable=: go to the definition of function
  • =find-library=: go to the definition of /feature/ (i.e. module, package)

Better options exists so that you don't have to remember all of these.

Honorable mention: [[https://github.com/purcell/elisp-slime-nav][elisp-slime-nav]], that can be seen as an ancestor to =elisp-def=. If you want to jump to symbols in files which aren't loaded in your Emacs you can fallback to the more general [[https://github.com/jacktasia/dumb-jump][dumb-jump]] package.

**** 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 requiring 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.

**** 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]]

 /standard/ (bundled with every Emacs install)

 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.

** Profiling

Emacs provides 2 Elips profilers:

  • =profiler.el=: profile a whole call stack, easier to use
  • =elp.el=: profile only selected functions

Both are briefly mentioned in the [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Profiling.html][profiling section]] of the /Emacs Lisp Reference Manual/.

Either one is of a great help to debug slow Elisp code, most noticeable during user interactions (Emacs seems to freeze).

=profiler.el= is easily toggled using =profiler-start=, =profiler-stop=. To obtain a result report call =profiler-report=.

=elp.el= can target individual functions with =elp-instrument-function= or a whole package with =elp-instrument-package=.

To profile individual forms Emacs also comes with the =benchmark= library. The /Emacs Package Developer’s Handbook/ has a [[https://github.com/alphapapa/emacs-package-dev-handbook#profiling--optimization][whole section]] dedicated to this with thorough examples and helper macros.

*** 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:

  • =byte-compile-file=: validate the file compiles cleanly
  • =checkdoc=: validate the documentation
  • =check-declare-file= / =check-declare-directory=: validate the declaration of symbols
  • =package-lint-current-buffer=: validate format for submitting as a package

It's tedious to run manually each and every of those commands. Thankfully projects aim at making this process easier.

For maximum efficiency, they can be integrated into a [[https://en.wikipedia.org/wiki/Continuous_integration][CI]] chain (/GitHub actions/ or /Travis/).

**** 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/.

** 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: - [[https://github.com/Fanael/highlight-defined][highlight-defined]] which is superseded by =lisp-extra-font-lock= functionalities

Not Elisp-specific but commonly used in the context of Elisp development: - traditionally, /form feed/ characters (=^L=) are used in Elisp source as a section delimiters. Either [[https://github.com/purcell/page-break-lines][page-break-lines]] or [[https://depp.brause.cc/form-feed/][form-feed]] can be used to display them as intended. - for those that can barely stand parentheses, [[https://github.com/tarsius/paren-face][paren-face]] can be used to dim them in Lisp-based modes - for those that love parentheses, [[https://github.com/Fanael/rainbow-delimiters][rainbow-delimiters]] allows displaying them in different colors depending on their nesting depth

*** 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]]

 /standard/ (bundled with every Emacs install)

 Standard Emacs pretty-printing util.

**** ppp

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

 Advanced pretty-printing utils.
  • Libraries

    Traditionally, it was recommended to not use external libs/dependencies and prefer using standard APIs bundled with Emacs.

    These recommendation are still mostly valid but predated the advent of =package.el=.

    Some external libs are now considered "standard", as lots of popular packages use them and they can outperform standard implementations while still being simpler to use (e.g. =dash=).

    Some libraries might be listed several times, as they fit in several categories (e.g. =subr-x=, =dash=).

** Core / General Purpose

**** cl-lib

 /standard/ (bundled with every Emacs install)

 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]]

 /standard/ (bundled with every Emacs install)

 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]]

 /informal standard/ (not bundled with Emacs, but used everywhere)

 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]]

 /informal standard/ (not bundled with Emacs, but used everywhere)

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

 Mostly usefull for writing tests.

**** dokey

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

 Trigger keyboard events.

**** 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).

**** 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]]

 /standard/ (bundled with every Emacs install)

 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]]

 /informal standard/ (not bundled with Emacs, but used everywhere)

 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]]

 /standard/ (bundled with every Emacs install)

 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]]

 /standard/ (bundled with every Emacs install, since version 25)

**** dash

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

 /informal standard/ (not bundled with Emacs, but used everywhere)

 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 thee 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 or  =asoc.el= and =ht= are high quality choice.

**** map

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

 /standard/ (bundled with every Emacs install, since version 25)

 supports: alists, plists and hash-tables.

 Shared API for all 3 Elisp map objects.
 Weirdly enough, plists are called "arrays" in its source/inline docs.

 No documentation other than what is inlined in source.

**** asoc

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

 /informal standard/ (not bundled with Emacs, but used everywhere)

 supports: only alists.

 Nice set of additional APIs for alists.

**** ht

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

 /informal standard/ (not bundled with Emacs, but used everywhere)

 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]]

 /standard/ (bundled with every Emacs install)

 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]]

 /standard/ (bundled with every Emacs install)

 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]]

 /informal standard/ (not bundled with Emacs, but used everywhere)

 Advanced yet easy to use datetiem / 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

 /standard/ (bundled with every Emacs install)

 Library for defining, manipulating and displaying tables.

**** tablist

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

 /informal standard/ (not bundled with Emacs, but used everywhere)

 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]]

 /standard/ (bundled with every Emacs install)

 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]]

 /standard/ (bundled with every Emacs install)

 Provides APIs to create and manipulate a ring data structure.

 Used by: =ERC=

*** 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]]

 /standard/ (bundled with every Emacs install)

 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.

**** 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]]

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

**** 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

 /standard/ (bundled with every Emacs install)

 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 can be considered both a file format and a tree format.
=org-element.el= ([[https://orgmode.org/worg/dev/org-element-api.html][doc]]) implements the parser used by =org-mode= 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]]

 /standard/ (bundled with every Emacs install)

**** 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:

  • [[https://www.emacswiki.org/emacs/NoThreading][emacswiki/No Threading]]
  • [[https://www.emacswiki.org/emacs/NoThreading][emacswiki/Concurrent Emacs]]
  • blog post from @skeeto: [[https://nullprogram.com/blog/2018/05/31/][Emacs 26 Brings Generators and Threads]]

*** Timers

**** timer

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

 /standard/ (bundled with every Emacs install)

 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]]

 /standard/ (bundled with every Emacs install)

 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]]

 Not super-actively maintained, but 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]]

 /informal standard/ (not bundled with Emacs, but used everywhere)

 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.

**** 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.

** 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]]

/informal standard/ (not bundled with Emacs, but used everywhere)

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]]), wich has a few limitations.
It exposes functions =url-retrieve-synchronously= and =url-retrieve= (async).

**** request

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

 Supports a bunch of options exposed clearly with keyword arguments.

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

 Advanced asynchronicity via bindings with =deferred=.

**** 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/.

**** 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.

** Database Access

*** SQL

**** 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.

** GUI

*** 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]]

 /standard/ (bundled with every Emacs install)
  • Heroes

    Emacs has too many heroes to really list.

    In this section, we list some users who have significantly contributed with libraries and resources that improve the Emacs development experience.

    They are listed in alphabetical order.

    Another complementary list is [[https://github.com/tarsius/elisp-maintainers][elisp-maintainers]].

** @alphapapa

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

Contributed to Elisp development with:

  • [[https://github.com/alphapapa/emacs-package-dev-handbook][The Emacs Package Developer’s Handbook]]
  • =makem.sh=
  • =ts=
  • =org-ql=

** Bozhidar Batsov (@bbatsov)

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

Known for:

  • [[https://github.com/bbatsov/projectile][projectile]]: the best project management package for Emacs
  • [[https://cider.mx/][CIDER]]: the interactive Clojure development environment for Emacs

Contributed to Elisp development with:

  • [[https://github.com/bbatsov/emacs-lisp-style-guide][The Emacs Lisp Style Guide]]

** Caio Rordrigues (@caiorss)

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

Contributed to Elisp development with:

  • his book [[http://caiorss.github.io/Emacs-Elisp-Programming/][Emacs In a Box]]

** Chris Wellons (@skeeto)

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

Known for:

  • [[https://github.com/skeeto/elfeed][elfeed]], the popular Emacs RSS reader
  • [[https://github.com/skeeto/skewer-mode][skewer-mode]], interactive web development with auto-reload on edit

Contributed to Elisp development with:

  • his blog, /nullprogram.com/
  • =aio=
  • =emacsql=
  • =simple-httpd=
  • =week-ref=

** 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:

  • being the head of the Emacs project maintainers
  • authoring =use-pacakge=

Contributed to Elisp development with:

  • =async.el=
  • talks on how to setup Emacs to ease Elisp development:
    • [[https://www.youtube.com/watch?v=QFClYrhV1z4][Emacs Lisp Development - @ Emacs Conference 2013]]
    • [[https://sachachua.com/blog/2015/04/2015-04-08-emacs-lisp-development-tips-with-john-wiegley/][Emacs Lisp Development Tips - Sacha Chua Emacs Chat 2015-04-08]].

** Jonas Bernoulli (@tarsius)

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

Known for:

  • authoring [[https://github.com/magit/magit][magit]]
  • lots of high quality smaller packages ([[https://github.com/tarsius/orglink][orglink]], [[https://github.com/tarsius/keycast][keycast]]...)

Contributed to Elisp development with:

  • [[https://github.com/magit/transient][transient]]
  • =closql=

** Magnar Sveen (@magnars)

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

Contributed to Elisp development with:

  • [[https://github.com/magnars/s.el][s]] (strings)
  • [[https://github.com/magnars/dash.el][dash]] (lists)

** Nicolas Petton

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

Known for:

  • creating the popular [[https://github.com/NicolasPetton/Indium][Indium]] interactive Javascript development environment

Contributed to Elisp development with:

  • creating the now standard =seq.el= and =map.el=
  • =stream.el=

** 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:

  • [[http://www.dr-qubit.org/undo-tree/undo-tree.el][undo-tree]]

Contributed to Elisp development with [[http://www.dr-qubit.org/emacs_data-structures.html][his implementation of basic and more complex data structures]]: =queue=, =heap=, =avl-tree=, =trie=, =dict-tree=, =tNFA=.

** Xah Lee

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

A controversial figure in the Emacs community (he is [[http://ergoemacs.org/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.

  • Contributing

    Contributions and suggestions are always welcome!

    The [[https://github.com/p3r7][original author]] made this document available as he felt something like it was missing.

    The idea is to have this evolve into a community effort, the initial version being only a baseline.

** 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 a 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 package apply not only to Elisp development and should be listed.

 Don't create a sub-section 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 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.
  • License

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

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].