summaryrefslogtreecommitdiff
path: root/src/changes.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/changes.rs')
-rw-r--r--src/changes.rs45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/changes.rs b/src/changes.rs
index 5099364..986e9c4 100644
--- a/src/changes.rs
+++ b/src/changes.rs
@@ -1,3 +1,5 @@
+use std::path::PathBuf;
+
use rowan::NodeOrToken;
use crate::pipeline::Change;
@@ -174,3 +176,46 @@ fn next_indentation(node: &rnix::SyntaxNode) -> Option<usize> {
None
}
}
+
+/// give line & column of a position marker in the given string
+fn line_at_textpos(content: &str, pos: rowan::TextSize) -> Option<(usize, usize)> {
+ let pos: usize = pos.into();
+ content
+ .split("\n")
+ .scan(0usize, |acc,line| {
+ let start = *acc;
+ let end = line.len() + 1 + start;
+ *acc = end;
+ Some((start, end))
+ })
+ .enumerate()
+ .find(|(_, (_, end))| *end > pos)
+ .map(|(line, (start, _))| (line + 1, pos + 1 - start))
+}
+
+pub fn format_pos(path: &PathBuf, content: &str, pos1: rowan::TextSize) -> String {
+ let (line1, col1) = line_at_textpos(content, pos1).unwrap();
+ format!("{path:?}:{line1}:{col1}")
+}
+
+pub fn format_range(path: &PathBuf, content: &str, range: rowan::TextRange) -> String {
+ let (line1, col1) = line_at_textpos(content, range.start()).unwrap();
+ let (line2, col2) = line_at_textpos(content, range.end()).unwrap();
+ format!("{}:{line1}:{col1}-{line2}:{col2}", path.to_string_lossy())
+}
+
+pub fn format_range_json(path: &PathBuf, content: &str, range: rowan::TextRange) -> serde_json::Value {
+ let (line1, col1) = line_at_textpos(content, range.start()).unwrap();
+ let (line2, col2) = line_at_textpos(content, range.end()).unwrap();
+ serde_json::json!({
+ "file": path,
+ "start": {
+ "line": line1,
+ "column": col1
+ },
+ "end": {
+ "line": line2,
+ "column": col2
+ }
+ })
+}