Skip to content

Commit

Permalink
Merge pull request #1118 from julia-vscode/fe/apply_edits
Browse files Browse the repository at this point in the history
apply_text_edits: make sure indices are computed with updated document.
  • Loading branch information
pfitzseb committed Jul 2, 2022
2 parents 315d3c7 + 61cb95b commit c36876b
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 18 deletions.
5 changes: 0 additions & 5 deletions src/document.jl
Expand Up @@ -70,11 +70,6 @@ function set_is_workspace_file(doc::Document, value::Bool)
doc._workspace_file = value
end

function applytextdocumentchanges(doc::Document, change)
text_document = apply_text_edits(doc._text_document, [change], get_version(doc._text_document))
set_text_document!(doc, text_document)
end

get_offset(doc::Document, line::Integer, character::Integer) = get_offset(doc._text_document, line, character)
get_offset(doc::Document, p::Position) = get_offset(doc, p.line, p.character)
get_offset(doc::Document, r::Range) = get_offset(doc, r.start):get_offset(doc, r.stop)
Expand Down
3 changes: 3 additions & 0 deletions src/textdocument.jl
Expand Up @@ -82,6 +82,9 @@ function apply_text_edits(doc::TextDocument, edits, new_version)
# No range given, replace all text
content = edit.text
else
# Rebind doc here so that we compute the range for the updated document in
# _convert_lsrange_to_jlrange when applying multiple edits
doc = TextDocument(doc._uri, content, new_version)
editrange = _convert_lsrange_to_jlrange(doc, edit.range)
content = string(content[1:prevind(content, editrange.start)], edit.text, content[nextind(content, editrange.stop):lastindex(content)])
end
Expand Down
1 change: 0 additions & 1 deletion test/runtests.jl
Expand Up @@ -3,7 +3,6 @@ using LanguageServer:
Document,
TextDocument,
apply_text_edits,
applytextdocumentchanges,
get_text_document,
set_text_document!,
get_text,
Expand Down
33 changes: 23 additions & 10 deletions test/test_document.jl
Expand Up @@ -48,23 +48,36 @@ s6 = "\n"
d6 = Document(TextDocument(uri"untitled:none", s6, 0), false)
@test get_line_offsets(get_text_document(d6)) == [0,1]

@testset "applytextdocumentchanges" begin
doc = LS.Document(TextDocument(uri"file:///example/path/example.jl", "function foo()", 0), false)
c1 = LS.TextDocumentContentChangeEvent(LS.Range(LS.Position(0, 14), LS.Position(0, 14)),
0, "\n")
c2 = LS.TextDocumentContentChangeEvent(LS.Range(LS.Position(1, 0), LS.Position(1, 0)),
0, " ")
@testset "apply_text_edits" begin
version = 0
doc = TextDocument(uri"file:///example/path/example.jl", "function foo()", version)
c1 = LS.TextDocumentContentChangeEvent(LS.Range(LS.Position(0, 14), LS.Position(0, 14)), 0, "\n")
c2 = LS.TextDocumentContentChangeEvent(LS.Range(LS.Position(1, 0), LS.Position(1, 0)), 0, " ")
c3 = LS.TextDocumentContentChangeEvent(missing, missing, "println(\"Hello World\")")

LS.applytextdocumentchanges(doc, c1)
doc = LS.apply_text_edits(doc, [c1], version += 1)
@test LS.get_text(doc) == "function foo()\n"
# Implicitly test for issue #403
LS.applytextdocumentchanges(doc, c2)
doc = LS.apply_text_edits(doc, [c2], version += 1)
@test LS.get_text(doc) == "function foo()\n "
LS.applytextdocumentchanges(doc, c3)
doc = LS.apply_text_edits(doc, [c3], version += 1)
@test LS.get_text(doc) == "println(\"Hello World\")"

# Test muliple edits (#1118)
doc = TextDocument(uri"file:///example/path/example.jl", "module Crash\n\n\n\nend # module Crash\n", version)
edits = [
LS.TextDocumentContentChangeEvent(LS.Range(LS.Position(2, 0), LS.Position(2, 0)), 0, "p"),
LS.TextDocumentContentChangeEvent(LS.Range(LS.Position(2, 1), LS.Position(2, 1)), 0, "r"),
LS.TextDocumentContentChangeEvent(LS.Range(LS.Position(2, 2), LS.Position(2, 2)), 0, "i"),
LS.TextDocumentContentChangeEvent(LS.Range(LS.Position(2, 3), LS.Position(2, 3)), 0, "n"),
LS.TextDocumentContentChangeEvent(LS.Range(LS.Position(2, 4), LS.Position(2, 4)), 0, "t"),
]
doc = LS.apply_text_edits(doc, edits, version += 1)
@test LS.get_text(doc) == "module Crash\n\nprint\n\nend # module Crash\n"

# doc currently has only one line, applying change to 2nd line should throw
@test_throws LanguageServer.LSOffsetError LS.applytextdocumentchanges(doc, c2)
doc = LS.apply_text_edits(doc, [c3], version += 1)
@test_throws LanguageServer.LSOffsetError LS.apply_text_edits(doc, [c2], version += 1)
end

@testset "UTF16 handling" begin
Expand Down
4 changes: 2 additions & 2 deletions test/test_edit.jl
Expand Up @@ -21,10 +21,10 @@ mktempdir() do dir
LanguageServer.VersionedTextDocumentIdentifier(get_uri(doc), 5),
[LanguageServer.TextDocumentContentChangeEvent(LanguageServer.Range(LanguageServer.Position(s1...), LanguageServer.Position(s2...)), 0, insert)]
)
tdcce = params.contentChanges[1]
tdcce = params.contentChanges

# TODO: This should only re-parse necessary parts of the document
LanguageServer.applytextdocumentchanges(doc, tdcce)
LanguageServer.set_text_document!(doc, LanguageServer.apply_text_edits(get_text_document(doc), tdcce, 1))
LanguageServer.parse_all(doc, server)

new_cst = CSTParser.parse(LanguageServer.get_text(doc), true)
Expand Down

0 comments on commit c36876b

Please sign in to comment.