diff options
author | stuebinm | 2024-04-19 02:49:45 +0200 |
---|---|---|
committer | stuebinm | 2024-04-19 02:49:45 +0200 |
commit | f17762ec0ef9eea0ee3e67b0b2b1ec4fd623a72b (patch) | |
tree | d1ae38663152d0aebad0943e4de7816fbc39befe /src/changes.rs | |
parent | 93d72079a86849e0453c9130c73e1702e3d66f69 (diff) |
(instead of just printing them, might be useful for scripts — also, I've
not come up with a better name than "nixq" yet, so it really ought to be
able to query things)
Diffstat (limited to 'src/changes.rs')
-rw-r--r-- | src/changes.rs | 45 |
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 + } + }) +} |