All Projects β†’ susam β†’ Emacs4cl

susam / Emacs4cl

Licence: mit
A 40 line ~/.emacs to quickly set up vanilla Emacs for Common Lisp programming

Projects that are alternatives of or similar to Emacs4cl

Uncap
Map Caps Lock to Escape or any key to any key
Stars: ✭ 705 (+366.89%)
Mutual labels:  emacs, minimalist
Dracula Theme
πŸ§›πŸ»β€β™‚οΈ One theme. All platforms.
Stars: ✭ 17,480 (+11476.16%)
Mutual labels:  dark-theme, emacs
Emacs
πŸ§›πŸ»β€β™‚οΈ Dark theme for Emacs
Stars: ✭ 190 (+25.83%)
Mutual labels:  dark-theme, emacs
webgui
Web Technologies based Crossplatform GUI Framework with Dark theme
Stars: ✭ 81 (-46.36%)
Mutual labels:  dark-theme, minimalist
Emacs Color Themes
A collection of custom themes for Emacs. All the themes are named after famous programmers.
Stars: ✭ 469 (+210.6%)
Mutual labels:  dark-theme, emacs
Emacs Kaolin Themes
Set of eye pleasing themes for GNU Emacs. Supports both GUI and terminal.
Stars: ✭ 421 (+178.81%)
Mutual labels:  dark-theme, emacs
emfy
A dark and sleek Emacs setup for general purpose editing and programming
Stars: ✭ 843 (+458.28%)
Mutual labels:  dark-theme, minimalist
Spacemacs Theme
Light and dark theme for spacemacs that supports GUI and terminal
Stars: ✭ 483 (+219.87%)
Mutual labels:  dark-theme, emacs
Nimbus Theme
The best dark theme for Emacs
Stars: ✭ 102 (-32.45%)
Mutual labels:  dark-theme, emacs
Gatsby Starter Delog
A blog for designers and developer, built with Gatsby and Netlfiy CMS. Live demo https://delog-w3layouts.netlify.com/
Stars: ✭ 145 (-3.97%)
Mutual labels:  dark-theme
Emacs Bootstrap
Your on-the-fly Emacs development environment.
Stars: ✭ 147 (-2.65%)
Mutual labels:  emacs
Mu4e Alert
Desktop notifications and modeline display for mu4e
Stars: ✭ 143 (-5.3%)
Mutual labels:  emacs
Practical Dapr
A full-stack .NET microservices build on Dapr and Tye
Stars: ✭ 140 (-7.28%)
Mutual labels:  minimalist
Org Fragtog
Automatically toggle Org mode LaTeX fragment previews as the cursor enters and exits them
Stars: ✭ 149 (-1.32%)
Mutual labels:  emacs
Hugo Theme Console
A minimal, responsive and light theme for Hugo inspired by Linux console.
Stars: ✭ 143 (-5.3%)
Mutual labels:  minimalist
Writingwithemacs
Tips, Examples, and Resources for Writing with Emacs
Stars: ✭ 150 (-0.66%)
Mutual labels:  emacs
Discord Bot List
Just another botlist for discord
Stars: ✭ 143 (-5.3%)
Mutual labels:  dark-theme
Ghidra Dark
Dark theme installer for Ghidra
Stars: ✭ 143 (-5.3%)
Mutual labels:  dark-theme
Mastodon.el
Emacs client for Mastodon
Stars: ✭ 150 (-0.66%)
Mutual labels:  emacs
Pihole Dark
A Dark theme for the pihole admin page.
Stars: ✭ 149 (-1.32%)
Mutual labels:  dark-theme

Emacs For Common Lisp (Emacs4CL)

This repository provides a tiny .emacs file to set up Emacs quickly for Common Lisp programming. This document provides a detailed description of how to set it up and get started with Common Lisp programming.

View Source MIT License Twitter

This repository provides a good middle ground between configuring Emacs manually by installing SLIME, Paredit, etc. yourself with M-x package-install commands and installing Portacle. It promotes a do-it-yourself approach to automate customizing Emacs for Common Lisp programming. Here is how the development environment is going to look like:

Screenshot of Emacs

If you are already comfortable with Emacs and only want to understand the content of the .emacs file, you can skip ahead directly to the Line-by-Line Explanation section that describes every line of this Emacs initialization file in detail.

Contents

Who Is This For?

Are you an absolute beginner to Emacs? Are you so new to Emacs that you do not even have ~/.emacs or ~/.emacs.d on your file system? Have you considered learning Common Lisp but when you picked up a book like Practical Common Lisp, you learnt that it recommends Emacs and SLIME for development environment and it seemed like a significant additional learning curve for you? If you answered "yes" to most of these questions, then this project is for you.

The .emacs file in this project provides you a quick way to get started with setting up your development environment. This document explains how to do so in a step-by-step manner. This document also explains the content of .emacs file in a line-by-line manner.

What About Portacle?

Portacle is fine. It is an often recommended Common Lisp development environment for beginners. It provides an Emacs-based fully featured integrated development environment for Common Lisp. Portacle consists of Emacs customized heavily with custom configuration and a rich selection of packages and tools that make it suitable for Common Lisp programming. However, some of the customizations done by Portacle look odd to an experienced Emacs user:

  • A default *scratch* buffer with more than 10 lines of comments that consume some valuable screen real-estate.

  • Enabling line numbers in all buffers including the SLIME Read-Eval-Print Loop (REPL) buffer. Enabling line numbers in Emacs is considered to be an antipattern by some experienced Emacs users. See the Opinion References section for more details on this.

More importantly, installing Portacle hides away the underlying details of what goes into making Emacs ready for Common Lisp development. Programmers who like to set up their tools from scratch may find that Portacle does not offer the opportunity to do so because it bundles all useful tools already.

Also, Portacle is still Emacs. To use Portacle effectively, you have to learn Emacs and SLIME anyway. If you are going to learn Emacs and SLIME anyway, you might as well set it up yourself. Then you can add only those customizations to Emacs that you need instead of Portacle deciding what your Emacs experience should be like.

This project provides a good middle ground between setting up Emacs from scratch manually and installing Portacle. It promotes a do-it-yourself approach to setting up Emacs for Common Lisp programming. More importantly, it helps you understand each step of the work that goes into customizing Emacs as an environment for Common Lisp programming.

Get Started

This section helps you to set up Emacs for Common Lisp development quickly and see what the end result looks like. Perform the following steps to get started:

  1. Install SBCL and Emacs.

    On macOS, enter the following command if you have Homebrew:

    brew install sbcl
    brew install --cask emacs
    

    On Debian, Ubuntu, or another Debian-based Linux system, enter the following command:

    sudo apt-get install sbcl emacs
    

    For other environments, download SBCL and Emacs from http://www.sbcl.org/platform-table.html and https://www.gnu.org/software/emacs/ respectively.

  2. Copy the Emacs initialization file .emacs provided here to your home directory. Here is an example curl command to do so:

    curl -L https://github.com/susam/emacs4cl/raw/master/.emacs >> ~/.emacs
    
  3. Start Emacs:

    emacs
    

    On macOS, you may receive the following error message in a dialog box: 'β€œEmacs.app” can’t be opened because Apple cannot check it for malicious software.' To resolve this issue, go to Apple menu > System Preferences > Security & Privacy > General and click 'Open Anyway'.

    It may take a minute or so for Emacs to start the very first time. When it starts the first time with the new Emacs initialization file obtained in the previous step, it installs the packages specified in it. This is only a one-time activity. The next time you start Emacs, it will start instantly. We will see how .emacs takes care of it in the line-by-line guide later.

  4. Within Emacs, start SLIME by typing the following key sequence:

    M-x slime RET
    

    In the Emacs world (and elsewhere too), the prefix M- denotes the meta modifier key. It does not exist on most modern keyboards. Use the alt key or the option key as a modifier key or esc as a prefix key to enter M-.

    For example, M-x is going to be alt + x or option + x or esc x on a modern keyboard.

    Similarly, RET denotes the enter key or the return key.

  5. After SLIME REPL starts, enter the following expression at the CL-USER> prompt and type enter.

    (format t "hello, world~%")
    

    If the output "hello, world" appears in SLIME REPL, the development environment setup is complete.

  6. Optionally, install Quicklisp with the following commands:

    curl -O https://beta.quicklisp.org/quicklisp.lisp
    sbcl --load quicklisp.lisp --eval "(quicklisp-quickstart:install)" --quit
    sbcl --load ~/quicklisp/setup.lisp --eval "(ql:add-to-init-file)" --quit
    

    Quicklisp helps in installing Common Lisp libraries from its repository. You do not need it when you have just begun learning Common Lisp. But as you grow more experienced with Common Lisp and begin developing real world applications, sooner or later, you will need Quicklisp to install libraries that help you solve your problems.

    The first command in the code block fetches quicklisp.lisp. The second command installs Quicklisp to ~/quicklisp. The third command adds some code to SBCL's initialization file at ~/.sbclrc, so that Quicklisp is automatically loaded when SBCL starts.

