Fork me on GitHub

Has anyone tried "embedding" sci in emacs? I always find I'm gradually implementing clojure in elisp no matter what I try to do, could be a shortcut. I'm not emacs proficient to know whether one could just use libsci or similar or maybe some persistent proc based approach.


Maybe you can just call out to bb for certain things?


That's definitely the easy path!


Does emacs have JS bindings maybe? (I don't think so right?) VSCode might be able to leverage SCI in extensions directly

excited 1

That is a very good point! I never felt at home in the vscode ui, but a sci based plugin might change everything


cc @pez - not sure if that's a fun idea to try out for something


Clover, a plugin by @mauricio.szabo already uses SCI to expose stuff in VSCode I believe

🙏 1

@tgg very interesting, emacs-ng integrated with deno - we could easily make something for that


@rahul080327 have you ever tried emacs-ng?


had a look during my year with emacs, looks promising! but my head and hand are quite vim key tuned for the 6+ years now and never used the emacs bindings too. Always felt im making whatever im typing in has to have vim motions. I'll admit EVIL is better than vim but neovim+lua is another level. Cant see others close to it. EVIL on emacs-ng wasnt that good last time i tried it or some issues or something


anyways the lua powered nvim ecosystem is amazing now, not much reason to look the the other way 😅


I always forget you're not using emacs :)


but if this means we can power emacs via sci with cljs, its definitely tempting


does neovim have js bindings or only lua?


can do a large set of bindings like lua, python, js, ruby etc. lua and vimscript are natively available


so sci + neovim is feasible then


nvim is made with a json rpc style so plugins just need to talk json rpc


oh right, so it could even be just a JVM


yeah its a very modular architechture, lang neutral, all GUIs for instance are also rpc based. very different from emacs and even vim


justc checked, python, ruby, node, perl have official sdks apart from lua and vimscript. also its LuaJIT so, quite the speed!


the parinfer plugin is in rust 😄


VS Code is probably very SCI friendly. Could be cool to expose the VS Code API that way in an extension. Would be a bit like AppleScript, I imagine. 😃


Any ideas of what you could achieve with such a thing?


It would make VS Code scriptable, is what I see. Since there is a generic executeCommand function in the API, I think extensions would also get scriptable. But it is rather late here and my brain is fried so I might not be thinking about it correctly.


OK, feel free to continue some other time :)


Haha. I hope that someone will try this!


I might try it, but first I have to have someone who proposes some crazy idea to me

excited 1

I don't know the VSCode API stuff that well :)


@U037TPXKBGS knows it better than most. Maybe we can get some input from him.


Definitely not an expert, but happy to think about stuff. Unfortunately I have no clue what y'all are talking about or what you want to achieve hahaha, would appreciate some context!


@U037TPXKBGS SCI is a CLJ(S) interpreter which works in the browser, or Node.js. This means you could evaluate Clojure in a VSCode plugin.


Ah for like custom user scripting perhaps?


Yeah. A scriptable editor. Using a nice scripting language with a REPL.


Is there any prior work, like extensions that let users do things in JS?


Clover already uses SCI to let users create custom REPL UI things I believe


Sounds an awful lot like emacs no? Hahaha idk actually, all i know is that emacs uses clisp for config or extension right? While it's true that executeCommand() would be easy to invoke in cljs, I'm pretty sure that only a minority of the vscode behavior/api are offered as commands - it could be a very limited start, though perhaps if expectations are set low enough anything is a good start lol. Scratch that, as long as you can eval arbitrary js (which I realize is the question here) you can just cljs and do the usual js interop stuff. If you can do that, you'd probably still be limited to vscode extension API not the internal API proper. The extension api is a great start though thinking-face


Yes, arbitrary JS interop is possible with SCI


And you can hook in any library you want to make that available to the evaluator


This notion of a scriptable editor is too foreign for me (beyond nominally) for me to understand exactly what we want here. I just looked at clover - what do we want that it doesn't do exactly? Do we want some means by which to run arbitrary code and modify vscode as it runs in real-time? Like building an extension for it, but without the compile-package-release-install cycle, replaced instead with an arbitrary number of scripts that you can edit and have reflected in real time? If I got some user stories or examples of envisioned usage, I might comprehend better. For example, do the following fall under what you folks are thinking of: 1. I want to create a new tab to the right that displays the git blame or commit history of the currently open file 2. I want to be able to select some arbitrary text/code, and have it pinned somewhere in another tab or to the right, keeping a list of "pinned" selections as I work on some wide ranging changes to some project so I don't have to open the files to remember what they contain 3. I want to adjust the color of the title bar arbitrarily at will in real time Or is it more like what I thought calva was already doing, where if I'm working on a clj project and I want to evaluate some forms at will and see their output inline or in the output window?


