diff --git a/lib/elixir/lib/code/fragment.ex b/lib/elixir/lib/code/fragment.ex index ff7c46e6afe..8843341c010 100644 --- a/lib/elixir/lib/code/fragment.ex +++ b/lib/elixir/lib/code/fragment.ex @@ -133,6 +133,7 @@ defmodule Code.Fragment do def cursor_context(fragment, opts \\ []) def cursor_context(binary, opts) when is_binary(binary) and is_list(opts) do + # CRLF not relevant here - we discard everything before last `\n` binary = case :binary.matches(binary, "\n") do [] -> @@ -151,6 +152,7 @@ defmodule Code.Fragment do end def cursor_context(charlist, opts) when is_list(charlist) and is_list(opts) do + # CRLF not relevant here - we discard everything before last `\n` charlist = case charlist |> Enum.chunk_by(&(&1 == ?\n)) |> List.last([]) do [?\n | _] -> [] @@ -508,7 +510,7 @@ defmodule Code.Fragment do def surround_context(binary, {line, column}, opts) when is_binary(binary) do binary - |> String.split("\n") + |> String.split(["\r\n", "\n"]) |> Enum.at(line - 1, '') |> String.to_charlist() |> position_surround_context(line, column, opts) @@ -516,6 +518,8 @@ defmodule Code.Fragment do def surround_context(charlist, {line, column}, opts) when is_list(charlist) do charlist + |> :string.replace('\r\n', '\n', :all) + |> :string.join('') |> :string.split('\n', :all) |> Enum.at(line - 1, '') |> position_surround_context(line, column, opts) diff --git a/lib/elixir/test/elixir/code_fragment_test.exs b/lib/elixir/test/elixir/code_fragment_test.exs index 07de062421d..ad3533e4094 100644 --- a/lib/elixir/test/elixir/code_fragment_test.exs +++ b/lib/elixir/test/elixir/code_fragment_test.exs @@ -20,6 +20,10 @@ defmodule CodeFragmentTest do assert CF.cursor_context('\n') == :expr assert CF.cursor_context("\n\n") == :expr assert CF.cursor_context('\n\n') == :expr + assert CF.cursor_context("\r\n") == :expr + assert CF.cursor_context('\r\n') == :expr + assert CF.cursor_context("\r\n\r\n") == :expr + assert CF.cursor_context('\r\n\r\n') == :expr end test "local_or_var" do @@ -267,6 +271,8 @@ defmodule CodeFragmentTest do test "newlines" do assert CF.cursor_context("this+does-not*matter\nHello.") == {:dot, {:alias, 'Hello'}, ''} assert CF.cursor_context('this+does-not*matter\nHello.') == {:dot, {:alias, 'Hello'}, ''} + assert CF.cursor_context("this+does-not*matter\r\nHello.") == {:dot, {:alias, 'Hello'}, ''} + assert CF.cursor_context('this+does-not*matter\r\nHello.') == {:dot, {:alias, 'Hello'}, ''} end end @@ -278,6 +284,18 @@ defmodule CodeFragmentTest do begin: {3, 1}, end: {3, 9} } + + assert CF.surround_context("\r\n\r\nhello_wo\r\n", {3, i}) == %{ + context: {:local_or_var, 'hello_wo'}, + begin: {3, 1}, + end: {3, 9} + } + + assert CF.surround_context('\r\n\r\nhello_wo\r\n', {3, i}) == %{ + context: {:local_or_var, 'hello_wo'}, + begin: {3, 1}, + end: {3, 9} + } end end