fennel repl on a unix socket

phoen
Daniel Barlow 2022-07-01 22:28:41 +01:00
parent 03b32ffa7e
commit 798dd9ed5c
4 changed files with 69 additions and 1 deletions

View File

@ -25,6 +25,13 @@ As of 2022 these principles are more aspirational than actual.
is suboptimally hairy, at least for the moment: Nix makes a wrapper
script for the Lua executable that has appropriate `LUA_PATH` and
`LUA_CPATH` settings, but it doesn't do the same for kiwmi.
## Connecting to the repl
If you are using the example rc.fnl, it opens a Unix socket that you
can connect to and interact with a Fennel REPL. I use
[socat](http://www.dest-unreach.org/socat/) for this purpose:
$ socat - unix-connect:${XDG_RUNTIME_DIR}/kiwmi-repl.wayland-1.socket
# TODO

9
rc.fnl
View File

@ -1,7 +1,16 @@
(local { : GdkPixbuf } (require :lgi))
(local { : view } (require :fennel))
(local socket-repl (require :socket-repl))
(let [repl-socket-name
(..
(: (os.getenv "XDG_RUNTIME_DIR") :gsub "/$" "")
"/kiwmi-repl."
(os.getenv "WAYLAND_DISPLAY")
".socket"
)]
(socket-repl.start repl-socket-name))
(fn texture-from-file [renderer filename]

View File

@ -1,7 +1,7 @@
with import <nixpkgs> {} ;
let p = callPackage ./. {};
in (p.overrideAttrs (o:{
nativeBuildInputs = [pkgs.gdb];
nativeBuildInputs = with pkgs; [gdb socat];
shellHook = ''
export LUA_PATH=`lua -e 'print(package.path)'`
export LUA_CPATH=`lua -e 'print(package.cpath)'`

52
socket-repl.fnl Normal file
View File

@ -0,0 +1,52 @@
(local { : fdopen } (require "posix.stdio"))
(local fcntl (require "posix.fcntl"))
(local unistd (require "posix.unistd"))
(local socket (require "posix.sys.socket"))
(local { : repl } (require :fennel))
(fn watch-fd [fd mode handler]
(kiwmi:event_loop_add_fd fd mode handler))
(fn unix-socket-listener [pathname on-connected]
(let [sa {:family socket.AF_UNIX
:path pathname
}
fd (socket.socket socket.AF_UNIX socket.SOCK_STREAM 0)]
(socket.bind fd sa)
(socket.listen fd 5)
(watch-fd
fd fcntl.O_RDWR
#(let [connected-fd (socket.accept $1)]
(on-connected connected-fd)))
))
(fn start [pathname]
(print pathname)
(unistd.unlink pathname)
(unix-socket-listener
pathname
(fn [fd]
(let [sock (fdopen fd "w+")
repl-coro (coroutine.create repl)]
(print :fd fd :sock sock)
(watch-fd fd fcntl.O_RDONLY
#(coroutine.resume repl-coro (unistd.read $1 1024)))
(coroutine.resume repl-coro
{:readChunk
(fn [{: stack-size}]
(sock:write
(if (> stack-size 0) ".." ">> "))
(sock:flush)
(coroutine.yield))
:onValues
(fn [vals]
(sock:write (table.concat vals "\t"))
(sock:write "\n"))
:onError
(fn [errtype err]
(sock:write
(.. errtype " error: " (tostring err) "\n")))
})))))
{ : start }