66//! state (open documents) while the database observes it through the overlay.
77use std:: sync:: Arc ;
88
9- use camino:: Utf8Path ;
10- use camino:: Utf8PathBuf ;
119use djls_source:: File ;
1210use djls_source:: PositionEncoding ;
1311use tower_lsp_server:: lsp_types:: TextDocumentContentChangeEvent ;
@@ -21,28 +19,6 @@ use crate::files::OsFileSystem;
2119use crate :: files:: OverlayFileSystem ;
2220use crate :: paths;
2321
24- /// Result of a workspace operation that affected a tracked file.
25- #[ derive( Clone ) ]
26- pub enum WorkspaceFileEvent {
27- Created { file : File , path : Utf8PathBuf } ,
28- Updated { file : File , path : Utf8PathBuf } ,
29- }
30-
31- impl WorkspaceFileEvent {
32- #[ must_use]
33- pub fn file ( & self ) -> File {
34- match self {
35- Self :: Created { file, .. } | Self :: Updated { file, .. } => * file,
36- }
37- }
38-
39- #[ must_use]
40- pub fn path ( & self ) -> & Utf8Path {
41- match self {
42- Self :: Created { path, .. } | Self :: Updated { path, .. } => path. as_path ( ) ,
43- }
44- }
45- }
4622/// Workspace facade that manages buffers and file system.
4723///
4824/// This struct provides a unified interface for managing document buffers
@@ -83,13 +59,19 @@ impl Workspace {
8359 & self . buffers
8460 }
8561
62+ /// Get a document from the buffer if it's open.
63+ #[ must_use]
64+ pub fn get_document ( & self , url : & Url ) -> Option < TextDocument > {
65+ self . buffers . get ( url)
66+ }
67+
8668 /// Open a document in the workspace and ensure a corresponding Salsa file exists.
8769 pub fn open_document (
8870 & mut self ,
8971 db : & mut dyn Db ,
9072 url : & Url ,
9173 document : TextDocument ,
92- ) -> Option < WorkspaceFileEvent > {
74+ ) -> Option < File > {
9375 self . buffers . open ( url. clone ( ) , document) ;
9476 self . ensure_and_touch ( db, url)
9577 }
@@ -102,7 +84,7 @@ impl Workspace {
10284 changes : Vec < TextDocumentContentChangeEvent > ,
10385 version : i32 ,
10486 encoding : PositionEncoding ,
105- ) -> Option < WorkspaceFileEvent > {
87+ ) -> Option < File > {
10688 if let Some ( mut document) = self . buffers . get ( url) {
10789 document. update ( changes, version, encoding) ;
10890 self . buffers . update ( url. clone ( ) , document) ;
@@ -120,25 +102,8 @@ impl Workspace {
120102 self . ensure_and_touch ( db, url)
121103 }
122104
123- /// Ensure a file is tracked in Salsa and report its state.
124- pub fn track_file ( & self , db : & mut dyn Db , path : & Utf8Path ) -> WorkspaceFileEvent {
125- let path_buf = path. to_owned ( ) ;
126- let ( file, existed) = db. intern_file ( path) ;
127- if existed {
128- WorkspaceFileEvent :: Updated {
129- file,
130- path : path_buf,
131- }
132- } else {
133- WorkspaceFileEvent :: Created {
134- file,
135- path : path_buf,
136- }
137- }
138- }
139-
140105 /// Touch the tracked file when the client saves the document.
141- pub fn save_document ( & mut self , db : & mut dyn Db , url : & Url ) -> Option < WorkspaceFileEvent > {
106+ pub fn save_document ( & mut self , db : & mut dyn Db , url : & Url ) -> Option < File > {
142107 self . ensure_and_touch ( db, url)
143108 }
144109
@@ -155,21 +120,11 @@ impl Workspace {
155120 closed
156121 }
157122
158- /// Get a document from the buffer if it's open.
159- #[ must_use]
160- pub fn get_document ( & self , url : & Url ) -> Option < TextDocument > {
161- self . buffers . get ( url)
162- }
163-
164- pub fn ensure_and_touch ( & self , db : & mut dyn Db , url : & Url ) -> Option < WorkspaceFileEvent > {
165- self . ensure_file_for_url ( db, url) . inspect ( |event| {
166- db. touch_file ( event. file ( ) ) ;
167- } )
168- }
169-
170- fn ensure_file_for_url ( & self , db : & mut dyn Db , url : & Url ) -> Option < WorkspaceFileEvent > {
123+ fn ensure_and_touch ( & self , db : & mut dyn Db , url : & Url ) -> Option < File > {
171124 let path = paths:: url_to_path ( url) ?;
172- Some ( self . track_file ( db, path. as_path ( ) ) )
125+ let file = db. track_file ( path. as_path ( ) ) ;
126+ db. touch_file ( file) ;
127+ Some ( file)
173128 }
174129}
175130
@@ -399,14 +354,14 @@ mod tests {
399354 self . fs . clone ( )
400355 }
401356
402- fn intern_file ( & mut self , path : & Utf8Path ) -> ( File , bool ) {
357+ fn track_file ( & mut self , path : & Utf8Path ) -> File {
403358 if let Some ( entry) = self . files . get ( path) {
404- return ( * entry, true ) ;
359+ return * entry;
405360 }
406361
407362 let file = File :: new ( self , path. to_owned ( ) , 0 ) ;
408363 self . files . insert ( path. to_owned ( ) , file) ;
409- ( file, false )
364+ file
410365 }
411366
412367 fn get_file ( & self , path : & Utf8Path ) -> Option < File > {
@@ -421,14 +376,9 @@ mod tests {
421376 let url = Url :: parse ( "file:///test.py" ) . unwrap ( ) ;
422377
423378 let document = TextDocument :: new ( "print('hello')" . to_string ( ) , 1 , LanguageId :: Python ) ;
424- let event = workspace. open_document ( & mut db, & url, document) . unwrap ( ) ;
425-
426- match event {
427- WorkspaceFileEvent :: Created { ref path, .. } => {
428- assert_eq ! ( path. file_name( ) , Some ( "test.py" ) ) ;
429- }
430- WorkspaceFileEvent :: Updated { .. } => panic ! ( "expected created event" ) ,
431- }
379+ let file = workspace. open_document ( & mut db, & url, document) . unwrap ( ) ;
380+ let path = file. path ( & db) ;
381+ assert_eq ! ( path. file_name( ) , Some ( "test.py" ) ) ;
432382 assert ! ( workspace. buffers. get( & url) . is_some( ) ) ;
433383 }
434384
@@ -446,11 +396,11 @@ mod tests {
446396 range_length: None ,
447397 text: "updated" . to_string( ) ,
448398 } ] ;
449- let event = workspace
399+ let file = workspace
450400 . update_document ( & mut db, & url, changes, 2 , PositionEncoding :: Utf16 )
451401 . unwrap ( ) ;
452402
453- assert ! ( matches! ( event , WorkspaceFileEvent :: Updated { .. } ) ) ;
403+ assert_eq ! ( file . path ( & db ) . file_name ( ) , Some ( "test.py" ) ) ;
454404 let buffer = workspace. buffers . get ( & url) . unwrap ( ) ;
455405 assert_eq ! ( buffer. content( ) , "updated" ) ;
456406 assert_eq ! ( buffer. version( ) , 2 ) ;
@@ -502,10 +452,9 @@ mod tests {
502452 let url = Url :: from_file_path ( file_path. as_std_path ( ) ) . unwrap ( ) ;
503453
504454 let document = TextDocument :: new ( "line1\n line2" . to_string ( ) , 1 , LanguageId :: HtmlDjango ) ;
505- let event = workspace
455+ let file = workspace
506456 . open_document ( & mut db, & url, document. clone ( ) )
507457 . unwrap ( ) ;
508- let file = event. file ( ) ;
509458
510459 let source = file. source ( & db) ;
511460 assert_eq ! ( source. as_str( ) , document. content( ) ) ;
@@ -532,8 +481,7 @@ mod tests {
532481 let url = Url :: from_file_path ( file_path. as_std_path ( ) ) . unwrap ( ) ;
533482
534483 let document = TextDocument :: new ( "initial" . to_string ( ) , 1 , LanguageId :: Python ) ;
535- let event = workspace. open_document ( & mut db, & url, document) . unwrap ( ) ;
536- let file = event. file ( ) ;
484+ let file = workspace. open_document ( & mut db, & url, document) . unwrap ( ) ;
537485
538486 let changes = vec ! [ TextDocumentContentChangeEvent {
539487 range: None ,
@@ -559,8 +507,7 @@ mod tests {
559507 let url = Url :: from_file_path ( file_path. as_std_path ( ) ) . unwrap ( ) ;
560508
561509 let document = TextDocument :: new ( "buffer content" . to_string ( ) , 1 , LanguageId :: Python ) ;
562- let event = workspace. open_document ( & mut db, & url, document) . unwrap ( ) ;
563- let file = event. file ( ) ;
510+ let file = workspace. open_document ( & mut db, & url, document) . unwrap ( ) ;
564511
565512 assert_eq ! ( file. source( & db) . as_str( ) , "buffer content" ) ;
566513
0 commit comments