package linol
LSP server library
Install
Dune Dependency
Authors
Maintainers
Sources
linol-0.10.tbz
sha256=174bb8cad5b8b0c260d62b0a85da13c4f5caba4fcee042ee58284b09de7896ea
sha512=77460788407c72a33fbe289ec9c78421117543594b3524a5c8fe836f0e272c5ceb1e1074b91c1d1f476f89b75b6f63847a8021675a782ff36457c9626121a7f4
doc/src/linol.lsp/uri0.ml.html
Source file uri0.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 164
(* This module is based on the [vscode-uri] implementation: https://github.com/microsoft/vscode-uri/blob/main/src/uri.ts. It only supports scheme, authority and path. Query, port and fragment are not implemented *) open Import module Private = struct let win32 = ref Sys.win32 end type t = Uri_lexer.t = { scheme : string ; authority : string ; path : string ; query : string option ; fragment : string option } let query t = t.query let fragment t = t.fragment let backslash_to_slash = String.map ~f:(function | '\\' -> '/' | c -> c) ;; let slash_to_backslash = String.map ~f:(function | '/' -> '\\' | c -> c) ;; let of_path path = let path = if !Private.win32 then backslash_to_slash path else path in Uri_lexer.of_path path ;; let to_path { path; ; scheme; query; _ } = let path = let len = String.length path in if len = 0 then "/" else ( let buff = Buffer.create 64 in if (not (String.is_empty authority)) && len > 1 && scheme = "file" then ( Buffer.add_string buff "//"; Buffer.add_string buff authority; Buffer.add_string buff path) else if len < 3 then Buffer.add_string buff path else ( let c0 = path.[0] in let c1 = path.[1] in let c2 = path.[2] in if c0 = '/' && ((c1 >= 'A' && c1 <= 'Z') || (c1 >= 'a' && c1 <= 'z')) && c2 = ':' then ( Buffer.add_char buff (Char.lowercase_ascii c1); Buffer.add_substring buff path 2 (String.length path - 2)) else Buffer.add_string buff path); (match query with | None -> () | Some query -> Buffer.add_char buff '?'; Buffer.add_string buff query); Buffer.contents buff) in if !Private.win32 then slash_to_backslash path else path ;; let of_string = Uri_lexer.of_string let safe_chars = let a = Array.make 256 false in let always_safe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.-~" in for i = 0 to String.length always_safe - 1 do let c = Char.code always_safe.[i] in a.(c) <- true done; a ;; let slash_code = 47 (* https://github.com/mirage/ocaml-uri/blob/master/lib/uri.ml#L284 *) let encode ?(allow_slash = false) s = let len = String.length s in let buf = Buffer.create len in let rec scan start cur = if cur >= len then Buffer.add_substring buf s start (cur - start) else ( let c = Char.code s.[cur] in if (allow_slash && c = slash_code) || safe_chars.(c) then scan start (cur + 1) else ( if cur > start then Buffer.add_substring buf s start (cur - start); Buffer.add_string buf (Printf.sprintf "%%%02X" c); scan (cur + 1) (cur + 1))) in scan 0 0; Buffer.contents buf ;; let to_string { scheme; ; path; query; fragment } = let buff = Buffer.create 64 in if not (String.is_empty scheme) then ( Buffer.add_string buff scheme; Buffer.add_char buff ':'); if (not (String.is_empty authority)) || scheme = "file" then Buffer.add_string buff "//"; (*TODO: implement full logic: https://github.com/microsoft/vscode-uri/blob/96acdc0be5f9d5f2640e1c1f6733bbf51ec95177/src/uri.ts#L605 *) if not (String.is_empty authority) then ( let s = String.lowercase_ascii authority in Buffer.add_string buff (encode s)); if not (String.is_empty path) then ( let encode = encode ~allow_slash:true in let encoded_colon = "%3A" in let len = String.length path in if len >= 3 && path.[0] = '/' && path.[2] = ':' then ( let drive_letter = Char.lowercase_ascii path.[1] in if drive_letter >= 'a' && drive_letter <= 'z' then ( Buffer.add_char buff '/'; Buffer.add_char buff drive_letter; Buffer.add_string buff encoded_colon; let s = String.sub path ~pos:3 ~len:(len - 3) in Buffer.add_string buff (encode s))) else if len >= 2 && path.[1] = ':' then ( let drive_letter = Char.lowercase_ascii path.[0] in if drive_letter >= 'a' && drive_letter <= 'z' then ( Buffer.add_char buff drive_letter; Buffer.add_string buff encoded_colon; let s = String.sub path ~pos:2 ~len:(len - 2) in Buffer.add_string buff (encode s))) else Buffer.add_string buff (encode path)); (match query with | None -> () | Some q -> Buffer.add_char buff '?'; Buffer.add_string buff (encode q)); (match fragment with | None -> () | Some f -> Buffer.add_char buff '#'; Buffer.add_string buff (encode f)); Buffer.contents buff ;; let yojson_of_t t = `String (to_string t) let t_of_yojson json = Json.Conv.string_of_yojson json |> of_string let equal = ( = ) let compare (x : t) (y : t) = Stdlib.compare x y let hash = Hashtbl.hash
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>