using ropey
This commit is contained in:
Generated
+17
@@ -448,6 +448,7 @@ dependencies = [
|
|||||||
"dashmap 6.1.0",
|
"dashmap 6.1.0",
|
||||||
"mist-codegen",
|
"mist-codegen",
|
||||||
"mist-parser",
|
"mist-parser",
|
||||||
|
"ropey",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
@@ -623,6 +624,16 @@ dependencies = [
|
|||||||
"bitflags 2.11.1",
|
"bitflags 2.11.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ropey"
|
||||||
|
version = "1.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "93411e420bcd1a75ddd1dc3caf18c23155eda2c090631a85af21ba19e97093b5"
|
||||||
|
dependencies = [
|
||||||
|
"smallvec",
|
||||||
|
"str_indices",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
@@ -742,6 +753,12 @@ version = "1.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "str_indices"
|
||||||
|
version = "0.4.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d08889ec5408683408db66ad89e0e1f93dff55c73a4ccc71c427d5b277ee47e6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.117"
|
version = "2.0.117"
|
||||||
|
|||||||
@@ -19,3 +19,4 @@ cargo_metadata = "0.23.1"
|
|||||||
|
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
ropey = "1"
|
||||||
|
|||||||
+31
-24
@@ -8,6 +8,7 @@ use std::path::{Component, PathBuf};
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use mist_parser::rev_mapper;
|
use mist_parser::rev_mapper;
|
||||||
|
use ropey::Rope;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
use tower_lsp::jsonrpc::Result;
|
use tower_lsp::jsonrpc::Result;
|
||||||
use tower_lsp::lsp_types::notification::Notification;
|
use tower_lsp::lsp_types::notification::Notification;
|
||||||
@@ -539,44 +540,50 @@ pub fn from_rust_to_mist(mut path: PathBuf) -> PathBuf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn insert_at_position(s: &str, line: usize, col: usize, insert: &str) -> String {
|
fn insert_at_position(s: &str, line: usize, col: usize, insert: &str) -> String {
|
||||||
let mut lines: Vec<String> = s.lines().map(|l| l.to_string()).collect();
|
let mut rope = Rope::from_str(s);
|
||||||
|
|
||||||
// Convert to 0-index
|
// Convert to 0-indexed
|
||||||
let line_idx = line.saturating_sub(1);
|
let line_idx = line.saturating_sub(1);
|
||||||
let col_idx = col.saturating_sub(1);
|
let col_idx = col.saturating_sub(1);
|
||||||
|
|
||||||
// Ensure line exists (optional behavior: extend with empty lines)
|
// Clamp line
|
||||||
if line_idx >= lines.len() {
|
let line_idx = line_idx.min(rope.len_lines().saturating_sub(1));
|
||||||
lines.resize(line_idx + 1, String::new());
|
|
||||||
}
|
|
||||||
|
|
||||||
let target = &mut lines[line_idx];
|
// Get start char index of the line
|
||||||
|
let line_start = rope.line_to_char(line_idx);
|
||||||
|
|
||||||
// Clamp column to valid char boundary
|
// Get line length in chars
|
||||||
let char_idx = target
|
let line = rope.line(line_idx);
|
||||||
.char_indices()
|
let line_len = line.len_chars();
|
||||||
.nth(col_idx)
|
|
||||||
.map(|(i, _)| i)
|
|
||||||
.unwrap_or(target.len()); // if past end, append
|
|
||||||
|
|
||||||
target.insert_str(char_idx, insert);
|
// Clamp column
|
||||||
|
let col_idx = col_idx.min(line_len);
|
||||||
|
|
||||||
lines.join("\n")
|
// Final insertion char index
|
||||||
|
let insert_idx = line_start + col_idx;
|
||||||
|
|
||||||
|
rope.insert(insert_idx, insert);
|
||||||
|
|
||||||
|
rope.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_row_col(output: &str, inject: &str) -> Option<(usize, usize)> {
|
fn find_row_col(output: &str, inject: &str) -> Option<(usize, usize)> {
|
||||||
// 1. Find the flat byte index just like your original code
|
let rope = Rope::from_str(output);
|
||||||
|
|
||||||
let byte_idx = output.find(inject)?;
|
let byte_idx = output.find(inject)?;
|
||||||
|
|
||||||
// 2. Slice the string up to the match point
|
// Convert byte index -> char index
|
||||||
let prefix = &output[..byte_idx];
|
let char_idx = output[..byte_idx].chars().count();
|
||||||
|
|
||||||
// 3. Row = number of newlines found before the match + 1 (1-indexed)
|
// Ropey line lookup
|
||||||
let row = prefix.lines().count();
|
let line_idx = rope.char_to_line(char_idx);
|
||||||
|
|
||||||
// 4. Column = character count of the remaining text on the current line + 1
|
// Line start char index
|
||||||
// (Using .chars().count() ensures it works with multi-byte UTF-8 symbols)
|
let line_start = rope.line_to_char(line_idx);
|
||||||
let col = prefix.lines().last().unwrap_or("").chars().count() + 1;
|
|
||||||
|
|
||||||
Some((row, col))
|
// Column within line
|
||||||
|
let col_idx = char_idx - line_start;
|
||||||
|
|
||||||
|
// Return 1-indexed
|
||||||
|
Some((line_idx + 1, col_idx + 1))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user