liquid

qqq 2018-01-02T06:57:09.000026Z

this is a completely serious question: @mogenslund: is there any plans on setting up a webserver + rendering liquid output into svg

qqq 2018-01-02T06:57:15.000067Z

this is what I am imagining:

qqq 2018-01-02T06:57:30.000033Z

liquid fires up, runs a ring server, has websocket

qqq 2018-01-02T06:57:53.000074Z

there is a minimal *.cljs file, which talks to the jvm side, and it (1) routes keystroke / mouse clicks back to jmv and (2) gets a new svg object, which it displays

qqq 2018-01-02T06:58:07.000009Z

the main.cljs file is minimal and basically never changes; all the logic is doine in clojure

qqq 2018-01-02T06:58:16.000044Z

there should not be latency ikssues so longa s everything is over localhost

qqq 2018-01-02T06:58:52.000006Z

so now we get all the power of dom/svg rendering, but we don't have to deal with cljs, ahd all the logic + scripts + extensions stay in jvm land; this also allows the editor to still make system calls

qqq 2018-01-02T06:58:54.000113Z

[/end idea]

mogenslund 2018-01-02T07:26:24.000051Z

Hi @qqq. Thank you for making suggestions. I think I need a bit of clearification of what you want to achieve. By "liquid output", do you mean just the text editor view? An not something custom rendered within the editor? Like "(render-elephant)" which will then produce the image of an elephant when going to localhost? Right now, if you start liquid with "--server" and go to "localhost:8520" in a browser (Chrome seems to give the best experience) then you can use the editor within the browser. It uses JavaScript to update the changed lines. It should be possible to make "localhost" return svg as alternative, I just need to understand the usecase to be able to implement the right solution.

qqq 2018-01-02T11:50:44.000086Z

Here's the idea I've had for a while, and perhaps there is something fundamentally flawed with it since no one has done this yet. I want a Clojure IDE where: 1. the "GUI" is rendered in dom/svg on localhost:8000 2. all the logic / 'backend' is running on clojure/jvm ==== The way this would work is: 1. I run "start-ide project-dir" -- it runs the jvm, loads up clojure, and sets up a ring server + websocket on 8000 2. I point my browser at localhost:8000 3. at every keystroke, (in the browser) an event is sent back to the clojure/jvm logic code, which processes the keystroke, generates a new dom/svg tree, sends it back via websocket, and my localhost:8000 shows the new data 4. if everything is localhost, the latency should be < realtime ===== 1. Why has the backend be in Clojure/JVM, why not do everything in CLJS? 1a. CLJS in the browser can not modify the filesystem / make OS calls. I want my IDE to be able to do those. 1b. In practice, the Clojure REPL has worked better for me than any CLJS REPL. 2. Why use the DOM/SVG/WebBrowser as the GUI instead of Terminal / JFrame ? 2a. I don't have a good answer to this, besides "I just want to have the full power the DOM/SVG at my fingertips for displaying output."

qqq 2018-01-02T11:50:55.000196Z

@mogenslund: ^

qqq 2018-01-02T11:51:46.000150Z

So the idea is we take the editor/ide, split it into "front-end/back-end", and instead of having the front-end be Terminal/JFrame, we make it DOM/SVG in a browser.

qqq 2018-01-02T11:53:17.000165Z

I believe this would be better than: * better than emacs because: I can script in CLJ instead of eliksp; front end of dom/svg is more expressive than emacs/gtk * better than atom because I can script in CLJ instead of javascript

mogenslund 2018-01-02T12:01:32.000248Z

But is that not what you get, if you start Liquid with the "--server" flag? Then you can access Liquid from a browser on port 8520 with localhost:8520. Or you can run with "--server --port=8000" to have it on port 8000. If you have the liq.jar you can just execute java -jar liq.jar --server --port=8000 or from the source folder with clj -m dk.salza.liq.core --server --port=8000

mogenslund 2018-01-02T12:02:09.000257Z