Yes, control VSCode using a script, so the three points


So a user can save their snippets in the settings


and maybe bind it to a shortcut


We don't know exactly what we want, we're just exploring possibilities


Interesting. Here comes stream of consciousness thinking out loud: 1. The way vscode extensions are loaded at runtime or startup time or whatever, is that the extension.js file (almost always a bundled artifact of some build process) is read and essentially "eval"ed and loaded into the current... process? runtime? as a named module, in whom a function with the name extension or something - essentially a main() - is called with an extension context object containing a bunch of API and state. 2. If our Extension X is loaded, and it can eval arbitrary js without a remote repl but literally by way of (unsafe of course) native eval() , said evaled js will get access to everything the Extension X has access to at runtime. 3. If we rely on external processes we'd have to wrap possibly every single vsc ext API in rpc/faux LSP handlers and do rpc calls between the ExtensionX/vsc process. 4. Therefore, assuming we keep it in-process we have to be able to basically do something like eval(cljs2Js(userInput)) to run stuff or like eval(cljs2Js(userInput).main(someContextObjMaybe)), forgetting async stuff for the time being, and starting with a single script or user input string


From what i gather clover runs js code via nrepl or something like that. Maybe I'm wrong about needing to be in process to retain access to unlimited API, so I'd have to see what clover or other prior arts in pure js have been capable of wrt vsc APIs


Maybe clover's creator can chime in!


It's not eval(cljs2JS(userInput)) since SCI is not a compiler, it's an interpreter: just sci.eval_string(userInput) is enough

wow 1

Thanks for your input, I'm tuning out now


Ok, about this... Atom does have support for adding arbitrary commands and control almost all aspect from what they call the "Init Script". VSCode have limited support for that. In theory it should be possible. But arbitrary commands like "add this line to the editor" may be impossible because there's limited API for it. But it's worth a try, honestly


What Clover does, is cheat a little bit - there's something on VSCode API called "tasks". Tasks are like "run thins command in a terminal". What VSCode added was the possibility to use a "virtual terminal", and that's where Clover hooks into. The reason to hook on tasks is because you can't add arbitrary commands to the VSCode API, and Tasks allow you to have keybindings, so it's the "less worse" way to do it 😄


Please ping me at #chlorine-clover (or @ mention me later) for tips about this 😄. I'm not really a VSCode user, and probably will never be, but I can somewhat show what I did 😄


@mauricio.szabo Maybe it helps explaining what you're using SCI for in Chlorine


@mauricio.szabo Btw, this was fake: But using your JS->CLJ translator, maybe it would work ;)

😆 1

Yeah, sounds fun! (Not really) 😄 So, about Clover: initially, I used SCI to allow for rendering things on the UI in different ways. For example, suppose one is designing a tic-tac-toe program. Instead of rendering the result as [[:X nil nil]...], they could render as a graphical element. I used hiccup for this approach, but there are things that became hard - like, for example, rendering a vector or list, where a traversal of every element was necessary. So I decided to send everything to SCI, and if a clojure form appeared, SCI would render it.


Then I though: why not go further? So I defined a config file that it's pure SCI-flavored ClojureScript, and each defn becomes a command for Clover to run. So you can, for example, decide to eval a result, tap> it, then render back at the editor easily. This made configs portable between VSCode and Atom, and finally, made possible to have a hot-reloadable config too. So, currently, that's how I'm using: both for evaluation results and configuration of the plug-in


Chlorine on Emacs? wow


(Not really, I still depend on Node.JS APIs. But yet, maybe it's an interesting experiment, to port some of the work on other plug-ins and tools to a SCI-compatible code, and then re-use everything!)


Ok, about this... Atom does have support for adding arbitrary commands and control almost all aspect from what they call the "Init Script". VSCode have limited support for that. In theory it should be possible. But arbitrary commands like "add this line to the editor" may be impossible because there's limited API for it. But it's worth a try, honestly