1     let write_to_actual (item : FileItem) =
2         item.actual_path = item.path
3              actual_directory_path = item.directory_path
4              actual_name = item.name
5              actual_parent = item.parent.unwrap
6     
7     type Editor
8         def apply self =
9             let changed =
10                let set = Set<FileItem>.new
11                let changed = List<FileItem>.new
12                for item in self.changed do
13                    if not set.contains item then
14                        set.add item
15                        changed.add item
16    
17                changed
18    
19            let removed =
20                changed.filter { x -> x.path.is_empty && x.actual_path.is_not_empty }
21    
22            let created =
23                changed.filter { x -> x.path.is_not_empty && x.actual_path.is_empty }
24    
25            let created_removed =
26                changed.filter { x -> x.path.is_empty && x.actual_path.is_empty }
27    
28            let moved = changed.filter { x ->
29                let path = x.path
30                let actual_path = x.actual_path
31                path.is_not_empty && actual_path.is_not_empty && path <> actual_path }
32    
33            let order_changed = changed.filter { x ->
34                if not x.is_directory || x.is_root then
35                    false
36                else
37                    let path = x.path
38                    let actual_path = x.actual_path
39                    path.is_not_empty && actual_path.is_not_empty
40                    && path == actual_path }
41    
42            let split (list : List<FileItem>) = list.partition { not _.is_directory }
43    
44            let (removed_files, removed_directories) = split removed
45            let (created_files, created_directories) = split created
46            let (moved_files, moved_directories) = split moved
47    
48            for file in removed_files do
49                let actual_path = file.actual_path
50                if actual_path.is_not_empty then
51                    fs/remove_file actual_path
52    
53            let keep_directories = Set<String>.new
54            for directory in created_directories + moved_directories do
55                let path = directory.path
56                keep_directories.add path
57                if not fs/exists path then
58                    fs/create_path path
59                else
60                    assert fs/is_directory path
61    
62            for file in moved_files do
63                let from_path = file.actual_path
64                let to_path = file.path
65                assert not fs/exists to_path
66                fs/rename from_path to_path
67                write_to_actual file
68    
69            for directory in removed_directories + moved_directories do
70                let path = directory.actual_path
71                if not keep_directories.contains path then
72                    try_remove_order_file path
73                    fs/remove_directory path
74    
75            for file in created_files do
76                let path = file.path
77                assert not fs/exists path
78                fs/create_file path
79                write_to_actual file
80    
81            for directory in created_directories + moved_directories do
82                write_to_actual directory
83    
84            let directories = Set<FileItem>.new
85            for directory in created_directories + moved_directories + order_changed do
86                directories.add directory
87    
88            for file in moved_files do
89                let directory = file.parent.unwrap
90                directories.insert directory |> ignore
91    
92            for directory in directories do
93                save_order directory
94    
95            let file_item_tab_items = self.file_item_tab_items
96            for file in removed + created_removed do
97                if file_item_tab_items.contains file then
98                    self.tab_control.close_tab file_item_tab_items[file]
99    
100               if self.content_changed.contains file then
101                   self.content_changed.remove file
102   
103           self.changed.clear
104