From 803d6e0f8d9346d0856b6e8ad72e55db93065271 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Thu, 13 May 2021 12:07:56 +0200 Subject: [PATCH] Fix doc opening to use absolute filenames Now we store doc.filename only and removed doc.abs_filename. The former doc.filename is always the absolute filename. We use now the variable core.working_dir to transform relative path into absolute ones. --- data/core/commands/core.lua | 4 +- data/core/commands/doc.lua | 6 +- data/core/doc/init.lua | 15 +-- data/core/docview.lua | 4 +- data/core/init.lua | 37 +++--- data/plugins/treeview.lua | 2 +- data/plugins/workspace.lua | 222 ------------------------------------ 7 files changed, 26 insertions(+), 264 deletions(-) delete mode 100644 data/plugins/workspace.lua diff --git a/data/core/commands/core.lua b/data/core/commands/core.lua index d818c391..0acf1f86 100644 --- a/data/core/commands/core.lua +++ b/data/core/commands/core.lua @@ -87,8 +87,8 @@ command.add(nil, { ["core:open-file"] = function() local view = core.active_view - if view.doc and view.doc.abs_filename then - core.command_view:set_text(common.home_encode(view.doc.abs_filename)) + if view.doc and view.doc.filename then + core.command_view:set_text(common.home_encode(view.doc.filename)) end core.command_view:enter("Open File", function(text, item) local filename = common.home_expand(item and item.text or text) diff --git a/data/core/commands/doc.lua b/data/core/commands/doc.lua index 9b6ba9af..b1f3ebcb 100644 --- a/data/core/commands/doc.lua +++ b/data/core/commands/doc.lua @@ -68,12 +68,10 @@ end local function save(filename) - local abs_filename if filename then - filename = core.normalize_to_project_dir(filename) - abs_filename = core.project_absolute_path(filename) + filename = core.normalize_to_working_dir(filename) end - doc():save(filename, abs_filename) + doc():save(filename) local saved_filename = doc().filename core.on_doc_save(saved_filename) core.log("Saved \"%s\"", saved_filename) diff --git a/data/core/doc/init.lua b/data/core/doc/init.lua index ca41cdad..ed561d23 100644 --- a/data/core/doc/init.lua +++ b/data/core/doc/init.lua @@ -36,11 +36,11 @@ local function splice(t, at, remove, insert) end -function Doc:new(filename, abs_filename, new_file) +function Doc:new(filename, new_file) self.new_file = new_file self:reset() if filename then - self:set_filename(filename, abs_filename) + self.filename = filename if not new_file then self:load(filename) end @@ -69,12 +69,6 @@ function Doc:reset_syntax() end -function Doc:set_filename(filename, abs_filename) - self.filename = filename - self.abs_filename = abs_filename -end - - function Doc:load(filename) local fp = assert( io.open(filename, "rb") ) self:reset() @@ -94,11 +88,10 @@ function Doc:load(filename) end -function Doc:save(filename, abs_filename) +function Doc:save(filename) if not filename then assert(self.filename, "no filename set to default to") filename = self.filename - abs_filename = self.abs_filename end local fp = assert( io.open(filename, "wb") ) for _, line in ipairs(self.lines) do @@ -106,7 +99,7 @@ function Doc:save(filename, abs_filename) fp:write(line) end fp:close() - self:set_filename(filename, abs_filename) + self.filename = filename self.new_file = false self:reset_syntax() self:clean() diff --git a/data/core/docview.lua b/data/core/docview.lua index 070ee0c4..6070a386 100644 --- a/data/core/docview.lua +++ b/data/core/docview.lua @@ -88,9 +88,9 @@ end function DocView:get_filename() - if self.doc.abs_filename then + if self.doc.filename then local post = self.doc:is_dirty() and "*" or "" - return common.home_encode(self.doc.abs_filename) .. post + return common.home_encode(self.doc.filename) .. post end return self:get_name() end diff --git a/data/core/init.lua b/data/core/init.lua index 8f0e8f53..ab067a85 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -59,13 +59,11 @@ end function core.open_folder_project(dir_path_abs) - -- if core.set_project_dir(dir_path_abs, core.on_quit_project) then core.root_view:close_all_docviews() core.project_entries = {} -- FIXME: check stat info to verify is a directory core.add_project_directory(dir_path_abs) update_recents_project("add", dir_path_abs) - -- core.on_enter_project(dir_path_abs) end @@ -304,7 +302,7 @@ end function core.add_project_file(path) - path = normalize_path(path) + path = common.normalize_path(path) table.insert(core.project_entries, { -- type = 'file', name = path, @@ -404,6 +402,7 @@ function core.init() core.threads = setmetatable({}, { __mode = "k" }) core.blink_start = system.get_time() core.blink_timer = core.blink_start + core.working_dir = system.absolute_path(".") local project_dir_abs = system.absolute_path(project_dir) if project_dir_abs then @@ -411,7 +410,7 @@ function core.init() update_recents_project("add", project_dir_abs) end -- FIXME: below, check if project_dir_abs is ok as a project directory - local set_project_ok = project_dir_abs --and core.open_folder_project(project_dir_abs) --core.set_project_dir(project_dir_abs) + local set_project_ok = project_dir_abs if set_project_ok then if project_dir_explicit then update_recents_project("add", project_dir_abs) @@ -722,16 +721,7 @@ function core.pop_clip_rect() renderer.set_clip_rect(x, y, w, h) end - -function core.normalize_to_project_dir(filename) - filename = common.normalize_path(filename) - if common.path_belongs_to(filename, core.project_dir) then - filename = common.relative_path(core.project_dir, filename) - end - return filename -end - - +-- FIXME: update comment -- The function below works like system.absolute_path except it -- doesn't fail if the file does not exist. We consider that the -- current dir is core.project_dir so relative filename are considered @@ -739,31 +729,34 @@ end -- Please note that .. or . in the filename are not taken into account. -- This function should get only filenames normalized using -- common.normalize_path function. -function core.project_absolute_path(filename) +function core.working_dir_absolute_path(filename) if filename:match('^%a:\\') or filename:find('/', 1, true) then return filename else - return core.project_dir .. PATHSEP .. filename + return core.working_dir .. PATHSEP .. filename end end +function core.normalize_to_working_dir(filename) + filename = common.normalize_path(filename) + return core.working_dir_absolute_path(filename) +end + function core.open_doc(filename) local new_file = not filename or not system.get_file_info(filename) - local abs_filename if filename then -- normalize filename and set absolute filename then -- try to find existing doc for filename - filename = core.normalize_to_project_dir(filename) - abs_filename = core.project_absolute_path(filename) + filename = core.normalize_to_working_dir(filename) for _, doc in ipairs(core.docs) do - if doc.abs_filename and abs_filename == doc.abs_filename then + if doc.filename and filename == doc.filename then return doc end end end -- no existing doc for filename; create new - local doc = Doc(filename, abs_filename, new_file) + local doc = Doc(filename, new_file) table.insert(core.docs, doc) core.log_quiet(filename and "Opened doc \"%s\"" or "Opened new doc", filename) return doc @@ -1023,7 +1016,7 @@ end core.add_save_hook(function(filename) local doc = core.active_view.doc - if doc and doc:is(Doc) and doc.abs_filename == USERDIR .. PATHSEP .. "init.lua" then + if doc and doc:is(Doc) and doc.filename == USERDIR .. PATHSEP .. "init.lua" then core.reload_module("core.style") core.load_user_directory() end diff --git a/data/plugins/treeview.lua b/data/plugins/treeview.lua index bc88fdaf..87858b54 100644 --- a/data/plugins/treeview.lua +++ b/data/plugins/treeview.lua @@ -238,7 +238,7 @@ function TreeView:on_mouse_pressed(button, x, y, clicks) end else core.try(function() - local doc_filename = common.relative_path(core.project_dir, self.hovered_item.abs_filename) + local doc_filename = self.hovered_item.abs_filename core.root_view:open_doc(core.open_doc(doc_filename)) end) end diff --git a/data/plugins/workspace.lua b/data/plugins/workspace.lua deleted file mode 100644 index 25c7f672..00000000 --- a/data/plugins/workspace.lua +++ /dev/null @@ -1,222 +0,0 @@ --- mod-version:1 -- lite-xl 1.16 -local core = require "core" -local common = require "core.common" -local DocView = require "core.docview" - - -local function workspace_files_for(project_dir) - local basename = common.basename(project_dir) - local workspace_dir = USERDIR .. PATHSEP .. "ws" - local info_wsdir = system.get_file_info(workspace_dir) - if not info_wsdir then - local ok, err = system.mkdir(workspace_dir) - if not ok then - error("cannot create workspace directory: %s", err) - end - end - return coroutine.wrap(function() - local files = system.list_dir(workspace_dir) or {} - local n = #basename - for _, file in ipairs(files) do - if file:sub(1, n) == basename then - local id = tonumber(file:sub(n + 1):match("^-(%d+)$")) - if id then - coroutine.yield(workspace_dir .. PATHSEP .. file, id) - end - end - end - end) -end - - -local function load_workspace_file(project_dir) - for filename, id in workspace_files_for(project_dir) do - local load_f = loadfile(filename) - local workspace = load_f and load_f() - if workspace and workspace.path == project_dir then - os.remove(filename) - return workspace - end - end -end - - -local function get_workspace_filename(project_dir) - local id_list = {} - for filename, id in workspace_files_for(project_dir) do - id_list[id] = true - end - local id = 1 - while id_list[id] do - id = id + 1 - end - local basename = common.basename(project_dir) - return USERDIR .. PATHSEP .. "ws" .. PATHSEP .. basename .. "-" .. tostring(id) -end - - -local function has_no_locked_children(node) - if node.locked then return false end - if node.type == "leaf" then return true end - return has_no_locked_children(node.a) and has_no_locked_children(node.b) -end - - -local function get_unlocked_root(node) - if node.type == "leaf" then - return not node.locked and node - end - if has_no_locked_children(node) then - return node - end - return get_unlocked_root(node.a) or get_unlocked_root(node.b) -end - - -local function save_view(view) - local mt = getmetatable(view) - if mt == DocView then - return { - type = "doc", - active = (core.active_view == view), - filename = view.doc.filename, - selection = { view.doc:get_selection() }, - scroll = { x = view.scroll.to.x, y = view.scroll.to.y }, - text = not view.doc.filename and view.doc:get_text(1, 1, math.huge, math.huge) - } - end - for name, mod in pairs(package.loaded) do - if mod == mt then - return { - type = "view", - active = (core.active_view == view), - module = name - } - end - end -end - - -local function load_view(t) - if t.type == "doc" then - local ok, doc = pcall(core.open_doc, t.filename) - if not ok then - return DocView(core.open_doc()) - end - local dv = DocView(doc) - if t.text then doc:insert(1, 1, t.text) end - doc:set_selection(table.unpack(t.selection)) - dv.last_line, dv.last_col = doc:get_selection() - dv.scroll.x, dv.scroll.to.x = t.scroll.x, t.scroll.x - dv.scroll.y, dv.scroll.to.y = t.scroll.y, t.scroll.y - return dv - end - return require(t.module)() -end - - -local function save_node(node) - local res = {} - res.type = node.type - if node.type == "leaf" then - res.views = {} - for _, view in ipairs(node.views) do - local t = save_view(view) - if t then - table.insert(res.views, t) - if node.active_view == view then - res.active_view = #res.views - end - end - end - else - res.divider = node.divider - res.a = save_node(node.a) - res.b = save_node(node.b) - end - return res -end - - -local function load_node(node, t) - if t.type == "leaf" then - local res - for _, v in ipairs(t.views) do - local view = load_view(v) - if v.active then res = view end - node:add_view(view) - end - if t.active_view then - node:set_active_view(node.views[t.active_view]) - end - return res - else - node:split(t.type == "hsplit" and "right" or "down") - node.divider = t.divider - local res1 = load_node(node.a, t.a) - local res2 = load_node(node.b, t.b) - return res1 or res2 - end -end - - -local function save_directories() - local project_dir = core.project_dir - local dir_list = {} - for i = 2, #core.project_directories do - dir_list[#dir_list + 1] = common.relative_path(project_dir, core.project_directories[i].name) - end - return dir_list -end - - -local function save_workspace() - local root = get_unlocked_root(core.root_view.root_node) - local workspace_filename = get_workspace_filename(core.project_dir) - local fp = io.open(workspace_filename, "w") - if fp then - local node_text = common.serialize(save_node(root)) - local dir_text = common.serialize(save_directories()) - fp:write(string.format("return { path = %q, documents = %s, directories = %s }\n", core.project_dir, node_text, dir_text)) - fp:close() - end -end - - -local function load_workspace() - local workspace = load_workspace_file(core.project_dir) - 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 - for i, dir_name in ipairs(workspace.directories) do - core.add_project_directory(system.absolute_path(dir_name)) - end - end -end - - -local run = core.run - -function core.run(...) - if #core.docs == 0 then - core.try(load_workspace) - - local on_quit_project = core.on_quit_project - function core.on_quit_project() - core.try(save_workspace) - 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) - end - end - - core.run = run - return core.run(...) -end