Closed zachdaniel closed 4 months ago
That looks like a great idea. I was asking myself if we could use Code.Fragment. container_cursor_to_quoted/2
(available since Elixir 1.17) here.
iex> Code.Fragment.container_cursor_to_quoted("if ... do")
{:ok, {:if, [line: 1], [{:..., [line: 1], []}, [do: {:__cursor__, [line: 1], []}]]}}
iex> Code.Fragment.container_cursor_to_quoted("... |> Enum.filter(")
{:ok,
{:|>, [line: 1],
[
{:..., [line: 1], []},
{{:., [line: 1], [{:__aliases__, [line: 1], [:Enum]}, :filter]}, [line: 1],
[{:__cursor__, [line: 1], []}]}
]}}
The ...
for skipping would be nice. The function move_to_cursor
could accept opts to set the skip marker.
Zipper.move_to_cursor(zipper, "if ... do")
Zipper.move_to_cursor(zipper, "if :ignore do", skip: :ignore)
Hmm....that is pretty nice. I like that better than ___skip___
😆
curious to see if it will play out
So, I've used __cursor__
again to line up with that function, and ...
for skipping, but I did just realize that IIRC ...
is going to be an operator used by Elixir in 1.18. So we probably can't use that. I think it will have to be something else. Maybe __
?
I think a variation using container_cursor_to_quoted
would make sense, but it would be a different function since it only has to match on what "leads up to" the cursor, whereas this has to match up before and after.
Yes, with container_cursor_to_quoted
it would be a different function but a variant that could make sense. It's a shame that we can't use ...
. I think __
could also fit there.
When move_to_cursor
works we could try something like Regex.named_caputres
😄
{zipper, caputres} = Zipper.move_to_coursor_and_capture(zipper, "__cursor__ |> Enum.map(__map) |> Enum.join(__join) ")
captures.map #=> AST for Enum.map args
captures.join #=> AST ...
But, one step at a time.
Maybe
__
?
When I first took a stab at this, I went with __
because it felt like a really weird thing to type in most elixir code, so I'm good with using this to ignore values!
__
is especially good, because you get this:
iex(1)> defmodule Thing do
...(1)> def thing(__), do: 10
...(1)> end
warning: unknown compiler variable "__" (expected one of __MODULE__, __ENV__, __DIR__, __CALLER__, __STACKTRACE__)
└─ iex:2: Thing.thing/1
So, I'm sure that there will need to be lots of workshopping or even that the implementation should be fully changed, but this at a minimum starts the conversation :)
Its relatively simple, but does technically break if someone is using the variables/functions
___cursor___
or___skip___
(note the triple underscores).