-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathREADME.html
499 lines (451 loc) · 18.4 KB
/
README.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<!-- 2022-03-28 Mon 16:50 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Emlua: run Lua in Emacs as a module</title>
<meta name="author" content="Eduardo Ochs" />
<meta name="generator" content="Org Mode" />
<style>
#content { max-width: 60em; margin: auto; }
.title { text-align: center;
margin-bottom: .2em; }
.subtitle { text-align: center;
font-size: medium;
font-weight: bold;
margin-top:0; }
.todo { font-family: monospace; color: red; }
.done { font-family: monospace; color: green; }
.priority { font-family: monospace; color: orange; }
.tag { background-color: #eee; font-family: monospace;
padding: 2px; font-size: 80%; font-weight: normal; }
.timestamp { color: #bebebe; }
.timestamp-kwd { color: #5f9ea0; }
.org-right { margin-left: auto; margin-right: 0px; text-align: right; }
.org-left { margin-left: 0px; margin-right: auto; text-align: left; }
.org-center { margin-left: auto; margin-right: auto; text-align: center; }
.underline { text-decoration: underline; }
#postamble p, #preamble p { font-size: 90%; margin: .2em; }
p.verse { margin-left: 3%; }
pre {
border: 1px solid #e6e6e6;
border-radius: 3px;
background-color: #f2f2f2;
padding: 8pt;
font-family: monospace;
overflow: auto;
margin: 1.2em;
}
pre.src {
position: relative;
overflow: auto;
}
pre.src:before {
display: none;
position: absolute;
top: -8px;
right: 12px;
padding: 3px;
color: #555;
background-color: #f2f2f299;
}
pre.src:hover:before { display: inline; margin-top: 14px;}
/* Languages per Org manual */
pre.src-asymptote:before { content: 'Asymptote'; }
pre.src-awk:before { content: 'Awk'; }
pre.src-authinfo::before { content: 'Authinfo'; }
pre.src-C:before { content: 'C'; }
/* pre.src-C++ doesn't work in CSS */
pre.src-clojure:before { content: 'Clojure'; }
pre.src-css:before { content: 'CSS'; }
pre.src-D:before { content: 'D'; }
pre.src-ditaa:before { content: 'ditaa'; }
pre.src-dot:before { content: 'Graphviz'; }
pre.src-calc:before { content: 'Emacs Calc'; }
pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
pre.src-fortran:before { content: 'Fortran'; }
pre.src-gnuplot:before { content: 'gnuplot'; }
pre.src-haskell:before { content: 'Haskell'; }
pre.src-hledger:before { content: 'hledger'; }
pre.src-java:before { content: 'Java'; }
pre.src-js:before { content: 'Javascript'; }
pre.src-latex:before { content: 'LaTeX'; }
pre.src-ledger:before { content: 'Ledger'; }
pre.src-lisp:before { content: 'Lisp'; }
pre.src-lilypond:before { content: 'Lilypond'; }
pre.src-lua:before { content: 'Lua'; }
pre.src-matlab:before { content: 'MATLAB'; }
pre.src-mscgen:before { content: 'Mscgen'; }
pre.src-ocaml:before { content: 'Objective Caml'; }
pre.src-octave:before { content: 'Octave'; }
pre.src-org:before { content: 'Org mode'; }
pre.src-oz:before { content: 'OZ'; }
pre.src-plantuml:before { content: 'Plantuml'; }
pre.src-processing:before { content: 'Processing.js'; }
pre.src-python:before { content: 'Python'; }
pre.src-R:before { content: 'R'; }
pre.src-ruby:before { content: 'Ruby'; }
pre.src-sass:before { content: 'Sass'; }
pre.src-scheme:before { content: 'Scheme'; }
pre.src-screen:before { content: 'Gnu Screen'; }
pre.src-sed:before { content: 'Sed'; }
pre.src-sh:before { content: 'shell'; }
pre.src-sql:before { content: 'SQL'; }
pre.src-sqlite:before { content: 'SQLite'; }
/* additional languages in org.el's org-babel-load-languages alist */
pre.src-forth:before { content: 'Forth'; }
pre.src-io:before { content: 'IO'; }
pre.src-J:before { content: 'J'; }
pre.src-makefile:before { content: 'Makefile'; }
pre.src-maxima:before { content: 'Maxima'; }
pre.src-perl:before { content: 'Perl'; }
pre.src-picolisp:before { content: 'Pico Lisp'; }
pre.src-scala:before { content: 'Scala'; }
pre.src-shell:before { content: 'Shell Script'; }
pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
/* additional language identifiers per "defun org-babel-execute"
in ob-*.el */
pre.src-cpp:before { content: 'C++'; }
pre.src-abc:before { content: 'ABC'; }
pre.src-coq:before { content: 'Coq'; }
pre.src-groovy:before { content: 'Groovy'; }
/* additional language identifiers from org-babel-shell-names in
ob-shell.el: ob-shell is the only babel language using a lambda to put
the execution function name together. */
pre.src-bash:before { content: 'bash'; }
pre.src-csh:before { content: 'csh'; }
pre.src-ash:before { content: 'ash'; }
pre.src-dash:before { content: 'dash'; }
pre.src-ksh:before { content: 'ksh'; }
pre.src-mksh:before { content: 'mksh'; }
pre.src-posh:before { content: 'posh'; }
/* Additional Emacs modes also supported by the LaTeX listings package */
pre.src-ada:before { content: 'Ada'; }
pre.src-asm:before { content: 'Assembler'; }
pre.src-caml:before { content: 'Caml'; }
pre.src-delphi:before { content: 'Delphi'; }
pre.src-html:before { content: 'HTML'; }
pre.src-idl:before { content: 'IDL'; }
pre.src-mercury:before { content: 'Mercury'; }
pre.src-metapost:before { content: 'MetaPost'; }
pre.src-modula-2:before { content: 'Modula-2'; }
pre.src-pascal:before { content: 'Pascal'; }
pre.src-ps:before { content: 'PostScript'; }
pre.src-prolog:before { content: 'Prolog'; }
pre.src-simula:before { content: 'Simula'; }
pre.src-tcl:before { content: 'tcl'; }
pre.src-tex:before { content: 'TeX'; }
pre.src-plain-tex:before { content: 'Plain TeX'; }
pre.src-verilog:before { content: 'Verilog'; }
pre.src-vhdl:before { content: 'VHDL'; }
pre.src-xml:before { content: 'XML'; }
pre.src-nxml:before { content: 'XML'; }
/* add a generic configuration mode; LaTeX export needs an additional
(add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
pre.src-conf:before { content: 'Configuration File'; }
table { border-collapse:collapse; }
caption.t-above { caption-side: top; }
caption.t-bottom { caption-side: bottom; }
td, th { vertical-align:top; }
th.org-right { text-align: center; }
th.org-left { text-align: center; }
th.org-center { text-align: center; }
td.org-right { text-align: right; }
td.org-left { text-align: left; }
td.org-center { text-align: center; }
dt { font-weight: bold; }
.footpara { display: inline; }
.footdef { margin-bottom: 1em; }
.figure { padding: 1em; }
.figure p { text-align: center; }
.equation-container {
display: table;
text-align: center;
width: 100%;
}
.equation {
vertical-align: middle;
}
.equation-label {
display: table-cell;
text-align: right;
vertical-align: middle;
}
.inlinetask {
padding: 10px;
border: 2px solid gray;
margin: 10px;
background: #ffffcc;
}
#org-div-home-and-up
{ text-align: right; font-size: 70%; white-space: nowrap; }
textarea { overflow-x: auto; }
.linenr { font-size: smaller }
.code-highlighted { background-color: #ffff00; }
.org-info-js_info-navigation { border-style: none; }
#org-info-js_console-label
{ font-size: 10px; font-weight: bold; white-space: nowrap; }
.org-info-js_search-highlight
{ background-color: #ffff00; color: #000000; font-weight: bold; }
.org-svg { width: 90%; }
</style>
</head>
<body>
<div id="content" class="content">
<h1 class="title">Emlua: run Lua in Emacs as a module</h1>
<div id="outline-container-org2782536" class="outline-2">
<h2 id="org2782536"><span class="section-number-2">1.</span> Introduction</h2>
<div class="outline-text-2" id="text-1">
<p>
Emlua implements a <i>very minimalistic</i> way to run a Lua interpreter
inside Emacs <i>as a module</i>. Running a Lua REPL in Emacs <a href="http://www.gnu.org/software/emacs/manual/html_node/emacs/Interactive-Shell.html">in a shell
buffer</a> is trivial - see <a href="http://angg.twu.net/LATEX/2021emacsconf.pdf#page=3">these slides</a>, the <a href="http://angg.twu.net/emacsconf2021.html">page</a> of my presentation at
the EmacsConf2021, or <a href="http://angg.twu.net/eev-intros/find-eev-quick-intro.html#6">this tutorial of eepitch</a> - but Emlua does
something different.
</p>
<p>
To test Emlua you will need: 1) an Emacs compiled with support for
<a href="http://www.gnu.org/software/emacs/manual/html_node/elisp/Dynamic-Modules.html">dynamic modules</a>, 2) <a href="https://packages.debian.org/bullseye/liblua5.3-dev">liblua5.3-dev</a> or something equivalent to it,
and 3) <a href="http://angg.twu.net/#eev">eev</a>.
</p>
<p>
At this moment all the tests are either in <a href="http://angg.twu.net/emacsconf2021.html">test blocks</a> or in <a href="http://angg.twu.net/eev-intros/find-eev-quick-intro.html#3">sexps in
comments</a>, so you will need <a href="http://angg.twu.net/#eev">eev</a> to run them - but eev is a <a href="http://angg.twu.net/eev-intros/find-eev-intro.html#1">very
non-invasive package</a> and it is easy to turn eev-mode on and off, so,
ahem, "everybody should have eev installed". 🙃
</p>
<p>
Here is a screenshot - click on it to enlarge:
</p>
<p>
<a href="2022eepitch-emlua-0.png"><IMG SRC="2022eepitch-emlua-0-small.png"></a>
</p>
</div>
</div>
<div id="outline-container-org0a096dc" class="outline-2">
<h2 id="org0a096dc"><span class="section-number-2">2.</span> The low-level way</h2>
<div class="outline-text-2" id="text-2">
<p>
The low-level way to test Emlua is to run the test blocks in
<a href="http://angg.twu.net/emlua/emlua.cpp.html#tests-in-tmp"><code>emlua.cpp</code></a>. Here is a copy of the body of the first test block:
</p>
<div class="org-src-container">
<pre class="src src-sh">rm -Rfv /tmp/emlua/
mkdir /tmp/emlua/
cd /tmp/emlua/
git clone https://github.com/edrx/emlua .
make
</pre>
</div>
<p>
It downloads a copy of emlua from the git repository and compiles
<code>emlua.cpp</code>. You may need to set some directories - for example, on my
machine I need this instead of a plain "<code>make</code>":
</p>
<div class="org-src-container">
<pre class="src src-sh">make EMACS_DIR=$HOME/bigsrc/emacs29
</pre>
</div>
<p>
Then load the module with this sexp,
</p>
<div class="org-src-container">
<pre class="src src-elisp">(load "emlua.so")
</pre>
</div>
<p>
The test blocks in <a href="http://angg.twu.net/emlua/emlua.cpp.html#tests-in-tmp"><code>emlua.cpp</code></a> also contain sexps that let you run
some very low-level tests, like this one:
</p>
<div class="org-src-container">
<pre class="src src-elisp">(emlua-dostring "
a = a or 0
a = a + 1
return 22+33, '44', {}, a, nil
")
</pre>
</div>
<p>
The result of the sexp above is this:
</p>
<div class="org-src-container">
<pre class="src src-elisp">["55" "44" "table: 0x55a0f1979040" "0" "nil"]
</pre>
</div>
<p>
The function <code>emlua-dostring</code> is very primitive - it returns a vector
of strings in case of success, and a string in the case of errors.
</p>
</div>
</div>
<div id="outline-container-org9e3b04b" class="outline-2">
<h2 id="org9e3b04b"><span class="section-number-2">3.</span> Exchanging data</h2>
<div class="outline-text-2" id="text-3">
<p>
The file <a href="http://angg.twu.net/emlua/emlua-data.el.html"><code>emlua-data.el</code></a> implements a very basic way to send strings
and numbers to Lua code. After loading it we can set the Lua variables
<code>a</code> and <code>b</code> to <code>2.34</code> and <code>"foo bar"</code> by running this:
</p>
<div class="org-src-container">
<pre class="src 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"]
</pre>
</div>
</div>
</div>
<div id="outline-container-org9138b81" class="outline-2">
<h2 id="org9138b81"><span class="section-number-2">4.</span> Two Lua REPLs written in Lua</h2>
<div class="outline-text-2" id="text-4">
<p>
The file <a href="http://angg.twu.net/emlua/Repl1.lua.html">Repl1.lua</a> contains two Lua REPLs written in Lua. They can
both be tested by first running this <a href="http://www.gnu.org/software/emacs/manual/html_node/emacs/Environment.html"><code>setenv</code></a> to make Lua use <a href="http://angg.twu.net/emlua/edrxlib.lua.html">my init
file</a>,
</p>
<div class="org-src-container">
<pre class="src src-elisp">(setenv "LUA_INIT" "@/tmp/emlua/edrxlib.lua")
</pre>
</div>
<p>
and then running the test blocks in <code>Repl1.lua</code>. The REPL implemented
by the class <a href="http://angg.twu.net/emlua/Repl1.lua.html#EdrxRepl"><code>EdrxRepl</code></a> is very simple, and the other one, implemented
by the class <a href="http://angg.twu.net/emlua/Repl1.lua.html#EdrxEmacsRepl"><code>EdrxEmacsRepl</code></a>, is a variant of <code>EdrxRepl</code> that
<a href="http://angg.twu.net/emlua/Repl1.lua.html#WithFakePrint">redirects</a> the outputs of <code>print</code> and <code>io.write</code> to a string before
writing it to stdout. The REPL that runs inside Emacs uses the class
<code>EdrxEmacsRepl</code>, but calls methods in it that return the output as a
string.
</p>
</div>
</div>
<div id="outline-container-org9127379" class="outline-2">
<h2 id="org9127379"><span class="section-number-2">5.</span> The file emlua-init.el</h2>
<div class="outline-text-2" id="text-5">
<p>
The file <a href="http://angg.twu.net/emlua/emlua-init.el.html">emlua-init.el</a> 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:
</p>
<div class="org-src-container">
<pre class="src src-elisp">(add-to-list 'load-path "/tmp/emlua/")
(emlua-init-so)
(emlua-init-dofiles)
(emlua-init-newrepl)
</pre>
</div>
</div>
</div>
<div id="outline-container-org2bb39b1" class="outline-2">
<h2 id="org2bb39b1"><span class="section-number-2">6.</span> Accessing the files with code-c-d</h2>
<div class="outline-text-2" id="text-6">
<p>
If you understand how to create "<a href="http://angg.twu.net/eev-intros/find-eev-quick-intro.html#9">short hyperlinks</a>" with <a href="http://angg.twu.net/eev-intros/find-eev-quick-intro.html#9.1"><code>code-c-d</code></a> in
eev you can use something like this to point to the files in the emlua
directory:
</p>
<div class="org-src-container">
<pre class="src 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")
</pre>
</div>
</div>
</div>
<div id="outline-container-org6548f4c" class="outline-2">
<h2 id="org6548f4c"><span class="section-number-2">7.</span> Running the Lua REPL in Emacs</h2>
<div class="outline-text-2" id="text-7">
<p>
The file <a href="http://angg.twu.net/emlua/emlua-repl.el.html"><code>emlua-repl.el</code></a> defines a function called <a href="http://angg.twu.net/emlua/emlua-repl.el.html#eepitch-emlua"><code>eepitch-emlua</code></a>,
that is similar to <a href="http://angg.twu.net/eev-intros/find-eev-quick-intro.html#6"><code>eepitch-shell</code></a>, but whose <a href="http://angg.twu.net/eev-intros/find-eev-quick-intro.html#6.2">target</a> is the Lua
interpreter in the dynamic module. Take a look at the comments at the
top of the file <a href="http://angg.twu.net/emlua/emlua-repl.el.html"><code>emlua-repl.el</code></a>.
</p>
<p>
Here is a <a href="http://angg.twu.net/IMAGES/2022eepitch-emlua-0.png">screenshot</a>,
</p>
</div>
</div>
<div id="outline-container-orgb04c7a1" class="outline-2">
<h2 id="orgb04c7a1"><span class="section-number-2">8.</span> Testing everything</h2>
<div class="outline-text-2" id="text-8">
<p>
You should probably be able to test everything in just three steps: 1)
copy the block below to an Emacs buffer, 2) adjust the <code>EMACS_DIR</code>, 3)
run the block by typing <kbd><f8></kbd> on each line.
The bullets will behave as <a href="http://angg.twu.net/eev-intros/find-eev-quick-intro.html#6.1">red stars</a>, as explained <a href="http://angg.twu.net/2020-list-packages-eev-nav.html#f8">here</a>.
</p>
<pre class="example">
• (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)
</pre>
</div>
</div>
<div id="outline-container-orgdae8e6b" class="outline-2">
<h2 id="orgdae8e6b"><span class="section-number-2">9.</span> This is a prototype</h2>
<div class="outline-text-2" id="text-9">
<p>
At this moment <code>emlua</code> isn't very useful <i>per se</i>, but it is very easy
to hack and extend.
</p>
</div>
</div>
<div id="outline-container-org749b052" class="outline-2">
<h2 id="org749b052"><span class="section-number-2">10.</span> Ideas</h2>
<div class="outline-text-2" id="text-10">
<p>
In Agda the same symbol can have different meanings depending on the
context, and the key <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 <a href="http://www.gnu.org/software/emacs/manual/html_node/elisp/Text-Properties.html">text
properties</a>. See the screenshot below (click to enlarge it):
</p>
<p>
<a href="2022agda-mode-prop.png"><IMG SRC="2022agda-mode-prop-small.png"></a>
</p>
<p>
The function <a href="http://angg.twu.net/emlua/emlua-repl.el.html#emlua-dostring+"><code>emlua-dostring+</code></a> in <code>emlua-repl.el</code> 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
<code>eepitch-emlua</code> to develop interactively the Lua functions that we
will call using <code>emlua-dostring+</code>.
</p>
<p>
Emacs can display SVG images - see the packages <a href="https://elpa.gnu.org/packages/svg.html">svg</a> and <a href="https://github.com/dalanicolai/sketch-mode">sketch-mode</a> -
and we can use <code>emlua-dostring+</code> to create and modify SVG images.
</p>
</div>
</div>
</div>
</body>
</html>