Now that your environment is setup, read the next section to learn how to use this environment in more detail.

Step-by-Step Usage

Use SBCL

Steel Bank Common Lisp (SBCL) is a high performance Common Lisp compiler. It runs on several Unix and Unix-like systems such as Linux, FreeBSD, macOS, etc. It also runs experimentally on Windows. It is the most popular free and open source implementation of Common Lisp as of December 2020. See the Opinion References section for survey results related to this.

The steps provided below show how to run SBCL independently. This is not a typical way to run SBCL because most of the time we interact with SBCL via SLIME right from within Emacs. However running it independently once helps one appreciate that it is an independent program that compiles and executes Common Lisp code. Here are the steps:

  1. Open your favourite editor, type this code, and save it as hello.lisp:

    (format t "hello, world~%")
    
  2. Then enter this command in the shell to run the program:

    sbcl --script hello.lisp
    
  3. Now start the SBCL Read-Eval-Print Loop (REPL) with the following command in the shell:

    sbcl
    
  4. An asterisk prompt appears. Enter a Common Lisp expression at the asterisk prompt like this and type enter:

    (+ 1 2)
    

    The result should appear as the output.

  5. Similarly, enter the following expression at the SBCL prompt and type enter:

    (format t "hello, world~%")
    
  6. Finally, enter the following expression and type enter to exit the SBCL REPL:

    (exit)
    

Use Emacs

Emacs is a very powerful and extensible editor. It comes with over 10,000 built-in commands. A small section like this can barely scratch the surface of Emacs. Yet, this section makes a modest attempt at getting you started with Emacs and then provides more resources to learn further. Perform the following steps to get started:

  1. Start Emacs:

    emacs
    
  2. Within Emacs, enter the following command to open a file, say, ~/hello.txt:

    C-x C-f hello.txt RET
    

    A new buffer to edit hello.txt is created. If a file with that name already exists on your file system, then it loads the content of the file into the buffer.

    Note that in the Emacs world (and elsewhere too), the notation C- denotes the ctrl modifier key. Thus C-x denotes ctrl + x.

    The notation RET denotes the enter or return key.

    Typing consecutive C- key sequences can be optimized by pressing and holding down the ctrl key, then typing the other keys, and then releasing the ctrl key. For example, to type C-x C-f, first press and hold down ctrl, then type x, then type f, and then release ctrl. In other words, think of C-x C-f as C-(x f). This shortcut works for other modifier keys too.

  3. Now type some text into the buffer. Type out at least 3-4 words. We will need it for the next two steps.

  4. Move backward by one word with the following key sequence:

    M-b
    

    Remember from the previous section that M- denotes the meta modifier key. The above command can be typed with alt + b or option + b or esc b.

    If you face any issue with the alt key or the option key, read Emacs Wiki: Meta Key Problems.

  5. Now move forward by one word with the following key sequence:

    M-f
    
  6. The C-g key sequence cancels the current command. This can be used when you mistype a command and want to start over or if you type a command partially, then change your mind and then you want to cancel the partially typed command. Try out these examples:

    C-x C-f C-g
    
    C-x C-g
    
  7. Save the buffer to a file on the file system with this command:

    C-x C-s
    
  8. Quit Emacs:

    C-x C-c
    

