From 926e004c4124a24e2fe04a40886c36d36181e141 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Sun, 6 Dec 2020 00:57:27 +0100 Subject: [PATCH 01/24] 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 From 745dd99e978685bb456c26c0abce7ca14d833fd6 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Sun, 6 Dec 2020 01:03:54 +0100 Subject: [PATCH 02/24] Use original document views node to open a new document Used when the active view is a locked node. --- data/core/rootview.lua | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/data/core/rootview.lua b/data/core/rootview.lua index c0daf8ad..a6e8ae3c 100644 --- a/data/core/rootview.lua +++ b/data/core/rootview.lua @@ -432,20 +432,17 @@ function RootView:get_active_node() return self.root_node:get_node_for_view(core.active_view) end --- Get un unlocked node with at least one view. -local function get_node_unlocked(node) - if not node.locked and #node.views > 0 then +local function get_main_document_view(node) + if node.has_documents_view then return node end if node.type ~= "leaf" then - local a = get_node_unlocked(node.a) - if a then return a end - return get_node_unlocked(node.b) + return get_main_document_view(node.a) or get_main_document_view(node.b) end end -function RootView:get_document_view() - local node = get_node_unlocked(self.root_node) +function RootView:get_main_document_view() + local node = get_main_document_view(self.root_node) if node then return node.views[1] end @@ -454,8 +451,8 @@ end function RootView:open_doc(doc) local node = self:get_active_node() if node.locked then - local default_view = self:get_document_view() - assert(default_view, "Cannot find an unlocked node to open the document.") + local default_view = self:get_main_document_view() + assert(default_view, "internal error: cannot find original document node.") core.set_active_view(default_view) node = self:get_active_node() end From 3cb52881fcc17ce3f4bb1ef44ec45149407083c2 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Sun, 6 Dec 2020 01:04:14 +0100 Subject: [PATCH 03/24] Pass options to Lite with script run-local --- run-local | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run-local b/run-local index 17284818..3e02e54a 100755 --- a/run-local +++ b/run-local @@ -28,4 +28,4 @@ fi for module_name in core plugins colors fonts; do cp -r "data/$module_name" "$datadir" done -exec "$bindir/lite" +exec "$bindir/lite" "${@:2}" From ffaf5e0ea57cb757ed7d715fc0e22aab50369f88 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Sun, 6 Dec 2020 13:10:46 +0100 Subject: [PATCH 04/24] Use USERDIR to store projects --- data/plugins/projectmanager.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/plugins/projectmanager.lua b/data/plugins/projectmanager.lua index 2379cfa6..46ab8737 100644 --- a/data/plugins/projectmanager.lua +++ b/data/plugins/projectmanager.lua @@ -10,7 +10,7 @@ local projects_file = ".lite_projects.lua" project_manager.projects = {} local function load_projects() - local ok, t = pcall(dofile, EXEDIR .. "/" .. projects_file) + local ok, t = pcall(dofile, USERDIR .. "/" .. projects_file) if ok then project_manager.projects = t end end @@ -30,7 +30,7 @@ local function serialize(val) end local function save_projects() - local fp = io.open(EXEDIR .. "/" .. projects_file, "w") + local fp = io.open(USERDIR .. "/" .. projects_file, "w") if fp then fp:write("return ", serialize(project_manager.projects), "\n") fp:close() From ca9bf21819a382fc39b834173d10c795c218b427 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Sun, 6 Dec 2020 13:24:55 +0100 Subject: [PATCH 05/24] Reword name for identifying primary view --- data/core/init.lua | 2 +- data/core/rootview.lua | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/data/core/init.lua b/data/core/init.lua index 00c3b540..461f839d 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -180,7 +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.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) diff --git a/data/core/rootview.lua b/data/core/rootview.lua index a6e8ae3c..690fdeec 100644 --- a/data/core/rootview.lua +++ b/data/core/rootview.lua @@ -397,7 +397,7 @@ function Node:close_all_docviews() i = i + 1 end end - if #self.views == 0 and self.has_documents_view then + if #self.views == 0 and self.is_primary_view then self:add_view(EmptyView()) end else @@ -432,17 +432,17 @@ function RootView:get_active_node() return self.root_node:get_node_for_view(core.active_view) end -local function get_main_document_view(node) - if node.has_documents_view then +local function get_primary_view(node) + if node.is_primary_view then return node end if node.type ~= "leaf" then - return get_main_document_view(node.a) or get_main_document_view(node.b) + return get_primary_view(node.a) or get_primary_view(node.b) end end -function RootView:get_main_document_view() - local node = get_main_document_view(self.root_node) +function RootView:get_primary_view() + local node = get_primary_view(self.root_node) if node then return node.views[1] end @@ -451,7 +451,7 @@ end function RootView:open_doc(doc) local node = self:get_active_node() if node.locked then - local default_view = self:get_main_document_view() + local default_view = self:get_primary_view() assert(default_view, "internal error: cannot find original document node.") core.set_active_view(default_view) node = self:get_active_node() From ebaa2b4f2678377bac0bcffbf2aa63491b0a38b7 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Mon, 7 Dec 2020 17:38:36 +0100 Subject: [PATCH 06/24] Fix bug related to creation of user's init file --- data/core/init.lua | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/data/core/init.lua b/data/core/init.lua index 461f839d..463180eb 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -137,9 +137,12 @@ end local function load_user_directory() local init_filename = USERDIR .. "/init.lua" - local info = system.get_file_info(USERDIR) - if not info then + local stat_info_dir = system.get_file_info(USERDIR) + if not stat_info_dir then create_user_directory() + end + local stat_info_file = system.get_file_info(init_filename) + if not stat_info_file then write_user_init_file(init_filename) end return dofile(init_filename) From 48ad8a8392c742f9ce7939677951eaf737624bea Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Mon, 7 Dec 2020 17:42:50 +0100 Subject: [PATCH 07/24] Run locally using a local user directory for testing --- run-local | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/run-local b/run-local index 3e02e54a..69af2108 100755 --- a/run-local +++ b/run-local @@ -9,6 +9,8 @@ else datadir="$rundir/share/lite-xl" fi +userdir="$rundir/.lite" + if [ "$#" -lt 1 ]; then echo "usage: $0 " exit 1 @@ -16,7 +18,7 @@ fi builddir="$1" rm -fr "$rundir" -mkdir -p "$bindir" "$datadir" +mkdir -p "$bindir" "$datadir" "$userdir" if [ -f "$builddir/src/lite" ]; then cp "$builddir/src/lite" "$bindir" elif [ -f "$builddir/src/lite.exe" ]; then @@ -28,4 +30,4 @@ fi for module_name in core plugins colors fonts; do cp -r "data/$module_name" "$datadir" done -exec "$bindir/lite" "${@:2}" +HOME="$userdir" USERPROFILE="$userdir" exec "$bindir/lite" "${@:2}" From a3adfeb8f673550824b2f8b06d95bf2d76bef366 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Mon, 7 Dec 2020 18:06:58 +0100 Subject: [PATCH 08/24] Begin reworks of project manager --- data/core/common.lua | 15 +++++ data/plugins/projectmanager.lua | 100 +++++--------------------------- 2 files changed, 30 insertions(+), 85 deletions(-) diff --git a/data/core/common.lua b/data/core/common.lua index 1fc91b80..659cf244 100644 --- a/data/core/common.lua +++ b/data/core/common.lua @@ -102,6 +102,21 @@ function common.path_suggest(text) end +function common.dir_path_suggest(text) + local path, name = text:match("^(.-)([^/\\]*)$") + local files = system.list_dir(path == "" and "." or path) or {} + local res = {} + for _, file in ipairs(files) do + file = path .. file + local info = system.get_file_info(file) + if info and info.type == "dir" and file:lower():find(text:lower(), nil, true) == 1 then + table.insert(res, file) + end + end + return res +end + + function common.match_pattern(text, pattern, ...) if type(pattern) == "string" then return text:find(pattern, ...) diff --git a/data/plugins/projectmanager.lua b/data/plugins/projectmanager.lua index 46ab8737..5ba7a4a2 100644 --- a/data/plugins/projectmanager.lua +++ b/data/plugins/projectmanager.lua @@ -5,13 +5,13 @@ local command = require "core.command" local common = require "core.common" local keymap = require "core.keymap" -local projects_file = ".lite_projects.lua" +local recent_projects_file = "recent_projects.lua" -project_manager.projects = {} +project_manager.recents = {} local function load_projects() - local ok, t = pcall(dofile, USERDIR .. "/" .. projects_file) - if ok then project_manager.projects = t end + local ok, t = pcall(dofile, USERDIR .. "/" .. recent_projects_file) + if ok then project_manager.recents = t end end load_projects() @@ -30,9 +30,9 @@ local function serialize(val) end local function save_projects() - local fp = io.open(USERDIR .. "/" .. projects_file, "w") + local fp = io.open(USERDIR .. "/" .. recent_projects_file, "w") if fp then - fp:write("return ", serialize(project_manager.projects), "\n") + fp:write("return ", serialize(project_manager.recents), "\n") fp:close() end end @@ -42,89 +42,19 @@ local function path_base_name(str) 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 +function project_manager.open_folder() + core.command_view:enter("Open Folder", function(text) + if core.confirm_close_all() then + core.root_view:close_all_docviews() + table.insert(project_manager.recents, text) save_projects() + core.switch_project = text end - end) + end, common.dir_path_suggest) 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, - }) + ["project-manager:open-folder"] = project_manager.open_folder, +}) return project_manager From c0f0325bbb2943a15fc588cfd71622974976e5a5 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Tue, 8 Dec 2020 09:42:11 +0100 Subject: [PATCH 09/24] Fix behavior of project manager to store directories --- data/core/rootview.lua | 1 + data/plugins/projectmanager.lua | 25 +++++++++++++++---------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/data/core/rootview.lua b/data/core/rootview.lua index 690fdeec..de66a01f 100644 --- a/data/core/rootview.lua +++ b/data/core/rootview.lua @@ -19,6 +19,7 @@ local function draw_text(x, y, color) local lines = { { fmt = "%s to run a command", cmd = "core:find-command" }, { fmt = "%s to open a file from the project", cmd = "core:find-file" }, + { fmt = "%s to open a folder", cmd = "project-manager:open-folder" }, } th = style.font:get_height() y = y + (dh - th * 2 - style.padding.y) / 2 diff --git a/data/plugins/projectmanager.lua b/data/plugins/projectmanager.lua index 5ba7a4a2..073fcbee 100644 --- a/data/plugins/projectmanager.lua +++ b/data/plugins/projectmanager.lua @@ -17,16 +17,12 @@ 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, ",") .. "}" + local ls = {"{"} + for i = 1, #val do + ls[#ls + 1] = " " .. string.format("%q", val[i]) .. "," end - return tostring(val) + ls[#ls + 1] = "}" + return table.concat(ls, "\n") end local function save_projects() @@ -44,17 +40,26 @@ end function project_manager.open_folder() core.command_view:enter("Open Folder", function(text) + 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 if core.confirm_close_all() then core.root_view:close_all_docviews() table.insert(project_manager.recents, text) save_projects() core.switch_project = text end - end, common.dir_path_suggest) + end, function(text) + return text == "" and project_manager.recents or common.dir_path_suggest(text) + end) end command.add(nil, { ["project-manager:open-folder"] = project_manager.open_folder, }) +keymap.add { ["ctrl+shift+o"] = "project-manager:open-folder" } + return project_manager From 9c7e477cd124ef431f9e7192179eda36a06e962e Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Tue, 8 Dec 2020 09:42:31 +0100 Subject: [PATCH 10/24] Do not use a separate director for userdir in run-local --- run-local | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run-local b/run-local index 69af2108..2f866dfb 100755 --- a/run-local +++ b/run-local @@ -9,7 +9,7 @@ else datadir="$rundir/share/lite-xl" fi -userdir="$rundir/.lite" +userdir="$rundir" if [ "$#" -lt 1 ]; then echo "usage: $0 " From e88adc0567dd1c4477c4840bfa041785176957e6 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Tue, 8 Dec 2020 16:57:24 +0100 Subject: [PATCH 11/24] Move project manager into core init file --- data/core/commands/core.lua | 15 ++++++++ data/core/init.lua | 48 +++++++++++++++++++++++- data/core/keymap.lua | 1 + data/core/rootview.lua | 2 +- data/plugins/projectmanager.lua | 65 --------------------------------- 5 files changed, 64 insertions(+), 67 deletions(-) delete mode 100644 data/plugins/projectmanager.lua diff --git a/data/core/commands/core.lua b/data/core/commands/core.lua index a4cf4d7d..c6ef6743 100644 --- a/data/core/commands/core.lua +++ b/data/core/commands/core.lua @@ -111,4 +111,19 @@ command.add(nil, { doc:save(filename) end end, + + ["core:open-folder"] = function() + core.command_view:enter("Open Folder", function(text) + 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 + if core.confirm_close_all() then + core.open_folder_project(text) + end + end, function(text) + return text == "" and core.recent_projects or common.dir_path_suggest(text) + end) + end, }) diff --git a/data/core/init.lua b/data/core/init.lua index 463180eb..373f2108 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -11,6 +11,48 @@ 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 return end + end + recents[n + 1] = dirname +end + +local function save_projects() + local fp = io.open(USERDIR .. "/recent_projects.lua", "w") + if fp then + local _, err = fp:write("return ", table_serialize(core.recent_projects), "\n") + if err then + core.error("Error saving recent projects, %d entries", #core.recent_projects) + end + 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 +end local function project_scan_thread() local function diff_files(a, b) @@ -157,7 +199,9 @@ function core.init() CommandView = require "core.commandview" Doc = require "core.doc" - local project_dir = "." + load_projects() + + local project_dir = #core.recent_projects > 0 and core.recent_projects[#core.recent_projects] or "." local files = {} for i = 2, #ARGS do local info = system.get_file_info(ARGS[i]) or {} @@ -165,6 +209,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 diff --git a/data/core/keymap.lua b/data/core/keymap.lua index 4d48ed4e..5c715def 100644 --- a/data/core/keymap.lua +++ b/data/core/keymap.lua @@ -181,6 +181,7 @@ keymap.add { ["ctrl+shift+end"] = "doc:select-to-end-of-doc", ["shift+pageup"] = "doc:select-to-previous-page", ["shift+pagedown"] = "doc:select-to-next-page", + ["ctrl+shift+o"] = "core:open-folder", } return keymap diff --git a/data/core/rootview.lua b/data/core/rootview.lua index de66a01f..3fd6e6d5 100644 --- a/data/core/rootview.lua +++ b/data/core/rootview.lua @@ -19,7 +19,7 @@ local function draw_text(x, y, color) local lines = { { fmt = "%s to run a command", cmd = "core:find-command" }, { fmt = "%s to open a file from the project", cmd = "core:find-file" }, - { fmt = "%s to open a folder", cmd = "project-manager:open-folder" }, + { fmt = "%s to open a folder", cmd = "core:open-folder" }, } th = style.font:get_height() y = y + (dh - th * 2 - style.padding.y) / 2 diff --git a/data/plugins/projectmanager.lua b/data/plugins/projectmanager.lua deleted file mode 100644 index 073fcbee..00000000 --- a/data/plugins/projectmanager.lua +++ /dev/null @@ -1,65 +0,0 @@ -local project_manager = {} - -local core = require "core" -local command = require "core.command" -local common = require "core.common" -local keymap = require "core.keymap" - -local recent_projects_file = "recent_projects.lua" - -project_manager.recents = {} - -local function load_projects() - local ok, t = pcall(dofile, USERDIR .. "/" .. recent_projects_file) - if ok then project_manager.recents = t end -end - -load_projects() - -local function serialize(val) - local ls = {"{"} - for i = 1, #val do - ls[#ls + 1] = " " .. string.format("%q", val[i]) .. "," - end - ls[#ls + 1] = "}" - return table.concat(ls, "\n") -end - -local function save_projects() - local fp = io.open(USERDIR .. "/" .. recent_projects_file, "w") - if fp then - fp:write("return ", serialize(project_manager.recents), "\n") - fp:close() - end -end - -local function path_base_name(str) - local pattern = "[\\/]?([^\\/]+)[\\/]?$" - return str:match(pattern) -end - -function project_manager.open_folder() - core.command_view:enter("Open Folder", function(text) - 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 - if core.confirm_close_all() then - core.root_view:close_all_docviews() - table.insert(project_manager.recents, text) - save_projects() - core.switch_project = text - end - end, function(text) - return text == "" and project_manager.recents or common.dir_path_suggest(text) - end) -end - -command.add(nil, { - ["project-manager:open-folder"] = project_manager.open_folder, -}) - -keymap.add { ["ctrl+shift+o"] = "project-manager:open-folder" } - -return project_manager From f882957ebc2225acdf5c2e1c077047f32962a345 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Tue, 8 Dec 2020 16:59:05 +0100 Subject: [PATCH 12/24] Experimentally add priority run when scanning project files Avoid yielding when a first scan is required but seems quite ineffective. --- data/core/init.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/data/core/init.lua b/data/core/init.lua index 373f2108..72065b99 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -55,6 +55,8 @@ function core.open_folder_project(dirname) 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 @@ -70,7 +72,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 {} @@ -120,11 +122,13 @@ local function project_scan_thread() end core.project_files = t core.redraw = true + priority_run = false end -- wait for next scan if core.switch_project then system.chdir(core.switch_project) + priority_run = true core.switch_project = nil else coroutine.yield(config.project_scan_rate) From 8448eee79fcfb53beaed2451484b5b6a3cbb8ca5 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Tue, 8 Dec 2020 18:49:58 +0100 Subject: [PATCH 13/24] More accurate list of recent projects --- data/core/init.lua | 19 ++++++++++++------- run-local | 2 +- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/data/core/init.lua b/data/core/init.lua index 72065b99..508b2f4f 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -31,18 +31,18 @@ local function add_project_to_recents(dirname) local recents = core.recent_projects local n = #recents for i = 1, n do - if dirname == recents[i] then return end + if dirname == recents[i] then + table.remove(recents, i) + break + end end - recents[n + 1] = dirname + table.insert(recents, 1, dirname) end local function save_projects() local fp = io.open(USERDIR .. "/recent_projects.lua", "w") if fp then - local _, err = fp:write("return ", table_serialize(core.recent_projects), "\n") - if err then - core.error("Error saving recent projects, %d entries", #core.recent_projects) - end + fp:write("return ", table_serialize(core.recent_projects), "\n") fp:close() end end @@ -205,7 +205,7 @@ function core.init() load_projects() - local project_dir = #core.recent_projects > 0 and core.recent_projects[#core.recent_projects] or "." + local project_dir = core.recent_projects[1] or "." local files = {} for i = 2, #ARGS do local info = system.get_file_info(ARGS[i]) or {} @@ -241,6 +241,11 @@ function core.init() command.add_defaults() local got_plugin_error = not core.load_plugins() local got_user_error = not core.try(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 diff --git a/run-local b/run-local index 2f866dfb..1bf3cc2b 100755 --- a/run-local +++ b/run-local @@ -9,7 +9,7 @@ else datadir="$rundir/share/lite-xl" fi -userdir="$rundir" +userdir="$(realpath "$rundir")" if [ "$#" -lt 1 ]; then echo "usage: $0 " From ba898b50fc0fd32ac162377f2613ebd6b35dce73 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Tue, 8 Dec 2020 23:35:49 +0100 Subject: [PATCH 14/24] Force a clear of treeview on switch project --- data/core/init.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data/core/init.lua b/data/core/init.lua index 508b2f4f..7976578e 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -51,6 +51,8 @@ function core.open_folder_project(dirname) core.root_view:close_all_docviews() add_project_to_recents(dirname) save_projects() + core.project_files = {} + core.redraw = true core.switch_project = dirname end From ebcfa63de1e2341f6a092a967e56bb0bebf3da92 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Tue, 8 Dec 2020 23:36:50 +0100 Subject: [PATCH 15/24] Fix centerings of text in EmptyView --- data/core/rootview.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/core/rootview.lua b/data/core/rootview.lua index 3fd6e6d5..834e96c4 100644 --- a/data/core/rootview.lua +++ b/data/core/rootview.lua @@ -19,10 +19,10 @@ local function draw_text(x, y, color) local lines = { { fmt = "%s to run a command", cmd = "core:find-command" }, { fmt = "%s to open a file from the project", cmd = "core:find-file" }, - { fmt = "%s to open a folder", cmd = "core:open-folder" }, + { fmt = "%s to change project folder", cmd = "core:open-folder" }, } th = style.font:get_height() - y = y + (dh - th * 2 - style.padding.y) / 2 + y = y + (dh - (th + style.padding.y) * #lines) / 2 local w = 0 for _, line in ipairs(lines) do local text = string.format(line.fmt, keymap.get_binding(line.cmd)) From 33109e6110a22695d2203dda339695ba723ebc00 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Wed, 9 Dec 2020 15:41:25 +0100 Subject: [PATCH 16/24] Fix responsiveness problem of open-folder command --- data/core/init.lua | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/data/core/init.lua b/data/core/init.lua index 7976578e..43ee47f9 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -51,9 +51,8 @@ function core.open_folder_project(dirname) core.root_view:close_all_docviews() add_project_to_recents(dirname) save_projects() - core.project_files = {} - core.redraw = true core.switch_project = dirname + core.threads[core.project_scan_thread_id].wake = 0 end local function project_scan_thread() @@ -239,7 +238,7 @@ function core.init() 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) @@ -358,6 +357,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 @@ -585,6 +585,7 @@ 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() @@ -596,16 +597,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 From 6409b67ea2d36b8572ebefb764bf88dd0d18ea66 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Thu, 10 Dec 2020 12:44:01 +0100 Subject: [PATCH 17/24] Add core:restart function to restart the editor --- data/core/commands/core.lua | 4 ++++ data/core/init.lua | 9 +++++++++ doc/usage.md | 7 +++++++ src/main.c | 19 +++++++++++++++---- 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/data/core/commands/core.lua b/data/core/commands/core.lua index c6ef6743..701ffd0b 100644 --- a/data/core/commands/core.lua +++ b/data/core/commands/core.lua @@ -12,6 +12,10 @@ command.add(nil, { core.quit() end, + ["core:restart"] = function() + core.restart() + end, + ["core:force-quit"] = function() core.quit(true) end, diff --git a/data/core/init.lua b/data/core/init.lua index 43ee47f9..c3e40e53 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -229,6 +229,7 @@ function core.init() core.project_files = {} core.redraw = true core.visited_files = {} + core.restart_request = false core.root_view = RootView() core.command_view = CommandView() @@ -289,6 +290,13 @@ function core.quit(force) end +function core.restart() + if core.confirm_close_all() then + core.restart_request = true + end +end + + function core.load_plugins() local no_errors = true local files = system.list_dir(DATADIR .. "/plugins") @@ -590,6 +598,7 @@ function core.run() 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 diff --git a/doc/usage.md b/doc/usage.md index 3b536cc5..6878a8e4 100644 --- a/doc/usage.md +++ b/doc/usage.md @@ -132,6 +132,13 @@ then be loaded manually as needed by using the `require` function. Plugins can be downloaded from the [plugins repository](https://github.com/rxi/lite-plugins). +## Restarting the editor + +If you modifies the user configuration file or some of the Lua implementation files you may +restart the editor using the command "Core: Restart". +All the application will be restarting by keeping the window that is already used. + + ## Color Themes Colors themes in lite are lua modules which overwrite the color fields of lite's `core.style` module. Color themes should be placed in the `data/user/colors` diff --git a/src/main.c b/src/main.c index 1704a6f1..010f16a5 100644 --- a/src/main.c +++ b/src/main.c @@ -89,8 +89,9 @@ int main(int argc, char **argv) { init_window_icon(); ren_init(window); - - lua_State *L = luaL_newstate(); + lua_State *L; +init_lua: + L = luaL_newstate(); luaL_openlibs(L); api_load_libs(L); @@ -117,7 +118,7 @@ int main(int argc, char **argv) { lua_setglobal(L, "EXEFILE"); - (void) luaL_dostring(L, + const char *init_lite_code = \ "local core\n" "xpcall(function()\n" " SCALE = tonumber(os.getenv(\"LITE_SCALE\")) or SCALE\n" @@ -153,8 +154,18 @@ int main(int argc, char **argv) { " pcall(core.on_error, err)\n" " end\n" " os.exit(1)\n" - "end)"); + "end)\n" + "return core and core.restart_request\n"; + if (luaL_loadstring(L, init_lite_code)) { + fprintf(stderr, "internal error when starting the application\n"); + exit(1); + } + lua_pcall(L, 0, 1, 0); + if (lua_toboolean(L, -1)) { + lua_close(L); + goto init_lua; + } lua_close(L); SDL_DestroyWindow(window); From 9114148b453af42795f6f409990023d430a964f8 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Thu, 10 Dec 2020 17:56:53 +0100 Subject: [PATCH 18/24] Automatically reload style when saving the project user module --- data/core/commands/core.lua | 27 ++++++++++++++++++++++--- data/core/init.lua | 39 ++++++++++++++++++++++++------------- data/core/keymap.lua | 3 ++- data/core/rootview.lua | 3 ++- data/core/style.lua | 6 ++++++ data/user/init.lua | 13 ++++++++++++- 6 files changed, 72 insertions(+), 19 deletions(-) diff --git a/data/core/commands/core.lua b/data/core/commands/core.lua index 701ffd0b..cf904ccf 100644 --- a/data/core/commands/core.lua +++ b/data/core/commands/core.lua @@ -102,7 +102,15 @@ command.add(nil, { end, ["core:open-user-module"] = function() - core.root_view:open_doc(core.open_doc(USERDIR .. "/init.lua")) + local user_module_doc = core.open_doc(USERDIR .. "/init.lua") + if not user_module_doc then return end + local doc_save = user_module_doc.save + user_module_doc.save = function(self) + doc_save(self) + core.reload_module("core.style") + core.load_user_directory() + end + core.root_view:open_doc(user_module_doc) end, ["core:open-project-module"] = function() @@ -116,8 +124,8 @@ command.add(nil, { end end, - ["core:open-folder"] = function() - core.command_view:enter("Open Folder", function(text) + ["core:change-project-folder"] = function() + core.command_view:enter("Change Project Folder", function(text) 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) @@ -130,4 +138,17 @@ command.add(nil, { return text == "" and core.recent_projects or common.dir_path_suggest(text) end) end, + + ["core:open-project-folder"] = function() + core.command_view:enter("Open Project", function(text) + 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 + system.exec(string.format("%q %q", EXEFILE, text)) + end, function(text) + return text == "" and core.recent_projects or common.dir_path_suggest(text) + end) + end, }) diff --git a/data/core/init.lua b/data/core/init.lua index c3e40e53..0f20576f 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -166,33 +166,46 @@ 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 use save it 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 ]]) init_file:close() end -local function load_user_directory() - local init_filename = USERDIR .. "/init.lua" - local stat_info_dir = system.get_file_info(USERDIR) - if not stat_info_dir then - create_user_directory() - end - local stat_info_file = system.get_file_info(init_filename) - if not stat_info_file then - 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 @@ -242,7 +255,7 @@ function core.init() 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("(.*)[/\\\\](.*)") diff --git a/data/core/keymap.lua b/data/core/keymap.lua index 5c715def..3798d4da 100644 --- a/data/core/keymap.lua +++ b/data/core/keymap.lua @@ -88,6 +88,8 @@ keymap.add { ["ctrl+p"] = "core:find-file", ["ctrl+o"] = "core:open-file", ["ctrl+n"] = "core:new-doc", + ["ctrl+shift+c"] = "core:change-project-folder", + ["ctrl+shift+o"] = "core:open-project-folder", ["alt+return"] = "core:toggle-fullscreen", ["alt+shift+j"] = "root:split-left", @@ -181,7 +183,6 @@ keymap.add { ["ctrl+shift+end"] = "doc:select-to-end-of-doc", ["shift+pageup"] = "doc:select-to-previous-page", ["shift+pagedown"] = "doc:select-to-next-page", - ["ctrl+shift+o"] = "core:open-folder", } return keymap diff --git a/data/core/rootview.lua b/data/core/rootview.lua index 834e96c4..f311b11d 100644 --- a/data/core/rootview.lua +++ b/data/core/rootview.lua @@ -19,7 +19,8 @@ local function draw_text(x, y, color) local lines = { { fmt = "%s to run a command", cmd = "core:find-command" }, { fmt = "%s to open a file from the project", cmd = "core:find-file" }, - { fmt = "%s to change project folder", cmd = "core:open-folder" }, + { fmt = "%s to change project folder", cmd = "core:change-project-folder" }, + { fmt = "%s to open a project folder", cmd = "core:open-project-folder" }, } th = style.font:get_height() y = y + (dh - (th + style.padding.y) * #lines) / 2 diff --git a/data/core/style.lua b/data/core/style.lua index e8567de5..e87a8ff6 100644 --- a/data/core/style.lua +++ b/data/core/style.lua @@ -53,4 +53,10 @@ style.syntax["string"] = { common.color "#f7c95c" } style.syntax["operator"] = { common.color "#93DDFA" } style.syntax["function"] = { common.color "#93DDFA" } + +style.load = function(module_name) + package.loaded[module_name] = nil + require(module_name) +end + return style diff --git a/data/user/init.lua b/data/user/init.lua index bb7f4b3f..b72bab26 100644 --- a/data/user/init.lua +++ b/data/user/init.lua @@ -1,13 +1,24 @@ -- put user settings here -- this module will be loaded after everything else when the application starts +-- it will be automatically reloaded when use save it 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 + From a41754b382fef8538a2497a6a9ae1febd235c46d Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Fri, 11 Dec 2020 14:36:32 +0100 Subject: [PATCH 19/24] Fix font hinting when using subpixel rendering Ensure we set the font's size with freetype to the intended size so that hinting works as expected and perform subpixel scaling using affine matrix coefficient. --- lib/font_renderer/font_renderer_alpha.h | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/lib/font_renderer/font_renderer_alpha.h b/lib/font_renderer/font_renderer_alpha.h index 5dcf5e37..53304688 100644 --- a/lib/font_renderer/font_renderer_alpha.h +++ b/lib/font_renderer/font_renderer_alpha.h @@ -81,20 +81,17 @@ public: void set_font_height(double height) { const double scale_x = (m_prescale_x ? 100.0 : 1.0); m_feng.height(height); - if (m_subpixel) { - const int subpixel_scale = 3; - m_feng.width(height * scale_x * subpixel_scale); - } else { - m_feng.width(height * scale_x); - } + m_feng.width(height * scale_x); } template void draw_codepoint(Rasterizer& ras, Scanline& sl, RenSolid& ren_solid, const color_type color, - int codepoint, double& x, double& y, int subpixel_scale) + int codepoint, double& x, double& y, const int subpixel_scale) { const double scale_x = (m_prescale_x ? 100.0 : 1.0); + // Coefficient to scale back the glyph to the final scale. + const double cx_inv_scale = subpixel_scale / scale_x; // Represent the delta in x scaled by scale_x. double x_delta = 0; @@ -114,15 +111,15 @@ public: double ty = m_hinting ? floor(y + 0.5) : y; ras.reset(); m_mtx.reset(); - m_mtx *= agg::trans_affine_scaling(1.0 / scale_x, 1); - m_mtx *= agg::trans_affine_translation(start_x + x_delta / scale_x, ty); + m_mtx *= agg::trans_affine_scaling(cx_inv_scale, 1); + m_mtx *= agg::trans_affine_translation(start_x + cx_inv_scale * x_delta, ty); ras.add_path(m_trans); ren_solid.color(color); agg::render_scanlines(ras, sl, ren_solid); } y += glyph->advance_y; - x += (x_delta + glyph->advance_x) / scale_x; + x += cx_inv_scale * (x_delta + glyph->advance_x); } } @@ -135,7 +132,7 @@ public: void render_codepoint(agg::rendering_buffer& ren_buf, const color_type text_color, double& x, double& y, - int codepoint, int subpixel_scale) + int codepoint, const int subpixel_scale) { if (!m_font_loaded) { return; From 2373c63a0bcae7cf56d1f9e8008fb03f2757a7a6 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Fri, 11 Dec 2020 14:49:03 +0100 Subject: [PATCH 20/24] Complete the initial user configuration file --- data/core/init.lua | 10 +++++++++- data/user/init.lua | 11 +++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/data/core/init.lua b/data/core/init.lua index 0f20576f..59601d2e 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -166,7 +166,7 @@ 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 use save it +-- it will be automatically reloaded when saved local keymap = require "core.keymap" local config = require "core.config" @@ -187,6 +187,14 @@ local style = require "core.style" -- 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 diff --git a/data/user/init.lua b/data/user/init.lua index b72bab26..afaa6108 100644 --- a/data/user/init.lua +++ b/data/user/init.lua @@ -1,6 +1,6 @@ -- put user settings here -- this module will be loaded after everything else when the application starts --- it will be automatically reloaded when use save it +-- it will be automatically reloaded when saved local keymap = require "core.keymap" local config = require "core.config" @@ -21,4 +21,11 @@ local style = require "core.style" -- 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 From b396556df413e36fd93875bf6399c214580c953b Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Fri, 11 Dec 2020 15:14:13 +0100 Subject: [PATCH 21/24] Print warning about the portable option based on OS --- build-packages.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build-packages.sh b/build-packages.sh index b9a65d64..5ecfe7f1 100755 --- a/build-packages.sh +++ b/build-packages.sh @@ -62,6 +62,7 @@ lite_build_package_windows () { local bindir="$pdir" local datadir="$pdir/data" else + echo "WARNING: using non portable option on unix-like system" local bindir="$pdir/bin" local datadir="$pdir/share/lite-xl" fi @@ -119,6 +120,7 @@ lite_build_package_linux () { local os="linux" local pdir=".package-build/lite-xl" if [ $portable == "true" ]; then + echo "WARNING: using portable option on unix-like system" local bindir="$pdir" local datadir="$pdir/data" else From 7cf37999dfe0f97f8964f8c248bc76680c4df864 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Fri, 11 Dec 2020 15:14:57 +0100 Subject: [PATCH 22/24] Include rxi/lite-colors when building a package --- build-packages.sh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/build-packages.sh b/build-packages.sh index 5ecfe7f1..b7cccfa6 100755 --- a/build-packages.sh +++ b/build-packages.sh @@ -71,6 +71,9 @@ lite_build_package_windows () { for module_name in core plugins colors fonts; do copy_directory_from_repo --strip-components=1 "data/$module_name" "$datadir" done + for module_name in plugins colors; do + cp -r "$build/third/data/$module_name" "$datadir" + done cp "$build/src/lite.exe" "$bindir" strip --strip-all "$bindir/lite.exe" pushd ".package-build" @@ -101,6 +104,9 @@ lite_build_package_macosx () { for module_name in core plugins colors fonts; do copy_directory_from_repo --strip-components=1 "data/$module_name" "$datadir" done + for module_name in plugins colors; do + cp -r "$build/third/data/$module_name" "$datadir" + done cp "$build/src/lite" "$bindir" strip "$bindir/lite" pushd ".package-build" @@ -132,6 +138,9 @@ lite_build_package_linux () { for module_name in core plugins colors fonts; do copy_directory_from_repo --strip-components=1 "data/$module_name" "$datadir" done + for module_name in plugins colors; do + cp -r "$build/third/data/$module_name" "$datadir" + done cp "$build/src/lite" "$bindir" strip "$bindir/lite" pushd ".package-build" @@ -156,6 +165,15 @@ lite_build_package () { fi } +lite_copy_third_party_modules () { + local build="$1" + curl --insecure -L "https://github.com/rxi/lite-colors/archive/master.zip" -o "$build/rxi-lite-colors.zip" + mkdir -p "$build/third/data/colors" "$build/third/data/plugins" + unzip "$build/rxi-lite-colors.zip" -d "$build" + mv "$build/lite-colors-master/colors" "$build/third/data" + rm -fr "$build/lite-colors-master" +} + if [[ -z "$1" || -z "$2" ]]; then echo "usage: $0 [options] " exit 1 @@ -186,5 +204,6 @@ if [ -z ${pgo+set} ]; then else lite_build_pgo "$portable" "$build_dir" fi +lite_copy_third_party_modules "$build_dir" lite_build_package "$portable" "$build_dir" "$version" "$arch" From 40ac8993605d45ae68157a6ee70d2550806a4f72 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Sat, 12 Dec 2020 00:05:11 +0100 Subject: [PATCH 23/24] Restore core.quit and core.temp_filename to be compatible with Lite --- data/core/init.lua | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/data/core/init.lua b/data/core/init.lua index 59601d2e..e0ec3289 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -303,11 +303,33 @@ function core.confirm_close_all() 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 + +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 core.confirm_close_all() then + if force then + delete_temp_files() os.exit() end + if core.confirm_close_all() then + core.quit(true) + end end From 3b30bfa18b615ba1f0fc6e7d26d860350c8ff12d Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Sat, 12 Dec 2020 20:26:27 +0100 Subject: [PATCH 24/24] Improve left/right scrolling behavior for DocView With the new behavior when moving right and triggering a scroll in the right direction a subsequent movement left do not longer triggers a scrolling to the left. The scrolling to the left happens only when needed for the visibility of the current position. In other terms with the old behavior the scrolling was purely a function of the position and was adjusted even when not strictly needed for the visibility of the cursor. Now the scrolling is no longer a pure function of the position but it has a "memory" behavior. The scrolling will be adjusted only if needed to accommodate the position of the cursor. Reduce also the width of the margin when the scrolling will be triggered and calculate as a function of the font character width. With the modification now Lite behaves like the other editors. In addition the selection of text with the mouse is much more easy when a scrolling of the line is needed. --- data/core/docview.lua | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/data/core/docview.lua b/data/core/docview.lua index 73191c23..4bffd56f 100644 --- a/data/core/docview.lua +++ b/data/core/docview.lua @@ -187,8 +187,14 @@ function DocView:scroll_to_make_visible(line, col) self.scroll.to.y = math.max(self.scroll.to.y, max) local gw = self:get_gutter_width() local xoffset = self:get_col_x_offset(line, col) - local max = xoffset - self.size.x + gw + self.size.x / 5 - self.scroll.to.x = math.max(0, max) + local xmargin = 3 * self:get_font():get_width(' ') + local xsup = xoffset + gw + xmargin + local xinf = xoffset - xmargin + if xsup > self.scroll.x + self.size.x then + self.scroll.to.x = xsup - self.size.x + elseif xinf < self.scroll.x then + self.scroll.to.x = math.max(0, xinf) + end end