Skip to content

Commit 1157640

Browse files
reshuffle! CHANGE PLACES
1 parent 3aeabfc commit 1157640

File tree

7 files changed

+116
-76
lines changed

7 files changed

+116
-76
lines changed

crates/djls-ide/src/diagnostics.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,17 +57,16 @@ impl DiagnosticError for ValidationError {
5757

5858
/// Convert a Span to an LSP Range using line offsets.
5959
fn span_to_lsp_range(span: Span, line_index: &LineIndex) -> lsp_types::Range {
60-
let (start_line, start_char) = line_index.to_line_col(span.start);
61-
let (end_line, end_char) = line_index.to_line_col(span.start.saturating_add(span.length));
60+
let (start_pos, end_pos) = span.to_line_col(line_index);
6261

6362
lsp_types::Range {
6463
start: lsp_types::Position {
65-
line: start_line,
66-
character: start_char,
64+
line: start_pos.line(),
65+
character: start_pos.column(),
6766
},
6867
end: lsp_types::Position {
69-
line: end_line,
70-
character: end_char,
68+
line: end_pos.line(),
69+
character: end_pos.column(),
7170
},
7271
}
7372
}

crates/djls-source/src/file.rs

Lines changed: 1 addition & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use camino::Utf8Path;
55
use camino::Utf8PathBuf;
66

77
use crate::db::Db;
8+
use crate::position::LineIndex;
89

910
#[salsa::input]
1011
pub struct File {
@@ -116,48 +117,3 @@ impl FileKind {
116117
}
117118
}
118119
}
119-
120-
#[derive(Debug, Clone, PartialEq, Eq)]
121-
pub struct LineIndex(Vec<u32>);
122-
123-
impl LineIndex {
124-
#[must_use]
125-
pub fn from_text(text: &str) -> Self {
126-
let mut starts = Vec::with_capacity(256);
127-
starts.push(0);
128-
for (i, b) in text.bytes().enumerate() {
129-
if b == b'\n' {
130-
starts.push(u32::try_from(i).unwrap_or_default() + 1);
131-
}
132-
}
133-
LineIndex(starts)
134-
}
135-
136-
#[must_use]
137-
pub fn to_line_col(&self, offset: u32) -> (u32, u32) {
138-
if self.0.is_empty() {
139-
return (0, 0);
140-
}
141-
142-
let line = match self.0.binary_search(&offset) {
143-
Ok(exact) => exact,
144-
Err(0) => 0,
145-
Err(next) => next - 1,
146-
};
147-
148-
let line_start = self.0[line];
149-
let column = offset.saturating_sub(line_start);
150-
151-
(u32::try_from(line).unwrap_or_default(), column)
152-
}
153-
154-
#[must_use]
155-
pub fn line_start(&self, line: u32) -> Option<u32> {
156-
self.0.get(line as usize).copied()
157-
}
158-
159-
#[must_use]
160-
pub fn lines(&self) -> &[u32] {
161-
&self.0
162-
}
163-
}

crates/djls-source/src/lib.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
mod db;
22
mod file;
3-
mod span;
3+
mod position;
44

55
pub use db::Db;
66
pub use file::File;
77
pub use file::FileKind;
8-
pub use file::LineIndex;
9-
pub use span::Span;
8+
pub use position::ByteOffset;
9+
pub use position::LineCol;
10+
pub use position::LineIndex;
11+
pub use position::Span;

