From cc8bc0b210d5716d970717e86216a6b059eecf05 Mon Sep 17 00:00:00 2001 From: mitchell <70453897+667e-11@users.noreply.github.com> Date: Wed, 15 Aug 2007 16:36:19 -0400 Subject: Renamed handlers module to events, updated everything to reflect changes. --- core/events.lua | 434 +++++++++++++++++++++++++++++++++++++ core/ext/mime_types.lua | 12 +- core/ext/pm/buffer_browser.lua | 12 +- core/ext/pm/ctags_browser.lua | 10 +- core/ext/pm/macro_browser.lua | 6 +- core/file_io.lua | 8 +- core/handlers.lua | 379 -------------------------------- core/init.lua | 2 +- modules/cpp/commands.lua | 4 - modules/lua/commands.lua | 1 - modules/textadept/editing.lua | 4 +- modules/textadept/key_commands.lua | 8 +- modules/textadept/keys.lua | 4 +- modules/textadept/macros.lua | 6 +- src/lua_interface.c | 10 +- src/textadept.c | 2 +- 16 files changed, 476 insertions(+), 426 deletions(-) create mode 100644 core/events.lua delete mode 100644 core/handlers.lua diff --git a/core/events.lua b/core/events.lua new file mode 100644 index 00000000..9c8cbdb4 --- /dev/null +++ b/core/events.lua @@ -0,0 +1,434 @@ +-- Copyright 2007 Mitchell mitchellcaladbolg.net. See LICENSE. + +--- +-- Module that handles Scintilla and Textadept notifications/events. +-- Most of Textadept's functionality comes through handlers. Scintilla +-- notifications, Textadept's own events, and user-defined events can all be +-- handled. +-- +-- @usage +-- Each event can have multiple handlers, which are simply Lua functions that +-- are called in the sequence they are added as handler functions. Sometimes it +-- is useful to have a handler run under a specific condition(s). If this is the +-- case, place a conditional in the function that returns if it isn't met. +-- +-- For users creating their own events, one does not have to be explicitly +-- defined. A handler can simply be added for an event name, and 'handle'd when +-- necessary. +-- +-- Scintilla notifications: +-- char_added +-- ch: the (integer) character added. +-- save_point_reached +-- save_point_left +-- double_click +-- position: the position of the beginning of the line clicked. +-- line: the line clicked. +-- update_ui +-- macro_record +-- message: the SCI_* message. +-- wParam: wParam in SCI_*. +-- lParam: lParam in SCI_*. +-- margin_click +-- margin: the margin number. +-- modifiers: mouse modifiers. +-- position: the position of the beginning of the line at the point clicked. +-- user_list_selection +-- wParam: the user list ID. +-- text: the text of the selected item. +-- uri_dropped: +-- text: the URI dropped. +-- call_tip_click +-- position: 1 or 2 if the up or down arrow was clicked; 0 otherwise. +-- auto_c_selection +-- lParam: the start position of the word being completed. +-- text: the text of the selected item. +-- +-- Textadept events: +-- buffer_new +-- buffer_deleted +-- buffer_switch +-- view_new +-- view_switch +-- quit +-- keypress +-- code: the key code. +-- shift: flag indicating whether or not shift is pressed. +-- control: flag indicating whether or not control is pressed. +-- alt: flag indicating whether or not alt is pressed. +module('textadept.events', package.seeall) + +local events = textadept.events + +--- +-- Adds a handler function to an event. +-- @param event The string event name. +-- @param f The Lua function to add. +-- @param index Optional index to insert the handler into. +function add_handler(event, f, index) + local plural = event..'s' + if not events[plural] then events[plural] = {} end + local handlers = events[plural] + if index then + table.insert(handlers, index, f) + else + handlers[#handlers + 1] = f + end +end + +--- +-- Calls every handler function added to an event in sequence. +-- If true or false is returned by any handler, the iteration ceases. Normally +-- this function is called by the system when necessary, but it can be called +-- in scripts to handle user-defined events. +-- @param event The string event name. +-- @param ... Arguments to the handler. +function handle(event, ...) + local plural = event..'s' + local handlers = events[plural] + if not handlers then return end + for _, f in ipairs(handlers) do + local result = f( unpack{...} ) + if result == true or result == false then return result end + end +end + +--- +-- Reloads event handlers. +-- Clears each event's table of handlers and reloads this module to reset to the +-- default handlers. +function reload() + package.loaded['events'] = nil + for handler in pairs(events) do + if events[handler..'s'] then events[handler..'s'] = nil end + end + require 'events' +end + +-- Textadept events. +function buffer_new() + return handle('buffer_new') +end +function buffer_deleted() + return handle('buffer_deleted') +end +function buffer_switch() + return handle('buffer_switch') +end +function view_new() + return handle('view_new') +end +function view_switch() + return handle('view_switch') +end +function quit() + return handle('quit') +end +function keypress(code, shift, control, alt) + return handle('keypress', code, shift, control, alt) +end + +-- Scintilla notifications. +function char_added(n) + return handle( 'char_added', string.char(n.ch) ) +end +function save_point_reached() + return handle('save_point_reached') +end +function save_point_left() + return handle('save_point_left') +end +function double_click(n) + return handle('double_click', n.position, n.line) +end +function update_ui() + return handle('update_ui') +end +function macro_record(n) + return handle('macro_record', n.message, n.wParam, n.lParam) +end +function margin_click(n) + return handle('margin_click', n.margin, n.modifiers, n.position) +end +function user_list_selection(n) + return handle('user_list_selection', n.wParam, n.text) +end +function uri_dropped(n) + return handle('uri_dropped', n.text) +end +function call_tip_click(n) + return handle('call_tip_click', n.position) +end +function auto_c_selection(n) + return handle('auto_c_selection', n.lParam, n.text) +end + +--- Map of Scintilla notifications to their handlers. +local c = textadept.constants +local scnnotifications = { + [c.SCN_CHARADDED] = char_added, + [c.SCN_SAVEPOINTREACHED] = save_point_reached, + [c.SCN_SAVEPOINTLEFT] = save_point_left, + [c.SCN_DOUBLECLICK] = double_click, + [c.SCN_UPDATEUI] = update_ui, + [c.SCN_MACRORECORD] = macro_record, + [c.SCN_MARGINCLICK] = margin_click, + [c.SCN_USERLISTSELECTION] = user_list_selection, + [c.SCN_URIDROPPED] = uri_dropped, + [c.SCN_CALLTIPCLICK] = call_tip_click, + [c.SCN_AUTOCSELECTION] = auto_c_selection +} + +--- +-- Handles Scintilla notifications. +-- @param n The Scintilla notification structure as a Lua table. +function notification(n) + local f = scnnotifications[n.code] + if f then f(n) end +end + +-- Default handlers to follow. + +add_handler('char_added', + function(char) -- auto-indent on return + if char ~= '\n' then return end + local buffer = buffer + local anchor, caret = buffer.anchor, buffer.current_pos + local curr_line = buffer:line_from_position(caret) + local last_line = curr_line - 1 + while last_line >= 0 and #buffer:get_line(last_line) == 1 do + last_line = last_line - 1 + end + if last_line >= 0 then + local indentation = buffer.line_indentation[last_line] + local s = buffer.line_indent_position[curr_line] + buffer.line_indentation[curr_line] = indentation + local e = buffer.line_indent_position[curr_line] + local diff = e - s + if e > s then -- move selection on + if anchor >= s then anchor = anchor + diff end + if caret >= s then caret = caret + diff end + elseif e < s then -- move selection back + if anchor >= e then anchor = anchor >= s and anchor + diff or e end + if caret >= e then caret = caret >= s and caret + diff or e end + end + buffer:set_sel(anchor, caret) + end + end) + +--- +-- [Local function] 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 'Untitled' + local d = buffer.dirty and ' * ' or ' - ' + textadept.title = filename:match('[^/]+$')..d..'Textadept ('..filename..')' +end + +add_handler('save_point_reached', + function() -- changes Textadept title to show 'clean' buffer + buffer.dirty = false + set_title(buffer) + end) + +add_handler('save_point_left', + function() -- changes Textadept title to show 'dirty' buffer + buffer.dirty = true + set_title(buffer) + end) + +--- +-- [Local table] A table of (integer) brace characters with their matches. +-- @class table +-- @name _braces +local _braces = { -- () [] {} <> + [40] = 1, [91] = 1, [123] = 1, [60] = 1, + [41] = 1, [93] = 1, [125] = 1, [62] = 1, +} + +--- +-- [Local function] Highlights matching/mismatched braces appropriately. +-- @param current_pos The position to match braces at. +local function match_brace(current_pos) + local buffer = buffer + if _braces[ buffer.char_at[current_pos] ] and + buffer:get_style_name( buffer.style_at[current_pos] ) == 'operator' then + local pos = buffer:brace_match(current_pos) + if pos ~= -1 then + buffer:brace_highlight(current_pos, pos) + else + buffer:brace_bad_light(current_pos) + end + return true + end + return false +end + +add_handler('update_ui', + function() -- highlights matching braces + local buffer = buffer + if not match_brace(buffer.current_pos) then buffer:brace_bad_light(-1) end + end) + +local docstatusbar_text = + "Line: %d/%d Col: %d Lexer: %s %s %s %s" +add_handler('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:get_lexer_language() + local mode = buffer.overtype and 'OVR' or 'INS' + local eol = ( { 'CRLF', 'CR', 'LF' } )[buffer.eol_mode + 1] + local tabs = (buffer.use_tabs and 'Tabs:' or 'Spaces:')..buffer.indent + textadept.docstatusbar_text = + docstatusbar_text:format(line, max, col, lexer, mode, eol, tabs) + end) + +add_handler('margin_click', + function(margin, modifiers, position) -- toggles folding + local buffer = buffer + local line = buffer:line_from_position(position) + buffer:toggle_fold(line) + end) + +add_handler('buffer_new', + function() -- set additional buffer functions + local buffer, textadept = buffer, textadept + buffer.save = textadept.io.save + buffer.save_as = textadept.io.save_as + buffer.close = textadept.io.close + set_title(buffer) + end) + +add_handler('buffer_switch', + function() -- updates titlebar and statusbar + set_title(buffer) + update_ui() + end) + +add_handler('view_switch', + function() -- updates titlebar and statusbar + set_title(buffer) + update_ui() + end) + +add_handler('quit', + function() -- prompts for confirmation if any buffers are dirty; saves session + local any = false + local list = 'The following buffers are unsaved:\n\n' + for _, buffer in ipairs(textadept.buffers) do + if buffer.dirty then + list = list..(buffer.filename or 'Untitled')..'\n' + any = true + end + end + if any then + list = list..'\nQuit without saving?' + if os.execute('zenity --question --title Alert '.. + '--text "'..list..'"') ~= 0 then + return false + end + end + textadept.io.save_session() + return true + end) + + +--- +-- Shows completions for the current command_entry text. +-- Opens a new buffer (if one hasn't already been opened) for printing possible +-- completions. +-- @param command The command to complete. +function show_completions(command) + local textadept = textadept + local cmpl_buffer, goto + if buffer.shows_completions then + cmpl_buffer = buffer + else + for index, buffer in ipairs(textadept.buffers) do + if buffer.shows_completions then + cmpl_buffer = index + goto = buffer.doc_pointer ~= textadept.focused_doc_pointer + elseif buffer.doc_pointer == textadept.focused_doc_pointer then + textadept.prev_buffer = index + end + end + if not cmpl_buffer then + cmpl_buffer = textadept.new_buffer() + cmpl_buffer.shows_completions = true + else + if goto then view:goto(cmpl_buffer) end + cmpl_buffer = textadept.buffers[cmpl_buffer] + end + end + cmpl_buffer:clear_all() + + local substring = command:match('[%w_.:]+$') or '' + local path, o, prefix = substring:match('^([%w_.:]-)([.:]?)([%w_]*)$') + local ret, tbl = pcall(loadstring('return ('..path..')')) + if not ret then tbl = getfenv(0) end + if type(tbl) ~= 'table' then return end + local cmpls = {} + for k in pairs(tbl) do + if type(k) == 'string' and k:match('^'..prefix) then + cmpls[#cmpls + 1] = k + end + end + if path == 'buffer' then + if o == ':' then + for f in pairs(textadept.buffer_functions) do + if f:match('^'..prefix) then cmpls[#cmpls + 1] = f end + end + else + for p in pairs(textadept.buffer_properties) do + if p:match('^'..prefix) then cmpls[#cmpls + 1] = p end + end + end + end + table.sort(cmpls) + for _, cmpl in ipairs(cmpls) do cmpl_buffer:add_text(cmpl..'\n') end + cmpl_buffer:set_save_point() +end + +--- +-- Hides the completion buffer if it is currently focused and restores the +-- previous focused buffer (if possible). +function hide_completions() + local textadept = textadept + if buffer.shows_completions then + buffer:close() + if textadept.prev_buffer then view:goto_buffer(textadept.prev_buffer) end + end +end + +--- +-- Default error handler. +-- Opens a new buffer (if one hasn't already been opened) for printing errors. +-- @param ... Error strings. +function error(...) + local function handle_error(...) + local textadept = textadept + local error_message = table.concat( {...} , '\n' ) + local error_buffer + for index, buffer in ipairs(textadept.buffers) do + if buffer.shows_errors then + error_buffer = buffer + if buffer.doc_pointer ~= textadept.focused_doc_pointer then + view:goto_buffer(index) + end + break + end + end + if not error_buffer then + error_buffer = textadept.new_buffer() + error_buffer.shows_errors = true + end + error_buffer:append_text(error_message..'\n') + error_buffer:set_save_point() + end + pcall( handle_error, unpack{...} ) -- prevent endless loops if this errors +end diff --git a/core/ext/mime_types.lua b/core/ext/mime_types.lua index ec4ef808..912faf00 100644 --- a/core/ext/mime_types.lua +++ b/core/ext/mime_types.lua @@ -94,7 +94,7 @@ local function load_language_module_from_filename(filename) if ret then _m[lang].set_buffer_properties() elseif not ret and not err:match("^module '"..lang.."' not found:") then - textadept.handlers.error(err) + textadept.events.error(err) end end end @@ -119,8 +119,8 @@ local function handle_switch() end end -local handlers = textadept.handlers -handlers.add_handler_function('file_opened', handle_new) -handlers.add_handler_function('file_saved_as', handle_new) -handlers.add_handler_function('buffer_switch', handle_switch) -handlers.add_handler_function('view_new', handle_switch) +local events = textadept.events +events.add_handler('file_opened', handle_new) +events.add_handler('file_saved_as', handle_new) +events.add_handler('buffer_switch', handle_switch) +events.add_handler('view_new', handle_switch) diff --git a/core/ext/pm/buffer_browser.lua b/core/ext/pm/buffer_browser.lua index 1c2fb33c..47cc6de6 100644 --- a/core/ext/pm/buffer_browser.lua +++ b/core/ext/pm/buffer_browser.lua @@ -46,12 +46,12 @@ function perform_menu_action(menu_item, selected_item) textadept.pm.activate() end -local add_handler_function = textadept.handlers.add_handler_function +local add_handler = textadept.events.add_handler local function update_view() if matches(textadept.pm.entry_text) then textadept.pm.activate() end end -add_handler_function('file_opened', update_view) -add_handler_function('buffer_new', update_view) -add_handler_function('buffer_deleted', update_view) -add_handler_function('save_point_reached', update_view) -add_handler_function('save_point_left', update_view) +add_handler('file_opened', update_view) +add_handler('buffer_new', update_view) +add_handler('buffer_deleted', update_view) +add_handler('save_point_reached', update_view) +add_handler('save_point_left', update_view) diff --git a/core/ext/pm/ctags_browser.lua b/core/ext/pm/ctags_browser.lua index 842dce9e..5166b423 100644 --- a/core/ext/pm/ctags_browser.lua +++ b/core/ext/pm/ctags_browser.lua @@ -230,7 +230,7 @@ function perform_menu_action(menu_item, selected_item) end -local add_handler_function = textadept.handlers.add_handler_function +local add_handler = textadept.events.add_handler local function update_view() if matches(textadept.pm.entry_text) then if buffer.filename then @@ -240,7 +240,7 @@ local function update_view() end end end -add_handler_function('file_opened', update_view) -add_handler_function('buffer_deleted', update_view) -add_handler_function('buffer_switch', update_view) -add_handler_function('save_point_reached', update_view) +add_handler('file_opened', update_view) +add_handler('buffer_deleted', update_view) +add_handler('buffer_switch', update_view) +add_handler('save_point_reached', update_view) diff --git a/core/ext/pm/macro_browser.lua b/core/ext/pm/macro_browser.lua index 3fc38aca..de8af373 100644 --- a/core/ext/pm/macro_browser.lua +++ b/core/ext/pm/macro_browser.lua @@ -35,9 +35,9 @@ function perform_menu_action(menu_item, selected_item) textadept.pm.activate() end -local add_handler_function = textadept.handlers.add_handler_function +local add_handler = textadept.events.add_handler local function update_view() if matches(textadept.pm.entry_text) then textadept.pm.activate() end end -add_handler_function('macro_saved', update_view) -add_handler_function('macro_deleted', update_view) +add_handler('macro_saved', update_view) +add_handler('macro_deleted', update_view) diff --git a/core/file_io.lua b/core/file_io.lua index 958a03cc..cdc09af0 100644 --- a/core/file_io.lua +++ b/core/file_io.lua @@ -5,7 +5,7 @@ -- Opens and saves files and sessions and reads API files. module('textadept.io', package.seeall) -local handlers = textadept.handlers +local events = textadept.events --- -- [Local function] Opens a file or goes to its already open buffer. @@ -24,7 +24,7 @@ local function open_helper(filename) end buffer.filename = filename buffer:set_save_point() - handlers.handle('file_opened', filename) + events.handle('file_opened', filename) end --- @@ -58,7 +58,7 @@ function save(buffer) f:close() buffer:set_save_point() else - handlers.error(err) + events.error(err) end end @@ -77,7 +77,7 @@ function save_as(buffer, filename) if #filename > 0 then buffer.filename = filename:sub(1, -2) -- chomp buffer:save() - handlers.handle('file_saved_as', filename) + events.handle('file_saved_as', filename) end end diff --git a/core/handlers.lua b/core/handlers.lua deleted file mode 100644 index 2a343dd3..00000000 --- a/core/handlers.lua +++ /dev/null @@ -1,379 +0,0 @@ --- Copyright 2007 Mitchell mitchellcaladbolg.net. See LICENSE. - ---- Handler module that handles Scintilla and Textadept notifications/events. -module('textadept.handlers', package.seeall) - -local handlers = textadept.handlers - ---- --- Adds a function to a handler. --- Every handler has a table of functions associated with it that are run when --- the handler is called by Textadept. --- @param handler The string handler name. --- @param f The Lua function to add. --- @param index Optional index to insert the handler into. -function add_handler_function(handler, f, index) - local plural = handler..'s' - if not handlers[plural] then handlers[plural] = {} end - local funcs = handlers[plural] - if index then - table.insert(funcs, index, f) - else - funcs[#funcs+ 1] = f - end -end - ---- --- Calls every function added to a handler in sequence. --- If true or false is returned by any function, the iteration ceases. --- @param handler The string handler name. --- @param ... Arguments to the handler. -function handle(handler, ...) - local plural = handler..'s' - if not handlers[plural] then return end - local funcs = handlers[plural] - for _, f in ipairs(funcs) do - local result = f( unpack{...} ) - if result == true or result == false then return result end - end -end - ---- --- Reloads handlers. --- Clears each table of handlers for each handler function and reloads this --- module to reset to the default handlers. -function reload() - package.loaded['handlers'] = nil - for handler in pairs(handlers) do - if handlers[handler..'s'] then handlers[handler..'s'] = nil end - end - require 'handlers' -end - --- Signals. -function buffer_new() - return handle('buffer_new') -end -function buffer_deleted() - return handle('buffer_deleted') -end -function buffer_switch() - return handle('buffer_switch') -end -function view_new() - return handle('view_new') -end -function view_switch() - return handle('view_switch') -end -function quit() - return handle('quit') -end -function keypress(code, shift, control, alt) - return handle('keypress', code, shift, control, alt) -end - --- Scintilla notifications. -function char_added(n) - return handle( 'char_added', string.char(n.ch) ) -end -function save_point_reached() - return handle('save_point_reached') -end -function save_point_left() - return handle('save_point_left') -end -function double_click(n) - return handle('double_click', n.position, n.line) -end -function update_ui() - return handle('update_ui') -end -function macro_record(n) - return handle('macro_record', n.message, n.wParam, n.lParam) -end -function margin_click(n) - return handle('margin_click', n.margin, n.modifiers, n.position) -end -function user_list_selection(n) - return handle('user_list_selection', n.wParam, n.text) -end -function uri_dropped(n) - return handle('uri_dropped', n.text) -end -function call_tip_click(n) - return handle('call_tip_click', n.position) -end -function auto_c_selection(n) - return handle('auto_c_selection', n.lParam, n.text) -end - ---- Map of Scintilla notifications to their handlers. -local c = textadept.constants -local scnnotifications = { - [c.SCN_CHARADDED] = char_added, - [c.SCN_SAVEPOINTREACHED] = save_point_reached, - [c.SCN_SAVEPOINTLEFT] = save_point_left, - [c.SCN_DOUBLECLICK] = double_click, - [c.SCN_UPDATEUI] = update_ui, - [c.SCN_MACRORECORD] = macro_record, - [c.SCN_MARGINCLICK] = margin_click, - [c.SCN_USERLISTSELECTION] = user_list_selection, - [c.SCN_URIDROPPED] = uri_dropped, - [c.SCN_CALLTIPCLICK] = call_tip_click, - [c.SCN_AUTOCSELECTION] = auto_c_selection -} - ---- --- Handles Scintilla notifications. --- @param n The Scintilla notification structure as a Lua table. -function notification(n) - local f = scnnotifications[n.code] - if f then f(n) end -end - --- Default handlers to follow. - -add_handler_function('char_added', - function(char) -- auto-indent on return - if char ~= '\n' then return end - local buffer = buffer - local anchor, caret = buffer.anchor, buffer.current_pos - local curr_line = buffer:line_from_position(caret) - local last_line = curr_line - 1 - while last_line >= 0 and #buffer:get_line(last_line) == 1 do - last_line = last_line - 1 - end - if last_line >= 0 then - local indentation = buffer.line_indentation[last_line] - local s = buffer.line_indent_position[curr_line] - buffer.line_indentation[curr_line] = indentation - local e = buffer.line_indent_position[curr_line] - local diff = e - s - if e > s then -- move selection on - if anchor >= s then anchor = anchor + diff end - if caret >= s then caret = caret + diff end - elseif e < s then -- move selection back - if anchor >= e then anchor = anchor >= s and anchor + diff or e end - if caret >= e then caret = caret >= s and caret + diff or e end - end - buffer:set_sel(anchor, caret) - end - end) - ---- --- [Local function] 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 'Untitled' - local d = buffer.dirty and ' * ' or ' - ' - textadept.title = filename:match('[^/]+$')..d..'Textadept ('..filename..')' -end - -add_handler_function('save_point_reached', - function() -- changes Textadept title to show 'clean' buffer - buffer.dirty = false - set_title(buffer) - end) - -add_handler_function('save_point_left', - function() -- changes Textadept title to show 'dirty' buffer - buffer.dirty = true - set_title(buffer) - end) - ---- --- [Local table] A table of (integer) brace characters with their matches. --- @class table --- @name _braces -local _braces = { -- () [] {} <> - [40] = 1, [91] = 1, [123] = 1, [60] = 1, - [41] = 1, [93] = 1, [125] = 1, [62] = 1, -} - ---- --- [Local function] Highlights matching/mismatched braces appropriately. --- @param current_pos The position to match braces at. -local function match_brace(current_pos) - local buffer = buffer - if _braces[ buffer.char_at[current_pos] ] and - buffer:get_style_name( buffer.style_at[current_pos] ) == 'operator' then - local pos = buffer:brace_match(current_pos) - if pos ~= -1 then - buffer:brace_highlight(current_pos, pos) - else - buffer:brace_bad_light(current_pos) - end - return true - end - return false -end - -add_handler_function('update_ui', - function() -- highlights matching braces - local buffer = buffer - if not match_brace(buffer.current_pos) then buffer:brace_bad_light(-1) end - end) - -local docstatusbar_text = - "Line: %d/%d Col: %d Lexer: %s %s %s %s" -add_handler_function('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:get_lexer_language() - local mode = buffer.overtype and 'OVR' or 'INS' - local eol = ( { 'CRLF', 'CR', 'LF' } )[buffer.eol_mode + 1] - local tabs = (buffer.use_tabs and 'Tabs:' or 'Spaces:')..buffer.indent - textadept.docstatusbar_text = - docstatusbar_text:format(line, max, col, lexer, mode, eol, tabs) - end) - -add_handler_function('margin_click', - function(margin, modifiers, position) -- toggles folding - local buffer = buffer - local line = buffer:line_from_position(position) - buffer:toggle_fold(line) - end) - -add_handler_function('buffer_new', - function() -- set additional buffer functions - local buffer, textadept = buffer, textadept - buffer.save = textadept.io.save - buffer.save_as = textadept.io.save_as - buffer.close = textadept.io.close - set_title(buffer) - end) - -add_handler_function('buffer_switch', - function() -- updates titlebar and statusbar - set_title(buffer) - update_ui() - end) - -add_handler_function('view_switch', - function() -- updates titlebar and statusbar - set_title(buffer) - update_ui() - end) - -add_handler_function('quit', - function() -- prompts for confirmation if any buffers are dirty; saves session - local any = false - local list = 'The following buffers are unsaved:\n\n' - for _, buffer in ipairs(textadept.buffers) do - if buffer.dirty then - list = list..(buffer.filename or 'Untitled')..'\n' - any = true - end - end - if any then - list = list..'\nQuit without saving?' - if os.execute('zenity --question --title Alert '.. - '--text "'..list..'"') ~= 0 then - return false - end - end - textadept.io.save_session() - return true - end) - - ---- --- Shows completions for the current command_entry text. --- Opens a new buffer (if one hasn't already been opened) for printing possible --- completions. --- @param command The command to complete. -function show_completions(command) - local textadept = textadept - local cmpl_buffer, goto - if buffer.shows_completions then - cmpl_buffer = buffer - else - for index, buffer in ipairs(textadept.buffers) do - if buffer.shows_completions then - cmpl_buffer = index - goto = buffer.doc_pointer ~= textadept.focused_doc_pointer - elseif buffer.doc_pointer == textadept.focused_doc_pointer then - textadept.prev_buffer = index - end - end - if not cmpl_buffer then - cmpl_buffer = textadept.new_buffer() - cmpl_buffer.shows_completions = true - else - if goto then view:goto(cmpl_buffer) end - cmpl_buffer = textadept.buffers[cmpl_buffer] - end - end - cmpl_buffer:clear_all() - - local substring = command:match('[%w_.:]+$') or '' - local path, o, prefix = substring:match('^([%w_.:]-)([.:]?)([%w_]*)$') - local ret, tbl = pcall(loadstring('return ('..path..')')) - if not ret then tbl = getfenv(0) end - if type(tbl) ~= 'table' then return end - local cmpls = {} - for k in pairs(tbl) do - if type(k) == 'string' and k:match('^'..prefix) then - cmpls[#cmpls + 1] = k - end - end - if path == 'buffer' then - if o == ':' then - for f in pairs(textadept.buffer_functions) do - if f:match('^'..prefix) then cmpls[#cmpls + 1] = f end - end - else - for p in pairs(textadept.buffer_properties) do - if p:match('^'..prefix) then cmpls[#cmpls + 1] = p end - end - end - end - table.sort(cmpls) - for _, cmpl in ipairs(cmpls) do cmpl_buffer:add_text(cmpl..'\n') end - cmpl_buffer:set_save_point() -end - ---- --- Hides the completion buffer if it is currently focused and restores the --- previous focused buffer (if possible). -function hide_completions() - local textadept = textadept - if buffer.shows_completions then - buffer:close() - if textadept.prev_buffer then view:goto_buffer(textadept.prev_buffer) end - end -end - ---- --- Default error handler. --- Opens a new buffer (if one hasn't already been opened) for printing errors. --- @param ... Error strings. -function error(...) - local function handle_error(...) - local textadept = textadept - local error_message = table.concat( {...} , '\n' ) - local error_buffer - for index, buffer in ipairs(textadept.buffers) do - if buffer.shows_errors then - error_buffer = buffer - if buffer.doc_pointer ~= textadept.focused_doc_pointer then - view:goto_buffer(index) - end - break - end - end - if not error_buffer then - error_buffer = textadept.new_buffer() - error_buffer.shows_errors = true - end - error_buffer:append_text(error_message..'\n') - error_buffer:set_save_point() - end - pcall( handle_error, unpack{...} ) -- prevent endless loops if this errors -end diff --git a/core/init.lua b/core/init.lua index 297495e6..f699b8e0 100644 --- a/core/init.lua +++ b/core/init.lua @@ -17,5 +17,5 @@ end package.path = package.path..';'.._HOME..'/core/?.lua' require 'iface' -require 'handlers' +require 'events' require 'file_io' diff --git a/modules/cpp/commands.lua b/modules/cpp/commands.lua index 472ca130..62c06be2 100644 --- a/modules/cpp/commands.lua +++ b/modules/cpp/commands.lua @@ -8,7 +8,6 @@ module('_m.cpp.commands', package.seeall) local keys = _G.keys if type(keys) == 'table' then local m_editing = _m.textadept.editing - local m_handlers = textadept.handlers keys.cpp = { al = { textadept.io.open, _HOME..'/modules/cpp/init.lua' }, ['s\n'] = { function() @@ -18,10 +17,7 @@ if type(keys) == 'table' then end }, cq = { m_editing.block_comment, '//~' }, ['('] = { function() ---~ buffer.word_chars = ---~ '_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' m_editing.show_call_tip(_m.cpp.api, true) ---~ buffer:set_chars_default() return false end }, } diff --git a/modules/lua/commands.lua b/modules/lua/commands.lua index f3dbe333..2b59f171 100644 --- a/modules/lua/commands.lua +++ b/modules/lua/commands.lua @@ -71,7 +71,6 @@ end local keys = _G.keys if type(keys) == 'table' then local m_editing = _m.textadept.editing - local m_handlers = textadept.handlers keys.lua = { al = { textadept.io.open, _HOME..'/modules/lua/init.lua' }, ac = { diff --git a/modules/textadept/editing.lua b/modules/textadept/editing.lua index 282d5ad3..d15ebb9b 100644 --- a/modules/textadept/editing.lua +++ b/modules/textadept/editing.lua @@ -55,7 +55,7 @@ local enclosure = { single_tag = { left = '<', right = ' />' } } -textadept.handlers.add_handler_function('char_added', +textadept.events.add_handler('char_added', function(c) -- matches characters specified in char_matches if char_matches[c] then buffer:insert_text( -1, char_matches[c] ) @@ -154,7 +154,7 @@ function show_call_tip(api, start) buffer:call_tip_show(current_call_tip.start_pos, call_tip) end -textadept.handlers.add_handler_function('call_tip_click', +textadept.events.add_handler('call_tip_click', function(position) -- display the next or previous call tip if not buffer:call_tip_active() then return end if position == 1 and current_call_tip.num > 1 then diff --git a/modules/textadept/key_commands.lua b/modules/textadept/key_commands.lua index 7493a6ec..2072795f 100644 --- a/modules/textadept/key_commands.lua +++ b/modules/textadept/key_commands.lua @@ -143,9 +143,9 @@ keys.ap = { 'goto_buffer', v, -1, false } keys.can = { textadept.goto_view, 1, false } keys.cap = { textadept.goto_view, -1, false } -local m_handlers = textadept.handlers -keys.cab = { m_handlers.handle, 'call_tip_click', 1 } -keys.caf = { m_handlers.handle, 'call_tip_click', 2 } +local m_events = textadept.events +keys.cab = { m_events.handle, 'call_tip_click', 1 } +keys.caf = { m_events.handle, 'call_tip_click', 2 } keys.cs = { textadept.find.focus } keys['c\t'] = { textadept.pm.focus } @@ -180,7 +180,7 @@ local function toggle_setting(setting) elseif type(state) == 'number' then buffer[setting] = buffer[setting] == 0 and 1 or 0 end - textadept.handlers.update_ui() -- for updating statusbar + textadept.events.update_ui() -- for updating statusbar end keys.ct.v = {} -- view chain diff --git a/modules/textadept/keys.lua b/modules/textadept/keys.lua index 93d089a9..996cdabf 100644 --- a/modules/textadept/keys.lua +++ b/modules/textadept/keys.lua @@ -159,7 +159,7 @@ local function keypress(code, shift, control, alt) local ret, retval = pcall( func, unpack(args) ) if ret then if type(retval) == 'boolean' then return retval end - else textadept.handlers.error(retval) end -- error + else textadept.events.error(retval) end -- error end return true else @@ -175,7 +175,7 @@ local function keypress(code, shift, control, alt) else return true end end end -textadept.handlers.add_handler_function('keypress', keypress, 1) +textadept.events.add_handler('keypress', keypress, 1) --- -- [Local function] Tries to get a key command based on the lexer and current diff --git a/modules/textadept/macros.lua b/modules/textadept/macros.lua index 0d81f105..c97a372b 100644 --- a/modules/textadept/macros.lua +++ b/modules/textadept/macros.lua @@ -38,7 +38,7 @@ local function macro_notification(msg, wParam, lParam) textadept.statusbar_text = 'Macro recording' end end -textadept.handlers.add_handler_function('macro_record', macro_notification) +textadept.events.add_handler('macro_record', macro_notification) --- -- Starts recording a macro. @@ -81,7 +81,7 @@ function stop_recording() list[macro_name] = current save() textadept.statusbar_text = 'Macro saved' - textadept.handlers.handle('macro_saved') + textadept.events.handle('macro_saved') else textadept.statusbar_text = 'Macro not saved' end @@ -124,7 +124,7 @@ function delete(macro_name) if list[macro_name] then list[macro_name] = nil save() - textadept.handlers.handle('macro_deleted') + textadept.events.handle('macro_deleted') end end diff --git a/src/lua_interface.c b/src/lua_interface.c index c3f8d99d..0be9362e 100644 --- a/src/lua_interface.c +++ b/src/lua_interface.c @@ -328,7 +328,7 @@ bool l_call_function(int nargs, int retn=0, bool keep_return=false) { // error message is at stack top void l_handle_error(LS *lua, const char *errmsg) { - if (focused_editor && l_is_ta_table_function("handlers", "error")) { + if (focused_editor && l_is_ta_table_function("events", "error")) { l_insert(lua, -1); // shift error message down if (errmsg) lua_pushstring(lua, errmsg); l_call_function(errmsg ? 2 : 1); @@ -340,11 +340,11 @@ void l_handle_error(LS *lua, const char *errmsg) { } bool l_handle_signal(const char *s) { - return l_is_ta_table_function("handlers", s) ? l_call_function(0, 1) : true; + return l_is_ta_table_function("events", s) ? l_call_function(0, 1) : true; } bool l_handle_keypress(int keyval, GdkEventKey *event) { - if (!l_is_ta_table_function("handlers", "keypress")) return false; + if (!l_is_ta_table_function("events", "keypress")) return false; lua_pushinteger(lua, keyval); lua_pushboolean(lua, (event->state & GDK_SHIFT_MASK) > 0 ? 1 : 0); lua_pushboolean(lua, (event->state & GDK_CONTROL_MASK) > 0 ? 1 : 0); @@ -353,7 +353,7 @@ bool l_handle_keypress(int keyval, GdkEventKey *event) { } void l_handle_completion(const char *command) { - if (!l_is_ta_table_function("handlers", + if (!l_is_ta_table_function("events", command ? "show_completions" : "hide_completions")) return; if (command) lua_pushstring(lua, command); l_call_function(command ? 1 : 0); @@ -363,7 +363,7 @@ void l_handle_completion(const char *command) { #define l_scn_str(s, n) { lua_pushstring(lua, s); lua_setfield(lua, -2, n); } void l_handle_scnnotification(SCNotification *n) { - if (!l_is_ta_table_function("handlers", "notification")) return; + if (!l_is_ta_table_function("events", "notification")) return; lua_newtable(lua); l_scn_int(n->nmhdr.code, "code"); l_scn_int(n->position, "position"); diff --git a/src/textadept.c b/src/textadept.c index 416b83fb..98096123 100644 --- a/src/textadept.c +++ b/src/textadept.c @@ -244,7 +244,7 @@ static bool t_keypress(GtkWidget*, GdkEventKey *event, gpointer) { return l_handle_keypress(event->keyval, event); } -static bool w_keypress(GtkWidget* , GdkEventKey *event, gpointer) { +static bool w_keypress(GtkWidget*, GdkEventKey *event, gpointer) { if (event->keyval == 0xff1b && GTK_WIDGET_VISIBLE(findbox)) { gtk_widget_hide(findbox); gtk_widget_grab_focus(focused_editor); -- cgit v1.2.3