Skip to content

Commit

Permalink
Fix regex matching prefix
Browse files Browse the repository at this point in the history
extend character classes to cover unicode letters
correctly escape all chars
add missing unicode regex modifiers
fixes #221
  • Loading branch information
lukaszsamson committed Oct 8, 2023
1 parent 78239e2 commit 497d9b7
Show file tree
Hide file tree
Showing 8 changed files with 24 additions and 8 deletions.
2 changes: 1 addition & 1 deletion lib/elixir_sense.ex
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ defmodule ElixirSense do

# Fix incomplete kw key, e.g. cursor after `option1: 1, opt`
fix_incomplete_kw_key = fn text_before, text_after ->
if Regex.match?(~r/\,\s*([\p{L}_][\p{L}\p{N}_@]*[?!]?)?$/, text_before) do
if Regex.match?(~r/\,\s*([\p{L}_][\p{L}\p{N}_@]*[?!]?)?$/u, text_before) do
text_before <> ": :__fake_value__" <> text_after
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/elixir_sense/core/metadata_builder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,7 @@ defmodule ElixirSense.Core.MetadataBuilder do
defp pre({:@, meta_attr, [{name, meta, params}]}, state) when is_atom(name) do
name_string = Atom.to_string(name)

if String.match?(name_string, ~r/^[_\p{Ll}\p{Lo}][\p{L}\p{N}_]*[?!]?$/) and
if String.match?(name_string, ~r/^[_\p{Ll}\p{Lo}][\p{L}\p{N}_]*[?!]?$/u) and
not String.starts_with?(name_string, "__atom_elixir_marker_") do
line = Keyword.fetch!(meta_attr, :line)
column = Keyword.fetch!(meta_attr, :column)
Expand Down
2 changes: 1 addition & 1 deletion lib/elixir_sense/core/parser.ex
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ defmodule ElixirSense.Core.Parser do
|> Enum.join("\n")

_ ->
if Regex.match?(~r/^[\p{L}_][\p{L}\p{N}_@]*[?!]?$/, token) do
if Regex.match?(~r/^[\p{L}_][\p{L}\p{N}_@]*[?!]?$/u, token) do
remove_line(source, line)
else
replace_line_with_marker(source, line)
Expand Down
2 changes: 1 addition & 1 deletion lib/elixir_sense/core/source.ex
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ defmodule ElixirSense.Core.Source do

line_str = line |> String.slice(0, col - 1)

case Regex.run(~r/[\w0-9\._!\?\:@&\^~+<>=*\/|\\]+$/, line_str) do
case Regex.run(~r/[\p{L}\p{N}\.\_\!\?\:\@\&\^\~\+\-\<\>\=\*\/\|\\]+$/u, line_str) do
nil -> ""
[prefix] when is_binary(prefix) -> prefix
end
Expand Down
2 changes: 1 addition & 1 deletion lib/elixir_sense/plugins/ecto.ex
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ defmodule ElixirSense.Plugins.Ecto do
end),
assoc_code <- Source.text_after(text_before, line, col),
[_, var] <-
Regex.run(~r/^assoc\(\s*([_\p{Ll}\p{Lo}][\p{L}\p{N}_]*[?!]?)\s*,/, assoc_code),
Regex.run(~r/^assoc\(\s*([_\p{Ll}\p{Lo}][\p{L}\p{N}_]*[?!]?)\s*,/u, assoc_code),
%{^var => %{type: type}} <- Query.extract_bindings(text_before, from_info, env, meta),
true <- function_exported?(type, :__schema__, 1) do
{:override, Query.find_assoc_suggestions(type, hint)}
Expand Down
4 changes: 2 additions & 2 deletions lib/elixir_sense/plugins/ecto/query.ex
Original file line number Diff line number Diff line change
Expand Up @@ -215,15 +215,15 @@ defmodule ElixirSense.Plugins.Ecto.Query do
def extract_bindings(prefix, %{pos: {{line, col}, _}} = func_info, env, buffer_metadata) do
func_code = Source.text_after(prefix, line, col)

from_matches = Regex.scan(~r/^.+\(?\s*(#{@binding_r})/, func_code)
from_matches = Regex.scan(~r/^.+\(?\s*(#{@binding_r})/u, func_code)

# TODO this code is broken
# depends on join positions that we are unable to get from AST
# line and col was previously assigned to each option in Source.which_func
join_matches =
for join when join in @joins <- func_info.options_so_far,
code = Source.text_after(prefix, line, col),
match <- Regex.scan(~r/^#{join}\:\s*(#{@binding_r})/, code) do
match <- Regex.scan(~r/^#{join}\:\s*(#{@binding_r})/u, code) do
match
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ defmodule ElixirSense.Providers.Suggestion.Reducers.Callbacks do
list = Enum.sort(list)

cond do
Regex.match?(~r/\s(def|defmacro)\s+([_\p{Ll}\p{Lo}][\p{L}\p{N}_]*[?!]?)?$/, text_before) ->
Regex.match?(~r/\s(def|defmacro)\s+([_\p{Ll}\p{Lo}][\p{L}\p{N}_]*[?!]?)?$/u, text_before) ->
{:halt, %{acc | result: list}}

match?({_f, _a}, scope) ->
Expand Down
16 changes: 16 additions & 0 deletions test/elixir_sense/suggestions_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,22 @@ defmodule ElixirSense.SuggestionsTest do
assert list |> Enum.any?(&(&1.type == :function))
end

test "functions from unicode module" do
buffer = """
defmodule :你好 do
def 运行 do
IO.puts("你好")
end
end
:你好.
"""

list = ElixirSense.suggestions(buffer, 7, 5)

assert list |> Enum.any?(&(&1.type == :function && &1.name == "运行"))
end

test "with an alias" do
buffer = """
defmodule MyModule do
Expand Down

0 comments on commit 497d9b7

Please sign in to comment.