Merge branch 'project-manager'

This commit is contained in:
Francesco Abbate
2020-12-12 20:27:07 +01:00
13 changed files with 334 additions and 66 deletions
+137 -34
View File
@@ -11,8 +11,53 @@ local Doc
local core = {}
local function table_serialize(t)
local ls = {"{"}
for i = 1, #t do
ls[#ls + 1] = string.format(" %q,", t[i])
end
ls[#ls + 1] = "}"
return table.concat(ls, "\n")
end
local function load_projects()
local ok, t = pcall(dofile, USERDIR .. "/recent_projects.lua")
core.recent_projects = (ok and t or {})
end
local function add_project_to_recents(dirname)
dirname = system.absolute_path(dirname)
if not dirname then return end
local recents = core.recent_projects
local n = #recents
for i = 1, n do
if dirname == recents[i] then
table.remove(recents, i)
break
end
end
table.insert(recents, 1, dirname)
end
local function save_projects()
local fp = io.open(USERDIR .. "/recent_projects.lua", "w")
if fp then
fp:write("return ", table_serialize(core.recent_projects), "\n")
fp:close()
end
end
function core.open_folder_project(dirname)
core.root_view:close_all_docviews()
add_project_to_recents(dirname)
save_projects()
core.switch_project = dirname
core.threads[core.project_scan_thread_id].wake = 0
end
local function project_scan_thread()
local priority_run = true
local function diff_files(a, b)
if #a ~= #b then return true end
for i, v in ipairs(a) do
@@ -28,7 +73,7 @@ local function project_scan_thread()
end
local function get_files(path, t)
coroutine.yield()
if not priority_run then coroutine.yield() end
t = t or {}
local size_limit = config.file_size_limit * 10e5
local all = system.list_dir(path) or {}
@@ -78,10 +123,17 @@ local function project_scan_thread()
end
core.project_files = t
core.redraw = true
priority_run = false
end
-- wait for next scan
coroutine.yield(config.project_scan_rate)
if core.switch_project then
system.chdir(core.switch_project)
priority_run = true
core.switch_project = nil
else
coroutine.yield(config.project_scan_rate)
end
end
end
@@ -121,30 +173,54 @@ local function write_user_init_file(init_filename)
init_file:write([[
-- put user settings here
-- this module will be loaded after everything else when the application starts
-- it will be automatically reloaded when saved
local keymap = require "core.keymap"
local config = require "core.config"
local style = require "core.style"
-- light theme:
-- require "colors.summer"
-- style.load("colors.summer")
-- key binding:
-- keymap.add { ["ctrl+escape"] = "core:quit" }
-- customize fonts:
-- style.font = renderer.font.load(DATADIR .. "/fonts/font.ttf", 14 * SCALE)
-- style.code_font = renderer.font.load(DATADIR .. "/fonts/monospace.ttf", 13.5 * SCALE)
--
-- fonts used by the editor:
-- style.font : user interface
-- style.big_font : big text in welcome screen
-- style.icon_font : icons
-- style.code_font : code
--
-- the function to load the font accept a 3rd optional argument like:
--
-- {antialiasing="grayscale", hinting="full"}
--
-- possible values are:
-- antialiasing: grayscale, subpixel
-- hinting: none, slight, full
]])
init_file:close()
end
local function load_user_directory()
local init_filename = USERDIR .. "/init.lua"
local info = system.get_file_info(USERDIR)
if not info then
create_user_directory()
write_user_init_file(init_filename)
end
return dofile(init_filename)
function core.load_user_directory()
return core.try(function()
local stat_dir = system.get_file_info(USERDIR)
if not stat_dir then
create_user_directory()
end
local init_filename = USERDIR .. "/init.lua"
local stat_file = system.get_file_info(init_filename)
if not stat_file then
write_user_init_file(init_filename)
end
dofile(init_filename)
end)
end
@@ -156,7 +232,9 @@ function core.init()
CommandView = require "core.commandview"
Doc = require "core.doc"
local project_dir = "."
load_projects()
local project_dir = core.recent_projects[1] or "."
local files = {}
for i = 2, #ARGS do
local info = system.get_file_info(ARGS[i]) or {}
@@ -164,6 +242,8 @@ function core.init()
table.insert(files, system.absolute_path(ARGS[i]))
elseif info.type == "dir" then
project_dir = ARGS[i]
add_project_to_recents(project_dir)
save_projects()
end
end
@@ -177,18 +257,25 @@ function core.init()
core.project_files = {}
core.redraw = true
core.visited_files = {}
core.restart_request = false
core.root_view = RootView()
core.command_view = CommandView()
core.status_view = StatusView()
core.root_view.root_node.is_primary_view = true
core.root_view.root_node:split("down", core.command_view, true)
core.root_view.root_node.b:split("down", core.status_view, true)
core.add_thread(project_scan_thread)
core.project_scan_thread_id = core.add_thread(project_scan_thread)
command.add_defaults()
local got_plugin_error = not core.load_plugins()
local got_user_error = not core.try(load_user_directory)
local got_user_error = not core.load_user_directory()
do
local pdir, pname = system.absolute_path(project_dir):match("(.*)[/\\\\](.*)")
core.log("Opening project %q from directory %q", pname, pdir)
end
local got_project_error = not core.load_project_module()
for _, filename in ipairs(files) do
@@ -201,6 +288,28 @@ function core.init()
end
function core.confirm_close_all()
local dirty_count = 0
local dirty_name
for _, doc in ipairs(core.docs) do
if doc:is_dirty() then
dirty_count = dirty_count + 1
dirty_name = doc:get_name()
end
end
if dirty_count > 0 then
local text
if dirty_count == 1 then
text = string.format("\"%s\" has unsaved changes. Quit anyway?", dirty_name)
else
text = string.format("%d docs have unsaved changes. Quit anyway?", dirty_count)
end
local confirm = system.show_confirm_dialog("Unsaved Changes", text)
if not confirm then return false end
end
return true
end
local temp_uid = (system.get_time() * 1000) % 0xffffffff
local temp_file_prefix = string.format(".lite_temp_%08x", temp_uid)
local temp_file_counter = 0
@@ -225,25 +334,16 @@ function core.quit(force)
delete_temp_files()
os.exit()
end
local dirty_count = 0
local dirty_name
for _, doc in ipairs(core.docs) do
if doc:is_dirty() then
dirty_count = dirty_count + 1
dirty_name = doc:get_name()
end
if core.confirm_close_all() then
core.quit(true)
end
if dirty_count > 0 then
local text
if dirty_count == 1 then
text = string.format("\"%s\" has unsaved changes. Quit anyway?", dirty_name)
else
text = string.format("%d docs have unsaved changes. Quit anyway?", dirty_count)
end
local confirm = system.show_confirm_dialog("Unsaved Changes", text)
if not confirm then return end
end
function core.restart()
if core.confirm_close_all() then
core.restart_request = true
end
core.quit(true)
end
@@ -317,6 +417,7 @@ function core.add_thread(f, weak_ref)
local key = weak_ref or #core.threads + 1
local fn = function() return core.try(f) end
core.threads[key] = { cr = coroutine.create(fn), wake = 0 }
return key
end
@@ -544,10 +645,12 @@ end)
function core.run()
local idle_iterations = 0
local frame_duration = 1 / config.fps
while true do
core.frame_start = system.get_time()
local did_redraw = core.step()
local need_more_work = run_threads()
if core.restart_request then break end
if not did_redraw and not need_more_work then
idle_iterations = idle_iterations + 1
-- do not wait of events at idle_iterations = 1 to give a chance at core.step to run
@@ -555,16 +658,16 @@ function core.run()
if idle_iterations > 1 then
if system.window_has_focus() then
-- keep running even with no events to make the cursor blinks
system.wait_event(1 / config.fps)
system.wait_event(frame_duration)
else
system.wait_event()
end
end
else
idle_iterations = 0
local elapsed = system.get_time() - core.frame_start
system.sleep(math.max(0, frame_duration - elapsed))
end
local elapsed = system.get_time() - core.frame_start
system.sleep(math.max(0, 1 / config.fps - elapsed))
end
end