WIP: implement new project commands

Implement commands to load a project from a directory and integrate
the project module within the core modules replacing the workspace
plugin.

Needs polishing but the basic functionalities are there.
This commit is contained in:
Francesco Abbate 2021-05-18 17:20:40 +02:00
parent 9c83082ce8
commit ef4ad10326
3 changed files with 105 additions and 75 deletions

View File

@ -91,13 +91,15 @@ command.add(nil, {
core.command_view:set_text(common.home_encode(view.doc.filename))
end
core.command_view:enter("Open File", function(text)
local filename = core.working_dir_absolute_path(common.home_expand(text))
local filename = common.normalize_path(core.working_dir_absolute_path(common.home_expand(text)))
local info = system.get_file_info(filename)
if info and info.type == "dir" then
core.add_project_directory(filename)
core.set_recent_open("dir", filename)
core.reschedule_project_scan()
else
core.add_project_file(filename)
core.set_recent_open("file", filename)
core.root_view:open_doc(core.open_doc(filename))
end
end, function (text)
@ -143,7 +145,7 @@ command.add(nil, {
end
end,
["core:change-project-folder"] = function()
--[[ ["core:change-project-folder"] = function()
core.command_view:enter("Change Project Folder", function(text, item)
text = system.absolute_path(common.home_expand(item and item.text or text))
if text == core.working_dir then return end
@ -166,7 +168,7 @@ command.add(nil, {
end
system.exec(string.format("%q %q", EXEFILE, text))
end, suggest_directory)
end,
end,]]
["core:add-directory"] = function()
core.command_view:enter("Add Directory", function(text, item)

View File

@ -3,6 +3,7 @@ local common = require "core.common"
local config = require "core.config"
local style = require "core.style"
local command
local project
local keymap
local RootView
local StatusView
@ -17,41 +18,52 @@ local core = {}
local function load_session()
local ok, t = pcall(dofile, USERDIR .. "/session.lua")
if ok then
return t.recents, t.window
return t.recent_projects, t.recents_open, t.window
end
return {}
return {}, {dir={}, file={}}
end
local function save_session()
local fp = io.open(USERDIR .. "/session.lua", "w")
if fp then
fp:write("return {recents=", common.serialize(core.recent_projects),
", window=", common.serialize(table.pack(system.get_window_size())),
"}\n")
fp:write(string.format(
"return { recent_projects= %s, recents_open= %s, window= %s}\n",
common.serialize(core.recent_projects),
common.serialize(core.recents_open),
common.serialize(table.pack(system.get_window_size()))
))
fp:close()
end
end
local function update_recents_project(action, dir_path_abs)
local dirname = common.normalize_path(dir_path_abs)
if not dirname then return end
local recents = core.recent_projects
local function update_recents(recents, action, name)
local n = #recents
for i = 1, n do
if dirname == recents[i] then
if name == recents[i] then
table.remove(recents, i)
break
end
end
if action == "add" then
table.insert(recents, 1, dirname)
table.insert(recents, 1, name)
end
end
local function cleanup_recent_projects()
function core.set_recent_project(name)
update_recents(core.recent_projects, "add", name)
end
function core.set_recent_open(type, filename)
update_recents(core.recents_open[type], "add", filename)
end
-- FIXME: remove or adapt
--[[ local function cleanup_recent_projects()
local recents = core.recent_projects
local i = 1
while i <= #recents do
@ -62,7 +74,7 @@ local function cleanup_recent_projects()
i = i + 1
end
end
end
end ]]
function core.reschedule_project_scan()
@ -72,11 +84,14 @@ function core.reschedule_project_scan()
end
function core.open_folder_project(dir_path_abs)
function core.new_project_from_directory(dir_path_abs)
core.root_view:close_all_docviews()
core.project_entries = {}
core.add_project_directory(dir_path_abs)
update_recents_project("add", dir_path_abs)
system.chdir(dir_path_abs)
core.working_dir = dir_path_abs
core.set_recent_open("dir", dir_path_abs)
core.reschedule_project_scan()
end
@ -384,6 +399,7 @@ end
function core.init()
command = require "core.command"
keymap = require "core.keymap"
project = require "core.project"
RootView = require "core.rootview"
StatusView = require "core.statusview"
TitleView = require "core.titleview"
@ -399,17 +415,19 @@ function core.init()
end
do
local recent_projects, window_position = load_session()
-- FIXME: change the name for "recents_open"
local window_position
core.recent_projects, core.recents_open, window_position = load_session()
if window_position then
system.set_window_size(table.unpack(window_position))
end
core.recent_projects = recent_projects
end
cleanup_recent_projects()
-- cleanup_recent_projects()
core.log_items = {}
core.docs = {}
core.project_entries = {}
core.project_name = ""
local init_files = {}
local delayed_errors = {}
@ -426,7 +444,8 @@ function core.init()
filename = system.absolute_path(filename)
if filename then
core.add_project_directory(filename)
update_recents_project("add", filename)
-- FIXME
-- update_recents(core.recents_open.dir, "add", filename)
end
else
local error_msg = string.format("error: invalid file or directory \"%s\"", ARGS[i])
@ -434,16 +453,6 @@ function core.init()
end
end
local init_message
if #core.project_entries == 0 then
if #core.recent_projects > 0 then
init_message = string.format("Opening project from directory \"%s\"", core.recent_projects[1])
core.add_project_directory(core.recent_projects[1])
else
init_message = string.format("Empty project: use the \"Core: Open File\" command to open a file or a directory.")
end
end
core.threads = setmetatable({}, { __mode = "k" })
core.frame_start = 0
core.clip_rect_stack = {{ 0,0,0,0 }}
@ -485,10 +494,6 @@ function core.init()
core.working_dir = system.absolute_path(".")
end
if init_message then
core.log(init_message)
end
local got_user_error = not core.load_user_directory()
local plugins_success, plugins_refuse_list = core.load_plugins()
local got_project_error = not core.load_project_module()
@ -530,6 +535,13 @@ function core.init()
if item.text == "Exit" then os.exit(1) end
end)
end
if #core.docs == 0 then
local ws = core.try(project.load_workspace, USERDIR .. PATHSEP .. "workspace.lua")
if not ws then
core.log("Empty project: use the \"Core: Open File\" command to open a file or a directory.")
end
end
end
@ -580,12 +592,16 @@ function core.temp_filename(ext)
.. string.format("%06x", temp_file_counter) .. (ext or "")
end
-- override to perform an operation before quitting or entering the
-- current project
do
local do_nothing = function() end
core.on_quit_project = do_nothing
core.on_enter_project = do_nothing
function core.on_quit_project()
local filename = USERDIR .. PATHSEP .. "workspace.lua"
core.try(project.save_workspace, filename)
end
function core.on_enter_project(new_dir)
-- FIXME: check the logic
-- core.try(project.load_workspace, USERDIR .. PATHSEP .. "workspace.lua")
end

View File

@ -1,9 +1,9 @@
-- mod-version:1 -- lite-xl 1.16
local core = require "core"
local command = require "core.command"
local common = require "core.common"
local DocView = require "core.docview"
local project = {}
local function has_no_locked_children(node)
if node.locked then return false end
@ -110,7 +110,7 @@ local function load_node(node, t)
end
local function save_workspace(filename)
function project.save_workspace(filename)
local root = get_unlocked_root(core.root_view.root_node)
local fp = io.open(filename, "w")
if fp then
@ -122,21 +122,35 @@ local function save_workspace(filename)
end
end
local project_entries_text = common.serialize(topdir_entries)
fp:write(string.format("return { working_dir = %q, documents = %s, project_entries = %s }\n", core.working_dir, node_text, project_entries_text))
fp:write(string.format(
"return { project_name = %q, working_dir = %q, documents = %s, project_entries = %s }\n",
core.project_name, core.working_dir, node_text, project_entries_text))
fp:close()
end
end
local function load_workspace(filename)
function project.load(name)
core.project_name = name
local filename = common.path_join(USERDIR, "projects", name .. ".lua")
project.load_workspace(filename)
core.log("Loaded project %s.", core.project_name)
core.reschedule_project_scan()
end
function project.load_workspace(filename)
local load = loadfile(filename)
local workspace = load and load()
-- FIXME: decide, error or return a success code
if not workspace then error("Cannot load workspace") end
if workspace then
local root = get_unlocked_root(core.root_view.root_node)
local active_view = load_node(root, workspace.documents)
if active_view then
core.set_active_view(active_view)
end
core.project_name = workspace.project_name
core.project_entries = {}
for _, entry in ipairs(workspace.project_entries) do
if entry.type == "dir" then
@ -149,29 +163,9 @@ local function load_workspace(filename)
end
end
local run = core.run
function core.run(...)
if #core.docs == 0 then
core.try(load_workspace, USERDIR .. PATHSEP .. "workspace.lua")
local on_quit_project = core.on_quit_project
function core.on_quit_project()
local filename = USERDIR .. PATHSEP .. "workspace.lua"
core.try(save_workspace, filename)
on_quit_project()
end
local on_enter_project = core.on_enter_project
function core.on_enter_project(new_dir)
on_enter_project(new_dir)
core.try(load_workspace, USERDIR .. PATHSEP .. "workspace.lua")
end
end
core.run = run
return core.run(...)
local function suggest_directory(text)
text = common.home_expand(text)
return common.home_encode_list(text == "" and core.recents_open.dir or common.dir_path_suggest(text))
end
command.add(nil, {
@ -188,20 +182,38 @@ command.add(nil, {
core.log("Saved project %s.", core.project_name)
end)
end,
["project:save"] = function()
if core.project_name == "" then
core.command_view:enter("Save Project As", function(text)
core.project_name = text
end)
end
local filename = common.path_join(USERDIR, "projects", core.project_name .. ".lua")
save_workspace(filename)
core.set_recent_project(core.project_name)
core.log("Saved project %s.", core.project_name)
end,
["project:load"] = function()
core.command_view:enter("Load Project", function(text)
-- FIXME: add sanity check of project name.
core.project_name = text
local filename = common.path_join(USERDIR, "projects", text .. ".lua")
load_workspace(filename)
core.log("Loaded project %s.", core.project_name)
core.reschedule_project_scan()
project.load(text)
core.set_recent_project(core.project_name)
end)
end,
["project:open-directory"] = function()
core.command_view:enter("Open Directory", function(text, item)
text = system.absolute_path(common.home_expand(item and item.text or text))
if text == core.working_dir then return end
local path_stat = system.get_file_info(text)
if not path_stat or path_stat.type ~= 'dir' then
core.error("Cannot open folder %q", text)
return
end
core.confirm_close_all(core.new_project_from_directory, text)
end, suggest_directory)
end,
})
return project