@@ -2,21 +2,7 @@ local notify = require("nvim-tree.notify")
22local log = require (" nvim-tree.log" )
33local utils = require (" nvim-tree.utils" )
44
5- local M = {
6- config = {},
7- }
8-
9- --- @class Event
10- local Event = {
11- _events = {},
12- }
13- Event .__index = Event
14-
15- --- @class Watcher
16- local Watcher = {
17- _watchers = {},
18- }
19- Watcher .__index = Watcher
5+ local Class = require (" nvim-tree.class" )
206
217local FS_EVENT_FLAGS = {
228 -- inotify or equivalent will be used; fallback to stat has not yet been implemented
@@ -25,42 +11,62 @@ local FS_EVENT_FLAGS = {
2511 recursive = false ,
2612}
2713
14+ local M = {
15+ config = {},
16+ }
17+
18+ --- @class (exact ) Event : Class
19+ --- @field destroyed boolean
20+ --- @field private path string
21+ --- @field private fs_event uv.uv_fs_event_t ?
22+ --- @field private listeners function[]
23+ local Event = Class :new ()
24+
25+ --- Registry of all events
26+ --- @type Event[]
27+ local events = {}
28+
29+ --- Static factory method
30+ --- Creates and starts an Event
2831--- @param path string
2932--- @return Event | nil
30- function Event :new (path )
31- log .line (" watcher" , " Event:new '%s'" , path )
32-
33- local e = setmetatable ({
34- _path = path ,
35- _fs_event = nil ,
36- _listeners = {},
37- }, Event )
38-
39- if e :start () then
40- Event ._events [path ] = e
41- return e
33+ function Event :create (path )
34+ log .line (" watcher" , " Event:create '%s'" , path )
35+
36+ --- @type Event
37+ local o = {
38+ destroyed = false ,
39+ path = path ,
40+ fs_event = nil ,
41+ listeners = {},
42+ }
43+ o = self :new (o ) --[[ @as Event]]
44+
45+ if o :start () then
46+ events [path ] = o
47+ return o
4248 else
4349 return nil
4450 end
4551end
4652
4753--- @return boolean
4854function Event :start ()
49- log .line (" watcher" , " Event:start '%s'" , self ._path )
55+ log .line (" watcher" , " Event:start '%s'" , self .path )
5056
5157 local rc , _ , name
5258
53- self ._fs_event , _ , name = vim .loop .new_fs_event ()
54- if not self ._fs_event then
55- self ._fs_event = nil
56- notify .warn (string.format (" Could not initialize an fs_event watcher for path %s : %s" , self ._path , name ))
59+ self .fs_event , _ , name = vim .loop .new_fs_event ()
60+ if not self .fs_event then
61+ self .fs_event = nil
62+ notify .warn (string.format (" Could not initialize an fs_event watcher for path %s : %s" , self .path , name ))
5763 return false
5864 end
5965
6066 local event_cb = vim .schedule_wrap (function (err , filename )
6167 if err then
62- log .line (" watcher" , " event_cb '%s' '%s' FAIL : %s" , self ._path , filename , err )
63- local message = string.format (" File system watcher failed (%s) for path %s, halting watcher." , err , self ._path )
68+ log .line (" watcher" , " event_cb '%s' '%s' FAIL : %s" , self .path , filename , err )
69+ local message = string.format (" File system watcher failed (%s) for path %s, halting watcher." , err , self .path )
6470 if err == " EPERM" and (utils .is_windows or utils .is_wsl ) then
6571 -- on directory removal windows will cascade the filesystem events out of order
6672 log .line (" watcher" , message )
@@ -69,19 +75,19 @@ function Event:start()
6975 self :destroy (message )
7076 end
7177 else
72- log .line (" watcher" , " event_cb '%s' '%s'" , self ._path , filename )
73- for _ , listener in ipairs (self ._listeners ) do
78+ log .line (" watcher" , " event_cb '%s' '%s'" , self .path , filename )
79+ for _ , listener in ipairs (self .listeners ) do
7480 listener (filename )
7581 end
7682 end
7783 end )
7884
79- rc , _ , name = self ._fs_event :start (self ._path , FS_EVENT_FLAGS , event_cb )
85+ rc , _ , name = self .fs_event :start (self .path , FS_EVENT_FLAGS , event_cb )
8086 if rc ~= 0 then
8187 if name == " EMFILE" then
8288 M .disable_watchers (" fs.inotify.max_user_watches exceeded, see https://github.com/nvim-tree/nvim-tree.lua/wiki/Troubleshooting" )
8389 else
84- notify .warn (string.format (" Could not start the fs_event watcher for path %s : %s" , self ._path , name ))
90+ notify .warn (string.format (" Could not start the fs_event watcher for path %s : %s" , self .path , name ))
8591 end
8692 return false
8793 end
9197
9298--- @param listener function
9399function Event :add (listener )
94- table.insert (self ._listeners , listener )
100+ table.insert (self .listeners , listener )
95101end
96102
97103--- @param listener function
98104function Event :remove (listener )
99- utils .array_remove (self ._listeners , listener )
100- if # self ._listeners == 0 then
105+ utils .array_remove (self .listeners , listener )
106+ if # self .listeners == 0 then
101107 self :destroy ()
102108 end
103109end
104110
105111--- @param message string | nil
106112function Event :destroy (message )
107- log .line (" watcher" , " Event:destroy '%s'" , self ._path )
113+ log .line (" watcher" , " Event:destroy '%s'" , self .path )
108114
109- if self ._fs_event then
115+ if self .fs_event then
110116 if message then
111117 notify .warn (message )
112118 end
113119
114- local rc , _ , name = self ._fs_event :stop ()
120+ local rc , _ , name = self .fs_event :stop ()
115121 if rc ~= 0 then
116- notify .warn (string.format (" Could not stop the fs_event watcher for path %s : %s" , self ._path , name ))
122+ notify .warn (string.format (" Could not stop the fs_event watcher for path %s : %s" , self .path , name ))
117123 end
118- self ._fs_event = nil
124+ self .fs_event = nil
119125 end
120126
121- Event ._events [self ._path ] = nil
122-
123127 self .destroyed = true
128+ events [self .path ] = nil
124129end
125130
131+ --- Static factory method
132+ --- Creates and starts a Watcher
133+ --- @class (exact ) Watcher : Class
134+ --- @field data table user data
135+ --- @field destroyed boolean
136+ --- @field private path string
137+ --- @field private callback fun (watcher : Watcher )
138+ --- @field private files string[] ?
139+ --- @field private listener fun (filename : string )?
140+ --- @field private event Event
141+ local Watcher = Class :new ()
142+
143+ --- Registry of all watchers
144+ --- @type Watcher[]
145+ local watchers = {}
146+
147+ --- Static factory method
126148--- @param path string
127149--- @param files string[] | nil
128- --- @param callback function
129- --- @param data table
150+ --- @param callback fun ( watcher : Watcher )
151+ --- @param data table user data
130152--- @return Watcher | nil
131- function Watcher :new (path , files , callback , data )
132- log .line (" watcher" , " Watcher:new '%s' %s" , path , vim .inspect (files ))
133-
134- local w = setmetatable (data , Watcher )
153+ function Watcher :create (path , files , callback , data )
154+ log .line (" watcher" , " Watcher:create '%s' %s" , path , vim .inspect (files ))
135155
136- w ._event = Event ._events [path ] or Event :new (path )
137- w ._listener = nil
138- w ._path = path
139- w ._files = files
140- w ._callback = callback
141-
142- if not w ._event then
156+ local event = events [path ] or Event :create (path )
157+ if not event then
143158 return nil
144159 end
145160
146- w :start ()
161+ --- @type Watcher
162+ local o = {
163+ data = data ,
164+ destroyed = false ,
165+ path = path ,
166+ callback = callback ,
167+ files = files ,
168+ listener = nil ,
169+ event = event ,
170+ }
171+ o = self :new (o ) --[[ @as Watcher]]
172+
173+ o :start ()
147174
148- table.insert (Watcher . _watchers , w )
175+ table.insert (watchers , o )
149176
150- return w
177+ return o
151178end
152179
153180function Watcher :start ()
154- self ._listener = function (filename )
155- if not self ._files or vim .tbl_contains (self ._files , filename ) then
156- self ._callback (self )
181+ self .listener = function (filename )
182+ if not self .files or vim .tbl_contains (self .files , filename ) then
183+ self .callback (self )
157184 end
158185 end
159186
160- self ._event :add (self ._listener )
187+ self .event :add (self .listener )
161188end
162189
163190function Watcher :destroy ()
164- log .line (" watcher" , " Watcher:destroy '%s'" , self ._path )
191+ log .line (" watcher" , " Watcher:destroy '%s'" , self .path )
165192
166- self ._event :remove (self ._listener )
193+ self .event :remove (self .listener )
167194
168- utils .array_remove (Watcher . _watchers , self )
195+ utils .array_remove (watchers , self )
169196
170197 self .destroyed = true
171198end
@@ -183,11 +210,11 @@ end
183210function M .purge_watchers ()
184211 log .line (" watcher" , " purge_watchers" )
185212
186- for _ , w in ipairs (utils .array_shallow_clone (Watcher . _watchers )) do
213+ for _ , w in ipairs (utils .array_shallow_clone (watchers )) do
187214 w :destroy ()
188215 end
189216
190- for _ , e in pairs (Event . _events ) do
217+ for _ , e in pairs (events ) do
191218 e :destroy ()
192219 end
193220end
0 commit comments