mirror of
https://github.com/c-cube/linol.git
synced 2025-12-12 22:10:58 -05:00
git-subtree-dir: thirdparty/lsp git-subtree-split: aae6986391a8519de3da6a7a341f2bd3376e0d2f
316 lines
7.8 KiB
OCaml
316 lines
7.8 KiB
OCaml
open Lsp
|
|
open Lsp.Types
|
|
module List = ListLabels
|
|
module String = StringLabels
|
|
|
|
let printf = Printf.printf
|
|
|
|
let tuple_range start end_ =
|
|
{ Range.start =
|
|
(let line, character = start in
|
|
{ Position.line; character })
|
|
; end_ =
|
|
(let line, character = end_ in
|
|
{ Position.line; character })
|
|
}
|
|
;;
|
|
|
|
let make_document ?(position_encoding = `UTF8) uri ~text =
|
|
let td =
|
|
let version = 1 in
|
|
let languageId = "fake language" in
|
|
let textDocument = { TextDocumentItem.uri; version; languageId; text } in
|
|
Text_document.make ~position_encoding { DidOpenTextDocumentParams.textDocument }
|
|
in
|
|
Text_document.apply_content_changes
|
|
td
|
|
[ TextDocumentContentChangeEvent.create ~text () ]
|
|
;;
|
|
|
|
let test_general text changes =
|
|
let test position_encoding =
|
|
let td =
|
|
let uri = DocumentUri.of_path "" in
|
|
let version = 1 in
|
|
let languageId = "fake language" in
|
|
let textDocument = { TextDocumentItem.uri; version; languageId; text } in
|
|
Text_document.make ~position_encoding { DidOpenTextDocumentParams.textDocument }
|
|
in
|
|
let td =
|
|
Text_document.apply_content_changes
|
|
td
|
|
(ListLabels.map changes ~f:(fun (range, text) ->
|
|
TextDocumentContentChangeEvent.create ?range ~text ()))
|
|
in
|
|
Text_document.text td
|
|
in
|
|
let utf8 = test `UTF8 in
|
|
let utf16 = test `UTF16 in
|
|
if String.equal utf16 utf8
|
|
then printf "result: %s\n" (String.escaped utf8)
|
|
else (
|
|
print_endline "[FAILURE] utf16 and utf8 disagree";
|
|
printf "utf16: %s\n" (String.escaped utf16);
|
|
printf "utf8: %s\n" (String.escaped utf8))
|
|
;;
|
|
|
|
let test text range ~change = test_general text [ Some range, change ]
|
|
|
|
let test_multiple text changes =
|
|
test_general text (List.map changes ~f:(fun (range, text) -> Some range, text))
|
|
;;
|
|
|
|
let%expect_test "first line insert" =
|
|
let range = tuple_range (0, 1) (0, 3) in
|
|
test "foo bar baz" range ~change:"XXXX";
|
|
[%expect
|
|
{|
|
|
result: fXXXX bar baz |}]
|
|
;;
|
|
|
|
let%expect_test "null edit" =
|
|
test "foo bar" (tuple_range (0, 2) (0, 2)) ~change:"";
|
|
[%expect
|
|
{|
|
|
result: foo bar |}]
|
|
;;
|
|
|
|
let%expect_test "no range" =
|
|
test_general "foo bar baz" [ None, "XXXX" ];
|
|
[%expect
|
|
{|
|
|
result: XXXX |}]
|
|
;;
|
|
|
|
let%expect_test "char by char" =
|
|
test_multiple
|
|
""
|
|
[ tuple_range (0, 0) (0, 0), "f"
|
|
; tuple_range (0, 1) (0, 1), "o"
|
|
; tuple_range (0, 2) (0, 2), "o"
|
|
];
|
|
[%expect
|
|
{|
|
|
result: foo |}]
|
|
;;
|
|
|
|
let%expect_test "char by char - 2" =
|
|
test_multiple
|
|
"char by char - 2\n"
|
|
[ tuple_range (1, 10) (1, 10), "b"
|
|
; tuple_range (1, 10) (1, 10), "a"
|
|
; tuple_range (1, 10) (1, 10), "r"
|
|
; tuple_range (1, 1) (1, 2), ""
|
|
];
|
|
[%expect
|
|
{|
|
|
result: char by char - 2\nbr |}]
|
|
;;
|
|
|
|
let%expect_test "char by char - 3" =
|
|
test_multiple
|
|
"first line skip\nchar by char - 2\n"
|
|
[ tuple_range (1, 4) (1, 5), ""
|
|
; tuple_range (1, 3) (1, 4), ""
|
|
; tuple_range (1, 3) (1, 3), "x"
|
|
];
|
|
[%expect
|
|
{|
|
|
result: first line skip\nchaxby char - 2\n |}]
|
|
;;
|
|
|
|
let%expect_test "insert last" =
|
|
test "x" (tuple_range (0, 1) (0, 1)) ~change:"y";
|
|
[%expect
|
|
{|
|
|
result: xy |}];
|
|
test "x\ny" (tuple_range (1, 1) (1, 1)) ~change:"z";
|
|
[%expect
|
|
{|
|
|
result: x\nyz |}];
|
|
test "x\ny" (tuple_range (1, 10) (1, 10)) ~change:"z";
|
|
[%expect
|
|
{|
|
|
result: x\nyz |}]
|
|
;;
|
|
|
|
let%expect_test "replace second line" =
|
|
let range = tuple_range (1, 0) (2, 0) in
|
|
test "foo\nbar\nbaz\n" range ~change:"XXXX\n";
|
|
[%expect
|
|
{|
|
|
result: foo\nXXXX\nbaz\n |}]
|
|
;;
|
|
|
|
let%expect_test "edit in second line" =
|
|
let range = tuple_range (1, 1) (1, 2) in
|
|
test "foo\nbar\nbaz\n" range ~change:"-XXX-";
|
|
[%expect
|
|
{|
|
|
result: foo\nb-XXX-r\nbaz\n |}]
|
|
;;
|
|
|
|
let%expect_test "insert at the end" =
|
|
let range = tuple_range (3, 0) (3, 0) in
|
|
test "foo\nbar\nbaz\n" range ~change:"XXX";
|
|
[%expect
|
|
{|
|
|
result: foo\nbar\nbaz\nXXX |}];
|
|
let range = tuple_range (3, 0) (4, 0) in
|
|
test "foo\nbar\nbaz\n" range ~change:"XXX";
|
|
[%expect
|
|
{|
|
|
result: foo\nbar\nbaz\nXXX |}]
|
|
;;
|
|
|
|
let%expect_test "insert at the beginning" =
|
|
let range = tuple_range (0, 0) (0, 0) in
|
|
test "foo\n\bar\nbaz\n" range ~change:"XXX\n";
|
|
[%expect
|
|
{|
|
|
result: XXX\nfoo\n\bar\nbaz\n |}]
|
|
;;
|
|
|
|
let%expect_test "insert in the middle" =
|
|
test "ab" (tuple_range (0, 1) (0, 1)) ~change:"---";
|
|
[%expect
|
|
{|
|
|
result: a---b |}]
|
|
;;
|
|
|
|
let%expect_test "replace first line" =
|
|
let range = tuple_range (0, 0) (1, 0) in
|
|
test "foo\nbar\n" range ~change:"baz\n";
|
|
[%expect
|
|
{|
|
|
result: baz\nbar\n |}]
|
|
;;
|
|
|
|
let%expect_test "beyond max char" =
|
|
let range = tuple_range (0, 0) (0, 100) in
|
|
test "foo\nbar\n" range ~change:"baz";
|
|
[%expect
|
|
{|
|
|
result: baz\nbar\n |}]
|
|
;;
|
|
|
|
let%expect_test "entire line without newline" =
|
|
test "xxx\n" (tuple_range (0, 0) (0, 3)) ~change:"baz";
|
|
[%expect
|
|
{|
|
|
result: baz\n |}];
|
|
test "xxx\n" (tuple_range (0, 0) (0, 4)) ~change:"baz";
|
|
[%expect
|
|
{|
|
|
result: baz\n |}];
|
|
test "xxx\n" (tuple_range (0, 0) (1, 0)) ~change:"baz";
|
|
[%expect
|
|
{|
|
|
result: baz |}]
|
|
;;
|
|
|
|
let%expect_test "replace two lines" =
|
|
test "a\nb\nc\n" (tuple_range (0, 0) (2, 0)) ~change:"XXX\n";
|
|
[%expect
|
|
{|
|
|
result: XXX\nc\n |}]
|
|
;;
|
|
|
|
let%expect_test "join lines" =
|
|
test "a\nb" (tuple_range (0, 1) (1, 0)) ~change:"";
|
|
[%expect
|
|
{|
|
|
result: ab |}]
|
|
;;
|
|
|
|
let%expect_test "remove text" =
|
|
test "a---b" (tuple_range (0, 1) (0, 4)) ~change:"";
|
|
[%expect
|
|
{|
|
|
result: ab |}]
|
|
;;
|
|
|
|
let%expect_test "remove newline - 1" =
|
|
test "\n" (tuple_range (0, 0) (0, 1)) ~change:"";
|
|
[%expect
|
|
{|
|
|
result: \n |}]
|
|
;;
|
|
|
|
let%expect_test "remove newlines - 2" =
|
|
test_multiple "\nXXX\n" [ tuple_range (0, 0) (0, 1), "" ];
|
|
[%expect
|
|
{|
|
|
result: \nXXX\n |}]
|
|
;;
|
|
|
|
let%expect_test "remove newlines - 3" =
|
|
test_multiple
|
|
"\nXXX\n\n"
|
|
[ tuple_range (0, 0) (0, 1), ""; tuple_range (0, 1) (0, 2), "" ];
|
|
[%expect
|
|
{|
|
|
result: \nXXX\n\n |}]
|
|
;;
|
|
|
|
let%expect_test "update when inserting a line at the end of the doc" =
|
|
test "let x = 1;\n\nlet y = 2;" (tuple_range (2, 10) (2, 10)) ~change:"\n-ZZZ";
|
|
[%expect
|
|
{|
|
|
result: let x = 1;\n\nlet y = 2;\n-ZZZ |}]
|
|
;;
|
|
|
|
let%expect_test "update when inserting a line at the end of the doc" =
|
|
test_multiple
|
|
"1\n2\n3\n"
|
|
[ tuple_range (1, 9) (1, 9), "l"; tuple_range (1, 9) (1, 10), "" ];
|
|
[%expect
|
|
{|
|
|
result: 1\n2l\n3\n |}]
|
|
;;
|
|
|
|
let%expect_test "absolute_position" =
|
|
let text = "foo|bar\nbaz.x" in
|
|
let td = make_document (Uri.of_path "foo.ml") ~text in
|
|
let test (line, character) =
|
|
let offset = Text_document.absolute_position td (Position.create ~line ~character) in
|
|
printf "position: %d/%d\n" offset (String.length text)
|
|
in
|
|
test (0, 0);
|
|
[%expect {| position: 0/13 |}];
|
|
test (3, 0);
|
|
[%expect {| position: 13/13 |}];
|
|
test (1, 0);
|
|
[%expect {| position: 8/13 |}];
|
|
test (1, 100);
|
|
[%expect {| position: 13/13 |}];
|
|
test (0, 100);
|
|
[%expect {| position: 7/13 |}];
|
|
test (100, 0);
|
|
[%expect {| position: 13/13 |}]
|
|
;;
|
|
|
|
let%expect_test "replace second line first line is \\n" =
|
|
let range = tuple_range (1, 2) (1, 2) in
|
|
let doc = make_document (Uri.of_path "foo.ml") ~text:"\nfoo\nbar\nbaz\n" in
|
|
let edit = TextEdit.create ~newText:"change" ~range in
|
|
let new_doc = Text_document.apply_text_document_edits doc [ edit ] in
|
|
new_doc |> Text_document.text |> String.escaped |> print_endline;
|
|
[%expect
|
|
{|
|
|
\nfochangeo\nbar\nbaz\n |}]
|
|
;;
|
|
|
|
let%expect_test "get position after change" =
|
|
let range = tuple_range (1, 2) (1, 2) in
|
|
let doc = make_document (Uri.of_path "foo.ml") ~text:"\nfoo\nbar\nbaz\n" in
|
|
let edit = TextDocumentContentChangeEvent.create ~text:"change" ~range () in
|
|
let new_doc = Text_document.apply_content_changes doc [ edit ] in
|
|
let pos = Text_document.absolute_position new_doc range.start in
|
|
new_doc |> Text_document.text |> String.escaped |> print_endline;
|
|
printf "pos: %d\n" pos;
|
|
[%expect
|
|
{|
|
|
\nfochangeo\nbar\nbaz\n
|
|
pos: 22 |}]
|
|
;;
|