aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuild-packages.sh21
-rw-r--r--data/core/commands/core.lua42
-rw-r--r--data/core/common.lua15
-rw-r--r--data/core/docview.lua10
-rw-r--r--data/core/init.lua171
-rw-r--r--data/core/keymap.lua2
-rw-r--r--data/core/rootview.lua62
-rw-r--r--data/core/style.lua6
-rw-r--r--data/user/init.lua20
-rw-r--r--doc/usage.md7
-rw-r--r--lib/font_renderer/font_renderer_alpha.h19
-rwxr-xr-xrun-local6
-rw-r--r--src/main.c19
13 files changed, 334 insertions, 66 deletions
diff --git a/build-packages.sh b/build-packages.sh
index b9a65d64..b7cccfa6 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
@@ -70,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"
@@ -100,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"
@@ -119,6 +126,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
@@ -130,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"
@@ -154,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] <version> <arch>"
exit 1
@@ -184,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"
diff --git a/data/core/commands/core.lua b/data/core/commands/core.lua
index a4cf4d7d..cf904ccf 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,
@@ -98,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()
@@ -111,4 +123,32 @@ command.add(nil, {
doc:save(filename)
end
end,
+
+ ["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)
+ 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,
+
+ ["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/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/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
diff --git a/data/core/init.lua b/data/core/init.lua
index e50259b4..19852233 100644
--- a/data/core/init.lua
+++ b/data/core/init.lua
@@ -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
diff --git a/data/core/keymap.lua b/data/core/keymap.lua
index 4d48ed4e..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",
diff --git a/data/core/rootview.lua b/data/core/rootview.lua
index 51150079..f311b11d 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"
@@ -18,9 +19,11 @@ 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:change-project-folder" },
+ { fmt = "%s to open a project folder", cmd = "core:open-project-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))
@@ -376,6 +379,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.is_primary_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()
@@ -396,20 +434,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_primary_view(node)
+ if node.is_primary_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_primary_view(node.a) or get_primary_view(node.b)
end
end
-function RootView:get_document_view()
- local node = get_node_unlocked(self.root_node)
+function RootView:get_primary_view()
+ local node = get_primary_view(self.root_node)
if node then
return node.views[1]
end
@@ -418,8 +453,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_primary_view()
+ assert(default_view, "internal error: cannot find original document node.")
core.set_active_view(default_view)
node = self:get_active_node()
end
@@ -437,6 +472,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/core/style.lua b/data/core/style.lua
index 1084540d..45492a6d 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..afaa6108 100644
--- a/data/user/init.lua
+++ b/data/user/init.lua
@@ -1,13 +1,31 @@
-- 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
diff --git a/doc/usage.md b/doc/usage.md
index 5ea4e28e..7efcb4ff 100644
--- a/doc/usage.md
+++ b/doc/usage.md
@@ -140,6 +140,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.
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<class Rasterizer, class Scanline, class RenSolid>
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;
diff --git a/run-local b/run-local
index 17284818..1bf3cc2b 100755
--- a/run-local
+++ b/run-local
@@ -9,6 +9,8 @@ else
datadir="$rundir/share/lite-xl"
fi
+userdir="$(realpath "$rundir")"
+
if [ "$#" -lt 1 ]; then
echo "usage: $0 <build-dir>"
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"
+HOME="$userdir" USERPROFILE="$userdir" exec "$bindir/lite" "${@:2}"
diff --git a/src/main.c b/src/main.c
index 770f9bfb..0bdd660d 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);