dotemacs

My Emacs configuration
git clone git://git.entf.net/dotemacs
Log | Files | Refs | LICENSE

commit 7fdb3009f91eed630dc39ff7de765bf6cc16d691
parent 9b6354fcc7a6867dac04257ace00b9d8e18bb17f
Author: Lukas Henkel <lh@entf.net>
Date:   Mon, 26 Jun 2023 20:22:52 +0200

sly contribs

Diffstat:
Aelpa/macrostep-0.9.2.signed | 2++
Aelpa/macrostep-0.9.2/.elpaignore | 2++
Aelpa/macrostep-0.9.2/Makefile | 17+++++++++++++++++
Aelpa/macrostep-0.9.2/README-elpa | 235+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/macrostep-0.9.2/README.org | 203+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/macrostep-0.9.2/macrostep-autoloads.el | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/macrostep-0.9.2/macrostep-c.el | 183+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/macrostep-0.9.2/macrostep-pkg.el | 2++
Aelpa/macrostep-0.9.2/macrostep.el | 1125++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/sly-macrostep-20191211.1630/collect-macro-forms.lisp | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/sly-macrostep-20191211.1630/package.lisp | 22++++++++++++++++++++++
Aelpa/sly-macrostep-20191211.1630/sly-macrostep-autoloads.el | 40++++++++++++++++++++++++++++++++++++++++
Aelpa/sly-macrostep-20191211.1630/sly-macrostep-pkg.el | 9+++++++++
Aelpa/sly-macrostep-20191211.1630/sly-macrostep.el | 147+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/sly-macrostep-20191211.1630/slynk-macrostep.asd | 14++++++++++++++
Aelpa/sly-macrostep-20191211.1630/slynk-macrostep.lisp | 215+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/sly-named-readtables-20191013.2138/example.lisp | 24++++++++++++++++++++++++
Aelpa/sly-named-readtables-20191013.2138/sly-named-readtables-autoloads.el | 23+++++++++++++++++++++++
Aelpa/sly-named-readtables-20191013.2138/sly-named-readtables-pkg.el | 14++++++++++++++
Aelpa/sly-named-readtables-20191013.2138/sly-named-readtables.el | 116+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/sly-named-readtables-20191013.2138/slynk-named-readtables.asd | 12++++++++++++
Aelpa/sly-named-readtables-20191013.2138/slynk-named-readtables.lisp | 38++++++++++++++++++++++++++++++++++++++
Minit.el | 7+++++--
23 files changed, 2580 insertions(+), 2 deletions(-)

diff --git a/elpa/macrostep-0.9.2.signed b/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 diff --git a/elpa/macrostep-0.9.2/.elpaignore b/elpa/macrostep-0.9.2/.elpaignore @@ -0,0 +1,2 @@ +.travis.yml +LICENSE diff --git a/elpa/macrostep-0.9.2/Makefile b/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 diff --git a/elpa/macrostep-0.9.2/README-elpa b/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. diff --git a/elpa/macrostep-0.9.2/README.org b/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 diff --git a/elpa/macrostep-0.9.2/macrostep-autoloads.el b/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 diff --git a/elpa/macrostep-0.9.2/macrostep-c.el b/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 diff --git a/elpa/macrostep-0.9.2/macrostep-pkg.el b/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") diff --git a/elpa/macrostep-0.9.2/macrostep.el b/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 diff --git a/elpa/sly-macrostep-20191211.1630/collect-macro-forms.lisp b/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)))) diff --git a/elpa/sly-macrostep-20191211.1630/package.lisp b/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)) + diff --git a/elpa/sly-macrostep-20191211.1630/sly-macrostep-autoloads.el b/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 diff --git a/elpa/sly-macrostep-20191211.1630/sly-macrostep-pkg.el b/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: diff --git a/elpa/sly-macrostep-20191211.1630/sly-macrostep.el b/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 diff --git a/elpa/sly-macrostep-20191211.1630/slynk-macrostep.asd b/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: diff --git a/elpa/sly-macrostep-20191211.1630/slynk-macrostep.lisp b/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) diff --git a/elpa/sly-named-readtables-20191013.2138/example.lisp b/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) diff --git a/elpa/sly-named-readtables-20191013.2138/sly-named-readtables-autoloads.el b/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 diff --git a/elpa/sly-named-readtables-20191013.2138/sly-named-readtables-pkg.el b/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: diff --git a/elpa/sly-named-readtables-20191013.2138/sly-named-readtables.el b/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 + diff --git a/elpa/sly-named-readtables-20191013.2138/slynk-named-readtables.asd b/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: diff --git a/elpa/sly-named-readtables-20191013.2138/slynk-named-readtables.lisp b/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) diff --git a/init.el b/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)