aboutsummaryrefslogtreecommitdiff
path: root/modules/textadept/command_entry.lua
diff options
context:
space:
mode:
Diffstat (limited to 'modules/textadept/command_entry.lua')
-rw-r--r--modules/textadept/command_entry.lua167
1 files changed, 88 insertions, 79 deletions
diff --git a/modules/textadept/command_entry.lua b/modules/textadept/command_entry.lua
index 9b4f36e9..0a8ca6e4 100644
--- a/modules/textadept/command_entry.lua
+++ b/modules/textadept/command_entry.lua
@@ -6,40 +6,19 @@ local M = ui.command_entry
--[[ This comment is for LuaDoc.
---
-- Textadept's Command Entry.
---
--- ## Modes
---
--- The command entry supports multiple [modes](#keys.Modes) that have their own
--- sets of key bindings stored in a separate table in `_G.keys` under a mode
--- prefix key. Mode names are arbitrary, but cannot conflict with lexer names or
--- key sequence strings (e.g. `'lua'` or `'send'`) due to the method Textadept
--- uses for looking up key bindings. An example mode is "lua_command" mode for
--- executing Lua commands:
---
--- local function complete_lua() ... end
--- local function run_lua() ... end
--- keys['ce'] = function() ui.command_entry.enter_mode('lua_command') end
--- keys.lua_command = {
--- ['\t'] = complete_lua,
--- ['\n'] = function() return ui.command_entry.finish_mode(run_lua) end
--- }
---
--- In this case, `Ctrl+E` opens the command entry and enters "lua_command" key
--- mode where the `Tab` and `Enter` keys have special, defined functionality.
--- (By default, Textadept pre-defines `Esc` to exit any command entry mode.)
--- `Tab` shows a list of Lua completions for the entry text and `Enter` exits
--- "lua_command" key mode and executes the entered code. The command entry
--- handles all other editing and movement keys normally.
+-- It supports multiple modes that each have their own functionality, such as
+-- running Lua code, searching for text incrementally, and filtering text
+-- through shell commands.
-- @field height (number)
-- The height in pixels of the command entry.
module('ui.command_entry')]]
---
-- A metatable with typical platform-specific key bindings for text entries.
--- This metatable may be used to add basic editing keys to command entry modes.
--- It is automatically added to command entry modes unless a metatable was
--- previously set.
--- @usage setmetatable(keys.my_mode, ui.command_entry.editing_keys)
+-- This metatable may be used to add basic editing and movement keys to command
+-- entry modes. It is automatically added to command entry modes unless a
+-- metatable was previously set.
+-- @usage setmetatable(mode_keys, ui.command_entry.editing_keys)
-- @class table
-- @name editing_keys
M.editing_keys = {__index = {
@@ -60,52 +39,6 @@ M.editing_keys = {__index = {
[(OSX or CURSES) and 'cd' or '\0'] = function() M:clear() end
}}
----
--- Opens the command entry in key mode *mode*, highlighting text with lexer name
--- *lexer*, and displaying *height* number of lines at a time.
--- Key bindings will be looked up in `keys[mode]` instead of `keys`. The `Esc`
--- key exits the current mode, closes the command entry, and restores normal key
--- lookup.
--- This function is useful for binding keys to enter a command entry mode.
--- @param mode The key mode to enter into, or `nil` to exit the current mode.
--- @param lexer Optional string lexer name to use for command entry text. The
--- default value is `'text'`.
--- @param height Optional number of lines to display in the command entry. The
--- default value is `1`.
--- @usage keys['ce'] =
--- function() ui.command_entry.enter_mode('command_entry') end
--- @see _G.keys.MODE
--- @name enter_mode
-function M.enter_mode(mode, lexer, height)
- if M:auto_c_active() then M:auto_c_cancel() end -- may happen in curses
- keys.MODE = mode
- if mode then
- local mkeys = keys[mode]
- if not mkeys['esc'] then mkeys['esc'] = M.enter_mode end
- if not getmetatable(mkeys) then setmetatable(mkeys, M.editing_keys) end
- end
- M:select_all()
- M.focus()
- M:set_lexer(lexer or 'text')
- M.height = M:text_height(0) * (height or 1)
-end
-
----
--- Exits the current key mode, closes the command entry, and calls function *f*
--- (if given) with the command entry's text as an argument.
--- This is useful for binding keys to exit a command entry mode and perform an
--- action with the entered text.
--- @param f Optional function to call. It should accept the command entry text
--- as an argument.
--- @usage keys['\n'] =
--- function() return ui.command_entry.finish_mode(ui.print) end
--- @name finish_mode
-function M.finish_mode(f)
- if M:auto_c_active() then return false end -- allow Enter to autocomplete
- M.enter_mode(nil)
- if f then f((M:get_text())) end
-end
-
-- Environment for abbreviated Lua commands.
-- @class table
-- @name env
@@ -197,19 +130,95 @@ local function complete_lua()
M:auto_c_show(#part - 1, table.concat(cmpls, ' '))
end
--- Define key mode for entering Lua commands.
-keys.lua_command = {
- ['\t'] = complete_lua,
- ['\n'] = function() return M.finish_mode(run_lua) end
-}
+-- Key mode for entering Lua commands.
+-- @class table
+-- @name lua_mode_keys
+local lua_mode_keys = {['\t'] = complete_lua}
+
+---
+-- Opens the command entry, subjecting it to any key bindings defined in table
+-- *mode_keys*, highlighting text with lexer name *lexer*, and displaying
+-- *height* number of lines at a time, and then when the `Enter` key is pressed,
+-- closes the command entry and calls function *f* (if non-`nil`) with the
+-- command entry's text as an argument.
+-- By default with no arguments given, opens a Lua command entry.
+-- The command entry does not respond to Textadept's default key bindings, but
+-- instead to the key bindings defined in *mode_keys* and in
+-- `ui.command_entry.editing_keys`.
+-- @param f Optional function to call upon pressing `Enter` in the command
+-- entry, ending the mode. It should accept the command entry text as an
+-- argument.
+-- @param mode_keys Optional table of key bindings to respond to. This is in
+-- addition to the basic editing and movement keys defined in
+-- `ui.command_entry.editing_keys`.
+-- `Esc` and `Enter` are automatically defined to cancel and finish the
+-- command entry, respectively.
+-- This parameter may be omitted completely.
+-- @param lexer Optional string lexer name to use for command entry text. The
+-- default value is `'text'`.
+-- @param height Optional number of lines to display in the command entry. The
+-- default value is `1`.
+-- @see editing_keys
+-- @usage ui.command_entry.run(ui.print)
+-- @name run
+function M.run(f, mode_keys, lexer, height)
+ if M:auto_c_active() then M:auto_c_cancel() end -- may happen in curses
+ if not f and not mode_keys then
+ f, mode_keys, lexer = run_lua, lua_mode_keys, 'lua'
+ elseif type(mode_keys) == 'string' then
+ mode_keys, lexer, height = {}, mode_keys, lexer
+ elseif not mode_keys then
+ mode_keys = {}
+ end
+ if not mode_keys['esc'] then mode_keys['esc'] = M.focus end -- hide
+ mode_keys['\n'] = mode_keys['\n'] or function()
+ if M:auto_c_active() then return false end -- allow Enter to autocomplete
+ M.focus() -- hide
+ if f then f((M:get_text())) end
+ end
+ if not getmetatable(mode_keys) then
+ setmetatable(mode_keys, M.editing_keys)
+ end
+ M:select_all()
+ M.focus()
+ M:set_lexer(lexer or 'text')
+ M.height = M:text_height(0) * (height or 1)
+ keys._command_entry, keys.MODE = mode_keys, '_command_entry'
+end
+
+-- Redefine ui.command_entry.focus() to clear any current key mode on hide/show.
+local orig_focus = M.focus
+M.focus = function()
+ keys.MODE = nil
+ orig_focus()
+end
-- Configure the command entry's default properties.
+-- Also find the key binding for `textadept.editing.show_documentation` and use
+-- it to show Lua documentation in the Lua command entry.
events.connect(events.INITIALIZED, function()
M.h_scroll_bar, M.v_scroll_bar = false, false
M.margin_width_n[0], M.margin_width_n[1], M.margin_width_n[2] = 0, 0, 0
M.call_tip_position = true
+ for key, f in pairs(keys) do
+ if f == textadept.editing.show_documentation then
+ lua_mode_keys[key] = function()
+ -- Temporarily change _G.buffer since ui.command_entry is the "active"
+ -- buffer.
+ local orig_buffer = _G.buffer
+ _G.buffer = ui.command_entry
+ textadept.editing.show_documentation()
+ _G.buffer = orig_buffer
+ end
+ break
+ end
+ end
end)
+-- TODO: deprecated; remove after next release.
+M.enter_mode = function() ui.dialogs.ok_msgbox{text='ui.command_entry.enter_mode() is deprecated and will be removed.',informative_text='Please use ui.command_entry.run()',no_cancel=true} end
+M.finish_mode = function() ui.dialogs.ok_msgbox{text='ui.command_entry.finish_mode() is deprecated and will be removed.',informative_text='Please use ui.command_entry.run()',no_cancel=true} end
+
--[[ The function below is a Lua C function.
---