@qqq

qqq 2018-01-02T12:06:09.000022Z

WTF, this is already implemented? I have to try this now. 🙂

qqq 2018-01-02T12:06:47.000159Z

based on the video linked on the github page, I incorectly thought it was terminal/jframe only

qqq 2018-01-02T12:10:52.000292Z

is there a lein or boot command to run from src? for some reason, I actually don't have clojure installed on a system-wide path (i.e. it's accessible only via boot/lein)

mogenslund 2018-01-02T12:13:54.000046Z

From source you should be able to just run lein run --server --port=8000

qqq 2018-01-02T12:14:18.000141Z

trying that now; was just writing a boot file 🙂

qqq 2018-01-02T12:14:37.000019Z

whoa

qqq 2018-01-02T12:14:50.000082Z

I'm sold.

qqq 2018-01-02T12:15:40.000177Z

wait, you changed hjkl to jkli ? 🙂

qqq 2018-01-02T12:15:51.000178Z

I guess it makes an "wasd" style arrow

mogenslund 2018-01-02T12:18:29.000272Z

Yes I did that. And JL beginning of line and end of line. I have not done any fancy resize, but you can adjust the size at startup with: lein run --server --port=8000 --rows=50 --columns=160

qqq 2018-01-02T12:19:15.000051Z

this is amazing

qqq 2018-01-02T12:19:15.000305Z

https://imgur.com/a/t1ONs

qqq 2018-01-02T12:19:29.000241Z

is there something wrong with my left hand side? it's not the "repl answer" that I see in your videos

qqq 2018-01-02T12:20:01.000274Z

or is that a lambda ascii art .?

qqq 2018-01-02T12:21:01.000262Z

n/m, I get https://imgur.com/a/GVkAH now

qqq 2018-01-02T12:21:03.000290Z

all looks good

qqq 2018-01-02T12:23:49.000056Z

this is amazing, I just defined a function + executed it

qqq 2018-01-02T12:25:40.000184Z

how is this only 4906 linesof code w/o any dependencies besides cloljure-complete ?

qqq 2018-01-02T12:27:28.000272Z

@mogenslund: I don't see any cljs / cljc / js files in the source tree; where is the client side code?

mogenslund 2018-01-02T12:30:46.000178Z

The js code is just generated as strings inside src/dk/salza/liq/adapters/webadapter.clj and returned to the browser.

qqq 2018-01-02T12:31:58.000104Z

just found it myself via webpage -> inspect -> hmm, hand written html starts grepping for html file --> nothing found starts grepping for substrings --> adapter/webadapter.clj, see this big (str " .... ") blob this is impressive

qqq 2018-01-02T12:45:26.000124Z

@mogenslund: so I just finished skimming webadapter.clj ; are the highlihts the following: 1. this is done via http-get requests, not websockets 2. if auto-update is turned on (default off), we pull every 20 ms 3. updates are of the form: line-id : raw-html-for-that-line [ this also explains how you got color in the dom output] there's some keymap defined -- is this just common names for weird characters? (I'm not sure why it exists since I can't find the corresponding a-z A-'Z 0-9)

mogenslund 2018-01-02T12:57:41.000058Z

Yes it is done via http get. Autoupdate is only useful if multiple user are accessing the editor at the same time, so Bob will see if Alice is moving the cursor. Yes, line ids with raw html is the way I send the changes. Internally I store keys as keywords like :a 😛 :c :space :enter etc. Conversion from "a" to :a is done automatically, while special symbols are done manually. I have a general internal representation of a view. In the tty.clj it is translated to terminal codes, in the JFrame it is translated into Graphics commands and for web.clj it is translated into html. I also have a "recorder view". Which just translates it into a series of changes which can be replayed.

mogenslund 2018-01-02T13:02:55.000196Z

Each step from input until a generic view is created is described in this document: https://github.com/mogenslund/liquid/wiki/Data-Transformations So creating a new view is done by translating the last data structure to specific view commands.

