GithubHelp home page GithubHelp logo

moldable-emacs's People

Contributors

ag91 avatar alanz avatar ikappaki avatar tychobrailleur avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

moldable-emacs's Issues

Namespace prefixes & Style: Opinion? Standard?

I am not completely sure about this, but I think emacs states that you should use hyphens and not forward slashes to prefix your namespace:

https://www.gnu.org/software/emacs/manual/html_node/elisp/Coding-Conventions.html#Coding-Conventions

You should choose a short word to distinguish your program from other Lisp programs. The names of all global symbols in your program, that is the names of variables, constants, and functions, should begin with that chosen prefix. Separate the prefix from the rest of the name with a hyphen, ‘-’. This practice helps avoid name conflicts, since all global variables in Emacs Lisp share the same name space, and all functions share another name space26. Use two hyphens to separate prefix and name if the symbol is not meant to be used by other packages.

I know there are some packages that use the forward slash, but I'm unsure if this is just preference or goes against the accepted style guidelines. Personally, I am always a bit surprised when I use a package that uses hyphens forward-slashes.

I'm wondering how you would feel about switching?

EDIT: I switched the source of my surprise around. Forward-slashes surprise me, not hyphens!

Issue with running CodeAsTree mold on process buffer

Hi,

I've tried to follow the steps in capture links from html with playground but noticed the html to tree source step failing with the following error:

Wrong type argument: arrayp, nil.

Steps to reproduce:

  1. Follow instructions from the article to retrieve the html from the nyxt articles page (I've introduced the additional (tree-sitter-mode) line):
(progn
  (switch-to-buffer (url-retrieve-synchronously "https://nyxt.atlas.engineer/articles"))
  (goto-char (point-min))
  (delete-region (point-min) url-http-end-of-headers)
  (html-mode)
  (tree-sitter-mode))
  1. M-x me-mold RET and select CodeAsTree give the above error.

The issue appears to be related with the mold trying to use the non-existant buffer file name from the async process.

Patch to follow.

Issues with tutorial ListCurrentEmacsBuffersAndSizesInBarChart.org

invoke M-x and type me/mold

I guess it is me-mold instead

type “Playground”

I get

Warning (emacs): Mold nil has no examples! Would you mind to add one?
You can use TODO now to add the last usage as an example

and no buffer opens. After reading the README, I realize I needed to do (me-setup-molds). You might want to repeat it in the tutorial if it is meant for new users.

type “PlistToBarChart” and hit return

I get an error about missing csv-mode. You might want to add csv-mode to prerequisites.

Installation with straight.el / use-pacakge

Hello! I use straight.el with its use-package integration to install my packages. However, it seems to not be loading things properly: for instance, when I try the Stats mold, I get Symbol's function definition is void: incf.

Here's my configuration:

(use-package moldable-emacs
  :straight (:host github :repo "ag91/moldable-emacs"
                   :files (("molds/" . "molds/")
                           ("tutorials/" . "tutorials/")
                           :defaults))
  :bind (("C-c m m" . me-mold)
       ("C-c m f" . me-go-forward)
       ("C-c m b" . me-go-back)
       ("C-c m o" . me-open-at-point)
       ("C-c m d" . me-mold-docs)
       ("C-c m e a" . me-mold-add-last-example))
  :config (me-setup-molds))

Thanks!

Readme improvements

Hi, I have read several blog posts about this package and watched several videos and I still have hard time understanding what this package does. There were several good pieces of advice on reddit which are mostly related to blog posts. I'd like to help making this readme more understandable by providing some observations I have.

  1. The word "story" is over-used. It is used in BDD, Storybook and probably in more places. The common thing I find across all of them is that the word "story" is a bad analogy for technical people which makes it hard to understand what it really does, but apparently it is a very easy to grasp analogy for non-technical people who don't need to understand what it really is. Current readme seems to use this word in a similar fashion "You have a story in mind", with an example story “Given a code buffer, I want to see duplicated code because I copy-pasted a lot and I want to cleanup.”. If we were to give a definition of this sample "story", I would say it is "What I want to do" + "What I need to have already" or in technical terms function + precondition. Immediate solution might be to remove the word "story" and describe it without any analogies, just say what it really is.
  2. I think an important question the readme should address is how this package is better than other similar solutions. What even are similar solutions? Readme should specify similar concepts so we, humans, can build our understanding upon some previous knowledge we have with similar tools. I don't believe this package realizes a unique idea that has never been invented before even approximately or badly.
  3. I can summarize my current misunderstanding in a simple question: "how is this different from just a function with a precondition?". I will provide some examples from the readme:
    • "Molds “mold” the data in your context into the data of your result" - this is exactly what a pure function does, transforms data from one form to another form
    • "The power of moldable-emacs is to make this micro-tools highly composable" - pure functions are highly composable, probably no need to comment further

I used the term "pure function" because it is not strictly true for non-pure functions. But if we speak in terms of Emacs, "creating a buffer with some text" might as well qualify as "pure" in certain contexts, and I believe this is also the main point of this package that we use Emacs buffers as input and output of the functions.

Excited but lost

Hi,

coming from the Pharo community, I know where this project comes from and I'm excited. Unfortunately, I don't find enough information on your blog or on this repository to get started and understand what can be done. I think a step-by-step tutorial would really help.

Thank you

WhatMoldsCanIUse? gives backtrace

Invoking the mold WhatMoldsCanIUse? gives the following backtrace

Debugger entered--Lisp error: (void-variable it)
  (eval it)
  (not (eval it))
  (cond ((equal '((not (eval it))) '(:given)) (and (eq major-mode 'lisp-mode) (me-require 'emacs-with-nyxt) (emacs-with-nyxt-connected-p) (emacs-with-nyxt-send-sexps '(find-mode (current-buffer) 'web-mode)) (thunk-force tree-thunk))) ((equal '((not (eval it))) '(:then)) (progn (get-buffer-create buffername) (let* ((result (let (...) (let ... ...)))) (save-current-buffer (set-buffer buffername) (emacs-lisp-mode) (erase-buffer) (me-print-to-buffer result) (set (make-local-variable 'self) result))) (condition-case nil (progn (switch-to-buffer-other-window (get-buffer buffername))) (error nil)))) (t (not (eval it))))
  (cl-symbol-macrolet ((tree (thunk-force tree-thunk))) (pcase '((not (eval it))) ('(:given) (and (eq major-mode 'lisp-mode) (me-require 'emacs-with-nyxt) (emacs-with-nyxt-connected-p) (emacs-with-nyxt-send-sexps '(find-mode (current-buffer) 'web-mode)) tree)) ('(:then) (progn (get-buffer-create buffername) (let* ((result (--> ... ... ... ... ... ... ...))) (with-current-buffer buffername (emacs-lisp-mode) (erase-buffer) (me-print-to-buffer result) (setq-local self result))) (ignore-errors (switch-to-buffer-other-window (get-buffer buffername))))) (_ (not (eval it)))))
  (let ((tree-thunk (thunk-delay (progn (unless (list-at-point) (progn (goto-char ...) (search-forward "(" nil t))) (or (ignore-errors (eval ...)) (list-at-point)))))) (cl-symbol-macrolet ((tree (thunk-force tree-thunk))) (pcase '((not (eval it))) ('(:given) (and (eq major-mode 'lisp-mode) (me-require 'emacs-with-nyxt) (emacs-with-nyxt-connected-p) (emacs-with-nyxt-send-sexps '(find-mode ... ...)) tree)) ('(:then) (progn (get-buffer-create buffername) (let* ((result ...)) (with-current-buffer buffername (emacs-lisp-mode) (erase-buffer) (me-print-to-buffer result) (setq-local self result))) (ignore-errors (switch-to-buffer-other-window (get-buffer buffername))))) (_ (not (eval it))))))
  (thunk-let ((tree (progn (unless (list-at-point) (progn (goto-char (point-min)) (search-forward "(" nil t))) (or (ignore-errors (eval (list-at-point))) (list-at-point))))) (pcase '((not (eval it))) ('(:given) (and (eq major-mode 'lisp-mode) (me-require 'emacs-with-nyxt) (emacs-with-nyxt-connected-p) (emacs-with-nyxt-send-sexps '(find-mode (current-buffer) 'web-mode)) tree)) ('(:then) (progn (get-buffer-create buffername) (let* ((result (--> ... ... ... ... ... ... ...))) (with-current-buffer buffername (emacs-lisp-mode) (erase-buffer) (me-print-to-buffer result) (setq-local self result))) (ignore-errors (switch-to-buffer-other-window (get-buffer buffername))))) (_ (not (eval it)))))
  (thunk-let* ((tree (progn (unless (list-at-point) (progn (goto-char (point-min)) (search-forward "(" nil t))) (or (ignore-errors (eval (list-at-point))) (list-at-point))))) (pcase '((not (eval it))) ('(:given) (and (eq major-mode 'lisp-mode) (me-require 'emacs-with-nyxt) (emacs-with-nyxt-connected-p) (emacs-with-nyxt-send-sexps '(find-mode (current-buffer) 'web-mode)) tree)) ('(:then) (progn (get-buffer-create buffername) (let* ((result (--> ... ... ... ... ... ... ...))) (with-current-buffer buffername (emacs-lisp-mode) (erase-buffer) (me-print-to-buffer result) (setq-local self result))) (ignore-errors (switch-to-buffer-other-window (get-buffer buffername))))) (_ (not (eval it)))))
  (let ((buffername (concat "*moldable-emacs-" (or nil "Eval Parenscript with Nyxt") "*"))) (thunk-let* ((tree (progn (unless (list-at-point) (progn (goto-char ...) (search-forward "(" nil t))) (or (ignore-errors (eval ...)) (list-at-point))))) (pcase '((not (eval it))) ('(:given) (and (eq major-mode 'lisp-mode) (me-require 'emacs-with-nyxt) (emacs-with-nyxt-connected-p) (emacs-with-nyxt-send-sexps '(find-mode ... ...)) tree)) ('(:then) (progn (get-buffer-create buffername) (let* ((result ...)) (with-current-buffer buffername (emacs-lisp-mode) (erase-buffer) (me-print-to-buffer result) (setq-local self result))) (ignore-errors (switch-to-buffer-other-window (get-buffer buffername))))) (_ (not (eval it))))))
  (progn (let ((buffername (concat "*moldable-emacs-" (or nil "Eval Parenscript with Nyxt") "*"))) (thunk-let* ((tree (progn (unless (list-at-point) (progn ... ...)) (or (ignore-errors ...) (list-at-point))))) (pcase '((not (eval it))) ('(:given) (and (eq major-mode 'lisp-mode) (me-require 'emacs-with-nyxt) (emacs-with-nyxt-connected-p) (emacs-with-nyxt-send-sexps '...) tree)) ('(:then) (progn (get-buffer-create buffername) (let* (...) (with-current-buffer buffername ... ... ... ...)) (ignore-errors (switch-to-buffer-other-window ...)))) (_ (not (eval it)))))))
  eval((progn (let ((buffername (concat "*moldable-emacs-" (or nil "Eval Parenscript with Nyxt") "*"))) (thunk-let* ((tree (progn (unless ... ...) (or ... ...)))) (pcase '((not ...)) ('(:given) (and (eq major-mode ...) (me-require ...) (emacs-with-nyxt-connected-p) (emacs-with-nyxt-send-sexps ...) tree)) ('(:then) (progn (get-buffer-create buffername) (let* ... ...) (ignore-errors ...))) (_ (not (eval it))))))) t)
  (closure ((it-index . 1) (it me-require 'emacs-with-nyxt) (i . 2) (list (emacs-with-nyxt-connected-p) (emacs-with-nyxt-send-sexps '(find-mode (current-buffer) 'web-mode)) tree) (result) (it (eq major-mode 'lisp-mode) (me-require 'emacs-with-nyxt) (emacs-with-nyxt-connected-p) (emacs-with-nyxt-send-sexps '(find-mode (current-buffer) 'web-mode)) tree) (given-cond and (eq major-mode 'lisp-mode) (me-require 'emacs-with-nyxt) (emacs-with-nyxt-connected-p) (emacs-with-nyxt-send-sexps '(find-mode (current-buffer) 'web-mode)) tree) (mold :key "Eval Parenscript with Nyxt" :let ((tree (progn (unless ... ...) (or ... ...)))) :given (:fn (and (eq major-mode 'lisp-mode) (me-require 'emacs-with-nyxt) (emacs-with-nyxt-connected-p) (emacs-with-nyxt-send-sexps '...) tree)) :then (:fn (let* ((result ...)) (with-current-buffer buffername (emacs-lisp-mode) (erase-buffer) (me-print-to-buffer result) (setq-local self result)))) :docs "You can evaluate some Parenscript in the current b..." :examples nil :origin "/home/alanz/.emacs.d/elpa/moldable-emacs-20211125....") t) (m clause) (eval (list 'progn (list 'let (list (list 'buffername (cons ... ...))) (list (if (condition-case nil ... ...) 'let* 'thunk-let*) (plist-get m :let) (list 'pcase (list ... clause) (list ... ...) (list ... ...) (cons ... clause))))) 't))((:key "Eval Parenscript with Nyxt" :let ((tree (progn (unless (list-at-point) (progn (goto-char ...) (search-forward "(" nil t))) (or (ignore-errors (eval ...)) (list-at-point))))) :given (:fn (and (eq major-mode 'lisp-mode) (me-require 'emacs-with-nyxt) (emacs-with-nyxt-connected-p) (emacs-with-nyxt-send-sexps '(find-mode (current-buffer) 'web-mode)) tree)) :then (:fn (let* ((result (--> (emacs-with-nyxt-send-sexps ...) (string-reverse it) (s-split " ," it) (-drop 1 it) (s-join " ," it) (string-reverse it) (read it)))) (with-current-buffer buffername (emacs-lisp-mode) (erase-buffer) (me-print-to-buffer result) (setq-local self result)))) :docs "You can evaluate some Parenscript in the current b..." :examples nil :origin "/home/alanz/.emacs.d/elpa/moldable-emacs-20211125....") ((not (eval it))))
  funcall((closure ((it-index . 1) (it me-require 'emacs-with-nyxt) (i . 2) (list (emacs-with-nyxt-connected-p) (emacs-with-nyxt-send-sexps '(find-mode (current-buffer) 'web-mode)) tree) (result) (it (eq major-mode 'lisp-mode) (me-require 'emacs-with-nyxt) (emacs-with-nyxt-connected-p) (emacs-with-nyxt-send-sexps '(find-mode (current-buffer) 'web-mode)) tree) (given-cond and (eq major-mode 'lisp-mode) (me-require 'emacs-with-nyxt) (emacs-with-nyxt-connected-p) (emacs-with-nyxt-send-sexps '(find-mode (current-buffer) 'web-mode)) tree) (mold :key "Eval Parenscript with Nyxt" :let ((tree (progn (unless ... ...) (or ... ...)))) :given (:fn (and (eq major-mode 'lisp-mode) (me-require 'emacs-with-nyxt) (emacs-with-nyxt-connected-p) (emacs-with-nyxt-send-sexps '...) tree)) :then (:fn (let* ((result ...)) (with-current-buffer buffername (emacs-lisp-mode) (erase-buffer) (me-print-to-buffer result) (setq-local self result)))) :docs "You can evaluate some Parenscript in the current b..." :examples nil :origin "/home/alanz/.emacs.d/elpa/moldable-emacs-20211125....") t) (m clause) (eval (list 'progn (list 'let (list (list 'buffername (cons ... ...))) (list (if (condition-case nil ... ...) 'let* 'thunk-let*) (plist-get m :let) (list 'pcase (list ... clause) (list ... ...) (list ... ...) (cons ... clause))))) 't)) (:key "Eval Parenscript with Nyxt" :let ((tree (progn (unless (list-at-point) (progn (goto-char ...) (search-forward "(" nil t))) (or (ignore-errors (eval ...)) (list-at-point))))) :given (:fn (and (eq major-mode 'lisp-mode) (me-require 'emacs-with-nyxt) (emacs-with-nyxt-connected-p) (emacs-with-nyxt-send-sexps '(find-mode (current-buffer) 'web-mode)) tree)) :then (:fn (let* ((result (--> (emacs-with-nyxt-send-sexps ...) (string-reverse it) (s-split " ," it) (-drop 1 it) (s-join " ," it) (string-reverse it) (read it)))) (with-current-buffer buffername (emacs-lisp-mode) (erase-buffer) (me-print-to-buffer result) (setq-local self result)))) :docs "You can evaluate some Parenscript in the current b..." :examples nil :origin "/home/alanz/.emacs.d/elpa/moldable-emacs-20211125....") ((not (eval it))))
  (and (seqp it) (-contains\? it 'me-require) (funcall #'(lambda (m clause) (eval (list 'progn (list 'let (list ...) (list ... ... ...))) 't)) mold '((not (eval it)))))
  (or (and (seqp it) (-contains\? it 'executable-find) (funcall #'(lambda (m clause) (eval (list 'progn (list ... ... ...)) 't)) mold '((not (eval it))))) (and (seqp it) (-contains\? it 'me-require) (funcall #'(lambda (m clause) (eval (list 'progn (list ... ... ...)) 't)) mold '((not (eval it))))))
  (if (or (and (seqp it) (-contains\? it 'executable-find) (funcall #'(lambda (m clause) (eval (list ... ...) 't)) mold '((not (eval it))))) (and (seqp it) (-contains\? it 'me-require) (funcall #'(lambda (m clause) (eval (list ... ...) 't)) mold '((not (eval it)))))) (progn (setq result (cons it result))))
  (while list (setq it (car-safe (prog1 list (setq list (cdr list)))) it-index i i (1+ i)) (if (or (and (seqp it) (-contains\? it 'executable-find) (funcall #'(lambda (m clause) (eval ... ...)) mold '((not ...)))) (and (seqp it) (-contains\? it 'me-require) (funcall #'(lambda (m clause) (eval ... ...)) mold '((not ...))))) (progn (setq result (cons it result)))))
  (let ((list it) (i 0) it it-index) (ignore it it-index) (while list (setq it (car-safe (prog1 list (setq list (cdr list)))) it-index i i (1+ i)) (if (or (and (seqp it) (-contains\? it 'executable-find) (funcall #'(lambda ... ...) mold '(...))) (and (seqp it) (-contains\? it 'me-require) (funcall #'(lambda ... ...) mold '(...)))) (progn (setq result (cons it result))))))
  (let (result) (let ((list it) (i 0) it it-index) (ignore it it-index) (while list (setq it (car-safe (prog1 list (setq list (cdr list)))) it-index i i (1+ i)) (if (or (and (seqp it) (-contains\? it 'executable-find) (funcall #'... mold '...)) (and (seqp it) (-contains\? it 'me-require) (funcall #'... mold '...))) (progn (setq result (cons it result)))))) (nreverse result))
  (let ((it (cdr given-cond))) (let (result) (let ((list it) (i 0) it it-index) (ignore it it-index) (while list (setq it (car-safe (prog1 list (setq list ...))) it-index i i (1+ i)) (if (or (and (seqp it) (-contains\? it ...) (funcall ... mold ...)) (and (seqp it) (-contains\? it ...) (funcall ... mold ...))) (progn (setq result (cons it result)))))) (nreverse result)))
  (and (condition-case nil (progn (> (length given-cond) 1)) (error nil)) (eq (car given-cond) 'and) (let ((it (cdr given-cond))) (let (result) (let ((list it) (i 0) it it-index) (ignore it it-index) (while list (setq it (car-safe (prog1 list ...)) it-index i i (1+ i)) (if (or (and ... ... ...) (and ... ... ...)) (progn (setq result ...))))) (nreverse result))))
  (list :key (plist-get mold :key) :missing-dependencies (and (condition-case nil (progn (> (length given-cond) 1)) (error nil)) (eq (car given-cond) 'and) (let ((it (cdr given-cond))) (let (result) (let ((list it) (i 0) it it-index) (ignore it it-index) (while list (setq it (car-safe ...) it-index i i (1+ i)) (if (or ... ...) (progn ...)))) (nreverse result)))))
  (let ((given-cond (me-get-in mold '(:given :fn)))) (list :key (plist-get mold :key) :missing-dependencies (and (condition-case nil (progn (> (length given-cond) 1)) (error nil)) (eq (car given-cond) 'and) (let ((it (cdr given-cond))) (let (result) (let ((list it) (i 0) it it-index) (ignore it it-index) (while list (setq it ... it-index i i ...) (if ... ...))) (nreverse result))))))
  me-find-missing-dependencies-for-mold((:key "Eval Parenscript with Nyxt" :let ((tree (progn (unless (list-at-point) (progn (goto-char ...) (search-forward "(" nil t))) (or (ignore-errors (eval ...)) (list-at-point))))) :given (:fn (and (eq major-mode 'lisp-mode) (me-require 'emacs-with-nyxt) (emacs-with-nyxt-connected-p) (emacs-with-nyxt-send-sexps '(find-mode (current-buffer) 'web-mode)) tree)) :then (:fn (let* ((result (--> (emacs-with-nyxt-send-sexps ...) (string-reverse it) (s-split " ," it) (-drop 1 it) (s-join " ," it) (string-reverse it) (read it)))) (with-current-buffer buffername (emacs-lisp-mode) (erase-buffer) (me-print-to-buffer result) (setq-local self result)))) :docs "You can evaluate some Parenscript in the current b..." :examples nil :origin "/home/alanz/.emacs.d/elpa/moldable-emacs-20211125...."))
  mapcar(me-find-missing-dependencies-for-mold ((:key "Eval Parenscript wit..." :let ... :given ... :then ... :docs "You can evaluate som..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "Playground Parenscri..." :given ... :then ... :docs "You can write some P..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "Eval JS with Nyxt" :given ... :then ... :docs "You can evaluate som..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "Playground JS with N..." :given ... :then ... :docs "You can write some J..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "List To Picture" :given ... :then ... :origin "/home/alanz/.emacs.d...") (:key "List To Dot" :let ... :given ... :then ... :docs "You can transform a ..." :examples ... :origin "/home/alanz/.emacs.d...") (:key "Audit with Lighthous..." :let ... :given ... :then ... :docs "You can audit a url ..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "Eval With Clojure" :given ... :then ... :docs "You can evaluate the..." :examples ... :origin "/home/alanz/.emacs.d...") (:key "Playground Clojure" :given ... :then ... :docs "You can play around ..." :examples ... :origin "/home/alanz/.emacs.d...") (:key "EdnToElisp" :let ... :given ... :then ... :docs "You can parse EDN fo..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "Clojure examples for..." :let ... :given ... :then ... :docs "You can list example..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "Files To Edit As Org..." :let ... :given ... :then ... :docs "You can make a TODO ..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "List Files To Edit A..." :let ... :given ... :then ... :docs "You can list the fil..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "Image To Text" :docs "Extracts text from t..." :let ... :given ... :then ... :examples ... :origin "/home/alanz/.emacs.d...") (:key "OrgTablesToDotPictur..." :given ... :then ... :docs "Make a graph image o..." :origin "/home/alanz/.emacs.d...") (:key "DotToPicture" :given ... :then ... :docs "Convert Graphviz dot..." :origin "/home/alanz/.emacs.d...") (:key "OrgTablesToDot" :let ... :given ... :then ... :docs "Convert Org tables t..." :origin "/home/alanz/.emacs.d...") (:key "FunctionsComplexity" :let ... :given ... :then ... :docs "Show a table showing..." :origin "/home/alanz/.emacs.d...") (:key "PlistToLineChart" :given ... :then ... :docs "Make a line chart ou..." :origin "/home/alanz/.emacs.d...") (:key "PlistToBarChart" :given ... :then ... :docs "Make a bar chart out..." :origin "/home/alanz/.emacs.d...") ...))
  -map(me-find-missing-dependencies-for-mold ((:key "Eval Parenscript wit..." :let ... :given ... :then ... :docs "You can evaluate som..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "Playground Parenscri..." :given ... :then ... :docs "You can write some P..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "Eval JS with Nyxt" :given ... :then ... :docs "You can evaluate som..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "Playground JS with N..." :given ... :then ... :docs "You can write some J..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "List To Picture" :given ... :then ... :origin "/home/alanz/.emacs.d...") (:key "List To Dot" :let ... :given ... :then ... :docs "You can transform a ..." :examples ... :origin "/home/alanz/.emacs.d...") (:key "Audit with Lighthous..." :let ... :given ... :then ... :docs "You can audit a url ..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "Eval With Clojure" :given ... :then ... :docs "You can evaluate the..." :examples ... :origin "/home/alanz/.emacs.d...") (:key "Playground Clojure" :given ... :then ... :docs "You can play around ..." :examples ... :origin "/home/alanz/.emacs.d...") (:key "EdnToElisp" :let ... :given ... :then ... :docs "You can parse EDN fo..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "Clojure examples for..." :let ... :given ... :then ... :docs "You can list example..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "Files To Edit As Org..." :let ... :given ... :then ... :docs "You can make a TODO ..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "List Files To Edit A..." :let ... :given ... :then ... :docs "You can list the fil..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "Image To Text" :docs "Extracts text from t..." :let ... :given ... :then ... :examples ... :origin "/home/alanz/.emacs.d...") (:key "OrgTablesToDotPictur..." :given ... :then ... :docs "Make a graph image o..." :origin "/home/alanz/.emacs.d...") (:key "DotToPicture" :given ... :then ... :docs "Convert Graphviz dot..." :origin "/home/alanz/.emacs.d...") (:key "OrgTablesToDot" :let ... :given ... :then ... :docs "Convert Org tables t..." :origin "/home/alanz/.emacs.d...") (:key "FunctionsComplexity" :let ... :given ... :then ... :docs "Show a table showing..." :origin "/home/alanz/.emacs.d...") (:key "PlistToLineChart" :given ... :then ... :docs "Make a line chart ou..." :origin "/home/alanz/.emacs.d...") (:key "PlistToBarChart" :given ... :then ... :docs "Make a bar chart out..." :origin "/home/alanz/.emacs.d...") ...))
  me-find-missing-dependencies-for-molds(((:key "Eval Parenscript wit..." :let ... :given ... :then ... :docs "You can evaluate som..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "Playground Parenscri..." :given ... :then ... :docs "You can write some P..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "Eval JS with Nyxt" :given ... :then ... :docs "You can evaluate som..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "Playground JS with N..." :given ... :then ... :docs "You can write some J..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "List To Picture" :given ... :then ... :origin "/home/alanz/.emacs.d...") (:key "List To Dot" :let ... :given ... :then ... :docs "You can transform a ..." :examples ... :origin "/home/alanz/.emacs.d...") (:key "Audit with Lighthous..." :let ... :given ... :then ... :docs "You can audit a url ..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "Eval With Clojure" :given ... :then ... :docs "You can evaluate the..." :examples ... :origin "/home/alanz/.emacs.d...") (:key "Playground Clojure" :given ... :then ... :docs "You can play around ..." :examples ... :origin "/home/alanz/.emacs.d...") (:key "EdnToElisp" :let ... :given ... :then ... :docs "You can parse EDN fo..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "Clojure examples for..." :let ... :given ... :then ... :docs "You can list example..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "Files To Edit As Org..." :let ... :given ... :then ... :docs "You can make a TODO ..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "List Files To Edit A..." :let ... :given ... :then ... :docs "You can list the fil..." :examples nil :origin "/home/alanz/.emacs.d...") (:key "Image To Text" :docs "Extracts text from t..." :let ... :given ... :then ... :examples ... :origin "/home/alanz/.emacs.d...") (:key "OrgTablesToDotPictur..." :given ... :then ... :docs "Make a graph image o..." :origin "/home/alanz/.emacs.d...") (:key "DotToPicture" :given ... :then ... :docs "Convert Graphviz dot..." :origin "/home/alanz/.emacs.d...") (:key "OrgTablesToDot" :let ... :given ... :then ... :docs "Convert Org tables t..." :origin "/home/alanz/.emacs.d...") (:key "FunctionsComplexity" :let ... :given ... :then ... :docs "Show a table showing..." :origin "/home/alanz/.emacs.d...") (:key "PlistToLineChart" :given ... :then ... :docs "Make a line chart ou..." :origin "/home/alanz/.emacs.d...") (:key "PlistToBarChart" :given ... :then ... :docs "Make a bar chart out..." :origin "/home/alanz/.emacs.d...") ...))
  (let ((list (me-find-missing-dependencies-for-molds (me-usable-molds-requiring-deps))) (i 0) it it-index) (ignore it it-index) (while list (setq it (pop list) it-index i i (1+ i)) (when (plist-get it :missing-dependencies) (push it result))))
  (--each (me-find-missing-dependencies-for-molds (me-usable-molds-requiring-deps)) (when (plist-get it :missing-dependencies) (push it result)))
  (let (result) (--each (me-find-missing-dependencies-for-molds (me-usable-molds-requiring-deps)) (when (plist-get it :missing-dependencies) (push it result))) (nreverse result))
  (--filter (plist-get it :missing-dependencies) (me-find-missing-dependencies-for-molds (me-usable-molds-requiring-deps)))
  (let* ((molds (me-usable-molds)) (missing-deps-molds (--filter (plist-get it :missing-dependencies) (me-find-missing-dependencies-for-molds (me-usable-molds-requiring-deps))))) (with-current-buffer buffername (erase-buffer) (org-mode) (insert "* Molds you can use now.\n\n") (me-insert-org-table `(("Mold" :extractor (lambda (obj) (ignore-errors ...))) ("Demo" :extractor (lambda (obj) (plist-get obj :key)) :handler (lambda (s) (if ... ... "Not available."))) ("Documentation" :extractor (lambda (obj) (or ... "Not available.")) :handler (lambda (s) (car ...)))) molds) (when missing-deps-molds (insert "\n\n\n** Molds you could use by installing some extra...") (me-insert-org-table `(("Mold" :extractor (lambda ... ...)) ("Demo" :extractor (lambda ... ...) :handler (lambda ... ...)) ("Documentation" :extractor (lambda ... ...) :handler (lambda ... ...)) ("Required Dependencies" :extractor (lambda ... ...) :handler (lambda ... ...))) missing-deps-molds)) (setq-local self molds)))
  (progn (get-buffer-create buffername) (let* ((molds (me-usable-molds)) (missing-deps-molds (--filter (plist-get it :missing-dependencies) (me-find-missing-dependencies-for-molds (me-usable-molds-requiring-deps))))) (with-current-buffer buffername (erase-buffer) (org-mode) (insert "* Molds you can use now.\n\n") (me-insert-org-table `(("Mold" :extractor (lambda ... ...)) ("Demo" :extractor (lambda ... ...) :handler (lambda ... ...)) ("Documentation" :extractor (lambda ... ...) :handler (lambda ... ...))) molds) (when missing-deps-molds (insert "\n\n\n** Molds you could use by installing some extra...") (me-insert-org-table `(("Mold" :extractor ...) ("Demo" :extractor ... :handler ...) ("Documentation" :extractor ... :handler ...) ("Required Dependencies" :extractor ... :handler ...)) missing-deps-molds)) (setq-local self molds))) (ignore-errors (switch-to-buffer-other-window (get-buffer buffername))))
  (cond ((equal '(:then) '(:given)) t) ((equal '(:then) '(:then)) (progn (get-buffer-create buffername) (let* ((molds (me-usable-molds)) (missing-deps-molds (--filter (plist-get it :missing-dependencies) (me-find-missing-dependencies-for-molds ...)))) (with-current-buffer buffername (erase-buffer) (org-mode) (insert "* Molds you can use now.\n\n") (me-insert-org-table `(... ... ...) molds) (when missing-deps-molds (insert "\n\n\n** Molds you could use by installing some extra...") (me-insert-org-table `... missing-deps-molds)) (setq-local self molds))) (ignore-errors (switch-to-buffer-other-window (get-buffer buffername))))) (t :then))
  (pcase '(:then) ('(:given) t) ('(:then) (progn (get-buffer-create buffername) (let* ((molds (me-usable-molds)) (missing-deps-molds (--filter (plist-get it :missing-dependencies) (me-find-missing-dependencies-for-molds ...)))) (with-current-buffer buffername (erase-buffer) (org-mode) (insert "* Molds you can use now.\n\n") (me-insert-org-table `(... ... ...) molds) (when missing-deps-molds (insert "\n\n\n** Molds you could use by installing some extra...") (me-insert-org-table `... missing-deps-molds)) (setq-local self molds))) (ignore-errors (switch-to-buffer-other-window (get-buffer buffername))))) (_ :then))
  (let* nil (pcase '(:then) ('(:given) t) ('(:then) (progn (get-buffer-create buffername) (let* ((molds (me-usable-molds)) (missing-deps-molds (--filter ... ...))) (with-current-buffer buffername (erase-buffer) (org-mode) (insert "* Molds you can use now.\n\n") (me-insert-org-table `... molds) (when missing-deps-molds (insert "\n\n\n** Molds you could use by installing some extra...") (me-insert-org-table ... missing-deps-molds)) (setq-local self molds))) (ignore-errors (switch-to-buffer-other-window (get-buffer buffername))))) (_ :then)))
  (let ((buffername (concat "*moldable-emacs-" (or nil "WhatMoldsCanIUse?") "*"))) (let* nil (pcase '(:then) ('(:given) t) ('(:then) (progn (get-buffer-create buffername) (let* ((molds ...) (missing-deps-molds ...)) (with-current-buffer buffername (erase-buffer) (org-mode) (insert "* Molds you can use now.\n\n") (me-insert-org-table ... molds) (when missing-deps-molds ... ...) (setq-local self molds))) (ignore-errors (switch-to-buffer-other-window (get-buffer buffername))))) (_ :then))))
  (progn (let ((buffername (concat "*moldable-emacs-" (or nil "WhatMoldsCanIUse?") "*"))) (let* nil (pcase '(:then) ('(:given) t) ('(:then) (progn (get-buffer-create buffername) (let* (... ...) (with-current-buffer buffername ... ... ... ... ... ...)) (ignore-errors (switch-to-buffer-other-window ...)))) (_ :then)))))
  eval((progn (let ((buffername (concat "*moldable-emacs-" (or nil "WhatMoldsCanIUse?") "*"))) (let* nil (pcase '(:then) ('(:given) t) ('(:then) (progn (get-buffer-create buffername) (let* ... ...) (ignore-errors ...))) (_ :then))))) t)
  (closure ((mold :key "WhatMoldsCanIUse?" :given (:fn t) :then (:fn (let* ((molds ...) (missing-deps-molds ...)) (with-current-buffer buffername (erase-buffer) (org-mode) (insert "* Molds you can use now.\n\n") (me-insert-org-table ... molds) (when missing-deps-molds ... ...) (setq-local self molds)))) :docs "You can see examples and demos of the molds you ca..." :examples nil :origin "/home/alanz/.emacs.d/elpa/moldable-emacs-20211125....") t) (m clause) (eval (list 'progn (list 'let (list (list 'buffername (cons ... ...))) (list (if (condition-case nil ... ...) 'let* 'thunk-let*) (plist-get m :let) (list 'pcase (list ... clause) (list ... ...) (list ... ...) (cons ... clause))))) 't))((:key "WhatMoldsCanIUse?" :given (:fn t) :then (:fn (let* ((molds (me-usable-molds)) (missing-deps-molds (--filter (plist-get it :missing-dependencies) (me-find-missing-dependencies-for-molds ...)))) (with-current-buffer buffername (erase-buffer) (org-mode) (insert "* Molds you can use now.\n\n") (me-insert-org-table `(... ... ...) molds) (when missing-deps-molds (insert "\n\n\n** Molds you could use by installing some extra...") (me-insert-org-table `... missing-deps-molds)) (setq-local self molds)))) :docs "You can see examples and demos of the molds you ca..." :examples nil :origin "/home/alanz/.emacs.d/elpa/moldable-emacs-20211125....") (:then))
  funcall((closure ((mold :key "WhatMoldsCanIUse?" :given (:fn t) :then (:fn (let* ((molds ...) (missing-deps-molds ...)) (with-current-buffer buffername (erase-buffer) (org-mode) (insert "* Molds you can use now.\n\n") (me-insert-org-table ... molds) (when missing-deps-molds ... ...) (setq-local self molds)))) :docs "You can see examples and demos of the molds you ca..." :examples nil :origin "/home/alanz/.emacs.d/elpa/moldable-emacs-20211125....") t) (m clause) (eval (list 'progn (list 'let (list (list 'buffername (cons ... ...))) (list (if (condition-case nil ... ...) 'let* 'thunk-let*) (plist-get m :let) (list 'pcase (list ... clause) (list ... ...) (list ... ...) (cons ... clause))))) 't)) (:key "WhatMoldsCanIUse?" :given (:fn t) :then (:fn (let* ((molds (me-usable-molds)) (missing-deps-molds (--filter (plist-get it :missing-dependencies) (me-find-missing-dependencies-for-molds ...)))) (with-current-buffer buffername (erase-buffer) (org-mode) (insert "* Molds you can use now.\n\n") (me-insert-org-table `(... ... ...) molds) (when missing-deps-molds (insert "\n\n\n** Molds you could use by installing some extra...") (me-insert-org-table `... missing-deps-molds)) (setq-local self molds)))) :docs "You can see examples and demos of the molds you ca..." :examples nil :origin "/home/alanz/.emacs.d/elpa/moldable-emacs-20211125....") (:then))
  me-mold-run-then((:key "WhatMoldsCanIUse?" :given (:fn t) :then (:fn (let* ((molds (me-usable-molds)) (missing-deps-molds (--filter (plist-get it :missing-dependencies) (me-find-missing-dependencies-for-molds ...)))) (with-current-buffer buffername (erase-buffer) (org-mode) (insert "* Molds you can use now.\n\n") (me-insert-org-table `(... ... ...) molds) (when missing-deps-molds (insert "\n\n\n** Molds you could use by installing some extra...") (me-insert-org-table `... missing-deps-molds)) (setq-local self molds)))) :docs "You can see examples and demos of the molds you ca..." :examples nil :origin "/home/alanz/.emacs.d/elpa/moldable-emacs-20211125...."))
  (let ((it (funcall #'(lambda (mold) (let (... ... it it-index) (ignore it it-index) (while list ... ...)) mold) it))) (me-mold-run-then it))
  (let ((it (-find #'(lambda (x) (string= (plist-get x :key) it)) molds))) (let ((it (funcall #'(lambda (mold) (let ... ... ...) mold) it))) (me-mold-run-then it)))
  (let ((it (completing-read "Pick the mold you need:" it))) (let ((it (-find #'(lambda (x) (string= ... it)) molds))) (let ((it (funcall #'(lambda ... ... mold) it))) (me-mold-run-then it))))
  (let ((it keys)) (let ((it (completing-read "Pick the mold you need:" it))) (let ((it (-find #'(lambda ... ...) molds))) (let ((it (funcall #'... it))) (me-mold-run-then it)))))
  (let* ((beginning (current-time)) (molds (me-usable-molds)) (keys (mapcar #'(lambda (it) (ignore it) (plist-get it :key)) molds)) (ending (current-time)) (_ (if me-molds-debug-on (progn (message "Finding molds took %s seconds in total." (time-to-seconds (time-subtract ending beginning))))))) (let ((it keys)) (let ((it (completing-read "Pick the mold you need:" it))) (let ((it (-find #'... molds))) (let ((it (funcall ... it))) (me-mold-run-then it))))) (run-hooks 'me-mold-after-hook))
  me-mold()
  funcall-interactively(me-mold)
  call-interactively(me-mold nil nil)
  command-execute(me-mold)

Build Warnings & Errors

Hello! I am very excited by this work, and I wanted to try it out. To do so, I created a Guix package both because I use Guix and I wanted to start playing around, and because Guix builds in a clean-room environment and helps me to understand what software actually needs and does.

Here is the package definition:

(define-public emacs-moldable-emacs
  (let ((commit "0737b3aecc0afd6d59166563d566bbe1d322a9d2"))
    (package
      (name "emacs-moldable-emacs")
      (version (git-version "0.0.0" "1" commit))
      (source
       (origin
         (method git-fetch)
         (uri (git-reference
               (url "https://github.com/ag91/moldable-emacs")
               (commit commit)))
         (file-name (git-file-name name version))
         (sha256
          (base32 "0zlmv7qrjc01y0j3hrrw80r82z1a5l4ki3b8ldnq0qls61x1xwfy"))))
      (inputs
       `(("emacs-dash" ,emacs-dash)
         ("emacs-s" ,emacs-s)
         ("emacs-async" ,emacs-async)))
      (build-system emacs-build-system)
      (home-page "https://github.com/ag91/moldable-emacs")
      (synopsis "Adapting Emacs for moldable development ")
      (description
       "This is an extension of Emacs aiming to enable Moldable
Development. Or better still, aiming to make you a better story teller
when you deal with code.")
      (license license:gpl3+))))

Unfortunately I got a build error:

Build Log
The following derivation will be built:
   /gnu/store/g7r2bp615xf2b036wwyqgfi651yfsc2y-emacs-moldable-emacs-0.0.0-1.0737b3a.drv
building /gnu/store/g7r2bp615xf2b036wwyqgfi651yfsc2y-emacs-moldable-emacs-0.0.0-1.0737b3a.drv...
starting phase `set-SOURCE-DATE-EPOCH'
phase `set-SOURCE-DATE-EPOCH' succeeded after 0.0 seconds
starting phase `set-paths'
environment variable `PATH' set to `/gnu/store/6kfvm6qhm5g875jp34x84bgiffhwbyn9-emacs-minimal-27.2/bin:/gnu/store/v6f44zccwh9z5zk3pjlywjybbi8n2hjh-tar-1.32/bin:/gnu/store/ncydgq2znms5n1d2k5yqshhf58nsixwv-gzip-1.10/bin:/gnu/store/i8h2pcxqdq07ijm3ibkka8f4smn1w48v-bzip2-1.0.8/bin:/gnu/store/9860f1abqj8wjjnwl8a9v54pdcc3bhgf-xz-5.2.4/bin:/gnu/store/60g7r3l01fd7c58yjbm6krgcwj1jkpwg-file-5.38/bin:/gnu/store/n4n560pfvvw50a9369axw5vj5rrqfj1n-diffutils-3.7/bin:/gnu/store/cd5qf3kcnlq35p9k392pjdpdzpsnds70-patch-2.7.6/bin:/gnu/store/hic7snhayfl7m6cpfqqr73nmm19bpqkg-findutils-4.7.0/bin:/gnu/store/swqdvwri9dbv6zssg6v0by7l05hd6wxp-gawk-5.0.1/bin:/gnu/store/ishk7fswcs4gkwcp8mh788z4mvvl9bxh-sed-4.8/bin:/gnu/store/bhs4rj58v8j1narb2454raan2ps38xd8-grep-3.4/bin:/gnu/store/57xj5gcy1jbl9ai2lnrqnpr0dald9i65-coreutils-8.32/bin:/gnu/store/hm40bxnv8jxmbc1lpb7zfimii4xm9m81-make-4.3/bin:/gnu/store/pwcp239kjf7lnj5i4lkdzcfcxwcfyk72-bash-minimal-5.0.16/bin:/gnu/store/mpa04aq8lblbcviyxywxcsb1zbi0mf39-ld-wrapper-0/bin:/gnu/store/m1z7cdbqsqyp9xnjw5cvlb4a7gkcg3m4-binutils-2.34/bin:/gnu/store/rn75fm7adgx3pw5j8pg3bczfqq1y17lk-gcc-7.5.0/bin:/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/bin:/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/sbin'
environment variable `EMACSLOADPATH' set to `/gnu/store/6kfvm6qhm5g875jp34x84bgiffhwbyn9-emacs-minimal-27.2/share/emacs/site-lisp:/gnu/store/255jfysgmqi8lwl8x0nh88x3j5s3fi8a-emacs-dash-2.19.1/share/emacs/site-lisp:/gnu/store/lkin08vh3vlz0f5qirvhbq00jskmx834-emacs-s-1.12.0/share/emacs/site-lisp:/gnu/store/24bnqdxmchk3vgahazbbpqaq8wzbj1hr-emacs-async-1.9.4/share/emacs/site-lisp'
environment variable `INFOPATH' set to `/gnu/store/6kfvm6qhm5g875jp34x84bgiffhwbyn9-emacs-minimal-27.2/share/info:/gnu/store/v6f44zccwh9z5zk3pjlywjybbi8n2hjh-tar-1.32/share/info:/gnu/store/ncydgq2znms5n1d2k5yqshhf58nsixwv-gzip-1.10/share/info:/gnu/store/n4n560pfvvw50a9369axw5vj5rrqfj1n-diffutils-3.7/share/info:/gnu/store/hic7snhayfl7m6cpfqqr73nmm19bpqkg-findutils-4.7.0/share/info:/gnu/store/swqdvwri9dbv6zssg6v0by7l05hd6wxp-gawk-5.0.1/share/info:/gnu/store/ishk7fswcs4gkwcp8mh788z4mvvl9bxh-sed-4.8/share/info:/gnu/store/bhs4rj58v8j1narb2454raan2ps38xd8-grep-3.4/share/info:/gnu/store/57xj5gcy1jbl9ai2lnrqnpr0dald9i65-coreutils-8.32/share/info:/gnu/store/hm40bxnv8jxmbc1lpb7zfimii4xm9m81-make-4.3/share/info:/gnu/store/pwcp239kjf7lnj5i4lkdzcfcxwcfyk72-bash-minimal-5.0.16/share/info:/gnu/store/m1z7cdbqsqyp9xnjw5cvlb4a7gkcg3m4-binutils-2.34/share/info:/gnu/store/rn75fm7adgx3pw5j8pg3bczfqq1y17lk-gcc-7.5.0/share/info:/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/share/info'
environment variable `BASH_LOADABLES_PATH' unset
environment variable `C_INCLUDE_PATH' set to `/gnu/store/6kfvm6qhm5g875jp34x84bgiffhwbyn9-emacs-minimal-27.2/include:/gnu/store/i8h2pcxqdq07ijm3ibkka8f4smn1w48v-bzip2-1.0.8/include:/gnu/store/9860f1abqj8wjjnwl8a9v54pdcc3bhgf-xz-5.2.4/include:/gnu/store/60g7r3l01fd7c58yjbm6krgcwj1jkpwg-file-5.38/include:/gnu/store/swqdvwri9dbv6zssg6v0by7l05hd6wxp-gawk-5.0.1/include:/gnu/store/hm40bxnv8jxmbc1lpb7zfimii4xm9m81-make-4.3/include:/gnu/store/m1z7cdbqsqyp9xnjw5cvlb4a7gkcg3m4-binutils-2.34/include:/gnu/store/rn75fm7adgx3pw5j8pg3bczfqq1y17lk-gcc-7.5.0/include:/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/include:/gnu/store/gfapkk5c6hvl1d94m4sqnhn7f9l5gqyh-linux-libre-headers-5.4.20/include'
environment variable `CPLUS_INCLUDE_PATH' set to `/gnu/store/6kfvm6qhm5g875jp34x84bgiffhwbyn9-emacs-minimal-27.2/include:/gnu/store/i8h2pcxqdq07ijm3ibkka8f4smn1w48v-bzip2-1.0.8/include:/gnu/store/9860f1abqj8wjjnwl8a9v54pdcc3bhgf-xz-5.2.4/include:/gnu/store/60g7r3l01fd7c58yjbm6krgcwj1jkpwg-file-5.38/include:/gnu/store/swqdvwri9dbv6zssg6v0by7l05hd6wxp-gawk-5.0.1/include:/gnu/store/hm40bxnv8jxmbc1lpb7zfimii4xm9m81-make-4.3/include:/gnu/store/m1z7cdbqsqyp9xnjw5cvlb4a7gkcg3m4-binutils-2.34/include:/gnu/store/rn75fm7adgx3pw5j8pg3bczfqq1y17lk-gcc-7.5.0/include/c++:/gnu/store/rn75fm7adgx3pw5j8pg3bczfqq1y17lk-gcc-7.5.0/include:/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/include:/gnu/store/gfapkk5c6hvl1d94m4sqnhn7f9l5gqyh-linux-libre-headers-5.4.20/include'
environment variable `LIBRARY_PATH' set to `/gnu/store/6kfvm6qhm5g875jp34x84bgiffhwbyn9-emacs-minimal-27.2/lib:/gnu/store/i8h2pcxqdq07ijm3ibkka8f4smn1w48v-bzip2-1.0.8/lib:/gnu/store/9860f1abqj8wjjnwl8a9v54pdcc3bhgf-xz-5.2.4/lib:/gnu/store/60g7r3l01fd7c58yjbm6krgcwj1jkpwg-file-5.38/lib:/gnu/store/swqdvwri9dbv6zssg6v0by7l05hd6wxp-gawk-5.0.1/lib:/gnu/store/m1z7cdbqsqyp9xnjw5cvlb4a7gkcg3m4-binutils-2.34/lib:/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib:/gnu/store/s3dcqzwqaakv1yx37by9chksdbkgih17-glibc-2.31-static/lib:/gnu/store/hwcky7446s952w0mwchhmm211ll07zrq-glibc-utf8-locales-2.31/lib'
environment variable `GUIX_LOCPATH' set to `/gnu/store/hwcky7446s952w0mwchhmm211ll07zrq-glibc-utf8-locales-2.31/lib/locale'
phase `set-paths' succeeded after 0.0 seconds
starting phase `install-locale'
using 'en_US.utf8' locale for category "LC_ALL"
phase `install-locale' succeeded after 0.0 seconds
starting phase `unpack'
`/gnu/store/ardf5qwqj82gva405hywf2vbd25jhqgh-emacs-moldable-emacs-0.0.0-1.0737b3a-checkout/moldable-emacs.el' -> `./moldable-emacs.el'
`/gnu/store/ardf5qwqj82gva405hywf2vbd25jhqgh-emacs-moldable-emacs-0.0.0-1.0737b3a-checkout/LICENSE.md' -> `./LICENSE.md'
`/gnu/store/ardf5qwqj82gva405hywf2vbd25jhqgh-emacs-moldable-emacs-0.0.0-1.0737b3a-checkout/README.org' -> `./README.org'
`/gnu/store/ardf5qwqj82gva405hywf2vbd25jhqgh-emacs-moldable-emacs-0.0.0-1.0737b3a-checkout/resources/my.jpg' -> `./resources/my.jpg'
`/gnu/store/ardf5qwqj82gva405hywf2vbd25jhqgh-emacs-moldable-emacs-0.0.0-1.0737b3a-checkout/molds/core-1.el' -> `./molds/core-1.el'
`/gnu/store/ardf5qwqj82gva405hywf2vbd25jhqgh-emacs-moldable-emacs-0.0.0-1.0737b3a-checkout/molds/contrib.el' -> `./molds/contrib.el'
`/gnu/store/ardf5qwqj82gva405hywf2vbd25jhqgh-emacs-moldable-emacs-0.0.0-1.0737b3a-checkout/molds/contrib-1.el' -> `./molds/contrib-1.el'
`/gnu/store/ardf5qwqj82gva405hywf2vbd25jhqgh-emacs-moldable-emacs-0.0.0-1.0737b3a-checkout/molds/core.el' -> `./molds/core.el'
phase `unpack' succeeded after 0.0 seconds
starting phase `expand-load-path'
source directory "/tmp/guix-build-emacs-moldable-emacs-0.0.0-1.0737b3a.drv-0/source" prepended to the `EMACSLOADPATH' environment variable
expanded load paths for dash-2.19.1, s-1.12.0, async-1.9.4
phase `expand-load-path' succeeded after 0.0 seconds
starting phase `patch-usr-bin-file'
phase `patch-usr-bin-file' succeeded after 0.0 seconds
starting phase `patch-source-shebangs'
phase `patch-source-shebangs' succeeded after 0.0 seconds
starting phase `patch-generated-file-shebangs'
phase `patch-generated-file-shebangs' succeeded after 0.0 seconds
starting phase `check'
test suite not run
phase `check' succeeded after 0.0 seconds
starting phase `install'
`/tmp/guix-build-emacs-moldable-emacs-0.0.0-1.0737b3a.drv-0/source/moldable-emacs.el' -> `/gnu/store/46r4pm57qrppz5jb90l5nid8c575y117-emacs-moldable-emacs-0.0.0-1.0737b3a/share/emacs/site-lisp/moldable-emacs-0.0.0-1.0737b3a/moldable-emacs.el'
phase `install' succeeded after 0.0 seconds
starting phase `make-autoloads'
  INFO     Scraping files for moldable-emacs-autoloads.el... 
  INFO     Scraping files for moldable-emacs-autoloads.el...done
phase `make-autoloads' succeeded after 0.0 seconds
starting phase `enable-autoloads-compilation'
phase `enable-autoloads-compilation' succeeded after 0.0 seconds
starting phase `patch-el-files'
phase `patch-el-files' succeeded after 0.0 seconds
starting phase `build'
Checking /gnu/store/46r4pm57qrppz5jb90l5nid8c575y117-emacs-moldable-emacs-0.0.0-1.0737b3a/share/emacs/site-lisp/moldable-emacs-0.0.0-1.0737b3a/...
Compiling /gnu/store/46r4pm57qrppz5jb90l5nid8c575y117-emacs-moldable-emacs-0.0.0-1.0737b3a/share/emacs/site-lisp/moldable-emacs-0.0.0-1.0737b3a/moldable-emacs-autoloads.el...
Compiling /gnu/store/46r4pm57qrppz5jb90l5nid8c575y117-emacs-moldable-emacs-0.0.0-1.0737b3a/share/emacs/site-lisp/moldable-emacs-0.0.0-1.0737b3a/moldable-emacs.el...

In toplevel form:
moldable-emacs.el:5:1:Warning: defcustom for ‘me/files-with-molds’ fails to
    specify type
moldable-emacs.el:5:1:Warning: defcustom for ‘me/files-with-molds’ fails to
    specify containing group
moldable-emacs.el:5:1:Warning: defcustom for ‘me/files-with-molds’ fails to
    specify type
moldable-emacs.el:5:1:Warning: defcustom for ‘me/files-with-molds’ fails to
    specify containing group
moldable-emacs.el:15:1:Warning: defcustom for ‘me/molds-debug-on’ fails to
    specify type
moldable-emacs.el:15:1:Warning: defcustom for ‘me/molds-debug-on’ fails to
    specify containing group
moldable-emacs.el:15:1:Warning: defcustom for ‘me/molds-debug-on’ fails to
    specify type
moldable-emacs.el:15:1:Warning: defcustom for ‘me/molds-debug-on’ fails to
    specify containing group

In me/insert-string-table:
moldable-emacs.el:116:15:Warning: assignment to free variable
    ‘org-confirm-elisp-link-function’

In me/alist-to-plist:
moldable-emacs.el:122:27:Warning: ‘(_ (ignore-errors (= (length (car alist))
    (length (-filter #'stringp (car alist))))))’ is a malformed function
moldable-emacs.el:126:25:Warning: reference to free variable ‘keys’

In me/first-org-table:
moldable-emacs.el:170:28:Warning: reference to free variable
    ‘org-table-line-regexp’

In me/all-flat-org-tables:
moldable-emacs.el:182:38:Warning: reference to free variable
    ‘org-table-line-regexp’

In me/mold-treesitter-to-parse-tree:
moldable-emacs.el:209:46:Warning: reference to free variable
    ‘tree-sitter-tree’
moldable-emacs.el:223:31:Warning: reference to free variable ‘acc’
moldable-emacs.el:226:21:Warning: assignment to free variable ‘acc’
moldable-emacs.el:227:18:Warning: reference to free variable ‘fn’

In me/setup-self-mold-data:
moldable-emacs.el:429:35:Warning: reference to free variable ‘self’
moldable-emacs.el:434:46:Warning: reference to free variable ‘mold-data’
moldable-emacs.el:435:20:Warning: reference to free variable
    ‘me/last-used-mold’

In me/set-dired-self-for-playground:
moldable-emacs.el:442:17:Warning: reference to free variable
    ‘me/last-used-mold’
moldable-emacs.el:443:25:Warning: reference to free variable ‘mold-data’
moldable-emacs.el:449:49:Warning: ‘mark-whole-buffer’ is for interactive use
    only.
moldable-emacs.el:451:37:Warning: assignment to free variable ‘self’

In me/set-self-mold-data:
moldable-emacs.el:459:38:Warning: reference to free variable ‘self’
moldable-emacs.el:461:16:Warning: assignment to free variable ‘mold-data’

In me/mold-demo:
moldable-emacs.el:731:22:Warning: ‘(mold mold)’ is a malformed function
moldable-emacs.el:734:8:Warning: reference to free variable ‘example’
moldable-emacs.el:759:1:Warning: defcustom for ‘me/enable-history’ fails to
    specify type
moldable-emacs.el:759:1:Warning: defcustom for ‘me/enable-history’ fails to
    specify containing group
moldable-emacs.el:759:1:Warning: defcustom for ‘me/enable-history’ fails to
    specify type
moldable-emacs.el:759:1:Warning: defcustom for ‘me/enable-history’ fails to
    specify containing group
Symbol’s value as variable is void: me/before-register-mold-hook
command "/gnu/store/6kfvm6qhm5g875jp34x84bgiffhwbyn9-emacs-minimal-27.2/bin/emacs" "--quick" "--batch" "--eval=(eval '(progn (setq byte-compile-debug t) (byte-recompile-directory (file-name-as-directory \"/gnu/store/46r4pm57qrppz5jb90l5nid8c575y117-emacs-moldable-emacs-0.0.0-1.0737b3a/share/emacs/site-lisp/moldable-emacs-0.0.0-1.0737b3a\") 0 1)) t)" failed with status 255
builder for `/gnu/store/g7r2bp615xf2b036wwyqgfi651yfsc2y-emacs-moldable-emacs-0.0.0-1.0737b3a.drv' failed with exit code 1
build of /gnu/store/g7r2bp615xf2b036wwyqgfi651yfsc2y-emacs-moldable-emacs-0.0.0-1.0737b3a.drv failed
View build log at '/var/log/guix/drvs/g7/r2bp615xf2b036wwyqgfi651yfsc2y-emacs-moldable-emacs-0.0.0-1.0737b3a.drv.bz2'.
guix build: error: build of `/gnu/store/g7r2bp615xf2b036wwyqgfi651yfsc2y-emacs-moldable-emacs-0.0.0-1.0737b3a.drv' failed

I know this is a very new mode, so I was wondering if there is a stable commit I can use to start? And if you find this helpful, Guix is a very handy tool to guide development, and can be used on any Linux distribution.

Consider giving molds a `:type-vector` property to support auto composability

Sorry, this got a little long. Writing this up helped me think through things.

TLDR: If we give mold definitions an ordered list of type information, in increasing specificity, and write a few functions, moldable-emacs can synthesize composable molds without having to write them.


From what I can tell, the "moldable" concept is about defining a graph:

  • The vertices in the graph are states data, (i.e. a buffer) can be in
  • The edges in the graph are the molds, i.e. functions which transform data from state, i.e. Mold = f(Sn) = Sm
  • The graph is directed and permits loops, i.e. you can go from list -> csv -> list, or Sn -> Sm -> Sn.

My impression is that the power of the moldable concept comes from the fact that if you can connect novel data in a buffer with a vertex in the graph with high valency (i.e. a high number of edges), you can now leverage the full body of molds to do interesting things. That is to say, if you can make the data in your buffer look like something the moldable graph knows a lot about, you can transform that buffer into interesting things.

Currently, moldable-emacs has the concept of "composable molds". This is a manual definition of a path through the graph. Molds already define their requisite starting state, Sn which includes assertions about runtime requirements as well as data type information. If they separated out the runtime-requirements from statements about the data's state, and then declared the state they will leave a buffer in, Sm, it should be possible to write an algorithm to automatically discover what "end states" are possible for the current buffer.

This would reduce the maintenance burden of manually defining every path through the graph possible, and might surprise the user at what's possible with their current buffer.

Representing the vertices beginning state, Sn

I think there are a few pieces of information:

  • What libraries must be available
  • Any preconditions on activation
  • The most general type of data that can be accepted (I'll expound in the next section)

Representing the vertices end state, Sm

I think it should provide the type information of the data in increasing specificity (e.g. this is an emacs-lisp buffer, which means it's code, which means it's a tree, but it might be a tree with a pre-defined type, like an alist or plist, etc.). This is a vector of type-information, i.e. (using the previous example) <emacs-lisp, code, tree, plist>, or TV=<T0, T1, ..., Tn>. Note that the mold is in a unique position to have the highest resolution of what type-vector the data it produces has.

Building the graph, G

When the hypothetical algorithm tries to build the graph, it would need to walk the list of known molds, V={M0, M1, ..., Mn}, and for each mold, Mi:

  • Determine if Mi is activatable, e.g. does the running emacs process contain the necessary libraries to execute the mold. This is a filter for whether the mold enters into the graph.
  • Compare against each mold, Mj such that f(Mi, Mj) = { if TjTVi, then Tj, otherwise nil.
  • If Tj is returned, then we add the edge between Mi and Mj.

Using the graph, G

  • When a user invokes me-mold, walk the graph to find the vertex whose type-vector fits the buffer/data in the most general way, i.e. f(buffer, G) = Mi where:
    • f(Mi) = required type Ti
    • f(buffer) = TVb
    • TiTVb
    • f(T, TV) = index of T, TVn
    • n < any other TVn, i.e. the match with the lowest index wins
      • In the case where there are multiple TVn which are equal, prefer the TV with the lowest magnitude (length) | TV |.
        • In the case where there are multiple TV of equal magnitude, pick the first one sorted alphanumerically (this makes things deterministic).
  • Calculate the minimum spanning tree for Mi (for performance, these could be cached when the graph is constructed, and when molds are added at runtime).
  • Present the terminal vertices as Mold options to run.
  • Traversing the path through the graph may fail if one of the mold's prerequisites fails. When this happens, a copy of the graph should be made for the buffer, the edge that failed should be removed, and the minimum spanning tree should be recalculated.

The reason to use the mold with the most general matching type-vector as a starting point is so that we get the most paths through the graph as possible. Going back to our example, <emacs-lisp, code, tree, plist>, there might be some molds that can operate on plists, but not trees. If we pick the plist mold as a starting point, we are now disconnected from any other vertices that might know what to do with emacs-lisp, code, or trees.

The reason to use the mold with the lowest magnitude type-vector is because between two molds that have matched the buffer's type in equally general ways, the mold with the higher length type-vector is making the most specific claim about the data in the buffer, and we cannot be sure the assertion holds since a mold did not generate the data. E.g. a buffer is highly likely to be <emacs-lisp, code, tree>, but it is as of yet unknown whether it is <emacs-lisp, code, tree, plist>.

Implications

This approach changes molds a little. Instead of defining molds as BeginStateToEndState, e.g. "CSVToOrgTable", molds should only be named to refer to their end state, e.g. "ToOrgTable" (or I suggest, "to-org-table"). This is because that when the user is presented with options, the options will be terminal vertices, but the span between the user's buffer and the terminal vertex might be long. It would not make sense to see "CSVToOrgTable" if I'm looking at an emacs-lisp buffer. It would make sense (albeit maybe surprising!) to see "ToCSV".

Molds should become as small as possible to promote reuse.

Traversing the path through the graph may fail if one of the mold's prerequisites fails. For this reason, prerequisites should be used sparingly.

Composable molds go away, because moldable-emacs handles that messy bit for us :)

Show and tell: Xref to Org todo list

I have been playing with moldable-emacs, and made a mold to convert xref results to an Org TODO list

The first part populates a Playground with the xref data

;; Following function is based on xref-query-replace-in-results
(defun me-get-xrefs ()
  "Run in the *xref* buffer, return the actual xrefs."
  (let* (item xrefs iter ret)
    (save-excursion
      (while (setq item (xref--search-property 'xref-item))
        (let ((pitem (list :summary (xref-item-summary item) :location (xref-item-location item)) ))
          (push pitem xrefs))))
    xrefs
    ))

(defun me-set-xref-self-for-playground ()
  "Set Playground `self' to xref list of locations."
  (when (and
         (s-starts-with-p "Playground" me-last-used-mold)
         (ignore-errors mold-data)
         (eq (plist-get mold-data :old-mode) 'xref--xref-buffer-mode))
    (setq-local self (with-current-buffer (plist-get mold-data :old-buffer)
                       (progn (goto-char (point-min))
                              (me-get-xrefs))))))
                       ;; (buffer-string)))))

;; the order is important: keep before me-set-self-mold-data, hence 91
(add-hook 'me-mold-after-hook #'me-set-xref-self-for-playground 91)

The next one converts it to a todo list

(me-register-mold
 :key "XrefToOrgTodos"
 :given (:fn (and
              (eq major-mode 'emacs-lisp-mode)))
 :then (:fn
        (let* ((tree self)
               (text (concat
                      "* Todo list [/]\n"
                      (s-join
                       "\n\n"
                       (--map
                        (format
                         "- [ ] [[elisp:%s][%s]]"
                         (format
                          "(progn (find-file-other-window \"%s\") (goto-char %s))"
                          (xref-location-group (plist-get it :location))
                          (marker-position (xref-location-marker (plist-get it :location))))
                         (s-truncate 100 (plist-get it :summary)))
                        tree)))))
          (with-current-buffer buffername
            (erase-buffer)
            (org-mode)
            (setq-local org-confirm-elisp-link-function nil)
            (insert text))))
 :docs "Transform an xref plist into an Org mode TODO list."
 :examples ())

Issues with the "ElispListToOrgTable" mold & `me-alist-to-plist`

I was working my way through the tutorial, and I get to the step where you are supposed to turn the list of buffers into a bar-chart. This fails for me, so I tried running ElispListToOrgTable with the following data:

((:buffer "Playground" :size 201)
 (:buffer " *Minibuf-1*" :size 0)
 (:buffer "Show Tutorials" :size 3510)
 (:buffer "*scratch*" :size 187)
 (:buffer "moldable-emacs.el" :size 47852)
 (:buffer " *Minibuf-0*" :size 0)
 (:buffer "*Messages*" :size 34483)
 (:buffer " *code-conversion-work*" :size 11)
 (:buffer " *Echo Area 0*" :size 0)
 (:buffer " *Echo Area 1*" :size 0)
 (:buffer "*Compile-Log*" :size 0)
 (:buffer "*Warnings*" :size 328)
 (:buffer "*direnv*" :size 0)
 (:buffer "core.el" :size 42803)
 (:buffer "contrib.el" :size 16916)
 (:buffer " *org-src-fontification:emacs-lisp-mode*" :size 90)
 (:buffer " *helm candidates:Emacs Commands history*" :size 7)
 (:buffer " *helm candidates:Emacs Commands*" :size 192024)
 (:buffer "*helm M-x*" :size 2276)
 (:buffer "*Completions*" :size 305)
 (:buffer "EvalSexp" :size 0))

I get this stack-trace:

Debugger entered--Lisp error: (wrong-type-argument sequencep :buffer)
  #f(compiled-function (it) #<bytecode 0x10c26e1>)(:buffer)
  mapcar(#f(compiled-function (it) #<bytecode 0x10c26e1>) (:buffer "Playground" :size 201))
  me-alist-to-plist(((:buffer "Playground" :size 201) (:buffer " *Minibuf-1*" :size 0) (:buffer "Show Tutorials" :size 3510) (:buffer "*scratch*" :size 187) (:buffer "moldable-emacs.el" :size 47852) (:buffer " *Minibuf-0*" :size 0) (:buffer "*Messages*" :size 34483) (:buffer " *code-conversion-work*" :size 11) (:buffer " *Echo Area 0*" :size 0) (:buffer " *Echo Area 1*" :size 0) (:buffer "*Compile-Log*" :size 0) (:buffer "*Warnings*" :size 328) (:buffer "*direnv*" :size 0) (:buffer "core.el" :size 42803) (:buffer "contrib.el" :size 16916) (:buffer " *org-src-fontification:emacs-lisp-mode*" :size 90) (:buffer " *helm candidates:Emacs Commands history*" :size 7) (:buffer " *helm candidates:Emacs Commands*" :size 192024) (:buffer "*helm M-x*" :size 2276) (:buffer "*Completions*" :size 305) (:buffer "EvalSexp" :size 0)))
  (if (ignore-errors (length (car l))) (me-alist-to-plist l) (me-alist-to-plist (-map #'-cons-to-list l)))
  (let* ((list (if (ignore-errors (length (car l))) (me-alist-to-plist l) (me-alist-to-plist (-map #'-cons-to-list l))))) (with-current-buffer buffername (org-mode) (erase-buffer) (me-insert-flat-org-table list) (setq-local self list)))
  (progn (get-buffer-create buffername) (let* ((list (if (ignore-errors (length (car l))) (me-alist-to-plist l) (me-alist-to-plist (-map #'-cons-to-list l))))) (with-current-buffer buffername (org-mode) (erase-buffer) (me-insert-flat-org-table list) (setq-local self list))) (ignore-errors (switch-to-buffer-other-window (get-buffer buffername))))
  (cond ((equal '(:then) '(:given)) (ignore-errors (and (>= (length l) 2) (listp (car l)) (or (consp (car l)) (--all\? (= (length it) (length ...)) l)) (or (-all\? #'stringp (list (caar l) (cdar l))) (-all\? #'stringp (car l)) (and (stringp (caar l)) (stringp (cdar l))) (--all\? (equal (-filter ... ...) (-filter ... it)) l))))) ((equal '(:then) '(:then)) (progn (get-buffer-create buffername) (let* ((list (if (ignore-errors ...) (me-alist-to-plist l) (me-alist-to-plist ...)))) (with-current-buffer buffername (org-mode) (erase-buffer) (me-insert-flat-org-table list) (setq-local self list))) (ignore-errors (switch-to-buffer-other-window (get-buffer buffername))))) (t :then))
  (pcase '(:then) ('(:given) (ignore-errors (and (>= (length l) 2) (listp (car l)) (or (consp (car l)) (--all\? (= (length it) (length ...)) l)) (or (-all\? #'stringp (list (caar l) (cdar l))) (-all\? #'stringp (car l)) (and (stringp (caar l)) (stringp (cdar l))) (--all\? (equal (-filter ... ...) (-filter ... it)) l))))) ('(:then) (progn (get-buffer-create buffername) (let* ((list (if (ignore-errors ...) (me-alist-to-plist l) (me-alist-to-plist ...)))) (with-current-buffer buffername (org-mode) (erase-buffer) (me-insert-flat-org-table list) (setq-local self list))) (ignore-errors (switch-to-buffer-other-window (get-buffer buffername))))) (_ :then))
  (let* ((l (list-at-point))) (pcase '(:then) ('(:given) (ignore-errors (and (>= (length l) 2) (listp (car l)) (or (consp (car l)) (--all\? (= ... ...) l)) (or (-all\? #'stringp (list ... ...)) (-all\? #'stringp (car l)) (and (stringp ...) (stringp ...)) (--all\? (equal ... ...) l))))) ('(:then) (progn (get-buffer-create buffername) (let* ((list (if ... ... ...))) (with-current-buffer buffername (org-mode) (erase-buffer) (me-insert-flat-org-table list) (setq-local self list))) (ignore-errors (switch-to-buffer-other-window (get-buffer buffername))))) (_ :then)))
  (let ((buffername (or nil "ElispListToOrgTable"))) (let* ((l (list-at-point))) (pcase '(:then) ('(:given) (ignore-errors (and (>= (length l) 2) (listp (car l)) (or (consp ...) (--all\? ... l)) (or (-all\? ... ...) (-all\? ... ...) (and ... ...) (--all\? ... l))))) ('(:then) (progn (get-buffer-create buffername) (let* ((list ...)) (with-current-buffer buffername (org-mode) (erase-buffer) (me-insert-flat-org-table list) (setq-local self list))) (ignore-errors (switch-to-buffer-other-window (get-buffer buffername))))) (_ :then))))
  (progn (let ((buffername (or nil "ElispListToOrgTable"))) (let* ((l (list-at-point))) (pcase '(:then) ('(:given) (ignore-errors (and (>= ... 2) (listp ...) (or ... ...) (or ... ... ... ...)))) ('(:then) (progn (get-buffer-create buffername) (let* (...) (with-current-buffer buffername ... ... ... ...)) (ignore-errors (switch-to-buffer-other-window ...)))) (_ :then)))))
  eval((progn (let ((buffername (or nil "ElispListToOrgTable"))) (let* ((l (list-at-point))) (pcase '(:then) ('(:given) (ignore-errors (and ... ... ... ...))) ('(:then) (progn (get-buffer-create buffername) (let* ... ...) (ignore-errors ...))) (_ :then))))) t)
  me-mold-run-then((:key "ElispListToOrgTable" :let ((l (list-at-point))) :given (:fn (ignore-errors (and (>= (length l) 2) (listp (car l)) (or (consp (car l)) (--all\? (= ... ...) l)) (or (-all\? #'stringp (list ... ...)) (-all\? #'stringp (car l)) (and (stringp ...) (stringp ...)) (--all\? (equal ... ...) l))))) :then (:fn (let* ((list (if (ignore-errors ...) (me-alist-to-plist l) (me-alist-to-plist ...)))) (with-current-buffer buffername (org-mode) (erase-buffer) (me-insert-flat-org-table list) (setq-local self list)))) :docs "You can produce an Org Table of the plist, list or..." :examples ((:name "Alist to Org table" :given (:type file :name "/tmp/my.el" :mode emacs-lisp-mode :contents "((\"Index\" \"Value\")\n (1 3)\n (2 9)\n (3  27))") :then (:type buffer :name "Org Table for list starting for (:Index 1 :Value 3..." :mode org-mode :contents "| Index | Value |\n|-------+-------|\n|     1 |     ...")) (:name "Cons list to Org table" :given (:type file :name "/tmp/my.el" :mode emacs-lisp-mode :contents "((\"Index\" . \"Value\")\n (1 . 3)\n (2 . 9)\n (3 . 27))") :then (:type buffer :name "Org Table for list starting for (:Index 1 :Value 3..." :mode org-mode :contents "| Index | Value |\n|-------+-------|\n|     1 |     ...")) (:name "Property list to Org table" :given (:type file :name "/tmp/my.el" :mode emacs-lisp-mode :contents "((:index 1 :value 3)\n (:index 2 :value 9)\n (:index...") :then (:type buffer :name "Org Table for list starting for (:index 1 :value 3..." :mode org-mode :contents "| index | value |\n|-------+-------|\n|     1 |     ..."))) :origin "/gnu/store/amsqdqzp1s0nmy185l9py4vd9hvqbihi-emacs-..."))
  me-mold()
  funcall-interactively(me-mold)
  call-interactively(me-mold record nil)
  command-execute(me-mold record)

I think this is an issue somewhere in this function:

(defun me-alist-to-plist (alist)
"Convert ALIST to a `plist'."
(if-let* ((_ (ignore-errors (= (length (car alist)) (length (-filter #'stringp (car alist))))))
(keys (--map (intern (concat ":" it)) (car alist))))
(--map (-flatten (-zip-lists keys it)) (cdr alist))
alist))

But I also think there is probably other issues with this mold:

  • Checking that this lists in the top-level-list are the same length is not valid. E.g., this is a perfectly valid alist: (assoc 'a '((a 1) (b 2 3 4 5)))
  • I think the what the :given precondition is really checking for is that there is a list of uniform plists. These types of lists would implicitly form an alist, but not in the way I think this mold means it. I.e.
(assoc :buffer
       '((:buffer "Playground" :size 201)
         (:buffer " *Minibuf-1*" :size 0)
         (:buffer "Show Tutorials" :size 3510)
         (:buffer "*scratch*" :size 187)
         (:buffer "moldable-emacs.el" :size 47852)
         (:buffer " *Minibuf-0*" :size 0)
         (:buffer "*Messages*" :size 34483)
         (:buffer " *code-conversion-work*" :size 11)
         (:buffer " *Echo Area 0*" :size 0)
         (:buffer " *Echo Area 1*" :size 0)
         (:buffer "*Compile-Log*" :size 0)
         (:buffer "*Warnings*" :size 328)
         (:buffer "*direnv*" :size 0)
         (:buffer "core.el" :size 42803)
         (:buffer "contrib.el" :size 16916)
         (:buffer " *org-src-fontification:emacs-lisp-mode*" :size 90)
         (:buffer " *helm candidates:Emacs Commands history*" :size 7)
         (:buffer " *helm candidates:Emacs Commands*" :size 192024)
         (:buffer "*helm M-x*" :size 2276)
         (:buffer "*Completions*" :size 305)
         (:buffer "EvalSexp" :size 0)))

=> (:buffer "Playground" :size 201).

Traditionally, Lisps have consed additional values onto an alist because assoc style functions will stop once they find the first match. This is how alists are updated.

Therefore, I think it may be incorrect and misleading to call a function named me-alist-to-plist since this is not really an alist despite being in an alist shape, and this may be why there's an error.

I haven't continued digging into what shape of list me-insert-flat-org-table expects.

WhatMoldsCanIUse? does not report molds with failed dependencies

I do not have org-ql installed.

If I open an org-mode file, and activate WhatMoldsCanIUse? it does not add a section noting the missing dependencies.

Perhaps there should be a test for this, with a test mold having an impossible dependency to keep it from regressing.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.