mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-08-03 09:52:27 +00:00
fix: converts out of bounds offsets again (#115)
* fix: converts out of bounds offsets again * fix: wrong length calculation * dev: accept hash
This commit is contained in:
parent
5f27135419
commit
3a0e8e3d26
3 changed files with 77 additions and 5 deletions
|
@ -123,7 +123,10 @@ typst-pdf = { git = "https://github.com/Myriad-Dreamin/typst.git", branch = "tin
|
||||||
|
|
||||||
# typst = { path = "../typst/crates/typst" }
|
# typst = { path = "../typst/crates/typst" }
|
||||||
# typst-ide = { path = "../typst/crates/typst-ide" }
|
# typst-ide = { path = "../typst/crates/typst-ide" }
|
||||||
|
# typst-timing = { path = "../typst/crates/typst-timing" }
|
||||||
|
# typst-svg = { path = "../typst/crates/typst-svg" }
|
||||||
# typst-pdf = { path = "../typst/crates/typst-pdf" }
|
# typst-pdf = { path = "../typst/crates/typst-pdf" }
|
||||||
|
# typst-render = { path = "../typst/crates/typst-render" }
|
||||||
# typst-syntax = { path = "../typst/crates/typst-syntax" }
|
# typst-syntax = { path = "../typst/crates/typst-syntax" }
|
||||||
|
|
||||||
# typst-ts-svg-exporter = { path = "../typst.ts/exporter/svg" }
|
# typst-ts-svg-exporter = { path = "../typst.ts/exporter/svg" }
|
||||||
|
|
|
@ -74,8 +74,21 @@ pub mod lsp_to_typst {
|
||||||
lsp_position_encoding: LspPositionEncoding,
|
lsp_position_encoding: LspPositionEncoding,
|
||||||
typst_source: &Source,
|
typst_source: &Source,
|
||||||
) -> Option<TypstOffset> {
|
) -> Option<TypstOffset> {
|
||||||
if lsp_position.line >= typst_source.len_lines() as u32 {
|
let lines = typst_source.len_lines() as u32;
|
||||||
if lsp_position.line > typst_source.len_lines() as u32 || lsp_position.character > 0 {
|
if lsp_position.line >= lines
|
||||||
|
|| (lsp_position.line + 1 == lines && {
|
||||||
|
let last_line_offset = typst_source.line_to_byte(lines as usize - 1)?;
|
||||||
|
let last_line_chars = &typst_source.text()[last_line_offset..];
|
||||||
|
let len = match lsp_position_encoding {
|
||||||
|
LspPositionEncoding::Utf8 => last_line_chars.len(),
|
||||||
|
LspPositionEncoding::Utf16 => {
|
||||||
|
last_line_chars.chars().map(char::len_utf16).sum::<usize>()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
lsp_position.character as usize >= len
|
||||||
|
})
|
||||||
|
{
|
||||||
|
if lsp_position.line > lines || lsp_position.character > 0 {
|
||||||
log::warn!(
|
log::warn!(
|
||||||
"LSP position is out of bounds: {:?}, while only {:?} lines and {:?} characters at the end.",
|
"LSP position is out of bounds: {:?}, while only {:?} lines and {:?} characters at the end.",
|
||||||
lsp_position, typst_source.len_lines(), typst_source.line_to_range(typst_source.len_lines() - 1),
|
lsp_position, typst_source.len_lines(), typst_source.line_to_range(typst_source.len_lines() - 1),
|
||||||
|
@ -306,6 +319,7 @@ pub mod typst_to_lsp {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
use lsp_types::Position;
|
||||||
use typst::syntax::Source;
|
use typst::syntax::Source;
|
||||||
|
|
||||||
use crate::{lsp_to_typst, PositionEncoding};
|
use crate::{lsp_to_typst, PositionEncoding};
|
||||||
|
@ -332,6 +346,53 @@ mod test {
|
||||||
assert_eq!(res, 22..22);
|
assert_eq!(res, 22..22);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn issue_14_invalid_range_2() {
|
||||||
|
let source = Source::detached(
|
||||||
|
r"#let f(a) = {
|
||||||
|
a
|
||||||
|
}
|
||||||
|
",
|
||||||
|
);
|
||||||
|
let rng = LspRange {
|
||||||
|
start: LspPosition {
|
||||||
|
line: 2,
|
||||||
|
character: 1,
|
||||||
|
},
|
||||||
|
// EOF
|
||||||
|
end: LspPosition {
|
||||||
|
line: 3,
|
||||||
|
character: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let res = lsp_to_typst::range(rng, PositionEncoding::Utf16, &source).unwrap();
|
||||||
|
assert_eq!(res, 19..source.len_bytes());
|
||||||
|
// EOF
|
||||||
|
let rng = LspRange {
|
||||||
|
start: LspPosition {
|
||||||
|
line: 3,
|
||||||
|
character: 1,
|
||||||
|
},
|
||||||
|
end: LspPosition {
|
||||||
|
line: 4,
|
||||||
|
character: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let res = lsp_to_typst::range(rng, PositionEncoding::Utf16, &source).unwrap();
|
||||||
|
assert_eq!(res, source.len_bytes()..source.len_bytes());
|
||||||
|
|
||||||
|
for line in 0..=5 {
|
||||||
|
for character in 0..2 {
|
||||||
|
let off = lsp_to_typst::position(
|
||||||
|
Position { line, character },
|
||||||
|
PositionEncoding::Utf16,
|
||||||
|
&source,
|
||||||
|
);
|
||||||
|
assert!(off.is_some(), "line: {line}, character: {character}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn utf16_position_to_utf8_offset() {
|
fn utf16_position_to_utf8_offset() {
|
||||||
let source = Source::detached(ENCODING_TEST_STRING);
|
let source = Source::detached(ENCODING_TEST_STRING);
|
||||||
|
|
|
@ -139,8 +139,16 @@ fn e2e() {
|
||||||
std::env::set_var("RUST_BACKTRACE", "full");
|
std::env::set_var("RUST_BACKTRACE", "full");
|
||||||
|
|
||||||
let cwd = find_git_root().unwrap();
|
let cwd = find_git_root().unwrap();
|
||||||
// assert!(exec("cargo", ["build", "--release", "--bin",
|
if cfg!(target_os = "...") {
|
||||||
// "tinymist"]).success());
|
let w = Command::new("cargo")
|
||||||
|
.args(["build", "--release", "--bin", "tinymist"])
|
||||||
|
.status();
|
||||||
|
assert!(handle_io(w).success());
|
||||||
|
handle_io(std::fs::copy(
|
||||||
|
cwd.join("target/release/tinymist.exe"),
|
||||||
|
cwd.join("editors/vscode/out/tinymist.exe"),
|
||||||
|
));
|
||||||
|
}
|
||||||
let root = cwd.join("target/e2e/tinymist");
|
let root = cwd.join("target/e2e/tinymist");
|
||||||
gen(&root.join("vscode"), |srv| {
|
gen(&root.join("vscode"), |srv| {
|
||||||
use lsp_types::notification::*;
|
use lsp_types::notification::*;
|
||||||
|
@ -347,7 +355,7 @@ fn e2e() {
|
||||||
std::fs::write(root.join("vscode/result_sorted.json"), c).unwrap();
|
std::fs::write(root.join("vscode/result_sorted.json"), c).unwrap();
|
||||||
let hash = format!("siphash128_13:{:x}", hash);
|
let hash = format!("siphash128_13:{:x}", hash);
|
||||||
|
|
||||||
insta::assert_snapshot!(hash, @"siphash128_13:3ca43097c9772ff12a1918d876cbf6ad");
|
insta::assert_snapshot!(hash, @"siphash128_13:1e0ee515d35c16937e02684a605379bb");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct StableHash<'a>(&'a Value);
|
struct StableHash<'a>(&'a Value);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue