Skip to content

Latest commit

 

History

History
269 lines (205 loc) · 9.43 KB

README.org

File metadata and controls

269 lines (205 loc) · 9.43 KB

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 in a shell buffer is trivial - see these slides, the page of my presentation at the EmacsConf2021, or this tutorial of eepitch - but Emlua does something different.

To test Emlua you will need: 1) an Emacs compiled with support for dynamic modules, 2) liblua5.3-dev or something equivalent to it, and 3) eev.

At this moment all the tests are either in test blocks or in sexps in comments, so you will need eev to run them - but eev is a 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>@@

The low-level way

The low-level way to test Emlua is to run the test blocks in ~emlua.cpp~. Here is a copy of the body of the first test block:

rm -Rfv /tmp/emlua/
mkdir   /tmp/emlua/
cd      /tmp/emlua/
git clone https://github.com/edrx/emlua .
make

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”:

make EMACS_DIR=$HOME/bigsrc/emacs29

Then load the module with this sexp,

(load "emlua.so")

The test blocks in ~emlua.cpp~ also contain sexps that let you run some very low-level tests, like this one:

(emlua-dostring "
  a = a or 0
  a = a + 1
  return 22+33, '44', {}, a, nil
")

The result of the sexp above is this:

["55" "44" "table: 0x55a0f1979040" "0" "nil"]

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 ~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:

(emlua-dostring (emlua-format "a,b = %s,%s" 2.34 "foo bar"))
(emlua-dostring "return a, type(a), b")
;;   -->          ["2.34" "number" "foo bar"]

Two Lua REPLs written in Lua

The file Repl1.lua contains two Lua REPLs written in Lua. They can both be tested by first running this ~setenv~ to make Lua use my init file,

(setenv "LUA_INIT" "@/tmp/emlua/edrxlib.lua")

and then running the test blocks in Repl1.lua. The REPL implemented by the class ~EdrxRepl~ is very simple, and the other one, implemented by the class ~EdrxEmacsRepl~, is a variant of EdrxRepl that 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 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:

(add-to-list 'load-path "/tmp/emlua/")
(emlua-init-so)
(emlua-init-dofiles)
(emlua-init-newrepl)

Accessing the files with code-c-d

If you understand how to create ”short hyperlinks” with ~code-c-d~ in eev you can use something like this to point to the files in the emlua directory:

(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")

Running the Lua REPL in Emacs

The file ~emlua-repl.el~ defines a function called ~eepitch-emlua~, that is similar to ~eepitch-shell~, but whose target is the Lua interpreter in the dynamic module. Take a look at the comments at the top of the file ~emlua-repl.el~.

Here is a 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>&lt;f8&gt;</kbd>@@ on each line. The bullets will behave as red stars, as explained here.

• (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)

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 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 ~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 svg and sketch-mode - and we can use emlua-dostring+ to create and modify SVG images.