-
Notifications
You must be signed in to change notification settings - Fork 55
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
Create zipper at root node #189
Comments
No problemo! Even though it is a dupe, it is clearly written and easy to understand. ❤️ I think we can close. |
Oh wait... I see what you were doing there. Maybe |
This is kinda sorta also related to #70. |
Exactly... I was proposing a function like this: (defn of-string*
"Create and return zipper from all forms in Clojure/ClojureScript/EDN string `s`. Starts at the root `:forms` node.
Optional `opts` can specify:
- `:track-position?` set to `true` to enable ones-based row/column tracking, see [docs on position tracking](/doc/01-user-guide.adoc#position-tracking).
- `:auto-resolve` specify a function to customize namespaced element auto-resolve behavior, see [docs on namespaced elements](/doc/01-user-guide.adoc#namespaced-elements)"
([s] (of-string s {}))
([s opts]
(some-> s p/parse-string-all (edn* opts)))) |
Ah. You are matching the Then for consistency, this proposal option would also include a new |
Yes, although my one hesitation is that I'm not sure
Yes, that would make sense. As with any library that has lots of composable functions, any "shortcut" quickly leads to a Cambrian explosion. |
The nice thing about the If we took the options approach instead:
Meh. I think we have an existing convention. My feeling is trying to correct history (that might not be even terribly flawed) is more confusing than going with the flow. We already have a kitchen sink of functions, what's 2 more? If we added these functions, we could also revise So yeah, I'd be fine with new If we ever get to #70, it would only make sense for the non-starred versions ( Let's see if @borkdude can find any flaws/gotchas with this approach. |
I agree with the original proposed solution |
Am looking into this and have been reminded, by the code, of a historical nuance.
I remember not liking the fact that Because Edit: this is nitty grittier than I remembered: |
These new zip API functions are the same as their of-string and of-file counterparts except that they do no auto navigation at all. Closes clj-commons#189
* Add rewrite-clj.zip of-string* and of-file* These new zip API functions are the same as their of-string and of-file counterparts except that they do no auto navigation at all. Closes #189 * usage of deprecated edn functions in user guide switch to of-node functions instead * minor typo in user guide example
Problem/Opportunity
Many files begin with copyright notices, documentation, or other kinds of comments and whitespace.
z/of-string
navigates past these to the first non-whitespace node (or to the root:forms
node if the file is only whitespace.)z/find-last-by-pos
navigates usingz/next*
, meaning it navigates "forward" from the current node.Together this makes it unnecessarily challenging to navigate based on cursor position, especially to leading comment nodes.
Consider, for example, clojure-lsp. It starts with data provided by a text editor: the contents of a file and a cursor position. clojure-lsp wants to navigate to the node at that position. It doesn't know a priori whether the file did or did not start with comments, or whether it was entirely comments. It also doesn't know whether the cursor position was in the leading comments, or somewhere after them. So, after parsing with
z/of-string
, it can't callz/find-last-by-pos
until it has taken all of these variations into account.In other words, this tests fails:
Proposed Solution
I'd like a new function
z/of-string*
that stays at the root:forms
node. With this function,z/find-last-by-pos
will reliably find any node based on cursor position, even in leading comments. I believe this new function can be a copyof-string
that usesedn*
instead ofedn
.Alternative Solutions
There are a few workarounds.
(-> text z/of-string z/leftmost*)
. This will navigate either A) to the first node in the file, regardless of whether it was code or whitespace, or B) to the root node if the file was only whitespace. In either casez/find-last-by-pos
can find any node.(let [loc (z/of-string text)] (or (z/up loc) loc))
. This will navigate to the root:forms
node, taking into account the possibility that you were already there. This is an awkward way to undo the navigation thatz/edn
does.Alternatively, this can be solved in calling applications. See, clojure-lsp/clojure-lsp#1252 for a proposal to do this for clojure-lsp.
Additional context
This was the root cause of clojure-lsp/clojure-lsp#1251, which has been temporarily patched in clojure-lsp.
Action
I'd be happy to submit a PR for
z/of-string*
.The text was updated successfully, but these errors were encountered: