weixin_39553352 2020-11-29 12:07
浏览 0

Leading close-parens

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

  • 写回答

5条回答 默认 最新

  • weixin_39553352 2020-11-29 12:07
    关注

    reverted test cases from f1808ba46d04a5496f9fc2db882d6fb699e1ac3d until i decide which option to take

    评论

报告相同问题?