qqq 2018-01-02T13:09:24.000307Z

That doc is really useful. Especially the secion on sliders + synta x highlighting. I have the following confusion: Based on section "Sliders"< I get the impression that each buffer = 1 slider. However, there is a latter section "split into lines", which seems to imply one slider / line when highlighting? What is going on here?

mogenslund 2018-01-02T13:16:20.000059Z

The syntax highlight is sort of injected into the slider (a copy). Then the slider is transformed into a list of lines. Here it is not a slider anymore. It is an intermediate step between having a slider with syntax highlight and having a list of lines for "printing". I have not looked into it yet, but a am playing with the thought of using the slider as an even more general structure, so I do not have to make these abusive in between steps.

qqq 2018-01-02T13:18:37.000063Z

I know very little about editor internals. I think emacs uses something similar to slider. However, it seems very weird to have to constantly convert before/after <-> 2d matrix of chars For example, implementing 'i" seems to be like: look at :before, figure out current column from that, then look at :before again, to, based on \r\n, get previous line, then shift a bunch of chars over to :after whereas in a 2d view, it's (update-in [.... ::y] dec) 🙂

mogenslund 2018-01-02T13:29:26.000092Z

When I started creating the editor, my main thought was to create a very robust editor without a view, considering all characters equal, including newlines. The slider is incredibly fast a when inserting text at point and moving the cursor. And it is very vel covered with tests. So my second steps was to implement as much as possible of editor operations in terms of the slider. So everything is pretty until something needs to be rendered (there is line wrap and possible multiple views of the same buffer.) Since I have learned a lot about text editors, since I began, I do consider rewriting some parts, espacially the views.

mogenslund 2018-01-02T13:35:53.000357Z

I have a performance test for the slider which does around 200,000 editor operations within ½ second. I think it is the key to few codelines, that my basis is very robust and very fast.

mogenslund 2018-01-02T13:50:51.000175Z

But maybe the update-in is fast also. I was actually surprised about the good performance if vector for another project. If I was to change I think I would have to define an interface and compare performance directly. Right now I also only split the visual part of the slider into lines and only apply syntax highlight to the visual part as well, to avoid a lot of processing on large files.

qqq 2018-01-02T14:01:43.000004Z

A big difference between you and me -- is that you actually wrote an editor, whereas my knowledge is only from reading stuff. 🙂

mogenslund 2018-01-02T14:36:14.000315Z

But I do like improvement suggestions, anyway 🙂 And sometimes I actually do change code based on feedback 🙂 One of the most demanding actions when doing a text editor is actually moving the cursor up and down when a line is wrapped multiple times, so that is usually the case I consider, when I consider changing implementation (And I really hate that this action requires knowledge about the view)

qqq 2018-01-02T14:37:33.000441Z

I wonder if you can get the best of both words via: (this doesn't solve line wrapping issue)

{::before-lines ;; vector of lines
::cur-line-before-chars ;; vector of chars
::cur-line-after-chars ;; vector of chars
;;after-lines ;; vector of lines
}

qqq 2018-01-02T14:38:25.000450Z

I'm really in this weird situation where the only two languages I currently use are elisp + clojure; soon to be possibly on clojure. As such, I'm fasinated by structure/ast editors, and saying fuck it to the whole notion of strings/chars.i

mogenslund 2018-01-02T15:06:31.000020Z

But this will probably require splitting a vector when moving up and down. I think, if the implementation is done with a vector of vectors then the position should be implemented as just a row number and a column number, so must non inserting/deleting operations would just be updating those two numbers. But I still think it is hard to compete with just basic operations on the head of two lists.

qqq 2018-01-02T21:54:26.000371Z

1. Yes, this would still require splitting vectors on up/down. 2. It mainly avoids the "re-split string into lines" on "vertical operations" switching topics a bit: are there any features from https://github.com/oakes/Nightcode or https://github.com/arthuredelstein/clooj you are looking to borrow ?