{"id":13894697,"url":"https://github.com/susam/emacs4cl","last_synced_at":"2025-05-14T23:15:51.389Z","repository":{"id":41170415,"uuid":"320580847","full_name":"susam/emacs4cl","owner":"susam","description":"A tiny DIY kit to set up vanilla Emacs for Common Lisp programming","archived":false,"fork":false,"pushed_at":"2024-02-27T00:01:08.000Z","size":278,"stargazers_count":381,"open_issues_count":1,"forks_count":23,"subscribers_count":14,"default_branch":"main","last_synced_at":"2024-11-24T23:33:53.495Z","etag":null,"topics":["common-lisp","dark-theme","emacs","emacs-initialization","emacs-lisp","minimalist","paredit","rainbow-delimiters","sbcl","slime"],"latest_commit_sha":null,"homepage":"","language":"Emacs Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/susam.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"custom":["https://www.buymeacoffee.com/susam"]}},"created_at":"2020-12-11T13:24:30.000Z","updated_at":"2024-11-06T08:34:20.000Z","dependencies_parsed_at":"2024-01-31T12:05:02.576Z","dependency_job_id":"f8a94a8e-a44c-4a73-a2e7-11adc2956429","html_url":"https://github.com/susam/emacs4cl","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susam%2Femacs4cl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susam%2Femacs4cl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susam%2Femacs4cl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susam%2Femacs4cl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/susam","download_url":"https://codeload.github.com/susam/emacs4cl/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254243313,"owners_count":22038048,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["common-lisp","dark-theme","emacs","emacs-initialization","emacs-lisp","minimalist","paredit","rainbow-delimiters","sbcl","slime"],"created_at":"2024-08-06T18:01:42.737Z","updated_at":"2025-05-14T23:15:51.366Z","avatar_url":"https://github.com/susam.png","language":"Emacs Lisp","funding_links":["https://www.buymeacoffee.com/susam"],"categories":["Emacs Lisp","Emacs ##"],"sub_categories":["Third-party APIs"],"readme":"Emacs For Common Lisp (Emacs4CL)\n================================\n\nThis repository provides a tiny [`.emacs`] file to set up Emacs quickly\nfor Common Lisp programming. This document provides a detailed\ndescription of how to set it up and get started with Common Lisp\nprogramming.\n\n[![View Source][Source SVG]][Source URL]\n[![MIT License][License SVG]][L]\n[![Mastodon][Mastodon SVG]][Mastodon URL]\n\n[Source SVG]: https://img.shields.io/badge/view-~%2f.emacs-brightgreen\n[Source URL]: .emacs\n[License SVG]: https://img.shields.io/badge/license-MIT-%233ea639\n[Mastodon SVG]: https://img.shields.io/badge/mastodon-%40susam-%2355f\n[Mastodon URL]: https://mastodon.social/@susam\n\nThis repository provides a good middle ground between configuring Emacs\nmanually by installing SLIME, Paredit, etc. yourself with `M-x\npackage-install` commands and installing Portacle. It promotes a\ndo-it-yourself approach to automate customizing Emacs for Common Lisp\nprogramming. Here is how the development environment is going to look\nlike:\n\n[![Screenshot of Emacs][screenshot]][screenshot]\n\n[screenshot]: https://susam.github.io/blob/img/emacs4cl/emacs4cl-0.5.0.png\n\nIf you are already comfortable with Emacs and only want to understand\nthe content of the [`.emacs`] file, you can skip ahead directly to the\n[Line-by-Line Explanation](#line-by-line-explanation) section that\ndescribes every line of this Emacs initialization file in detail.\n\n[`.emacs`]: .emacs\n\n\nContents\n--------\n\n* [Who Is This For?](#who-is-this-for)\n* [Get Started](#get-started)\n* [Step-by-Step Usage](#step-by-step-usage)\n  * [Use SBCL](#use-sbcl)\n  * [Use Emacs](#use-emacs)\n  * [Use SLIME](#use-slime)\n  * [Use Paredit](#use-paredit)\n  * [Use Rainbow Delimiters](#use-rainbow-delimiters)\n  * [Use Quicklisp](#use-quicklisp)\n* [Line-by-Line Explanation](#line-by-line-explanation)\n  * [Tweak UI](#tweak-ui)\n  * [Use Spaces for Indentation](#use-spaces-for-indentation)\n  * [Highlight Parentheses](#highlight-parentheses)\n  * [Install Packages](#install-packages)\n  * [Inferior Lisp Program](#inferior-lisp-program)\n  * [Add Hooks](#add-hooks)\n  * [Colorful Parentheses](#colorful-parentheses)\n* [More Emacs Customization](#more-emacs-customization)\n* [Alternatives](#alternatives)\n* [Opinion References](#opinion-references)\n* [Channels](#channels)\n* [License](#license)\n\n\nWho Is This For?\n----------------\n\nAre you an absolute beginner to Emacs? Are you so new to Emacs that\nyou do not even have `~/.emacs` or `~/.emacs.d` on your file system?\nHave you considered learning Common Lisp but when you picked up a book\nlike [Practical Common Lisp][pcl], you learnt that it recommends Emacs\nand SLIME for development environment and it seemed like a significant\nadditional learning curve for you? If you answered \"yes\" to most of\nthese questions, then this project is for you.\n\nThe [`.emacs`] file in this project provides you a quick way to get\nstarted with setting up your development environment. This document\nexplains how to do so in a step-by-step manner. This document also\nexplains the content of [`.emacs`] file in a line-by-line manner.\n\n[pcl]: http://www.gigamonkeys.com/book/\n[clc]: https://lispcookbook.github.io/cl-cookbook/\n\n\nGet Started\n-----------\n\nThis section helps you to set up Emacs for Common Lisp development\nquickly and see what the end result looks like. Perform the following\nsteps to get started:\n\n 1. Install SBCL and Emacs.\n\n    On macOS, enter the following command if you have\n    [Homebrew](https://brew.sh):\n\n    ```sh\n    brew install sbcl\n    brew install --cask emacs\n    ```\n\n    On Debian, Ubuntu, or another Debian-based Linux system, enter the\n    following command:\n\n    ```\n    sudo apt-get install sbcl emacs\n    ```\n\n    For other environments, download SBCL and Emacs from\n    http://www.sbcl.org/platform-table.html and\n    https://www.gnu.org/software/emacs/ respectively.\n\n 2. Copy the Emacs initialization file [`.emacs`] provided here to\n    your home directory. Here is an example `curl` command that copies\n    the initialization file to its traditional location:\n\n    ```sh\n    curl -L https://github.com/susam/emacs4cl/raw/main/.emacs \u003e\u003e ~/.emacs\n    ```\n\n    Here is another alternative that copies the initialization file to\n    a more convenient location:\n\n    ```sh\n    mkdir ~/.emacs.d\n    curl -L https://github.com/susam/emacs4cl/raw/main/.emacs \u003e\u003e ~/.emacs.d/init.el\n    ```\n\n    Yet another popular alternative is to copy the initialization file\n    to an XDG-compatible location as follows:\n\n    ```sh\n    mkdir -p ~/.config/emacs\n    curl -L https://github.com/susam/emacs4cl/raw/main/.emacs \u003e\u003e ~/.config/emacs/init.el\n    ```\n\n    Emacs can automatically load the Emacs initialization file from\n    any of the paths used above. See section [The Emacs Initialization\n    File][emacs-init-doc] of the Emacs manual for more details about\n    this. Most users these days prefer one of the last two locations\n    because it allows all Emacs configuration to conveniently remain\n    in one directory.\n\n    [emacs-init-doc]: https://www.gnu.org/software/emacs/manual/html_node/emacs/Init-File.html\n\n 3. Start Emacs:\n\n    ```sh\n    emacs\n    ```\n\n    On macOS, you may receive the following error message in a dialog\n    box: '“Emacs.app” can’t be opened because Apple cannot check it for\n    malicious software.' To resolve this issue, go to Apple menu \u003e\n    System Preferences \u003e Security \u0026 Privacy \u003e General and click 'Open\n    Anyway'.\n\n    It may take a minute or so for Emacs to start the very first time.\n    When it starts the first time with the new Emacs initialization\n    file obtained in the previous step, it installs the packages\n    specified in it. This is only a one-time activity. The next time you\n    start Emacs, it will start instantly. We will see how [`.emacs`]\n    takes care of it in the line-by-line guide later.\n\n 4. Within Emacs, start SLIME by typing the following key sequence:\n\n    ```\n    M-x slime RET\n    ```\n\n    In the Emacs world (and elsewhere too), the prefix `M-` denotes the\n    meta modifier key. It does not exist on most modern keyboards. Use\n    the \u003ckbd\u003ealt\u003c/kbd\u003e key or the \u003ckbd\u003eoption\u003c/kbd\u003e key as a modifier\n    key or \u003ckbd\u003eesc\u003c/kbd\u003e as a prefix key to enter `M-`.\n\n    For example, `M-x` is going to be \u003ckbd\u003ealt\u003c/kbd\u003e + \u003ckbd\u003ex\u003c/kbd\u003e or\n    \u003ckbd\u003eoption\u003c/kbd\u003e + \u003ckbd\u003ex\u003c/kbd\u003e or \u003ckbd\u003eesc\u003c/kbd\u003e \u003ckbd\u003ex\u003c/kbd\u003e on a\n    modern keyboard.\n\n    Similarly, `RET` denotes the \u003ckbd\u003eenter\u003c/kbd\u003e key or the\n    \u003ckbd\u003ereturn\u003c/kbd\u003e key.\n\n 5. After SLIME REPL starts, enter the following expression at the\n    `CL-USER\u003e` prompt and type \u003ckbd\u003eenter\u003c/kbd\u003e.\n\n    ```lisp\n    (format t \"hello, world~%\")\n    ```\n\n    If the output `\"hello, world\"` appears in SLIME REPL, the\n    development environment setup is complete.\n\n 6. Optionally, install Quicklisp with the following commands:\n\n    ```sh\n    curl -O https://beta.quicklisp.org/quicklisp.lisp\n    sbcl --load quicklisp.lisp --eval \"(quicklisp-quickstart:install)\" --quit\n    sbcl --load ~/quicklisp/setup.lisp --eval \"(ql:add-to-init-file)\" --quit\n    ```\n\n    Quicklisp helps in installing Common Lisp libraries from its\n    repository. You do not need it when you have just begun learning\n    Common Lisp. But as you grow more experienced with Common Lisp and\n    begin developing real world applications, sooner or later, you will\n    need Quicklisp to install libraries that help you solve your\n    problems.\n\n    The first command in the code block fetches `quicklisp.lisp`. The\n    second command installs Quicklisp to `~/quicklisp`. The third\n    command adds some code to SBCL's initialization file at `~/.sbclrc`,\n    so that Quicklisp is automatically loaded when SBCL starts.\n\nNow that your environment is setup, read the next section to learn how\nto use this environment in more detail.\n\n\nStep-by-Step Usage\n------------------\n\n### Use SBCL\n\nSteel Bank Common Lisp (SBCL) is a high performance Common Lisp\ncompiler. It runs on several Unix and Unix-like systems such as Linux,\nFreeBSD, macOS, etc. It also runs experimentally on Windows. It is the\nmost popular free and open source implementation of Common Lisp as of\nDecember 2020. See the [Opinion References](#opinion-references) section\nfor survey results related to this.\n\nThe steps provided below show how to run SBCL independently. This is not\na typical way to run SBCL because most of the time we interact with SBCL\nvia SLIME right from within Emacs. However running it independently once\nhelps one appreciate that it is an independent program that compiles and\nexecutes Common Lisp code. Here are the steps:\n\n 1. Open your favourite editor, type this code, and save it as\n    `hello.lisp`:\n\n    ```lisp\n    (format t \"hello, world~%\")\n    ```\n\n 2. Then enter this command in the shell to run the program:\n\n    ```sh\n    sbcl --script hello.lisp\n    ```\n\n 3. Now start the SBCL Read-Eval-Print Loop (REPL) with the following\n    command in the shell:\n\n    ```sh\n    sbcl\n    ```\n\n 4. An asterisk prompt appears. Enter a Common Lisp expression at the\n    asterisk prompt like this and type \u003ckbd\u003eenter\u003c/kbd\u003e:\n\n    ```lisp\n    (+ 1 2)\n    ```\n\n    The result should appear as the output.\n\n 5. Similarly, enter the following expression at the SBCL prompt and\n    type \u003ckbd\u003eenter\u003c/kbd\u003e:\n\n    ```lisp\n    (format t \"hello, world~%\")\n    ```\n\n 6. Finally, enter the following expression and type \u003ckbd\u003eenter\u003c/kbd\u003e\n    to exit the SBCL REPL:\n\n    ```lisp\n    (exit)\n    ```\n\n\n### Use Emacs\n\nEmacs is a very powerful and extensible editor. It comes with over\n10,000 built-in commands. A small section like this can barely scratch\nthe surface of Emacs. Yet, this section makes a modest attempt at\ngetting you started with Emacs and then provides more resources to\nlearn further. Perform the following steps to get started:\n\n 1. Start Emacs:\n\n    ```sh\n    emacs\n    ```\n\n 2. Within Emacs, enter the following command to open a file, say,\n    `hello.txt`:\n\n    ```\n    C-x C-f hello.txt RET\n    ```\n\n    A new buffer to edit `hello.txt` is created. If a file with that\n    name already exists on your file system, then it loads the content\n    of the file into the buffer.\n\n    Note that in the Emacs world (and elsewhere too), the\n    notation `C-` denotes the \u003ckbd\u003ectrl\u003c/kbd\u003e modifier key. Thus `C-x`\n    denotes \u003ckbd\u003ectrl\u003c/kbd\u003e + \u003ckbd\u003ex\u003c/kbd\u003e.\n\n    The notation `RET` denotes the \u003ckbd\u003eenter\u003c/kbd\u003e or \u003ckbd\u003ereturn\u003c/kbd\u003e\n    key.\n\n    Typing consecutive `C-` key sequences can be optimized by pressing\n    and holding down the \u003ckbd\u003ectrl\u003c/kbd\u003e key, then typing the other\n    keys, and then releasing the \u003ckbd\u003ectrl\u003c/kbd\u003e key. For example, to\n    type `C-x C-f`, first press and hold down \u003ckbd\u003ectrl\u003c/kbd\u003e, then\n    type \u003ckbd\u003ex\u003c/kbd\u003e, then type \u003ckbd\u003ef\u003c/kbd\u003e, and then release\n    \u003ckbd\u003ectrl\u003c/kbd\u003e. In other words, think of `C-x C-f` as `C-(x f)`.\n    This shortcut works for other modifier keys too.\n\n 3. Now type some text into the buffer. Type out at least 3-4 words. We\n    will need it for the next two steps.\n\n 4. Move backward by one word with the following key sequence:\n\n    ```\n    M-b\n    ```\n\n    Remember from the previous section that `M-` denotes the meta\n    modifier key. The above command can be typed with\n    \u003ckbd\u003ealt\u003c/kbd\u003e + \u003ckbd\u003eb\u003c/kbd\u003e or \u003ckbd\u003eoption\u003c/kbd\u003e + \u003ckbd\u003eb\u003c/kbd\u003e or\n    \u003ckbd\u003eesc\u003c/kbd\u003e \u003ckbd\u003eb\u003c/kbd\u003e.\n\n    If you face any issue with the \u003ckbd\u003ealt\u003c/kbd\u003e key or the\n    \u003ckbd\u003eoption\u003c/kbd\u003e key, read [Emacs Wiki: Meta Key\n    Problems](https://www.emacswiki.org/emacs/MetaKeyProblems).\n\n 5. Now move forward by one word with the following key sequence:\n\n    ```\n    M-f\n    ```\n\n 5. The `C-g` key sequence cancels the current command. This can be used\n    when you mistype a command and want to start over or if you type a\n    command partially, then change your mind and then you want to cancel\n    the partially typed command. Try out these examples:\n\n    ```\n    C-x C-f C-g\n    ```\n\n    ```\n    C-x C-g\n    ```\n\n 7. Save the buffer to a file on the file system with this command:\n\n    ```\n    C-x C-s\n    ```\n\n 8. Quit Emacs:\n\n    ```\n    C-x C-c\n    ```\n\nNow you know how to start Emacs, open a file, save it, and quit. Improve\nyour Emacs knowledge further by taking the Emacs tutorial that comes\nalong with Emacs. In Emacs, type `C-h t` to start the tutorial.\n\nThe key bindings to perform various operations like creating file,\nsaving file, quitting the editor, etc. may look arcane at first, but\nrepeated usage of the key bindings develops muscle memory soon and after\nhaving used them for a few days, one does not even have to think about\nthem. The fingers do what the mind wants effortlessly due to muscle\nmemory.\n\nWhile you are getting used to the Emacs key bindings, keep this [GNU\nEmacs Reference Card][emacs-ref] handy.\n\n[emacs-ref]: https://www.gnu.org/software/emacs/refcards/pdf/refcard.pdf\n\n\n### Use SLIME\n\nSuperior Lisp Interaction Mode for Emacs (SLIME) is a very popular Emacs\nmode that adds support for interacting with a running Common Lisp\nprocess for compilation, debugging, document lookup, etc. while\ndeveloping Common Lisp applications. Perform the following steps to get\nstarted with it:\n\n 1. Start Emacs:\n\n    ```sh\n    emacs\n    ```\n\n 2. Within Emacs, start SLIME by typing the following key sequence:\n\n    ```\n    M-x slime RET\n    ```\n\n    Remember that `M-x` translates to \u003ckbd\u003ealt\u003c/kbd\u003e + \u003ckbd\u003ex\u003c/kbd\u003e or\n    \u003ckbd\u003eesc\u003c/kbd\u003e \u003ckbd\u003ex\u003c/kbd\u003e on a modern keyboard.\n\n 3. A new buffer named `*slime-repl sbcl*` should have now appeared with\n    the following prompt:\n\n    ```\n    CL-USER\u003e\n    ```\n\n    This is a Read-Eval-Print-Loop (REPL) where you can evaluate Common\n    Lisp expressions.\n\n 3. Enter the following expression in the REPL:\n\n    ```lisp\n    (+ 1 2)\n    ```\n\n    The following result should appear when you type \u003ckbd\u003eenter\u003c/kbd\u003e:\n\n    ```\n    3\n    ```\n\n 4. We will now see how to work on a Lisp source file and send\n    expressions to the REPL for evaluation using SLIME commands without\n    having to leave Emacs. First, create a buffer for a new file, for\n    example:\n\n    ```\n    C-x C-f foo.lisp\n    ```\n\n 5. Now enter this Lisp code into the buffer for `foo.lisp`:\n\n    ```lisp\n    (+ 1 2)\n    ```\n\n 6. While the cursor is placed after the closing parenthesis (not on it,\n    but after it), type the following command:\n\n    ```\n    C-x C-e\n    ```\n\n    The result `3` should appear in a minibuffer at the bottom.\n\nThere is a lot more to SLIME than what is described above. To learn more\nabout SLIME, see [Slime User Manual][slime-doc]. Also, keep this [Slime\nQuick Reference Card][slime-ref] handy.\n\n[slime-doc]: https://www.gnu.org/software/emacs/manual/html_node/emacs/index.html\n[slime-ref]: http://www.chiark.greenend.org.uk/doc/slime/slime-refcard.pdf\n\n\n### Use Paredit\n\nParedit helps in keeping parentheses balanced and also in performing\nstructured editing of S-expressions in Lisp code. It provides a powerful\nset of commands to manipulate S-expressions in various ways. Perform the\nfollowing steps to get started with Paredit:\n\n 1. Run Emacs:\n\n    ```sh\n    emacs\n    ```\n\n 2. Open a Common Lisp source file:\n\n    ```\n    C-x C-f foo.lisp\n    ```\n\n 3. Type the following code only:\n\n    ```lisp\n    (defun square (x\n    ```\n\n    At this point, Paredit should have inserted the two closing\n    parentheses automatically. The code should look like this:\n\n    ```lisp\n    (defun square (x))\n                    -\n    ```\n\n    The cursor should be situated just after the parameter `x`. The\n    underbar shows where the cursor should be.\n\n 4. Type the closing parentheses now. Yes, type it even if the closing\n    parenthesis is already present. The cursor should now skip over the\n    first closing parenthesis like this:\n\n    ```lisp\n    (defun square (x))\n                     -\n    ```\n\n    Of course, there was no need to type the closing parenthesis\n    because it was already present but typing it out to skip over it\n    is more efficient than moving over it with movement commands. This\n    is, in fact, a very nifty feature of Paredit. We can enter code\n    with the same keystrokes as we would without Paredit.\n\n 5. Now type \u003ccode\u003eenter\u003c/code\u003e to create a new line just before the\n    last parenthesis. A newline is inserted like this:\n\n    ```lisp\n    (defun square (x)\n      )\n      -\n    ```\n\n 6. Now type only this:\n\n    ```lisp\n    (* x x\n    ```\n\n    Again, Paredit would have inserted the closing parenthesis\n    automatically. The code should look like this now:\n\n    ```lisp\n    (defun square (x)\n      (* x x))\n            -\n    ```\n\nThere is a lot more to Paredit than this. To learn more, see [The\nAnimated Guide to Paredit][paredit-ref].\n\nNote: While many Lisp programmers find Paredit very convenient and\npowerful while manipulating S-expressions in Lisp code, there are a few\npeople who do not like Paredit because they find the Paredit behaviour\nintrusive. See the [Opinion References](#opinion-references) section for\nmore discussion on this topic.\n\n[paredit-ref]: http://danmidwood.com/content/2014/11/21/animated-paredit.html\n\n\n### Use Rainbow Delimiters\n\nThere is not much to learn about using Rainbow Delimiters. In the\nprevious sections, you must have seen that as you type nested\nparentheses, each parenthesis is highlighted with a different color.\nThat is done by Rainbow Delimiters. It colors each parenthesis\naccording to its nesting depth level.\n\nNote: Not everyone likes Rainbow Delimiters. Some people find\nparentheses in multiple colors distracting. See the [Opinion\nReferences](#opinion-references) section for more discussion on this\ntopic.\n\n\n### Use Quicklisp\n\nThis is an optional section for beginners to Common Lisp. Quicklisp\nhelps in installing Common Lisp libraries from its repository. You would\nnot need it when you are just learning Common Lisp as a beginner. But as\nyou grow more experienced with Common Lisp and begin developing real\nworld applications, sooner or later, you will need Quicklisp to install\nlibraries that help you solve your problems.\n\nEnsure that you have installed Quicklisp as specified in the [Get\nStarted](#get-started) section. Then follow these steps to become\nfamiliar with Quicklisp:\n\n 1. Start Emacs:\n\n    ```sh\n    emacs\n    ```\n\n 2. Within Emacs, start SLIME by typing the following key sequence:\n\n    ```\n    M-x slime RET\n    ```\n\n 3. Open a new file, say `server.lisp` with the following key sequence:\n\n    ```\n    C-x C-f server.lisp\n    ```\n\n 4. Enter the following code into the buffer for the new file:\n\n    ```lisp\n    (ql:quickload \"hunchentoot\")\n    (hunchentoot:start (make-instance 'hunchentoot:easy-acceptor :port 4242))\n    ```\n\n    The first line fetches and loads Hunchentoot from Quicklisp.\n    Hunchentoot is a popular Common Lisp web server toolkit for building\n    dynamic websites. The second line uses Hunchentoot to start a web\n    server listening on TCP port 4242.\n\n 5. Evaluate the whole buffer with the following key sequence:\n\n    ```\n    M-x slime-eval-buffer RET\n    ```\n\n 6. Visit http://127.0.0.1:4242/ with your web browser. A web page with\n    a welcome message from Hunchentoot should appear.\n\n\nLine-by-Line Explanation\n------------------------\n\nThis section explains the [`.emacs`] file provided here line-by-line.\n\n\n### Tweak UI\n\nThe first few lines in our [`.emacs`] merely tweak the Emacs user\ninterface. These are of course not essential for Common Lisp\nprogramming. However, many new Emacs users often ask how to customize\nthe user interface to add a good color scheme and make it look minimal,\nso this section indulges a little in customizing the user interface. The\nactual Common Lisp related customization begins in the next section:\n[Highlight Parentheses](#highlight-parentheses).\n\nHere is a line-by-line explanation of the UI tweaks in [`.emacs`]:\n\n  - When Emacs runs in a GUI window, by default, it starts with a menu\n    bar, tool bar, and scroll bar. Many (but not all) users like to\n    hide them in order to make the Emacs frame look clean and minimal.\n    The following lines disable the tool bar and scroll bar. The menu\n    bar is left enabled.\n\n    ```elisp\n    (when (display-graphic-p)\n      (tool-bar-mode 0)\n      (scroll-bar-mode 0))\n    ```\n\n    The `when` expression checks if Emacs is running with graphic\n    display before disabling the tool bar and scroll bar. Without the\n    `when` expression, we get the following error on Emacs without\n    graphic display support: `Symbol's function definition is void:\n    tool-bar-mode`. An example of Emacs without graphics support is\n    `emacs-nox` on Debian 10. Note that this is only an author's\n    preference. You may comment out one or more of these lines if you\n    want to retain the tool bar or scroll bar.\n\n    Some users like to hide the menu bar as well. To disable the menu\n    bar, include `(menu-bar-mode 0)` as top-level-expression (i.e.,\n    outside the `when` expression) in the initialization file. Even\n    with the menu bar disabled, the menu can be accessed anytime by\n    typing `\u003cf10\u003e`. For beginners to Emacs, it is advisable to keep\n    the menu bar enabled because it helps in discovering new features.\n\n  - Inhibit the startup screen with the `Welcome to GNU Emacs` message\n    from appearing:\n\n    ```elisp\n    (setq inhibit-startup-screen t)\n    ```\n\n    If you are a beginner to Emacs, you might find the startup screen\n    helpful. It contains links to tutorial, manuals, common tasks, etc.\n    If you want to retain the startup screen, comment this line out.\n\n  - Load a beautiful dark color theme known as `wombat`:\n\n    ```elisp\n    (load-theme 'wombat)\n    ```\n\n    If you want to check the other built-in themes, type\n    `M-x customize-themes RET`. A new window with a buffer named\n    `*Custom Themes*` appear. In this buffer, select any theme you want\n    to test. After you are done testing, you can close this new window\n    with `C-x 0`.\n\n  - Choose a darker shade of gray for the background color to improve\n    the contrast of the theme:\n\n    ```elisp\n    (set-face-background 'default \"#111\")\n    ```\n\n    Although Wombat is a pretty nice theme that comes with Emacs, in\n    this theme, the cursor, search matches, and comments can often be\n    difficult to spot because they are all colored with different\n    shades of gray while the background is also gray. The above line\n    of Emacs Lisp code chooses a darker shade of gray for the\n    background in order to improve the contrast and make the other\n    elements that are colored with a lighter shade of gray easier to\n    spot.\n\n\n### Use Spaces for Indentation\n\nThe following point shows how to configure Emacs to insert spaces, not\ntabs, for indenting code.\n\n  - Use spaces, not tabs, for indentation:\n\n    ```elisp\n    (setq-default indent-tabs-mode nil)\n    ```\n\n    Emacs uses a mix of tabs and spaces by default for indentation and\n    alignment. To verify the default behaviour, first comment out the\n    above line of Emacs Lisp code, save it, then restart Emacs, then\n    open a new Common Lisp source file, say, `C-x C-f foo.lisp RET`\n    and type the following three lines of Common Lisp code:\n\n    ```lisp\n    (defun foo ()\n      (concat \"foo\"\n              \"bar\"))\n    ```\n\n    While typing the above code, do not type \u003ckbd\u003etab\u003c/kbd\u003e or\n    \u003ckbd\u003espace\u003c/kbd\u003e to indent the second and third lines. When you\n    type \u003ckbd\u003eenter\u003c/kbd\u003e at the end of each line, Emacs automatically\n    inserts the necessary tabs and spaces to indent the code. After\n    entering this code, type `M-x whitespace-mode RET` to visualize\n    whitespace characters. This mode displays each space with a middle\n    dot (`·`) and each tab with a right pointing guillemet (`»`). With\n    whitespace mode enabled, you should find that the second line of\n    code is indented with two spaces but the third line is indented\n    with a single tab followed by two spaces. Emacs has a `tab-width`\n    variable that is set to `8` by default. For every `tab-width`\n    columns of indentation, Emacs inserts a tab to indent the code.\n    The third line requires 10 leading spaces for alignment, so Emacs\n    inserts one tab character followed by 2 spaces to make the third\n    line look aligned. However, this code would look misaligned on\n    another editor with a different `tab-width` setting. That's why we\n    configure Emacs to use only spaces to indent and align code.\n\n    Now to verify that the above line of Emacs Lisp code works as\n    expected, uncomment the function call to set `indent-tabs-mode` to\n    `nil`, save it, then restart Emacs, and then perform the\n    above experiment involving the three lines of Emacs Lisp code\n    again. This time, you should see that no tabs are used for\n    indentation. Only spaces are used for indentation.\n\n    In some type of files, we must use literal tabs. For example, in\n    `Makefile`, the syntax of target rules require that the commands\n    under a target are indented by a literal tab character. In such\n    files, Emacs is smart enough to always use literal tabs for\n    indentation regardless of the above variable setting.\n\n    Mixing tabs and spaces for indenting source code can be\n    problematic, especially, when the author of code or Emacs\n    inadvertently uses tabs for alignment (as opposed to using tabs\n    for indentation only which would be fine) and another programmer\n    views the file with an editor with a different tab width setting.\n    In fact, in the experiment above, Emacs did use a literal tab\n    character to align code which would cause the code to look\n    misaligned on another editor with a different tab width setting.\n    See [Tabs Are Evil](https://www.emacswiki.org/emacs/TabsAreEvil)\n    for more details on this topic.\n\n\n### Highlight Parentheses\n\nThe following points describe how we enable highlighting of parentheses:\n\n  - The next point shows how to enable highlighting of matching pair of\n    parentheses. By default, there is a small delay between the movement\n    of a cursor and the highlighting of the matching pair of\n    parentheses. The following line of code gets rid of this delay:\n\n    ```elisp\n    (setq show-paren-delay 0)\n    ```\n\n    This line of code must come before the one in the next point for it\n    to be effective.\n\n  - Highlight matching parentheses:\n\n    ```elisp\n    (show-paren-mode)\n    ```\n\n    A pair of parenthesis is highlighted when the cursor is on the\n    opening parenthesis of the pair or just after the closing\n    parenthesis of the pair.\n\n\n### Install Packages\n\nThe following points describe how we automate the installation of\nEmacs packages we need. These points are essential to Common Lisp\nprogramming with Emacs:\n\n  - The following code disables TLS 1.3 to work around a known bug in\n    GNU Emacs versions 26.1 and 26.2:\n\n    ```elisp\n    (when (and (version\u003c emacs-version \"26.3\") (\u003e= libgnutls-version 30603))\n      (setq gnutls-algorithm-priority \"NORMAL:-VERS-TLS1.3\"))\n    ```\n\n    See https://debbugs.gnu.org/34341 for more details on the bug. This\n    code is not required while using GNU Emacs version 26.3 or 27.1 or a\n    later version although leaving this code intact should do no harm\n    because this code checks whether the Emacs version is less than 26.3\n    before applying the workaround.\n\n  - When we install packages using `package-install` (coming up soon\n    in a later point), a few customizations are written automatically\n    into the Emacs initialization file (`~/.emacs` in our case). This\n    has the rather undesirable effect of our carefully handcrafted\n    `~/.emacs` being meddled by `package-install`. To be precise, it\n    is the `custom` package invoked by `package-install` that intrudes\n    into our Emacs initialization file. To prevent that, we ask\n    `custom` to write the customizations to a separate file with the\n    following code:\n\n    ```elisp\n    (setq custom-file (concat user-emacs-directory \"custom.el\"))\n    ```\n\n    Note that this line of code must occur before the\n    `package-install` call.\n\n  - Emacs does not load the custom-file automatically, so we add the\n    following code to load it:\n\n    ```elisp\n    (load custom-file t)\n    ```\n\n    It is important to load the custom-file because it may contain\n    customizations we have written to it directly or via the customize\n    interface (say, using `M-x customize RET`). If we don't load this\n    file, then any customizations written to this file will not become\n    available in our Emacs environment.\n\n    The boolean argument `t` ensures that no error occurs when the\n    custom-file is missing. Without it, when Emacs starts for the\n    first time with our initialization file and there is no\n    custom-file yet, the following error occurs: `File is missing:\n    Cannot open load file, No such file or directory,\n    ~/.emacs.d/custom.el`. Setting the second argument to `t` prevents\n    this error when Emacs is run with our initialization file for the\n    first time.\n\n  - This is necessary for defining the `package-archives` list we will\n    use in the next point.\n\n    ```elisp\n    (require 'package)\n    ```\n\n  - Add Milkypostman's Emacs Lisp Package Archive (MELPA) to the list of\n    archives to fetch packages from:\n\n    ```elisp\n    (add-to-list 'package-archives '(\"melpa\" . \"https://melpa.org/packages/\") t)\n    ```\n\n    By default only GNU Emacs Lisp Package Archive (ELPA) is in the list\n    of archives to fetch from. The above line adds MELPA too to the\n    list. If you are curious to see what the original value of\n    `package-archives` was and what it is now due to the above line,\n    type `C-h o package-archives RET`.\n\n  - Initialize the package system:\n\n    ```elisp\n    (package-initialize)\n    ```\n\n    While initializing the package system, this call also initializes\n    the `package-archive-contents` variable used in the next point.\n\n  - Download package descriptions from package archives only if they\n    have not been downloaded before:\n\n    ```elisp\n    (unless package-archive-contents\n      (package-refresh-contents))\n    ```\n\n    The first line checks whether package descriptions from package\n    archives have been fetched. See the `~/.emacs.d/elpa/archives` or\n    `~/.config/emacs/elpa/archives` directory for archive contents in\n    case you are curious. If the archive contents have not been\n    fetched then the second line fetches them. Thus the second line\n    executes only when the Emacs initialization is loaded for the\n    first time. The first time Emacs starts with the [.emacs](.emacs)\n    file of this repository, it takes a while to fetch the package\n    archives. However, once the package archives have been fetched and\n    Emacs is started again later, it starts instantly because the code\n    above takes care not to fetch package archives again when it is\n    already cached locally.\n\n  - Install SLIME, Paredit, and Rainbow Delimiters only if they are not\n    installed already:\n\n    ```elisp\n    (dolist (package '(slime paredit rainbow-delimiters))\n      (unless (package-installed-p package)\n        (package-install package)))\n    ```\n\n    This loops iterates over each package name in a list of packages.\n    For each package, it checks whether the package is installed with\n    the `package-installed-p` function. If it is not installed, then\n    it is installed with the `package-install` function. You can\n    modify the list of packages in the first line to add other\n    packages that you might need in future or remove packages that you\n    do not want.\n\n    The first time Emacs starts with this initialization file, it\n    takes a while to install the packages we need. However, once the\n    packages are installed and Emacs is started again later, it starts\n    instantly because the code above takes care to not attempt\n    installing packages that are already installed.\n\n\n### Inferior Lisp Program\n\nThe following steps describe setting up the `inferior-lisp-program`\nvariable so that Emacs can use SBCL to load and execute SLIME:\n\n  - Emacs uses a variable named `inferior-lisp-program` to start SLIME.\n    The use of this variable can be seen in the next point. This\n    variable specifies the program to be invoked for loading and\n    executing SLIME. We will set this to just `sbcl`, i.e., just the\n    program name without the complete path. Avoiding absolute path of\n    SBCL in Emacs initialization file has the advantage that the same\n    initialization file can work well on other systems too where the\n    location of SBCL may be different.\n\n    On macOS, when we install SBCL using `brew install sbcl`, the\n    compiler binary executable is written to `/usr/local/bin/sbcl`. The\n    path `/usr/local/bin` is generally available in the shell's `$PATH`\n    environment variable, so when Emacs is launched from the shell, its\n    `exec-path` variable contains `/usr/local/bin`. As a result, it can\n    find `sbcl` and start SLIME successfully.\n\n    However, when Emacs is launched from the desktop (say, from macOS\n    Dock), it does not have `/usr/local/bin` in its `exec-path`, so it\n    fails to start SLIME with this error: `Searching for program: No\n    such file or directory, sbcl`. The following line of code works\n    around this issue by adding `/usr/local/bin` to the `exec-path`\n    variable:\n\n    ```elisp\n    (add-to-list 'exec-path \"/usr/local/bin\")\n    ```\n\n    Now there are several other ways to resolve this issue. A popular\n    way is to specify the absolute path of SBCL as the\n    `inferior-lisp-program`. Yet another way is to configure macOS\n    desktop such that when a program is launched from GUI, it contains\n    `/usr/local/bin` in its `PATH`.\n\n    The workaround shown above is recommended in this document for\n    two reasons. Firstly, we don't want to hard-code absolute path of\n    SBCL in the Emacs initialization file, so that the same\n    initilization file can work well on other systems where the location\n    of SBCL may be different. Secondly, we want to keep the workaround\n    minimally invasive, so that we don't have to go around meddling with\n    the desktop settings only for the sake of Emacs.\n\n  - Specify the program to be invoked for loading and executing SLIME:\n\n    ```elisp\n    (setq inferior-lisp-program \"sbcl\")\n    ```\n\n\n### Add Hooks\n\nThis section describes how to enable Paredit and Rainbow Delimiters.\nThese are not absolutely essential for having an interactive programming\nenvironment for Common Lisp. However many programmers find them useful\nwhile some do not.\n\nIn case you decide not to use either Paredit or Rainbow Delimiters,\nthen you may skip this section. In that case, you might also want to\nremove these packages from the `dolist` expression of [`.emacs`].\n\n  - Enable Paredit while editing Emacs Lisp code:\n\n    ```elisp\n    (add-hook 'emacs-lisp-mode-hook 'enable-paredit-mode)\n    ```\n\n    Paredit helps in keeping parentheses balanced and in performing\n    structured editing of S-expressions. While we configure it to be\n    used for Common Lisp programming, we might as well configure it for\n    editing Emacs Lisp code too. Then the experience of editing Emacs\n    Lisp code and that of editing Common Lisp code will be consistent\n    with each other.\n\n    To test that Paredit is enabled for editing Emacs Lisp code, open a\n    new Emacs Lisp file, say, `foo.el`. Then type `(`. Paredit should\n    automatically insert the corresponding `)`.\n\n  - Enable Paredit in eval-expression minibuffer:\n\n    ```elisp\n    (add-hook 'eval-expression-minibuffer-setup-hook 'enable-paredit-mode)\n    ```\n\n    To test this, enter `M-:` to bring up the eval-expression minbuffer\n    and type `(`. Paredit should automatically insert the corresponding\n    `)`.\n\n  - Enable Paredit while interactively evaluating Emacs Lisp expressions\n    in inferior-emacs-lisp-mode (IELM):\n\n    ```elisp\n    (add-hook 'ielm-mode-hook 'enable-paredit-mode)\n    ```\n\n    To test this, enter `M-x ielm RET`. When the `*ielm*` buffer\n    appears, type `(`. Paredit should automatically insert the\n    corresponding `)`.\n\n  - Enable Paredit in Lisp interaction mode:\n\n    ```elisp\n    (add-hook 'lisp-interaction-mode-hook 'enable-paredit-mode)\n    ```\n\n    To test this, first open a non-Lisp file, say, `C-x C-f foo.txt\n    RET`. Now type `(`. Note that no corresponding `)` is inserted\n    because we are not in Lisp interaction mode yet. Delete `(`. Then\n    start Lisp interaction mode with the command `M-x\n    lisp-interaction-mode RET`. Type `(` again. Paredit should now\n    automatically insert the corresponding `)`.\n\n  - Enable Paredit while editing Common Lisp code:\n\n    ```elisp\n    (add-hook 'lisp-mode-hook 'enable-paredit-mode)\n    ```\n\n    To test this, open a new Common Lisp source file, say, `C-x C-f\n    foo.lisp RET`. Then type `(`. Paredit should automatically insert\n    the corresponding `)`.\n\n  - Enable Paredit in SLIME REPL:\n\n    ```elisp\n    (add-hook 'slime-repl-mode-hook 'enable-paredit-mode)\n    ```\n\n    To test this, start SLIME with `M-x slime RET`. Then type `(` in\n    SLIME REPL. Paredit should automatically insert the corresponding\n    `)`.\n\n  - When we type \u003ckbd\u003ebackspace\u003c/kbd\u003e or \u003ckbd\u003edelete\u003c/kbd\u003e to delete a\n    parenthesis in the SLIME REPL, Paredit fails to keep the parentheses\n    balanced because SLIME interferes with Paredit by grabbing the\n    delete key. To fix this issue, use the following code:\n\n    ```elisp\n    (require 'paredit)\n    (defun override-slime-del-key ()\n      (define-key slime-repl-mode-map\n        (read-kbd-macro paredit-backward-delete-key) nil))\n    (add-hook 'slime-repl-mode-hook 'override-slime-del-key)\n    ```\n\n    To test this, start SLIME with `M-x slime RET`. Then type `(+ 1 (+\n    2 (+ 3 4)))`. Even though, the closing parentheses `)))` will be\n    automatically inserted, type them out to advance the cursor to the\n    end of the line. When you type `)` even if it is already present,\n    Paredit just skips over the already present `)`. Once you are at\n    the end of the line, type \u003ckbd\u003ebackspace\u003c/kbd\u003e or \u003ckbd\u003edelete\u003c/kbd\u003e\n    multiple times. Paredit will keep the parentheses balanced at all\n    times.\n\n  - Enable Rainbow Delimiters while editing Emacs Lisp code:\n\n    ```elisp\n    (add-hook 'emacs-lisp-mode-hook 'rainbow-delimiters-mode)\n    ```\n\n    Rainbow Delimiters color nested parentheses with different colors\n    according to the depth level of each parenthesis. To test this\n    open a new Emacs Lisp file, say, `foo.el`. Then type `((((`.\n    Rainbow Delimiters should color each parenthesis differently.\n\n  - Enable Rainbow Delimiters while interactively evaluating Emacs Lisp\n    expressions in inferior-emacs-lisp-mode (IELM):\n\n    ```elisp\n    (add-hook 'ielm-mode-hook 'rainbow-delimiters-mode)\n    ```\n\n    To test this, enter `M-x ielm RET`. When the `*ielm*` buffer comes\n    up, type `((((`. Rainbow Delimiters should color each parenthesis\n    differently.\n\n  - Enable Rainbow Delimiters in Lisp interaction mode:\n\n    ```elisp\n    (add-hook 'lisp-interaction-mode-hook 'rainbow-delimiters-mode)\n    ```\n\n    To test this, first open a non-Lisp file, say, `foo.txt`. Now type\n    `((((`. Then start Lisp interaction mode with the command `M-x\n    lisp-interaction-mode RET`. Rainbow Delimiters should now color each\n    parenthesis differently.\n\n  - Enable Rainbow Delimiters while editing Common Lisp code:\n\n    ```elisp\n    (add-hook 'lisp-mode-hook 'rainbow-delimiters-mode)\n    ```\n\n    To test this, open a new Common Lisp source file, say, `foo.lisp`.\n    Then type `((((`. Rainbow Delimiters should color each parenthesis\n    differently.\n\n  - Enable Rainbow Delimiters in SLIME REPL:\n\n    ```elisp\n    (add-hook 'slime-repl-mode-hook 'rainbow-delimiters-mode)\n    ```\n\n    To test this, start SLIME with `M-x slime RET`. Then type `((((` at\n    the REPL prompt. Rainbow Delimiters should color each parenthesis\n    differently.\n\nYou may have noticed that we did not enable Rainbow Delimiters for\neval-expression. That is because it does not work as expected as of\nDec 2020. See https://github.com/Fanael/rainbow-delimiters/issues/57 for\nmore details.\n\n\n### Colorful Parentheses\n\nThe default colors that the Rainbow Delimiters package chooses for the\nnested parentheses are too subtle to easily recognize the matching\npair of parentheses. Some Lisp programmers like to customize the\ncolors to make the parentheses look more colorful. This section shows\none way to do this.\n\n  - This is necessary to use the various Rainbow Delimiters faces that\n    appear in the next point.\n\n    ```elisp\n    (require 'rainbow-delimiters)\n    ```\n\n  - Set different colors for parentheses at different nesting level.\n\n    ```elisp\n    (set-face-foreground 'rainbow-delimiters-depth-1-face \"#c66\")  ; red\n    (set-face-foreground 'rainbow-delimiters-depth-2-face \"#6c6\")  ; green\n    (set-face-foreground 'rainbow-delimiters-depth-3-face \"#69f\")  ; blue\n    (set-face-foreground 'rainbow-delimiters-depth-4-face \"#cc6\")  ; yellow\n    (set-face-foreground 'rainbow-delimiters-depth-5-face \"#6cc\")  ; cyan\n    (set-face-foreground 'rainbow-delimiters-depth-6-face \"#c6c\")  ; magenta\n    (set-face-foreground 'rainbow-delimiters-depth-7-face \"#ccc\")  ; light gray\n    (set-face-foreground 'rainbow-delimiters-depth-8-face \"#999\")  ; medium gray\n    (set-face-foreground 'rainbow-delimiters-depth-9-face \"#666\")  ; dark gray\n    ```\n\n\nMore Emacs Customization\n------------------------\n\nThis project focusses primarily on setting up a Common Lisp\ndevelopment environment. If you want to enhance your Emacs setup from\nbeing a Common Lisp development environment to being a more general\npurpose editing and programming environment, please see my new project\n[Emfy](https://github.com/susam/emfy). Emfy is similar to this\nproject, however, Emfy offers more customization to make Emacs easier\nto use for general purpose editing and programming.\n\n\nAlternatives\n------------\n\nThere are two popular alternatives to Emacs4CL:\n\n- [Portacle](https://portacle.github.io/): Portacle is an Emacs-based\n  fully featured integrated development environment (IDE) for Common\n  Lisp. Portacle consists of Emacs customized heavily with custom\n  configuration and a rich selection of packages and tools that make\n  it suitable for Common Lisp programming.\n- [Lem](https://lem-project.github.io/): Lem is an Emacs-like editor\n  and Common Lisp IDE written from scratch using Common Lisp itself.\n\nBoth are good alternatives to Emacs4CL. Since Lem is a completely\ndifferent editor, there is not much to compare between Lem and\nEmacs4CL. Lem offers an appealing option for those who prefer to\nengage in Common Lisp development activities using an editor that is\nwritten in Common Lisp itself.\n\nPortacle, however, is Emacs packaged with custom packages,\nconfiguration, and Common Lisp tools. Portacle tucks away the\nunderlying details of what goes into making Emacs ready for Common\nLisp development in its rather large configuration directory. Since\nPortacle is still Emacs, to use Portacle effectively, you have to\nlearn Emacs and SLIME anyway. If you are going to learn Emacs and\nSLIME anyway, you might as well set it up yourself. Then you can add\nonly those customizations to Emacs that you need instead of Portacle\ndeciding what your Emacs experience should be like.\n\nEmacs4CL provides a good middle ground between setting up Emacs from\nscratch manually and installing Portacle. It promotes a do-it-yourself\napproach to setting up Emacs for Common Lisp programming. More\nimportantly, it helps you understand each step of the work that goes\ninto customizing Emacs as an environment for Common Lisp programming.\n\n\nOpinion References\n------------------\n\n- [State of Common Lisp Survey 2020][cl-survey-2020]\n- [Displaying line numbers is an Emacs anti-pattern][ln-anti-pattern]\n- [Give paredit mode a chance][paredit-chance]\n- [Never warmed up to paredit][paredit-never-warmed]\n- [Coloring each paren differently only adds noise][rainbow-noise]\n\n[cl-survey-2020]: https://docs.google.com/forms/d/e/1FAIpQLSfg7UJRKrkI3OjOHWL4xI-murE4LpQjIxsiAhFdPEmtyLX3kg/viewanalytics\n[ln-anti-pattern]: https://lobste.rs/s/vgjknq/emacs_begin_learning_common_lisp#c_su9qz9\n[paredit-chance]: https://stackoverflow.com/a/5243421/303363\n[paredit-never-warmed]: https://lobste.rs/s/vgjknq/emacs_begin_learning_common_lisp#c_0y6zpd\n[rainbow-noise]: https://lobste.rs/s/vgjknq/emacs_begin_learning_common_lisp#c_1n78vl\n\n\nChannels\n--------\n\nThe following channels are available for asking questions, seeking\nhelp and receiving updates regarding this project:\n\n- GitHub: [emacs4cl/issues](http://github.com/susam/emacs4cl/issues)\n- Mastodon: [@susam@mastodon.social](https://mastodon.social/@susam)\n- Matrix: [#susam:matrix.org](https://matrix.to/#/#susam:matrix.org)\n- Libera: [#susam](https://web.libera.chat/#susam)\n\nYou are welcome to follow or subscribe to one or more of these channels\nto receive updates and ask questions about this project.\n\n\nLicense\n-------\n\nThis is free and open source software. You can use, copy, modify,\nmerge, publish, distribute, sublicense, and/or sell copies of it,\nunder the terms of the MIT License. See [LICENSE.md][L] for details.\n\nThis software is provided \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nexpress or implied. See [LICENSE.md][L] for details.\n\n[L]: LICENSE.md\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsusam%2Femacs4cl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsusam%2Femacs4cl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsusam%2Femacs4cl/lists"}