@@ -16,6 +16,17 @@ local SCRIPT_TEXT_HTML_QUERY = [[
16
16
(end_tag))
17
17
]]
18
18
19
+ local function is_position_between_range (position , range )
20
+ local start_row , start_col , end_row , end_col = unpack (range )
21
+
22
+ return not (
23
+ position .line < start_row
24
+ or position .line > end_row
25
+ or (position .line == start_row and position .character < start_col )
26
+ or (position .line == end_row and position .character > end_col )
27
+ )
28
+ end
29
+
19
30
local function initialize_virtual_document ()
20
31
-- creating path in the same directory as edited file so every setting set up for directory will apply
21
32
local virtual_document_path = vim .api .nvim_buf_get_name (0 ) .. " -tmp" .. VIRTUAL_DOCUMENT_EXTENSION
@@ -82,9 +93,6 @@ local function extract_js_script_code_ranges()
82
93
return code_chunks
83
94
end
84
95
85
- --- TODO
86
- --- Make it work for <script> ... </script> (script in one line)
87
- --- Make it work for <script> ... <script> <script> ... </script> (two or more scripts in one line)
88
96
--- Gets the content from buffer, replaces everything with empty lines and then inserts code chunks
89
97
--- at correct positions and replaces virtual document with those lines.
90
98
--- @param original_buffer_uri string - uri of the buffer to extract code from
@@ -96,35 +104,38 @@ function M.update_virtual_document(original_buffer_uri)
96
104
local requested_buf_all_lines =
97
105
vim .api .nvim_buf_get_lines (vim .uri_to_bufnr (original_buffer_uri ), 0 , - 1 , false )
98
106
99
- local empty_lines = vim .tbl_map (function (line )
100
- return string.rep (" " , vim .fn .strdisplaywidth (line ))
101
- end , requested_buf_all_lines )
102
-
103
107
local scripts_ranges = extract_js_script_code_ranges ()
104
108
105
- -- TODO check if deepcopy is necessary
106
- -- idea: create one loop over every line of requested buffer and check for all
107
- -- chunks and if no chunks is in the position replace with whitespace
108
- local lines = vim .deepcopy (empty_lines )
109
- for _ , script_range in ipairs (scripts_ranges ) do
110
- for index in ipairs (empty_lines ) do
111
- -- when chunk is in the middle of the script just replace whole lines
112
- if index > script_range .range [1 ] and index < script_range .range [3 ] then
113
- lines [index ] = requested_buf_all_lines [index ]
114
- -- when chunk is in the same line as the start and end tag we need
115
- -- make some of the line empty and some parts fill with script code
116
- elseif index == script_range .range [1 ] then
117
- local row_script_part = string.sub (requested_buf_all_lines [index ], script_range .range [2 ])
118
- lines [index ] = string.sub (empty_lines [index ], 0 , script_range .range [2 ] - 1 )
119
- .. row_script_part
120
- elseif index == script_range .range [3 ] then
121
- local row_script_part = string.sub (requested_buf_all_lines [index ], 0 , script_range .range [4 ])
122
- lines [index ] = row_script_part .. string.sub (empty_lines [index ], script_range .range [4 ] + 1 )
109
+ local function replace_char (pos , str , r )
110
+ return str :sub (1 , pos - 1 ) .. r .. str :sub (pos + 1 )
111
+ end
112
+
113
+ -- this might be not that performant but we should observe how it performs
114
+ for line_index , line in ipairs (requested_buf_all_lines ) do
115
+ for character_index = 1 , # line do
116
+ local is_position_in_script = false
117
+
118
+ for _ , script_range in ipairs (scripts_ranges ) do
119
+ if
120
+ is_position_between_range (
121
+ { line = line_index , character = character_index },
122
+ script_range .range
123
+ )
124
+ then
125
+ is_position_in_script = true
126
+ break
127
+ end
128
+ end
129
+
130
+ if not is_position_in_script then
131
+ requested_buf_all_lines [line_index ] =
132
+ replace_char (character_index , requested_buf_all_lines [line_index ], " " )
123
133
end
124
134
end
125
135
end
126
136
127
- vim .api .nvim_buf_set_lines (M .virtual_document_bufnr , 0 , - 1 , false , lines )
137
+ -- this line throws E565: Not allowed to change text or change window sometimes and nned to investigate why
138
+ vim .api .nvim_buf_set_lines (M .virtual_document_bufnr , 0 , - 1 , false , requested_buf_all_lines )
128
139
129
140
return M .virtual_document_bufnr
130
141
end
@@ -146,10 +157,28 @@ function M.rewrite_request_uris(method, params, current_buffer_uri)
146
157
end
147
158
148
159
-- in those methods there are whole contents of the file so we need to rewrite them as well
149
- if tbl .text and (method == " textDocument/didOpen" or method == " textDocument/didChange " ) then
160
+ if tbl .text and (method == " textDocument/didOpen" ) then
150
161
tbl .text =
151
162
table.concat (vim .api .nvim_buf_get_lines (M .virtual_document_bufnr , 0 , - 1 , false ), " \n " )
152
163
end
164
+
165
+ if tbl .text and (method == " textDocument/didChange" ) then
166
+ local start_row = tbl .range .start .line
167
+ local start_col = tbl .range .start .character
168
+ local end_row = tbl .range [" end" ].line
169
+ local end_col = tbl .range [" end" ].character
170
+ tbl .text = table.concat (
171
+ vim .api .nvim_buf_get_text (
172
+ M .virtual_document_bufnr ,
173
+ start_row ,
174
+ start_col ,
175
+ end_row ,
176
+ end_col ,
177
+ {}
178
+ ),
179
+ " \n "
180
+ )
181
+ end
153
182
end
154
183
155
184
replace_original_uri_to_virtual_document_uri (params )
@@ -192,15 +221,10 @@ function M.create_redirect_handlers()
192
221
local client = vim .lsp .get_client_by_id (ctx .client_id )
193
222
local script_nodes = extract_script_text_nodes (0 )
194
223
for _ , script_node in ipairs (script_nodes ) do
195
- local start_row , start_col , end_row , end_col = script_node :range ()
196
-
197
- local is_script_node_between_request_range = not (
198
- request_start_range .line < start_row
199
- or request_start_range .line > end_row
200
- or (request_start_range .line == start_row and request_start_range .character < start_col )
201
- or (request_start_range .line == end_row and request_start_range .character > end_col )
202
- )
203
- if is_script_node_between_request_range and client .name == plugin_config .plugin_name then
224
+ if
225
+ is_position_between_range (request_start_range , script_node :range ())
226
+ and client .name == plugin_config .plugin_name
227
+ then
204
228
baseHoverHandler (err , res , ctx , config )
205
229
return
206
230
end
0 commit comments