@@ -5,32 +5,28 @@ local core = require "nvim-tree.core"
5
5
local notify = require " nvim-tree.notify"
6
6
7
7
local find_file = require (" nvim-tree.actions.finders.find-file" ).fn
8
+ local async = require " nvim-tree.async"
8
9
9
10
local M = {}
10
11
12
+ --- @async
11
13
local function create_and_notify (file )
12
- local ok , fd = pcall (vim .loop .fs_open , file , " w" , 420 )
13
- if not ok then
14
+ local fd , err
15
+ if M .enable_async then
16
+ err , fd = async .call (vim .loop .fs_open , file , " w" , 420 )
17
+ else
18
+ fd , err = vim .loop .fs_open (file , " w" , 420 )
19
+ end
20
+ if err then
14
21
notify .error (" Couldn't create file " .. file )
15
22
return
16
23
end
17
- vim .loop .fs_close (fd )
18
- events ._dispatch_file_created (file )
19
- end
20
-
21
- local function create_file (file )
22
- if utils .file_exists (file ) then
23
- local prompt_select = " Overwrite " .. file .. " ?"
24
- local prompt_input = prompt_select .. " y/n: "
25
- lib .prompt (prompt_input , prompt_select , { " y" , " n" }, { " Yes" , " No" }, function (item_short )
26
- utils .clear_prompt ()
27
- if item_short == " y" then
28
- create_and_notify (file )
29
- end
30
- end )
24
+ if M .enable_async then
25
+ async .call (vim .loop .fs_close , fd )
31
26
else
32
- create_and_notify ( file )
27
+ vim . loop . fs_close ( fd )
33
28
end
29
+ events ._dispatch_file_created (file )
34
30
end
35
31
36
32
local function get_num_nodes (iter )
@@ -41,6 +37,68 @@ local function get_num_nodes(iter)
41
37
return i
42
38
end
43
39
40
+ local function create_file (new_file_path )
41
+ -- create a folder for each path element if the folder does not exist
42
+ -- if the answer ends with a /, create a file for the last path element
43
+ local is_last_path_file = not new_file_path :match (utils .path_separator .. " $" )
44
+ local path_to_create = " "
45
+ local idx = 0
46
+
47
+ local num_nodes = get_num_nodes (utils .path_split (utils .path_remove_trailing (new_file_path )))
48
+ local is_error = false
49
+ for path in utils .path_split (new_file_path ) do
50
+ idx = idx + 1
51
+ local p = utils .path_remove_trailing (path )
52
+ if # path_to_create == 0 and utils .is_windows then
53
+ path_to_create = utils .path_join { p , path_to_create }
54
+ else
55
+ path_to_create = utils .path_join { path_to_create , p }
56
+ end
57
+ if is_last_path_file and idx == num_nodes then
58
+ if M .enable_async then
59
+ async .schedule ()
60
+ end
61
+ if utils .file_exists (new_file_path ) then
62
+ local prompt_select = " Overwrite " .. new_file_path .. " ?"
63
+ local prompt_input = prompt_select .. " y/n: "
64
+ if M .enable_async then
65
+ local item_short = async .call (lib .prompt , prompt_input , prompt_select , { " y" , " n" }, { " Yes" , " No" })
66
+ utils .clear_prompt ()
67
+ if item_short == " y" then
68
+ create_and_notify (new_file_path )
69
+ end
70
+ else
71
+ lib .prompt (prompt_input , prompt_select , { " y" , " n" }, { " Yes" , " No" }, function (item_short )
72
+ utils .clear_prompt ()
73
+ if item_short == " y" then
74
+ create_and_notify (new_file_path )
75
+ end
76
+ end )
77
+ end
78
+ else
79
+ create_and_notify (new_file_path )
80
+ end
81
+ elseif not utils .file_exists (path_to_create ) then
82
+ local err
83
+ if M .enable_async then
84
+ err = async .call (vim .loop .fs_mkdir , path_to_create , 493 )
85
+ else
86
+ local _
87
+ _ , err = vim .loop .fs_mkdir (path_to_create , 493 )
88
+ end
89
+ if err then
90
+ notify .error (" Could not create folder " .. path_to_create .. " : " .. err )
91
+ is_error = true
92
+ break
93
+ end
94
+ events ._dispatch_folder_created (new_file_path )
95
+ end
96
+ end
97
+ if not is_error then
98
+ notify .info (new_file_path .. " was properly created" )
99
+ end
100
+ end
101
+
44
102
local function get_containing_folder (node )
45
103
if node .nodes ~= nil then
46
104
return utils .path_add_trailing (node .absolute_path )
@@ -49,7 +107,8 @@ local function get_containing_folder(node)
49
107
return node .absolute_path :sub (0 , - node_name_size - 1 )
50
108
end
51
109
52
- function M .fn (node )
110
+ -- TODO: once async feature is finalized, use `async.wrap` instead of cb param
111
+ function M .fn (node , cb )
53
112
node = node and lib .get_last_group_node (node )
54
113
if not node or node .name == " .." then
55
114
node = {
@@ -74,45 +133,24 @@ function M.fn(node)
74
133
return
75
134
end
76
135
77
- -- create a folder for each path element if the folder does not exist
78
- -- if the answer ends with a /, create a file for the last path element
79
- local is_last_path_file = not new_file_path :match (utils .path_separator .. " $" )
80
- local path_to_create = " "
81
- local idx = 0
82
-
83
- local num_nodes = get_num_nodes (utils .path_split (utils .path_remove_trailing (new_file_path )))
84
- local is_error = false
85
- for path in utils .path_split (new_file_path ) do
86
- idx = idx + 1
87
- local p = utils .path_remove_trailing (path )
88
- if # path_to_create == 0 and vim .fn .has " win32" == 1 then
89
- path_to_create = utils .path_join { p , path_to_create }
90
- else
91
- path_to_create = utils .path_join { path_to_create , p }
92
- end
93
- if is_last_path_file and idx == num_nodes then
94
- create_file (path_to_create )
95
- elseif not utils .file_exists (path_to_create ) then
96
- local success = vim .loop .fs_mkdir (path_to_create , 493 )
97
- if not success then
98
- notify .error (" Could not create folder " .. path_to_create )
99
- is_error = true
100
- break
136
+ if M .enable_async then
137
+ async .exec (create_file , new_file_path , function (err )
138
+ find_file (utils .path_remove_trailing (new_file_path ))
139
+ if cb then
140
+ cb (err )
101
141
end
102
- events . _dispatch_folder_created ( new_file_path )
103
- end
104
- end
105
- if not is_error then
106
- notify . info (new_file_path .. " was properly created " )
142
+ end )
143
+ else
144
+ create_file ( new_file_path )
145
+ -- synchronously refreshes as we can't wait for the watchers
146
+ find_file ( utils . path_remove_trailing (new_file_path ) )
107
147
end
108
-
109
- -- synchronously refreshes as we can't wait for the watchers
110
- find_file (utils .path_remove_trailing (new_file_path ))
111
148
end )
112
149
end
113
150
114
151
function M .setup (opts )
115
152
M .enable_reload = not opts .filesystem_watchers .enable
153
+ M .enable_async = opts .experimental .async .create_file
116
154
end
117
155
118
156
return M
0 commit comments