crates/djls-source/src/position.rs

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
use serde::Serialize;
2+
3+
/// A byte offset within a text document.
4+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)]
5+
pub struct ByteOffset(pub u32);
6+
7+
/// A line and column position within a text document.
8+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9+
pub struct LineCol(pub (u32, u32));
10+
11+
impl LineCol {
12+
#[must_use]
13+
pub fn line(&self) -> u32 {
14+
self.0 .0
15+
}
16+
17+
#[must_use]
18+
pub fn column(&self) -> u32 {
19+
self.0 .1
20+
}
21+
}
22+
23+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)]
24+
pub struct Span {
25+
pub start: u32,
26+
pub length: u32,
27+
}
28+
29+
impl Span {
30+
#[must_use]
31+
pub fn new(start: u32, length: u32) -> Self {
32+
Self { start, length }
33+
}
34+
35+
#[must_use]
36+
pub fn start_offset(&self) -> ByteOffset {
37+
ByteOffset(self.start)
38+
}
39+
40+
#[must_use]
41+
pub fn end_offset(&self) -> ByteOffset {
42+
ByteOffset(self.start.saturating_add(self.length))
43+
}
44+
45+
/// Convert this span to start and end line/column positions using the given line index.
46+
#[must_use]
47+
pub fn to_line_col(&self, line_index: &LineIndex) -> (LineCol, LineCol) {
48+
let start = line_index.to_line_col(self.start_offset());
49+
let end = line_index.to_line_col(self.end_offset());
50+
(start, end)
51+
}
52+
}
53+
54+
#[derive(Debug, Clone, PartialEq, Eq)]
55+
pub struct LineIndex(Vec<u32>);
56+
57+
impl LineIndex {
58+
#[must_use]
59+
pub fn from_text(text: &str) -> Self {
60+
let mut starts = Vec::with_capacity(256);
61+
starts.push(0);
62+
for (i, b) in text.bytes().enumerate() {
63+
if b == b'\n' {
64+
starts.push(u32::try_from(i).unwrap_or_default() + 1);
65+
}
66+
}
67+
LineIndex(starts)
68+
}
69+
70+
#[must_use]
71+
pub fn to_line_col(&self, offset: ByteOffset) -> LineCol {
72+
if self.0.is_empty() {
73+
return LineCol((0, 0));
74+
}
75+
76+
let line = match self.0.binary_search(&offset.0) {
77+
Ok(exact) => exact,
78+
Err(0) => 0,
79+
Err(next) => next - 1,
80+
};
81+
82+
let line_start = self.0[line];
83+
let column = offset.0.saturating_sub(line_start);
84+
85+
LineCol((u32::try_from(line).unwrap_or_default(), column))
86+
}
87+
88+
#[must_use]
89+
pub fn line_start(&self, line: u32) -> Option<u32> {
90+
self.0.get(line as usize).copied()
91+
}
92+
93+
#[must_use]
94+
pub fn lines(&self) -> &[u32] {
95+
&self.0
96+
}
97+
}

crates/djls-source/src/span.rs

Lines changed: 0 additions & 14 deletions
This file was deleted.

crates/djls-workspace/src/document.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,6 @@ impl TextDocument {
150150
self.offset_for_position_with_text(position, &self.content, encoding)
151151
}
152152

153-
#[must_use]
154-
pub fn offset_to_position(&self, offset: u32) -> Position {
155-
let (line, character) = self.line_index.to_line_col(offset);
156-
Position::new(line, character)
157-
}
158-
159153
/// Convert position to text offset using the specified encoding.
160154
///
161155
/// Returns a valid offset, clamping out-of-bounds positions to document/line boundaries.

crates/djls-workspace/src/workspace.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,8 +340,14 @@ mod tests {
340340
assert_eq!(source.as_str(), document.content());
341341

342342
let line_index = file.line_index(&db);
343-
assert_eq!(line_index.to_line_col(0), (0, 0));
344-
assert_eq!(line_index.to_line_col(6), (1, 0));
343+
assert_eq!(
344+
line_index.to_line_col(djls_source::ByteOffset(0)),
345+
djls_source::LineCol((0, 0))
346+
);
347+
assert_eq!(
348+
line_index.to_line_col(djls_source::ByteOffset(6)),
349+
djls_source::LineCol((1, 0))
350+
);
345351
}
346352

347353
#[test]

0 commit comments

Comments
 (0)