Now you know how to start Emacs, open a file, save it, and quit. Improve your Emacs knowledge further by taking the Emacs tutorial that comes along with Emacs. In Emacs, type C-h t to start the tutorial.

The key bindings to perform various operations like creating file, saving file, quitting the editor, etc. may look arcane at first, but repeated usage of the key bindings develops muscle memory soon and after having used them for a few days, one does not even have to think about them. The fingers do what the mind wants effortlessly due to muscle memory.

While you are getting used to the Emacs key bindings, keep this GNU Emacs Reference Card handy. Also, if you are using it in GUI mode, then the menu options can be quite helpful. The menu options contain frequently used operations. The option for each operation also displays the key bindings that can be used to invoke the same operation.

Use SLIME

Superior Lisp Interaction Mode for Emacs (SLIME) is a very popular Emacs mode that adds support for interacting with a running Common Lisp process for compilation, debugging, document lookup, etc. while developing Common Lisp applications. Perform the following steps to get started with it:

  1. Start Emacs:

    emacs
    
  2. Within Emacs, start SLIME by typing the following key sequence:

    M-x slime RET
    

    Remember that M-x translates to alt + x or esc x on a modern keyboard.

  3. A new buffer named *slime-repl sbcl* should have now appeared with the following prompt:

    CL-USER>
    

    This is a Read-Eval-Print-Loop (REPL) where you can evaluate Common Lisp expressions.

  4. Enter the following expression in the REPL:

    (+ 1 2)
    

    The following result should appear when you type enter:

    3
    
  5. We will now see how to work on a Lisp source file and send expressions to the REPL for evaluation using SLIME commands without having to leave Emacs. First, create a buffer for a new file, for example:

    C-x C-f foo.lisp
    
  6. Now enter this Lisp code into the buffer for foo.lisp:

    (+ 1 2)
    
  7. While the cursor is placed after the closing parenthesis (not on it, but after it), type the following command:

    C-x C-e
    

    The result 3 should appear in a minibuffer at the bottom.

There is a lot more to SLIME than what is described above. To learn more about SLIME, see Slime User Manual. Also, keep this Slime Quick Reference Card handy.

Use Paredit

