Remove the project scan thread
Since the directory monitoring is now basically working we remove the project scan thread periodically scanning the project directory. Each project's directory is scanned only once at the beginning when calling the function `core.add_project_directory` and is updated incrementally when directory change events are treated. The config variable `project_scan_rate` is removed as well as the function `core.reschedule_project_scan`.
This commit is contained in:
parent
09d2c0a325
commit
7ee00c3317
|
@ -191,8 +191,6 @@ command.add(nil, {
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
core.add_project_directory(system.absolute_path(text))
|
core.add_project_directory(system.absolute_path(text))
|
||||||
-- TODO: add the name of directory to prioritize
|
|
||||||
core.reschedule_project_scan()
|
|
||||||
end, suggest_directory)
|
end, suggest_directory)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
local config = {}
|
local config = {}
|
||||||
|
|
||||||
config.project_scan_rate = 5
|
|
||||||
config.fps = 60
|
config.fps = 60
|
||||||
config.max_log_items = 80
|
config.max_log_items = 80
|
||||||
config.message_timeout = 5
|
config.message_timeout = 5
|
||||||
|
|
|
@ -52,13 +52,6 @@ local function update_recents_project(action, dir_path_abs)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function core.reschedule_project_scan()
|
|
||||||
if core.project_scan_thread_id then
|
|
||||||
core.threads[core.project_scan_thread_id].wake = 0
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function core.set_project_dir(new_dir, change_project_fn)
|
function core.set_project_dir(new_dir, change_project_fn)
|
||||||
local chdir_ok = pcall(system.chdir, new_dir)
|
local chdir_ok = pcall(system.chdir, new_dir)
|
||||||
if chdir_ok then
|
if chdir_ok then
|
||||||
|
@ -66,9 +59,6 @@ function core.set_project_dir(new_dir, change_project_fn)
|
||||||
core.project_dir = common.normalize_path(new_dir)
|
core.project_dir = common.normalize_path(new_dir)
|
||||||
core.project_directories = {}
|
core.project_directories = {}
|
||||||
core.add_project_directory(new_dir)
|
core.add_project_directory(new_dir)
|
||||||
core.project_files = {}
|
|
||||||
core.project_files_limit = false
|
|
||||||
core.reschedule_project_scan()
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
|
@ -106,8 +96,8 @@ local function get_project_file_info(root, file, size_limit)
|
||||||
local info = system.get_file_info(root .. file)
|
local info = system.get_file_info(root .. file)
|
||||||
if info then
|
if info then
|
||||||
info.filename = strip_leading_path(file)
|
info.filename = strip_leading_path(file)
|
||||||
|
return info.size < size_limit and info
|
||||||
end
|
end
|
||||||
return info and info.size < size_limit and info
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -156,48 +146,47 @@ local function get_directory_files(root, path, t, recursive, begin_hook)
|
||||||
return t, entries_count
|
return t, entries_count
|
||||||
end
|
end
|
||||||
|
|
||||||
local function project_scan_thread()
|
|
||||||
local function diff_files(a, b)
|
-- FIXME: change the name with core.scan_project_folder
|
||||||
if #a ~= #b then return true end
|
function core.project_scan_topdir(index)
|
||||||
for i, v in ipairs(a) do
|
local dir = core.project_directories[index]
|
||||||
if b[i].filename ~= v.filename
|
local t, entries_count = get_directory_files(dir.name, "", {}, true)
|
||||||
or b[i].modified ~= v.modified then
|
if entries_count > config.max_project_files then
|
||||||
return true
|
dir.files_limit = true
|
||||||
end
|
if core.status_view then -- FIXME
|
||||||
|
core.status_view:show_message("!", style.accent,
|
||||||
|
"Too many files in project directory: stopped reading at "..
|
||||||
|
config.max_project_files.." files. For more information see "..
|
||||||
|
"usage.md at github.com/franko/lite-xl."
|
||||||
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
dir.files = t
|
||||||
while true do
|
if dir.name == core.project_dir then
|
||||||
-- get project files and replace previous table if the new table is
|
core.project_files = dir.files
|
||||||
-- different
|
|
||||||
local i = 1
|
|
||||||
while not core.project_files_limit and i <= #core.project_directories do
|
|
||||||
local dir = core.project_directories[i]
|
|
||||||
local t, entries_count = get_directory_files(dir.name, "", {}, true)
|
|
||||||
if diff_files(dir.files, t) then
|
|
||||||
if entries_count > config.max_project_files then
|
|
||||||
core.project_files_limit = true
|
|
||||||
core.status_view:show_message("!", style.accent,
|
|
||||||
"Too many files in project directory: stopped reading at "..
|
|
||||||
config.max_project_files.." files. For more information see "..
|
|
||||||
"usage.md at github.com/franko/lite-xl."
|
|
||||||
)
|
|
||||||
end
|
|
||||||
dir.files = t
|
|
||||||
core.redraw = true
|
|
||||||
end
|
|
||||||
if dir.name == core.project_dir then
|
|
||||||
core.project_files = dir.files
|
|
||||||
end
|
|
||||||
i = i + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
-- wait for next scan
|
|
||||||
coroutine.yield(config.project_scan_rate)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function core.add_project_directory(path)
|
||||||
|
-- top directories has a file-like "item" but the item.filename
|
||||||
|
-- will be simply the name of the directory, without its path.
|
||||||
|
-- The field item.topdir will identify it as a top level directory.
|
||||||
|
path = common.normalize_path(path)
|
||||||
|
local watch_id = system.watch_dir(path)
|
||||||
|
print("DEBUG watch_id:", watch_id)
|
||||||
|
table.insert(core.project_directories, {
|
||||||
|
name = path,
|
||||||
|
item = {filename = common.basename(path), type = "dir", topdir = true},
|
||||||
|
files_limit = false,
|
||||||
|
is_dirty = true,
|
||||||
|
watch_id = watch_id,
|
||||||
|
})
|
||||||
|
core.project_scan_topdir(#core.project_directories)
|
||||||
|
core.redraw = true
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function core.is_project_folder(dirname)
|
function core.is_project_folder(dirname)
|
||||||
for _, dir in ipairs(core.project_directories) do
|
for _, dir in ipairs(core.project_directories) do
|
||||||
if dir.name == dirname then
|
if dir.name == dirname then
|
||||||
|
@ -227,7 +216,7 @@ function core.scan_project_folder(dirname, filename)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- FIXME: rename this function
|
||||||
local function find_project_files_co(root, path)
|
local function find_project_files_co(root, path)
|
||||||
local size_limit = config.file_size_limit * 10e5
|
local size_limit = config.file_size_limit * 10e5
|
||||||
local all = system.list_dir(root .. path) or {}
|
local all = system.list_dir(root .. path) or {}
|
||||||
|
@ -250,39 +239,46 @@ end
|
||||||
|
|
||||||
local function project_files_iter(state)
|
local function project_files_iter(state)
|
||||||
local dir = core.project_directories[state.dir_index]
|
local dir = core.project_directories[state.dir_index]
|
||||||
state.file_index = state.file_index + 1
|
if state.co then
|
||||||
while dir and state.file_index > #dir.files do
|
local ok, name, file = coroutine.resume(state.co, dir.name, "")
|
||||||
state.dir_index = state.dir_index + 1
|
if ok and name then
|
||||||
state.file_index = 1
|
return name, file
|
||||||
dir = core.project_directories[state.dir_index]
|
else
|
||||||
|
state.co = false
|
||||||
|
state.file_index = 1
|
||||||
|
state.dir_index = state.dir_index + 1
|
||||||
|
dir = core.project_directories[state.dir_index]
|
||||||
|
end
|
||||||
|
else
|
||||||
|
state.file_index = state.file_index + 1
|
||||||
|
while dir and state.file_index > #dir.files do
|
||||||
|
state.dir_index = state.dir_index + 1
|
||||||
|
state.file_index = 1
|
||||||
|
dir = core.project_directories[state.dir_index]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
if not dir then return end
|
if not dir then return end
|
||||||
|
if dir.files_limit then
|
||||||
|
state.co = coroutine.create(find_project_files_co)
|
||||||
|
return project_files_iter(state)
|
||||||
|
end
|
||||||
return dir.name, dir.files[state.file_index]
|
return dir.name, dir.files[state.file_index]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function core.get_project_files()
|
function core.get_project_files()
|
||||||
if core.project_files_limit then
|
local state = { dir_index = 1, file_index = 0 }
|
||||||
return coroutine.wrap(function()
|
return project_files_iter, state
|
||||||
for _, dir in ipairs(core.project_directories) do
|
|
||||||
find_project_files_co(dir.name, "")
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
else
|
|
||||||
local state = { dir_index = 1, file_index = 0 }
|
|
||||||
return project_files_iter, state
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function core.project_files_number()
|
function core.project_files_number()
|
||||||
if not core.project_files_limit then
|
local n = 0
|
||||||
local n = 0
|
for i = 1, #core.project_directories do
|
||||||
for i = 1, #core.project_directories do
|
if core.project_directories[i].files_limit then return end
|
||||||
n = n + #core.project_directories[i].files
|
n = n + #core.project_directories[i].files
|
||||||
end
|
|
||||||
return n
|
|
||||||
end
|
end
|
||||||
|
return n
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -441,22 +437,6 @@ function core.load_user_directory()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function core.add_project_directory(path)
|
|
||||||
-- top directories has a file-like "item" but the item.filename
|
|
||||||
-- will be simply the name of the directory, without its path.
|
|
||||||
-- The field item.topdir will identify it as a top level directory.
|
|
||||||
path = common.normalize_path(path)
|
|
||||||
local watch_id = system.watch_dir(path);
|
|
||||||
table.insert(core.project_directories, {
|
|
||||||
name = path,
|
|
||||||
item = {filename = common.basename(path), type = "dir", topdir = true},
|
|
||||||
files = {},
|
|
||||||
is_dirty = true,
|
|
||||||
watch_id = watch_id,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function core.remove_project_directory(path)
|
function core.remove_project_directory(path)
|
||||||
-- skip the fist directory because it is the project's directory
|
-- skip the fist directory because it is the project's directory
|
||||||
for i = 2, #core.project_directories do
|
for i = 2, #core.project_directories do
|
||||||
|
@ -592,7 +572,6 @@ function core.init()
|
||||||
cur_node = cur_node:split("down", core.command_view, {y = true})
|
cur_node = cur_node:split("down", core.command_view, {y = true})
|
||||||
cur_node = cur_node:split("down", core.status_view, {y = true})
|
cur_node = cur_node:split("down", core.status_view, {y = true})
|
||||||
|
|
||||||
core.project_scan_thread_id = core.add_thread(project_scan_thread)
|
|
||||||
command.add_defaults()
|
command.add_defaults()
|
||||||
local got_user_error = not core.load_user_directory()
|
local got_user_error = not core.load_user_directory()
|
||||||
local plugins_success, plugins_refuse_list = core.load_plugins()
|
local plugins_success, plugins_refuse_list = core.load_plugins()
|
||||||
|
|
|
@ -3,9 +3,10 @@ local core = require "core"
|
||||||
local config = require "core.config"
|
local config = require "core.config"
|
||||||
local Doc = require "core.doc"
|
local Doc = require "core.doc"
|
||||||
|
|
||||||
|
|
||||||
local times = setmetatable({}, { __mode = "k" })
|
local times = setmetatable({}, { __mode = "k" })
|
||||||
|
|
||||||
|
local autoreload_scan_rate = 5
|
||||||
|
|
||||||
local function update_time(doc)
|
local function update_time(doc)
|
||||||
local info = system.get_file_info(doc.filename)
|
local info = system.get_file_info(doc.filename)
|
||||||
times[doc] = info.modified
|
times[doc] = info.modified
|
||||||
|
@ -40,7 +41,7 @@ core.add_thread(function()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- wait for next scan
|
-- wait for next scan
|
||||||
coroutine.yield(config.project_scan_rate)
|
coroutine.yield(autoreload_scan_rate)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
|
@ -207,7 +207,6 @@ local function create_directory_in(item)
|
||||||
core.error("cannot create directory %q: %s", dirname, err)
|
core.error("cannot create directory %q: %s", dirname, err)
|
||||||
end
|
end
|
||||||
item.expanded = true
|
item.expanded = true
|
||||||
core.reschedule_project_scan()
|
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
`core.scan_project_folder`:
|
||||||
|
scan a single folder, without recursion. Used when too many files.
|
||||||
|
|
||||||
|
|
||||||
|
`core.add_project_directory`:
|
||||||
|
Add a new top-level folder to the project.
|
||||||
|
|
||||||
|
`core.set_project_dir`:
|
||||||
|
Set the initial project directory.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
`core.project_scan_thread`:
|
||||||
|
Should disappear now that we use dmon.
|
||||||
|
|
||||||
|
|
||||||
|
`core.project_scan_topdir`:
|
||||||
|
New function to scan a top level project folder.
|
||||||
|
|
||||||
|
|
||||||
|
`config.project_scan_rate`:
|
||||||
|
`core.project_scan_thread_id`:
|
||||||
|
`core.reschedule_project_scan`:
|
||||||
|
`core.project_files_limit`:
|
||||||
|
A eliminer.
|
||||||
|
|
||||||
|
`core.get_project_files`:
|
||||||
|
To be fixed. Use `find_project_files_co` for a single directory
|
||||||
|
|
||||||
|
In TreeView remove usage of self.last to detect new scan that changed the files list.
|
||||||
|
|
Loading…
Reference in New Issue