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