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

"Parent expression" hack #23

Open
oakmac opened this issue Dec 27, 2015 · 5 comments
Open

"Parent expression" hack #23

oakmac opened this issue Dec 27, 2015 · 5 comments

Comments

@oakmac
Copy link
Owner

oakmac commented Dec 27, 2015

This issue is to track the "parent expression" hack that is described in the README.

Please add to it if you experience a significant problem or have ideas for a better approach.

@shaunlebron
Copy link
Contributor

If the cursor is at line n, we cannot reliably identify the starting line of its highest-level parent expression without parsing all lines 0 to n. proof is straightforward. Furthermore, a line starting with a ( is neither necessary nor sufficient for determining the start of a list expression because:

  • it could be inside a string
  • top-level expressions can still be indented

only thing I can think of at the moment is to isolate and apply parinfer's lisp reader in a minimal way just for finding this line number. regardless of how the API exposes this, I think this is the only way to reliably get this data.

@oakmac
Copy link
Owner Author

oakmac commented Dec 27, 2015

For clarity:

The purpose of the "parent expression" hack is not to detect the start of top-level expressions with perfect accuracy. As you noted, that would obviously require parsing the file - which is exactly the expensive computational cost we are trying to avoid for performance reasons while editing.

The purpose is to quickly detect something that looks like a parent expression. Without fully parsing, this will always be a guess and always have edge cases that are not covered (like the two cases you mention above).

The purpose of this issue is to track cases where this breaks under normal development circumstances. Presumably, users of Parinfer buy into the idea that there is a relationship between Lisp code structure and indentation. In Lisp dialects that adhere to this idea, I am not aware of one that doesn't start parent expressions at the beginning of a line as a strong convention. I suspect someone who didn't want to follow that convention in their code would likely not choose Parinfer as an editing mode in the first place.

@shaunlebron
Copy link
Contributor

a surprising result, but the reader can now identify all top-level open-parens of a 2800 line file in ~7ms. So I plan to offload the responsibility of fast change processing to a new pure change function, tracked here: https://github.com/shaunlebron/parinfer/issues/75

@kyleerhabor
Copy link

kyleerhabor commented Jun 10, 2022

Although this is an old issue, is this why expressions like this have weird behavior?

;; Take this code.
(ds.cdn/resize (ds.cdn/effective-user-avatar user) size)

;; If you delete the opening `(` at `ds.cdn/effective-user-avatar`, you're left with:
(ds.cdn/resize ds.cdn/effective-user-avatar user) size

;; But if you had the code separated line-for-line like this:
(ds.cdn/resize
  (ds.cdn/effective-user-avatar user)
  size)

;; And tried deleting again, you'd be left with this
;; (which is correct, according to http://shaunlebron.github.io/parinfer/#paredit-emerges).
(ds.cdn/resize
  ds.cdn/effective-user-avatar user
  size)

@oakmac
Copy link
Owner Author

oakmac commented Jun 10, 2022

is this why expressions like this have weird behavior?

No; this behavior is unrelated to the parent expression hack.

In the case you have described, Parinfer does not have enough information to decide whether to close the paren after user or size. The decision to close either way comes with trade-offs explored in this issue and these test cases.

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

3 participants