Fork me on GitHub
#parinfer
<
2016-02-22
>
shaunlebron01:02:30

@cfleming, yeah chris and I paired this afternoon to fix the selection issue you mentioned

shaunlebron01:02:52

when a selection is made, or if there are multiple cursors, atom-parinfer will not update the cursor position for you

cfleming01:02:03

I’ll replicate that logic, I think.

cfleming01:02:08

I’m just playing around with the idea of creating deltas instead of updating the lines in place - then the algorithm can be run in one pass over the original document, and the user could call a function to get new text with the deltas applied, or choose to receive the deltas.

cfleming01:02:32

Most editors won’t store the text as a single contiguous string, so applying small deltas will probably be more efficient.

cfleming01:02:07

If the change gets too tricky, I’ll just use the existing algorithm for now since I should get a release out sometime soon.

shaunlebron01:02:30

character-based diffs?

shaunlebron01:02:55

a nice property of parinfer is that it will never add or remove lines, just modifies existing ones

shaunlebron01:02:16

so that’s why the line-based deltas are so straightforward, i’m returning changedLines

cfleming01:02:47

Yeah, I saw that. Perhaps I’ll just use that to start since that’s (relatively) minimal.

shaunlebron01:02:07

just trying to understand what the delta change looks like, or what it’s doing

shaunlebron01:02:42

so instead of modifying the line in result.lines[i], you’re doing something else?

cfleming01:02:53

Right. Instead of scanning by line, I scan once over the whole text without splitting it into lines. I do the line bookkeeping when I see a \n

cfleming01:02:10

And instead of line/x combos, I just use an offset into the whole document.

cfleming01:02:40

Then the changes are stored as a list of start, end, replacement combos.

cfleming01:02:07

I’m worried about the garbage being created on every call to parinfer by taking the document and splitting it into lines.

cfleming01:02:30

On the JVM that used to re-use the same character array, but it now copies it instead.

cfleming01:02:37

I’m not sure about JS engines.

shaunlebron01:02:11

i think that’s feasible

cfleming01:02:25

Yeah, I don’t think the change is going to be too big.

shaunlebron01:02:29

the last version changed removeParenTrail

shaunlebron01:02:45

it used to remove the paren trail after processing every line

shaunlebron01:02:11

it’s now just popParenTrail, modifies the paren stack

cfleming01:02:28

It would also mean that you wouldn’t need the getLineEnding thing to re-join the lines.

shaunlebron01:02:43

anyway, no unnecessary modifications, and you can watch all line modifications at replaceWithinLine function

cfleming01:02:10

And it is probably feasible to apply the changes in whichever way is friendliest to the JS garbage collector.

cfleming01:02:32

I’m actually very impressed with how well V8 handles all the string concatenation though.

cfleming01:02:49

I guess they have to optimise it a lot since there’s no mutable option.

cfleming01:02:34

Anyway, I’m hoping to have it working this afternoon with a bit of luck, and we can see if we like it at that stage.

cfleming02:02:14

As an aside, I’m using http://wallabyjs.com to make the change, it’s lovely.

shaunlebron02:02:21

was it slow when splitting lines?

cfleming02:02:41

I’m not sure. I don’t know whether the JS engines re-use the backing char array or not.

cfleming02:02:21

The JVM used to but then they changed it since apparently people would often hold onto small substrings of very large backing arrays, which caused memory problems.

cfleming02:02:28

So substring() now copies instead.

cfleming02:02:09

But I’m not just thinking about memory pressure, I suspect that in practice applying diffs will be much better for performance in text editors, although I have no idea how to benchmark that.

shaunlebron02:02:40

i’m really liking the delta idea

shaunlebron02:02:48

are you trying this in parinfer.js first?

shaunlebron02:02:55

with wallaby somehow?

cfleming02:02:09

You’ll be pleased to hear that Wallaby shows great test coverage too, only a couple of edge cases not covered (tabs and \r\n)

shaunlebron02:02:47

awesome, would love to try this

cfleming02:02:55

I have the wallaby config if you want to try it, let me know.

shaunlebron02:02:57

yeah, i sort of changed my testing philosophy in parinfer, just focusing on the core inference stuff

cfleming02:02:13

Sure, that makes sense.

shaunlebron02:02:16

yeah, if you have time to share that

shaunlebron02:02:49

need to step out for an hour

shaunlebron02:02:04

awesome change btw if we can get that in

cfleming02:02:13

Sure, no problem

cfleming02:02:34

I think he has an atom plugin now, no vim sorry

cfleming02:02:48

Oh, and sublime too

shaunlebron02:02:59

haha, i don’t mind that

shaunlebron02:02:04

i’ll be moving to parinfer soon anyway

cfleming02:02:20

ok, talk to you later

cfleming02:02:55

@shaunlebron: Actually, one more advantage of the deltas is that you don’t actually need to track cursor or selection position - they’ll automatically be updated by the editor as the text is modified.

shaunlebron03:02:24

lol, yeah, the editor should totally take care of that. way simpler

cfleming03:02:54

I have about half the tests passing now

cfleming22:02:28

There are some tricky cases with this.

cfleming22:02:50

I had hoped that all edits would be applied to the document in source order, but that’s not the case.

cfleming22:02:44

For example, in (def foo [a b]], the second ] is removed first, because it’s unmatched.

cfleming22:02:55

Then the paren trail is corrected, which is tricky now.