Skip to content

Commit 1504949

Browse files
wip
1 parent 43de88f commit 1504949

File tree

2 files changed

+92
-15
lines changed

2 files changed

+92
-15
lines changed

crates/djls-templates/src/nodelist.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use djls_source::Span;
2+
23
use crate::db::Db as TemplateDb;
34

45
#[salsa::tracked(debug)]

crates/djls-workspace/src/workspace.rs

Lines changed: 91 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,9 @@ impl Workspace {
9898
document: TextDocument,
9999
) -> Option<WorkspaceFileEvent> {
100100
self.buffers.open(url.clone(), document);
101-
self.ensure_file_for_url(db, url).inspect(|event| {
102-
if let WorkspaceFileEvent::Updated { file, .. } = event {
103-
db.touch_file(*file);
104-
}
101+
self.ensure_file_for_url(db, url).map(|event| {
102+
db.touch_file(event.file());
103+
event
105104
})
106105
}
107106

@@ -128,8 +127,9 @@ impl Workspace {
128127
}
129128
}
130129

131-
self.ensure_file_for_url(db, url).inspect(|event| {
130+
self.ensure_file_for_url(db, url).map(|event| {
132131
db.touch_file(event.file());
132+
event
133133
})
134134
}
135135

@@ -153,20 +153,23 @@ impl Workspace {
153153
/// Touch the tracked file when the client saves the document.
154154
pub fn save_document(&self, db: &mut dyn Db, url: &Url) -> Option<WorkspaceFileEvent> {
155155
let path = paths::url_to_path(url)?;
156+
156157
let event = self.track_file(db, path.as_path());
157158
db.touch_file(event.file());
158159
Some(event)
159160
}
160161

161162
/// Close a document, removing it from buffers and touching the tracked file.
162163
pub fn close_document(&mut self, db: &mut dyn Db, url: &Url) -> Option<TextDocument> {
164+
let closed = self.buffers.close(url);
165+
163166
if let Some(path) = paths::url_to_path(url) {
164167
if let Some(file) = self.files.get(&path) {
165168
db.touch_file(*file);
166169
}
167170
}
168171

169-
self.buffers.close(url)
172+
closed
170173
}
171174

172175
/// Get a document from the buffer if it's open.
@@ -202,12 +205,12 @@ mod tests {
202205
use std::sync::Arc;
203206

204207
use camino::Utf8Path;
208+
use camino::Utf8PathBuf;
205209
use tempfile::tempdir;
206210
use url::Url;
207211

208212
use super::*;
209213
use crate::encoding::PositionEncoding;
210-
use crate::InMemoryFileSystem;
211214
use crate::LanguageId;
212215

213216
#[salsa::db]
@@ -218,10 +221,10 @@ mod tests {
218221
}
219222

220223
impl TestDb {
221-
fn new() -> Self {
224+
fn new(fs: Arc<dyn FileSystem>) -> Self {
222225
Self {
223226
storage: salsa::Storage::default(),
224-
fs: Arc::new(InMemoryFileSystem::new()),
227+
fs,
225228
}
226229
}
227230
}
@@ -231,8 +234,8 @@ mod tests {
231234

232235
#[salsa::db]
233236
impl djls_source::Db for TestDb {
234-
fn read_file_source(&self, _path: &Utf8Path) -> std::io::Result<String> {
235-
Ok(String::new())
237+
fn read_file_source(&self, path: &Utf8Path) -> std::io::Result<String> {
238+
self.fs.read_to_string(path)
236239
}
237240
}
238241

@@ -246,7 +249,7 @@ mod tests {
246249
#[test]
247250
fn test_open_document() {
248251
let mut workspace = Workspace::new();
249-
let mut db = TestDb::new();
252+
let mut db = TestDb::new(workspace.file_system());
250253
let url = Url::parse("file:///test.py").unwrap();
251254

252255
let document = TextDocument::new("print('hello')".to_string(), 1, LanguageId::Python);
@@ -264,7 +267,7 @@ mod tests {
264267
#[test]
265268
fn test_update_document() {
266269
let mut workspace = Workspace::new();
267-
let mut db = TestDb::new();
270+
let mut db = TestDb::new(workspace.file_system());
268271
let url = Url::parse("file:///test.py").unwrap();
269272

270273
let document = TextDocument::new("initial".to_string(), 1, LanguageId::Python);
@@ -288,7 +291,7 @@ mod tests {
288291
#[test]
289292
fn test_close_document() {
290293
let mut workspace = Workspace::new();
291-
let mut db = TestDb::new();
294+
let mut db = TestDb::new(workspace.file_system());
292295
let url = Url::parse("file:///test.py").unwrap();
293296

294297
let document = TextDocument::new("content".to_string(), 1, LanguageId::Python);
@@ -306,7 +309,7 @@ mod tests {
306309
std::fs::write(&file_path, "disk content").unwrap();
307310

308311
let mut workspace = Workspace::new();
309-
let mut db = TestDb::new();
312+
let mut db = TestDb::new(workspace.file_system());
310313
let url = Url::from_file_path(&file_path).unwrap();
311314

312315
let document = TextDocument::new("buffer content".to_string(), 1, LanguageId::Python);
@@ -318,4 +321,77 @@ mod tests {
318321
.unwrap();
319322
assert_eq!(content, "buffer content");
320323
}
324+
325+
#[test]
326+
fn test_file_source_reads_from_buffer() {
327+
let mut workspace = Workspace::new();
328+
let mut db = TestDb::new(workspace.file_system());
329+
330+
let temp_dir = tempdir().unwrap();
331+
let file_path = Utf8PathBuf::from_path_buf(temp_dir.path().join("template.html")).unwrap();
332+
std::fs::write(file_path.as_std_path(), "disk template").unwrap();
333+
let url = Url::from_file_path(file_path.as_std_path()).unwrap();
334+
335+
let document = TextDocument::new("line1\nline2".to_string(), 1, LanguageId::HtmlDjango);
336+
let event = workspace
337+
.open_document(&mut db, &url, document.clone())
338+
.unwrap();
339+
let file = event.file();
340+
341+
let source = file.source(&db);
342+
assert_eq!(source.as_str(), document.content());
343+
344+
let line_index = file.line_index(&db);
345+
assert_eq!(line_index.to_line_col(0), (0, 0));
346+
assert_eq!(line_index.to_line_col(6), (1, 0));
347+
}
348+
349+
#[test]
350+
fn test_update_document_updates_source() {
351+
let mut workspace = Workspace::new();
352+
let mut db = TestDb::new(workspace.file_system());
353+
354+
let temp_dir = tempdir().unwrap();
355+
let file_path = Utf8PathBuf::from_path_buf(temp_dir.path().join("buffer.py")).unwrap();
356+
std::fs::write(file_path.as_std_path(), "disk").unwrap();
357+
let url = Url::from_file_path(file_path.as_std_path()).unwrap();
358+
359+
let document = TextDocument::new("initial".to_string(), 1, LanguageId::Python);
360+
let event = workspace.open_document(&mut db, &url, document).unwrap();
361+
let file = event.file();
362+
363+
let changes = vec![TextDocumentContentChangeEvent {
364+
range: None,
365+
range_length: None,
366+
text: "updated".to_string(),
367+
}];
368+
workspace
369+
.update_document(&mut db, &url, changes, 2, PositionEncoding::Utf16)
370+
.unwrap();
371+
372+
let source = file.source(&db);
373+
assert_eq!(source.as_str(), "updated");
374+
}
375+
376+
#[test]
377+
fn test_close_document_reverts_to_disk() {
378+
let mut workspace = Workspace::new();
379+
let mut db = TestDb::new(workspace.file_system());
380+
381+
let temp_dir = tempdir().unwrap();
382+
let file_path = Utf8PathBuf::from_path_buf(temp_dir.path().join("close.py")).unwrap();
383+
std::fs::write(file_path.as_std_path(), "disk content").unwrap();
384+
let url = Url::from_file_path(file_path.as_std_path()).unwrap();
385+
386+
let document = TextDocument::new("buffer content".to_string(), 1, LanguageId::Python);
387+
let event = workspace.open_document(&mut db, &url, document).unwrap();
388+
let file = event.file();
389+
390+
assert_eq!(file.source(&db).as_str(), "buffer content");
391+
392+
workspace.close_document(&mut db, &url);
393+
394+
let source_after = file.source(&db);
395+
assert_eq!(source_after.as_str(), "disk content");
396+
}
321397
}

0 commit comments

Comments
 (0)