Paredit helps in keeping parentheses balanced and also in performing structured editing of S-expressions in Lisp code. It provides a powerful set of commands to manipulate S-expressions in various ways. Perform the following steps to get started with Paredit:

  1. Run Emacs:

    emacs
    
  2. Open a Common Lisp source file:

    C-x C-f foo.lisp
    
  3. Type the following code only:

    (defun square (x
    

    At this point, Paredit should have inserted the two closing parentheses automatically. The code should look like this:

    (defun square (x))
                    -
    

    The cursor should be situated just after the parameter x. The underbar shows where the cursor should be.

  4. Type the closing parentheses now. Yes, type it even if the closing parenthesis is already present. The cursor should now skip over the first closing parenthesis like this:

    (defun square (x))
                     -
    

    Of course, there was no need to type the closing parenthesis because it was already present but typing it out to skip over it is more efficient than then moving over it with movement commands. This is, in fact, a very nifty feature of Paredit. We can enter code with the same keystrokes as we would without Paredit.

  5. Now type enter to create a new line just before the last parenthesis. A newline is inserted like this:

    (defun square (x)
      )
      -
    
  6. Now type only this:

    (* x x
    

    Again, Paredit would have inserted the closing parenthesis automatically. The code should look like this now:

    (defun square (x)
      (* x x))
            -
    

There is a lot more to Paredit than this. To learn more, see The Animated Guide to Paredit.

Note: While many Lisp programmers find Paredit very convenient and powerful while manipulating S-expressions in Lisp code, there are a few people who do not like Paredit because they find the Paredit behaviour intrusive. See the Opinion References section for more discussion on this topic.

Use Rainbow Delimiters

There is not much to learn about using Rainbow Delimiters. In the previous sections, you must have seen that as you type nested parentheses, each parenthesis is highlighted with a different color. That is done by Rainbow Delimiters. It colors each parenthesis according to its nesting depth level.

Note: Not everyone likes Rainbow Delimiters. Some people find parentheses in multiple colors distracting. See the Opinion References section for more discussion on this topic.

Use Quicklisp

This is an optional section for beginners to Common Lisp. Quicklisp helps in installing Common Lisp libraries from its repository. You would not need it when you are just learning Common Lisp as a beginner. But as you grow more experienced with Common Lisp and begin developing real world applications, sooner or later, you will need Quicklisp to install libraries that help you solve your problems.

Ensure that you have installed Quicklisp as specified in the Get Started section. Then follow these steps to become familiar with Quicklisp:

  1. Start Emacs:

    emacs
    
  2. Within Emacs, start SLIME by typing the following key sequence:

    M-x slime RET
    
  3. Open a new file, say server.lisp with the following key sequence:

    C-x C-f server.lisp
    
  4. Enter the following code into the buffer for the new file:

    (ql:quickload "hunchentoot")
    (hunchentoot:start (make-instance 'hunchentoot:easy-acceptor :port 4242))
    

    The first line fetches and loads Hunchentoot from Quicklisp. Hunchentoot is a popular Common Lisp web server toolkit for building dynamic websites. The second line uses Hunchentoot to start a web server listening on TCP port 4242.

  5. Evaluate the whole buffer with the following key sequence:

    M-x slime-eval-buffer RET
    
  6. Visit http://127.0.0.1:4242/ with your web browser. A web page with a welcome message from Hunchentoot should appear.

Line-by-Line Explanation

This section explains the .emacs file provided here line-by-line.

Tweak UI

The first few lines in our .emacs merely tweak the Emacs user interface. These are of course not essential for Common Lisp programming. However, many new Emacs users often ask how to customize the user interface to add a good color scheme and make it look minimal, so this section indulges a little in customizing the user interface. The actual Common Lisp related customization begins in the next section: Highlight Parentheses.

Here is a line-by-line explanation of the UI tweaks in .emacs:

  • Hide the menu bar:

    (menu-bar-mode 0)
    

    When Emacs runs in a GUI window, by default, starts with a menu bar, tool bar, and scroll bar. Experienced users use Emacs completely through the keyboard via the various key bindings for various operations, so many of them hide these additional bars to make the Emacs window look clean and minimal.

    If you are a beginner to Emacs, you might find the menu bar helpful initially, so you might not want this line in your Emacs initialization file. In that case, remove this line or just comment it out by inserting a semicolon (i.e., ;) before the opening parentheses.

  • Hide the tool bar and scroll bar:

    (when (display-graphic-p)
      (tool-bar-mode 0)
      (scroll-bar-mode 0))
    

    The when expression checks if Emacs is running with graphic display before disabling the tool bar and scroll bar. Without the when expression, we get the following error on Emacs without graphic display support: Symbol's function definition is void: tool-bar-mode. An example of Emacs without graphics support is emacs-nox on Debian 10.

    Note that this is only an author's preference. You may comment out one or more of these lines if you want to retain the tool bar or scroll bar.

  • Inhibit the startup screen with the Welcome to GNU Emacs message from appearing:

    (setq inhibit-startup-screen t)
    

    If you are a beginner to Emacs, you might find the startup screen helpful. It contains links to tutorial, manuals, common tasks, etc. If you want to retain the startup screen, comment this line out.

  • Load a beautiful dark color theme known as wombat:

    (load-theme 'wombat)
    

    If you want to check the other built-in themes, type M-x customize-themes RET. A new window with a buffer named *Custom Themes* appear. In this buffer, select any theme you want to test. After you are done testing, you can close this new window with C-x 0.

Use Spaces for Indentation

The following point shows how to configure Emacs to insert spaces, not tabs, for indenting code.

  • Use spaces, not tabs, for indentation:

    ;; Use spaces, not tabs, for indentation.
    (setq-default indent-tabs-mode nil)
    

    Emacs uses a mix of tabs and spaces by default for indentation. To verify the default behaviour, first comment out the above line of Emacs Lisp code, save it, then restart Emacs, then open a new Common Lisp source file, say, C-x C-f foo.lisp RET and type the following three lines of Common Lisp code:

    (defun hello-loop ()
      (loop repeat 5
            do (format t "hello~%")))
    

    While typing the above code, do not type tab or space to indent the second and third lines. When you type enter at the end of each line, Emacs automatically inserts the necessary tabs and spaces to indent the code. After entering this code, type M-x whitespace-mode RET to visualize whitespace characters. This mode displays each space with a middle dot (Β·) and each tab with a right pointing guillemet (Β»). With whitespace mode enabled, you should find that the second line of code is indented with two spaces but the third line is indented with a single tab. Emacs has a tab-width variable that is set to 8 by default. For every tab-width columns of indentation, Emacs inserts a tab to indent the code. That is why, the third line has one tab character for indentation.

    Now to verify that the above line of Emacs Lisp code works as expected, uncomment it again to enable that line, save it, then restart Emacs, and then perform the above experiment involving the three lines of Common Lisp code again. This time, you should see that no tabs are used for indentation. Only spaces are used for indentation.

Mixing tabs and spaces for indenting source code can be problematic, especially, when another programmer views the file with an editor with a different tab width setting. See Tabs Are Evil for more details on this topic.

Highlight Parentheses

The following points describe how we enable highlighting of parentheses:

  • The next point shows how to enable highlighting of matching pair of parentheses. By default, there is a small delay between the movement of a cursor and the highlighting of the matching pair of parentheses. The following line of code gets rid of this delay:

    (setq show-paren-delay 0)
    

    This line of code must come before the one in the next point for it to be effective.

  • Highlight matching parentheses:

    (show-paren-mode)
    

    A pair of parenthesis is highlighted when the cursor is on the opening parenthesis of the pair or just after the closing parenthesis of the pair.

Install Packages

This section is essential to Common Lisp programming with Emacs. The following points describe how we automate the installation of Emacs packages we need:

  • The following code disables TLS 1.3 to work around a known bug in GNU Emacs versions 26.1 and 26.2:

    (when (and (version< emacs-version "26.3") (>= libgnutls-version 30603))
      (setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3"))
    

    See https://debbugs.gnu.org/34341 for more details on the bug. This code is not required while using GNU Emacs version 26.3 or 27.1 or a later version although leaving this code intact should do no harm because this code checks whether the Emacs version is less than 26.3 before applying the workaround.

  • This is necessary for defining the package-archives list we will use in the next point.

    (require 'package)
    
  • Add Milkypostman's Emacs Lisp Package Archive (MELPA) to the list of archives to fetch packages from:

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

    By default only GNU Emacs Lisp Package Archive (ELPA) is in the list of archives to fetch from. The above line adds MELPA too to the list. If you are curious to see what the original value of package-archives was and what it is now due to the above line, type C-h o package-archives RET.

  • Initialize the package system:

    (package-initialize)
    

    While initializing the package system, this call also initializes the package-archive-contents variable used in the next point.

  • Download package descriptions from package archives only if they have not been downloaded before:

    (unless package-archive-contents
      (package-refresh-contents))
    

    The first line checks whether package descriptions from package archives from archives have been fetched. See the ~/.emacs.d/elpa/archives directory for archive contents in case you are curious. If the archive contents have not been fetched then the second line fetches them. Thus the second line executes only when the Emacs initialization is loaded for the first time. The first time Emacs starts with the .emacs file of this repository, it takes a while to fetch the package archives. However, once the package archives have been fetched and Emacs is started again later, it starts instantly because the code above takes care not to fetch package archives again when it is already cached locally.

  • When we install packages using package-install (coming up in the next point), a few customizations are written automatically into the Emacs initialization file (~/.emacs in our case). This has the rather undesirable effect of our carefully handcrafted ~/.emacs being meddled by package-install. To be precise, it is the custom package invoked by package-install that intrudes into our Emacs initialization file. To prevent that, we ask custom to write the customizations to a separate file at ~/.emacs.d/custom.el with the following code:

    (setq custom-file (concat user-emacs-directory "custom.el"))
    
  • Install SLIME, Paredit, and Rainbow Delimiters only if they are not installed already:

    (dolist (package '(slime paredit rainbow-delimiters))
      (unless (package-installed-p package)
        (package-install package)))
    

    This loops iterates over each package name in a list of packages. For each package, it checks whether the package is installed with the package-installed-p function. If it is not installed, then it is installed with the package-install function. You can modify the list of packages in the first line to add other packages that you might need in future or remove packages that you do not want.

    The first time Emacs starts with this initialization file, it takes a while to install the packages we need. However, once the packages are installed and Emacs is started again later, it starts instantly because the code above takes care to not attempt installing packages that are already installed.

Inferior Lisp Program

The following steps describe setting up the inferior-lisp-program variable so that Emacs can use SBCL to load and execute SLIME:

  • Emacs uses a variable named inferior-lisp-program to start SLIME. The use of this variable can be seen in the next point. This variable specifies the program to be invoked for loading and executing SLIME. We will set this to just sbcl, i.e., just the program name without the complete path. Avoiding absolute path of SBCL in Emacs initialization file has the advantage that the same initialization file can work well on other systems too where the location of SBCL may be different.

    On macOS, when we install SBCL using brew install sbcl, the compiler binary executable is written to /usr/local/bin/sbcl. The path /usr/local/bin is generally available in the shell's $PATH environment variable, so when Emacs is launched from the shell, its exec-path variable contains /usr/local/bin. As a result, it can find sbcl and start SLIME successfully.

    However, when Emacs is launched from the desktop (say, from macOS Dock), it does not have /usr/local/bin in its exec-path, so it fails to start SLIME with this error: Searching for program: No such file or directory, sbcl. The following line of code works around this issue by adding /usr/local/bin to the exec-path variable:

    (add-to-list 'exec-path "/usr/local/bin")
    

    Now there are several other ways to resolve this issue. A popular way is to specify the absolute path of SBCL as the inferior-lisp-program. Yet another way is to configure macOS desktop such that when a program is launched from GUI, it contains /usr/local/bin in its PATH.

    The workaround shown above is recommended in this document for two reasons. Firstly, we don't want to hard-code absolute path of SBCL in the Emacs initialization file, so that the same initilization file can work well on other systems where the location of SBCL may be different. Secondly, we want to keep the workaround minimally invasive, so that we don't have to go around meddling with the desktop settings only for the sake of Emacs.

  • Specify the program to be invoked for loading and executing SLIME:

    (setq inferior-lisp-program "sbcl")
    

Add Hooks

This section describes how to enable Paredit and Rainbow Delimiters. These are not absolutely essential for having an interactive programming environment for Common Lisp. However many programmers find them useful while some do not find them useful.

In case you decide not to use either Paredit or Rainbow, then you may skip this section. In that case, you might also want to remove these packages from the dolist expression of .emacs.

  • Enable Paredit while editing Emacs Lisp code:

    (add-hook 'emacs-lisp-mode-hook 'enable-paredit-mode)
    

    Paredit helps in keeping parentheses balanced and in performing structured editing of S-expressions. While we configure it to be used for Common Lisp programming, we might as well configure it for editing Emacs Lisp code too. Then the experience of editing Emacs Lisp code and that of editing Common Lisp code will be consistent with each other.

    To test that Paredit is enabled for editing Emacs Lisp code, open a new Emacs Lisp file, say, foo.el. Then type (. Paredit should automatically insert the corresponding ).

  • Enable Paredit in eval-expression minibuffer:

    (add-hook 'eval-expression-minibuffer-setup-hook 'enable-paredit-mode)
    

    To test this, enter M-: to bring up the eval-expression minbuffer and type (. Paredit should automatically insert the corresponding ).

  • Enable Paredit while interactively evaluating Emacs Lisp expressions in inferior-emacs-lisp-mode (IELM):

    (add-hook 'ielm-mode-hook 'enable-paredit-mode)
    

    To test this, enter M-x ielm RET. When the *ielm* buffer appears, type (. Paredit should automatically insert the corresponding ).

  • Enable Paredit while editing Common Lisp code:

    (add-hook 'lisp-mode-hook 'enable-paredit-mode)
    

    To test this, open a new Common Lisp source file, say, C-x C-f foo.lisp RET. Then type (. Paredit should automatically insert the corresponding ).

  • Enable Paredit in Lisp interaction mode:

    (add-hook 'lisp-interaction-mode-hook 'enable-paredit-mode)
    

    To test this, first open a non-Lisp file, say, C-x C-f foo.txt RET. Now type (. Note that no corresponding ) is inserted because we are not in Lisp interaction mode yet. Delete (. Then start Lisp interaction mode with the command M-x lisp-interaction-mode RET. Type ( again. Paredit should now automatically insert the corresponding ).

  • Enable Paredit in SLIME REPL:

    (add-hook 'slime-repl-mode-hook 'enable-paredit-mode)
    

    To test this, start SLIME with M-x slime RET. Then type ( in SLIME REPL. Paredit should automatically insert the corresponding ).

  • When we type backspace or delete to delete a parenthesis in the SLIME REPL, Paredit fails to keep the parentheses balanced because SLIME interferes with Paredit by grabbing the delete key. To fix this issue, use the following code:

    (defun override-slime-del-key ()
      (define-key slime-repl-mode-map
        (read-kbd-macro paredit-backward-delete-key) nil))
    (add-hook 'slime-repl-mode-hook 'override-slime-del-key)
    

    To test this, start SLIME with M-x slime RET. Then type (+ 1 (+ 2 (+ 3 4))). Even though, the closing parentheses ))) will be automatically inserted, type them out to advance the cursor to the end of the line. When you type ) even if it is already present, Paredit just skips over the already present ). Once you are at the end of the line, type backspace or delete multiple times. Paredit will keep the parentheses balanced at all times.

  • Enable Rainbow Delimiters while editing Emacs Lisp code:

    (add-hook 'emacs-lisp-mode-hook 'rainbow-delimiters-mode)
    

    Rainbow Delimiters color nested parentheses with different colors according to the depth level of each parenthesis.

    To test this open a new Emacs Lisp file, say, foo.el. Then type ((((. Rainbow Delimiters should color each parenthesis differently.

  • Enable Rainbow Delimiters while interactively evaluating Emacs Lisp expressions in inferior-emacs-lisp-mode (IELM):

    (add-hook 'ielm-mode-hook 'rainbow-delimiters-mode)
    

    To test this, enter M-x ielm RET. When the *ielm* buffer comes up, type ((((. Rainbow Delimiters should color each parenthesis differently.

  • Enable Rainbow Delimiters while editing Common Lisp code:

    (add-hook 'lisp-mode-hook 'rainbow-delimiters-mode)
    

    To test this, open a new Common Lisp source file, say, foo.lisp. Then type ((((. Rainbow Delimiters should color each parenthesis differently.

  • Enable Rainbow Delimiters in Lisp interaction mode:

    (add-hook 'lisp-interaction-mode-hook 'rainbow-delimiters-mode)
    

    To test this, first open a non-Lisp file, say, foo.txt. Now type ((((. Then start Lisp interaction mode with the command M-x lisp-interaction-mode RET. Rainbow Delimiters should now color each parenthesis differently.

  • Enable Rainbow Delimiters in SLIME REPL:

    (add-hook 'slime-repl-mode-hook 'rainbow-delimiters-mode)
    

    To test this, start SLIME with M-x slime RET. Then type (((( at the REPL prompt. Rainbow Delimiters should color each parenthesis differently.

You may have noticed that we did not enable Rainbow Delimiters for eval-expression. That is because it does not work as expected as of Dec 2020. See https://github.com/Fanael/rainbow-delimiters/issues/57 for more details.

Opinion References

Channels

The following channels are available for asking questions, seeking help and receiving updates regarding this project:

You are welcome to follow or subscribe to one or more of these channels to receive updates and ask questions about this project. The Freenode and Matrix channels are bridged together, so if you join one of them, you will automatically receive the updates from the other one too.

License

This is free and open source software. You can use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of it, under the terms of the MIT License. See LICENSE.md for details.

This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND, express or implied. See LICENSE.md for details.

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