after much deliberation on https://github.com/shaunlebron/parinfer/issues/98, i'm still uncertain about what to do, but I have a better understanding of my options:
An extra rule
Lines starting with a close-paren represent a common intermediate state that Indent Mode will not allow unless we append a special rule. For example:
clj
;; 1. Initial state
(foo|) bar
;; 2. User presses enter
(foo
|) bar
;; 3. Indent Mode processes as normal (bad)
(foo
| bar)
The problem is that the user may expect to start typing at step 2 without
realizing that step 3 had already changed the AST on them. For example, if they
typed boo at step 2, this is the expected vs actual outcome:
;; Expected
(foo
boo|) bar
;; Actual
(foo
boo| bar)
The same type of problem can occur when backspacing on a line:
clj
;; 1. Initial state
(foo
boo|) bar
;; 2. User deletes 'boo'
(foo
|) bar
;; 3. Indent Mode processes as normal (bad)
(foo
| bar)
To allow the expected outcome, we must first let the user temporarily stay at step 2. That is, we must allow a line to start with a close-paren if the cursor is on it.
clj
(foo
|) bar
^ cursor allows indentation point to be a close-paren
When processing the leading close-paren, we must determine if it is matching or not. To recap, Indent Mode will correct close-parens at the end of the previous line depending on the indentation length of the current line. This means we must process this first before determining if the leading close-paren is valid.
clj
;; first the indentation length is measured from the leading close-paren
(foo
__) bar
^ leading close-paren at x=2
;; then we correct paren trail of previous line
(foo_
^ no corrections needed!
) bar
^ thus, leading close-paren is matching
But if the leading close-paren is further to left, it may result in being mismatched:
clj
;; first the indentation length is measured from the leading close-paren
(foo
) bar
^ leading close-paren at x=0
;; then we correct paren trail of previous line
(foo)
^ close-paren inserted due to following indentation
) bar
^ thus, leading close-paren is UNMATCHED
Thus, our rule must take both cases into account. First, for matching:
clj
;; matching leading close-paren
(foo
) bar
;; output choice A - leave it
(foo
) bar
;; output choice B - remove it
(foo
_ bar)
;; output choice C - error
(foo
) bar
^ error leading-close-paren
;; output choice D - join it to previous line
(foo) bar
;; output choice E - remove it, and keep indentation
(foo
bar)
;; output choice F - correct w/ paren mode
(foo)
bar
And if unmatched:
clj
;; unmatched leading close-paren
(foo
) bar
;; output choice A - error
(foo)
) bar
^ error unmatched-close-paren
;; output choice B - remove it
(foo
_ bar)
;; output choice C - remove it, and keep indentation
(foo)
bar
;; ... ?
该提问来源于开源项目:shaunlebron/parinfer