diff options
Diffstat (limited to 'crates/ra_ide_db')
-rw-r--r-- | crates/ra_ide_db/src/lib.rs | 1 | ||||
-rw-r--r-- | crates/ra_ide_db/src/source_change.rs | 120 |
2 files changed, 121 insertions, 0 deletions
diff --git a/crates/ra_ide_db/src/lib.rs b/crates/ra_ide_db/src/lib.rs index e6f2d36e9..52fcd7b6f 100644 --- a/crates/ra_ide_db/src/lib.rs +++ b/crates/ra_ide_db/src/lib.rs | |||
@@ -10,6 +10,7 @@ pub mod change; | |||
10 | pub mod defs; | 10 | pub mod defs; |
11 | pub mod search; | 11 | pub mod search; |
12 | pub mod imports_locator; | 12 | pub mod imports_locator; |
13 | pub mod source_change; | ||
13 | mod wasm_shims; | 14 | mod wasm_shims; |
14 | 15 | ||
15 | use std::sync::Arc; | 16 | use std::sync::Arc; |
diff --git a/crates/ra_ide_db/src/source_change.rs b/crates/ra_ide_db/src/source_change.rs new file mode 100644 index 000000000..4dd01b312 --- /dev/null +++ b/crates/ra_ide_db/src/source_change.rs | |||
@@ -0,0 +1,120 @@ | |||
1 | //! This modules defines type to represent changes to the source code, that flow | ||
2 | //! from the server to the client. | ||
3 | //! | ||
4 | //! It can be viewed as a dual for `AnalysisChange`. | ||
5 | |||
6 | use ra_db::{FileId, FilePosition, RelativePathBuf, SourceRootId}; | ||
7 | use ra_text_edit::{TextEdit, TextSize}; | ||
8 | |||
9 | #[derive(Debug)] | ||
10 | pub struct SourceChange { | ||
11 | /// For display in the undo log in the editor | ||
12 | pub label: String, | ||
13 | pub source_file_edits: Vec<SourceFileEdit>, | ||
14 | pub file_system_edits: Vec<FileSystemEdit>, | ||
15 | pub cursor_position: Option<FilePosition>, | ||
16 | } | ||
17 | |||
18 | impl SourceChange { | ||
19 | /// Creates a new SourceChange with the given label | ||
20 | /// from the edits. | ||
21 | pub fn from_edits<L: Into<String>>( | ||
22 | label: L, | ||
23 | source_file_edits: Vec<SourceFileEdit>, | ||
24 | file_system_edits: Vec<FileSystemEdit>, | ||
25 | ) -> Self { | ||
26 | SourceChange { | ||
27 | label: label.into(), | ||
28 | source_file_edits, | ||
29 | file_system_edits, | ||
30 | cursor_position: None, | ||
31 | } | ||
32 | } | ||
33 | |||
34 | /// Creates a new SourceChange with the given label, | ||
35 | /// containing only the given `SourceFileEdits`. | ||
36 | pub fn source_file_edits<L: Into<String>>(label: L, edits: Vec<SourceFileEdit>) -> Self { | ||
37 | let label = label.into(); | ||
38 | assert!(label.starts_with(char::is_uppercase)); | ||
39 | SourceChange { | ||
40 | label: label, | ||
41 | source_file_edits: edits, | ||
42 | file_system_edits: vec![], | ||
43 | cursor_position: None, | ||
44 | } | ||
45 | } | ||
46 | |||
47 | /// Creates a new SourceChange with the given label, | ||
48 | /// containing only the given `FileSystemEdits`. | ||
49 | pub(crate) fn file_system_edits<L: Into<String>>(label: L, edits: Vec<FileSystemEdit>) -> Self { | ||
50 | SourceChange { | ||
51 | label: label.into(), | ||
52 | source_file_edits: vec![], | ||
53 | file_system_edits: edits, | ||
54 | cursor_position: None, | ||
55 | } | ||
56 | } | ||
57 | |||
58 | /// Creates a new SourceChange with the given label, | ||
59 | /// containing only a single `SourceFileEdit`. | ||
60 | pub fn source_file_edit<L: Into<String>>(label: L, edit: SourceFileEdit) -> Self { | ||
61 | SourceChange::source_file_edits(label, vec![edit]) | ||
62 | } | ||
63 | |||
64 | /// Creates a new SourceChange with the given label | ||
65 | /// from the given `FileId` and `TextEdit` | ||
66 | pub fn source_file_edit_from<L: Into<String>>( | ||
67 | label: L, | ||
68 | file_id: FileId, | ||
69 | edit: TextEdit, | ||
70 | ) -> Self { | ||
71 | SourceChange::source_file_edit(label, SourceFileEdit { file_id, edit }) | ||
72 | } | ||
73 | |||
74 | /// Creates a new SourceChange with the given label | ||
75 | /// from the given `FileId` and `TextEdit` | ||
76 | pub fn file_system_edit<L: Into<String>>(label: L, edit: FileSystemEdit) -> Self { | ||
77 | SourceChange::file_system_edits(label, vec![edit]) | ||
78 | } | ||
79 | |||
80 | /// Sets the cursor position to the given `FilePosition` | ||
81 | pub fn with_cursor(mut self, cursor_position: FilePosition) -> Self { | ||
82 | self.cursor_position = Some(cursor_position); | ||
83 | self | ||
84 | } | ||
85 | |||
86 | /// Sets the cursor position to the given `FilePosition` | ||
87 | pub fn with_cursor_opt(mut self, cursor_position: Option<FilePosition>) -> Self { | ||
88 | self.cursor_position = cursor_position; | ||
89 | self | ||
90 | } | ||
91 | } | ||
92 | |||
93 | #[derive(Debug)] | ||
94 | pub struct SourceFileEdit { | ||
95 | pub file_id: FileId, | ||
96 | pub edit: TextEdit, | ||
97 | } | ||
98 | |||
99 | #[derive(Debug)] | ||
100 | pub enum FileSystemEdit { | ||
101 | CreateFile { source_root: SourceRootId, path: RelativePathBuf }, | ||
102 | MoveFile { src: FileId, dst_source_root: SourceRootId, dst_path: RelativePathBuf }, | ||
103 | } | ||
104 | |||
105 | pub struct SingleFileChange { | ||
106 | pub label: String, | ||
107 | pub edit: TextEdit, | ||
108 | pub cursor_position: Option<TextSize>, | ||
109 | } | ||
110 | |||
111 | impl SingleFileChange { | ||
112 | pub fn into_source_change(self, file_id: FileId) -> SourceChange { | ||
113 | SourceChange { | ||
114 | label: self.label, | ||
115 | source_file_edits: vec![SourceFileEdit { file_id, edit: self.edit }], | ||
116 | file_system_edits: Vec::new(), | ||
117 | cursor_position: self.cursor_position.map(|offset| FilePosition { file_id, offset }), | ||
118 | } | ||
119 | } | ||
120 | } | ||