1 //! This modules defines type to represent changes to the source code, that flow
2 //! from the server to the client.
4 //! It can be viewed as a dual for `AnalysisChange`.
6 use ra_db::{FileId, FilePosition, RelativePathBuf, SourceRootId};
7 use ra_text_edit::TextEdit;
9 #[derive(Debug, Clone)]
10 pub struct SourceChange {
11 /// For display in the undo log in the editor
13 pub source_file_edits: Vec<SourceFileEdit>,
14 pub file_system_edits: Vec<FileSystemEdit>,
15 pub cursor_position: Option<FilePosition>,
20 /// Creates a new SourceChange with the given label
22 pub fn from_edits<L: Into<String>>(
24 source_file_edits: Vec<SourceFileEdit>,
25 file_system_edits: Vec<FileSystemEdit>,
31 cursor_position: None,
36 /// Creates a new SourceChange with the given label,
37 /// containing only the given `SourceFileEdits`.
38 pub fn source_file_edits<L: Into<String>>(label: L, edits: Vec<SourceFileEdit>) -> Self {
39 let label = label.into();
40 assert!(label.starts_with(char::is_uppercase));
43 source_file_edits: edits,
44 file_system_edits: vec![],
45 cursor_position: None,
50 /// Creates a new SourceChange with the given label,
51 /// containing only the given `FileSystemEdits`.
52 pub(crate) fn file_system_edits<L: Into<String>>(label: L, edits: Vec<FileSystemEdit>) -> Self {
55 source_file_edits: vec![],
56 file_system_edits: edits,
57 cursor_position: None,
62 /// Creates a new SourceChange with the given label,
63 /// containing only a single `SourceFileEdit`.
64 pub fn source_file_edit<L: Into<String>>(label: L, edit: SourceFileEdit) -> Self {
65 SourceChange::source_file_edits(label, vec![edit])
68 /// Creates a new SourceChange with the given label
69 /// from the given `FileId` and `TextEdit`
70 pub fn source_file_edit_from<L: Into<String>>(
75 SourceChange::source_file_edit(label, SourceFileEdit { file_id, edit })
78 /// Creates a new SourceChange with the given label
79 /// from the given `FileId` and `TextEdit`
80 pub fn file_system_edit<L: Into<String>>(label: L, edit: FileSystemEdit) -> Self {
81 SourceChange::file_system_edits(label, vec![edit])
84 /// Sets the cursor position to the given `FilePosition`
85 pub fn with_cursor(mut self, cursor_position: FilePosition) -> Self {
86 self.cursor_position = Some(cursor_position);
90 /// Sets the cursor position to the given `FilePosition`
91 pub fn with_cursor_opt(mut self, cursor_position: Option<FilePosition>) -> Self {
92 self.cursor_position = cursor_position;
97 #[derive(Debug, Clone)]
98 pub struct SourceFileEdit {
103 #[derive(Debug, Clone)]
104 pub enum FileSystemEdit {
105 CreateFile { source_root: SourceRootId, path: RelativePathBuf },
106 MoveFile { src: FileId, dst_source_root: SourceRootId, dst_path: RelativePathBuf },
109 pub struct SingleFileChange {
114 impl SingleFileChange {
115 pub fn into_source_change(self, file_id: FileId) -> SourceChange {
118 source_file_edits: vec![SourceFileEdit { file_id, edit: self.edit }],
119 file_system_edits: Vec::new(),
120 cursor_position: None,