Skip to content

Commit de29729

Browse files
authored
Handle newlines inside an IEx prompt (#39)
When given text like: ``` iex> existing_zipper = (""" ...> IO.inspect("Hello, world!") ...> IO.puts("abc") ...> """ ``` We need to ensure that the newlines are preserved in the selectable text
1 parent b594740 commit de29729

2 files changed

Lines changed: 29 additions & 6 deletions

File tree

lib/makeup/lexers/elixir_lexer.ex

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,17 @@ defmodule Makeup.Lexers.ElixirLexer do
520520
[first, second | extra_tokens ++ [end_sigil | postprocess_helper(rest)]]
521521
end
522522

523+
# When parsing a ...> from a string we need to ensure that the newline is still selectable
524+
defp postprocess_helper([
525+
{:generic_prompt, %{language: :elixir} = meta, ["\n..." | rest_text]}
526+
| rest
527+
]) do
528+
newline = {:generic_prompt, %{language: :elixir, selectable: true}, ["\n"]}
529+
# Remove the \n from the ...> prompt
530+
first = {:generic_prompt, meta, ["..." | rest_text]}
531+
[newline, first | postprocess_helper(rest)]
532+
end
533+
523534
defp postprocess_helper([{:string_sigil, attrs, content} | tokens]) do
524535
# content is a list of the format ["~", sigil_char, separator, ... sigil_content ..., end_separator]
525536
sigil =

test/makeup/lexers/elixir_lexer/elixir_lexer_tokenizer_test.exs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -553,13 +553,17 @@ defmodule ElixirLexerTokenizerTestSnippet do
553553
{:operator, %{}, "="},
554554
{:whitespace, %{}, " "},
555555
{:string, %{}, "\""},
556-
{:generic_prompt, %{selectable: false}, "\n...> "},
556+
{:generic_prompt, %{selectable: true}, "\n"},
557+
{:generic_prompt, %{selectable: false}, "...> "},
557558
{:string, %{}, "ine1"},
558-
{:generic_prompt, %{selectable: false}, "\n...> "},
559+
{:generic_prompt, %{selectable: true}, "\n"},
560+
{:generic_prompt, %{selectable: false}, "...> "},
559561
{:string, %{}, "line2"},
560-
{:generic_prompt, %{selectable: false}, "\n...> "},
562+
{:generic_prompt, %{selectable: true}, "\n"},
563+
{:generic_prompt, %{selectable: false}, "...> "},
561564
{:string, %{}, "ilne3"},
562-
{:generic_prompt, %{selectable: false}, "\n...> "},
565+
{:generic_prompt, %{selectable: true}, "\n"},
566+
{:generic_prompt, %{selectable: false}, "...> "},
563567
{:string, %{}, "\""},
564568
{:whitespace, %{}, "\n"}
565569
]
@@ -578,7 +582,7 @@ defmodule ElixirLexerTokenizerTestSnippet do
578582
'''
579583

580584
first_prompt = "iex#{prompt_number}> "
581-
other_prompt = "\n...#{prompt_number}> "
585+
other_prompt = "...#{prompt_number}> "
582586

583587
assert [
584588
{:generic_prompt, %{selectable: false}, ^first_prompt},
@@ -587,12 +591,16 @@ defmodule ElixirLexerTokenizerTestSnippet do
587591
{:operator, %{}, "="},
588592
{:whitespace, %{}, " "},
589593
{ttype, %{}, ^ldelim},
594+
{:generic_prompt, %{selectable: true}, "\n"},
590595
{:generic_prompt, %{selectable: false}, ^other_prompt},
591596
{ttype, %{}, "line1"},
597+
{:generic_prompt, %{selectable: true}, "\n"},
592598
{:generic_prompt, %{selectable: false}, ^other_prompt},
593599
{ttype, %{}, "line2"},
600+
{:generic_prompt, %{selectable: true}, "\n"},
594601
{:generic_prompt, %{selectable: false}, ^other_prompt},
595602
{ttype, %{}, "line3"},
603+
{:generic_prompt, %{selectable: true}, "\n"},
596604
{:generic_prompt, %{selectable: false}, ^other_prompt},
597605
{ttype, %{}, ^rdelim},
598606
{:whitespace, %{}, "\n"}
@@ -618,7 +626,7 @@ defmodule ElixirLexerTokenizerTestSnippet do
618626
'''
619627

620628
first_prompt = "iex#{prompt_number}> "
621-
other_prompt = "\n...#{prompt_number}> "
629+
other_prompt = "...#{prompt_number}> "
622630

623631
sigil_start = sigil_prefix <> ldelim
624632

@@ -629,12 +637,16 @@ defmodule ElixirLexerTokenizerTestSnippet do
629637
{:operator, %{}, "="},
630638
{:whitespace, %{}, " "},
631639
{ttype, %{}, ^sigil_start},
640+
{:generic_prompt, %{selectable: true}, "\n"},
632641
{:generic_prompt, %{selectable: false}, ^other_prompt},
633642
{ttype, %{}, "line1"},
643+
{:generic_prompt, %{selectable: true}, "\n"},
634644
{:generic_prompt, %{selectable: false}, ^other_prompt},
635645
{ttype, %{}, "line2"},
646+
{:generic_prompt, %{selectable: true}, "\n"},
636647
{:generic_prompt, %{selectable: false}, ^other_prompt},
637648
{ttype, %{}, "line3"},
649+
{:generic_prompt, %{selectable: true}, "\n"},
638650
{:generic_prompt, %{selectable: false}, ^other_prompt},
639651
{ttype, %{}, ^rdelim},
640652
{:whitespace, %{}, "\n"}

0 commit comments

Comments
 (0)