Next release of Janet should have native Plan 9 support :D

#plan9 #janetlang

@pixx Neat! What are you using Janet for on plan9?

I've been quite enjoying using it for my Wayland window manager recently: https://codeberg.org/ifreund/rijan/

Writing Wayland clients is a lot more ergonomic when one doesn't have to use C :)

rijan

A window manager for the river Wayland compositor

Codeberg.org
@ifreund @pixx this dons look like something fun to play with

@ifreund

So, this is a script I'm using for a plan9 chatroom. It's probably godawful janet, and that's without looking at that acme module lmao (acme is the text editor).

This script mounts a chatroom over TCP, TLS, whatever (using os/shell because I cheated, don't have a bunch of plan9 APIs implemented yet and this was a test of other things first). It opens windows for the editor (def win (string "/mnt/acme" (slurp "/mnt/acme/new"))), relays from the chatfile into both a main output and a "grepped" one for notifications, and then relays from an input window into the chat file.

So basically: I use it primarily as an alternative to the system shell for scripting just because Janet has a lot of really nice things for string manipulation and file handling. I actually kinda feel like it's semantically a lot closer to a middle ground between C and a scripting language 😅

(def name "noam")
(def separator "→")
(def service "gridchat")
(def mtpt "/n/chat")
(def channel "chat")

(import "./acme")
(def acme (acme/init))

(def command (string/format "srv -c %s %s %s" addr service mtpt))
(def channel (string mtpt "/" channel))

(if-not (= 0 (os/shell command))
(error "Unable to dial."))

(def chatwin (acme/newwin acme "/acme/chat/chat" "nomenu" "scratch"))
(def grepwin (acme/newwin acme "/acme/chat/grep" "nomenu" "scratch"))
(def inwin (acme/newwin acme "/acme/chat/input" "nomenu" "scratch"))
(set (chatwin :body) (acme/body chatwin :a))
(set (grepwin :body) (acme/body grepwin :a))

(def chatfile (file/open channel :r+))

(def pid (os/posix-fork))
(def buf (buffer/new 1024))

(if (nil? pid)
# FIXME: once event loop is in, can move grep to background.
(while true
(buffer/clear buf)
(def line (file/read chatfile :line buf))
(file/write (chatwin :body) line)
(file/flush (chatwin :body))
(if-not (nil? (string/find name line)) (do
(file/write (grepwin :body) line)
(file/flush (grepwin :body))
))
)
(while true
(buffer/clear buf)
(def line (string/trim (file/read (inwin :event) :line buf)))
(if (and
(string/has-prefix? "KI" line)
(string/has-suffix? "" line)
) (do
(acme/yoink inwin)
(def input (string/trim (string/slice (acme/yoink inwin) 0 -2)))
(acme/clear inwin)
(def msg (string/format "%s %s %s\n" name separator input))
(file/write chatfile msg)
(file/flush chatfile)
))
)
)

@pixx This script makes me want to find time to play with plan9 :D

I've also come to greatly appreciate the balance between abstraction, low-level system programming primitives, and simplicity offered by languages like Lua and Janet. Janet feels much comfier than Lua though for me :)