@@ -247,6 +247,51 @@ defmodule Igniter.Code.Common do
247247 end
248248 end
249249
250+ def add_comment ( zipper , comment , opts \\ [ ] ) do
251+ zipper = maybe_move_to_single_child_block ( zipper )
252+
253+ comments =
254+ comment
255+ |> String . trim_leading ( "\n " )
256+ |> String . trim_trailing ( "\n " )
257+ |> String . split ( "\n " , trim: true )
258+ |> Enum . map ( fn
259+ "" ->
260+ "#"
261+
262+ string ->
263+ if String . starts_with? ( String . trim_leading ( string ) , "#" ) do
264+ string
265+ else
266+ if String . starts_with? ( string , " " ) do
267+ "#" <> string
268+ else
269+ "# " <> string
270+ end
271+ end
272+ end )
273+ |> Enum . map ( fn comment ->
274+ % {
275+ line: 0 ,
276+ text: comment ,
277+ column: 0 ,
278+ next_eol_count: 1 ,
279+ previous_eol_count: 1
280+ }
281+ end )
282+
283+ node =
284+ case opts [ :placement ] || :before do
285+ :before ->
286+ Sourceror . prepend_comments ( zipper . node , comments )
287+
288+ :after ->
289+ Sourceror . append_comments ( zipper . node , comments )
290+ end
291+
292+ Zipper . replace ( zipper , node )
293+ end
294+
250295 @ doc """
251296 Adds the provided code to the zipper.
252297
@@ -304,6 +349,8 @@ defmodule Igniter.Code.Common do
304349 expand_env? = Keyword . get ( opts , :expand_env? , true )
305350 placement = Keyword . get ( opts , :placement , :after )
306351
352+ new_code = clean_lines ( new_code )
353+
307354 new_code =
308355 if expand_env? do
309356 use_aliases ( new_code , zipper )
@@ -323,12 +370,12 @@ defmodule Igniter.Code.Common do
323370 { :__block__ , upwards_meta , upwards_code } = upwards . node
324371 index = Enum . count ( zipper . path . left || [ ] )
325372
326- { to_insert , new_meta } =
327- if extendable_block? ( new_code ) do
328- { :__block__ , new_meta , new_code } = new_code
329- { new_code , new_meta }
373+ to_insert =
374+ if extendable_block? ( new_code ) and ! has_comments? ( new_code ) do
375+ { :__block__ , _new_meta , new_code } = new_code
376+ new_code
330377 else
331- { [ new_code ] , [ ] }
378+ [ new_code ]
332379 end
333380
334381 { head , tail } =
@@ -340,16 +387,15 @@ defmodule Igniter.Code.Common do
340387
341388 Zipper . replace (
342389 upwards ,
343- { :__block__ , combine_comments ( upwards_meta , new_meta , placement ) ,
344- head ++ to_insert ++ tail }
390+ { :__block__ , upwards_meta , head ++ to_insert ++ tail }
345391 )
346392
347393 super_upwards && extendable_block? ( super_upwards . node ) ->
348394 { :__block__ , upwards_meta , upwards_code } = super_upwards . node
349395 index = Enum . count ( zipper . supertree . path . left || [ ] )
350396
351397 { to_insert , new_meta } =
352- if extendable_block? ( new_code ) do
398+ if extendable_block? ( new_code ) and ! has_comments? ( new_code ) do
353399 { :__block__ , new_meta , new_code } = new_code
354400 { new_code , new_meta }
355401 else
@@ -427,7 +473,7 @@ defmodule Igniter.Code.Common do
427473 Zipper . replace ( zipper , { :__block__ , meta , new_stuff } )
428474 else
429475 { code , meta } =
430- if extendable_block? ( new_code ) do
476+ if extendable_block? ( new_code ) and ! has_comments? ( new_code ) do
431477 { :__block__ , meta , new_stuff } = new_code
432478
433479 if placement == :after do
@@ -449,6 +495,22 @@ defmodule Igniter.Code.Common do
449495 end
450496 end
451497
498+ defp clean_lines ( ast ) do
499+ Macro . prewalk ( ast , fn
500+ { call , meta , args } ->
501+ { call , Keyword . put ( meta , :line , 0 ) , args }
502+
503+ other ->
504+ other
505+ end )
506+ end
507+
508+ defp has_comments? ( { _ , meta , _ } ) do
509+ List . wrap ( meta [ :leading_comments ] ) != [ ] || List . wrap ( meta [ :trailing_comments ] ) != [ ]
510+ end
511+
512+ defp has_comments? ( _ ) , do: false
513+
452514 @ doc """
453515 Updates all nodes matching the given predicate with the given function.
454516
@@ -566,7 +628,10 @@ defmodule Igniter.Code.Common do
566628 end
567629
568630 def replace_code ( % Zipper { } = zipper , new_code ) do
569- new_code = use_aliases ( new_code , zipper )
631+ new_code =
632+ new_code
633+ |> clean_lines ( )
634+ |> use_aliases ( zipper )
570635
571636 if extendable_block? ( new_code ) and in_extendable_block? ( zipper ) do
572637 at_supertree_root? = Zipper . up ( zipper ) == nil and ! ! zipper . supertree
@@ -629,7 +694,6 @@ defmodule Igniter.Code.Common do
629694 new_meta [ :trailing_comments ] || [ ] ,
630695 & ( ( new_meta [ :trailing_comments ] || [ ] ) ++ & 1 )
631696 )
632- |> ensure_unique_comments ( )
633697 else
634698 meta
635699 |> Keyword . update (
@@ -642,16 +706,9 @@ defmodule Igniter.Code.Common do
642706 new_meta [ :trailing_comments ] || [ ] ,
643707 & ( & 1 ++ ( new_meta [ :trailing_comments ] || [ ] ) )
644708 )
645- |> ensure_unique_comments ( )
646709 end
647710 end
648711
649- defp ensure_unique_comments ( meta ) do
650- meta
651- |> Keyword . update! ( :leading_comments , & Enum . uniq / 1 )
652- |> Keyword . update! ( :trailing_comments , & Enum . uniq / 1 )
653- end
654-
655712 defp multi_element_pipe? ( % { node: { :|> , _ , _ } } = zipper ) do
656713 up = Zipper . up ( zipper )
657714 down = Zipper . down ( zipper )
0 commit comments