Commit Diff


commit - 9b6354fcc7a6867dac04257ace00b9d8e18bb17f
commit + 7fdb3009f91eed630dc39ff7de765bf6cc16d691
blob - /dev/null
blob + 34a1ee5cd90f0b187d47a151b89288eef588cbca (mode 644)
--- /dev/null
+++ elpa/macrostep-0.9.2/.elpaignore
@@ -0,0 +1,2 @@
+.travis.yml
+LICENSE
blob - /dev/null
blob + f8e6a17c8c62a7cb48c0c86628730178ef879ff3 (mode 644)
--- /dev/null
+++ elpa/macrostep-0.9.2/Makefile
@@ -0,0 +1,17 @@
+EMACS ?= emacs
+
+all: macrostep.elc macrostep-c.elc
+
+clean:
+	rm -f *.elc
+
+test: clean all
+	$(EMACS) --batch -L . --load macrostep-test.el
+
+sandbox: all
+	$(EMACS) -Q -L . --load macrostep --load macrostep-c
+
+%.elc: %.el
+	$(EMACS) --batch -L . --funcall batch-byte-compile "$<"
+
+.PHONY: test all clean
blob - /dev/null
blob + b0608735e2326aacee547dfe00d631076fdbe2cd (mode 644)
--- /dev/null
+++ elpa/macrostep-0.9.2/README-elpa
@@ -0,0 +1,235 @@
+1 macrostep: interactive macro-expander
+═══════════════════════════════════════
+
+  `macrostep' is an Emacs minor mode for interactively stepping through
+  the expansion of macros in Emacs Lisp source code.  It lets you see
+  exactly what happens at each step of the expansion process by
+  pretty-printing the expanded forms inline in the source buffer, which
+  is temporarily read-only while macro expansions are visible.  You can
+  expand and collapse macro forms one step at a time, and evaluate or
+  instrument the expansions for debugging with Edebug as normal (but see
+  "Bugs and known limitations", below).  Single-stepping through the
+  expansion is particularly useful for debugging macros that expand into
+  another macro form.  These can be difficult to debug with Emacs'
+  built-in `macroexpand', which continues expansion until the top-level
+  form is no longer a macro call.
+
+  Both globally-visible macros as defined by `defmacro' and local macros
+  bound by `(cl-)macrolet' or another macro-defining form can be
+  expanded.  Within macro expansions, calls to macros and compiler
+  macros are fontified specially: macro forms using
+  `macrostep-macro-face', and functions with compiler macros using
+  `macrostep-compiler-macro-face'.  Uninterned symbols (gensyms) are
+  fontified based on which step in the expansion created them, to
+  distinguish them both from normal symbols and from other gensyms with
+  the same print name.
+
+  As of version 0.9, it is also possible to extend `macrostep' to work
+  with other languages with macro systems in addition to Emacs Lisp.  An
+  extension for Common Lisp (via SLIME) is in the works; contributions
+  for other languages are welcome.  See "Extending macrostep" below for
+  details.
+
+
+1.1 Key-bindings and usage
+──────────────────────────
+
+  The standard keybindings in `macrostep-mode' are the following:
+
+  e, =, RET 
+        expand the macro form following point one step
+  c, u, DEL 
+        collapse the form following point
+  q, C-c C-c
+        collapse all expanded forms and exit macrostep-mode
+  n, TAB    
+        jump to the next macro form in the expansion
+  p, M-TAB  
+        jump to the previous macro form in the expansion
+
+  It's not very useful to enable and disable macrostep-mode directly.
+  Instead, bind `macrostep-expand' to a key in `emacs-lisp-mode-map',
+  for example C-c e:
+
+  ┌────
+  │ (define-key emacs-lisp-mode-map (kbd "C-c e") 'macrostep-expand)
+  └────
+
+  You can then enter macrostep-mode and expand a macro form completely
+  by typing `C-c e e e ...' as many times as necessary.
+
+  Exit macrostep-mode by typing `q' or `C-c C-c', or by successively
+  typing `c' to collapse all surrounding expansions.
+
+
+1.2 Customization options
+─────────────────────────
+
+  Type `M-x customize-group RET macrostep RET' to customize options and
+  faces.
+
+  To display macro expansions in a separate window, instead of inline in
+  the source buffer, customize `macrostep-expand-in-separate-buffer' to
+  `t'.  The default is `nil'.  Whichever default behavior is selected,
+  the alternative behavior can be obtained temporarily by giving a
+  prefix argument to `macrostep-expand'.
+
+  To have `macrostep' ignore compiler macros, customize
+  `macrostep-expand-compiler-macros' to `nil'.  The default is `t'.
+
+  Customize the faces `macrostep-macro-face',
+  `macrostep-compiler-macro-face', and `macrostep-gensym-1' through
+  `macrostep-gensym-5' to alter the appearance of macro expansions.
+
+
+1.3 Locally-bound macros
+────────────────────────
+
+  As of version 0.9, `macrostep' can expand calls to a locally-bound
+  macro, whether defined by a surrounding `(cl-)macrolet' form, or by
+  another macro-defining macro.  In other words, it is possible to
+  expand the inner `local-macro' forms in both the following examples,
+  whether `local-macro' is defined by an enclosing `cl-macrolet' –
+
+  ┌────
+  │ (cl-macrolet ((local-macro (&rest args)
+  │ 		`(expansion of ,args)))
+  │   (local-macro (do-something)))
+  └────
+
+  – or by a macro which expands into `cl-macrolet', provided that its
+  definition of macro is evaluated prior to calling `macrostep-expand':
+
+  ┌────
+  │ (defmacro with-local-macro (&rest body)
+  │   `(cl-macrolet ((local-macro (&rest args)
+  │ 		   `(expansion of ,args)))
+  │      ,@body))
+  │ 
+  │ (with-local-macro
+  │     (local-macro (do something (else)))
+  └────
+
+  See the `with-js' macro in Emacs's `js.el' for a real example of the
+  latter kind of macro.
+
+  Expansion of locally-bound macros is implemented by instrumenting
+  Emacs Lisp's macro-expander to capture the environment at point.  A
+  similar trick is used to detect macro- and compiler-macro calls within
+  expanded text so that they can be fontified accurately.
+
+
+1.4 Expanding sub-forms
+───────────────────────
+
+  By moving point around in the macro expansion using
+  `macrostep-next-macro' and `macrostep-prev-macro' (bound to the `n'
+  and `p' keys), it is possible to expand other macro calls within the
+  expansion before expanding the outermost form.  This can sometimes be
+  useful, although it does not correspond to the real order of macro
+  expansion in Emacs Lisp, which proceeds by fully expanding the outer
+  form to a non-macro form before expanding sub-forms.
+
+  The main reason to expand sub-forms out of order is to help with
+  debugging macros which programmatically expand their arguments in
+  order to rewrite them.  Expanding the arguments of such a macro lets
+  you visualise what the macro definition would compute via
+  `macroexpand-all'.
+
+
+1.5 Extending macrostep for other languages
+───────────────────────────────────────────
+
+  Since version 0.9, it is possible to extend macrostep to work with
+  other languages besides Emacs Lisp.  In typical Emacs fashion, this is
+  implemented by setting buffer-local variables to different function
+  values.  Six buffer-local variables define the language-specific part
+  of the implementation:
+
+  • `macrostep-sexp-bounds-function'
+  • `macrostep-sexp-at-point-function'
+  • `macrostep-environment-at-point-function'
+  • `macrostep-expand-1-function'
+  • `macrostep-print-function'
+  • `macrostep-macro-form-p-function'
+
+  Typically, an implementation for another language would set these
+  variables in a major-mode hook.  See the docstrings of each variable
+  for details on how each one is called and what it should return.  At a
+  minimum, another language implementation needs to provide
+  `macrostep-sexp-at-point-function', `macrostep-expand-1-function', and
+  `macrostep-print-function'.  Lisp-like languages may be able to reuse
+  the default `macrostep-sexp-bounds-function' if they provide another
+  implementation of `macrostep-macro-form-p-function'.  Languages which
+  do not implement locally-defined macros can set
+  `macrostep-environment-at-point-function' to `ignore'.
+
+  Note that the core `macrostep' machinery only interprets the return
+  value of `macrostep-sexp-bounds-function', so implementations for
+  other languages can use any internal representations of code and
+  environments which is convenient.  Although the terminology is
+  Lisp-specific, there is no reason that implementations could not be
+  provided for non-Lisp languages with macro systems, provided there is
+  some way of identifying macro calls and calling the compiler /
+  preprocessor to obtain their expansions.
+
+
+1.6 Bugs and known limitations
+──────────────────────────────
+
+  You can evaluate and edebug macro-expanded forms and step through the
+  macro-expanded version, but the form that `eval-defun' and friends
+  read from the buffer won't have the uninterned symbols of the real
+  macro expansion.  This will probably work OK with CL-style gensyms,
+  but may cause problems with `make-symbol' symbols if they have the
+  same print name as another symbol in the expansion. It's possible that
+  using `print-circle' and `print-gensym' could get around this.
+
+  Please send other bug reports and feature requests to the author.
+
+
+1.7 Acknowledgements
+────────────────────
+
+  Thanks to:
+  • John Wiegley for fixing a bug with the face definitions under Emacs
+    24 & for plugging macrostep in his [EmacsConf presentation]!
+  • George Kettleborough for bug reports, and patches to highlight the
+    expanded region and properly handle backquotes.
+  • Nic Ferrier for suggesting support for local definitions within
+    macrolet forms
+  • Luís Oliveira for suggesting and implementing SLIME support
+
+  `macrostep' was originally inspired by J. V. Toups's 'Deep Emacs Lisp'
+  articles ([part 1], [part 2], [screencast]).
+
+
+[EmacsConf presentation] <http://youtu.be/RvPFZL6NJNQ>
+
+[part 1]
+<http://dorophone.blogspot.co.uk/2011/04/deep-emacs-part-1.html>
+
+[part 2]
+<http://dorophone.blogspot.co.uk/2011/04/deep-emacs-lisp-part-2.html>
+
+[screencast]
+<http://dorophone.blogspot.co.uk/2011/05/monadic-parser-combinators-in-elisp.html>
+
+
+1.8 Changelog
+─────────────
+
+  • v0.9, 2015-10-01:
+    • separate into Elisp-specific and generic components
+    • highlight and expand compiler macros
+    • improve local macro expansion and macro form identification by
+      instrumenting `macroexpand(-all)'
+  • v0.8, 2014-05-29: fix a bug with printing the first element of lists
+  • v0.7, 2014-05-11: expand locally-defined macros within
+    `(cl-)macrolet' forms
+  • v0.6, 2013-05-04: better handling of quote and backquote
+  • v0.5, 2013-04-16: highlight region, maintain cleaner buffer state
+  • v0.4, 2013-04-07: only enter macrostep-mode on successful
+    macro-expansion
+  • v0.3, 2012-10-30: print dotted lists correctly. autoload
+    definitions.
blob - /dev/null
blob + cdb7fe090808507c5ace00d7700447cec4e6e6c6 (mode 644)
--- /dev/null
+++ elpa/macrostep-0.9.2/README.org
@@ -0,0 +1,203 @@
+* macrostep: interactive macro-expander
+
+   =macrostep= is an Emacs minor mode for interactively stepping
+   through the expansion of macros in Emacs Lisp source code.  It lets
+   you see exactly what happens at each step of the expansion process
+   by pretty-printing the expanded forms inline in the source buffer,
+   which is temporarily read-only while macro expansions are visible.
+   You can expand and collapse macro forms one step at a time, and
+   evaluate or instrument the expansions for debugging with Edebug as
+   normal (but see "Bugs and known limitations", below).
+   Single-stepping through the expansion is particularly useful for
+   debugging macros that expand into another macro form.  These can be
+   difficult to debug with Emacs' built-in =macroexpand=, which
+   continues expansion until the top-level form is no longer a macro
+   call.
+
+   Both globally-visible macros as defined by =defmacro= and local
+   macros bound by =(cl-)macrolet= or another macro-defining form can
+   be expanded.  Within macro expansions, calls to macros and compiler
+   macros are fontified specially: macro forms using
+   =macrostep-macro-face=, and functions with compiler macros using
+   =macrostep-compiler-macro-face=.  Uninterned symbols (gensyms) are
+   fontified based on which step in the expansion created them, to
+   distinguish them both from normal symbols and from other gensyms
+   with the same print name.
+
+   As of version 0.9, it is also possible to extend =macrostep= to
+   work with other languages with macro systems in addition to Emacs
+   Lisp.  An extension for Common Lisp (via SLIME) is in the works;
+   contributions for other languages are welcome.  See "Extending
+   macrostep" below for details.
+
+** Key-bindings and usage
+   The standard keybindings in =macrostep-mode= are the following:
+ 
+    - e, =, RET  :: expand the macro form following point one step
+    - c, u, DEL  :: collapse the form following point
+    - q, C-c C-c :: collapse all expanded forms and exit macrostep-mode
+    - n, TAB     :: jump to the next macro form in the expansion
+    - p, M-TAB   :: jump to the previous macro form in the expansion
+
+    It's not very useful to enable and disable macrostep-mode
+    directly.  Instead, bind =macrostep-expand= to a key in
+    =emacs-lisp-mode-map=, for example C-c e:
+
+#+BEGIN_SRC emacs-lisp
+  (define-key emacs-lisp-mode-map (kbd "C-c e") 'macrostep-expand)
+#+END_SRC
+
+    You can then enter macrostep-mode and expand a macro form
+    completely by typing =C-c e e e ...= as many times as necessary.
+
+    Exit macrostep-mode by typing =q= or =C-c C-c=, or by successively
+    typing =c= to collapse all surrounding expansions.
+
+** Customization options
+   Type =M-x customize-group RET macrostep RET= to customize options
+   and faces.
+
+   To display macro expansions in a separate window, instead of inline
+   in the source buffer, customize
+   =macrostep-expand-in-separate-buffer= to =t=.  The default is
+   =nil=.  Whichever default behavior is selected, the alternative
+   behavior can be obtained temporarily by giving a prefix argument to
+   =macrostep-expand=.
+
+   To have =macrostep= ignore compiler macros, customize
+   =macrostep-expand-compiler-macros= to =nil=.  The default is =t=.
+
+   Customize the faces =macrostep-macro-face=,
+   =macrostep-compiler-macro-face=, and =macrostep-gensym-1= through
+   =macrostep-gensym-5= to alter the appearance of macro expansions.
+
+** Locally-bound macros
+   As of version 0.9, =macrostep= can expand calls to a locally-bound
+   macro, whether defined by a surrounding =(cl-)macrolet= form, or by
+   another macro-defining macro.  In other words, it is possible to
+   expand the inner =local-macro= forms in both the following
+   examples, whether =local-macro= is defined by an enclosing
+   =cl-macrolet= --
+   
+   #+BEGIN_SRC emacs-lisp
+     (cl-macrolet ((local-macro (&rest args)
+                     `(expansion of ,args)))
+       (local-macro (do-something)))
+   #+END_SRC
+
+   -- or by a macro which expands into =cl-macrolet=, provided that
+   its definition of macro is evaluated prior to calling
+   =macrostep-expand=:
+
+   #+BEGIN_SRC emacs-lisp
+     (defmacro with-local-macro (&rest body)
+       `(cl-macrolet ((local-macro (&rest args)
+                        `(expansion of ,args)))
+          ,@body))
+
+     (with-local-macro
+         (local-macro (do something (else)))
+   #+END_SRC
+
+   See the =with-js= macro in Emacs's =js.el= for a real example of
+   the latter kind of macro.
+
+   Expansion of locally-bound macros is implemented by instrumenting
+   Emacs Lisp's macro-expander to capture the environment at point.  A
+   similar trick is used to detect macro- and compiler-macro calls
+   within expanded text so that they can be fontified accurately.
+
+** Expanding sub-forms
+   By moving point around in the macro expansion using
+   =macrostep-next-macro= and =macrostep-prev-macro= (bound to the =n=
+   and =p= keys), it is possible to expand other macro calls within
+   the expansion before expanding the outermost form.  This can
+   sometimes be useful, although it does not correspond to the real
+   order of macro expansion in Emacs Lisp, which proceeds by fully
+   expanding the outer form to a non-macro form before expanding
+   sub-forms.
+
+   The main reason to expand sub-forms out of order is to help with
+   debugging macros which programmatically expand their arguments in
+   order to rewrite them.  Expanding the arguments of such a macro
+   lets you visualise what the macro definition would compute via
+   =macroexpand-all=.
+
+** Extending macrostep for other languages
+   Since version 0.9, it is possible to extend macrostep to work with
+   other languages besides Emacs Lisp.  In typical Emacs fashion, this
+   is implemented by setting buffer-local variables to different
+   function values.  Six buffer-local variables define the
+   language-specific part of the implementation:
+
+   - =macrostep-sexp-bounds-function=
+   - =macrostep-sexp-at-point-function=
+   - =macrostep-environment-at-point-function=
+   - =macrostep-expand-1-function=
+   - =macrostep-print-function=
+   - =macrostep-macro-form-p-function=
+
+   Typically, an implementation for another language would set these
+   variables in a major-mode hook.  See the docstrings of each
+   variable for details on how each one is called and what it should
+   return.  At a minimum, another language implementation needs to
+   provide =macrostep-sexp-at-point-function=,
+   =macrostep-expand-1-function=, and =macrostep-print-function=.
+   Lisp-like languages may be able to reuse the default
+   =macrostep-sexp-bounds-function= if they provide another
+   implementation of =macrostep-macro-form-p-function=.  Languages
+   which do not implement locally-defined macros can set
+   =macrostep-environment-at-point-function= to =ignore=.
+   
+   Note that the core =macrostep= machinery only interprets the return
+   value of =macrostep-sexp-bounds-function=, so implementations for
+   other languages can use any internal representations of code and
+   environments which is convenient.  Although the terminology is
+   Lisp-specific, there is no reason that implementations could not be
+   provided for non-Lisp languages with macro systems, provided there
+   is some way of identifying macro calls and calling the compiler /
+   preprocessor to obtain their expansions.
+
+** Bugs and known limitations
+   You can evaluate and edebug macro-expanded forms and step through
+   the macro-expanded version, but the form that =eval-defun= and
+   friends read from the buffer won't have the uninterned symbols of
+   the real macro expansion.  This will probably work OK with CL-style
+   gensyms, but may cause problems with =make-symbol= symbols if they
+   have the same print name as another symbol in the expansion. It's
+   possible that using =print-circle= and =print-gensym= could get
+   around this.
+
+   Please send other bug reports and feature requests to the author.
+
+** Acknowledgements
+   Thanks to:
+   - John Wiegley for fixing a bug with the face definitions under
+     Emacs 24 & for plugging macrostep in his [[http://youtu.be/RvPFZL6NJNQ][EmacsConf presentation]]!
+   - George Kettleborough for bug reports, and patches to highlight
+     the expanded region and properly handle backquotes.
+   - Nic Ferrier for suggesting support for local definitions within
+     macrolet forms
+   - Luís Oliveira for suggesting and implementing SLIME support
+
+   =macrostep= was originally inspired by J. V. Toups's 'Deep Emacs
+   Lisp' articles ([[http://dorophone.blogspot.co.uk/2011/04/deep-emacs-part-1.html][part 1]], [[http://dorophone.blogspot.co.uk/2011/04/deep-emacs-lisp-part-2.html][part 2]], [[http://dorophone.blogspot.co.uk/2011/05/monadic-parser-combinators-in-elisp.html][screencast]]).
+
+** Changelog
+   - v0.9, 2015-10-01:
+     - separate into Elisp-specific and generic components
+     - highlight and expand compiler macros
+     - improve local macro expansion and macro form identification by
+       instrumenting =macroexpand(-all)=
+   - v0.8, 2014-05-29: fix a bug with printing the first element of
+     lists
+   - v0.7, 2014-05-11: expand locally-defined macros within
+     =(cl-)macrolet= forms
+   - v0.6, 2013-05-04: better handling of quote and backquote
+   - v0.5, 2013-04-16: highlight region, maintain cleaner buffer state
+   - v0.4, 2013-04-07: only enter macrostep-mode on successful
+     macro-expansion
+   - v0.3, 2012-10-30: print dotted lists correctly. autoload
+     definitions.
+
+#+OPTIONS: author:nil email:nil toc:nil timestamp:nil
blob - /dev/null
blob + eeda2c28537b1f803fa9ad1d51cae239d363243b (mode 644)
--- /dev/null
+++ elpa/macrostep-0.9.2/macrostep-autoloads.el
@@ -0,0 +1,73 @@
+;;; macrostep-autoloads.el --- automatically extracted autoloads (do not edit)   -*- lexical-binding: t -*-
+;; Generated by the `loaddefs-generate' function.
+
+;; This file is part of GNU Emacs.
+
+;;; Code:
+
+(add-to-list 'load-path (or (and load-file-name (file-name-directory load-file-name)) (car load-path)))
+
+
+
+;;; Generated autoloads from macrostep.el
+
+(autoload 'macrostep-mode "macrostep" "\
+Minor mode for inline expansion of macros in Emacs Lisp source buffers.
+
+\\<macrostep-mode-map>Progressively expand macro forms with \\[macrostep-expand], collapse them with \\[macrostep-collapse],
+and move back and forth with \\[macrostep-next-macro] and \\[macrostep-prev-macro].  Use \\[macrostep-collapse-all] or collapse all
+visible expansions to quit and return to normal editing.
+
+\\{macrostep-mode-map}
+
+This is a minor mode.  If called interactively, toggle the
+`Macrostep mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'.  Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `macrostep-mode'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+(fn &optional ARG)" t)
+(autoload 'macrostep-expand "macrostep" "\
+Expand the macro form following point by one step.
+
+Enters `macrostep-mode' if it is not already active, making the
+buffer temporarily read-only.  If `macrostep-mode' is active and the
+form following point is not a macro form, search forward in the
+buffer and expand the next macro form found, if any.
+
+With a prefix argument, the expansion is displayed in a separate
+buffer instead of inline in the current buffer.  Setting
+`macrostep-expand-in-separate-buffer' to non-nil swaps these two
+behaviors.
+
+(fn &optional TOGGLE-SEPARATE-BUFFER)" t)
+(register-definition-prefixes "macrostep" '("macrostep-"))
+
+
+;;; Generated autoloads from macrostep-c.el
+
+(autoload 'macrostep-c-mode-hook "macrostep-c")
+(add-hook 'c-mode-hook #'macrostep-c-mode-hook)
+(register-definition-prefixes "macrostep-c" '("macrostep-c-"))
+
+;;; End of scraped data
+
+(provide 'macrostep-autoloads)
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; no-native-compile: t
+;; coding: utf-8-emacs-unix
+;; End:
+
+;;; macrostep-autoloads.el ends here
blob - /dev/null
blob + 226ecce2ac19e32f574682e77bdd3dc97fed4c7d (mode 644)
--- /dev/null
+++ elpa/macrostep-0.9.2/macrostep-c.el
@@ -0,0 +1,183 @@
+;;; macrostep-c.el --- macrostep interface to C preprocessor  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015 Jon Oddie
+
+;; Author: Jon Oddie <j.j.oddie@gmail.com>
+;; Url: https://github.com/emacsorphanage/macrostep
+;; Keywords: c, languages, macro, debugging
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; This file is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published
+;; by the Free Software Foundation, either version 3 of the License,
+;; or (at your option) any later version.
+;;
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this file.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; A thin wrapper around Emacs's built-in `cmacexp' library to provide
+;; basic support for expanding C macros using the `macrostep' user
+;; interface.  To use, position point on a macro use in a C buffer and
+;; type `M-x macrostep-expand'.  The variables `c-macro-preprocessor'
+;; and especially `c-macro-cppflags' may need to be set correctly for
+;; accurate expansion.
+
+;; This is fairly basic compared to the Emacs Lisp `macrostep'.  In
+;; particular, there is no step-by-step expansion, since C macros are
+;; expanded in a single "cpp" pass, and no pretty-printing.
+
+;; To hide the buffer containing "cpp" warnings (not recommended), you
+;; could do something like:
+;;
+;; (push `(,(regexp-quote macrostep-c-warning-buffer)
+;;          (display-buffer-no-window))
+;;       display-buffer-alist)
+
+;;; Code:
+
+(require 'macrostep)
+(require 'cmacexp)
+(require 'cl-lib)
+
+(require 'subr-x nil t)
+(defalias 'macrostep-c-string-trim
+  (if (fboundp 'string-trim)
+      #'string-trim
+    (lambda (string)
+      (when (string-match "\\`[ \t\n\r]+" string)
+	(setq string (replace-match "" t t string)))
+      (when (string-match "[ \t\n\r]+\\'" string)
+	(setq string (replace-match "" t t string)))
+      string)))
+
+(put 'macrostep-c-non-macro 'error-conditions
+     '(macrostep-c-non-macro error))
+(put 'macrostep-c-non-macro 'error-message
+     "Text around point is not a macro call.")
+
+(put 'macrostep-c-expansion-failed 'error-conditions
+     '(macrostep-c-expansion-failed error))
+(put 'macrostep-c-expansion-failed 'error-message
+     "Macro-expansion failed.")
+
+(defvar macrostep-c-warning-buffer "*Macroexpansion Warnings*")
+
+;;;###autoload
+(defun macrostep-c-mode-hook ()
+  (setq macrostep-sexp-bounds-function
+        #'macrostep-c-sexp-bounds)
+  (setq macrostep-sexp-at-point-function
+        #'macrostep-c-sexp-at-point)
+  (setq macrostep-environment-at-point-function
+        #'ignore)
+  (setq macrostep-expand-1-function
+        #'macrostep-c-expand-1)
+  (setq macrostep-print-function
+        #'macrostep-c-print-function)
+  (add-hook 'macrostep-mode-off-hook
+            #'macrostep-c-mode-off nil t))
+
+(defun macrostep-c-mode-off (&rest _ignore)
+  (when (derived-mode-p 'c-mode)
+    (let ((warning-window
+           (get-buffer-window macrostep-c-warning-buffer)))
+      (when warning-window
+        (quit-window nil warning-window)))))
+
+;;;###autoload
+(add-hook 'c-mode-hook #'macrostep-c-mode-hook)
+
+(defun macrostep-c-sexp-bounds ()
+  (save-excursion
+    (cl-loop
+     (let ((region (macrostep-c-sexp-bounds-1)))
+       (cond
+         ((null region)
+          (signal 'macrostep-c-non-macro nil))
+         ((macrostep-c-expandable-p region)
+          (cl-return region))
+         (t
+          (condition-case nil
+              (progn
+                (backward-up-list)
+                (skip-syntax-backward "-"))
+            (scan-error
+             (signal 'macrostep-c-non-macro nil)))))))))
+
+(defun macrostep-c-sexp-bounds-1 ()
+  (let ((region (bounds-of-thing-at-point 'symbol)))
+    (when region
+      (cl-destructuring-bind (symbol-start . symbol-end) region
+        (save-excursion
+          (goto-char symbol-end)
+          (if (looking-at "[[:space:]]*(")
+              (cons symbol-start (scan-sexps symbol-end 1))
+              region))))))
+
+(defun macrostep-c-expandable-p (region)
+  (cl-destructuring-bind (start . end) region
+    (condition-case nil
+        (cl-destructuring-bind (expansion _warnings)
+            (macrostep-c-expand-region start end)
+          (and (cl-plusp (length expansion))
+               (not (string= expansion (buffer-substring start end)))))
+      (macrostep-c-expansion-failed nil))))
+
+(defun macrostep-c-sexp-at-point (start end)
+  (cons start end))
+
+(defun macrostep-c-expand-1 (region _ignore)
+  (cl-destructuring-bind (start . end) region
+    (cl-destructuring-bind (expansion warnings)
+        (macrostep-c-expand-region start end)
+      (when (cl-plusp (length warnings))
+        (with-current-buffer
+            (get-buffer-create macrostep-c-warning-buffer)
+          (let ((inhibit-read-only t))
+            (erase-buffer)
+            (insert warnings)
+            (goto-char (point-min)))
+          (special-mode)
+          (display-buffer (current-buffer)
+                          '(display-buffer-pop-up-window
+                            (inhibit-same-window . t)
+                            (allow-no-window . t)))))
+      expansion)))
+
+(defun macrostep-c-expand-region (start end)
+  (let ((expansion
+         (condition-case nil
+             (c-macro-expansion start end
+                                (concat c-macro-preprocessor " "
+                                        c-macro-cppflags))
+           (search-failed
+            (signal 'macrostep-c-expansion-failed nil)))))
+    (with-temp-buffer
+      (save-excursion
+        (insert expansion))
+      (when (looking-at (regexp-quote "/*"))
+        (search-forward "*/"))
+      (let ((warnings (buffer-substring (point-min) (point)))
+            (expansion (buffer-substring (point) (point-max))))
+        (mapcar #'macrostep-c-string-trim (list expansion warnings))))))
+
+(defun macrostep-c-print-function (expansion &rest _ignore)
+  (with-temp-buffer
+    (insert expansion)
+    (let ((exit-code
+           (shell-command-on-region (point-min) (point-max) "indent" nil t)))
+      (when (zerop exit-code)
+        (setq expansion (macrostep-c-string-trim (buffer-string))))))
+  (insert expansion))
+
+(provide 'macrostep-c)
+
+;;; macrostep-c.el ends here
blob - /dev/null
blob + 22b0071fd1b14f0e6f7d71fee44850763327d77a (mode 644)
--- /dev/null
+++ elpa/macrostep-0.9.2/macrostep-pkg.el
@@ -0,0 +1,2 @@
+;; Generated package description from macrostep.el  -*- no-byte-compile: t -*-
+(define-package "macrostep" "0.9.2" "Interactive macro expander" '((cl-lib "0.5")) :commit "633586421e7fc14072cc1ca1655c1103b81a9093" :authors '(("Jon Oddie" . "j.j.oddie@gmail.com")) :maintainer '("Jon Oddie" . "j.j.oddie@gmail.com") :keywords '("lisp" "languages" "macro" "debugging") :url "https://github.com/emacsorphanage/macrostep")
blob - /dev/null
blob + 4a00a603f7a0cce838a1a6ce20d622d8854c90e4 (mode 644)
--- /dev/null
+++ elpa/macrostep-0.9.2/macrostep.el
@@ -0,0 +1,1125 @@
+;;; macrostep.el --- Interactive macro expander  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2012-2015 Jon Oddie
+;; Copyright (C) 2020-2023 Free Software Foundation, Inc.
+
+;; Author: Jon Oddie <j.j.oddie@gmail.com>
+;; Url: https://github.com/emacsorphanage/macrostep
+;; Keywords: lisp, languages, macro, debugging
+
+;; Package-Version: 0.9.2
+;; Package-Requires: ((cl-lib "0.5"))
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; This file is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published
+;; by the Free Software Foundation, either version 3 of the License,
+;; or (at your option) any later version.
+;;
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this file.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; `macrostep' is an Emacs minor mode for interactively stepping through
+;; the expansion of macros in Emacs Lisp source code.  It lets you see
+;; exactly what happens at each step of the expansion process by
+;; pretty-printing the expanded forms inline in the source buffer, which is
+;; temporarily read-only while macro expansions are visible.  You can
+;; expand and collapse macro forms one step at a time, and evaluate or
+;; instrument the expansions for debugging with Edebug as normal (but see
+;; "Bugs and known limitations", below).  Single-stepping through the
+;; expansion is particularly useful for debugging macros that expand into
+;; another macro form.  These can be difficult to debug with Emacs'
+;; built-in `macroexpand', which continues expansion until the top-level
+;; form is no longer a macro call.
+
+;; Both globally-visible macros as defined by `defmacro' and local macros
+;; bound by `(cl-)macrolet' or another macro-defining form can be expanded.
+;; Within macro expansions, calls to macros and compiler macros are
+;; fontified specially: macro forms using `macrostep-macro-face', and
+;; functions with compiler macros using `macrostep-compiler-macro-face'.
+;; Uninterned symbols (gensyms) are fontified based on which step in the
+;; expansion created them, to distinguish them both from normal symbols and
+;; from other gensyms with the same print name.
+
+;; As of version 0.9, it is also possible to extend `macrostep' to work
+;; with other languages with macro systems in addition to Emacs Lisp.  An
+;; extension for Common Lisp (via SLIME) is in the works; contributions for
+;; other languages are welcome.  See "Extending macrostep" below for
+;; details.
+
+
+;; 1 Key-bindings and usage
+;; ========================
+
+;;   The standard keybindings in `macrostep-mode' are the following:
+
+;;   e, =, RET : expand the macro form following point one step
+;;   c, u, DEL : collapse the form following point
+;;   q, C-c C-c: collapse all expanded forms and exit macrostep-mode
+;;   n, TAB    : jump to the next macro form in the expansion
+;;   p, M-TAB  : jump to the previous macro form in the expansion
+
+;;   It's not very useful to enable and disable macrostep-mode directly.
+;;   Instead, bind `macrostep-expand' to a key in `emacs-lisp-mode-map',
+;;   for example C-c e:
+
+;;   ,----
+;;   | (define-key emacs-lisp-mode-map (kbd "C-c e") 'macrostep-expand)
+;;   `----
+
+;;   You can then enter macrostep-mode and expand a macro form completely
+;;   by typing `C-c e e e ...' as many times as necessary.
+
+;;   Exit macrostep-mode by typing `q' or `C-c C-c', or by successively
+;;   typing `c' to collapse all surrounding expansions.
+
+
+;; 2 Customization options
+;; =======================
+
+;;   Type `M-x customize-group RET macrostep RET' to customize options and
+;;   faces.
+
+;;   To display macro expansions in a separate window, instead of inline in
+;;   the source buffer, customize `macrostep-expand-in-separate-buffer' to
+;;   `t'.  The default is `nil'.  Whichever default behavior is selected,
+;;   the alternative behavior can be obtained temporarily by giving a
+;;   prefix argument to `macrostep-expand'.
+
+;;   To have `macrostep' ignore compiler macros, customize
+;;   `macrostep-expand-compiler-macros' to `nil'.  The default is `t'.
+
+;;   Customize the faces `macrostep-macro-face',
+;;   `macrostep-compiler-macro-face', and `macrostep-gensym-1' through
+;;   `macrostep-gensym-5' to alter the appearance of macro expansions.
+
+
+;; 3 Locally-bound macros
+;; ======================
+
+;;   As of version 0.9, `macrostep' can expand calls to a locally-bound
+;;   macro, whether defined by a surrounding `(cl-)macrolet' form, or by
+;;   another macro-defining macro.  In other words, it is possible to
+;;   expand the inner `local-macro' forms in both the following examples,
+;;   whether `local-macro' is defined by an enclosing `cl-macrolet' --
+
+;;   ,----
+;;   | (cl-macrolet ((local-macro (&rest args)
+;;   |                 `(expansion of ,args)))
+;;   |   (local-macro (do-something)))
+;;   `----
+
+;;   -- or by a macro which expands into `cl-macrolet', provided that its
+;;   definition of macro is evaluated prior to calling `macrostep-expand':
+
+;;   ,----
+;;   | (defmacro with-local-macro (&rest body)
+;;   |   `(cl-macrolet ((local-macro (&rest args)
+;;   |                    `(expansion of ,args)))
+;;   |      ,@body))
+;;   |
+;;   | (with-local-macro
+;;   |     (local-macro (do something (else)))
+;;   `----
+
+;;   See the `with-js' macro in Emacs's `js.el' for a real example of the
+;;   latter kind of macro.
+
+;;   Expansion of locally-bound macros is implemented by instrumenting
+;;   Emacs Lisp's macro-expander to capture the environment at point.  A
+;;   similar trick is used to detect macro- and compiler-macro calls within
+;;   expanded text so that they can be fontified accurately.
+
+
+;; 4 Expanding sub-forms
+;; =====================
+
+;;   By moving point around in the macro expansion using
+;;   `macrostep-next-macro' and `macrostep-prev-macro' (bound to the `n'
+;;   and `p' keys), it is possible to expand other macro calls within the
+;;   expansion before expanding the outermost form.  This can sometimes be
+;;   useful, although it does not correspond to the real order of macro
+;;   expansion in Emacs Lisp, which proceeds by fully expanding the outer
+;;   form to a non-macro form before expanding sub-forms.
+
+;;   The main reason to expand sub-forms out of order is to help with
+;;   debugging macros which programmatically expand their arguments in
+;;   order to rewrite them.  Expanding the arguments of such a macro lets
+;;   you visualise what the macro definition would compute via
+;;   `macroexpand-all'.
+
+
+;; 5 Extending macrostep for other languages
+;; =========================================
+
+;;   Since version 0.9, it is possible to extend macrostep to work with
+;;   other languages besides Emacs Lisp.  In typical Emacs fashion, this is
+;;   implemented by setting buffer-local variables to different function
+;;   values.  Six buffer-local variables define the language-specific part
+;;   of the implementation:
+
+;;   - `macrostep-sexp-bounds-function'
+;;   - `macrostep-sexp-at-point-function'
+;;   - `macrostep-environment-at-point-function'
+;;   - `macrostep-expand-1-function'
+;;   - `macrostep-print-function'
+;;   - `macrostep-macro-form-p-function'
+
+;;   Typically, an implementation for another language would set these
+;;   variables in a major-mode hook.  See the docstrings of each variable
+;;   for details on how each one is called and what it should return.  At a
+;;   minimum, another language implementation needs to provide
+;;   `macrostep-sexp-at-point-function', `macrostep-expand-1-function', and
+;;   `macrostep-print-function'.  Lisp-like languages may be able to reuse
+;;   the default `macrostep-sexp-bounds-function' if they provide another
+;;   implementation of `macrostep-macro-form-p-function'.  Languages which
+;;   do not implement locally-defined macros can set
+;;   `macrostep-environment-at-point-function' to `ignore'.
+
+;;   Note that the core `macrostep' machinery only interprets the return
+;;   value of `macrostep-sexp-bounds-function', so implementations for
+;;   other languages can use any internal representations of code and
+;;   environments which is convenient.  Although the terminology is
+;;   Lisp-specific, there is no reason that implementations could not be
+;;   provided for non-Lisp languages with macro systems, provided there is
+;;   some way of identifying macro calls and calling the compiler /
+;;   preprocessor to obtain their expansions.
+
+
+;; 6 Bugs and known limitations
+;; ============================
+
+;;   You can evaluate and edebug macro-expanded forms and step through the
+;;   macro-expanded version, but the form that `eval-defun' and friends
+;;   read from the buffer won't have the uninterned symbols of the real
+;;   macro expansion.  This will probably work OK with CL-style gensyms,
+;;   but may cause problems with `make-symbol' symbols if they have the
+;;   same print name as another symbol in the expansion.  It's possible that
+;;   using `print-circle' and `print-gensym' could get around this.
+
+;;   Please send other bug reports and feature requests to the author.
+
+
+;; 7 Acknowledgements
+;; ==================
+
+;;   Thanks to:
+;;   - John Wiegley for fixing a bug with the face definitions under Emacs
+;;     24 & for plugging macrostep in his [EmacsConf presentation]!
+;;   - George Kettleborough for bug reports, and patches to highlight the
+;;     expanded region and properly handle backquotes.
+;;   - Nic Ferrier for suggesting support for local definitions within
+;;     macrolet forms
+;;   - Luís Oliveira for suggesting and implementing SLIME support
+
+;;   `macrostep' was originally inspired by J. V. Toups's 'Deep Emacs Lisp'
+;;   articles ([part 1], [part 2], [screencast]).
+
+;;   [EmacsConf presentation] http://youtu.be/RvPFZL6NJNQ
+
+;;   [part 1]
+;;   http://dorophone.blogspot.co.uk/2011/04/deep-emacs-part-1.html
+
+;;   [part 2]
+;;   http://dorophone.blogspot.co.uk/2011/04/deep-emacs-lisp-part-2.html
+
+;;   [screencast]
+;;   http://dorophone.blogspot.co.uk/2011/05/monadic-parser-combinators-in-elisp.html
+
+
+;; 8 Changelog
+;; ===========
+
+;;   - v0.9.2, 2023-05-12:
+;;     - name the keymap macrostep-mode-map, fixing a regression in v0.9.1
+;;   - v0.9.1, 2023-03-12:
+;;     - bug fixes, cleanup and modernization
+;;   - v0.9, 2015-10-01:
+;;     - separate into Elisp-specific and generic components
+;;     - highlight and expand compiler macros
+;;     - improve local macro expansion and macro form identification by
+;;       instrumenting `macroexpand(-all)'
+;;   - v0.8, 2014-05-29: fix a bug with printing the first element of lists
+;;   - v0.7, 2014-05-11: expand locally-defined macros within
+;;     `(cl-)macrolet' forms
+;;   - v0.6, 2013-05-04: better handling of quote and backquote
+;;   - v0.5, 2013-04-16: highlight region, maintain cleaner buffer state
+;;   - v0.4, 2013-04-07: only enter macrostep-mode on successful
+;;     macro-expansion
+;;   - v0.3, 2012-10-30: print dotted lists correctly.  autoload
+;;     definitions.
+
+;;; Code:
+
+(require 'pp)
+(require 'ring)
+(require 'cl-lib)
+
+
+;;; Constants and dynamically bound variables
+(defvar macrostep-overlays nil
+  "List of all macro stepper overlays in the current buffer.")
+(make-variable-buffer-local 'macrostep-overlays)
+
+(defvar macrostep-gensym-depth nil
+  "Number of macro expansion levels that have introduced gensyms so far.")
+(make-variable-buffer-local 'macrostep-gensym-depth)
+
+(defvar macrostep-gensyms-this-level nil
+  "t if gensyms have been encountered during current level of macro expansion.")
+(make-variable-buffer-local 'macrostep-gensyms-this-level)
+
+(defvar macrostep-saved-undo-list nil
+  "Saved value of `buffer-undo-list' upon entering macrostep mode.")
+(make-variable-buffer-local 'macrostep-saved-undo-list)
+
+(defvar macrostep-saved-read-only nil
+  "Saved value of `buffer-read-only' upon entering macrostep mode.")
+(make-variable-buffer-local 'macrostep-saved-read-only)
+
+(defvar macrostep-expansion-buffer nil
+  "Non-nil if the current buffer is a macro-expansion buffer.")
+(make-variable-buffer-local 'macrostep-expansion-buffer)
+
+(defvar macrostep-outer-environment nil
+  "Outermost macro-expansion environment to use in macro-expansion buffers.
+
+This variable is used to save information about any enclosing
+`cl-macrolet' context when a macro form is expanded in a separate
+buffer.")
+(make-variable-buffer-local 'macrostep-outer-environment)
+
+;;; Customization options and faces
+(defgroup macrostep nil
+  "Interactive macro stepper for Emacs Lisp."
+  :group 'lisp
+  :link '(emacs-commentary-link :tag "commentary" "macrostep.el")
+  :link '(emacs-library-link :tag "lisp file" "macrostep.el")
+  :link '(url-link :tag "web page" "https://github.com/joddie/macrostep"))
+
+(defface macrostep-gensym-1
+  '((((min-colors 16581375)) :foreground "#8080c0" :box t :bold t)
+    (((min-colors 8)) :background "cyan")
+    (t :inverse-video t))
+  "Face for gensyms created in the first level of macro expansion.")
+
+(defface macrostep-gensym-2
+  '((((min-colors 16581375)) :foreground "#8fbc8f" :box t :bold t)
+    (((min-colors 8)) :background "#00cd00")
+    (t :inverse-video t))
+  "Face for gensyms created in the second level of macro expansion.")
+
+(defface macrostep-gensym-3
+  '((((min-colors 16581375)) :foreground "#daa520" :box t :bold t)
+    (((min-colors 8)) :background "yellow")
+    (t :inverse-video t))
+  "Face for gensyms created in the third level of macro expansion.")
+
+(defface macrostep-gensym-4
+  '((((min-colors 16581375)) :foreground "#cd5c5c" :box t :bold t)
+    (((min-colors 8)) :background "red")
+    (t :inverse-video t))
+  "Face for gensyms created in the fourth level of macro expansion.")
+
+(defface macrostep-gensym-5
+  '((((min-colors 16581375)) :foreground "#da70d6" :box t :bold t)
+    (((min-colors 8)) :background "magenta")
+    (t :inverse-video t))
+  "Face for gensyms created in the fifth level of macro expansion.")
+
+(defface macrostep-expansion-highlight-face
+  `((((min-colors 16581375) (background light))
+     ,@(and (>= emacs-major-version 27) '(:extend t))
+     :background "#eee8d5")
+    (((min-colors 16581375) (background dark))
+     ,@(and (>= emacs-major-version 27) '(:extend t))
+     :background "#222222"))
+  "Face for macro-expansion highlight.")
+
+(defface macrostep-macro-face
+  '((t :underline t))
+  "Face for macros in macro-expanded code.")
+
+(defface macrostep-compiler-macro-face
+  '((t :slant italic))
+  "Face for compiler macros in macro-expanded code.")
+
+(defcustom macrostep-expand-in-separate-buffer nil
+  "When non-nil, show expansions in a separate buffer instead of inline."
+  :type 'boolean)
+
+(defcustom macrostep-expand-compiler-macros t
+  "When non-nil, also expand compiler macros."
+  :type 'boolean)
+
+;; Need the following for making the ring of faces
+(defun macrostep-make-ring (&rest items)
+  "Make a ring containing all of ITEMS with no empty slots."
+  (let ((ring (make-ring (length items))))
+    (mapc (lambda (item) (ring-insert ring item)) (reverse items))
+    ring))
+
+(defvar macrostep-gensym-faces
+  (macrostep-make-ring
+   'macrostep-gensym-1 'macrostep-gensym-2 'macrostep-gensym-3
+   'macrostep-gensym-4 'macrostep-gensym-5)
+  "Ring of all macrostepper faces for fontifying gensyms.")
+
+;; Other modes can enable macrostep by redefining these functions to
+;; language-specific versions.
+(defvar macrostep-sexp-bounds-function
+  #'macrostep-sexp-bounds
+  "Function to return the bounds of the macro form nearest point.
+
+It will be called with no arguments and should return a cons of
+buffer positions, (START . END).  It should use `save-excursion'
+to avoid changing the position of point.
+
+The default value, `macrostep-sexp-bounds', implements this for
+Emacs Lisp, and may be suitable for other Lisp-like languages.")
+(make-variable-buffer-local 'macrostep-sexp-bounds-function)
+
+(defvar macrostep-sexp-at-point-function
+  #'macrostep-sexp-at-point
+  "Function to return the macro form at point for expansion.
+
+It will be called with two arguments, the values of START and END
+returned by `macrostep-sexp-bounds-function', and with point
+positioned at START.  It should return a value suitable for
+passing as the first argument to `macrostep-expand-1-function'.
+
+The default value, `macrostep-sexp-at-point', implements this for
+Emacs Lisp, and may be suitable for other Lisp-like languages.")
+(make-variable-buffer-local 'macrostep-sexp-at-point-function)
+
+(defvar macrostep-environment-at-point-function
+  #'macrostep-environment-at-point
+  "Function to return the local macro-expansion environment at point.
+
+It will be called with no arguments, and should return a value
+suitable for passing as the second argument to
+`macrostep-expand-1-function'.
+
+The default value, `macrostep-environment-at-point', is specific
+to Emacs Lisp.  For languages which do not implement local
+macro-expansion environments, this should be set to `ignore'
+or `(lambda () nil)'.")
+(make-variable-buffer-local 'macrostep-environment-at-point-function)
+
+(defvar macrostep-expand-1-function
+  #'macrostep-expand-1
+  "Function to perform one step of macro-expansion.
+
+It will be called with two arguments, FORM and ENVIRONMENT, the
+return values of `macrostep-sexp-at-point-function' and
+`macrostep-environment-at-point-function' respectively.  It
+should return the result of expanding FORM by one step as a value
+which is suitable for passing as the argument to
+`macrostep-print-function'.
+
+The default value, `macrostep-expand-1', is specific to Emacs Lisp.")
+(make-variable-buffer-local 'macrostep-expand-1-function)
+
+(defvar macrostep-print-function
+  #'macrostep-pp
+  "Function to pretty-print macro expansions.
+
+It will be called with two arguments, FORM and ENVIRONMENT, the
+return values of `macrostep-sexp-at-point-function' and
+`macrostep-environment-at-point-function' respectively.  It
+should insert a pretty-printed representation at point in the
+current buffer, leaving point just after the inserted
+representation, without altering any other text in the current
+buffer.
+
+The default value, `macrostep-pp', is specific to Emacs Lisp.")
+(make-variable-buffer-local 'macrostep-print-function)
+
+(defvar macrostep-macro-form-p-function
+  #'macrostep-macro-form-p
+  "Function to check whether a form is a macro call.
+
+It will be called with two arguments, FORM and ENVIRONMENT -- the
+return values of `macrostep-sexp-at-point-function' and
+`macrostep-environment-at-point-function' respectively -- and
+should return non-nil if FORM would undergo macro-expansion in
+ENVIRONMENT.
+
+This is called only from `macrostep-sexp-bounds', so it need not
+be provided if a different value is used for
+`macrostep-sexp-bounds-function'.
+
+The default value, `macrostep-macro-form-p', is specific to Emacs Lisp.")
+(make-variable-buffer-local 'macrostep-macro-form-p-function)
+
+
+;;; Define keymap and minor mode
+(define-obsolete-variable-alias 'macrostep-mode-keymap 'macrostep-mode-map "2023")
+(define-obsolete-variable-alias 'macrostep-keymap 'macrostep-mode-map "2022")
+(defvar macrostep-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "RET") #'macrostep-expand)
+    (define-key map "=" #'macrostep-expand)
+    (define-key map "e" #'macrostep-expand)
+
+    (define-key map (kbd "DEL") #'macrostep-collapse)
+    (define-key map "u" #'macrostep-collapse)
+    (define-key map "c" #'macrostep-collapse)
+
+    (define-key map (kbd "TAB") #'macrostep-next-macro)
+    (define-key map "n" #'macrostep-next-macro)
+    (define-key map (kbd "M-TAB") #'macrostep-prev-macro)
+    (define-key map "p" #'macrostep-prev-macro)
+
+    (define-key map "q" #'macrostep-collapse-all)
+    (define-key map (kbd "C-c C-c") #'macrostep-collapse-all)
+    map)
+  "Keymap for `macrostep-mode'.")
+
+;;;###autoload
+(define-minor-mode macrostep-mode
+  "Minor mode for inline expansion of macros in Emacs Lisp source buffers.
+
+\\<macrostep-mode-map>Progressively expand macro forms with \
+\\[macrostep-expand], collapse them with \\[macrostep-collapse],
+and move back and forth with \\[macrostep-next-macro] and \
+\\[macrostep-prev-macro].  Use \\[macrostep-collapse-all] or collapse all
+visible expansions to quit and return to normal editing.
+
+\\{macrostep-mode-map}"
+  :lighter " Macro-Stepper"
+  :group 'macrostep
+  (if macrostep-mode
+      (progn
+        ;; Disable recording of undo information
+        (setq macrostep-saved-undo-list buffer-undo-list
+              buffer-undo-list t)
+        ;; Remember whether buffer was read-only
+        (setq macrostep-saved-read-only buffer-read-only
+              buffer-read-only t)
+        ;; Set up post-command hook to bail out on leaving read-only
+        (add-hook 'post-command-hook #'macrostep-command-hook nil t)
+        (message (substitute-command-keys "\
+\\<macrostep-mode-map>Entering macro stepper mode. \
+Use \\[macrostep-expand] to expand, \\[macrostep-collapse] to collapse, \
+\\[macrostep-collapse-all] to exit.")))
+
+    ;; Exiting mode
+    (if macrostep-expansion-buffer
+        ;; Kill dedicated expansion buffers
+        (quit-window t)
+      ;; Collapse any remaining overlays
+      (when macrostep-overlays (macrostep-collapse-all))
+      ;; Restore undo info & read-only state
+      (setq buffer-undo-list macrostep-saved-undo-list
+            buffer-read-only macrostep-saved-read-only
+            macrostep-saved-undo-list nil)
+      ;; Remove our post-command hook
+      (remove-hook 'post-command-hook #'macrostep-command-hook t))))
+
+;; Post-command hook: bail out of macrostep-mode if the user types C-x
+;; C-q to make the buffer writable again.
+(defun macrostep-command-hook ()
+  (if (not buffer-read-only)
+      (macrostep-mode 0)))
+
+
+;;; Interactive functions
+;;;###autoload
+(defun macrostep-expand (&optional toggle-separate-buffer)
+  "Expand the macro form following point by one step.
+
+Enters `macrostep-mode' if it is not already active, making the
+buffer temporarily read-only.  If `macrostep-mode' is active and the
+form following point is not a macro form, search forward in the
+buffer and expand the next macro form found, if any.
+
+With a prefix argument, the expansion is displayed in a separate
+buffer instead of inline in the current buffer.  Setting
+`macrostep-expand-in-separate-buffer' to non-nil swaps these two
+behaviors."
+  (interactive "P")
+  (cl-destructuring-bind (start . end)
+      (funcall macrostep-sexp-bounds-function)
+    (goto-char start)
+    (let* ((sexp (funcall macrostep-sexp-at-point-function start end))
+           (end (copy-marker end))
+           (text (buffer-substring start end))
+           (env (funcall macrostep-environment-at-point-function))
+           (expansion (funcall macrostep-expand-1-function sexp env)))
+
+      ;; Create a dedicated macro-expansion buffer and copy the text to
+      ;; be expanded into it, if required
+      (let ((separate-buffer-p
+             (if toggle-separate-buffer
+                 (not macrostep-expand-in-separate-buffer)
+               macrostep-expand-in-separate-buffer)))
+        (when (and separate-buffer-p (not macrostep-expansion-buffer))
+          (let ((mode major-mode)
+                (buffer
+                 (get-buffer-create (generate-new-buffer-name "*macro expansion*"))))
+            (set-buffer buffer)
+            (funcall mode)
+            (setq macrostep-expansion-buffer t)
+            (setq macrostep-outer-environment env)
+            (save-excursion
+              (setq start (point))
+              (insert text)
+              (setq end (point-marker)))
+            (pop-to-buffer buffer))))
+
+      (unless macrostep-mode (macrostep-mode t))
+      (let ((existing-overlay (macrostep-overlay-at-point))
+            (macrostep-gensym-depth macrostep-gensym-depth)
+            (macrostep-gensyms-this-level nil)
+            priority)
+        (if existing-overlay
+            (progn        ; Expanding part of a previous macro-expansion
+              (setq priority (1+ (overlay-get existing-overlay 'priority)))
+              (setq macrostep-gensym-depth
+                    (overlay-get existing-overlay 'macrostep-gensym-depth)))
+          ;; Expanding source buffer text
+          (setq priority 1)
+          (setq macrostep-gensym-depth -1))
+
+        (with-silent-modifications
+          (atomic-change-group
+            (let ((inhibit-read-only t))
+              (save-excursion
+                ;; Insert expansion
+                (funcall macrostep-print-function expansion env)
+                ;; Delete the original form
+                (macrostep-collapse-overlays-in (point) end)
+                (delete-region (point) end)
+                ;; Create a new overlay
+                (let* ((overlay
+                        (make-overlay start
+                                      (if (looking-at "\n")
+                                          (1+ (point))
+                                        (point))))
+                       (highlight-overlay (unless macrostep-expansion-buffer
+                                            (copy-overlay overlay))))
+                  (unless macrostep-expansion-buffer
+                    ;; Highlight the overlay in original source buffers only
+                    (overlay-put highlight-overlay 'face 'macrostep-expansion-highlight-face)
+                    (overlay-put highlight-overlay 'priority -1)
+                    (overlay-put overlay 'macrostep-highlight-overlay highlight-overlay))
+                  (overlay-put overlay 'priority priority)
+                  (overlay-put overlay 'macrostep-original-text text)
+                  (overlay-put overlay 'macrostep-gensym-depth macrostep-gensym-depth)
+                  (push overlay macrostep-overlays))))))))))
+
+(defun macrostep-collapse ()
+  "Collapse the innermost macro expansion near point to its source text.
+
+If no more macro expansions are visible after this, exit
+`macrostep-mode'."
+  (interactive)
+  (let ((overlay (macrostep-overlay-at-point)))
+    (when (not overlay) (error "No macro expansion at point"))
+    (let ((inhibit-read-only t))
+      (with-silent-modifications
+        (atomic-change-group
+          (macrostep-collapse-overlay overlay)))))
+  (if (not macrostep-overlays)
+      (macrostep-mode 0)))
+
+(defun macrostep-collapse-all ()
+  "Collapse all visible macro expansions and exit `macrostep-mode'."
+  (interactive)
+  (let ((inhibit-read-only t))
+    (with-silent-modifications
+      (dolist (overlay macrostep-overlays)
+        (let ((outermost (= (overlay-get overlay 'priority) 1)))
+          ;; We only need restore the original text for the outermost
+          ;; overlays
+          (macrostep-collapse-overlay overlay (not outermost))))))
+  (setq macrostep-overlays nil)
+  (macrostep-mode 0))
+
+(defun macrostep-next-macro ()
+  "Move point forward to the next macro form in macro-expanded text."
+  (interactive)
+  (let* ((start (if (get-text-property (point) 'macrostep-macro-start)
+                    (1+ (point))
+                  (point)))
+         (next (next-single-property-change start 'macrostep-macro-start)))
+    (if next
+        (goto-char next)
+      (error "No more macro forms found"))))
+
+(defun macrostep-prev-macro ()
+  "Move point back to the previous macro form in macro-expanded text."
+  (interactive)
+  (let (prev)
+    (save-excursion
+      (while
+          (progn
+            (setq prev (previous-single-property-change
+                        (point) 'macrostep-macro-start))
+            (if (or (not prev)
+                    (get-text-property (1- prev) 'macrostep-macro-start))
+                nil
+              (prog1 t (goto-char prev))))))
+    (if prev
+        (goto-char (1- prev))
+      (error "No previous macro form found"))))
+
+
+;;; Utility functions (not language-specific)
+
+(defun macrostep-overlay-at-point ()
+  "Return the innermost macro stepper overlay at point."
+  (cdr (get-char-property-and-overlay (point) 'macrostep-original-text)))
+
+(defun macrostep-collapse-overlay (overlay &optional no-restore-p)
+  "Collapse a macro-expansion overlay and restore the unexpanded source text.
+
+As a minor optimization, does not restore the original source
+text if NO-RESTORE-P is non-nil.  This is safe to do when
+collapsing all the sub-expansions of an outer overlay, since the
+outer overlay will restore the original source itself.
+
+Also removes the overlay from `macrostep-overlays'."
+  (with-current-buffer (overlay-buffer overlay)
+    ;; If we're cleaning up we don't need to bother restoring text
+    ;; or checking for inner overlays to delete
+    (unless no-restore-p
+      (let* ((start (overlay-start overlay))
+             (end (overlay-end overlay))
+             (text (overlay-get overlay 'macrostep-original-text))
+             (sexp-end
+              (copy-marker
+               (if (equal (char-before end) ?\n) (1- end) end))))
+        (macrostep-collapse-overlays-in start end)
+        (goto-char (overlay-start overlay))
+        (save-excursion
+          (insert text)
+          (delete-region (point) sexp-end))))
+    ;; Remove overlay from the list and delete it
+    (setq macrostep-overlays
+          (delq overlay macrostep-overlays))
+    (let ((highlight-overlay (overlay-get overlay 'macrostep-highlight-overlay)))
+      (when highlight-overlay (delete-overlay highlight-overlay)))
+    (delete-overlay overlay)))
+
+(defun macrostep-collapse-overlays-in (start end)
+  "Collapse all macrostepper overlays that are strictly between START and END.
+
+Will not collapse overlays that begin at START and end at END."
+  (dolist (ol (overlays-in start end))
+    (when (and (overlay-buffer ol)        ; collapsing may delete other overlays
+               (> (overlay-start ol) start)
+               (< (overlay-end ol) end)
+               (overlay-get ol 'macrostep-original-text))
+      (macrostep-collapse-overlay ol t))))
+
+
+;;; Emacs Lisp implementation
+
+(defun macrostep-sexp-bounds ()
+  "Find the bounds of the macro form nearest point.
+
+If point is not before an open-paren, moves up to the nearest
+enclosing list.  If the form at point is not a macro call,
+attempts to move forward to the next macro form as determined by
+`macrostep-macro-form-p-function'.
+
+Returns a cons of buffer positions, (START . END)."
+  (save-excursion
+    (if (not (looking-at "[(`]"))
+        (backward-up-list 1))
+    (if (equal (char-before) ?`)
+        (backward-char))
+    (let ((sexp (funcall macrostep-sexp-at-point-function))
+          (env (funcall macrostep-environment-at-point-function)))
+      ;; If this isn't a macro form, try to find the next one in the buffer
+      (unless (funcall macrostep-macro-form-p-function sexp env)
+        (condition-case nil
+            (macrostep-next-macro)
+          (error
+           (if (consp sexp)
+               (error "(%s ...) is not a macro form" (car sexp))
+             (error "Text at point is not a macro form"))))))
+    (cons (point) (scan-sexps (point) 1))))
+
+(defun macrostep-sexp-at-point (&rest _ignore)
+  "Return the sexp near point for purposes of macro-stepper expansion.
+
+If the sexp near point is part of a macro expansion, returns the
+saved text of the macro expansion, and does not read from the
+buffer.  This preserves uninterned symbols in the macro
+expansion, so that they can be fontified consistently.  (See
+`macrostep-print-sexp'.)"
+  (or (get-text-property (point) 'macrostep-expanded-text)
+      (sexp-at-point)))
+
+(defun macrostep-macro-form-p (form environment)
+  "Return non-nil if FORM would be evaluated via macro expansion.
+
+If FORM is an invocation of a macro defined by `defmacro' or an
+enclosing `cl-macrolet' form, return the symbol `macro'.
+
+If `macrostep-expand-compiler-macros' is non-nil and FORM is a
+call to a function with a compiler macro, return the symbol
+`compiler-macro'.
+
+Otherwise, return nil."
+  (car (macrostep--macro-form-info form environment t)))
+
+(defun macrostep--macro-form-info (form environment &optional inhibit-autoload)
+  "Return information about macro definitions that apply to FORM.
+
+If no macros are involved in the evaluation of FORM within
+ENVIRONMENT, returns nil.  Otherwise, returns a cons (TYPE
+. DEFINITION).
+
+If FORM would be evaluated by a macro defined by `defmacro',
+`cl-macrolet', etc., TYPE is the symbol `macro' and DEFINITION is
+the macro definition, as a function.
+
+If `macrostep-expand-compiler-macros' is non-nil and FORM would
+be compiled using a compiler macro, TYPE is the symbol
+`compiler-macro' and DEFINITION is the function that implements
+the compiler macro.
+
+If FORM is an invocation of an autoloaded macro, the behavior
+depends on the value of INHIBIT-AUTOLOAD.  If INHIBIT-AUTOLOAD is
+nil, the file containing the macro definition will be loaded
+using `load-library' and the macro definition returned as normal.
+If INHIBIT-AUTOLOAD is non-nil, no files will be loaded, and the
+value of DEFINITION in the result will be nil."
+  (if (not (and (consp form)
+                (symbolp (car form))))
+      `(nil . nil)
+    (let* ((head (car form))
+           (local-definition (assoc-default head environment #'eq)))
+      (if local-definition
+          `(macro . ,local-definition)
+        (let ((compiler-macro-definition
+               (and macrostep-expand-compiler-macros
+                    (or (get head 'compiler-macro)
+                        (get head 'cl-compiler-macro)))))
+          (if (and compiler-macro-definition
+                   (not (eq form
+                            (apply compiler-macro-definition form (cdr form)))))
+              `(compiler-macro . ,compiler-macro-definition)
+            (condition-case nil
+                (let ((fun (indirect-function head)))
+                  (cl-case (car-safe fun)
+                    ((macro)
+                     `(macro . ,(cdr fun)))
+                    ((autoload)
+                     (when (memq (nth 4 fun) '(macro t))
+                       (if inhibit-autoload
+                           `(macro . nil)
+                         (load-library (nth 1 fun))
+                         (macrostep--macro-form-info form nil))))
+                    (t
+                     `(nil . nil))))
+              (void-function nil))))))))
+
+(defun macrostep-expand-1 (form environment)
+  "Return result of macro-expanding the top level of FORM by exactly one step.
+Unlike `macroexpand', this function does not continue macro
+expansion until a non-macro-call results."
+  (cl-destructuring-bind (type . definition)
+      (macrostep--macro-form-info form environment)
+    (cl-ecase type
+      ((nil)
+       form)
+      ((macro)
+       (apply definition (cdr form)))
+      ((compiler-macro)
+       (let ((expansion (apply definition form (cdr form))))
+         (if (equal form expansion)
+             (error "Form left unchanged by compiler macro")
+           expansion))))))
+
+(put 'macrostep-grab-environment-failed 'error-conditions
+     '(macrostep-grab-environment-failed error))
+
+(defun macrostep-environment-at-point ()
+  "Return the local macro-expansion environment at point, if any.
+
+The local environment includes macros declared by any `macrolet'
+or `cl-macrolet' forms surrounding point, as well as by any macro
+forms which expand into a `macrolet'.
+
+The return value is an alist of elements (NAME . FUNCTION), where
+NAME is the symbol locally bound to the macro and FUNCTION is the
+lambda expression that returns its expansion."
+  ;; If point is on a macro form within an expansion inserted by
+  ;; `macrostep-print-sexp', a local environment may have been
+  ;; previously saved as a text property.
+  (let ((saved-environment
+         (get-text-property (point) 'macrostep-environment)))
+    (if saved-environment
+        saved-environment
+      ;; Otherwise, we (ab)use the macro-expander to return the
+      ;; environment at point.  If point is not at an evaluated
+      ;; position in the containing form,
+      ;; `macrostep-environment-at-point-1' will raise an error, and
+      ;; we back up progressively through the containing forms until
+      ;; it succeeds.
+      (save-excursion
+        (catch 'done
+          (while t
+            (condition-case nil
+                (throw 'done (macrostep-environment-at-point-1))
+              (macrostep-grab-environment-failed
+               (condition-case nil
+                   (backward-sexp)
+                 (scan-error (backward-up-list)))))))))))
+
+(defun macrostep-environment-at-point-1 ()
+  "Attempt to extract the macro environment that would be active at point.
+
+If point is not at an evaluated position within the containing
+form, raise an error."
+  ;; Macro environments are extracted using Emacs Lisp's builtin
+  ;; macro-expansion machinery.  The form containing point is copied
+  ;; to a temporary buffer, and a call to
+  ;; `--macrostep-grab-environment--' is inserted at point.  This
+  ;; altered form is then fully macro-expanded, in an environment
+  ;; where `--macrostep-grab-environment--' is defined as a macro
+  ;; which throws the environment to a uniquely-generated tag.
+  (let* ((point-at-top-level
+          (save-excursion
+            (while (ignore-errors (backward-up-list) t))
+            (point)))
+         (enclosing-form
+          (buffer-substring point-at-top-level
+                            (scan-sexps point-at-top-level 1)))
+         (position (- (point) point-at-top-level))
+         (tag (make-symbol "macrostep-grab-environment-tag"))
+         (grab-environment '--macrostep-grab-environment--))
+    (if (= position 0)
+        nil
+      (with-temp-buffer
+        (emacs-lisp-mode)
+        (insert enclosing-form)
+        (goto-char (+ (point-min) position))
+        (prin1 `(,grab-environment) (current-buffer))
+        (let ((form (read (copy-marker (point-min)))))
+          (catch tag
+            (cl-letf (((symbol-function #'message) (symbol-function #'format)))
+              (with-no-warnings
+                (ignore-errors
+                  (macroexpand-all
+                   `(cl-macrolet ((,grab-environment (&environment env)
+                                    (throw ',tag env)))
+                      ,form)))))
+            (signal 'macrostep-grab-environment-failed nil)))))))
+
+(defun macrostep-collect-macro-forms (form &optional environment)
+  "Identify sub-forms of FORM which undergo macro-expansion.
+
+FORM is an Emacs Lisp form.  ENVIRONMENT is a local environment of
+macro definitions.
+
+The return value is a list of two elements, (MACRO-FORM-ALIST
+COMPILER-MACRO-FORMS).
+
+MACRO-FORM-ALIST is an alist of elements of the form (SUBFORM
+. ENVIRONMENT), where SUBFORM is a form which undergoes
+macro-expansion in the course of expanding FORM, and ENVIRONMENT
+is the local macro environment in force when it is expanded.
+
+COMPILER-MACRO-FORMS is a list of subforms which would be
+compiled using a compiler macro.  Since there is no standard way
+to provide a local compiler-macro definition in Emacs Lisp, no
+corresponding local environments are collected for these.
+
+Forms and environments are extracted from FORM by instrumenting
+Emacs's builtin `macroexpand' function and calling
+`macroexpand-all'."
+  (let ((real-macroexpand (indirect-function #'macroexpand))
+        (macro-form-alist '())
+        (compiler-macro-forms '()))
+    (cl-letf
+        (((symbol-function #'macroexpand)
+          (lambda (form environment &rest args)
+            (let ((expansion
+                   (apply real-macroexpand form environment args)))
+              (cond ((not (eq expansion form))
+                     (setq macro-form-alist
+                           (cons (cons form environment)
+                                 macro-form-alist)))
+                    ((and (consp form)
+                          (symbolp (car form))
+                          macrostep-expand-compiler-macros
+                          (not (eq form
+                                   (cl-compiler-macroexpand form))))
+                     (setq compiler-macro-forms
+                           (cons form compiler-macro-forms))))
+              expansion))))
+      (ignore-errors
+        (macroexpand-all form environment)))
+    (list macro-form-alist compiler-macro-forms)))
+
+(defvar macrostep-collected-macro-form-alist nil
+  "An alist of macro forms and environments.
+Controls the printing of sub-forms in `macrostep-print-sexp'.")
+
+(defvar macrostep-collected-compiler-macro-forms nil
+  "A list of compiler-macro forms to be highlighted in `macrostep-print-sexp'.")
+
+(defun macrostep-pp (sexp environment)
+  "Pretty-print SEXP, fontifying macro forms and uninterned symbols."
+  (cl-destructuring-bind
+        (macrostep-collected-macro-form-alist
+         macrostep-collected-compiler-macro-forms)
+      (macrostep-collect-macro-forms sexp environment)
+    (let ((print-quoted t))
+      (macrostep-print-sexp sexp)
+      ;; Point is now after the expanded form; pretty-print it
+      (save-restriction
+        (narrow-to-region (scan-sexps (point) -1) (point))
+        (save-excursion
+          (pp-buffer)
+          ;; Remove the extra newline inserted by pp-buffer
+          (goto-char (point-max))
+          (delete-region
+           (point)
+           (save-excursion (skip-chars-backward " \t\n") (point))))
+        ;; Indent the newly-inserted form in context
+        (widen)
+        (save-excursion
+          (backward-sexp)
+          (indent-sexp))))))
+
+;; This must be defined before `macrostep-print-sexp':
+(defmacro macrostep-propertize (form &rest plist)
+  "Evaluate FORM, applying syntax properties in PLIST to any inserted text."
+  (declare (indent 1)
+           (debug (&rest form)))
+  (let ((start (make-symbol "start")))
+    `(let ((,start (point)))
+       (prog1
+           ,form
+         ,@(cl-loop for (key value) on plist by #'cddr
+                    collect `(put-text-property ,start (point)
+                                                ,key ,value))))))
+
+(defun macrostep-print-sexp (sexp)
+  "Insert SEXP like `print', fontifying macro forms and uninterned symbols.
+
+Fontifies uninterned symbols and macro forms using
+`font-lock-face' property, and saves the actual text of SEXP's
+sub-forms as the `macrostep-expanded-text' text property so that
+any uninterned symbols can be reused in macro expansions of the
+sub-forms.  See also `macrostep-sexp-at-point'.
+
+Macro and compiler-macro forms within SEXP are identified by
+comparison with the `macrostep-collected-macro-form-alist' and
+`macrostep-collected-compiler-macro-forms' variables, which
+should be dynamically let-bound around calls to this function."
+  (cond
+   ((symbolp sexp)
+    ;; Fontify gensyms
+    (if (not (eq sexp (intern-soft (symbol-name sexp))))
+        (macrostep-propertize
+            (prin1 sexp (current-buffer))
+          'font-lock-face (macrostep-get-gensym-face sexp))
+      ;; Print other symbols as normal
+      (prin1 sexp (current-buffer))))
+
+   ((listp sexp)
+    ;; Print quoted and quasiquoted forms nicely.
+    (let ((head (car sexp)))
+      (cond ((and (eq head 'quote)      ; quote
+                  (= (length sexp) 2))
+             (insert "'")
+             (macrostep-print-sexp (cadr sexp)))
+
+            ((and (eq head '\`)         ; backquote
+                  (= (length sexp) 2))
+             (if (assq sexp macrostep-collected-macro-form-alist)
+                 (macrostep-propertize
+                     (insert "`")
+                   'macrostep-expanded-text sexp
+                   'macrostep-macro-start t
+                   'font-lock-face 'macrostep-macro-face)
+               (insert "`"))
+             (macrostep-print-sexp (cadr sexp)))
+
+            ((and (memq head '(\, \,@)) ; unquote
+                  (= (length sexp) 2))
+             (princ head (current-buffer))
+             (macrostep-print-sexp (cadr sexp)))
+
+            (t                          ; other list form
+             (cl-destructuring-bind (macro? . environment)
+                 (or (assq sexp macrostep-collected-macro-form-alist)
+                     '(nil . nil))
+               (let
+                   ((compiler-macro?
+                     (memq sexp macrostep-collected-compiler-macro-forms)))
+                 (if (or macro? compiler-macro?)
+                     (progn
+                       ;; Save the real expansion as a text property on the
+                       ;; opening paren
+                       (macrostep-propertize
+                        (insert "(")
+                        'macrostep-macro-start t
+                        'macrostep-expanded-text sexp
+                        'macrostep-environment environment)
+                       ;; Fontify the head of the macro
+                       (macrostep-propertize
+                        (macrostep-print-sexp head)
+                        'font-lock-face
+                        (if macro?
+                            'macrostep-macro-face
+                          'macrostep-compiler-macro-face)))
+                   ;; Not a macro form
+                   (insert "(")
+                   (macrostep-print-sexp head))))
+
+             ;; Print remaining list elements
+             (setq sexp (cdr sexp))
+             (when sexp (insert " "))
+             (while sexp
+               (if (listp sexp)
+                   (progn
+                     (macrostep-print-sexp (car sexp))
+                     (when (cdr sexp) (insert " "))
+                     (setq sexp (cdr sexp)))
+                 ;; Print tail of dotted list
+                 (insert ". ")
+                 (macrostep-print-sexp sexp)
+                 (setq sexp nil)))
+             (insert ")")))))
+
+   ;; Print everything except symbols and lists as normal
+   (t (prin1 sexp (current-buffer)))))
+
+(defun macrostep-get-gensym-face (symbol)
+  "Return the face to use in fontifying SYMBOL in printed macro expansions.
+
+All symbols introduced in the same level of macro expansion are
+fontified using the same face (modulo the number of faces; see
+`macrostep-gensym-faces')."
+  (or (get symbol 'macrostep-gensym-face)
+      (progn
+        (if (not macrostep-gensyms-this-level)
+            (setq macrostep-gensym-depth (1+ macrostep-gensym-depth)
+                  macrostep-gensyms-this-level t))
+        (let ((face (ring-ref macrostep-gensym-faces macrostep-gensym-depth)))
+          (put symbol 'macrostep-gensym-face face)
+          face))))
+
+
+(provide 'macrostep)
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+;;; macrostep.el ends here
blob - /dev/null
blob + f5f115bd45c200174e068eadd9a1e35d67ea8e23 (mode 644)
--- /dev/null
+++ elpa/macrostep-0.9.2.signed
@@ -0,0 +1 @@
+Good signature from 066DAFCB81E42C40 GNU ELPA Signing Agent (2019) <elpasign@elpa.gnu.org> (trust undefined) created at 2023-05-18T23:10:03+0200 using RSA
\ No newline at end of file
blob - /dev/null
blob + 00f3aa0d4c361c70c149bd4af7fc4a644d23d125 (mode 644)
--- /dev/null
+++ elpa/sly-macrostep-20191211.1630/collect-macro-forms.lisp
@@ -0,0 +1,59 @@
+;;; collect-macro-forms.lisp -- helper macros for slynk-macrostep.lisp
+;;
+;; Authors: Luís Oliveira <luismbo@gmail.com>
+;;          Jon Oddie <j.j.oddie@gmail.com>
+;;          João Távora <joaotavora@gmail.com>
+;;
+;; License: Public Domain
+
+(in-package #:slynk-macrostep)
+
+;;; JT: These definitions brought into this contrib from SLIME's
+;;; backend.lisp. They could/should go into SLY if they prove to be useful
+;;; enough for writing other contribs, meanwhile keep them here.
+;;; 
+(defmacro with-collected-macro-forms
+    ((forms &optional result) instrumented-form &body body)
+  "Collect macro forms by locally binding *MACROEXPAND-HOOK*.
+Evaluates INSTRUMENTED-FORM and collects any forms which undergo
+macro-expansion into a list.  Then evaluates BODY with FORMS bound to
+the list of forms, and RESULT (optionally) bound to the value of
+INSTRUMENTED-FORM."
+  (assert (and (symbolp forms) (not (null forms))))
+  (assert (symbolp result))
+  ;; JT: Added conditional ignore spec
+  ;; 
+  (let ((result-var (or result
+                        (gensym))))
+    `(call-with-collected-macro-forms
+      (lambda (,forms ,result-var)
+        (declare (ignore ,@(unless result
+                             `(,result-var))))
+        ,@body)
+      (lambda () ,instrumented-form))))
+
+(defun call-with-collected-macro-forms (body-fn instrumented-fn)
+  (let ((return-value nil)
+        (collected-forms '()))
+    (let* ((real-macroexpand-hook *macroexpand-hook*)
+           (*macroexpand-hook*
+            (lambda (macro-function form environment)
+              (let ((result (funcall real-macroexpand-hook
+                                     macro-function form environment)))
+                (unless (eq result form)
+                  (push form collected-forms))
+                result))))
+      (setf return-value (funcall instrumented-fn)))
+    (funcall body-fn collected-forms return-value)))
+
+(defun collect-macro-forms (form &optional env)
+  "Collect subforms of FORM which undergo (compiler-)macro expansion.
+Returns two values: a list of macro forms and a list of compiler macro
+forms."
+  (with-collected-macro-forms (macro-forms expansion)
+      (ignore-errors (macroexpand-all form env))
+    (with-collected-macro-forms (compiler-macro-forms)
+        (handler-bind ((warning #'muffle-warning))
+          (ignore-errors
+            (compile nil `(lambda () ,expansion))))
+      (values macro-forms compiler-macro-forms))))
blob - /dev/null
blob + b27b55f65520118ce9e74bd6507b3ea0a5624081 (mode 644)
--- /dev/null
+++ elpa/sly-macrostep-20191211.1630/package.lisp
@@ -0,0 +1,22 @@
+;;; package.lisp -- package definition for slynk-macrostep.lisp
+;;
+;; Authors: Luís Oliveira <luismbo@gmail.com>
+;;          Jon Oddie <j.j.oddie@gmail.com>
+;;          João Távora <joaotavora@gmail.com>
+;;
+;; License: Public Domain
+
+(defpackage slynk-macrostep
+  (:use #:cl #:slynk-api)
+  (:import-from slynk
+		#:*macroexpand-printer-bindings*
+                #:with-buffer-syntax
+		#:with-bindings
+                #:to-string
+                #:macroexpand-all
+                #:compiler-macroexpand-1
+                #:debug-on-slynk-error
+                #:defslyfun)
+  (:export #:macrostep-expand-1
+           #:macro-form-p))
+
blob - /dev/null
blob + 25850868869a858c77f83d1e13f2bca6757f9066 (mode 644)
--- /dev/null
+++ elpa/sly-macrostep-20191211.1630/sly-macrostep-autoloads.el
@@ -0,0 +1,40 @@
+;;; sly-macrostep-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+                         (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "sly-macrostep" "sly-macrostep.el" (0 0 0 0))
+;;; Generated autoloads from sly-macrostep.el
+
+(with-eval-after-load 'sly
+  (add-to-list 'sly-contribs 'sly-macrostep 'append))
+
+(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "sly-macrostep" '("sly-macrostep")))
+
+;;;***
+
+;;;### (autoloads nil "sly-macrostep-tests" "sly-macrostep-tests.el"
+;;;;;;  (0 0 0 0))
+;;; Generated autoloads from sly-macrostep-tests.el
+
+(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "sly-macrostep-tests" '("sly-macrostep-")))
+
+(provide 'sly-macrostep-autoloads)
+
+;;;***
+
+
+;;; Generated autoloads from sly-macrostep.el
+
+(with-eval-after-load 'sly (add-to-list 'sly-contribs 'sly-macrostep 'append))
+(register-definition-prefixes "sly-macrostep" '("sly-macrostep"))
+
+;; Local Variables:
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; sly-macrostep-autoloads.el ends here
blob - /dev/null
blob + c10478b6a1a4f184baed40c1ffdeec95675c8736 (mode 644)
--- /dev/null
+++ elpa/sly-macrostep-20191211.1630/sly-macrostep-pkg.el
@@ -0,0 +1,9 @@
+(define-package "sly-macrostep" "20191211.1630" "fancy macro-expansion via macrostep.el"
+  '((sly "1.0.0beta2")
+    (macrostep "0.9"))
+  :commit "5113e4e926cd752b1d0bcc1508b3ebad5def5fad" :keywords
+  '("languages" "lisp" "sly")
+  :url "https://github.com/capitaomorte/sly-macrostep")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
blob - /dev/null
blob + 7169fdaf85dac158b29b785bf03a88a5b53766f6 (mode 644)
--- /dev/null
+++ elpa/sly-macrostep-20191211.1630/sly-macrostep.el
@@ -0,0 +1,147 @@
+;;; sly-macrostep.el --- fancy macro-expansion via macrostep.el
+;;
+;; Version: 0.1
+;; URL: https://github.com/capitaomorte/sly-macrostep
+;; Keywords: languages, lisp, sly
+;; Package-Requires: ((sly "1.0.0-beta2") (macrostep "0.9"))
+;; Authors: Luís Oliveira <luismbo@gmail.com>, Jon Oddie <j.j.oddie@gmail.com, João Távora <joaotavora@gmail.com>
+;;
+;; Copyright (C) 2016 the authors
+;; 
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+;;
+;;; Description:
+;;
+;; This is the SLY port of a contrib originally written for SLIME,
+;; with minimal changes, mostly "slime"->"sly" replacements.
+;;
+;; Fancier in-place macro-expansion using macrostep.el (originally
+;; written for Emacs Lisp).  To use, position point before the
+;; open-paren of the macro call in a SLY source or REPL buffer, and
+;; type `C-c M-e' or `M-x macrostep-expand'.  The pretty-printed
+;; result of `macroexpand-1' will be inserted inline in the current
+;; buffer, which is temporarily read-only while macro expansions are
+;; visible.  If the expansion is itself a macro call, expansion can be
+;; continued by typing `e'.  Expansions are collapsed to their
+;; original macro forms by typing `c' or `q'.  Other macro- and
+;; compiler-macro calls in the expansion will be font-locked
+;; differently, and point can be moved there quickly by typing `n' or
+;; `p'.  For more details, see the documentation of
+;; `macrostep-expand'.
+
+;;; Code:
+
+(require 'sly)
+(require 'macrostep)
+(require 'cl-lib)
+
+(define-sly-contrib sly-macrostep
+  "Interactive macro expansion via macrostep.el."
+  (:authors "Luís Oliveira       <luismbo@gmail.com>"
+            "Jon Oddie           <j.j.oddie@gmail.com>")
+  (:license "GPL")
+  (:slynk-dependencies slynk-macrostep)
+  (:on-load
+   (easy-menu-add-item sly-mode-map '(menu-bar SLY Debugging)
+                       ["Macro stepper..." macrostep-expand (sly-connected-p)])
+   (add-hook 'sly-editing-mode-hook #'sly-macrostep-mode-hook)
+   (define-key sly-editing-mode-map (kbd "C-c M-e") #'macrostep-expand)
+   (eval-after-load 'sly-mrepl
+     '(progn
+       (add-hook 'sly-mrepl-mode-hook #'sly-macrostep-mode-hook)
+       (define-key sly-mrepl-mode-map (kbd "C-c M-e") #'macrostep-expand)))))
+
+(defun sly-macrostep-mode-hook ()
+  (setq macrostep-sexp-at-point-function #'sly-macrostep-sexp-at-point)
+  (setq macrostep-environment-at-point-function #'sly-macrostep-context)
+  (setq macrostep-expand-1-function #'sly-macrostep-expand-1)
+  (setq macrostep-print-function #'sly-macrostep-insert)
+  (setq macrostep-macro-form-p-function #'sly-macrostep-macro-form-p))
+
+(defun sly-macrostep-sexp-at-point (&rest _ignore)
+  (sly-sexp-at-point))
+
+(defun sly-macrostep-context ()
+  (let (defun-start defun-end)
+    (save-excursion
+      (while
+          (condition-case nil
+              (progn (backward-up-list) t)
+            (scan-error nil)))
+      (setq defun-start (point))
+      (setq defun-end (scan-sexps (point) 1)))
+    (list (buffer-substring-no-properties
+           defun-start (point))
+          (buffer-substring-no-properties
+           (scan-sexps (point) 1) defun-end))))
+
+(defun sly-macrostep-expand-1 (string context)
+  (sly-dcase
+      (sly-eval
+       `(slynk-macrostep:macrostep-expand-1
+         ,string ,macrostep-expand-compiler-macros ',context))
+    ((:error error-message)
+     (error "%s" error-message))
+    ((:ok expansion positions)
+     (list expansion positions))))
+
+(defun sly-macrostep-insert (result _ignore)
+  "Insert RESULT at point, indenting to match the current column."
+  (cl-destructuring-bind (expansion positions) result
+    (let ((start (point))
+          (column-offset (current-column)))
+      (insert expansion)
+      (sly-macrostep--propertize-macros start positions)
+      (indent-rigidly start (point) column-offset))))
+
+(defun sly-macrostep--propertize-macros (start-offset positions)
+  "Put text properties on macro forms."
+  (dolist (position positions)
+    (cl-destructuring-bind (operator type start)
+        position
+      (let ((open-paren-position
+              (+ start-offset start)))
+        (put-text-property open-paren-position
+                           (1+ open-paren-position)
+                           'macrostep-macro-start
+                           t)
+        ;; this assumes that the operator starts right next to the
+        ;; opening parenthesis. We could probably be more robust.
+        (let ((op-start (1+ open-paren-position)))
+          (put-text-property op-start
+                             (+ op-start (length operator))
+                             'font-lock-face
+                             (if (eq type :macro)
+                                 'macrostep-macro-face
+                                 'macrostep-compiler-macro-face)))))))
+
+(defun sly-macrostep-macro-form-p (string context)
+  (sly-dcase
+      (sly-eval
+       `(slynk-macrostep:macro-form-p
+         ,string ,macrostep-expand-compiler-macros ',context))
+    ((:error error-message)
+     (error "%s" error-message))
+    ((:ok result)
+     result)))
+
+
+
+;;; Automatically add ourselves to `sly-contribs' when this file is loaded
+;;;###autoload
+(with-eval-after-load 'sly
+  (add-to-list 'sly-contribs 'sly-macrostep 'append))
+
+(provide 'sly-macrostep)
+;;; sly-macrostep.el ends here
blob - /dev/null
blob + ffb96543dfd25b08412ab65df9977c29854b40b1 (mode 644)
--- /dev/null
+++ elpa/sly-macrostep-20191211.1630/slynk-macrostep.asd
@@ -0,0 +1,14 @@
+;;; -*- lisp -*-
+(in-package :asdf)
+
+(defsystem :slynk-macrostep
+    :author "João Távora <https://github.com/capitaomorte>"
+    :depends-on (#:slynk)
+  :description "MACROSTEP support for Slynk"
+  :components ((:file "package")
+               (:file "collect-macro-forms")
+               (:file "slynk-macrostep")))
+
+;; Local Variables:
+;; coding: utf-8
+;; End:
blob - /dev/null
blob + 1fdab6e940125a876be1029b217c3904e0942e87 (mode 644)
--- /dev/null
+++ elpa/sly-macrostep-20191211.1630/slynk-macrostep.lisp
@@ -0,0 +1,215 @@
+;;; slynk-macrostep.lisp -- fancy macro-expansion via macrostep.el
+;;
+;; Authors: Luís Oliveira <luismbo@gmail.com>
+;;          Jon Oddie <j.j.oddie@gmail.com>
+;;          João Távora <joaotavora@gmail.com>
+;;
+;; License: Public Domain
+
+(in-package #:slynk-macrostep)
+
+
+(defslyfun macrostep-expand-1 (string compiler-macros? context)
+  (with-buffer-syntax ()
+    (let ((form (read-from-string string)))
+      (multiple-value-bind (expansion error-message)
+	  (expand-form-once form compiler-macros? context)
+	(if error-message
+            `(:error ,error-message)
+	    (multiple-value-bind (macros compiler-macros)
+		(collect-macro-forms-in-context expansion context)
+	      (let* ((all-macros (append macros compiler-macros))
+		     (pretty-expansion (pprint-to-string expansion))
+		     (positions (collect-form-positions expansion
+							pretty-expansion
+							all-macros))
+                     (subform-info
+                      (loop
+                         for form in all-macros
+                         for (start end) in positions
+                         when (and start end)
+                         collect (let ((op-name (to-string (first form)))
+                                       (op-type
+                                        (if (member form macros)
+                                            :macro
+                                            :compiler-macro)))
+                                   (list op-name
+                                         op-type
+                                         start)))))
+		`(:ok ,pretty-expansion ,subform-info))))))))
+
+(defun expand-form-once (form compiler-macros? context)
+  (multiple-value-bind (expansion expanded?)
+      (macroexpand-1-in-context form context)
+    (if expanded?
+	(values expansion nil)
+	(if (not compiler-macros?)
+	    (values nil "Not a macro form")
+	    (multiple-value-bind (expansion expanded?)
+		(compiler-macroexpand-1 form)
+	      (if expanded?
+		  (values expansion nil)
+		  (values nil "Not a macro or compiler-macro form")))))))
+
+(defslyfun macro-form-p (string compiler-macros? context)
+  (with-buffer-syntax ()
+    (let ((form
+           (handler-case
+               (read-from-string string)
+             (error (condition)
+               (unless (debug-on-slynk-error)
+                 (return-from macro-form-p
+                   `(:error ,(format nil "Read error: ~A" condition))))))))
+      `(:ok ,(macro-form-type form compiler-macros? context)))))
+
+(defun macro-form-type (form compiler-macros? context)
+  (cond
+    ((or (not (consp form))
+         (not (symbolp (car form))))
+     nil)
+    ((multiple-value-bind (expansion expanded?)
+         (macroexpand-1-in-context form context)
+       (declare (ignore expansion))
+       expanded?)
+     :macro)
+    ((and compiler-macros?
+          (multiple-value-bind (expansion expanded?)
+              (compiler-macroexpand-1 form)
+            (declare (ignore expansion))
+            expanded?))
+     :compiler-macro)
+    (t
+     nil)))
+
+
+;;;; Hacks to support macro-expansion within local context
+
+(defparameter *macrostep-tag* (gensym))
+
+(defparameter *macrostep-placeholder* '*macrostep-placeholder*)
+
+(define-condition expansion-in-context-failed (simple-error)
+  ())
+
+(defmacro throw-expansion (form &environment env)
+  (throw *macrostep-tag* (macroexpand-1 form env)))
+
+(defmacro throw-collected-macro-forms (form &environment env)
+  (throw *macrostep-tag* (collect-macro-forms form env)))
+
+(defun macroexpand-1-in-context (form context)
+  (handler-case
+      (macroexpand-and-catch
+       `(throw-expansion ,form) context)
+    (error ()
+      (macroexpand-1 form))))
+
+(defun collect-macro-forms-in-context (form context)
+  (handler-case
+      (macroexpand-and-catch
+       `(throw-collected-macro-forms ,form) context)
+    (error ()
+      (collect-macro-forms form))))
+
+(defun macroexpand-and-catch (form context)
+  (catch *macrostep-tag*
+    (macroexpand-all (enclose-form-in-context form context))
+    (error 'expansion-in-context-failed)))
+
+(defun enclose-form-in-context (form context)
+  (with-buffer-syntax ()
+    (destructuring-bind (prefix suffix) context
+      (let* ((placeholder-form
+              (read-from-string
+               (concatenate
+                'string
+                prefix (prin1-to-string *macrostep-placeholder*) suffix)))
+             (substituted-form (subst form *macrostep-placeholder*
+                                      placeholder-form)))
+        (if (not (equal placeholder-form substituted-form))
+            substituted-form
+            (error 'expansion-in-context-failed))))))
+
+
+;;;; Tracking Pretty Printer
+
+(defun marker-char-p (char)
+  (<= #xe000 (char-code char) #xe8ff))
+
+(defun make-marker-char (id)
+  ;; using the private-use characters U+E000..U+F8FF as markers, so
+  ;; that's our upper limit for how many we can use.
+  (assert (<= 0 id #x8ff))
+  (code-char (+ #xe000 id)))
+
+(defun marker-char-id (char)
+  (assert (marker-char-p char))
+  (- (char-code char) #xe000))
+
+(defparameter +whitespace+ (mapcar #'code-char '(9 13 10 32)))
+
+(defun whitespacep (char)
+  (member char +whitespace+))
+
+(defun pprint-to-string (object &optional pprint-dispatch)
+  (let ((*print-pprint-dispatch* (or pprint-dispatch *print-pprint-dispatch*)))
+    (with-bindings *macroexpand-printer-bindings*
+      (to-string object))))
+
+#-clisp
+(defun collect-form-positions (expansion printed-expansion forms)
+  (loop for (start end)
+     in (collect-marker-positions
+         (pprint-to-string expansion (make-tracking-pprint-dispatch forms))
+         (length forms))
+     collect (when (and start end)
+               (list (find-non-whitespace-position printed-expansion start)
+                     (find-non-whitespace-position printed-expansion end)))))
+
+;; The pprint-dispatch table constructed by
+;; MAKE-TRACKING-PPRINT-DISPATCH causes an infinite loop and stack
+;; overflow under CLISP version 2.49.  Make the COLLECT-FORM-POSITIONS
+;; entry point a no-op in thi case, so that basic macro-expansion will
+;; still work (without detection of inner macro forms)
+#+clisp
+(defun collect-form-positions (expansion printed-expansion forms)
+  nil)
+
+(defun make-tracking-pprint-dispatch (forms)
+  (let ((original-table *print-pprint-dispatch*)
+        (table (copy-pprint-dispatch)))
+    (flet ((maybe-write-marker (position stream)
+             (when position
+               (write-char (make-marker-char position) stream))))
+      (set-pprint-dispatch 'cons
+                           (lambda (stream cons)
+                             (let ((pos (position cons forms)))
+                               (maybe-write-marker pos stream)
+                               ;; delegate printing to the original table.
+                               (funcall (pprint-dispatch cons original-table)
+                                        stream
+                                        cons)
+                               (maybe-write-marker pos stream)))
+                           most-positive-fixnum
+                           table))
+    table))
+
+(defun collect-marker-positions (string position-count)
+  (let ((positions (make-array position-count :initial-element nil)))
+    (loop with p = 0
+          for char across string
+          unless (whitespacep char)
+            do (if (marker-char-p char)
+                   (push p (aref positions (marker-char-id char)))
+                   (incf p)))
+    (map 'list #'reverse positions)))
+
+(defun find-non-whitespace-position (string position)
+  (loop with non-whitespace-position = -1
+        for i from 0 and char across string
+        unless (whitespacep char)
+          do (incf non-whitespace-position)
+        until (eql non-whitespace-position position)
+        finally (return i)))
+
+(provide :slynk-macrostep)
blob - /dev/null
blob + 0e320d18746da490300882cbab21f28e5eb76720 (mode 644)
--- /dev/null
+++ elpa/sly-named-readtables-20191013.2138/example.lisp
@@ -0,0 +1,24 @@
+(eval-when (:compile-toplevel :load-toplevel :execute)
+  (ql:quickload :named-readtables))
+
+(defpackage #:silly-named-readtables (:use :cl #:named-readtables))
+(in-package #:silly-named-readtables)
+
+(defreadtable :silly-table
+  (:merge :standard)
+  (:dispatch-macro-char #\# #\' (lambda (stream char arg)
+                                  (declare (ignore char arg))
+                                  (let ((fname (read stream)))
+                                    (etypecase fname
+                                      ((or symbol (cons (eql cl:setf) *))
+                                       `(function ,fname))
+                                      (cons `(silly-function ,@fname))))))
+  (:case :upcase))
+
+(read-from-string "#'foo")           ;; => #'FOO
+(read-from-string "#'(foo bar)")     ;; => #'(FOO BLA)
+
+(in-readtable :silly-table)
+
+(read-from-string "#'some-function") ;; => #'SOME-FUNCTION
+(read-from-string "#'(foo bar)")     ;; => (SILLY-FUNCTION FOO BAR)
blob - /dev/null
blob + 0452751cecc324956928ca06b8aa0c8aa7802981 (mode 644)
--- /dev/null
+++ elpa/sly-named-readtables-20191013.2138/sly-named-readtables-autoloads.el
@@ -0,0 +1,23 @@
+;;; sly-named-readtables-autoloads.el --- automatically extracted autoloads (do not edit)   -*- lexical-binding: t -*-
+;; Generated by the `loaddefs-generate' function.
+
+;; This file is part of GNU Emacs.
+
+;;; Code:
+
+(add-to-list 'load-path (or (and load-file-name (file-name-directory load-file-name)) (car load-path)))
+
+
+;;; End of scraped data
+
+(provide 'sly-named-readtables-autoloads)
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; no-native-compile: t
+;; coding: utf-8-emacs-unix
+;; End:
+
+;;; sly-named-readtables-autoloads.el ends here
blob - /dev/null
blob + fb882cf4ae3e3e4380503baa726978c00f82d849 (mode 644)
--- /dev/null
+++ elpa/sly-named-readtables-20191013.2138/sly-named-readtables-pkg.el
@@ -0,0 +1,14 @@
+(define-package "sly-named-readtables" "20191013.2138" "Support named readtables in Common Lisp files"
+  '((sly "1.0.0beta2"))
+  :commit "a5a42674ccffa97ccd5e4e9742beaf3ea719931f" :authors
+  '(("João Távora" . "joaotavora@gmail.com"))
+  :maintainers
+  '(("João Távora" . "joaotavora@gmail.com"))
+  :maintainer
+  '("João Távora" . "joaotavora@gmail.com")
+  :keywords
+  '("languages" "lisp" "sly")
+  :url "https://github.com/capitaomorte/sly-named-readtables")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
blob - /dev/null
blob + 14f8f8bb1b96febcd0f4f9b066436e38ba16b951 (mode 644)
--- /dev/null
+++ elpa/sly-named-readtables-20191013.2138/sly-named-readtables.el
@@ -0,0 +1,116 @@
+;;; sly-named-readtables.el --- Support named readtables in Common Lisp files  -*- lexical-binding: t; -*-
+;;
+;; Version: 0.1
+;; URL: https://github.com/capitaomorte/sly-named-readtables
+;; Keywords: languages, lisp, sly
+;; Package-Requires: ((sly "1.0.0-beta2"))
+;; Author: João Távora <joaotavora@gmail.com>
+;; 
+;; Copyright (C) 2015 João Távora
+;;
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+;;
+;;; Commentary:
+;;; 
+;; An external contrib for SLY that enables different readtables to be
+;; active in different parts of the same file. 
+;;
+;; SLY lives at https://github.com/capitaomorte/sly.
+;; 
+;;; Installation:
+;;
+;; Since this is an external contrib with both Elisp and Lisp parts,
+;; merely loading the Elisp will have little effect. The contrib has
+;; to be registered in SLY's `sly-contribs' variable for SLY to take care
+;; of loading the Lisp side on demand.
+;;
+;; For convenience, the `sly-named-readtables-autoloads.el' Elisp file
+;; takes care of this automatically. So in your `~/.emacs' or
+;; `~/.emacs.d/init/el' init file:
+;; 
+;; (setq inferior-lisp-program "/path/to/your/preferred/lisp")
+;; (add-to-list 'load-path "/path/to/sly")
+;; (require 'sly-autoloads)
+;;  
+;; (add-to-list 'load-path "/path/to/sly-named-readtables")
+;; (require 'sly-named-readtables-autoloads)
+;;
+;; In case you already have SLY loaded and/or running, you might have to
+;; `M-x sly-setup' and `M-x sly-enable-contrib' to enable it.
+;;  
+;; `sly-named-readtables' should now kick in in Lisp buffers. You must
+;; have `named-readtables` setup in your Lisp before it takes any actual
+;; effect though. That's easy, just `(ql:quickload :named-readtables)'.
+;; 
+;;; Code:
+
+(require 'sly)
+
+(define-sly-contrib sly-named-readtables
+  "Automatically parse in-readtable forms in Lisp buffers"
+  (:slynk-dependencies slynk-named-readtables)
+  (:on-load (add-hook 'sly-editing-mode-hook 'sly-named-readtables-mode))
+  (:on-unload (remove-hook 'sly-editing-mode-hook 'sly-named-readtables-mode)))
+
+(defun sly-named-readtable--pretty-name (name)
+  ;; Let's leave this abstraction in place for now...
+  name)
+
+(define-minor-mode sly-named-readtables-mode
+  "Use EDITOR-HINTS.NAMED-READTABLES if available."
+  nil nil nil
+  (cond (sly-named-readtables-mode
+         (add-to-list 'sly-extra-mode-line-constructs
+                      'sly-named-readtables--mode-line-construct
+                      t)
+         (add-to-list 'sly-rex-extra-options-functions
+                      'sly-named-readtables--pass-readtable
+                      t))
+        (t
+         (setq sly-extra-mode-line-constructs
+               (delq 'sly-named-readtables--mode-line-construct
+                     sly-extra-mode-line-constructs)
+               sly-rex-extra-options-functions
+               (delq 'sly-named-readtables--pass-readtable
+                     sly-rex-extra-options-functions)))))
+
+(defun sly-named-readtables--grok-current-table ()
+  (let ((case-fold-search t)
+        (regexp (concat "^(\\(named-readtables:\\)?in-readtable\\>[ \t\n]*"
+                        "\\([^)]+\\)[ \t]*)")))
+    (save-excursion
+      (when (re-search-backward regexp nil t)
+        (match-string-no-properties 2)))))
+
+(defun sly-named-readtables--mode-line-construct ()
+  (let ((readtable-name (sly-named-readtables--grok-current-table)))
+    `(:propertize ,(or (and readtable-name
+                            (sly-named-readtable--pretty-name readtable-name))
+                       "*")
+                  face ,(if readtable-name 'hi-pink 'sly-mode-line)
+                  mouse-face mode-line-highlight
+                  help-echo ,(if readtable-name
+                                 (format "Special NAMED-READTABLE %s" readtable-name)
+                               "Default readtable"))))
+
+(defun sly-named-readtables--pass-readtable ()
+  (list :named-readtable (sly-named-readtables--grok-current-table)))
+
+;;;###autoload
+(with-eval-after-load 'sly
+  (add-to-list 'sly-contribs 'sly-named-readtables 'append))
+
+(provide 'sly-named-readtables)
+;;; sly-named-readtables.el ends here
+
blob - /dev/null
blob + 9b510a7372ed671b4e864480b21e271c01f41b1f (mode 644)
--- /dev/null
+++ elpa/sly-named-readtables-20191013.2138/slynk-named-readtables.asd
@@ -0,0 +1,12 @@
+;;; -*- lisp -*-
+(in-package :asdf)
+
+(defsystem :slynk-named-readtables
+    :author "João Távora <https://github.com/capitaomorte>"
+    :depends-on (#:slynk)
+  :description "NAMED-READTABLES support for Slynk"
+  :components ((:file "slynk-named-readtables")))
+
+;; Local Variables:
+;; coding: utf-8
+;; End:
blob - /dev/null
blob + 4c63db97f0008101898c0abe46f2347b9c0cbd4f (mode 644)
--- /dev/null
+++ elpa/sly-named-readtables-20191013.2138/slynk-named-readtables.lisp
@@ -0,0 +1,38 @@
+(defpackage #:slynk-named-readtables (:use :cl #:slynk-api))
+(in-package #:slynk-named-readtables)
+
+(defvar *find-readtable-function* nil
+  "Function taking a string designating a readtable.
+The function should return a READTABLEP object")
+
+(defun find-readtable-by-name (string)
+  "Find a  readtable corresponding to STRING."
+  (when string
+    (if *find-readtable-function*
+        (funcall *find-readtable-function* string)
+        (let* ((find-readtable-fn (and (find-package :editor-hints.named-readtables)
+                                       (find-symbol "FIND-READTABLE" :editor-hints.named-readtables)))
+               (readtable-designator
+                 (and find-readtable-fn
+                      string
+                      (with-buffer-syntax ()
+                        (let ((*read-eval* nil))
+                          ;; JT@15/08/13: Perhaps READ-FROM-STRING is
+                          ;; questionable here...
+                          (read-from-string string))))))
+          (funcall find-readtable-fn readtable-designator)))))
+
+
+(defun wrap-in-named-readtable (in-function &key (named-readtable nil)
+                                &allow-other-keys)
+  "Wrap IN-FUNCTION in readtable named by NAMED-READTABLE, a string."
+  (let* ((guess (and named-readtable
+                     (find-readtable-by-name named-readtable))))
+    (lambda ()
+      (let ((*buffer-readtable* (or guess
+                                    *buffer-readtable*)))
+        (funcall in-function)))))
+
+(pushnew 'wrap-in-named-readtable *eval-for-emacs-wrappers*)
+
+(provide 'slynk-named-readtables)
blob - d98fa43a49f501f3c8bb5c2f25fb215e908e6e68
blob + 0f3334cf4049bc064729e71dffcdf518e29c21aa
--- init.el
+++ init.el
@@ -266,7 +266,7 @@
  ;; If you edit it by hand, you could mess it up, so be careful.
  ;; Your init file should contain only one such instance.
  ;; If there is more than one, they won't work right.
- '(auth-sources '("~/.authinfo.gpg"))
+ '(auth-sources '(default))
  '(aw-dispatch-always t)
  '(aw-keys '(97 115 100 102 103 104 106 107 108))
  '(aw-scope 'frame)
@@ -290,6 +290,8 @@
  '(cursor-type 'bar)
  '(delete-old-versions t)
  '(delete-selection-mode t)
+ '(denote-modules '(project xref ffap))
+ '(denote-modules-global-mode t)
  '(dired-dwim-target 'dired-dwim-target-next)
  '(dired-kill-when-opening-new-dired-buffer t)
  '(ediff-split-window-function 'split-window-horizontally)
@@ -353,7 +355,7 @@
      ("melpa-stable" . "https://stable.melpa.org/packages/")
      ("melpa" . "https://melpa.org/packages/")))
  '(package-selected-packages
-   '(denote-refs denote-menu denote ox-epub ob-powershell powershell web-mode lexic editorconfig elfeed-tube-mpv elfeed-tube cider restclient-jq graphviz-dot-mode consult-eglot jq-mode multiple-cursors ob-restclient restclient vterm deadgrep helpful pdf-tools paredit-menu paredit corfu sly eglot aggressive-indent project nov nhexl-mode elfeed magit yaml-mode json-mode lua-mode go-mode geiser-guile geiser org-contrib org ace-window expand-region consult marginalia uuidgen request diminish which-key))
+   '(sly-named-readtables sly-macrostep denote-refs denote-menu denote ox-epub ob-powershell powershell web-mode lexic editorconfig elfeed-tube-mpv elfeed-tube cider restclient-jq graphviz-dot-mode consult-eglot jq-mode multiple-cursors ob-restclient restclient vterm deadgrep helpful pdf-tools paredit-menu paredit corfu sly eglot aggressive-indent project nov nhexl-mode elfeed magit yaml-mode json-mode lua-mode go-mode geiser-guile geiser org-contrib org ace-window expand-region consult marginalia uuidgen request diminish which-key))
  '(pcomplete-ignore-case t t)
  '(pixel-scroll-precision-mode t)
  '(read-buffer-completion-ignore-case t)
@@ -430,3 +432,4 @@
 (pdf-loader-install)
 
 (server-start)
+(put 'narrow-to-region 'disabled nil)