aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/ext/menu.lua30
-rw-r--r--core/file_io.lua145
2 files changed, 161 insertions, 14 deletions
diff --git a/core/ext/menu.lua b/core/ext/menu.lua
index c78b36ed..6549cbfd 100644
--- a/core/ext/menu.lua
+++ b/core/ext/menu.lua
@@ -361,28 +361,30 @@ local actions = {
[ID.LOAD_SESSION] = {
function()
local utf8_filename =
- cocoa_dialog('fileselect', {
- title = l.MENU_LOAD_SESSION_TITLE,
- ['with-directory'] = (textadept.session_file or ''):match('.+[/\\]'),
- ['with-file'] = (textadept.session_file or ''):match('[^/\\]+$'),
- ['no-newline'] = true
- })
+ t.dialog('fileselect',
+ '--title', l.MENU_LOAD_SESSION_TITLE,
+ '--with-directory',
+ (textadept.session_file or ''):match('.+[/\\]') or '',
+ '--with-file',
+ (textadept.session_file or ''):match('[^/\\]+$') or '',
+ '--no-newline')
if #utf8_filename > 0 then
- _m.textadept.session.load(t.iconv(utf8_filename, _CHARSET, 'UTF-8'))
+ t.io.load_session(t.iconv(utf8_filename, _CHARSET, 'UTF-8'))
end
end
},
[ID.SAVE_SESSION] = {
function()
local utf8_filename =
- cocoa_dialog('filesave', {
- title = l.MENU_SAVE_SESSION_TITLE,
- ['with-directory'] = (textadept.session_file or ''):match('.+[/\\]'),
- ['with-file'] = (textadept.session_file or ''):match('[^/\\]+$'),
- ['no-newline'] = true
- })
+ t.dialog('filesave',
+ '--title', l.MENU_SAVE_SESSION_TITLE,
+ '--with-directory',
+ (textadept.session_file or ''):match('.+[/\\]') or '',
+ '--with-file',
+ (textadept.session_file or ''):match('[^/\\]+$') or '',
+ '--no-newline')
if #utf8_filename > 0 then
- _m.textadept.session.save(t.iconv(utf8_filename, _CHARSET, 'UTF-8'))
+ t.io.save_session(t.iconv(utf8_filename, _CHARSET, 'UTF-8'))
end
end
},
diff --git a/core/file_io.lua b/core/file_io.lua
index 4634f8f6..bf0809cd 100644
--- a/core/file_io.lua
+++ b/core/file_io.lua
@@ -311,6 +311,151 @@ function close_all()
end
---
+-- Loads a Textadept session file.
+-- Textadept restores split views, opened buffers, cursor information, and
+-- project manager details.
+-- @param filename The absolute path to the session file to load. Defaults to
+-- $HOME/.textadept/session if not specified.
+-- @param only_pm Flag indicating whether or not to load only the Project
+-- Manager session settings. Defaults to false.
+-- @return true if the session file was opened and read; false otherwise.
+-- @usage textadept.io.load_session(filename)
+function load_session(filename, only_pm)
+ local ta_session = _USERHOME..'/session'
+ local f = io.open(filename or ta_session, 'rb')
+ if not f then return false end
+ local current_view, splits = 1, { [0] = {} }
+ for line in f:lines() do
+ if not only_pm then
+ if line:find('^buffer:') then
+ local anchor, current_pos, first_visible_line, filename =
+ line:match('^buffer: (%d+) (%d+) (%d+) (.+)$')
+ if not filename:find('^%[.+%]$') then
+ textadept.io.open(filename or '', 'rb')
+ else
+ textadept.new_buffer()
+ buffer._type = filename
+ end
+ -- Restore saved buffer selection and view.
+ local anchor = tonumber(anchor) or 0
+ local current_pos = tonumber(current_pos) or 0
+ local first_visible_line = tonumber(first_visible_line) or 0
+ local buffer = buffer
+ buffer._anchor, buffer._current_pos = anchor, current_pos
+ buffer._first_visible_line = first_visible_line
+ buffer:line_scroll(0,
+ buffer:visible_from_doc_line(first_visible_line))
+ buffer:set_sel(anchor, current_pos)
+ elseif line:find('^%s*split%d:') then
+ local level, num, type, size =
+ line:match('^(%s*)split(%d): (%S+) (%d+)')
+ local view = splits[#level] and splits[#level][tonumber(num)] or view
+ splits[#level + 1] = { view:split(type == 'true') }
+ splits[#level + 1][1].size = tonumber(size) -- could be 1 or 2
+ elseif line:find('^%s*view%d:') then
+ local level, num, buf_idx = line:match('^(%s*)view(%d): (%d+)$')
+ local view = splits[#level][tonumber(num)] or view
+ buf_idx = tonumber(buf_idx)
+ if buf_idx > #textadept.buffers then buf_idx = #textadept.buffers end
+ view:goto_buffer(buf_idx)
+ elseif line:find('^current_view:') then
+ local view_idx = line:match('^current_view: (%d+)')
+ current_view = tonumber(view_idx) or 1
+ end
+ end
+ if line:find('^size:') then
+ local width, height = line:match('^size: (%d+) (%d+)$')
+ if width and height then textadept.size = { width, height } end
+ elseif line:find('^pm:') then
+ local width, cursor, text = line:match('^pm: (%d+) ([%d:]+) (.+)$')
+ textadept.pm.width = width or 0
+ textadept.pm.entry_text = text or ''
+ textadept.pm.activate()
+ if cursor then textadept.pm.cursor = cursor end
+ end
+ end
+ f:close()
+ textadept.views[current_view]:focus()
+ textadept.session_file = filename or ta_session
+ return true
+end
+
+---
+-- Saves a Textadept session to a file.
+-- Saves split views, opened buffers, cursor information, and project manager
+-- details.
+-- @param filename The absolute path to the session file to save. Defaults to
+-- either the current session file or $HOME/.textadept/session if not
+-- specified.
+-- @usage textadept.io.save_session(filename)
+function save_session(filename)
+ local session = {}
+ local buffer_line = "buffer: %d %d %d %s" -- anchor, cursor, line, filename
+ local split_line = "%ssplit%d: %s %d" -- level, number, type, size
+ local view_line = "%sview%d: %d" -- level, number, doc index
+ -- Write out opened buffers.
+ for _, buffer in ipairs(textadept.buffers) do
+ local filename = buffer.filename or buffer._type
+ if filename then
+ local current = buffer.doc_pointer == textadept.focused_doc_pointer
+ local anchor = current and 'anchor' or '_anchor'
+ local current_pos = current and 'current_pos' or '_current_pos'
+ local first_visible_line =
+ current and 'first_visible_line' or '_first_visible_line'
+ session[#session + 1] =
+ buffer_line:format(buffer[anchor] or 0, buffer[current_pos] or 0,
+ buffer[first_visible_line] or 0, filename)
+ end
+ end
+ -- Write out split views.
+ local function write_split(split, level, number)
+ local c1, c2 = split[1], split[2]
+ local vertical, size = tostring(split.vertical), split.size
+ local spaces = (' '):rep(level)
+ session[#session + 1] = split_line:format(spaces, number, vertical, size)
+ spaces = (' '):rep(level + 1)
+ if type(c1) == 'table' then
+ write_split(c1, level + 1, 1)
+ else
+ session[#session + 1] = view_line:format(spaces, 1, c1)
+ end
+ if type(c2) == 'table' then
+ write_split(c2, level + 1, 2)
+ else
+ session[#session + 1] = view_line:format(spaces, 2, c2)
+ end
+ end
+ local splits = textadept.get_split_table()
+ if type(splits) == 'table' then
+ write_split(splits, 0, 0)
+ else
+ session[#session + 1] = view_line:format('', 1, splits)
+ end
+ -- Write out the current focused view.
+ local current_view = view
+ for index, view in ipairs(textadept.views) do
+ if view == current_view then
+ current_view = index
+ break
+ end
+ end
+ session[#session + 1] = ("current_view: %d"):format(current_view)
+ -- Write out other things.
+ local size = textadept.size
+ session[#session + 1] = ("size: %d %d"):format(size[1], size[2])
+ local pm = textadept.pm
+ session[#session + 1] =
+ ("pm: %d %s %s"):format(pm.width, pm.cursor or '0', pm.entry_text)
+ -- Write the session.
+ local ta_session = _USERHOME..'/session'
+ local f = io.open(filename or textadept.session_file or ta_session, 'wb')
+ if f then
+ f:write(table.concat(session, '\n'))
+ f:close()
+ end
+end
+
+---
-- Reads an API file.
-- Each non-empty line in the API file is structured as follows:
-- identifier (parameters) description