aboutsummaryrefslogtreecommitdiff
path: root/core/events.lua
diff options
context:
space:
mode:
Diffstat (limited to 'core/events.lua')
-rw-r--r--core/events.lua357
1 files changed, 189 insertions, 168 deletions
diff --git a/core/events.lua b/core/events.lua
index fabd52e5..3ee2e333 100644
--- a/core/events.lua
+++ b/core/events.lua
@@ -8,244 +8,262 @@ local M = {}
--
-- ## Overview
--
--- Textadept is very event-driven. Most of its functionality comes through event
--- handlers. Events occur when you create a new buffer, press a key, click on a
--- menu, etc. You can even make an event occur with Lua code. Instead of having
--- a single event handler however, each event can have a set of handlers. These
--- handlers are simply Lua functions that are called in the order they were
--- added to an event. This enables dynamically loaded modules to add their own
--- handlers to events.
+-- Events occur when you do things like create a new buffer, press a key, click
+-- on a menu, etc. You can even emit events yourself using Lua. Each event has a
+-- set of event handlers, which are simply Lua functions called in the order
+-- they were connected to an event. This enables dynamically loaded modules to
+-- connect to events.
--
-- Events themselves are nothing special. They do not have to be declared in
-- order to be used. They are simply strings containing an arbitrary event name.
--- When an event of this name occurs, either generated by Textadept or you, all
--- event handlers assigned to it are run.
+-- When an event of this name is emitted, either by Textadept or you, all event
+-- handlers assigned to it are run. Events can be given any number of arguments.
+-- These arguments will be passed to the event's handler functions. If an event
+-- handler returns a `true` or `false` boolean value explicitly, no subsequent
+-- handlers are called. This is useful if you want to stop the propagation of an
+-- event like a keypress if it has already been handled.
--
--- Events can be given any number of arguments. These arguments will be passed
--- to the event's handler functions. If a handler returns either true or false
--- explicitly, all subsequent handlers are not called. This is useful if you
--- want to stop the propagation of an event like a keypress.
---
--- ## Textadept Events
---
--- This is the set of default events that Textadept emits with the arguments
--- they pass. Events that modules emit are listed on their respective LuaDoc
--- pages.
---
--- * `APPLEEVENT_ODOC`
+-- @field APPLEEVENT_ODOC (string)
-- Called when Mac OSX tells Textadept to open a document.
--- * `uri`: The URI to open encoded in UTF-8.
--- * `AUTO_C_CHAR_DELETED`
+-- Arguments:
+--
+-- * `uri`: The URI to open encoded in UTF-8.
+-- @field AUTO_C_CHAR_DELETED (string)
-- Called when the user deleted a character while the autocompletion list was
-- active.
--- * `AUTO_C_RELEASE`
+-- @field AUTO_C_RELEASE (string)
-- Called when the user has cancelled the autocompletion list.
--- * `AUTO_C_SELECTION`
+-- @field AUTO_C_SELECTION (string)
-- Called when the user has selected an item in an autocompletion list and
-- before the selection is inserted.
-- Automatic insertion can be cancelled by calling
-- [`buffer:auto_c_cancel()`][] before returning from the event handler.
-- Arguments:
--- * `text`: The text of the selection.
--- * `position`: The start position of the word being completed.
--- * `BUFFER_AFTER_SWITCH`
+--
+-- * `text`: The text of the selection.
+-- * `position`: The start position of the word being completed.
+-- @field BUFFER_AFTER_SWITCH (string)
-- Called right after a buffer is switched to.
--- * `BUFFER_BEFORE_SWITCH`
+-- This is emitted by [`view:goto_buffer()`][].
+-- @field BUFFER_BEFORE_SWITCH (string)
-- Called right before another buffer is switched to.
--- * `BUFFER_DELETED`
+-- This is emitted by [`view:goto_buffer()`][].
+-- @field BUFFER_DELETED (string)
-- Called after a buffer was deleted.
--- * `BUFFER_NEW`
+-- This is emitted by [`buffer:delete()`][].
+-- @field BUFFER_NEW (string)
-- Called when a new buffer is created.
--- * `CALL_TIP_CLICK`
+-- This is emitted on startup and by [`new_buffer()`][].
+-- @field CALL_TIP_CLICK (string)
-- Called when the user clicks on a calltip.
-- Arguments:
--- * `position`: Set to 1 if the click is in an up arrow, 2 if in a down
--- arrow, and 0 if elsewhere.
--- * `CHAR_ADDED`
+--
+-- * `position`: Set to 1 if the click is in an up arrow, 2 if in a down
+-- arrow, and 0 if elsewhere.
+-- @field CHAR_ADDED (string)
-- Called when an ordinary text character is added to the buffer.
-- Arguments:
--- * `ch`: The text character byte.
--- * `COMMAND_ENTRY_COMMAND`
+--
+-- * `ch`: The text character byte.
+-- @field COMMAND_ENTRY_COMMAND (string)
-- Called when a command is entered into the Command Entry.
-- Arguments:
--- * `command`: The command text.
--- * `COMMAND_ENTRY_KEYPRESS`
+--
+-- * `command`: The command text.
+-- @field COMMAND_ENTRY_KEYPRESS (string)
-- Called when a key is pressed in the Command Entry.
-- Arguments:
--- * `code`: The key code.
--- * `shift`: The Shift key is held down.
--- * `ctrl`: The Control/Command key is held down.
--- * `alt`: The Alt/option key is held down.
--- * `meta`: The Control key on Mac OSX is held down.
--- * `DOUBLE_CLICK`
+--
+-- * `code`: The key code.
+-- * `shift`: The Shift key is held down.
+-- * `ctrl`: The Control/Command key is held down.
+-- * `alt`: The Alt/option key is held down.
+-- * `meta`: The Control key on Mac OSX is held down.
+-- @field DOUBLE_CLICK (string)
-- Called when the mouse button is double-clicked.
-- Arguments:
--- * `position`: The text position of the double click.
--- * `line`: The line of the double click.
--- * `modifiers`: The key modifiers held down. It is a combination of zero
--- or more of `_SCINTILLA.constants.SCMOD_ALT`,
--- `_SCINTILLA.constants.SCMOD_CTRL`,
--- `_SCINTILLA.constants.SCMOD_SHIFT`, and
--- `_SCINTILLA.constants.SCMOD_META`.
--- Note: If you set `buffer.rectangular_selection_modifier` to
--- `_SCINTILLA.constants.SCMOD_CTRL`, the Ctrl key is reported as *both*
--- Ctrl and Alt due to a Scintilla limitation with GTK.
--- * `DWELL_END`
+--
+-- * `position`: The text position of the double click.
+-- * `line`: The line of the double click.
+-- * `modifiers`: The key modifiers held down. It is a combination of zero or
+-- more of `_SCINTILLA.constants.SCMOD_ALT`,
+-- `_SCINTILLA.constants.SCMOD_CTRL`,
+-- `_SCINTILLA.constants.SCMOD_SHIFT`, and
+-- `_SCINTILLA.constants.SCMOD_META`.
+-- Note: If you set `buffer.rectangular_selection_modifier` to
+-- `_SCINTILLA.constants.SCMOD_CTRL`, the Ctrl key is reported as *both*
+-- Ctrl and Alt due to a Scintilla limitation with GTK+.
+-- @field DWELL_END (string)
-- Called after a `DWELL_START` and the mouse is moved or other activity such
-- as key press indicates the dwell is over.
-- Arguments:
--- * `position`: The nearest position in the document to the position where
--- the mouse pointer was lingering.
--- * `x`: Where the pointer lingered.
--- * `y`: Where the pointer lingered.
--- * `DWELL_START`
+--
+-- * `position`: The nearest position in the document to the position where
+-- the mouse pointer was lingering.
+-- * `x`: Where the pointer lingered.
+-- * `y`: Where the pointer lingered.
+-- @field DWELL_START (string)
-- Called when the user keeps the mouse in one position for the dwell period
-- (see `_SCINTILLA.constants.SCI_SETMOUSEDWELLTIME`).
-- Arguments:
--- * `position`: The nearest position in the document to the position where
--- the mouse pointer was lingering.
--- * `x`: Where the pointer lingered.
--- * `y`: Where the pointer lingered.
--- * `ERROR`
+--
+-- * `position`: The nearest position in the document to the position where
+-- the mouse pointer was lingering.
+-- * `x`: Where the pointer lingered.
+-- * `y`: Where the pointer lingered.
+-- @field ERROR (string)
-- Called when an error occurs.
-- Arguments:
--- * `text`: The error text.
--- * `FIND`
+--
+-- * `text`: The error text.
+-- @field FIND (string)
-- Called when finding text via the Find dialog box.
-- Arguments:
--- * `text`: The text to search for.
--- * `next`: Search forward.
--- * `HOTSPOT_CLICK`
+--
+-- * `text`: The text to search for.
+-- * `next`: Search forward.
+-- @field HOTSPOT_CLICK (string)
-- Called when the user clicks on text that is in a style with the hotspot
-- attribute set.
-- Arguments:
--- * `position`: The text position of the click.
--- * `modifiers`: The key modifiers held down. It is a combination of zero
--- or more of `_SCINTILLA.constants.SCMOD_ALT`,
--- `_SCINTILLA.constants.SCMOD_CTRL`,
--- `_SCINTILLA.constants.SCMOD_SHIFT`, and
--- `_SCINTILLA.constants.SCMOD_META`.
--- Note: If you set `buffer.rectangular_selection_modifier` to
--- `_SCINTILLA.constants.SCMOD_CTRL`, the Ctrl key is reported as *both*
--- Ctrl and Alt due to a Scintilla limitation with GTK.
--- * `HOTSPOT_DOUBLE_CLICK`
+--
+-- * `position`: The text position of the click.
+-- * `modifiers`: The key modifiers held down. It is a combination of zero or
+-- more of `_SCINTILLA.constants.SCMOD_ALT`,
+-- `_SCINTILLA.constants.SCMOD_CTRL`,
+-- `_SCINTILLA.constants.SCMOD_SHIFT`, and
+-- `_SCINTILLA.constants.SCMOD_META`.
+-- Note: If you set `buffer.rectangular_selection_modifier` to
+-- `_SCINTILLA.constants.SCMOD_CTRL`, the Ctrl key is reported as *both*
+-- Ctrl and Alt due to a Scintilla limitation with GTK+.
+-- @field HOTSPOT_DOUBLE_CLICK (string)
-- Called when the user double clicks on text that is in a style with the
-- hotspot attribute set.
-- Arguments:
--- * `position`: The text position of the double click.
--- * `modifiers`: The key modifiers held down. It is a combination of zero
--- or more of `_SCINTILLA.constants.SCMOD_ALT`,
--- `_SCINTILLA.constants.SCMOD_CTRL`,
--- `_SCINTILLA.constants.SCMOD_SHIFT`, and
--- `_SCINTILLA.constants.SCMOD_META`.
--- Note: If you set `buffer.rectangular_selection_modifier` to
--- `_SCINTILLA.constants.SCMOD_CTRL`, the Ctrl key is reported as *both*
--- Ctrl and Alt due to a Scintilla limitation with GTK.
--- * `HOTSPOT_RELEASE_CLICK`
+--
+-- * `position`: The text position of the double click.
+-- * `modifiers`: The key modifiers held down. It is a combination of zero or
+-- more of `_SCINTILLA.constants.SCMOD_ALT`,
+-- `_SCINTILLA.constants.SCMOD_CTRL`,
+-- `_SCINTILLA.constants.SCMOD_SHIFT`, and
+-- `_SCINTILLA.constants.SCMOD_META`.
+-- Note: If you set `buffer.rectangular_selection_modifier` to
+-- `_SCINTILLA.constants.SCMOD_CTRL`, the Ctrl key is reported as *both*
+-- Ctrl and Alt due to a Scintilla limitation with GTK+.
+-- @field HOTSPOT_RELEASE_CLICK (string)
-- Called when the user releases the mouse on text that is in a style with the
-- hotspot attribute set.
-- Arguments:
--- * `position`: The text position of the release.
--- * `INDICATOR_CLICK`
+--
+-- * `position`: The text position of the release.
+-- @field INDICATOR_CLICK (string)
-- Called when the user clicks the mouse on text that has an indicator.
-- Arguments:
--- * `position`: The text position of the click.
--- * `modifiers`: The key modifiers held down. It is a combination of zero
--- or more of `_SCINTILLA.constants.SCMOD_ALT`,
--- `_SCINTILLA.constants.SCMOD_CTRL`,
--- `_SCINTILLA.constants.SCMOD_SHIFT`, and
--- `_SCINTILLA.constants.SCMOD_META`.
--- Note: If you set `buffer.rectangular_selection_modifier` to
--- `_SCINTILLA.constants.SCMOD_CTRL`, the Ctrl key is reported as *both*
--- Ctrl and Alt due to a Scintilla limitation with GTK.
--- * `INDICATOR_RELEASE`
+--
+-- * `position`: The text position of the click.
+-- * `modifiers`: The key modifiers held down. It is a combination of zero or
+-- more of `_SCINTILLA.constants.SCMOD_ALT`,
+-- `_SCINTILLA.constants.SCMOD_CTRL`,
+-- `_SCINTILLA.constants.SCMOD_SHIFT`, and
+-- `_SCINTILLA.constants.SCMOD_META`.
+-- Note: If you set `buffer.rectangular_selection_modifier` to
+-- `_SCINTILLA.constants.SCMOD_CTRL`, the Ctrl key is reported as *both*
+-- Ctrl and Alt due to a Scintilla limitation with GTK+.
+-- @field INDICATOR_RELEASE (string)
-- Called when the user releases the mouse on text that has an indicator.
-- Arguments:
--- * `position`: The text position of the release.
--- * `KEYPRESS`
+--
+-- * `position`: The text position of the release.
+-- @field KEYPRESS (string)
-- Called when a key is pressed.
-- Arguments:
--- * `code`: The key code.
--- * `shift`: The Shift key is held down.
--- * `ctrl`: The Control/Command key is held down.
--- * `alt`: The Alt/option key is held down.
--- * `meta`: The Control key on Mac OSX is held down.
--- * `MARGIN_CLICK`
+--
+-- * `code`: The key code.
+-- * `shift`: The Shift key is held down.
+-- * `ctrl`: The Control/Command key is held down.
+-- * `alt`: The Alt/option key is held down.
+-- * `meta`: The Control key on Mac OSX is held down.
+-- @field MARGIN_CLICK (string)
-- Called when the mouse is clicked inside a margin.
-- Arguments:
--- * `margin`: The margin number that was clicked.
--- * `position`: The position of the start of the line in the buffer that
--- corresponds to the margin click.
--- * `modifiers`: The appropriate combination of
--- `_SCINTILLA.constants.SCI_SHIFT`, `_SCINTILLA.constants.SCI_CTRL`,
--- and `_SCINTILLA.constants.SCI_ALT` to indicate the keys that were
--- held down at the time of the margin click.
--- Note: If you set `buffer.rectangular_selection_modifier` to
--- `_SCINTILLA.constants.SCMOD_CTRL`, the Ctrl key is reported as *both*
--- Ctrl and Alt due to a Scintilla limitation with GTK.
--- * `MENU_CLICKED`
+--
+-- * `margin`: The margin number that was clicked.
+-- * `position`: The position of the start of the line in the buffer that
+-- corresponds to the margin click.
+-- * `modifiers`: The appropriate combination of
+-- `_SCINTILLA.constants.SCI_SHIFT`, `_SCINTILLA.constants.SCI_CTRL`,
+-- and `_SCINTILLA.constants.SCI_ALT` to indicate the keys that were held
+-- down at the time of the margin click.
+-- Note: If you set `buffer.rectangular_selection_modifier` to
+-- `_SCINTILLA.constants.SCMOD_CTRL`, the Ctrl key is reported as *both*
+-- Ctrl and Alt due to a Scintilla limitation with GTK+.
+-- @field MENU_CLICKED (string)
-- Called when a menu item is selected.
-- Arguments:
--- * `menu_id`: The numeric ID of the menu item set in [`gui.gtkmenu()`][].
--- * `QUIT`
+--
+-- * `menu_id`: The numeric ID of the menu item set in [`gui.menu()`][].
+-- @field QUIT (string)
-- Called when quitting Textadept.
-- When connecting to this event, connect with an index of 1 or the handler
-- will be ignored.
--- * `REPLACE`
+-- This is emitted by [`quit()`][].
+-- @field REPLACE (string)
-- Called to replace selected (found) text.
-- Arguments:
--- * `text`: The text to replace selected text with.
--- * `REPLACE_ALL`
+--
+-- * `text`: The text to replace selected text with.
+-- @field REPLACE_ALL (string)
-- Called to replace all occurances of found text.
-- Arguments:
--- * `find_text`: The text to search for.
--- * `repl_text`: The text to replace found text with.
--- * `RESET_AFTER`
+--
+-- * `find_text`: The text to search for.
+-- * `repl_text`: The text to replace found text with.
+-- @field RESET_AFTER (string)
-- Called after resetting the Lua state.
--- This is triggered by [`reset()`][].
--- * `RESET_BEFORE`
+-- This is emitted by [`reset()`][].
+-- @field RESET_BEFORE (string)
-- Called before resetting the Lua state.
--- This is triggered by [`reset()`][].
--- * `SAVE_POINT_LEFT`
+-- This is emitted by [`reset()`][].
+-- @field SAVE_POINT_LEFT (string)
-- Called when a save point is left.
--- * `SAVE_POINT_REACHED`
+-- @field SAVE_POINT_REACHED (string)
-- Called when a save point is entered.
--- * `UPDATE_UI`
+-- @field UPDATE_UI (string)
-- Called when either the text or styling of the buffer has changed or the
-- selection range has changed.
--- * `URI_DROPPED`
+-- @field URI_DROPPED (string)
-- Called when the user has dragged a URI such as a file name onto the view.
-- Arguments:
--- * `text`: The URI text encoded in UTF-8.
--- * `USER_LIST_SELECTION`
+--
+-- * `text`: The URI text encoded in UTF-8.
+-- @field USER_LIST_SELECTION (string)
-- Called when the user has selected an item in a user list.
-- Arguments:
--- * `list_type`: This is set to the list_type parameter from the
--- [`buffer:user_list_show()`][] call that initiated the list.
--- * `text`: The text of the selection.
--- * `position`: The position the list was displayed at.
--- * `VIEW_NEW`
+--
+-- * `list_type`: This is set to the list_type parameter from the
+-- [`buffer:user_list_show()`][] call that initiated the list.
+-- * `text`: The text of the selection.
+-- * `position`: The position the list was displayed at.
+-- @field VIEW_NEW (string)
-- Called when a new view is created.
--- * `VIEW_BEFORE_SWITCH`
+-- This is emitted on startup and by [`view:split()`][].
+-- @field VIEW_BEFORE_SWITCH (string)
-- Called right before another view is switched to.
--- * `VIEW_AFTER_SWITCH`
+-- This is emitted by [`gui.goto_view()`][].
+-- @field VIEW_AFTER_SWITCH (string)
-- Called right after another view is switched to.
+-- This is emitted by [`gui.goto_view()`][].
--
--- [`buffer:auto_c_cancel()`]: buffer.html#buffer.auto_c_cancel
--- [`gui.gtkmenu()`]: gui.html#gtkmenu
+-- [`buffer:auto_c_cancel()`]: buffer.html#auto_c_cancel
+-- [`view:goto_buffer()`]: view.html#goto_buffer
+-- [`new_buffer()`]: _G.html#new_buffer
+-- [`buffer:delete()`]: buffer.html#delete
+-- [`gui.menu()`]: gui.html#menu
+-- [`quit()`]: _G.html#quit
-- [`reset()`]: _G.html#reset
--- [`buffer:user_list_show()`]: buffer.html#buffer.user_list_show
---
--- ## Example
---
--- The following Lua code generates and handles a custom `my_event` event:
---
--- function my_event_handler(message)
--- gui.print(message)
--- end
---
--- events.connect('my_event', my_event_handler)
--- events.emit('my_event', 'my message') -- prints 'my message' to a view
+-- [`buffer:user_list_show()`]: buffer.html#user_list_show
+-- [`view:split()`]: view.html#split
+-- [`gui.goto_view()`]: gui.html#goto_view
module('events')]]
---
@@ -256,11 +274,12 @@ M.handlers = {}
---
-- Adds a handler function to an event.
--- @param event The string event name. It is arbitrary and need not be defined
--- anywhere.
+-- @param event The string event name. It is arbitrary and does not need to be
+-- defined previously.
-- @param f The Lua function to add.
-- @param index Optional index to insert the handler into.
-- @return Index of handler.
+-- @usage events.connect('my_event', function(message) gui.print(message) end)
-- @see disconnect
-- @name connect
function M.connect(event, f, index)
@@ -274,7 +293,7 @@ end
---
-- Disconnects a handler function from an event.
-- @param event The string event name.
--- @param index Index of the handler (returned by `events.connect()`).
+-- @param index Index of the handler returned by `events.connect()`.
-- @see connect
-- @name disconnect
function M.disconnect(event, index)
@@ -285,14 +304,16 @@ end
local error_emitted = false
---
--- Calls all handlers for the given event in sequence (effectively "generating"
--- the event).
+-- Calls all handlers for the given event in sequence.
-- If `true` or `false` is explicitly returned by any handler, the event is not
--- propagated any further; iteration ceases.
--- @param event The string event name.
+-- propagated any further; iteration ceases. This is useful if you want to stop
+-- the propagation of an event like a keypress.
+-- @param event The string event name. It is arbitrary and does not need to be
+-- defined previously.
-- @param ... Arguments passed to the handler.
--- @return `true` or `false` if any handler explicitly returned such; nil
+-- @return `true` or `false` if any handler explicitly returned such; `nil`
-- otherwise.
+-- @usage events.emit('my_event', 'my message')
-- @name emit
function M.emit(event, ...)
if not event then error(_L['Undefined event name']) end