Implement new `View` saving mechanism

This commit is contained in:
Guldoman 2021-08-29 04:54:08 +02:00
parent b4ed485ce9
commit ef0c093a61
No known key found for this signature in database
GPG Key ID: C08A498EC7F1AFDD
3 changed files with 66 additions and 45 deletions

View File

@ -7,10 +7,47 @@ local translate = require "core.doc.translate"
local View = require "core.view" local View = require "core.view"
local DocView = View:extend() local DocView = View:extend("DocView")
DocView.context = "session" DocView.context = "session"
function DocView:get_content()
return {
active = (core.active_view == self),
filename = self.doc.filename,
selection = { self.doc:get_selection() },
scroll = { x = self.scroll.to.x, y = self.scroll.to.y },
text = not self.doc.filename and self.doc:get_text(1, 1, math.huge, math.huge)
}
end
function DocView.from_content(t)
local dv
if not t.filename then
-- document not associated to a file
dv = DocView(core.open_doc())
if t.text then dv.doc:insert(1, 1, t.text) end
else
-- we have a filename, try to read the file
local ok, doc = pcall(core.open_doc, t.filename)
if ok then
dv = DocView(doc)
end
end
-- doc view "dv" can be nil here if the filename associated to the document
-- cannot be read.
if dv and dv.doc then
dv.doc:set_selection(table.unpack(t.selection))
dv.last_line, dv.last_col = dv.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
end
return dv
end
local function move_to_line_offset(dv, line, col, offset) local function move_to_line_offset(dv, line, col, offset)
local xo = dv.last_x_offset local xo = dv.last_x_offset
if xo.line ~= line or xo.col ~= col then if xo.line ~= line or xo.col ~= col then

View File

@ -7,6 +7,7 @@ local Object = require "core.object"
local View = Object:extend() local View = Object:extend()
-- Override how objects are created. This allows for automatic Views registration -- Override how objects are created. This allows for automatic Views registration
function View:extend(register_name) function View:extend(register_name)
local new_class = View.super.extend(self) local new_class = View.super.extend(self)
@ -17,11 +18,26 @@ function View:extend(register_name)
return new_class return new_class
end end
-- context can be "application" or "session". The instance of objects -- context can be "application" or "session". The instance of objects
-- with context "session" will be closed when a project session is -- with context "session" will be closed when a project session is
-- terminated. The context "application" is for functional UI elements. -- terminated. The context "application" is for functional UI elements.
View.context = "application" View.context = "application"
-- Returns a table that contains what shall be saved in a workspace file.
function View:get_content()
return { }
end
-- Returns a View created from the specified parameter `content`, which contains
-- what was returned from `View:get_content`.
function View.from_content(content)
return View()
end
function View:new() function View:new()
self.position = { x = 0, y = 0 } self.position = { x = 0, y = 0 }
self.size = { x = 0, y = 0 } self.size = { x = 0, y = 0 }
@ -30,6 +46,7 @@ function View:new()
self.scrollable = false self.scrollable = false
end end
function View:move_towards(t, k, dest, rate) function View:move_towards(t, k, dest, rate)
if type(t) ~= "table" then if type(t) ~= "table" then
return self:move_towards(self, t, k, dest, rate) return self:move_towards(self, t, k, dest, rate)

View File

@ -75,55 +75,22 @@ end
local function save_view(view) local function save_view(view)
local mt = getmetatable(view) if view.context ~= "session" then return end -- only save `session` View classes
if mt == DocView then if not view.registered_name then return end -- View didn't register
return { if not view.get_content then return end
type = "doc", local content = view:get_content()
active = (core.active_view == view), content.type = view.registered_name
filename = view.doc.filename, return content
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
if mt == LogView then return 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 end
local function load_view(t) local function load_view(t)
if t.type == "doc" then local class = core.get_registered_view(t.type)
local dv if class then
if not t.filename then t.type = nil
-- document not associated to a file return class.from_content and class.from_content(t)
dv = DocView(core.open_doc())
if t.text then dv.doc:insert(1, 1, t.text) end
else
-- we have a filename, try to read the file
local ok, doc = pcall(core.open_doc, t.filename)
if ok then
dv = DocView(doc)
end
end
-- doc view "dv" can be nil here if the filename associated to the document
-- cannot be read.
if dv and dv.doc then
dv.doc:set_selection(table.unpack(t.selection))
dv.last_line, dv.last_col = dv.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
end
return dv
end end
return require(t.module)() return require(t.module)() -- FIXME: is this needed? If a class is not registered, it should not be loaded
end end