diff options
author | 2009-07-12 12:59:49 -0400 | |
---|---|---|
committer | 2009-07-12 12:59:49 -0400 | |
commit | 16782a2ab5e158f418581b74452415cd561a5046 (patch) | |
tree | ff571846e5db078990f57825313abc1747fa82e7 | |
parent | 070f12d6eef343179335d12686c24f8055c2514d (diff) | |
download | textadept-16782a2ab5e158f418581b74452415cd561a5046.tar.gz textadept-16782a2ab5e158f418581b74452415cd561a5046.zip |
Moved session support from core/file_io.lua to a Textadept module.
-rw-r--r-- | core/events.lua | 3 | ||||
-rw-r--r-- | core/ext/key_commands.lua | 10 | ||||
-rw-r--r-- | core/ext/menu.lua | 4 | ||||
-rw-r--r-- | core/file_io.lua | 147 | ||||
-rw-r--r-- | init.lua | 4 | ||||
-rw-r--r-- | modules/textadept/init.lua | 1 | ||||
-rw-r--r-- | modules/textadept/session.lua | 156 |
7 files changed, 169 insertions, 156 deletions
diff --git a/core/events.lua b/core/events.lua index 25dfb25d..989877c0 100644 --- a/core/events.lua +++ b/core/events.lua @@ -456,7 +456,7 @@ add_handler('view_after_switch', end) add_handler('quit', - function() -- prompts for confirmation if any buffers are dirty; saves session + function() -- prompts for confirmation if any buffers are dirty local any = false local list = {} for _, buffer in ipairs(textadept.buffers) do @@ -474,7 +474,6 @@ add_handler('quit', ['no-newline'] = true }) ~= '2' then return false end end - textadept.io.save_session() return true end) diff --git a/core/ext/key_commands.lua b/core/ext/key_commands.lua index 265b5080..370aa1e3 100644 --- a/core/ext/key_commands.lua +++ b/core/ext/key_commands.lua @@ -33,6 +33,7 @@ if not MAC then keys.ct = {} -- Textadept command chain -- File + local m_session = _m.textadept.session keys.cn = { t.new_buffer } keys.co = { t.io.open } -- TODO: { 'reload', b } @@ -40,8 +41,8 @@ if not MAC then keys.css = { 'save_as', b } keys.cw = { 'close', b } keys.csw = { t.io.close_all } - -- TODO: { t.io.load_session } after prompting with open dialog - -- TODO: { t.io.save_session } after prompting with save dialog + -- TODO: { m_session.load } after prompting with open dialog + -- TODO: { m_session.save } after prompting with save dialog keys.aq = { t.quit } -- Edit @@ -214,6 +215,7 @@ else keys.at = {} -- Textadept command chain -- File + local m_session = _m.textadept.session keys.an = { t.new_buffer } keys.ao = { t.io.open } -- TODO: { 'reload', b } @@ -221,8 +223,8 @@ else keys.sas = { 'save_as', b } keys.aw = { 'close', b } keys.saw = { t.io.close_all } - -- TODO: { t.io.load_session } after prompting with open dialog - -- TODO: { t.io.save_session } after prompting with save dialog + -- TODO: { m_session.load } after prompting with open dialog + -- TODO: { m_session.save } after prompting with save dialog keys.aq = { t.quit } -- Edit diff --git a/core/ext/menu.lua b/core/ext/menu.lua index 654f3ba5..c78b36ed 100644 --- a/core/ext/menu.lua +++ b/core/ext/menu.lua @@ -368,7 +368,7 @@ local actions = { ['no-newline'] = true }) if #utf8_filename > 0 then - t.io.load_session(t.iconv(utf8_filename, _CHARSET, 'UTF-8')) + _m.textadept.session.load(t.iconv(utf8_filename, _CHARSET, 'UTF-8')) end end }, @@ -382,7 +382,7 @@ local actions = { ['no-newline'] = true }) if #utf8_filename > 0 then - t.io.save_session(t.iconv(utf8_filename, _CHARSET, 'UTF-8')) + _m.textadept.session.save(t.iconv(utf8_filename, _CHARSET, 'UTF-8')) end end }, diff --git a/core/file_io.lua b/core/file_io.lua index 859e52c6..2052da73 100644 --- a/core/file_io.lua +++ b/core/file_io.lua @@ -5,7 +5,7 @@ local locale = _G.locale --- -- Provides file input/output routines for Textadept. --- Opens and saves files and sessions and reads API files. +-- Opens and saves files and reads API files. -- -- Events (all filenames are encoded in UTF-8): -- file_opened(filename) @@ -309,151 +309,6 @@ 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 '') - 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 @@ -54,7 +54,7 @@ if not RESETTING then table.remove(arg, 1) end if #arg == 0 then - textadept.io.load_session() + _m.textadept.session.load() else local base_dir = arg[0]:match('^.+/') or '' for _, filename in ipairs(arg) do @@ -62,7 +62,7 @@ if not RESETTING then textadept.io.open(filename) end -- read only the Project Manager session settings - if not textadept.io.load_session(nil, true) then + if not _m.textadept.session.load(nil, true) then textadept.pm.entry_text = 'buffers' textadept.pm.activate() end diff --git a/modules/textadept/init.lua b/modules/textadept/init.lua index 535f0089..0d42cfd5 100644 --- a/modules/textadept/init.lua +++ b/modules/textadept/init.lua @@ -10,3 +10,4 @@ require 'textadept.editing' require 'textadept.lsnippets' require 'textadept.mlines' require 'textadept.run' +require 'textadept.session' diff --git a/modules/textadept/session.lua b/modules/textadept/session.lua new file mode 100644 index 00000000..a464da68 --- /dev/null +++ b/modules/textadept/session.lua @@ -0,0 +1,156 @@ +-- Copyright 2007-2009 Mitchell mitchell<att>caladbolg.net. See LICENSE. + +local textadept = _G.textadept +local locale = _G.locale + +--- +-- Session support for the textadept module. +-- There are several option variables used: +-- DEFAULT_SESSION: The path to the default session file. +module('_m.textadept.session', package.seeall) + +local DEFAULT_SESSION = _USERHOME..'/session' + +--- +-- 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 +-- DEFAULT_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 _m.textadept.session.load(filename) +function load(filename, only_pm) + local f = io.open(filename or DEFAULT_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 '') + 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 DEFAULT_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 DEFAULT_SESSION if not specified. +-- @usage _m.textadept.session.save(filename) +function save(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 f = io.open(filename or textadept.session_file or DEFAULT_SESSION, 'wb') + if f then + f:write(table.concat(session, '\n')) + f:close() + end +end + +textadept.events.add_handler('quit', save, 1) |