Skip to content

Commit fd68049

Browse files
authoredJul 12, 2024··
Merge pull request #805 from coq-community/fix-highlights
Fix highlights
2 parents 9652026 + 0b4aadd commit fd68049

File tree

6 files changed

+57
-18
lines changed

6 files changed

+57
-18
lines changed
 

‎language-server/dm/document.ml

+23-9
Original file line numberDiff line numberDiff line change
@@ -227,16 +227,24 @@ let pos_at_end parsed =
227227
| Some (stop, _) -> stop
228228
| None -> -1
229229

230+
let string_of_parsed_ast { tokens } =
231+
(* TODO implement printer for vernac_entry *)
232+
"[" ^ String.concat "--" (List.map (Tok.extract_string false) tokens) ^ "]"
233+
230234
let patch_sentence parsed scheduler_state_before id ({ parsing_start; ast; start; stop; synterp_state } : pre_sentence) =
231-
log @@ "Patching sentence " ^ Stateid.to_string id;
232235
let old_sentence = SM.find id parsed.sentences_by_id in
236+
log @@ Format.sprintf "Patching sentence %s , %s" (Stateid.to_string id) (string_of_parsed_ast old_sentence.ast);
233237
let scheduler_state_after, schedule =
234238
let ast = (ast.ast, ast.classification, synterp_state) in
235239
Scheduler.schedule_sentence (id,ast) scheduler_state_before parsed.schedule
236240
in
237241
let new_sentence = { old_sentence with ast; parsing_start; start; stop; scheduler_state_before; scheduler_state_after } in
238242
let sentences_by_id = SM.add id new_sentence parsed.sentences_by_id in
239-
let sentences_by_end = LM.remove old_sentence.stop parsed.sentences_by_end in
243+
let sentences_by_end = match LM.find_opt old_sentence.stop parsed.sentences_by_end with
244+
| Some { id } when Stateid.equal id new_sentence.id ->
245+
LM.remove old_sentence.stop parsed.sentences_by_end
246+
| _ -> parsed.sentences_by_end
247+
in
240248
let sentences_by_end = LM.add new_sentence.stop new_sentence sentences_by_end in
241249
{ parsed with sentences_by_end; sentences_by_id; schedule }, scheduler_state_after
242250

@@ -245,9 +253,11 @@ type diff =
245253
| Added of pre_sentence list
246254
| Equal of (sentence_id * pre_sentence) list
247255

256+
257+
248258
let same_tokens (s1 : sentence) (s2 : pre_sentence) =
249259
CList.equal Tok.equal s1.ast.tokens s2.ast.tokens
250-
260+
251261
(* TODO improve diff strategy (insertions,etc) *)
252262
let rec diff old_sentences new_sentences =
253263
match old_sentences, new_sentences with
@@ -256,13 +266,10 @@ let rec diff old_sentences new_sentences =
256266
| old_sentences, [] -> [Deleted (List.map (fun s -> s.id) old_sentences)]
257267
(* FIXME something special should be done when `Deleted` is applied to a parsing effect *)
258268
| old_sentence::old_sentences, new_sentence::new_sentences ->
259-
if same_tokens old_sentence new_sentence then
269+
if same_tokens old_sentence new_sentence then
260270
Equal [(old_sentence.id,new_sentence)] :: diff old_sentences new_sentences
261-
else Deleted [old_sentence.id] :: Added [new_sentence] :: diff old_sentences new_sentences
262-
263-
let string_of_parsed_ast { tokens } =
264-
(* TODO implement printer for vernac_entry *)
265-
"[" ^ String.concat "--" (List.map (Tok.extract_string false) tokens) ^ "]"
271+
else
272+
Deleted [old_sentence.id] :: Added [new_sentence] :: diff old_sentences new_sentences
266273

267274
let string_of_diff_item doc = function
268275
| Deleted ids ->
@@ -434,6 +441,13 @@ let invalidate top_edit top_id parsed_doc new_sentences =
434441
invalidate_diff parsed_doc scheduler_state invalid_ids diffs
435442
in
436443
let (_,_synterp_state,scheduler_state) = state_at_pos parsed_doc top_edit in
444+
let sentence_strings = LM.bindings @@ LM.map (fun s -> string_of_parsed_ast s.ast) parsed_doc.sentences_by_end in
445+
let sentence_strings = List.map (fun s -> snd s) sentence_strings in
446+
let sentence_string = String.concat " " sentence_strings in
447+
let sentence_strings_id = SM.bindings @@ SM.map (fun s -> string_of_parsed_ast s.ast) parsed_doc.sentences_by_id in
448+
let sentence_strings_id = List.map (fun s -> snd s) sentence_strings_id in
449+
let sentence_string_id = String.concat " " sentence_strings_id in
450+
log @@ Format.sprintf "Top edit: %i, Doc: %s, Doc by id: %s" top_edit sentence_string sentence_string_id;
437451
let old_sentences = sentences_after parsed_doc top_edit in
438452
let diff = diff old_sentences new_sentences in
439453
let unchanged_id = unchanged_id top_id diff in

‎language-server/dm/document.mli

+3-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ type parsing_error = {
4949
val parse_errors : document -> parsing_error list
5050
(** [parse_errors doc] returns the list of sentences which failed to parse
5151
(see validate_document) together with their error message *)
52-
52+
val apply_text_edit : document -> text_edit -> document
53+
(** [apply_text_edits doc edits] updates the text of [doc] with [edits]. The new
54+
text is not parsed or executed. *)
5355
val apply_text_edits : document -> text_edit list -> document
5456
(** [apply_text_edits doc edits] updates the text of [doc] with [edits]. The new
5557
text is not parsed or executed. *)

‎language-server/dm/documentManager.ml

+9-5
Original file line numberDiff line numberDiff line change
@@ -368,15 +368,19 @@ let reset { uri; opts; init_vs; document; execution_state; observe_id } =
368368
validate_document st, [inject_em_event feedback]
369369

370370
let apply_text_edits state edits =
371-
let document = Document.apply_text_edits state.document edits in
372-
let shift_diagnostics_locs exec_st (range, new_text) =
371+
let apply_edit_and_shift_diagnostics_locs_and_overview state (range, new_text as edit) =
372+
let document = Document.apply_text_edit state.document edit in
373+
let exec_st = state.execution_state in
374+
log @@ Format.sprintf "APPLYING TEXT EDIT %s [%s]" (Range.to_string range) new_text;
373375
let edit_start = RawDocument.loc_of_position (Document.raw_document state.document) range.Range.start in
374376
let edit_stop = RawDocument.loc_of_position (Document.raw_document state.document) range.Range.end_ in
375377
let edit_length = edit_stop - edit_start in
376-
ExecutionManager.shift_diagnostics_locs exec_st ~start:edit_stop ~offset:(String.length new_text - edit_length)
378+
let exec_st = ExecutionManager.shift_diagnostics_locs exec_st ~start:edit_stop ~offset:(String.length new_text - edit_length) in
379+
let execution_state = ExecutionManager.shift_overview exec_st ~before:(Document.raw_document state.document) ~after:(Document.raw_document document) ~start:edit_stop ~offset:(String.length new_text - edit_length) in
380+
{state with execution_state; document}
377381
in
378-
let execution_state = List.fold_left shift_diagnostics_locs state.execution_state edits in
379-
validate_document { state with document; execution_state }
382+
let state = List.fold_left apply_edit_and_shift_diagnostics_locs_and_overview state edits in
383+
validate_document state
380384

381385
let handle_event ev st =
382386
match ev with

‎language-server/dm/executionManager.ml

+18
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,24 @@ let feedback st id =
756756
let all_feedback st =
757757
List.fold_left (fun acc (id, (_,l)) -> List.map (fun x -> (id, x)) l @ acc) [] @@ SM.bindings st.of_sentence
758758

759+
let shift_overview st ~before ~after ~start ~offset =
760+
let shift_loc loc_start loc_end =
761+
if loc_start >= start then (loc_start + offset, loc_end + offset)
762+
else if loc_end > start then (loc_start, loc_end + offset)
763+
else (loc_start, loc_end)
764+
in
765+
let shift_range range =
766+
let r_start = RawDocument.loc_of_position before range.Range.start in
767+
let r_stop = RawDocument.loc_of_position before range.Range.end_ in
768+
let r_start', r_stop' = shift_loc r_start r_stop in
769+
Range.create ~start:(RawDocument.position_of_loc after r_start') ~end_:(RawDocument.position_of_loc after r_stop')
770+
in
771+
let processed = CList.Smart.map shift_range st.overview.processed in
772+
let processing = CList.Smart.map shift_range st.overview.processing in
773+
let prepared = CList.Smart.map shift_range st.overview.prepared in
774+
let overview = {processed; processing; prepared} in
775+
{st with overview}
776+
759777
let shift_diagnostics_locs st ~start ~offset =
760778
let shift_loc loc =
761779
let (loc_start, loc_stop) = Loc.unloc loc in

‎language-server/dm/executionManager.mli

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ val feedback : state -> sentence_id -> feedback_message list
5454
val all_errors : state -> (sentence_id * (Loc.t option * Pp.t * Quickfix.t list option)) list
5555
val all_feedback : state -> (sentence_id * feedback_message) list
5656

57+
val shift_overview : state -> before:RawDocument.t -> after:RawDocument.t -> start:int -> offset:int -> state
5758
val shift_diagnostics_locs : state -> start:int -> offset:int -> state
5859
val executed_ids : state -> sentence_id list
5960
val is_executed : state -> sentence_id -> bool

‎language-server/tests/common.ml

+3-3
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,12 @@ let task st id spec =
124124

125125

126126
let rec handle_events n (events : DocumentManager.event Sel.Todo.t) st =
127-
if n <= 0 then (Stdlib.Format.eprintf "handle_events run out of steps:\nTodo = %a\n" (Sel.Todo.pp DocumentManager.pp_event) events; Caml.exit 1)
127+
if n <= 0 then (Stdlib.Format.eprintf "handle_events run out of steps:\nTodo = %a\n" (Sel.Todo.pp DocumentManager.pp_event) events; Stdlib.exit 1)
128128
else if Sel.Todo.is_empty events then st
129129

130130
else begin
131131
(*Stdlib.Format.eprintf "waiting %a\n%!" Sel.(pp_todo DocumentManager.pp_event) events;*)
132-
Caml.flush_all ();
132+
Stdlib.flush_all ();
133133
let (ready, remaining) = Sel.pop_timeout ~stop_after_being_idle_for:0.1 events in
134134
match ready with
135135
| None ->
@@ -164,7 +164,7 @@ let check_diag st specl =
164164
(range, message, severity) in
165165
let match_diagnostic r s rex (range, message, severity) =
166166
Range.included ~in_:r range &&
167-
Caml.(=) severity (Some s) &&
167+
Stdlib.(=) severity (Some s) &&
168168
Str.string_match (Str.regexp rex) message 0
169169
in
170170
let diagnostics = DocumentManager.all_diagnostics st in

0 commit comments

Comments
 (0)
Please sign in to comment.