package vsrocq-language-server
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
VSRocq language server
Install
dune-project
Dependency
Authors
Maintainers
Sources
vsrocq-language-server-2.5.0.tar.gz
md5=15c22fee2131c4b3dae4258e8a4484f6
sha512=b5ab3eea5bb6af643d635781e741a7a7b217fcc33e84c2c9e3448962118a63e174569ef6069c50af2ab57508d5cef476a8cfade14957a9654b1fea16c29a08b9
doc/src/vsrocq-language-server.dm/rawDocument.ml.html
Source file rawDocument.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163(**************************************************************************) (* *) (* VSRocq *) (* *) (* Copyright INRIA and contributors *) (* (see version control and README file for authors & dates) *) (* *) (**************************************************************************) (* *) (* This file is distributed under the terms of the MIT License. *) (* See LICENSE file. *) (* *) (**************************************************************************) open Lsp.Types type text_edit = Range.t * string type t = { text : string; lines : int array; (* locs of beginning of lines *) is_ascii : bool array; (* whether lines are ascii-only *) } let compute_lines text = let len = String.length text in let rec loop idx current_ascii acc_lines acc_ascii = if idx >= len then let final_lines = Array.of_list (List.rev acc_lines) in let final_ascii = Array.of_list (List.rev (current_ascii :: acc_ascii)) in (final_lines, final_ascii) else let c = String.unsafe_get text idx in if c = '\n' then loop (idx + 1) true ((idx + 1) :: acc_lines) (current_ascii :: acc_ascii) else loop (idx + 1) (current_ascii && Char.code c < 128) acc_lines acc_ascii in loop 0 true [0] [] let create text = let lines, is_ascii = compute_lines text in { text; lines; is_ascii } let text t = t.text let line_count raw = Array.length raw.lines let line_span raw i = if i + 1 < Array.length raw.lines then (raw.lines.(i), raw.lines.(i+1) - raw.lines.(i)) else (raw.lines.(i), String.length raw.text - raw.lines.(i)) (* UTF8 byte -> UTF16 code unit position *) let code_unit_pos_of_loc raw line_idx loc = let line_start, line_len = line_span raw line_idx in let loc = max 0 (min loc line_len) in if raw.is_ascii.(line_idx) then (* ASCII fast path: character position == byte offset *) loc else let rec loop byte_offset utf16_count = if byte_offset >= loc then utf16_count else let d = String.get_utf_8_uchar raw.text (line_start + byte_offset) in let byte_len = Uchar.utf_decode_length d in let u = Uchar.utf_decode_uchar d in (* handle UTF16 properly, code-points above 0xFFFF take two units to encode *) let units = if Uchar.to_int u > 0xFFFF then 2 else 1 in loop (byte_offset + byte_len) (utf16_count + units) in loop 0 0 (* UTF16 code unit position -> UTF8 byte *) let loc_of_code_unit_pos raw line_idx pos = let line_start, line_len = line_span raw line_idx in let pos = max 0 (min pos line_len) in if raw.is_ascii.(line_idx) then (* ASCII fast path: character position == byte offset *) pos else let rec loop byte_offset utf16_count = if utf16_count >= pos then byte_offset else let d = String.get_utf_8_uchar raw.text (line_start + byte_offset) in let byte_len = Uchar.utf_decode_length d in let u = Uchar.utf_decode_uchar d in (* handle UTF16 properly, code-points above 0xFFFF take two units to encode *) let units = if Uchar.to_int u > 0xFFFF then 2 else 1 in loop (byte_offset + byte_len) (utf16_count + units) in loop 0 0 let line_of_loc raw loc = let nlines = line_count raw in let rec aux low high = if low > high then max 0 high else let mid = low + (high - low) / 2 in if raw.lines.(mid) <= loc then if mid = nlines - 1 || loc < raw.lines.(mid + 1) then mid else aux (mid + 1) high else aux low (mid - 1) in aux 0 (nlines - 1) let position_of_loc raw loc = let line = line_of_loc raw loc in let character = code_unit_pos_of_loc raw line (loc - raw.lines.(line)) in Position.{ line; character } let loc_of_position raw Position.{ line; character } = let nlines = line_count raw in let line = max 0 (min line (nlines - 1)) in let charloc = loc_of_code_unit_pos raw line character in raw.lines.(line) + charloc let end_loc raw = String.length raw.text let range_of_loc raw loc = let open Range in { start = position_of_loc raw loc.Loc.bp; end_ = position_of_loc raw loc.Loc.ep; } let word_back_reg = Str.regexp {|[^a-zA-Z_0-9.']|} let word_forward_reg = Str.regexp {|[^a-zA-Z_0-9']|} let word_at_loc raw loc : string option = try let start_ind = loc in (* Search backwards until we find a character that cannot be part of a word *) let first_non_word_ind = Str.search_backward word_back_reg raw.text start_ind in let first_word_ind = first_non_word_ind + 1 in (* Search forwards ensuring that all characters are part of a well defined word. (Cannot start with [0-9'.] and cannot end with .)*) let last_word_ind = Str.search_forward word_forward_reg raw.text start_ind in (* we get the substring from the first word index to the last index for the word *) let word = String.sub raw.text first_word_ind (last_word_ind - first_word_ind) in Some word with _ -> None let string_in_range raw start end_ = try String.sub raw.text start (end_ - start) with _ -> (* TODO: ERROR *) "" let apply_text_edit raw (Range.{start; end_}, editText) = let start = loc_of_position raw start in let stop = loc_of_position raw end_ in let before = String.sub raw.text 0 start in let after = String.sub raw.text stop (String.length raw.text - stop) in let new_text = before ^ editText ^ after in (* FIXME avoid concatenation *) let new_lines, new_is_ascii = compute_lines new_text in (* FIXME compute this incrementally *) { text = new_text; lines = new_lines; is_ascii = new_is_ascii }, start
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>