Fork me on GitHub
#parinfer
<
2016-02-11
>
snoe00:02:31

I've thought of turning on paren mode when pasting but haven't got around to trying it, I think it would make a lot of sense

cfleming00:02:16

Cursive can actually pre-process text on paste. This is something I’ve been thinking about doing for vanilla paredit - if the user tries to paste unbalanced text (by far the most common cause of unbalancing, for experienced users at least) I can pop up a window with the pasted text, highlight the bad parens and allow them to edit the text until it’s balanced before proceeding with the paste.

cfleming00:02:52

I’m thinking that in indent mode I’d adjust the indentation on paste so that it matches the point in the text that the user has pasted at.

cfleming00:02:10

In paren mode, perhaps do the same as I’m thinking for paredit.

cfleming00:02:05

Of course, lots of tricky corner cases if the user is replacing a selection with the pasted text, etc etc

snoe00:02:26

what if you run indent mode to balance the parens, then paste in with paren mode, which would indent for you

cfleming00:02:01

Interesting, I hadn’t considered that since parinfer wasn’t around when I started thinking about it.

cfleming00:02:25

But that actually sounds like a pretty nice idea.

cfleming00:02:04

I guess for an arbitrary paste, I’d have to run paren mode first (like the first time you open a file in the editor), then indent mode, then paren mode on paste?

cfleming00:02:11

I’d have to think about it.

cfleming00:02:37

I guess the difficulty is that the problematic case on paste is when it’s unbalanced, and neither parinfer mode handles that well.

snoe00:02:34

