-
Notifications
You must be signed in to change notification settings - Fork 40
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
handling auto-indent #59
Comments
some extra links from @snoe for solving item 2: |
paredit.js uses the following rules (from
|
The plan is to add a
Lastly, in Paren Mode, we can auto-calculate |
In regards to indentation, there are cases where tab is expected to be 8 spaces and opening file with parinfer on (in indent mode) messes it completely |
which parinfer plugin allows you to open a file in indent mode without processing in paren mode first? |
parinfer-mode dor emacs. |
I haven't had a ton of time to mess with it, so this is a bit of a knee-jerk reaction, but I'm not a fan of how Indent Mode can now easily get into a state where pressing the delete key seemingly doesn't work. (def m {:a 1
|}) From this state, the user can't delete, and instead they have to move the cursor somewhere else to kind of unlock themselves. I'm sure with some time, I'd get used to it, but it's definitely a bit weird. EDIT: As mentioned in the other thread, I've been using Atom, with Parinfer for balancing parens along with Paredit solely for newline auto-indentation (which seems to work decently well). I don't know about Vim users. |
yeah, it's a bit of a stopgap solution to run Paren Mode when a line starts with a close-paren. It fixes a lot of edge cases that I can dig up if needed. the new "smart" mode may be able to only auto-indent after a newline is inserted. Otherwise, we can revive the Would you expect similar behavior for the following case? (foo m {:a 1
|} bar) |
Oh wow, that example is a tricky one. Maybe it could be possible for Parinfer to not let the user end up in that kind of a state at all? So I'm assuming that the code started as: (foo m {:a 1|} bar) ...and the user pressed enter to end up at your example. Would it work if when the user presses enter, instead of producing: (foo m {:a 1
|} bar) ...Parinfer produced something more indent-mode-ish, like: (foo m {:a 1
|}
bar) ? |
your example is actually what I tried in Newline Mode, which I threw away in favor of Paren Mode. The problem is that this edge-case occurs not just after pressing Enter but also for Backspace. Paren Mode just allowed us to continue operating without splitting lines in surprising ways. It's a weird state that I couldn't resolve perfectly. |
@rgdelato there's not a lot of discussion happening in these issues, so i'm still patient to summarize past context, especially for someone who has good ideas around edge cases. please ask away if you have more ideas/questions. also helps me to reevaluate past decisions since my perspective is changing everyday |
(def m {:a 1
|}) I did some work using Smart Mode tonight and ran into this case. It is definitely weird to press Delete and not have the cursor move. I think you may be able to account for this in the Parinfer API without requiring editor plugins to "send you which keys were pressed". I think with the changes array + cursor information you can detect if Delete (or other "remove one character behind the cursor") operation occurred and then adjust the result accordingly. |
Just confirmed that this behavior only happens when |
I could special case this by removing
but that would be bad here:
|
I asked on Slack about what should happen when the user presses "delete" from here: (def m {:a 1
|} bar) @timgilbert suggested that this should happen: (def m {:a 1|} bar) which is an interesting idea. It's pretty clean: if you would go past a boundary with a leading close paren, jump to the previous line. I think it might be pretty cool if it doesn't end up feeling jarring in practice. In a similar vein, this solution might also work? (def m {:a 1}
|bar) if you would go past a boundary with a leading close paren, you lose the close paren and all contiguous whitespace after it. This also seems pretty clean, though maybe users would expect to get their close paren back if they press space from this result? You could imagine a case where that would make sense, such as pressing "space" from here: (def m '({:a 1}
|) bar) An alternate, but more complicated idea is that you'd temporarily end up here, with a close paren in a place that it clearly doesn't belong: (def m {:a 1
|} bar) ...but then after you move your cursor away, you'd be reformatted to this: (def m {:a 1}
bar) This potentially introduces a weird state where the user can type (or paste) more stuff that's indented incorrectly: (def m {:a 1
:b 2|} bar) Which I think might okay as long as we can fix them? (def m {:a 1
:b 2|} bar) But I wouldn't be surprised if this last idea turns out to have some pretty rough edge-case implications and/or feel wrong when actually using it in practice. |
Some light necromancy Is there a mathematical reason "at the beginning of line, followed by words" is treated differently from "not at the beginning of line, followed by words"? For me doing anything to the close-paren in response to a newline inserted before it(immediately or no) is a pretty clear violation of the visual language: paren trains are grey to represent "managed by parinfer", other parens are black to represent "not managed by parinfer", a black paren suddenly disappearing is jarring. This is probably also related to the current handling breaking undo-redo: |
As Parinfer works now (at least in Spacemacs), if I'm in this state, (defn foo [a b]
(let [x (+ a b)]
x))| and want to make a sibling for (defn foo [a b]
(let [x (+ a b)]
x|)) I don't have to count, since the editor highlights the matching open bracket, I know which form a backspace will get me into. Then if I hit enter, I'm still inside the I could see the proposed autoindent behavior being usable once I get used to it, but it seems less nice compared to how it works now. However, it would still be pretty good if a shift-tab did a dedent to the next appropriate spot. Counting the right number of backspaces is a bit harder, especially if the parent open bracket is a ways up. |
There are two extra features related to auto-indentation that Parinfer users are starting to expect. Parinfer may grow in scope to handle these cases somehow, or we will have to detail how this can be handled external to it:
Specifically, @snoe and @SevereOverfl0w expect the following from item 1: when pressing enter at the end of the last line:
They expect the cursor to be at the following position:
This behavior is handled in vim by using a mode called
autoindent
(seen here), which trivially copies the indentation of the previous line.The behavior for item 2 can be handled by
vim-clojure-static
, which defines configurable rules for how to indent forms.These two modes conflict with each other inside vim, so a solution to this problem must combine them when appropriate.
The text was updated successfully, but these errors were encountered: