Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Investigate using Parinfer for form entry #73

Closed
mfikes opened this issue Nov 12, 2015 · 19 comments
Closed

Investigate using Parinfer for form entry #73

mfikes opened this issue Nov 12, 2015 · 19 comments

Comments

@mfikes
Copy link
Member

mfikes commented Nov 12, 2015

Parinfer is here.

Rationale:

  1. It is difficult to type on a mobile keyboard so the heavy inference could reduce explicit keystrokes for balancing parens, etc.
  2. Using key combinations (like paredit) would probably make things more difficult if we went down that path. (You'd probably need explicit barf/slurp buttons—maybe Parinfer makes much of this moot)
  3. This would provide a nice way to auto-indent forms as entered, which Replete currently does not do.

Implementation ideas:

• Replace the existing input text field with a small web view that has Parinfer hooked up to it.
• Sort out how to make the input web view automatically grow and shrink vertically.
• Make sure Parinfer can work in self-host / bootstrapped mode (if it needs to use the reader, analyzer, etc.)

@shaunlebron
Copy link
Contributor

Alternatively, you can keep the single-line text field, and still take advantage of auto-paredit. You just need a pure function of your input text, which does the following:

  • unmatched close-parens are removed
  • the group of close-parens at the end of the line are removed
  • auto-close all unclosed open-parens

parinfer has its own simplified reader, btw, which seemed to work against all the core clojure repos I could throw at it.

@mfikes
Copy link
Member Author

mfikes commented Nov 12, 2015

@shaunlebron Replete actually has a multi-line input field which dynamically adjusts vertical height to grow or shrink to accommodate the s-expression.

@shaunlebron
Copy link
Contributor

@mfikes just tried out the multi-line input field, great!

Just published [parinfer "0.1.0"] which you can use from ClojureScript. You can just transform the input field with indent-mode/format-text after every keystroke. details

@mfikes
Copy link
Member Author

mfikes commented Nov 20, 2015

@shaunlebron cool. I may give it a try. Doesn't sound difficult.

@shaunlebron
Copy link
Contributor

I can put together a PR if you want to decide whether it's enabled by default or not, and how to enable if not.

@mfikes
Copy link
Member Author

mfikes commented Nov 21, 2015

Initial hook is in place now. It is working.

8fd5bd2

This gets us into a position where we can experiment with ergonomics, caret positioning, etc.

@shaunlebron
Copy link
Contributor

sweet! 👍

@mfikes
Copy link
Member Author

mfikes commented Nov 21, 2015

parinfer-replete

@mfikes
Copy link
Member Author

mfikes commented Nov 21, 2015

@shaunlebron In the parinfer branch, I've updated the code so it correctly supplies :cursor-x and :cursor-line hints. But, when hitting return, things don't behave like on the Parinfer web page. For example, if typing (+ 2) and then hitting return, and then 3, you instead get (+ 2)3 with a trailing newline. I have a question: Does Parinfer assume that something else is auto-indenting prior to feeding text to it? Or does it doe the indenting? (I'm thinking this may explain the difference.)

@shaunlebron
Copy link
Contributor

right, parinfer doesnt do any auto-indenting when pressing enter since it
doesnt know anything about the last character pressed. i can see about
adding a 'pressed-enter?' option

On Saturday, November 21, 2015, Mike Fikes notifications@github.com wrote:

@shaunlebron https://github.com/shaunlebron In the parinfer branch,
I've updated the code so it correctly supplies :cursor-x and :cursor-line
hints. But, when hitting return, things don't behave like on the Parinfer
web page. For example, if typing (+ 2) and then hitting return, and then 3,
you instead get (+ 2)3 with a trailing newline. I have a question: Does
Parinfer assume that something else is auto-indenting prior to feeding text
to it? Or does it doe the indenting? (I'm thinking this may explain the
difference.)


Reply to this email directly or view it on GitHub
#73 (comment).

@mfikes
Copy link
Member Author

mfikes commented Nov 21, 2015

@shaunlebron Ahh interesting. I need to make sure that the "re-set cursor position after putting text in field" logic is right. An interesting philosophical aspect I'm seeing is that perhaps Paredit is geared towards editing source files (where you may have a sequence of forms), while REPLs want the user to enter a single form. I'll play around with it more to gain a better understanding of its behavior, design philosophy, etc.

@shaunlebron
Copy link
Contributor

if you're referring to your logic here, that is how I handled it in CodeMirror as well. And actually, my pressed-enter? option wouldn't work unless I returned a cursor position from format-text, which I will do eventually.

I think Paredit is still useful inside a single top-level form, given all the nested expressions you can transform inside.

@mfikes
Copy link
Member Author

mfikes commented Nov 21, 2015

@shaunlebron Yeah. I was also pondering the concept of cursor position being returned from format-text as well, motivated by the case where (+ 2\n) gets transformed to (+ 2)\n, which effectively moves the cursor, while the UI doesn't know to do so. :)

I agree, Paredit is proving extremely useful for a single form. I think the consequences of hitting return is the only corner case.

@mfikes
Copy link
Member Author

mfikes commented Nov 21, 2015

@shaunlebron Ahh... I think I've confirmed my suspicion: the Parinfer page is using CodeMirror's Clojure mode. So hitting return does more than inserting "\n" into the text. CodeMirror adds some spaces. If I can figure out how to do the same, I think I can replicate the experience on the Parinfer demo pages.

@shaunlebron
Copy link
Contributor

Well, Paren Mode already corrects dedented lines of text, albeit with just a one-space indentation. So we could just process the text with Paren Mode (instead of Indent Mode) when pressing enter. For example, pressing enter right before b here:

(def foo [a b])

will result in:

(def foo [a 
b])

which Paren Mode would correct to be:

(def foo [a 
          b])

I'll have to finish https://github.com/shaunlebron/parinfer/issues/54 for this to work when pressing enter before a close-paren though.

@mfikes
Copy link
Member Author

mfikes commented Nov 21, 2015

@shaunlebron Ahh. Cool. Sounds like a promising plan. Of course, don't rush—all of this is in an experimental branch of Replete where it can take its time to mature.

@shaunlebron
Copy link
Contributor

cool, I'll write a note here when it's done.

@shaunlebron
Copy link
Contributor

released parinfer 0.2.0. When pressing enter:

  • run Paren Mode instead of Indent Mode
  • advance cursor to first non-whitespace char

@mfikes
Copy link
Member Author

mfikes commented Nov 22, 2015

@shaunlebron Updated and looks great:

indent-return

@mfikes mfikes closed this as completed in 63859c6 Nov 23, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants