From 926e004c4124a24e2fe04a40886c36d36181e141 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Sun, 6 Dec 2020 00:57:27 +0100 Subject: [PATCH] Preliminary version of project manager Adapted from contribute rxi/lite-plugins but changed to avoid restarting the application when switching project. Current problem: - the reload of the treeview take some time without any feedback for the user --- data/core/init.lua | 44 +++++------ data/core/rootview.lua | 41 ++++++++++ data/plugins/projectmanager.lua | 130 ++++++++++++++++++++++++++++++++ 3 files changed, 188 insertions(+), 27 deletions(-) create mode 100644 data/plugins/projectmanager.lua diff --git a/data/core/init.lua b/data/core/init.lua index 0ea433e4..00c3b540 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -81,7 +81,12 @@ local function project_scan_thread() end -- wait for next scan - coroutine.yield(config.project_scan_rate) + if core.switch_project then + system.chdir(core.switch_project) + core.switch_project = nil + else + coroutine.yield(config.project_scan_rate) + end end end @@ -175,6 +180,7 @@ function core.init() core.command_view = CommandView() core.status_view = StatusView() + core.root_view.root_node.has_documents_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) @@ -194,30 +200,7 @@ function core.init() 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 - -local function delete_temp_files() - for _, filename in ipairs(system.list_dir(EXEDIR)) do - if filename:find(temp_file_prefix, 1, true) == 1 then - os.remove(EXEDIR .. PATHSEP .. filename) - end - end -end - -function core.temp_filename(ext) - temp_file_counter = temp_file_counter + 1 - return EXEDIR .. PATHSEP .. temp_file_prefix - .. string.format("%06x", temp_file_counter) .. (ext or "") -end - - -function core.quit(force) - if force then - delete_temp_files() - os.exit() - end +function core.confirm_close_all() local dirty_count = 0 local dirty_name for _, doc in ipairs(core.docs) do @@ -234,9 +217,16 @@ function core.quit(force) 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 + if not confirm then return false end + end + return true +end + + +function core.quit(force) + if core.confirm_close_all() then + os.exit() end - core.quit(true) end diff --git a/data/core/rootview.lua b/data/core/rootview.lua index 51150079..c0daf8ad 100644 --- a/data/core/rootview.lua +++ b/data/core/rootview.lua @@ -4,6 +4,7 @@ local style = require "core.style" local keymap = require "core.keymap" local Object = require "core.object" local View = require "core.view" +local CommandView = require "core.commandview" local DocView = require "core.docview" @@ -376,6 +377,41 @@ function Node:draw() end +function Node:is_empty() + if self.type == "leaf" then + return #self.views == 0 + else + return self.a:is_empty() and self.b:is_empty() + end +end + + +function Node:close_all_docviews() + if self.type == "leaf" then + local i = 1 + while i <= #self.views do + local view = self.views[i] + if view:is(DocView) and not view:is(CommandView) then + table.remove(self.views, i) + else + i = i + 1 + end + end + if #self.views == 0 and self.has_documents_view then + self:add_view(EmptyView()) + end + else + self.a:close_all_docviews() + self.b:close_all_docviews() + if self.a:is_empty() then + self:consume(self.b) + elseif self.b:is_empty() then + self:consume(self.a) + end + end +end + + local RootView = View:extend() @@ -437,6 +473,11 @@ function RootView:open_doc(doc) end +function RootView:close_all_docviews() + self.root_node:close_all_docviews() +end + + function RootView:on_mouse_pressed(button, x, y, clicks) local div = self.root_node:get_divider_overlapping_point(x, y) if div then diff --git a/data/plugins/projectmanager.lua b/data/plugins/projectmanager.lua new file mode 100644 index 00000000..2379cfa6 --- /dev/null +++ b/data/plugins/projectmanager.lua @@ -0,0 +1,130 @@ +local project_manager = {} + +local core = require "core" +local command = require "core.command" +local common = require "core.common" +local keymap = require "core.keymap" + +local projects_file = ".lite_projects.lua" + +project_manager.projects = {} + +local function load_projects() + local ok, t = pcall(dofile, EXEDIR .. "/" .. projects_file) + if ok then project_manager.projects = t end +end + +load_projects() + +local function serialize(val) + if type(val) == "string" then + return string.format("%q", val) + elseif type(val) == "table" then + local t = {} + for k, v in pairs(val) do + table.insert(t, "[" .. serialize(k) .. "]=" .. serialize(v)) + end + return "{" .. table.concat(t, ",") .. "}" + end + return tostring(val) +end + +local function save_projects() + local fp = io.open(EXEDIR .. "/" .. projects_file, "w") + if fp then + fp:write("return ", serialize(project_manager.projects), "\n") + fp:close() + end +end + +local function path_base_name(str) + local pattern = "[\\/]?([^\\/]+)[\\/]?$" + return str:match(pattern) +end + +function project_manager.add_project() + local proj_dir = system.absolute_path(".") + local proj_name = path_base_name(proj_dir) + core.command_view:set_text(proj_name) + core.command_view:enter("Project Name", + function(text) + if text then + project_manager.projects[text] = proj_dir + save_projects() + end + end) +end + +local function get_project_names() + local t = {} + for k, v in pairs(project_manager.projects) do table.insert(t, k) end + return t +end + +local function project_lister(func) + local projects = get_project_names(); + core.command_view:enter("Open Project", func, function(text) + local res = common.fuzzy_match(projects, text) + for i, name in ipairs(res) do + res[i] = { + text = name, + info = project_manager.projects[name], + } + end + return res + end) +end + +function project_manager.rename_project(func) + project_lister(function(text, item) + if item then + core.command_view:set_text(item.text) + core.command_view:enter("Rename ".. item.text, + function(_text) + if _text then + project_manager.projects[_text] = project_manager.projects[item.text] + project_manager.projects[item.text] = nil + save_projects() + end + end) + end + end) +end + +function project_manager.open_project() + project_lister(function(text, item) + if item then + system.exec(string.format("%q %q", EXEFILE, item.info)) + end + end) +end + +function project_manager.switch_project() + project_lister(function(text, item) + if item then + if core.confirm_close_all() then + core.root_view:close_all_docviews() + core.switch_project = item.info + end + end + end) +end + +function project_manager.remove_project() + project_lister(function(text, item) + if item then + project_manager.projects[item.text] = nil + save_projects() + end + end) +end + +command.add(nil, { + ["project-manager:open-project"] = project_manager.open_project, + ["project-manager:switch-project"] = project_manager.switch_project, + ["project-manager:add-project"] = project_manager.add_project, + ["project-manager:remove-project"] = project_manager.remove_project, + ["project-manager:rename-project"] = project_manager.rename_project, + }) + +return project_manager