1
- defmodule Lexical.SourceFile do
1
+ defmodule Lexical.Document do
2
2
@ moduledoc """
3
3
A representation of a LSP text document
4
4
5
- A source file is the fundamental data structure of the Lexical language server.
5
+ A document is the fundamental data structure of the Lexical language server.
6
6
All language server documents are represented and backed by source files, which
7
7
provide functionality for fetching lines, applying changes, and tracking versions.
8
8
"""
9
9
alias Lexical.Convertible
10
- alias Lexical.SourceFile. Document
11
- alias Lexical.SourceFile.Edit
12
- alias Lexical.SourceFile.Line
13
- alias Lexical.SourceFile .Position
14
- alias Lexical.SourceFile .Range
10
+ alias Lexical.Document.Edit
11
+ alias Lexical.Document.Line
12
+ alias Lexical.Document.Lines
13
+ alias Lexical.Document .Position
14
+ alias Lexical.Document .Range
15
15
16
- import Lexical.SourceFile .Line
16
+ import Lexical.Document .Line
17
17
18
- alias __MODULE__ . Path , as: SourceFilePath
18
+ alias __MODULE__ . Path , as: DocumentPath
19
19
20
- @ derive { Inspect , only: [ :path , :version , :dirty? , :document ] }
20
+ @ derive { Inspect , only: [ :path , :version , :dirty? , :lines ] }
21
21
22
- defstruct [ :uri , :path , :version , dirty?: false , document : nil ]
22
+ defstruct [ :uri , :path , :version , dirty?: false , lines : nil ]
23
23
24
24
@ type version :: non_neg_integer ( )
25
25
@ type t :: % __MODULE__ {
26
26
uri: String . t ( ) ,
27
27
version: version ( ) ,
28
28
dirty?: boolean ,
29
- document: Document . t ( ) ,
29
+ lines: Lines . t ( ) ,
30
30
path: String . t ( )
31
31
}
32
32
@@ -35,44 +35,44 @@ defmodule Lexical.SourceFile do
35
35
# public
36
36
37
37
@ doc """
38
- Creates a new source fie from a uri or path, the source code
38
+ Creates a new document from a uri or path, the source code
39
39
as a binary and the vewrsion.
40
40
"""
41
41
@ spec new ( Lexical . path ( ) | Lexical . uri ( ) , String . t ( ) , version ( ) ) :: t
42
42
def new ( maybe_uri , text , version ) do
43
- uri = SourceFilePath . ensure_uri ( maybe_uri )
43
+ uri = DocumentPath . ensure_uri ( maybe_uri )
44
44
45
45
% __MODULE__ {
46
46
uri: uri ,
47
47
version: version ,
48
- document: Document . new ( text ) ,
49
- path: SourceFilePath . from_uri ( uri )
48
+ lines: Lines . new ( text ) ,
49
+ path: DocumentPath . from_uri ( uri )
50
50
}
51
51
end
52
52
53
53
@ doc """
54
54
Returns the number of lines in the document
55
55
"""
56
56
@ spec size ( t ) :: non_neg_integer ( )
57
- def size ( % __MODULE__ { } = source ) do
58
- Document . size ( source . document )
57
+ def size ( % __MODULE__ { } = document ) do
58
+ Lines . size ( document . lines )
59
59
end
60
60
61
61
@ doc """
62
- Marks the source file as dirty
62
+ Marks the document file as dirty
63
63
"""
64
64
@ spec mark_dirty ( t ) :: t
65
- def mark_dirty ( % __MODULE__ { } = source ) do
66
- % __MODULE__ { source | dirty?: true }
65
+ def mark_dirty ( % __MODULE__ { } = document ) do
66
+ % __MODULE__ { document | dirty?: true }
67
67
end
68
68
69
69
@ doc """
70
- Marks the source file as clean
70
+ Marks the document file as clean
71
71
"""
72
72
73
73
@ spec mark_clean ( t ) :: t
74
- def mark_clean ( % __MODULE__ { } = source ) do
75
- % __MODULE__ { source | dirty?: false }
74
+ def mark_clean ( % __MODULE__ { } = document ) do
75
+ % __MODULE__ { document | dirty?: false }
76
76
end
77
77
78
78
@ doc """
@@ -81,16 +81,16 @@ defmodule Lexical.SourceFile do
81
81
Returns {:ok, text} if the line exists, and :error if it doesn't
82
82
"""
83
83
@ spec fetch_text_at ( t , version ( ) ) :: { :ok , String . t ( ) } | :error
84
- def fetch_text_at ( % __MODULE__ { } = source , line_number ) do
85
- case fetch_line_at ( source , line_number ) do
84
+ def fetch_text_at ( % __MODULE__ { } = document , line_number ) do
85
+ case fetch_line_at ( document , line_number ) do
86
86
{ :ok , line ( text: text ) } -> { :ok , text }
87
87
_ -> :error
88
88
end
89
89
end
90
90
91
91
@ spec fetch_line_at ( t , version ( ) ) :: { :ok , Line . t ( ) } | :error
92
- def fetch_line_at ( % __MODULE__ { } = source , line_number ) do
93
- case Document . fetch_line ( source . document , line_number ) do
92
+ def fetch_line_at ( % __MODULE__ { } = document , line_number ) do
93
+ case Lines . fetch_line ( document . lines , line_number ) do
94
94
{ :ok , line } -> { :ok , line }
95
95
_ -> :error
96
96
end
@@ -103,97 +103,97 @@ defmodule Lexical.SourceFile do
103
103
{ :error , :invalid_version }
104
104
end
105
105
106
- def apply_content_changes ( % __MODULE__ { } = source , _ , [ ] ) do
107
- { :ok , source }
106
+ def apply_content_changes ( % __MODULE__ { } = document , _ , [ ] ) do
107
+ { :ok , document }
108
108
end
109
109
110
- def apply_content_changes ( % __MODULE__ { } = source , version , changes ) when is_list ( changes ) do
110
+ def apply_content_changes ( % __MODULE__ { } = document , version , changes ) when is_list ( changes ) do
111
111
result =
112
- Enum . reduce_while ( changes , source , fn
113
- nil , source ->
114
- { :cont , source }
112
+ Enum . reduce_while ( changes , document , fn
113
+ nil , document ->
114
+ { :cont , document }
115
115
116
- change , source ->
117
- case apply_change ( source , change ) do
118
- { :ok , new_source } ->
119
- { :cont , new_source }
116
+ change , document ->
117
+ case apply_change ( document , change ) do
118
+ { :ok , new_document } ->
119
+ { :cont , new_document }
120
120
121
121
error ->
122
122
{ :halt , error }
123
123
end
124
124
end )
125
125
126
126
case result do
127
- % __MODULE__ { } = source ->
128
- source = mark_dirty ( % __MODULE__ { source | version: version } )
127
+ % __MODULE__ { } = document ->
128
+ document = mark_dirty ( % __MODULE__ { document | version: version } )
129
129
130
- { :ok , source }
130
+ { :ok , document }
131
131
132
132
error ->
133
133
error
134
134
end
135
135
end
136
136
137
- def to_string ( % __MODULE__ { } = source ) do
138
- source
137
+ def to_string ( % __MODULE__ { } = document ) do
138
+ document
139
139
|> to_iodata ( )
140
140
|> IO . iodata_to_binary ( )
141
141
end
142
142
143
143
# private
144
144
145
- defp line_count ( % __MODULE__ { } = source ) do
146
- Document . size ( source . document )
145
+ defp line_count ( % __MODULE__ { } = document ) do
146
+ Lines . size ( document . lines )
147
147
end
148
148
149
149
defp apply_change (
150
- % __MODULE__ { } = source ,
150
+ % __MODULE__ { } = document ,
151
151
% Range { start: % Position { } = start_pos , end: % Position { } = end_pos } ,
152
152
new_text
153
153
) do
154
154
start_line = start_pos . line
155
155
156
156
new_lines_iodata =
157
157
cond do
158
- start_line > line_count ( source ) ->
159
- append_to_end ( source , new_text )
158
+ start_line > line_count ( document ) ->
159
+ append_to_end ( document , new_text )
160
160
161
161
start_line < 1 ->
162
- prepend_to_beginning ( source , new_text )
162
+ prepend_to_beginning ( document , new_text )
163
163
164
164
true ->
165
- apply_valid_edits ( source , new_text , start_pos , end_pos )
165
+ apply_valid_edits ( document , new_text , start_pos , end_pos )
166
166
end
167
167
168
168
new_document =
169
169
new_lines_iodata
170
170
|> IO . iodata_to_binary ( )
171
- |> Document . new ( )
171
+ |> Lines . new ( )
172
172
173
- { :ok , % __MODULE__ { source | document : new_document } }
173
+ { :ok , % __MODULE__ { document | lines : new_document } }
174
174
end
175
175
176
- defp apply_change ( % __MODULE__ { } = source , % Edit { range: nil } = edit ) do
177
- { :ok , % __MODULE__ { source | document: Document . new ( edit . text ) } }
176
+ defp apply_change ( % __MODULE__ { } = document , % Edit { range: nil } = edit ) do
177
+ { :ok , % __MODULE__ { document | lines: Lines . new ( edit . text ) } }
178
178
end
179
179
180
- defp apply_change ( % __MODULE__ { } = source , % Edit { range: % Range { } } = edit ) do
180
+ defp apply_change ( % __MODULE__ { } = document , % Edit { range: % Range { } } = edit ) do
181
181
if valid_edit? ( edit ) do
182
- apply_change ( source , edit . range , edit . text )
182
+ apply_change ( document , edit . range , edit . text )
183
183
else
184
184
{ :error , { :invalid_range , edit . range } }
185
185
end
186
186
end
187
187
188
- defp apply_change ( % __MODULE__ { } = source , % { range: range , text: text } ) do
189
- with { :ok , native_range } <- Convertible . to_native ( range , source ) do
190
- apply_change ( source , Edit . new ( text , native_range ) )
188
+ defp apply_change ( % __MODULE__ { } = document , % { range: range , text: text } ) do
189
+ with { :ok , native_range } <- Convertible . to_native ( range , document ) do
190
+ apply_change ( document , Edit . new ( text , native_range ) )
191
191
end
192
192
end
193
193
194
- defp apply_change ( % __MODULE__ { } = source , convertable_edit ) do
195
- with { :ok , edit } <- Convertible . to_native ( convertable_edit , source ) do
196
- apply_change ( source , edit )
194
+ defp apply_change ( % __MODULE__ { } = document , convertable_edit ) do
195
+ with { :ok , edit } <- Convertible . to_native ( convertable_edit , document ) do
196
+ apply_change ( document , edit )
197
197
end
198
198
end
199
199
@@ -204,16 +204,16 @@ defmodule Lexical.SourceFile do
204
204
end_pos . character >= 0
205
205
end
206
206
207
- defp append_to_end ( % __MODULE__ { } = source , edit_text ) do
208
- [ to_iodata ( source ) , edit_text ]
207
+ defp append_to_end ( % __MODULE__ { } = document , edit_text ) do
208
+ [ to_iodata ( document ) , edit_text ]
209
209
end
210
210
211
- defp prepend_to_beginning ( % __MODULE__ { } = source , edit_text ) do
212
- [ edit_text , to_iodata ( source ) ]
211
+ defp prepend_to_beginning ( % __MODULE__ { } = document , edit_text ) do
212
+ [ edit_text , to_iodata ( document ) ]
213
213
end
214
214
215
- defp apply_valid_edits ( % __MODULE__ { } = source , edit_text , start_pos , end_pos ) do
216
- Document . reduce ( source . document , [ ] , fn line ( ) = line , acc ->
215
+ defp apply_valid_edits ( % __MODULE__ { } = document , edit_text , start_pos , end_pos ) do
216
+ Lines . reduce ( document . lines , [ ] , fn line ( ) = line , acc ->
217
217
case edit_action ( line , edit_text , start_pos , end_pos ) do
218
218
:drop ->
219
219
acc
@@ -268,11 +268,7 @@ defmodule Lexical.SourceFile do
268
268
binary_part ( text , start_index , length )
269
269
end
270
270
271
- defp to_iodata ( % __MODULE__ { } = source ) do
272
- Document . to_iodata ( source . document )
271
+ defp to_iodata ( % __MODULE__ { } = document ) do
272
+ Lines . to_iodata ( document . lines )
273
273
end
274
-
275
- # defp increment_version(%__MODULE__{} = source) do
276
- # %__MODULE__{source | version: source.version + 1}
277
- # end
278
274
end
0 commit comments