Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
# This file: # https://github.com/edrx/emlua/ # https://github.com/edrx/emlua/#introduction # http://angg.twu.net/emlua/README.org.html # http://angg.twu.net/emlua/README.org # (find-angg "emlua/README.org") # (find-angg "emlua/") # https://raw.githubusercontent.com/edrx/emlua/main/README.org # https://github.com/edrx/emlua/blob/main/README.org # Author: Eduardo Ochs <eduardoochs@gmail.com> # Version: 2022mar28 # License: GPL2 # # See: <https://github.com/edrx/emlua>, # <https://github.com/edrx/emlua#introduction>. # # Announcements: # https://lists.gnu.org/archive/html/emacs-devel/2022-03/msg00767.html # https://lists.gnu.org/archive/html/eev/2022-03/msg00004.html # http://lua-users.org/lists/lua-l/2022-03/msg00098.html *** # # Some eev-isms: # (defun c () (interactive) (eek "C-c C-e h h")) # (defun o () (interactive) (find-angg "emlua/README.org")) # (defun v () (interactive) (brg "~/emlua/README.html")) # (defun cv () (interactive) (c) (v)) # (defun m () (interactive) (magit-status "~/emlua/")) # # (find-fline "~/usrc/org-git-hooks/build.el") # (require 'ox-md) # (org-md-export-to-markdown) # (org-html-export-to-html) # # (find-fline "~/emlua/") # (magit-status "~/emlua/") # (find-gitk "~/emlua/") # (find-mygitrepo-links "emlua") # (find-orgnode "Table of Contents") # # (s)tage all changes # (c)ommit -> (c)reate # (P)ush -> (p)ushremote # # #+OPTIONS: toc:nil num:nil #+OPTIONS: toc:nil #+TITLE: Emlua: run Lua in Emacs as a module * Introduction Emlua implements a /very minimalistic/ way to run a Lua interpreter inside Emacs /as a module/. Running a Lua REPL in Emacs [[http://www.gnu.org/software/emacs/manual/html_node/emacs/Interactive-Shell.html][in a shell buffer]] is trivial - see [[http://angg.twu.net/LATEX/2021emacsconf.pdf#page=3][these slides]], the [[http://angg.twu.net/emacsconf2021.html][page]] of my presentation at the EmacsConf2021, or [[http://angg.twu.net/eev-intros/find-eev-quick-intro.html#6][this tutorial of eepitch]] - but Emlua does something different. To test Emlua you will need: 1) an Emacs compiled with support for [[http://www.gnu.org/software/emacs/manual/html_node/elisp/Dynamic-Modules.html][dynamic modules]], 2) [[https://packages.debian.org/bullseye/liblua5.3-dev][liblua5.3-dev]] or something equivalent to it, and 3) [[http://angg.twu.net/#eev][eev]]. At this moment all the tests are either in [[http://angg.twu.net/emacsconf2021.html][test blocks]] or in [[http://angg.twu.net/eev-intros/find-eev-quick-intro.html#3][sexps in comments]], so you will need [[http://angg.twu.net/#eev][eev]] to run them - but eev is a [[http://angg.twu.net/eev-intros/find-eev-intro.html#1][very non-invasive package]] and it is easy to turn eev-mode on and off, so, ahem, "everybody should have eev installed". 🙃 Here is a screenshot - click on it to enlarge: @@html:<a href="2022eepitch-emlua-0.png"><IMG SRC="2022eepitch-emlua-0-small.png"></a>@@ # (find-elnode "Dynamic Modules") # (find-elnode "Dynamic Modules" "--with-modules") * The low-level way The low-level way to test Emlua is to run the test blocks in [[http://angg.twu.net/emlua/emlua.cpp.html#tests-in-tmp][~emlua.cpp~]]. Here is a copy of the body of the first test block: #+begin_src sh rm -Rfv /tmp/emlua/ mkdir /tmp/emlua/ cd /tmp/emlua/ git clone https://github.com/edrx/emlua . make #+end_src It downloads a copy of emlua from the git repository and compiles ~emlua.cpp~. You may need to set some directories - for example, on my machine I need this instead of a plain "~make~": #+begin_src sh make EMACS_DIR=$HOME/bigsrc/emacs29 #+end_src Then load the module with this sexp, #+begin_src elisp (load "emlua.so") #+end_src The test blocks in [[http://angg.twu.net/emlua/emlua.cpp.html#tests-in-tmp][~emlua.cpp~]] also contain sexps that let you run some very low-level tests, like this one: #+begin_src elisp (emlua-dostring " a = a or 0 a = a + 1 return 22+33, '44', {}, a, nil ") #+end_src The result of the sexp above is this: #+begin_src elisp ["55" "44" "table: 0x55a0f1979040" "0" "nil"] #+end_src The function ~emlua-dostring~ is very primitive - it returns a vector of strings in case of success, and a string in the case of errors. * Exchanging data The file [[http://angg.twu.net/emlua/emlua-data.el.html][~emlua-data.el~]] implements a very basic way to send strings and numbers to Lua code. After loading it we can set the Lua variables ~a~ and ~b~ to ~2.34~ and ~"foo bar"~ by running this: #+begin_src elisp (emlua-dostring (emlua-format "a,b = %s,%s" 2.34 "foo bar")) (emlua-dostring "return a, type(a), b") ;; --> ["2.34" "number" "foo bar"] #+end_src * Two Lua REPLs written in Lua The file [[http://angg.twu.net/emlua/Repl1.lua.html][Repl1.lua]] contains two Lua REPLs written in Lua. They can both be tested by first running this [[http://www.gnu.org/software/emacs/manual/html_node/emacs/Environment.html][~setenv~]] to make Lua use [[http://angg.twu.net/emlua/edrxlib.lua.html][my init file]], #+begin_src elisp (setenv "LUA_INIT" "@/tmp/emlua/edrxlib.lua") #+end_src and then running the test blocks in ~Repl1.lua~. The REPL implemented by the class [[http://angg.twu.net/emlua/Repl1.lua.html#EdrxRepl][~EdrxRepl~]] is very simple, and the other one, implemented by the class [[http://angg.twu.net/emlua/Repl1.lua.html#EdrxEmacsRepl][~EdrxEmacsRepl~]], is a variant of ~EdrxRepl~ that [[http://angg.twu.net/emlua/Repl1.lua.html#WithFakePrint][redirects]] the outputs of ~print~ and ~io.write~ to a string before writing it to stdout. The REPL that runs inside Emacs uses the class ~EdrxEmacsRepl~, but calls methods in it that return the output as a string. * The file emlua-init.el The file [[http://angg.twu.net/emlua/emlua-init.el.html][emlua-init.el]] contains functions that load the lua module, load edrxlib.lua and Repl1.lua, and create a global variable REPL in the Lua interpreter containing an instance of the class EdrxEmacsRepl. Try: #+begin_src elisp (add-to-list 'load-path "/tmp/emlua/") (emlua-init-so) (emlua-init-dofiles) (emlua-init-newrepl) #+end_src * Accessing the files with code-c-d If you understand how to create "[[http://angg.twu.net/eev-intros/find-eev-quick-intro.html#9][short hyperlinks]]" with [[http://angg.twu.net/eev-intros/find-eev-quick-intro.html#9.1][~code-c-d~]] in eev you can use something like this to point to the files in the emlua directory: #+begin_src elisp (code-c-d "emlua" "/tmp/emlua/" :anchor) (find-emluafile "") (find-emluafile "emlua-data.lua") (find-emluafile "emlua-init.lua") (find-emluafile "README.org") (find-emluafile "Repl1.lua") (find-emlua "Repl1.lua") (find-emlua "Repl1.lua" "EdrxEmacsRepl") #+end_src * Running the Lua REPL in Emacs The file [[http://angg.twu.net/emlua/emlua-repl.el.html][~emlua-repl.el~]] defines a function called [[http://angg.twu.net/emlua/emlua-repl.el.html#eepitch-emlua][~eepitch-emlua~]], that is similar to [[http://angg.twu.net/eev-intros/find-eev-quick-intro.html#6][~eepitch-shell~]], but whose [[http://angg.twu.net/eev-intros/find-eev-quick-intro.html#6.2][target]] is the Lua interpreter in the dynamic module. Take a look at the comments at the top of the file [[http://angg.twu.net/emlua/emlua-repl.el.html][~emlua-repl.el~]]. Here is a [[http://angg.twu.net/IMAGES/2022eepitch-emlua-0.png][screenshot]], * Testing everything You should probably be able to test everything in just three steps: 1) copy the block below to an Emacs buffer, 2) adjust the ~EMACS_DIR~, 3) run the block by typing @@html:<kbd><f8></kbd>@@ on each line. The bullets will behave as [[http://angg.twu.net/eev-intros/find-eev-quick-intro.html#6.1][red stars]], as explained [[http://angg.twu.net/2020-list-packages-eev-nav.html#f8][here]]. #+begin_src • (eepitch-shell) • (eepitch-kill) • (eepitch-shell) rm -Rfv /tmp/emlua/ mkdir /tmp/emlua/ cd /tmp/emlua/ git clone https://github.com/edrx/emlua . make EMACS_DIR=$HOME/bigsrc/emacs29 • (add-to-list 'load-path "/tmp/emlua/") • (require 'emlua-repl) • (emlua-init) • (eepitch-emlua) • (eepitch-kill) • (eepitch-emlua) print(2 + 3) print(2 + 3 + 4) = 2, 3, 4 = 2 + nil = EdrxEmacsRepl PPP(EdrxEmacsRepl) PPPV(EdrxEmacsRepl.__index) #+end_src * This is a prototype At this moment ~emlua~ isn't very useful /per se/, but it is very easy to hack and extend. * Ideas In Agda the same symbol can have different meanings depending on the context, and the key @@html:<kbd>M-,</kbd>@@ can be used to go the source code of the symbol at point. This is implemented by storing the location of the source of each symbol in a buffer in its [[http://www.gnu.org/software/emacs/manual/html_node/elisp/Text-Properties.html][text properties]]. See the screenshot below (click to enlarge it): @@html:<a href="2022agda-mode-prop.png"><IMG SRC="2022agda-mode-prop-small.png"></a>@@ The function [[http://angg.twu.net/emlua/emlua-repl.el.html#emlua-dostring+][~emlua-dostring+~]] in ~emlua-repl.el~ executes Lua code and interprets the result as elisp code to be executed by Emacs. We can use it to generate text with properties, and we can use ~eepitch-emlua~ to develop interactively the Lua functions that we will call using ~emlua-dostring+~. Emacs can display SVG images - see the packages [[https://elpa.gnu.org/packages/svg.html][svg]] and [[https://github.com/dalanicolai/sketch-mode][sketch-mode]] - and we can use ~emlua-dostring+~ to create and modify SVG images. # Local Variables: # coding: utf-8-unix # modes: (org-mode fundamental-mode) # org-html-postamble: nil # End: