aboutsummaryrefslogtreecommitdiff
path: root/core/gui.lua
diff options
context:
space:
mode:
Diffstat (limited to 'core/gui.lua')
-rw-r--r--core/gui.lua211
1 files changed, 211 insertions, 0 deletions
diff --git a/core/gui.lua b/core/gui.lua
index 2e184beb..4f4ee670 100644
--- a/core/gui.lua
+++ b/core/gui.lua
@@ -70,3 +70,214 @@ function gui.switch_buffer()
local ok, i = response:match('(%-?%d+)\n(%d+)$')
if ok == '1' then view:goto_buffer(tonumber(i) + 1, true) end
end
+
+local connect = _G.events.connect
+
+connect('view_new',
+ function() -- sets default properties for a Scintilla window
+ local buffer = buffer
+ local c = _SCINTILLA.constants
+
+ -- Allow redefinitions of these Scintilla key commands.
+ local ctrl_keys = {
+ '[', ']', '/', '\\', 'Z', 'Y', 'X', 'C', 'V', 'A', 'L', 'T', 'D', 'U'
+ }
+ local ctrl_shift_keys = { 'L', 'T', 'U' }
+ for _, key in ipairs(ctrl_keys) do
+ buffer:clear_cmd_key(string.byte(key), c.SCMOD_CTRL)
+ end
+ for _, key in ipairs(ctrl_shift_keys) do
+ buffer:clear_cmd_key(string.byte(key), c.SCMOD_CTRL + c.SCMOD_SHIFT)
+ end
+
+ if _THEME and #_THEME > 0 then
+ local ok, err = pcall(dofile, _THEME..'/view.lua')
+ if ok then return end
+ io.stderr:write(err)
+ end
+ end)
+
+local SETDIRECTFUNCTION = _SCINTILLA.properties.direct_function[1]
+local SETDIRECTPOINTER = _SCINTILLA.properties.doc_pointer[2]
+local SETLEXERLANGUAGE = _SCINTILLA.functions.set_lexer_language[1]
+connect('buffer_new',
+ function() -- sets default properties for a Scintilla document
+ local function run()
+ local buffer = buffer
+
+ -- Lexer.
+ buffer:set_lexer_language('lpeg')
+ buffer:private_lexer_call(SETDIRECTFUNCTION, buffer.direct_function)
+ buffer:private_lexer_call(SETDIRECTPOINTER, buffer.direct_pointer)
+ buffer:private_lexer_call(SETLEXERLANGUAGE, 'container')
+ buffer.style_bits = 8
+
+ -- Properties.
+ buffer.property['textadept.home'] = _HOME
+ buffer.property['lexer.lpeg.home'] = _LEXERPATH
+ buffer.property['lexer.lpeg.script'] = _HOME..'/lexers/lexer.lua'
+ if _THEME and #_THEME > 0 then
+ buffer.property['lexer.lpeg.color.theme'] = _THEME..'/lexer.lua'
+ end
+
+ -- Buffer.
+ buffer.code_page = _SCINTILLA.constants.SC_CP_UTF8
+
+ if _THEME and #_THEME > 0 then
+ local ok, err = pcall(dofile, _THEME..'/buffer.lua')
+ if ok then return end
+ io.stderr:write(err)
+ end
+ end
+ -- Normally when an error occurs, a new buffer is created with the error
+ -- message, but if an error occurs here, this event would be called again
+ -- and again, erroring each time resulting in an infinite loop; print error
+ -- to stderr instead.
+ local ok, err = pcall(run)
+ if not ok then io.stderr:write(err) end
+ end)
+
+-- Sets the title of the Textadept window to the buffer's filename.
+-- @param buffer The currently focused buffer.
+local function set_title(buffer)
+ local buffer = buffer
+ local filename = buffer.filename or buffer._type or L('Untitled')
+ local dirty = buffer.dirty and '*' or '-'
+ gui.title = string.format('%s %s Textadept (%s)', filename:match('[^/\\]+$'),
+ dirty, filename)
+end
+
+connect('save_point_reached',
+ function() -- changes Textadept title to show 'clean' buffer
+ buffer.dirty = false
+ set_title(buffer)
+ end)
+
+connect('save_point_left',
+ function() -- changes Textadept title to show 'dirty' buffer
+ buffer.dirty = true
+ set_title(buffer)
+ end)
+
+connect('uri_dropped',
+ function(utf8_uris) -- open uri(s)
+ for utf8_uri in utf8_uris:gmatch('[^\r\n]+') do
+ if utf8_uri:find('^file://') then
+ utf8_uri = utf8_uri:match('^file://([^\r\n]+)')
+ utf8_uri = utf8_uri:gsub('%%(%x%x)',
+ function(hex) return string.char(tonumber(hex, 16)) end)
+ if WIN32 then utf8_uri = utf8_uri:sub(2, -1) end -- ignore leading '/'
+ local uri = utf8_uri:iconv(_CHARSET, 'UTF-8')
+ if lfs.attributes(uri).mode ~= 'directory' then
+ io.open_file(utf8_uri)
+ end
+ end
+ end
+ end)
+
+local string_format = string.format
+local EOLs = { L('CRLF'), L('CR'), L('LF') }
+local GETLEXERLANGUAGE = _SCINTILLA.functions.get_lexer_language[1]
+connect('update_ui',
+ function() -- sets docstatusbar text
+ local buffer = buffer
+ local pos = buffer.current_pos
+ local line, max = buffer:line_from_position(pos) + 1, buffer.line_count
+ local col = buffer.column[pos] + 1
+ local lexer = buffer:private_lexer_call(GETLEXERLANGUAGE)
+ local eol = EOLs[buffer.eol_mode + 1]
+ local tabs = string_format('%s %d', buffer.use_tabs and L('Tabs:') or
+ L('Spaces:'), buffer.indent)
+ local enc = buffer.encoding or ''
+ gui.docstatusbar_text =
+ string_format('%s %d/%d %s %d %s %s %s %s', L('Line:'),
+ line, max, L('Col:'), col, lexer, eol, tabs, enc)
+ end)
+
+connect('margin_click',
+ function(margin, modifiers, position) -- toggles folding
+ buffer:toggle_fold(buffer:line_from_position(position))
+ end)
+
+connect('buffer_new', function() set_title(buffer) end)
+
+connect('buffer_before_switch',
+ function() -- save buffer properties
+ local buffer = buffer
+ -- Save view state.
+ buffer._anchor = buffer.anchor
+ buffer._current_pos = buffer.current_pos
+ buffer._first_visible_line = buffer.first_visible_line
+ -- Save fold state.
+ buffer._folds = {}
+ local folds = buffer._folds
+ local i = buffer:contracted_fold_next(0)
+ while i >= 0 do
+ folds[#folds + 1] = i
+ i = buffer:contracted_fold_next(i + 1)
+ end
+ end)
+
+connect('buffer_after_switch',
+ function() -- restore buffer properties
+ local buffer = buffer
+ if not buffer._folds then return end
+ -- Restore fold state.
+ for _, i in ipairs(buffer._folds) do buffer:toggle_fold(i) end
+ -- Restore view state.
+ buffer:set_sel(buffer._anchor, buffer._current_pos)
+ buffer:line_scroll(0,
+ buffer:visible_from_doc_line(buffer._first_visible_line) -
+ buffer.first_visible_line)
+ end)
+
+connect('buffer_after_switch',
+ function() -- updates titlebar and statusbar
+ set_title(buffer)
+ events.emit('update_ui')
+ end)
+
+connect('view_after_switch',
+ function() -- updates titlebar and statusbar
+ set_title(buffer)
+ events.emit('update_ui')
+ end)
+
+connect('reset_after', function() gui.statusbar_text = 'Lua reset' end)
+
+connect('quit',
+ function() -- prompts for confirmation if any buffers are dirty
+ local list = {}
+ for _, buffer in ipairs(_BUFFERS) do
+ if buffer.dirty then
+ list[#list + 1] = buffer.filename or buffer._type or L('Untitled')
+ end
+ end
+ if #list > 0 and
+ gui.dialog('msgbox',
+ '--title', L('Quit without saving?'),
+ '--text', L('The following buffers are unsaved:'),
+ '--informative-text',
+ string.format('%s', table.concat(list, '\n')),
+ '--button1', 'gtk-cancel',
+ '--button2', L('Quit _without saving'),
+ '--no-newline') ~= '2' then
+ return false
+ end
+ return true
+ end)
+
+if OSX then
+ connect('appleevent_odoc',
+ function(uri) return events.emit('uri_dropped', 'file://'..uri) end)
+
+ connect('buffer_new',
+ function() -- GTK-OSX has clipboard problems
+ buffer.paste = function()
+ local clipboard_text = gui.clipboard_text
+ if #clipboard_text > 0 then buffer:replace_sel(clipboard_text) end
+ end
+ end)
+end
+
+connect('error', function(...) gui._print(L('[Error Buffer]'), ...) end)