ag91 / moldable-emacs

Adapting Emacs for moldable development
GNU General Public License v3.0
105 stars 8 forks source link

Moldable Emacs is about molding data into information. You can represent data in many ways. The context you work with defines if a representation is more useful than another.

Moldable Emacs introduces a new concept: Mold. Think of a mold as a function that, given a precondition, transforms some data into the representation you need. This enhances your understanding of things but also allows you to [[https://ag91.github.io/blog/2021/08/11/moldable-emacs-editing-your-file-via-treesitter-(or-how-i-fixed-my-css-with-a-playground)/][solve specific problems you have by solving general problems with molds]]

Typically a mold takes as input an Emacs buffer and produce a new buffer. I designed Moldable Emacs so you can easily compose molds, so that one mold can fulfill a precondition for another mold.

[[https://www.youtube.com/watch?v=lLK7d6bTjuA][Presentation at EmacsConf21 here]].

For example, given a source code file, I want to find how complex its functions are. Then I want to know the aggregate complexity of all the functions. This is what I would do.

I have a Python file.

[[resources/pythonFile.jpg]]

I use =M-x me-mold= to choose the "FunctionsComplexity" mold.

[[resources/pythonFunctionComplexity.jpg]]

I use =M-x me-mold= again to choose the "Playground" mold (and write some code to calculate the total complexity).

[[resources/playgroundMold.jpg]]

I composed two molds for this: "FunctionsComplexity" (show complexity of functions as an Org Mode table) and "Playground" (similar to Emacs scratch buffer). The composition preserves (part of) the context through the local variables =self= and =mold-data=. An inspector buffer always shows you their current contents.

** Installation :PROPERTIES: :CREATED: [2021-06-23 Wed 00:09] :ID: b68dfda8-54d1-498c-b6f1-fdc52eb21889 :END:

The suggested way to install this package is via [[https://github.com/jwiegley/use-package][use-package]]. This is my installation configuration:

+begin_src elisp :noeval

(use-package moldable-emacs :init (if (f-directory-p "~/.emacs.d/lisp/moldable-emacs") (shell-command "cd ~/.emacs.d/lisp/moldable-emacs; git pull;") (shell-command "cd ~/.emacs.d/lisp/; git clone git@github.com:ag91/moldable-emacs.git")) :load-path "~/.emacs.d/lisp/moldable-emacs/" :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 g" . me-goto-mold-source) ("C-c m e a" . me-mold-add-last-example) ) :config (require 'moldable-emacs) (add-to-list 'me-files-with-molds (concat (file-name-directory (symbol-file 'me-mold)) "molds/experiments.el")) ;; TODO this is relevant only if you have private molds (me-setup-molds))

+end_src

If you are using =Doom Emacs= slightly modify this:

+begin_src elisp :noeval

(use-package! moldable-emacs ... (me-setup-molds)) (add-load-path! "~/.emacs.d/lisp/moldable-emacs/molds")

+end_src

I am working on making =moldable-emacs= itself explain which optional and external dependencies you may need for what, but it is still work in progress. For now an incomplete list from the top of my mind.

*** Emacs Dependencies :PROPERTIES: :CREATED: [2021-06-23 Wed 00:10] :ID: 198d454e-1d1c-4797-a572-75e6e928aeb6 :END:

This package requires:

Optionally:

*** (Optional) External Dependencies

*** Testing

Install the [[https://github.com/doublep/eldev][Elisp Development Tool (Eldev)]] and run

+begin_src shell

eldev test

+end_src

** Getting Started :PROPERTIES: :CREATED: [2021-10-04 Mon 21:40] :ID: ed317af9-902e-4048-a74f-035ce8af58bf :END:

You can start with a fun exercise: access tutorials via the "Show Tutorials" mold. Or you can look in [[tutorials/]].

** Similar Packages :PROPERTIES: :CREATED: [2022-01-10 Mon 21:51] :ID: 58f7084a-7b08-492b-acc6-16ba313320fd :END:

This extension attempts to implement [[https://gtoolkit.com/docs/moldable/][Moldable Development]] for Emacs users. If you speak SmallTalk, try [[https://gtoolkit.com/][GlamorousToolkit]] because it is much more advanced.

** Why I spend time developing this package :PROPERTIES: :CREATED: [2022-01-10 Mon 21:14] :ID: e56f17da-964d-48e8-8adb-93277edabcf8 :END:

I find Moldable Development interesting because attempts to fill a gap of expression. The context we live everyday often becomes a comfortable prison for ourselves. When I work as a software engineer, I cultivate a vocabulary and a toolkit that elevates me and so separates me from others. I mean if my grandpa asks me about what I am doing at the computer, I typically don't feel comfortable in replying: "I am baking a higher-order function to make this bit of code easier to test".

Unluckily, this is an universal issue. Listen to a chef masterclass and you may likely hear things like "mise-en-place", which may not ring a bell.

For software users this is a notable and critical issue because technology changes fast and the knowledge of yesterday is outdated today (for instance, checkout the number of versions of JS frameworks). This is pretty unsustainable. Moldable Development tries to start small and provide views for small data. This way you can understand small things. Then recur until we deal with big problems.

My hope is that we get to a point where I can tell my grandpa "I am baking a higher-order function to make this bit of code easier to test", but in the way he can understand. And I want my computer to help me into doing that. This is not too bigger of an effort than translating that legacy COBOL codebase to something a beginner Python developer can understand.

I believe the secret is in molding the data into information accessible to people. This for me is telling a story. A story is a sequence of facts that carries some meaning to the listener. It is a fundamental tool to exchange meaning. The meaning I want to convey to my grandpa is about the smart technique he can apply in his daily life, not necessarily about how that works in the programming language I am working with. Similarly, a company with a legacy COBOL codebase cares about the functionality and not the technology: if they could translate that to a newer language/technology without losing functionality, they would not mind. (I guess, they would like it even if they could just extract the functionality as a set of requirements and test a new implementation against those: often even that is hard).

At this point this package is not mature enough for all of the above (yet!). But let me give you some examples of stories I tell myself through molds.

** Further info :PROPERTIES: :CREATED: [2021-06-18 Fri 21:51] :END:

*** Vision :PROPERTIES: :CREATED: [2021-06-18 Fri 21:51] :ID: dc37968c-16b8-4414-b51d-77b245162970 :END:

https://ag91.github.io/blog/2021/06/18/moldable-emacs-vision-basic-concepts-and-design *** View code duplication as an Org buffer :PROPERTIES: :CREATED: [2021-06-18 Fri 21:52] :ID: 449520e9-de3b-48f9-8f06-bc1f6437102c :END:

https://ag91.github.io/blog/2021/05/26/moldable-emacs-make-everything-moldable-through-lisp

*** Exploring JSON via Elisp :PROPERTIES: :CREATED: [2021-06-18 Fri 21:51] :ID: 8a0e46f3-4407-4851-a440-f0994367b4b4 :END:

https://ag91.github.io/blog/2021/06/18/moldable-emacs-how-to-explore-json-via-elisp *** [Setup] Clojure tree-sitter grammar installation :PROPERTIES: :CREATED: [2021-06-23 Wed 00:20] :ID: 751a4e84-5193-4dbb-9fc9-91ec7a14c6b4 :END:

https://ag91.github.io/blog/2021/06/22/how-(simple-is)-to-install-a-clojure-tree-sitter-grammar-and-use-it-from-emacs/ *** OCR mold :PROPERTIES: :CREATED: [2021-07-19 Mon 19:37] :ID: dede04d1-b6c9-43c8-b3f4-d968fb89991b :END:

https://ag91.github.io/blog/2021/07/16/moldable-emacs-capturing-text-from-open-images-with-an-ocr-mold *** Grabbing hyperlinks from HTML with Playground :PROPERTIES: :CREATED: [2021-07-19 Mon 19:38] :ID: 6796b283-eca9-498a-bf25-0451f5832a03 :END:

https://ag91.github.io/blog/2021/07/19/moldable-emacs-capture-links-from-html-with-playground/ *** Showing examples for a Clojure function at point :PROPERTIES: :CREATED: [2021-07-27 Tue 23:21] :ID: 646f46fd-6a78-4c23-bccc-28fe51be76e7 :END:

https://ag91.github.io/blog/2021/07/27/moldable-emacs-finding-examples-of-clojure-functions-(with-tests)/ *** Code transformation: edit your CSS files with a Playground! :PROPERTIES: :CREATED: [2021-08-11 Wed 22:14] :ID: 9f3ab44c-8b79-41ed-bc57-183614f32eaa :END:

https://ag91.github.io/blog/2021/08/11/moldable-emacs-editing-your-file-via-treesitter-(or-how-i-fixed-my-css-with-a-playground)/ *** Prototype: integrating Nyxt and Vega-Lite :PROPERTIES: :CREATED: [2021-09-22 Wed 23:42] :END:

https://ag91.github.io/blog/2021/08/22/moldable-emacs-vega-lite-nyxt-and-emacs-towards-sustainable-development

*** Taking notes with molds :PROPERTIES: :CREATED: [2021-09-22 Wed 23:42] :END:

https://ag91.github.io/blog/2021/09/05/moldable-emacs-taking-lispy-notes-that-are-easier-to-search

*** Howto: Migrating to a terser format for molds :PROPERTIES: :CREATED: [2021-09-22 Wed 00:05] :ID: 2763024c-15ef-49da-bf94-888ec3de95e2 :END:

https://ag91.github.io/blog/2021/09/19/moldable-emacs-making-molds-a-little-easier-to-write/

*** Extend molds via hooks :PROPERTIES: :CREATED: [2021-09-24 Fri 23:51] :ID: dfb3ceec-80f1-4d73-abf4-7a31ec422d86 :END:

https://ag91.github.io/blog/2021/09/23/moldable-emacs-extending-the-playground-powers-via-hooks-to-include-dired

*** Check which molds you can use and demo them! :PROPERTIES: :CREATED: [2021-10-02 Sat 01:55] :ID: 65d29893-3b52-47ec-a1c7-aa5b47f893e7 :END:

https://ag91.github.io/blog/2021/10/02/moldable-emacs-molds-need-examples-too/

*** Moldable tutorials :PROPERTIES: :CREATED: [2021-10-16 Sat 00:10] :ID: b19d6408-4b54-4736-961c-ea7a1ffcf9f2 :END:

https://ag91.github.io/blog/2021/10/15/moldable-emacs-moldable-tutorials/

*** Stats mold :PROPERTIES: :CREATED: [2021-10-30 Sat 16:16] :END:

https://ag91.github.io/blog/2021/10/22/moldable-emacs-how-to-get-useful-info-about-a-buffer-without-reading-it/

*** JavaScript and Parenscript Mold with Nyxt :PROPERTIES: :CREATED: [2021-10-30 Sat 16:17] :ID: 04a7d91a-b061-4800-ae91-01309b0f58f7 :END:

https://ag91.github.io/blog/2021/10/29/emacs-with-nyxt-capturing-youtube-links-at-time-and-molding-nyxt-with-js/

Mold examples as tests :PROPERTIES: :CREATED: [2022-01-03 Mon 15:02] :ID: 9cc7b3c2-1773-41fa-aa58-2db4b28cf6b2 :END: https://ag91.github.io/blog/2021/12/23/moldable-emacs-examples-for-docs-demos-and-ert-tests Async molds :PROPERTIES: :CREATED: [2022-01-03 Mon 15:02] :END: https://ag91.github.io/blog/2021/12/31/moldable-emacs-make-your-molds-async-with-ease *** Learn syntax :PROPERTIES: :CREATED: [2022-02-11 Fri 23:50] :ID: fcc9dd9f-9290-486b-8dd8-ecb828071aac :END: https://ag91.github.io/blog/2022/02/11/moldable-emacs-learning-syntax-from-your-editor/