Closed shaunlebron closed 7 years ago
none of these options are good, so I'm looking at a fourth option to allow these invalid intermediate states, like we did here: http://shaunlebron.github.io/parinfer/#knowing-when-parens-move-in-indent-mode
I will try clamping the paren trails opposite to any open-paren on the current cursor line. That should prevent swallowing subsequent lines unintentionally, at least until the cursor is moved away.
With this extra rule, I want to provide more affordance for when a paren may be displaced after cursor movement. I think returning a list of warnings
like we do errors would be sufficient for this.
For example:
(println |{:a 1
:b 2}
bar)
Deleting println
shows:
(|{:a 1
:b 2}
^ warning: paren is currently being held (will be corrected if still invalid after editing)
bar)
The paren will have to be fixed if problem is still present after user is done editing (indicated by cursor position). More on this later.
Typing println
shows (and the warning clears)
(print| {:a 1
:b 2}
bar)
If bar
was originally indented like so:
(println |{:a 1
:b 2}
bar)
(print| {:a 1
:b 2}
^ warning: paren is currently being held (will be corrected if still invalid after editing)
bar)
If the user saves the file at this point, re-opening the file later will cause Paren Mode to correct indentation to preserve the intended structure (likewise corrected by Parlinter if project uses it).
But if the user moves the cursor away, we can add prevCursorLine
option to detect when to run Paren Mode in place (when cursor movement would result in structure changes):
(print {:a 1
:b 2}
bar)
^ dedented by 1 space to prevent structure change after cursor movement
We can not perform the indentation correction to prevent structure changes if we are not worried about it. But it seems like a good idea to follow what @DogLooksGood said:
IMO, when you want to edit some symbols, literals, etc, parens should never be changed. the indentation of bar, shouldn't affect the code struct.
If we do perform the correction, I also have to think about implications of the cursor moving as a result of change.
I have a idea, not sure if it covors all cases.
@DogLooksGood that could be a better idea when we start looking at characters inside the changes
option to perform inference. there are a lot of implications to explore there.
I think this new dedent behavior might warrant a separate "smart mode" function. Right now, the presence of the changes
option triggers this smart behavior, but this new dedent behavior is considered part of this smart mode, but must be on all the time since it is dependent on cursor position, not changes. Thus we need an explicit separate mode if we don't want this new behavior affecting original indent mode.
pasted from a brainstorm file:
|| adjust indentation of `4` to respect structure of these parens only
||
||
|| |||| lock the position of the close-parens opposite to these
|| ||||
vv vvvv
((|((((1
2
3)))))
^
|
| indentation of `4` must be corrected to respect this paren
4)
NON-ANNOTATED VERSION OF OUTPUT:
((((((1
2
3)))))
4)
INTERESTING, so moving to the right results in a full correction.
|| adjust indentation of `4` to respect structure of these parens only
|||||
|||||
||||| | lock the position of the close-parens opposite to these
||||| |
vvvvv v
(((((|(1
2
3)))))
^^^^
||||
|||| indentation of `4` must be corrected to respect these parens
4)
NON-ANNOTATED VERSION OF OUTPUT:
((((((1
^ 2
3)))))
4)
WHAT WE DISCOVERED
the resolution for INTERSECTING AREAS OF TENSION are equivalent?
WHAT the hell is INTERSECTING AREAS OF TENSION
Just an EXPRESSION ending with a Paren Trail containing multiple PRECARIOUS PARENS
WHAT the hell is PRECARIOUS PARENS
A close-paren that would move if the cursor was removed
Let's call this aforementioned EXPRESSION with PRECARIOUS PARENS a PRECARIOUS EXPRESSION?
---------------------
Does moving the cursor anywhere inside a precarious expression require full
resolution? YES?
PROVE IT
WAIT what are we trying to get to again?
Trying to see if we ever have to run a partial correction.
If we never have to run a partial correction, then maybe we can just run Paren Mode
when an expression leaves a state of tension.
RANDOM QUESTION:
(foo |(
^
moving the cursor before this paren should release a previously precarious expression?
conjecture: yes
RANDOM QUESTION: can I just run Paren Mode when a cursor releases a precarious expression?
conjecture: yes
RANDOM QUESTION: can there ever be more than one precarious expression?
conjecture: no
(as long as there is only one cursor)
CONJECTURE: moving the cursor outside of the HOLDING area:
- does not create another PRECARIOUS expression
- thus can be resolved by running Paren Mode on whole file
(foo |(
^^^^ HOLDING area of a precarious expression
HOW THEN do I detect the release of a precarious expression?
- previousCursor was in a holding area
- cursor is not in a holding area
DESIGN DRAFT for Smart Mode dedent resolution:
- if `changes` NOT passed and `previousCursor` IS passed
- detect release of precarious expression (using aforementioned steps)
- if detected, exit and run Paren Mode
implemented the current solution here: https://github.com/shaunlebron/parinfer/commit/24e31bbdbf792dbd15bc907c9887159cae13ba46
closing for now
from clojurians slack (lazy screenshot paste since clojurians log butchers the code blocks)