eh, it depends, pasting (let [foo bar and turning it into (let [foo bar]) with indent mode would make sense to me

mfikes00:02:06

@cfleming: I had to add special support for the paste use case for Planck's use of Parinfer, but I bet there isn't much to share with respect to it. (The paragraph below the YouTube video in http://blog.fikesfarm.com/posts/2016-02-10-indenting-with-parinfer.html .)

shaunlebron01:02:05

@cfleming my gut feeling is that the popup paste correction window has the right intentions, but will be difficult to get right

shaunlebron01:02:29

when copying multiple lines of text, the user may start at the beginning of a line or start at the first paren instead

shaunlebron01:02:15

pasting it somewhere has the same problems. they may paste at the beginning of a line or somewhere to the right

shaunlebron01:02:04

i would keep with the rules of indent mode here. users manually manage indentation and everything else falls in place

shaunlebron01:02:03

under these rules, pasting code seems to be predictable and correctable for the inevitable minor indentation mistakes that result

cfleming01:02:10

@shaunlebron: Ok, I’ll try that first and see how people find it.

cfleming02:02:13

How important is the cursorDx parameter?

cfleming02:02:20

It’s difficult to calculate in Cursive

shaunlebron02:02:35

good question

shaunlebron02:02:51

chris never figured it out in atom

shaunlebron02:02:01

i’ll give you an example in a minute, brb

cfleming02:02:06

In fact, several of the caret parameters are difficult to calculate, depending on how the event happens.

cfleming02:02:30

This is because IntelliJ makes the distinction between a document and an editor.

cfleming02:02:00

The modification event happens on the document, but the editor holds the caret position.

cfleming02:02:36

This is because you might have two editors open on the same document, or you might have modifications to a document that isn’t being edited (e.g. as a result of a refactoring)

cfleming02:02:06

In fact, this is trickier than I thought.

cfleming02:02:50

Also, is this a true statement: Paren mode only ever touches the leading indent of a line, and indent mode only ever deletes closing parens inside lines, and adds them at the end of lines?

shaunlebron03:02:48

short answer: cursorDx can be computed if there is an onChange event that communicates a portion of text that was added or removed and the position of the cursor

shaunlebron03:02:36

but it’s only important for pulling indentation of child expressions back when you move its open-paren container back

shaunlebron03:02:10

not many people are using paren-mode honestly

shaunlebron03:02:23

paren mode will move close-parens in some situations

shaunlebron03:02:46

(let [a 1
      ])

shaunlebron03:02:55

will be changed to:

cfleming03:02:34

Unfortunately, I get an onChange event, but I don’t have the caret position

cfleming03:02:22

Since there might be multiple editors looking at the doc, or none. I don’t think I have any way to determine whether a particular change is as a result of a user action in a particular editor.

shaunlebron03:02:04

it’s not something that is critical for a first run of parinfer in cursive

shaunlebron03:02:21

atom-parinfer has never had it, and no one has ever filed an issue

shaunlebron03:02:44

there are complaints about other things, but paren mode never seems to come up

shaunlebron03:02:53

i think folks are sticking to indent mode

cfleming03:02:03

What I can do is to maintain a list of open editors for a particular document. When I get a document event, I can see if the caret of any of those editors is at the boundaries of the change result - that is probably as a result of a change in that editor.

cfleming03:02:18

But there are some important cases that require knowing which line the caret is on, right?

shaunlebron03:02:55

part 2 of the design doc covers a bunch of cases that need it

cfleming03:02:48

The problem is I don’t think I can get that either.

cfleming03:02:07

Or at least, I’m going to have a set of them in the case where there is more than one editor.

cfleming03:02:58

I’ll probably have to modify the algorithm to clamp the paren trail on any of the caret lines.

shaunlebron03:02:19

that’s strange

cfleming03:02:45

Having more than one caret?

shaunlebron03:02:31

sorry, coming in and out of conversations

shaunlebron03:02:52

so yeah, seems strange that it’s hard to determine where the cursor is in a document

shaunlebron03:02:26

a document can have multiple editors

shaunlebron03:02:50

I think that’s fine

shaunlebron03:02:22

when an editor changes a document, process the document with that editor’s cursor information

shaunlebron03:02:36

I suppose we’re using cursor/caret interchangeably here

cfleming03:02:29

Right, IntelliJ uses caret for the typing position, and cursor for the mouse

cfleming03:02:34

Force of habit simple_smile

cfleming03:02:02

The problem is that on the document change event, I don’t know which editor (if any) caused the change.

shaunlebron03:02:03

hmm, is intellij open source?

shaunlebron03:02:11

might be a good PR

cfleming03:02:26

I don’t think they’ll change that.

cfleming03:02:46

It’s also possible there’s a way to do it that I’m not aware of.

cfleming03:02:55

I’ll ask on the forum.

shaunlebron03:02:13

yeah, that’s a good idea

shaunlebron03:02:55

makes me wonder if there are other types of plugins that would need such information

shaunlebron03:02:35

my first interaction with a text editor API was codemirror, which had this info readily available

shaunlebron03:02:51

so I assumed it was standard

cfleming03:02:02

Right, but codemirror only ever has a single document with a single editor.

cfleming03:02:17

i.e. they’re basically the same thing.

cfleming03:02:24

I wonder how e.g. sublime handles it.

shaunlebron03:02:29

i’ll check sublime-parinfer real quick

shaunlebron03:02:21

it has an on_modified event for every view

shaunlebron03:02:49

so I suppose there can be multiple views for a document

shaunlebron03:02:00

i.e. tabs/windows

cfleming03:02:10

So in the case where there are multiple views, parinfer will run multiple times?

shaunlebron03:02:29

well, I’m guessing here

shaunlebron03:02:45

but suppose I had two tabs opened to the same file

cfleming03:02:53

Because the on_modified doesn’t get the caret info, or didn’t use it at least.

shaunlebron03:02:37

editing on one view will cause the document to update

shaunlebron03:02:41

or its buffer, whatever

shaunlebron03:02:56

if the other view syncs, then that’s fine

shaunlebron03:02:11

the other view will only transform if its view’s on_modified is called

cfleming03:02:30

Yeah, depends if there are two on_modified events, or one and then the other doc is updated somehow.

cfleming03:02:57

But it’ll have its caret position moved and so forth, I’d expect it to get an update.

cfleming03:02:31

the other view, rather.

shaunlebron03:02:58

each view has a selection, which describes the caret position

cfleming03:02:30

Right, so it’s like an Editor in IntelliJ. The difference is that their on_modified receives the view, whereas mine doesn't

shaunlebron03:02:54

I wouldn’t expect the secondary view to kick off an on_modified event based on the first view

cfleming03:02:57

Again, for a text editor they can assume that all changes are as a result of user action in a view

shaunlebron03:02:08

i would expect them to sync views though

cfleming03:02:09

IntelliJ can't

cfleming03:02:41

I’ll ask in the forum and I’ll ask my mole at JetBrains too

shaunlebron03:02:39

yeah, share the post link here when you do

shaunlebron03:02:52

curious to see

cfleming03:02:08

Sadly, you may just see tumbleweeds

cfleming03:02:20

Although they’re getting better recently.

shaunlebron03:02:36

oh, I imagined a larger intellij community

cfleming03:02:55

No, the plugin community is pretty small.

cfleming03:02:06

In part because the doc + support is so bad.

cfleming03:02:21

I spend a lot of time diving through the IntelliJ source code.

cfleming03:02:31

But it is humungous

shaunlebron03:02:33

well that makes cursive all the more impressive then

shaunlebron03:02:47

at least it’s open source though

shaunlebron03:02:02

i guess that makes up for lack of docs

shaunlebron03:02:23

but you said humungous, so maybe not

cfleming03:02:11

I’m now curious, and am running cloc over it.

cfleming03:02:08

Oh dear, the IntelliJ source appears to have hung cloc, that’s not good.

shaunlebron03:02:31

I’ve never used cloc

shaunlebron03:02:46

find . -name “*.java” | xargs wc -l is my poorman’s cloc I guess

shaunlebron04:02:21

haha, that’s worked for smaller codebases at least

cfleming04:02:14

That claims 96kloc, which I don’t believe simple_smile

cfleming04:02:34

Given that cloc appears to have slowed to a crawl after 30k files

cfleming04:02:40

~/d/community (master)> cloc .
   78158 text files.
   67816 unique files.
   14590 files ignored.

 v 1.62  T=605.99 s (95.9 files/s, 9563.3 lines/s)
----------------------------------------------------------------------------------------
Language                              files          blank        comment           code
----------------------------------------------------------------------------------------
Java                                  46707         571050         689600        3201834
Python                                 6086         103644         155924         416348
XML                                    1845          12473           3389         281530
XSD                                     256          14623           3093         148651
HTML                                   2133           6639           3829          58595
Kotlin                                  312           5821           4956          29677
<snip>
Erlang                                    1              0              0              1
----------------------------------------------------------------------------------------
SUM:                                  58140         726580         875219        4193527
----------------------------------------------------------------------------------------

cfleming04:02:57

You didn’t believe me when I said humungous simple_smile

cfleming04:02:14

3.2M actual LOC

shaunlebron04:02:17

blank/comment?

shaunlebron04:02:30

where are the code lines?

cfleming04:02:36

The last column

shaunlebron04:02:05

oh, my slack window was too narrow

cfleming04:02:32

It takes like 20 mins+ to check out.

cfleming04:02:09

They peak at about 400 commits/day

cfleming04:02:41

Yole appears to top out at about 100/day just on his own 😐

shaunlebron04:02:09

yeah, intellij must do so many things

shaunlebron04:02:27

shame api isn’t documented

cfleming04:02:47

And that’s just one product of theirs (well two actually, PyCharm is in there too)

cfleming04:02:00

But all the Ultimate stuff which is closed source is probably a similar size.

shaunlebron04:02:07

i feel spoiled

shaunlebron04:02:16

codemirror was <9k

shaunlebron04:02:23

it was such a pleasure to read

shaunlebron04:02:34

can’t imagine cutting my teeth on 3.2m

cfleming04:02:55

Yeah, Marijn has a post where he talks about the pleasure of working on small, self-contained codebases

cfleming04:02:14

He was a nice guy actually, I hung out with him at a conference last year.

shaunlebron04:02:27

cool, does he speak at conferences? never looked

cfleming04:02:34

I’m actually wondering how this relates to multiple carets

cfleming04:02:51

Yeah, he spoke about Tern at Curry On where I met him.

cfleming04:02:33

Do Stripe give you a conference budget?

shaunlebron04:02:05

cool, I’ll check that out, I like his coding style and his project focus

shaunlebron04:02:16

yeah, stripe does I think

cfleming04:02:41

I recommend Curry On, it was great last year.

cfleming04:02:48

Ok, got to go, thanks for the help

cfleming04:02:54

I’ll let you know how I get on.

shaunlebron04:02:05

k cool, catch you later

shaunlebron05:02:26

btw, handling multiple cursors in parinfer would fix the issue like you said in the post

cfleming06:02:40

@shaunlebron: Yeah, I think I’ll do that tomorrow if I don’t get a response

cfleming06:02:49

It should be a small modification.