@@ -6,32 +6,37 @@ defmodule ElixirLS.LanguageServer.Providers.Rename do
6
6
"""
7
7
8
8
alias ElixirLS.LanguageServer.SourceFile
9
- #import ElixirLS.LanguageServer.Protocol
10
9
11
10
def rename ( % SourceFile { } = source_file , start_uri , line , character , new_name ) do
12
11
edits =
13
- with % { context: { context , char_ident } } when context in [ :local_or_var , :local_call ] <-
14
- Code.Fragment . surround_context ( source_file . text , { line , character } ) ,
12
+ with char_ident when not is_nil ( char_ident ) <-
13
+ get_char_ident ( source_file . text , line , character ) ,
15
14
% ElixirSense.Location { } = definition <-
16
15
ElixirSense . definition ( source_file . text , line , character ) ,
17
16
references <- ElixirSense . references ( source_file . text , line , character ) do
18
-
19
-
20
17
length_old = length ( char_ident )
21
18
22
- [
23
- % {
24
- uri: start_uri ,
25
- range:
26
- adjust_range (
27
- definition . line ,
28
- definition . column ,
29
- definition . line ,
30
- definition . column + length_old
19
+ definition_references =
20
+ case definition do
21
+ % { file: nil , type: :function } ->
22
+ parse_definition_source_code ( source_file . text )
23
+ |> get_all_fn_header_positions ( char_ident )
24
+ |> positions_to_references ( start_uri , length_old )
25
+
26
+ % { file: separate_file_path , type: :function } ->
27
+ parse_definition_source_code ( definition )
28
+ |> get_all_fn_header_positions ( char_ident )
29
+ |> positions_to_references ( SourceFile . path_to_uri ( separate_file_path ) , length_old )
30
+
31
+ _ ->
32
+ positions_to_references (
33
+ [ { definition . line , definition . column } ] ,
34
+ start_uri ,
35
+ length_old
31
36
)
32
- }
33
- | repack_references ( references , start_uri )
34
- ]
37
+ end
38
+
39
+ definition_references ++ repack_references ( references , start_uri )
35
40
else
36
41
_ ->
37
42
[ ]
@@ -62,7 +67,9 @@ defmodule ElixirLS.LanguageServer.Providers.Rename do
62
67
begin: { start_line , start_col } ,
63
68
end: { end_line , end_col } ,
64
69
context: { context , char_ident }
65
- } when context in [ :local_or_var , :local_call ] <- Code.Fragment . surround_context ( source_file . text , { line , character } ) do
70
+ }
71
+ when context in [ :local_or_var , :local_call ] <-
72
+ Code.Fragment . surround_context ( source_file . text , { line , character } ) do
66
73
% {
67
74
range: adjust_range ( start_line , start_col , end_line , end_col ) ,
68
75
placeholder: to_string ( char_ident )
@@ -91,10 +98,46 @@ defmodule ElixirLS.LanguageServer.Providers.Rename do
91
98
end
92
99
end
93
100
101
+ defp parse_definition_source_code ( % { file: file } ) do
102
+ ElixirSense.Core.Parser . parse_file ( file , true , true , 0 )
103
+ end
104
+
105
+ defp parse_definition_source_code ( source_text ) when is_binary ( source_text ) do
106
+ ElixirSense.Core.Parser . parse_string ( source_text , true , true , 0 )
107
+ end
108
+
109
+ defp get_all_fn_header_positions ( parsed_source , char_ident ) do
110
+ parsed_source . mods_funs_to_positions
111
+ |> Map . filter ( fn
112
+ { { _ , fn_name , _ } , _ } -> Atom . to_charlist ( fn_name ) == char_ident
113
+ end )
114
+ |> Enum . flat_map ( fn { _ , % { positions: positions } } -> positions end )
115
+ |> Enum . uniq ( )
116
+ end
117
+
118
+ defp positions_to_references ( header_positions , start_uri , length_old )
119
+ when is_list ( header_positions ) do
120
+ header_positions
121
+ |> Enum . map ( fn { line , column } ->
122
+ % {
123
+ uri: start_uri ,
124
+ range: adjust_range ( line , column , line , column + length_old )
125
+ }
126
+ end )
127
+ end
128
+
94
129
defp adjust_range ( start_line , start_character , end_line , end_character ) do
95
130
% {
96
131
start: % { line: start_line - 1 , character: start_character - 1 } ,
97
132
end: % { line: end_line - 1 , character: end_character - 1 }
98
133
}
99
134
end
135
+
136
+ defp get_char_ident ( text , line , character ) do
137
+ case Code.Fragment . surround_context ( text , { line , character } ) do
138
+ % { context: { context , char_ident } } when context in [ :local_or_var , :local_call ] -> char_ident
139
+ % { context: { :dot , _ , char_ident } } -> char_ident
140
+ _ -> nil
141
+ end
142
+ end
100
143
end
0 commit comments