1120 lines
44 KiB
HTML
1120 lines
44 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta name="generator" content=
|
||
"HTML Tidy for HTML5 for Linux version 5.2.0">
|
||
<title>Emacs</title>
|
||
<meta charset="utf-8">
|
||
<meta name="description" content="A collection of examples of using Common Lisp">
|
||
<meta name="viewport" content=
|
||
"width=device-width, initial-scale=1">
|
||
<link rel="icon" href=
|
||
"assets/cl-logo-blue.png"/>
|
||
<link rel="stylesheet" href=
|
||
"assets/style.css">
|
||
<script type="text/javascript" src=
|
||
"assets/highlight-lisp.js">
|
||
</script>
|
||
<script type="text/javascript" src=
|
||
"assets/jquery-3.2.1.min.js">
|
||
</script>
|
||
<script type="text/javascript" src=
|
||
"assets/jquery.toc/jquery.toc.min.js">
|
||
</script>
|
||
<script type="text/javascript" src=
|
||
"assets/toggle-toc.js">
|
||
</script>
|
||
|
||
<link rel="stylesheet" href=
|
||
"assets/github.css">
|
||
|
||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
|
||
</head>
|
||
<body>
|
||
<h1 id="title-xs"><a href="index.html">The Common Lisp Cookbook</a> – Emacs</h1>
|
||
<div id="logo-container">
|
||
<a href="index.html">
|
||
<img id="logo" src="assets/cl-logo-blue.png"/>
|
||
</a>
|
||
|
||
<div id="searchform-container">
|
||
<form onsubmit="duckSearch()" action="javascript:void(0)">
|
||
<input id="searchField" type="text" value="" placeholder="Search...">
|
||
</form>
|
||
</div>
|
||
|
||
<div id="toc-container" class="toc-close">
|
||
<div id="toc-title">Table of Contents</div>
|
||
<ul id="toc" class="list-unstyled"></ul>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="content-container">
|
||
<h1 id="title-non-xs"><a href="index.html">The Common Lisp Cookbook</a> – Emacs</h1>
|
||
|
||
<!-- Announcement we can keep for 1 month or more. I remove it and re-add it from time to time. -->
|
||
<p class="announce">
|
||
📢 🤶 ⭐
|
||
<a style="font-size: 120%" href="https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPY-XMAS2023" title="This course is under a paywall on the Udemy platform. Several videos are freely available so you can judge before diving in. vindarel is (I am) the main contributor to this Cookbook."> Discover our contributor's Lisp course with this Christmas coupon.</a>
|
||
<strong>
|
||
Recently added: 18 videos on MACROS.
|
||
</strong>
|
||
<a style="font-size: 90%" href="https://github.com/vindarel/common-lisp-course-in-videos/">Learn more</a>.
|
||
</p>
|
||
<p class="announce-neutral">
|
||
📕 <a href="index.html#download-in-epub">Get the EPUB and PDF</a>
|
||
</p>
|
||
|
||
|
||
<div id="content"
|
||
<!-- intentionnally left blank -->
|
||
|
||
<h2 id="using-emacs-as-an-ide">Using Emacs as an IDE</h2>
|
||
|
||
<p>This page is meant to provide an introduction to using <a href="https://www.gnu.org/software/emacs/">Emacs</a> as a Lisp IDE.</p>
|
||
|
||
<p><a href="https://shinmera.github.io/portacle/">Portacle</a> is a portable and
|
||
multi-platform CL development environment shipping Emacs, SBCL and
|
||
necessary extensions. It is a straightforward way to get going.</p>
|
||
|
||
<p><img src="assets/emacs-teaser.png" alt="" /></p>
|
||
|
||
<p><a name="Slide-2"></a></p>
|
||
|
||
<h3 id="why-use-emacs">Why Use Emacs?</h3>
|
||
|
||
<ul>
|
||
<li>Emacs has fantastic support for working with Lisp code</li>
|
||
<li>Not tying yourself into a single CL vendor’s editor</li>
|
||
<li>Runs on virtually every OS and CL implementation</li>
|
||
<li>Emacs will probably always be around</li>
|
||
<li>Emacs works well either with a mouse or without a mouse</li>
|
||
<li>Emacs works well either in GUI mode or in the terminal</li>
|
||
<li>Emacs has a large user base with multiple newsgroups</li>
|
||
<li>Built-in tree-sitter and LSP support</li>
|
||
<li>Excellent vim mode</li>
|
||
<li>Because <a href="http://orgmode.org">Org-mode</a></li>
|
||
<li>Because <a href="https://magit.vc/">Magit</a></li>
|
||
<li>Because <a href="http://emacsrocks.com">Emacs Rocks !</a></li>
|
||
<li>Vast number of extensions: <a href="https://github.com/emacs-tw/awesome-emacs">awesome-emacs</a>.</li>
|
||
</ul>
|
||
|
||
<p><a name="Slide-3"></a></p>
|
||
|
||
<h3 id="emacs-lisp-vs-common-lisp">Emacs Lisp vs Common Lisp</h3>
|
||
|
||
<p>It isn’t necessary to use Emacs Lisp to use Emacs with Slime or Sly for Common Lisp</p>
|
||
|
||
<p>However learning Emacs Lisp can be useful and is similar (but different) from CL:</p>
|
||
<ul>
|
||
<li>Dynamic scope is everywhere</li>
|
||
<li>There are no reader (or reader-related) functions</li>
|
||
<li>Does not support all the types that are supported in CL</li>
|
||
<li>Incomplete implementation of CLOS (with the add-on EIEIO package)</li>
|
||
<li>No numerical tower support</li>
|
||
</ul>
|
||
|
||
<p>Some good Emacs Lisp learning resources:</p>
|
||
<ul>
|
||
<li><a href="https://www.gnu.org/software/emacs/manual/eintr.html">An Introduction to Programming in Emacs Lisp</a></li>
|
||
<li><a href="http://www.oreilly.com/catalog/gnuext/">Writing GNU Emacs Extensions</a></li>
|
||
<li><a href="http://wikemacs.org/wiki/Category:Emacs_Lisp">Wikemacs</a></li>
|
||
</ul>
|
||
|
||
<p><a name="Slide-slime"></a></p>
|
||
|
||
<h4 id="slime-superior-lisp-interaction-mode-for-emacs">SLIME: Superior Lisp Interaction Mode for Emacs</h4>
|
||
|
||
<p><a href="http://common-lisp.net/project/slime/">SLIME</a> is the goto major mode
|
||
for CL programming.</p>
|
||
|
||
<ul>
|
||
<li>Pros:
|
||
<ul>
|
||
<li>Provides REPL which is hooked to implementation directly in Emacs</li>
|
||
<li>Has integrated Common Lisp debugger with Emacs interface</li>
|
||
<li>Interactive object-inspector in Emacs buffer</li>
|
||
<li>Has its own minor mode which enhances lisp-mode in many ways</li>
|
||
<li>Supports every common Common Lisp implementation</li>
|
||
<li>Readily available from MELPA</li>
|
||
<li>Actively maintained</li>
|
||
<li>Symbol completion</li>
|
||
<li>Cross-referencing</li>
|
||
<li>Can perform macroexpansions</li>
|
||
</ul>
|
||
</li>
|
||
<li>Setup:
|
||
<ul>
|
||
<li>Installing it from <a href="http://wikemacs.org/wiki/Melpa">MELPA</a> is straightforward. Search package-list-packages for ‘slime’ and click to install. It will install itself and all dependencies.</li>
|
||
<li>Enable the desired contribs (SLIME does very little by defaults), e.g. <code>(slime-setup '(slime-fancy slime-quicklisp slime-asdf))</code>.</li>
|
||
<li>Run SLIME with <code>M-x slime</code>.</li>
|
||
<li>See also your GNU/Linux distribution for a “slime” package.</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<p>Check out this <strong><a href="https://www.youtube.com/watch?v=sBcPNr1CKKw">video tutorial</a></strong> ! (and the author’s channel, full of great stuff)</p>
|
||
|
||
<h5 id="slime-fancy-contrib-packages-and-other-extensions">SLIME fancy, contrib packages and other extensions</h5>
|
||
|
||
<p>SLIME’s functionalities live in packages and so-called <a href="https://common-lisp.net/project/slime/doc/html/Contributed-Packages.html">contrib
|
||
modules</a>
|
||
must be loaded to add further functionalities. The default
|
||
<code>slime-fancy</code> includes:</p>
|
||
|
||
<ul>
|
||
<li>slime-autodoc</li>
|
||
<li>slime-c-p-c</li>
|
||
<li>slime-editing-commands</li>
|
||
<li>slime-fancy-inspector</li>
|
||
<li>slime-fancy-trace</li>
|
||
<li>slime-fontifying-fu</li>
|
||
<li>slime-fuzzy</li>
|
||
<li>slime-mdot-fu</li>
|
||
<li>slime-macrostep</li>
|
||
<li>slime-presentations</li>
|
||
<li>slime-references</li>
|
||
<li>slime-repl</li>
|
||
<li>slime-scratch</li>
|
||
<li>slime-package-fu</li>
|
||
<li>slime-trace-dialog</li>
|
||
</ul>
|
||
|
||
<p>SLIME also has some nice extensions like
|
||
<a href="https://github.com/emacs-helm/helm-slime">Helm-SLIME</a> which features, among
|
||
others:</p>
|
||
|
||
<ul>
|
||
<li>Fuzzy completion,</li>
|
||
<li>REPL and connection listing,</li>
|
||
<li>Fuzzy-search of the REPL history,</li>
|
||
<li>Fuzzy-search of the <em>apropos</em> documentation.</li>
|
||
</ul>
|
||
|
||
<h5 id="repl-interactions">REPL interactions</h5>
|
||
|
||
<p>From the SLIME REPL, press <code>,</code> to prompt for commands. There is completion
|
||
over the available systems and packages. Examples:</p>
|
||
|
||
<ul>
|
||
<li><code>,load-system</code></li>
|
||
<li><code>,reload-system</code></li>
|
||
<li><code>,in-package</code></li>
|
||
<li><code>,restart-inferior-lisp</code></li>
|
||
</ul>
|
||
|
||
<p>and many more.</p>
|
||
|
||
<p>With the <code>slime-quicklisp</code> contrib, you can also <code>,ql</code> to list all systems
|
||
available for installation.</p>
|
||
|
||
<h4 id="sly-sylvester-the-cats-common-lisp-ide">SLY: Sylvester the Cat’s Common Lisp IDE</h4>
|
||
|
||
<p><a href="https://github.com/joaotavora/sly">SLY</a> is a SLIME fork that contains
|
||
the following improvements:</p>
|
||
|
||
<ul>
|
||
<li>Completely redesigned REPL based on Emacs’s own full-featured comint.el.</li>
|
||
<li>Live code annotations via the <a href="https://joaotavora.github.io/sly/#Stickers">Stickers</a> feature.</li>
|
||
<li>Consistent interactive button interface. Everything can be copied to the REPL.</li>
|
||
<li>Multiple REPLs.</li>
|
||
<li>Multiple inspectors with independent history.</li>
|
||
<li>Regexp-capable <code>M-x sly-apropos</code>.</li>
|
||
<li>Contribs are first class SLY citizens, enabled by default, loaded with ASDF on demand:
|
||
<ul>
|
||
<li><a href="https://github.com/joaotavora/sly-named-readtables">NAMED-READTABLES</a> support</li>
|
||
<li><a href="https://github.com/joaotavora/sly-macrostep">macrostep.el</a></li>
|
||
<li><a href="https://github.com/joaotavora/sly-quicklisp">Quicklisp</a></li>
|
||
<li><a href="https://github.com/mmgeorge/sly-asdf">ASDF</a></li>
|
||
<li><a href="https://git.sr.ht/~fosskers/sly-overlay">Evaluation Overlays</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<h3 id="finding-ones-way-into-emacs-built-in-documentation">Finding one’s way into Emacs’ built-in documentation</h3>
|
||
|
||
<p>Emacs comes with built-in tutorials and documentation. Moreover, it is
|
||
a self-documented and self-discoverable editor, capable of introspection to let you
|
||
know about the current keybindings, to let you search about function documentation,
|
||
available variables,source code, tutorials, etc. Whenever you ask yourself questions like
|
||
“what are the available shortcuts to do x” or “what does this
|
||
keybinding really do”, the answer is most probably a keystroke away,
|
||
right inside Emacs. You should learn a few keybindings to be able to
|
||
discover Emacs with Emacs flawlessly.</p>
|
||
|
||
<p>The help on the topic is here:</p>
|
||
|
||
<ul>
|
||
<li><a href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Help.html#Help">Help page: commands for asking Emacs about its commands</a></li>
|
||
</ul>
|
||
|
||
<p>The help keybindings start with either <code>C-h</code> or <code>F1</code>. Important ones are:</p>
|
||
|
||
<ul>
|
||
<li><code>C-h k <keybinding></code>: what function does this keybinding call?</li>
|
||
<li><code>C-h f <function name></code>: what keybinding is linked to this function?</li>
|
||
<li><code>C-h a <topic></code>: show a list of commands whose name match the given <em>topic</em>. It accepts a keyword, a list of keywords or a regular expression.</li>
|
||
<li><code>C-h i</code>: show the Info page, a menu of major topics.</li>
|
||
</ul>
|
||
|
||
<p>Some Emacs packages give even more help.</p>
|
||
|
||
<h4 id="more-help-and-discoverability-packages">More help and discoverability packages</h4>
|
||
|
||
<p>Sometimes, you start typing a key sequence but you can’t remember it
|
||
completely. Or, you wonder what other keybindings are related. Comes
|
||
<a href="https://github.com/justbur/emacs-which-key">which-key-mode</a>. This
|
||
packages will display all possible keybindings starting with the key(s) you just typed.</p>
|
||
|
||
<p>For example, I know there are useful keybindings under <code>C-x</code> but I don’t remember which ones… I just type <code>C-x</code>, I wait for half a second, and which-key shows all the ones available.</p>
|
||
|
||
<p><img src="assets/emacs-which-key-minibuffer.png" alt="" /></p>
|
||
|
||
<p>Just try it with <code>C-h</code> too!</p>
|
||
|
||
<p>See also <a href="https://github.com/Wilfred/helpful">Helpful</a>, an alternative to the built-in Emacs help that provides much more contextual information.</p>
|
||
|
||
<p><img src="assets/emacs-helpful.png" style="height: 450px" /></p>
|
||
|
||
<h4 id="learn-emacs-with-the-built-in-tutorial">Learn Emacs with the built-in tutorial</h4>
|
||
|
||
<p>Emacs ships its own tutorial. You should give it a look to learn the most important keybindings and concepts.</p>
|
||
|
||
<p>Call it with <code>M-x help-with-tutorial</code> (where <code>M-x</code> is <code>alt-x</code>).</p>
|
||
|
||
<p><a name="Slide-9"></a></p>
|
||
|
||
<h3 id="working-with-lisp-code">Working with Lisp Code</h3>
|
||
|
||
<p>In this short tutorial we’ll see how to:</p>
|
||
|
||
<ul>
|
||
<li>edit Lisp code</li>
|
||
<li>evaluate and compile Lisp code</li>
|
||
<li>search Lisp code</li>
|
||
</ul>
|
||
|
||
<h4 id="packages-for-structured-editing">Packages for structured editing</h4>
|
||
|
||
<p>In addition to the built-in Emacs commands, you have several packages at your disposal
|
||
that will help to keep the parens and/or the indentation balanced.
|
||
The list below is somewhat sorted by age of the
|
||
extension, according to the
|
||
<a href="https://github.com/shaunlebron/history-of-lisp-editing">history of Lisp editing</a>:</p>
|
||
|
||
<ul>
|
||
<li><a href="https://www.emacswiki.org/emacs/ParEdit">Paredit</a> - Paredit is a
|
||
classic. It defines the must-have commands (move, kill, split, join
|
||
a sexp,…).
|
||
(<a href="http://danmidwood.com/content/2014/11/21/animated-paredit.html">visual tutorial</a>)</li>
|
||
<li><a href="https://github.com/Fuco1/smartparens">Smartparens</a> - Smartparens
|
||
not only deals with parens but with everything that comes in pairs
|
||
(html tags,…) and thus has features for non-lispy languages.</li>
|
||
<li><a href="https://github.com/abo-abo/lispy">Lispy</a> - Lispy reimagines Paredit
|
||
with the goal to have the shortest bindings (mostly one key) that
|
||
only act depending on the point position.</li>
|
||
<li><a href="https://github.com/promethial/paxedit">Paxedit</a> - Paxedit adds
|
||
commands based on the context (in a symbol, a sexp,… ) and puts
|
||
efforts on whitespace cleanup and context refactoring.</li>
|
||
<li><a href="http://shaunlebron.github.io/parinfer/">Parinfer</a> - Parinfer
|
||
automatically fixes the parens depending on the indentation, or the
|
||
other way round (or both !).</li>
|
||
</ul>
|
||
|
||
<p>We personally advice to try Parinfer and the famous Paredit, then to
|
||
go up the list. See explanations and even more on
|
||
<a href="http://wikemacs.org/wiki/Lisp_editing">Wikemacs</a>.</p>
|
||
|
||
<p><a name="Slide-10"></a></p>
|
||
|
||
<h4 id="editing">Editing</h4>
|
||
|
||
<p>Emacs has, of course, built-in commands to deal with s-expressions.</p>
|
||
|
||
<h5 id="forwardbackwardupdown-movement-and-selection-by-s-expressions">Forward/Backward/Up/Down movement and selection by s-expressions</h5>
|
||
|
||
<p>Use <code>C-M-f</code> and <code>C-M-b</code> (<code>forward-sexp</code> and <code>backward-sexp</code>) to move
|
||
in units of s-expressions.</p>
|
||
|
||
<p>Use <code>C-M-t</code> to swap
|
||
the first addition sexp and the second one. Put the cursor on the open
|
||
parens of “(+ x” in defun c and press</p>
|
||
|
||
<p>Use <code>C-M-@</code> to highlight an entire sexp. Then press <code>C-M-u</code> to expand
|
||
the selection “upwards” and <code>C-M-d</code> to move forward down one level of
|
||
parentheses.</p>
|
||
|
||
<h5 id="deleting-s-expressions">Deleting s-expressions</h5>
|
||
|
||
<p>Use <code>C-M-k</code> (<code>kill-sexp</code>) and <code>C-M-backspace</code> (<code>backward-kill-sexp</code>) (but caution: this keybinding may restart the system on GNU/Linux).</p>
|
||
|
||
<p>For example, if point is before <code>(progn</code> (I’ll use [] as an indication where the cursor is):</p>
|
||
|
||
<pre><code class="language-lisp">(defun d ()
|
||
(if t
|
||
(+ 3 3)
|
||
[](progn
|
||
(+ 1 1)
|
||
(if t
|
||
(+ 2 2)
|
||
(+ 3 3)))
|
||
(+ 4 4)))
|
||
</code></pre>
|
||
|
||
<p>and you press <code>C-M-k</code>, you get:</p>
|
||
|
||
<pre><code class="language-lisp">(defun d ()
|
||
(if t
|
||
(+ 3 3)
|
||
[]
|
||
(+ 4 4)))
|
||
</code></pre>
|
||
|
||
<h5 id="indenting-s-expressions">Indenting s-expressions</h5>
|
||
|
||
<p>Indentation is automatic for Lisp forms.</p>
|
||
|
||
<p>Pressing TAB will indent incorrectly indented code. For example, put
|
||
the point at the beginning of the <code>(+ 3 3)</code> form and press TAB:</p>
|
||
|
||
<pre><code class="language-lisp">(progn
|
||
(+ 3 3))
|
||
</code></pre>
|
||
|
||
<p>you correctly get</p>
|
||
|
||
<pre><code class="language-lisp">(progn
|
||
(+ 3 3))
|
||
</code></pre>
|
||
|
||
<p>Use <code>C-M-q</code> (<code>slime-reindent-defun</code>) to indent the current function definition:</p>
|
||
|
||
<pre><code class="language-lisp">;; Put the cursor on the open parens of "(defun ..."
|
||
;; and press "C-M-q" to indent the code:
|
||
(defun e ()
|
||
"A badly indented function."
|
||
(let ((x 20))
|
||
(loop for i from 0 to x
|
||
do (loop for j from 0 below 10
|
||
do (print j))
|
||
(if (< i 10)
|
||
(let ((z nil) )
|
||
(setq z (format t "x=~d" i))
|
||
(print z))))))
|
||
|
||
;; This is the result:
|
||
|
||
(defun e ()
|
||
"A badly indented function (now correctly indented)."
|
||
(let ((x 20))
|
||
(loop for i from 0 to x
|
||
do (loop for j from 0 below 10
|
||
do (print j))
|
||
(if (< i 10)
|
||
(let ((z nil) )
|
||
(setq z (format t "x=~d" i))
|
||
(print z))))))
|
||
</code></pre>
|
||
|
||
<p>You can also select a region and call <code>M-x indent-region</code>.</p>
|
||
|
||
<h5 id="support-for-parenthesis">Support for parenthesis</h5>
|
||
|
||
<p>Use <code>M-(</code> to insert a pair of parenthesis (<code>()</code>) and the same
|
||
keybinding with a prefix argument, <code>C-u M-(</code>, to enclose the
|
||
expression in front of the cursor with a pair of parens.</p>
|
||
|
||
<p>For example, we start with the cursor before the first paren:</p>
|
||
|
||
<pre><code class="language-lisp">CL-USER> |(- 2 2)
|
||
</code></pre>
|
||
|
||
<p>Press <code>C-u M-(</code> to enclose it with parens:</p>
|
||
|
||
<pre><code class="language-lisp">CL-USER> (|(- 2 2))
|
||
;; now write anything.
|
||
CL-USER> (zerop (- 2 2))
|
||
</code></pre>
|
||
|
||
<p>With a numbered prefix argument (<code>C-u 2 M-(</code>), wrap around this number of s-expressions.</p>
|
||
|
||
<p>Additionnaly, use <code>M-x check-parens</code> to spot malformed s-exps and <code>C-c
|
||
C-]</code> (<code>slime-close-all-parens-in-sexp</code>) to insert the required number
|
||
of closing parenthesis.</p>
|
||
|
||
<h5 id="code-completion">Code completion</h5>
|
||
|
||
<p>Use the built-in <code>C-c TAB</code> to complete symbols in SLIME. You can get tooltips
|
||
with <a href="http://company-mode.github.io/">company-mode</a>.</p>
|
||
|
||
<p><img src="assets/emacs-company-elisp.png" alt="" /></p>
|
||
|
||
<p>In the REPL, it’s simply TAB.</p>
|
||
|
||
<p>Use Emacs’ hippie-expand, bound to <code>M-/</code>, to complete any string
|
||
present in other open buffers.</p>
|
||
|
||
<h5 id="hidingshowing-code">Hiding/showing code</h5>
|
||
|
||
<p>Use <code>C-x n n</code> (narrow-to-region) and <code>C-x n w</code> to widen back.</p>
|
||
|
||
<p>See also <a href="http://wikemacs.org/wiki/Folding">code folding</a>.</p>
|
||
|
||
<h5 id="comments">Comments</h5>
|
||
|
||
<p>Insert a comment, comment a region with <code>M-;</code>, adjust text with <code>M-q</code>.</p>
|
||
|
||
<p><a name="Slide-11"></a></p>
|
||
|
||
<h4 id="evaluating-and-compiling-lisp-in-slime">Evaluating and Compiling Lisp in SLIME</h4>
|
||
|
||
<p>Compile the entire <strong>buffer</strong> by pressing <code>C-c C-k</code> (<code>slime-compile-and-load-file</code>).</p>
|
||
|
||
<p>Compile a <strong>region</strong> with <code>M-x slime-compile-region</code>.</p>
|
||
|
||
<p>Compile a <strong>defun</strong> by putting the cursor inside it and pressing <code>C-c C-c</code> (<code>slime-compile-defun</code>).</p>
|
||
|
||
<p>To <strong>evaluate</strong> rather than compile:</p>
|
||
|
||
<ul>
|
||
<li>evaluate the <strong>sexp</strong> before the point by putting the cursor after
|
||
its closing paren and pressing <code>C-x C-e</code>
|
||
(<code>slime-eval-last-expression</code>). The result is printed in the minibuffer.</li>
|
||
<li>similarly, use <code>C-c C-p</code> (<code>slime-pprint-eval-last-expression</code>) to eval and pretty-print the expression before point. It shows the result in a new “slime-description” window.</li>
|
||
<li>evaluate a region with <code>C-c C-r</code>,</li>
|
||
<li>evaluate a defun with <code>C-M-x</code>,</li>
|
||
<li>type <code>C-c C-e</code> (<code>slime-interactive-eval</code>) to get a prompt that asks for code to eval in the current context. It prints the result in the minibuffer. With a prefix argument, insert the result into the current buffer.</li>
|
||
<li>type <code>C-c C-j</code> (<code>slime-eval-last-expression-in-repl</code>), when the cursor is after the closing parenthesis of an expression, to send this expression to the REPL and evaluate it.</li>
|
||
</ul>
|
||
|
||
<p>See also other commands in the menu.</p>
|
||
|
||
<hr />
|
||
|
||
<p><strong>EVALUATION VS COMPILATION</strong></p>
|
||
|
||
<p>There are a couple of pragmatic differences when choosing between compiling or evaluating.
|
||
In general, it is better to <em>compile</em> top-level forms, for two reasons:</p>
|
||
|
||
<ul>
|
||
<li>Compiling a top-level form highlights warnings and errors in the editor, whereas evaluation does not.</li>
|
||
<li>SLIME keeps track of line-numbers of compiled forms, but when a top-level form is evaluated, the file line number information is lost. That’s problematic for code navigation afterwards.</li>
|
||
</ul>
|
||
|
||
<p><code>eval</code> is still useful to observe results from individual non top-level forms. For example, say you have this function:</p>
|
||
|
||
<pre><code class="language-lisp">(defun foo ()
|
||
(let ((f (open "/home/mariano/test.lisp")))
|
||
...))
|
||
</code></pre>
|
||
|
||
<p>Go to the end of the OPEN expression and evaluate it (<code>C-x C-e</code>), to observe the result:</p>
|
||
|
||
<pre><code>=> #<SB-SYS:FD-STREAM for "file /mnt/e6b00b8f-9dad-4bf4-bd40-34b1e6d31f0a/home/marian/test.lisp" {1003AAAB53}>
|
||
</code></pre>
|
||
|
||
<p>Or on this example, with the cursor on the last parentheses, press <code>C-x C-e</code> to evaluate the <code>let</code>:</p>
|
||
|
||
<pre><code class="language-lisp">(let ((n 20))
|
||
(loop for i from 0 below n
|
||
do (print i)))
|
||
</code></pre>
|
||
|
||
<p>You should see numbers printed in the REPL.</p>
|
||
|
||
<p>See also <a href="https://github.com/kaz-yos/eval-in-repl">eval-in-repl</a> to send any form to the repl.</p>
|
||
|
||
<hr />
|
||
|
||
<p><a name="Slide-12"></a></p>
|
||
|
||
<h4 id="searching-lisp-code">Searching Lisp Code</h4>
|
||
|
||
<h5 id="standard-emacs-text-search-isearch-forwardbackward-regexp-searches-searchreplace">Standard Emacs text search (isearch forward/backward, regexp searches, search/replace)</h5>
|
||
|
||
<p><code>C-s</code> does an incremental search forward (e.g. - as each key is
|
||
the search string is entered, the source file is searched for the
|
||
first match. This can make finding specific text much quicker as
|
||
you only need to type in the unique characters. Repeat searches
|
||
(using the same search characters) can be done by repeatedly
|
||
pressing <code>C-s</code></p>
|
||
|
||
<p><code>C-r</code> does an incremental search backward</p>
|
||
|
||
<p><code>C-s RET</code> and <code>C-r RET</code> both do conventional string searches
|
||
(forward and backward respectively)</p>
|
||
|
||
<p><code>C-M-s</code> and <code>C-M-r</code> both do regular expression searches (forward
|
||
and backward respectively)</p>
|
||
|
||
<p><code>M-%</code> does a search/replace while <code>C-M-%</code> does a regular
|
||
expression search/replace</p>
|
||
|
||
<h5 id="finding-occurrences-occur-grep">Finding occurrences (occur, grep)</h5>
|
||
|
||
<p>Use <code>M-x grep</code>, <code>rgrep</code>, <code>occur</code>…</p>
|
||
|
||
<p>See also interactive versions with
|
||
<a href="http://wikemacs.org/wiki/Helm-swoop">helm-swoop</a>, helm-occur,
|
||
<a href="https://github.com/Wilfred/ag.el">ag.el</a>.</p>
|
||
|
||
<h5 id="go-to-definition">Go to definition</h5>
|
||
|
||
<p>Put the cursor on any symbol and press <code>M-.</code> (<code>slime-edit-definition</code>) to go to its
|
||
definition. Press <code>M-,</code> to come back.</p>
|
||
|
||
<h5 id="go-to-symbol-list-symbols-in-current-source">Go to symbol, list symbols in current source</h5>
|
||
|
||
<p>Use <code>C-u M-.</code> (<code>slime-edit-definition</code> with a prefix argument, also available as <code>M-- M-.</code>) to autocomplete the symbol and navigate to it. This command always asks for a symbol even if the cursor is on one. It works with any loaded definition. Here’s a little <a href="https://www.youtube.com/watch?v=ZAEt73JHup8">demonstration video</a>.</p>
|
||
|
||
<p>You can think of it as a <code>imenu</code> completion that always work for any Lisp symbol. Add in <a href="https://common-lisp.net/project/slime/doc/html/Fuzzy-Completion.html">Slime’s fuzzy completion</a> for maximum powerness!</p>
|
||
|
||
<h5 id="crossreferencing-find-whos-calling-referencing-setting-a-symbol">Crossreferencing: find who’s calling, referencing, setting a symbol</h5>
|
||
|
||
<p>Slime has nice cross-referencing facilities. For example, you can ask
|
||
what calls a particular function, what expands a macro, or where a global variable is being used.</p>
|
||
|
||
<p>Results are presented in a new buffer, listing the places which reference a particular entity.
|
||
From there, we can press Enter to go to the corresponding source line,
|
||
or more interestingly we can recompile the place at point by pressing <strong>C-c C-c</strong> on that
|
||
line. Likewise, <strong>C-c C-k</strong> will recompile all the references. This is useful when
|
||
modifying macros, inline functions, or constants.</p>
|
||
|
||
<p>The bindings are the following (they are also shown in Slime’s menu):</p>
|
||
|
||
<ul>
|
||
<li><strong>C-c C-w c</strong> (<code>slime-who-calls</code>) callers of a function</li>
|
||
<li><strong>C-c C-w m</strong> (<code>slime-who-macroexpands</code>) places where a macro is expanded</li>
|
||
<li><strong>C-c C-w r</strong> (<code>slime-who-references</code>) global variable references</li>
|
||
<li><strong>C-c C-w b</strong> (<code>slime-who-bind</code>) global variable bindings</li>
|
||
<li><strong>C-c C-w s</strong> (<code>slime-who-sets</code>) global variable setters</li>
|
||
<li><strong>C-c C-w a</strong> (<code>slime-who-specializes</code>) methods specialized on a symbol</li>
|
||
</ul>
|
||
|
||
<p>And when the <code>slime-asdf</code> contrib is enabled,
|
||
<strong>C-c C-w d</strong> (<code>slime-who-depends-on</code>) lists dependent ASDF systems</p>
|
||
|
||
<p>And a general binding: <strong>M-?</strong> or <strong>M-_</strong> (<code>slime-edit-uses</code>) combines all
|
||
of the above, it lists every kind of references.</p>
|
||
|
||
<p><a name="Slide-13"></a></p>
|
||
|
||
<h3 id="lisp-documentation-in-emacs---learning-about-lisp-symbols">Lisp Documentation in Emacs - Learning About Lisp Symbols</h3>
|
||
|
||
<h4 id="argument-lists">Argument lists</h4>
|
||
|
||
<p>When you put the cursor on a function, SLIME will show its signature
|
||
in the minibuffer.</p>
|
||
|
||
<h4 id="documentation-lookup">Documentation lookup</h4>
|
||
|
||
<p>The main shortcut to know is:</p>
|
||
|
||
<ul>
|
||
<li><strong>C-c C-d d</strong> shows the symbols’ documentation on a new window (same result as using <code>describe</code>).</li>
|
||
</ul>
|
||
|
||
<p>Other bindings which may be useful:</p>
|
||
|
||
<ul>
|
||
<li><strong>C-c C-d f</strong> describes a function</li>
|
||
<li><strong>C-c C-d h</strong> looks up the symbol documentation in CLHS by opening the web browser. But it works only on symbols, so there are two more bindings:</li>
|
||
<li><strong>C-c C-d #</strong> for reader macros</li>
|
||
<li><strong>C-c C-d ~</strong> for format directives</li>
|
||
</ul>
|
||
|
||
<p>You can enhance the help buffer with the Slime extension <a href="https://github.com/mmontone/slime-doc-contribs">slime-doc-contribs</a>. It will show more information in a nice looking buffer, and it will add choices to the documentation command:</p>
|
||
|
||
<ul>
|
||
<li><strong>slime-help-package</strong> will display information about a CL package: it will nicely show its exported variables, conditions, classes, generic functions, functions and macros, with their documentation. It is a great way to see at a glance what a package provides.</li>
|
||
<li><strong>slime-help-system</strong> does the same for a <em>system</em>.</li>
|
||
<li><strong>slime-help-apropos-documentation</strong> will show symbols whose documentation contains matches for “PATTERN”, which is a great way to lookup for functions.</li>
|
||
<li>and more.</li>
|
||
</ul>
|
||
|
||
<p><img src="https://github.com/mmontone/slime-doc-contribs/raw/master/slime-help.png" alt="" /></p>
|
||
|
||
<h4 id="inspect">Inspect</h4>
|
||
|
||
<p>You can call <code>(inspect 'symbol)</code> from the REPL or call it with <code>C-c I</code> from a source file.</p>
|
||
|
||
<h4 id="macroexpand">Macroexpand</h4>
|
||
|
||
<p>Use <code>C-c M-m</code> to macroexpand a macro call</p>
|
||
|
||
<h4 id="consult-the-hyper-spec-clhs-offline">Consult the Hyper Spec (CLHS) offline</h4>
|
||
|
||
<p>The <a href="http://www.lispworks.com/documentation/common-lisp.html">Common Lisp Hyper Spec</a> is the
|
||
official online version of the ANSI Common Lisp standard. We can start
|
||
browsing it from <a href="http://www.lispworks.com/documentation/HyperSpec/Front/StartPts.htm">starting points</a>:
|
||
a shortened <a href="http://www.lispworks.com/documentation/HyperSpec/Front/Hilights.htm">table of contents of highlights</a>,
|
||
a <a href="http://www.lispworks.com/documentation/HyperSpec/Front/Hilights.htm">symbols index</a>,
|
||
a glossary, a master index.</p>
|
||
|
||
<p>Since January of 2023, we have the Common Lisp Community Spec: <a href="https://cl-community-spec.github.io/pages/index.html">https://cl-community-spec.github.io/pages/index.html</a>, a new web rendering of the specification. It is a more modern rendering:</p>
|
||
|
||
<ul>
|
||
<li>it has a <em>search box</em></li>
|
||
<li>it has <em>syntax highlihgting</em></li>
|
||
<li>it is hosted on GitHub and we have the right to modify it: https://github.com/fonol/cl-community-spec</li>
|
||
</ul>
|
||
|
||
<p>If you want other tools to do a quick look-up of symbols on the CLHS,
|
||
since the official website doesn’t have a search bar, you can use:</p>
|
||
<ul>
|
||
<li>Xach’s website search utility: <a href="https://www.xach.com/clhs?q=with-open-file">https://www.xach.com/clhs?q=with-open-file</a></li>
|
||
<li>the l1sp.org website: <a href="http://l1sp.org/search?q=with-open-file">http://l1sp.org/search?q=with-open-file</a>,</li>
|
||
<li>and we can use Duckduckgo’s or Brave Search’s <code>!clhs</code> “bang”.</li>
|
||
</ul>
|
||
|
||
<p>We can <strong>browse the CLHS offline</strong> with <a href="https://kapeli.com/dash">Dash</a> on MacOS, <a href="https://zealdocs.org/">Zeal</a> on GNU/Linux and <a href="https://velocity.silverlakesoftware.com/">Velocity</a> on Windows.</p>
|
||
|
||
<p>But we can also browse it offline from Emacs. We have to install a CL package and to configure the Emacs side with one command:</p>
|
||
|
||
<pre><code class="language-lisp">(ql:quickload "clhs")
|
||
(clhs:install-clhs-use-local)
|
||
</code></pre>
|
||
|
||
<p>Then add this to your Emacs configuration:</p>
|
||
|
||
<pre><code class="language-lisp">(load "~/quicklisp/clhs-use-local.el" 'noerror)
|
||
</code></pre>
|
||
|
||
<p>Now, you can use <code>C-c C-d h</code> to look-up the symbol at point in the
|
||
HyperSpec. This will open your browser, but look at its URL starting
|
||
with “file://home/”: it opens a local file.</p>
|
||
|
||
<p>Other commands are available:</p>
|
||
|
||
<ul>
|
||
<li>when you want to look-up a reader macro, such as <code>#'</code>
|
||
(sharpsign-quote) or <code>(</code> (left-parenthesis), use
|
||
<code>M-x common-lisp-hyperspec-lookup-reader-macro</code>, bound to <code>C-c C-d #</code>.</li>
|
||
<li>to look-up a <code>format</code> directive, such as <code>~A</code>, use <code>M-x
|
||
common-lisp-hyperspec-format</code>, bound to <code>C-c C-d ~</code>.
|
||
<ul>
|
||
<li>of course, you can TAB-complete on Emacs’ minibuffer prompt to see all the available format directives.</li>
|
||
</ul>
|
||
</li>
|
||
<li>you can also look-up glossary terms (for example, you can look-up “function” instead of “defun”), use <code>M-x common-lisp-hyperspec-glossary-term</code>, bound to <code>C-c C-d g</code>.</li>
|
||
</ul>
|
||
|
||
<h3 id="miscellaneous">Miscellaneous</h3>
|
||
|
||
<h4 id="synchronizing-packages">Synchronizing packages</h4>
|
||
|
||
<p><strong>C-c ~</strong> (<code>slime-sync-package-and-default-directory</code>): When run in a
|
||
buffer with a lisp file it will change the current package of the REPL
|
||
to the package of that file and also set the current directory of the REPL
|
||
to the parent directory of the file.</p>
|
||
|
||
<h4 id="calling-code">Calling code</h4>
|
||
|
||
<p><strong>C-c C-y</strong> (<code>slime-call-defun</code>): When the point is inside a defun and
|
||
C-c C-y is pressed,</p>
|
||
|
||
<p>(I’ll use [] as an indication where the cursor is)</p>
|
||
|
||
<pre><code class="language-lisp">(defun foo ()
|
||
nil[])
|
||
</code></pre>
|
||
|
||
<p>then <code>(foo [])</code> will be inserted into the REPL, so that you can write
|
||
additional arguments and run it.</p>
|
||
|
||
<p>If <code>foo</code> was in a different package than the package of the REPL,
|
||
<code>(package:foo )</code> or <code>(package::foo )</code> will be inserted.</p>
|
||
|
||
<p>This feature is very useful for testing a function you just wrote.</p>
|
||
|
||
<p>That works not only for defun, but also for defgeneric, defmethod,
|
||
defmacro, and define-compiler-macro in the same fashion as for defun.</p>
|
||
|
||
<p>For defvar, defparameter, defconstant: <code>[] *foo*</code> will be inserted
|
||
(the cursor is positioned before the symbol so that you can easily
|
||
wrap it into a function call).</p>
|
||
|
||
<p>For defclass: <code>(make-instance ‘class-name )</code>.</p>
|
||
|
||
<p><strong>Inserting calls to frames in the debugger</strong></p>
|
||
|
||
<p><strong>C-y</strong> in SLDB on a frame will insert a call to that frame into the REPL, e.g.,</p>
|
||
|
||
<pre><code>(/ 0) =>
|
||
…
|
||
1: (CCL::INTEGER-/-INTEGER 1 0)
|
||
…
|
||
</code></pre>
|
||
|
||
<p><strong>C-y</strong> will insert <code>(CCL::INTEGER-/-INTEGER 1 0)</code>.</p>
|
||
|
||
<p>(thanks to <a href="https://slime-tips.tumblr.com/page/2">Slime tips</a>)</p>
|
||
|
||
<h4 id="exporting-symbols">Exporting symbols</h4>
|
||
|
||
<p><strong>C-c x</strong> (<em>slime-export-symbol-at-point</em>) from the <code>slime-package-fu</code>
|
||
contrib: takes the symbol at point and modifies the <code>:export</code> clause of
|
||
the corresponding defpackage form. It also exports the symbol. When
|
||
called with a negative argument (C-u C-c x) it will remove the symbol
|
||
from <code>:export</code> and unexport it.</p>
|
||
|
||
<p><strong>M-x slime-export-class</strong> does the same but with symbols defined
|
||
by a structure or a class, like accessors, constructors, and so on.
|
||
It works on structures only on SBCL and Clozure CL so far.
|
||
Classes should work everywhere with MOP.</p>
|
||
|
||
<p>Customization</p>
|
||
|
||
<p>There are different styles of how symbols are presented in
|
||
<code>defpackage</code>, the default is to use uninterned symbols (<code>#:foo</code>).
|
||
This can be changed:</p>
|
||
|
||
<p>to use keywords:</p>
|
||
|
||
<pre><code class="language-lisp">(setq slime-export-symbol-representation-function
|
||
(lambda (n) (format ":%s" n)))
|
||
</code></pre>
|
||
|
||
<p>or strings:</p>
|
||
|
||
<pre><code class="language-lisp">(setq slime-export-symbol-representation-function
|
||
(lambda (n) (format "\"%s\"" (upcase n))))
|
||
</code></pre>
|
||
|
||
<h4 id="project-management">Project Management</h4>
|
||
|
||
<p>ASDF is the de-facto build facility. It is shipped in most Common Lisp implementations.</p>
|
||
|
||
<ul>
|
||
<li><a href="https://common-lisp.net/project/asdf/">ASDF</a></li>
|
||
<li><a href="https://gitlab.common-lisp.net/asdf/asdf/blob/master/doc/best_practices.md">ASDF best practices</a></li>
|
||
</ul>
|
||
|
||
<h4 id="searching-quicklisp-libraries">Searching Quicklisp libraries</h4>
|
||
|
||
<p>From the REPL, we can use <code>,ql</code> to install a package known by name already.</p>
|
||
|
||
<p>In addition, we can use the <a href="https://github.com/mmontone/quicklisp-systems">Quicklisp-systems</a> Slime extension to search, browse and load Quicklisp systems from Emacs.</p>
|
||
|
||
<h3 id="questionsanswers">Questions/Answers</h3>
|
||
|
||
<h4 id="utf-8-encoding">utf-8 encoding</h4>
|
||
|
||
<p>You might want to set this to your init file:</p>
|
||
|
||
<pre><code class="language-lisp">(set-language-environment "UTF-8")
|
||
(setenv "LC_CTYPE" "en_US.UTF-8")
|
||
</code></pre>
|
||
|
||
<p>and for Sly:</p>
|
||
|
||
<pre><code class="language-lisp">(setf sly-lisp-implementations
|
||
'((sbcl ("/usr/local/bin/sbcl") :coding-system utf-8-unix)
|
||
))
|
||
</code></pre>
|
||
|
||
<p>This will avoid getting <code>ascii stream decoding error</code>s when you have
|
||
non-ascii characters in files you evaluate with SLIME.</p>
|
||
|
||
<h4 id="default-cutcopypaste-keybindings">Default cut/copy/paste keybindings</h4>
|
||
|
||
<p><em>I am so used to C-c, C-v and friends to copy and paste text that
|
||
the default Emacs shortcuts don’t make any sense to me.</em></p>
|
||
|
||
<p>Luckily, you have a solution! Install <a href="http://www.emacswiki.org/cgi-bin/wiki.pl?CuaMode">cua-mode</a> and you can continue to use these shortcuts.</p>
|
||
|
||
<pre><code class="language-lisp">;; C-z=Undo, C-c=Copy, C-x=Cut, C-v=Paste (needs cua.el)
|
||
(require 'cua) (CUA-mode t)
|
||
</code></pre>
|
||
|
||
<h3 id="appendix">Appendix</h3>
|
||
|
||
<h4 id="all-slime-repl-shortcuts">All Slime REPL shortcuts</h4>
|
||
|
||
<p>Here is the reference of all Slime shortcuts that work in the REPL.</p>
|
||
|
||
<p>To see them, go in a REPL, type <code>C-h m</code> and go to the Slime REPL map section.</p>
|
||
|
||
<pre><code>REPL mode defined in ‘slime-repl.el’:
|
||
Major mode for interacting with a superior Lisp.
|
||
key binding
|
||
--- -------
|
||
|
||
C-c Prefix Command
|
||
C-j slime-repl-newline-and-indent
|
||
RET slime-repl-return
|
||
C-x Prefix Command
|
||
ESC Prefix Command
|
||
SPC slime-space
|
||
(that binding is currently shadowed by another mode)
|
||
, slime-handle-repl-shortcut
|
||
DEL backward-delete-char-untabify
|
||
<C-down> slime-repl-forward-input
|
||
<C-return> slime-repl-closing-return
|
||
<C-up> slime-repl-backward-input
|
||
<return> slime-repl-return
|
||
|
||
C-x C-e slime-eval-last-expression
|
||
|
||
C-c C-c slime-interrupt
|
||
C-c C-n slime-repl-next-prompt
|
||
C-c C-o slime-repl-clear-output
|
||
C-c C-p slime-repl-previous-prompt
|
||
C-c C-s slime-complete-form
|
||
C-c C-u slime-repl-kill-input
|
||
C-c C-z other-window
|
||
C-c ESC Prefix Command
|
||
C-c I slime-repl-inspect
|
||
|
||
M-RET slime-repl-closing-return
|
||
M-n slime-repl-next-input
|
||
M-p slime-repl-previous-input
|
||
M-r slime-repl-previous-matching-input
|
||
M-s previous-line
|
||
|
||
C-c C-z run-lisp
|
||
(that binding is currently shadowed by another mode)
|
||
|
||
C-M-x lisp-eval-defun
|
||
|
||
C-M-q indent-sexp
|
||
|
||
C-M-q prog-indent-sexp
|
||
(that binding is currently shadowed by another mode)
|
||
|
||
C-c M-e macrostep-expand
|
||
C-c M-i slime-fuzzy-complete-symbol
|
||
C-c M-o slime-repl-clear-buffer
|
||
</code></pre>
|
||
|
||
<h4 id="all-other-slime-shortcuts">All other Slime shortcuts</h4>
|
||
|
||
<p>Here are all the default keybindings defined by Slime mode.</p>
|
||
|
||
<p>To see them, go in a .lisp file, type <code>C-h m</code> and go to the Slime section.</p>
|
||
|
||
<pre><code>Commands to compile the current buffer’s source file and visually
|
||
highlight any resulting compiler notes and warnings:
|
||
C-c C-k - Compile and load the current buffer’s file.
|
||
C-c M-k - Compile (but not load) the current buffer’s file.
|
||
C-c C-c - Compile the top-level form at point.
|
||
|
||
Commands for visiting compiler notes:
|
||
M-n - Goto the next form with a compiler note.
|
||
M-p - Goto the previous form with a compiler note.
|
||
C-c M-c - Remove compiler-note annotations in buffer.
|
||
|
||
Finding definitions:
|
||
M-.
|
||
- Edit the definition of the function called at point.
|
||
M-,
|
||
- Pop the definition stack to go back from a definition.
|
||
|
||
Documentation commands:
|
||
C-c C-d C-d - Describe symbol.
|
||
C-c C-d C-a - Apropos search.
|
||
C-c M-d - Disassemble a function.
|
||
|
||
Evaluation commands:
|
||
C-M-x - Evaluate top-level from containing point.
|
||
C-x C-e - Evaluate sexp before point.
|
||
C-c C-p - Evaluate sexp before point, pretty-print result.
|
||
|
||
Full set of commands:
|
||
key binding
|
||
--- -------
|
||
|
||
C-c Prefix Command
|
||
C-x Prefix Command
|
||
ESC Prefix Command
|
||
SPC slime-space
|
||
|
||
C-c C-c slime-compile-defun
|
||
C-c C-j slime-eval-last-expression-in-repl
|
||
C-c C-k slime-compile-and-load-file
|
||
C-c C-s slime-complete-form
|
||
C-c C-y slime-call-defun
|
||
C-c ESC Prefix Command
|
||
C-c C-] slime-close-all-parens-in-sexp
|
||
C-c x slime-export-symbol-at-point
|
||
C-c ~ slime-sync-package-and-default-directory
|
||
|
||
C-M-a slime-beginning-of-defun
|
||
C-M-e slime-end-of-defun
|
||
M-n slime-next-note
|
||
M-p slime-previous-note
|
||
|
||
C-M-, slime-previous-location
|
||
C-M-. slime-next-location
|
||
|
||
C-c TAB completion-at-point
|
||
C-c RET slime-expand-1
|
||
C-c C-p slime-pprint-eval-last-expression
|
||
C-c C-u slime-undefine-function
|
||
C-c ESC Prefix Command
|
||
|
||
C-c C-b slime-interrupt
|
||
C-c C-d slime-doc-map
|
||
C-c C-e slime-interactive-eval
|
||
C-c C-l slime-load-file
|
||
C-c C-r slime-eval-region
|
||
C-c C-t slime-toggle-fancy-trace
|
||
C-c C-v Prefix Command
|
||
C-c C-w slime-who-map
|
||
C-c C-x Prefix Command
|
||
C-c C-z slime-switch-to-output-buffer
|
||
C-c ESC Prefix Command
|
||
C-c : slime-interactive-eval
|
||
C-c < slime-list-callers
|
||
C-c > slime-list-callees
|
||
C-c E slime-edit-value
|
||
C-c I slime-inspect
|
||
|
||
C-x C-e slime-eval-last-expression
|
||
C-x 4 Prefix Command
|
||
C-x 5 Prefix Command
|
||
|
||
C-M-x slime-eval-defun
|
||
M-, slime-pop-find-definition-stack
|
||
M-. slime-edit-definition
|
||
M-? slime-edit-uses
|
||
M-_ slime-edit-uses
|
||
|
||
C-c M-c slime-remove-notes
|
||
C-c M-e macrostep-expand
|
||
C-c M-i slime-fuzzy-complete-symbol
|
||
C-c M-k slime-compile-file
|
||
C-c M-q slime-reindent-defun
|
||
|
||
C-c M-m slime-macroexpand-all
|
||
|
||
C-c C-v C-d slime-describe-presentation-at-point
|
||
C-c C-v TAB slime-inspect-presentation-at-point
|
||
C-c C-v C-n slime-next-presentation
|
||
C-c C-v C-p slime-previous-presentation
|
||
C-c C-v C-r slime-copy-presentation-at-point-to-repl
|
||
C-c C-v C-w slime-copy-presentation-at-point-to-kill-ring
|
||
C-c C-v ESC Prefix Command
|
||
C-c C-v SPC slime-mark-presentation
|
||
C-c C-v d slime-describe-presentation-at-point
|
||
C-c C-v i slime-inspect-presentation-at-point
|
||
C-c C-v n slime-next-presentation
|
||
C-c C-v p slime-previous-presentation
|
||
C-c C-v r slime-copy-presentation-at-point-to-repl
|
||
C-c C-v w slime-copy-presentation-at-point-to-kill-ring
|
||
C-c C-v C-SPC slime-mark-presentation
|
||
|
||
C-c C-w C-a slime-who-specializes
|
||
C-c C-w C-b slime-who-binds
|
||
C-c C-w C-c slime-who-calls
|
||
C-c C-w RET slime-who-macroexpands
|
||
C-c C-w C-r slime-who-references
|
||
C-c C-w C-s slime-who-sets
|
||
C-c C-w C-w slime-calls-who
|
||
C-c C-w a slime-who-specializes
|
||
C-c C-w b slime-who-binds
|
||
C-c C-w c slime-who-calls
|
||
C-c C-w d slime-who-depends-on
|
||
C-c C-w m slime-who-macroexpands
|
||
C-c C-w r slime-who-references
|
||
C-c C-w s slime-who-sets
|
||
C-c C-w w slime-calls-who
|
||
|
||
C-c C-d C-a slime-apropos
|
||
C-c C-d C-d slime-describe-symbol
|
||
C-c C-d C-f slime-describe-function
|
||
C-c C-d C-g common-lisp-hyperspec-glossary-term
|
||
C-c C-d C-p slime-apropos-package
|
||
C-c C-d C-z slime-apropos-all
|
||
C-c C-d # common-lisp-hyperspec-lookup-reader-macro
|
||
C-c C-d a slime-apropos
|
||
C-c C-d d slime-describe-symbol
|
||
C-c C-d f slime-describe-function
|
||
C-c C-d g common-lisp-hyperspec-glossary-term
|
||
C-c C-d h slime-documentation-lookup
|
||
C-c C-d p slime-apropos-package
|
||
C-c C-d z slime-apropos-all
|
||
C-c C-d ~ common-lisp-hyperspec-format
|
||
C-c C-d C-# common-lisp-hyperspec-lookup-reader-macro
|
||
C-c C-d C-~ common-lisp-hyperspec-format
|
||
|
||
C-c C-x c slime-list-connections
|
||
C-c C-x n slime-next-connection
|
||
C-c C-x p slime-prev-connection
|
||
C-c C-x t slime-list-threads
|
||
|
||
C-c M-d slime-disassemble-symbol
|
||
C-c M-p slime-repl-set-package
|
||
|
||
C-x 5 . slime-edit-definition-other-frame
|
||
|
||
C-x 4 . slime-edit-definition-other-window
|
||
|
||
C-c C-v M-o slime-clear-presentations
|
||
</code></pre>
|
||
|
||
<h3 id="see-also">See also</h3>
|
||
|
||
<ul>
|
||
<li><a href="https://bnmcgn.github.io/lisp-guide/lisp-exploration.html">Common Lisp REPL exploration guide</a> - a concise and curated set of highlights to find one’s way in the REPL.</li>
|
||
</ul>
|
||
|
||
|
||
<p class="page-source">
|
||
Page source: <a href="https://github.com/LispCookbook/cl-cookbook/blob/master/emacs-ide.md">emacs-ide.md</a>
|
||
</p>
|
||
</div>
|
||
|
||
<script type="text/javascript">
|
||
|
||
// Don't write the TOC on the index.
|
||
if (window.location.pathname != "/cl-cookbook/") {
|
||
$("#toc").toc({
|
||
content: "#content", // will ignore the first h1 with the site+page title.
|
||
headings: "h1,h2,h3,h4"});
|
||
}
|
||
|
||
$("#two-cols + ul").css({
|
||
"column-count": "2",
|
||
});
|
||
$("#contributors + ul").css({
|
||
"column-count": "4",
|
||
});
|
||
</script>
|
||
|
||
|
||
|
||
<div>
|
||
<footer class="footer">
|
||
<hr/>
|
||
© 2002–2023 the Common Lisp Cookbook Project
|
||
<div>
|
||
📹 Discover <a style="color: darkgrey; text-decoration: underline", href="https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358">vindarel's Lisp course on Udemy</a>
|
||
</div>
|
||
</footer>
|
||
|
||
</div>
|
||
<div id="toc-btn">T<br>O<br>C</div>
|
||
</div>
|
||
|
||
<script text="javascript">
|
||
HighlightLisp.highlight_auto({className: null});
|
||
</script>
|
||
|
||
<script type="text/javascript">
|
||
function duckSearch() {
|
||
var searchField = document.getElementById("searchField");
|
||
if (searchField && searchField.value) {
|
||
var query = escape("site:lispcookbook.github.io/cl-cookbook/ " + searchField.value);
|
||
window.location.href = "https://duckduckgo.com/?kj=b2&kf=-1&ko=1&q=" + query;
|
||
// https://duckduckgo.com/params
|
||
// kj=b2: blue header in results page
|
||
// kf=-1: no favicons
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<script async defer data-domain="lispcookbook.github.io/cl-cookbook" src="https://plausible.io/js/plausible.js"></script>
|
||
|
||
</body>
|
||
</html>
|