aboutsummaryrefslogtreecommitdiff
path: root/modules/textadept
diff options
context:
space:
mode:
Diffstat (limited to 'modules/textadept')
-rw-r--r--modules/textadept/command_entry.lua167
-rw-r--r--modules/textadept/find.lua23
-rw-r--r--modules/textadept/keys.lua50
-rw-r--r--modules/textadept/menu.lua6
4 files changed, 120 insertions, 126 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.
---
diff --git a/modules/textadept/find.lua b/modules/textadept/find.lua
index b817289f..120abae5 100644
--- a/modules/textadept/find.lua
+++ b/modules/textadept/find.lua
@@ -204,10 +204,31 @@ function M.find_incremental(text, next, anchor)
if text then find_incremental(text, next, anchor) return end
incremental_start = buffer.current_pos
ui.command_entry:set_text('')
- ui.command_entry.enter_mode('find_incremental')
+ ui.command_entry.run(nil, M.find_incremental_keys)
end
---
+-- Table of key bindings used when searching for text incrementally.
+-- @class table
+-- @name find_incremental_keys
+M.find_incremental_keys = setmetatable({
+ ['\n'] = function()
+ M.find_entry_text = ui.command_entry:get_text() -- save
+ M.find_incremental(ui.command_entry:get_text(), true, true)
+ end,
+ ['\b'] = function()
+ local e = ui.command_entry:position_before(ui.command_entry.length)
+ M.find_incremental(ui.command_entry:text_range(0, e), true)
+ return false -- propagate
+ end
+}, {__index = function(_, k)
+ -- Add the character for any key pressed without modifiers to incremental
+ -- find.
+ if #k > 1 and k:find('^[cams]*.+$') then return end
+ M.find_incremental(ui.command_entry:get_text()..k, true)
+end})
+
+---
-- Searches directory *dir* or the user-specified directory for files that match
-- search text and search options (subject to optional filter *filter*), and
-- prints the results to a buffer titled "Files Found", highlighting found text.
diff --git a/modules/textadept/keys.lua b/modules/textadept/keys.lua
index 2d9cc31f..e2968ab6 100644
--- a/modules/textadept/keys.lua
+++ b/modules/textadept/keys.lua
@@ -532,8 +532,8 @@ elseif CURSES then
end
-- Unbound keys are handled by Scintilla, but when playing back a macro, this is
--- not possible. Define useful default keybindings so Scintilla does not have to
--- handle them.
+-- not possible. Define useful default key bindings so Scintilla does not have
+-- to handle them.
keys.left, keys.sleft = buffer.char_left, buffer.char_left_extend
keys.cleft, keys.csleft = buffer.word_left, buffer.word_left_extend
keys.right, keys.sright = buffer.char_right, buffer.char_right_extend
@@ -555,50 +555,16 @@ keys['\b'], keys['s\b'] = buffer.delete_back, buffer.delete_back
keys[not OSX and 'c\b' or 'm\b'] = buffer.del_word_left
keys[not OSX and 'cs\b' or 'ms\b'] = buffer.del_line_left
--- Modes.
-keys.filter_through = {
- ['\n'] = function()
- return ui.command_entry.finish_mode(textadept.editing.filter_through)
- end,
-}
-keys.find_incremental = {
- ['\n'] = function()
- ui.find.find_entry_text = ui.command_entry:get_text() -- save
- ui.find.find_incremental(ui.command_entry:get_text(), true, true)
- end,
- ['cr'] = function()
- ui.find.find_incremental(ui.command_entry:get_text(), false, true)
- end,
- ['\b'] = function()
- local e = ui.command_entry:position_before(ui.command_entry.length)
- ui.find.find_incremental(ui.command_entry:text_range(0, e), true)
- return false -- propagate
- end
-}
--- Add the character for any key pressed without modifiers to incremental find.
-setmetatable(keys.find_incremental, {__index = function(_, k)
- if #k > 1 and k:find('^[cams]*.+$') then return end
- ui.find.find_incremental(ui.command_entry:get_text()..k, true)
- end})
--- Show documentation for symbols in the Lua command entry.
-keys.lua_command[GUI and 'ch' or 'mh'] = 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
+-- Other.
+ui.find.find_incremental_keys.cr = function()
+ ui.find.find_incremental(ui.command_entry:get_text(), false, true) -- reverse
end
if OSX or CURSES then
-- UTF-8 input.
- keys.utf8_input = {
- ['\n'] = function()
- return ui.command_entry.finish_mode(function(code)
- buffer:add_text(utf8.char(tonumber(code, 16)))
- end)
- end
- }
keys[OSX and 'mU' or 'mu'] = function()
- ui.command_entry.enter_mode('utf8_input')
+ ui.command_entry.run(function(code)
+ buffer:add_text(utf8.char(tonumber(code, 16)))
+ end)
end
end
diff --git a/modules/textadept/menu.lua b/modules/textadept/menu.lua
index caaa3463..9b4cb9a4 100644
--- a/modules/textadept/menu.lua
+++ b/modules/textadept/menu.lua
@@ -103,7 +103,7 @@ local default_menubar = {
{_L['T_ranspose Characters'], textadept.editing.transpose_chars},
{_L['_Join Lines'], textadept.editing.join_lines},
{_L['_Filter Through'], function()
- ui.command_entry.enter_mode('filter_through', 'bash')
+ ui.command_entry.run(textadept.editing.filter_through, 'bash')
end},
{
title = _L['_Select'],
@@ -163,9 +163,7 @@ local default_menubar = {
},
{
title = _L['_Tools'],
- {_L['Command _Entry'], function()
- ui.command_entry.enter_mode('lua_command', 'lua')
- end},
+ {_L['Command _Entry'], ui.command_entry.run},
{_L['Select Co_mmand'], function() M.select_command() end},
SEPARATOR,
{_L['_Run'], textadept.run.run},