aboutsummaryrefslogtreecommitdiff
path: root/modules/textadept
diff options
context:
space:
mode:
authormitchell <70453897+667e-11@users.noreply.github.com>2013-04-11 23:58:33 -0400
committermitchell <70453897+667e-11@users.noreply.github.com>2013-04-11 23:58:33 -0400
commita65f9ac0c460fba64b2d8ddde2149661c025ea65 (patch)
tree9f1d3e7b73756b264974d0be272a722fc92e483e /modules/textadept
parent2a54e9fcfd955b8cf63fa42f41292d1176026721 (diff)
downloadtextadept-a65f9ac0c460fba64b2d8ddde2149661c025ea65.tar.gz
textadept-a65f9ac0c460fba64b2d8ddde2149661c025ea65.zip
Added key modes and changed the command entry to use them.
Removed obsoleted `events.COMMAND_ENTRY_COMMAND`.
Diffstat (limited to 'modules/textadept')
-rw-r--r--modules/textadept/command_entry.lua172
-rw-r--r--modules/textadept/filter_through.lua87
-rw-r--r--modules/textadept/find.lua129
-rw-r--r--modules/textadept/keys.lua28
-rw-r--r--modules/textadept/menu.lua4
5 files changed, 249 insertions, 171 deletions
diff --git a/modules/textadept/command_entry.lua b/modules/textadept/command_entry.lua
index 7e52282b..005af837 100644
--- a/modules/textadept/command_entry.lua
+++ b/modules/textadept/command_entry.lua
@@ -1,13 +1,79 @@
-- Copyright 2007-2013 Mitchell mitchell.att.foicica.com. See LICENSE.
--- Modified by Jay Gould.
+-- Abbreviated environment and commands from Jay Gould.
+
+local M = gui.command_entry
--[[ This comment is for LuaDoc.
---
-- Textadept's Command Entry.
+--
+-- ## Modes
+--
+-- The command entry supports multiple [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 used for
+-- looking up key bindings. An example mode is "lua_command" mode for executing
+-- Lua commands:
+--
+-- local gui_ce = gui.command_entry
+-- keys['ce'] = {gui_ce.enter_mode, 'lua_command'}
+-- keys.lua_command = {
+-- ['\t'] = gui_ce.complete_lua,
+-- ['\n'] = {gui_ce.finish_mode, gui_ce.execute_lua}
+-- }
+--
+-- 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, `Esc` is pre-defined 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. All other keys are
+-- handled normally by the command entry.
+--
+-- It is important to note that while in any command entry key mode, all editor
+-- key bindings are ignored -- even if the editor, not the command entry, has
+-- focus. You must first exit the key mode by pressing `Esc` (or `Enter` in the
+-- case of the above "lua_command" key mode).
+--
+-- [modes]: keys.html#Modes
-- @field entry_text (string)
-- The text in the entry.
module('gui.command_entry')]]
+---
+-- Opens the command entry in key mode *mode*.
+-- Key bindings will be looked up in `keys[mode]` instead of `keys`. The `Esc`
+-- (`⎋` on Mac OSX | `Esc` in curses) 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.
+-- @usage keys['ce'] = {gui.command_entry.enter_mode, 'command_entry'}
+-- @see _G.keys.MODE
+-- @name enter_mode
+function M.enter_mode(mode)
+ keys.MODE = mode
+ if mode then keys[mode]['esc'] = M.enter_mode end
+ -- In curses, M.focus() does not return immediately, so the key sequence that
+ -- called M.focus() is still on the keychain. Clear it.
+ if CURSES then keys.clear_key_sequence() end
+ M.focus()
+end
+
+---
+-- Exits the current key mode, closes the command entry, and calls function *f*
+-- with the command entry 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 The function to call. It should accept the command entry text as an
+-- argument.
+-- @usage keys['\n'] = {gui.command_entry.finish_mode, gui.print}
+-- @name finish_mode
+function M.finish_mode(f)
+ M.enter_mode(nil)
+ f(M.entry_text)
+ if CURSES then return false end -- propagate to exit CDK entry on Enter
+end
+
-- Environment for abbreviated commands.
-- @class table
-- @name env
@@ -29,71 +95,73 @@ local env = setmetatable({}, {
end,
})
-local events = events
-
--- Execute a Lua command.
-events.connect(events.COMMAND_ENTRY_COMMAND, function(command)
- local f, err = load(command, nil, 'bt', env)
+---
+-- Executes string *code* as Lua code.
+-- Code is subject to an "abbreviated" environment where the `buffer`, `view`,
+-- and `gui` tables are also considered as globals.
+-- @param code The Lua code to execute.
+-- @name execute_lua
+function M.execute_lua(code)
+ local f, err = load(code, nil, 'bt', env)
if err then error(err) end
- if not CURSES then gui.command_entry.focus() end -- toggle focus to hide
f()
events.emit(events.UPDATE_UI)
-end)
+end
+args.register('-e', '--execute', 1, M.execute_lua, 'Execute Lua code')
-events.connect(events.COMMAND_ENTRY_KEYPRESS, function(code)
- if keys.KEYSYMS[code] == 'esc' then
- gui.command_entry.focus() -- toggle focus to hide
- elseif keys.KEYSYMS[code] == '\t' then
- local substring = gui.command_entry.entry_text:match('[%w_.:]+$') or ''
- local path, o, prefix = substring:match('^([%w_.:]-)([.:]?)([%w_]*)$')
- local f, err = load('return ('..path..')', nil, 'bt', env)
- local ok, tbl = pcall(f)
- local cmpls = {}
- prefix = '^'..prefix
- if not ok then -- shorthand notation
- for _, t in ipairs{buffer, view, gui, _G} do
- for k in pairs(t) do
- if type(k) == 'string' and k:find(prefix) then
- cmpls[#cmpls + 1] = k
- end
- end
+---
+-- Shows a set of Lua code completions for string *code* or `entry_text`.
+-- Completions are subject to an "abbreviated" environment where the `buffer`,
+-- `view`, and `gui` tables are also considered as globals.
+-- @param code The Lua code to complete. The default value is the value of
+-- `entry_text`.
+-- @name complete_lua
+function M.complete_lua(code)
+ local substring = (code or M.entry_text):match('[%w_.:]+$') or ''
+ local path, op, prefix = substring:match('^([%w_.:]-)([.:]?)([%w_]*)$')
+ local f, err = load('return ('..path..')', nil, 'bt', env)
+ local ok, tbl = pcall(f)
+ local cmpls = {}
+ prefix = '^'..prefix
+ if not ok then -- shorthand notation
+ for _, t in ipairs{buffer, view, gui, _G} do
+ for k in pairs(t) do
+ if type(k) == 'string' and k:find(prefix) then cmpls[#cmpls + 1] = k end
end
+ end
+ for f in pairs(_SCINTILLA.functions) do
+ if f:find(prefix) then cmpls[#cmpls + 1] = f end
+ end
+ for p in pairs(_SCINTILLA.properties) do
+ if p:find(prefix) then cmpls[#cmpls + 1] = p end
+ end
+ else
+ if type(tbl) ~= 'table' then return end
+ for k in pairs(tbl) do
+ if type(k) == 'string' and k:find(prefix) then cmpls[#cmpls + 1] = k end
+ end
+ if path == 'buffer' and op == ':' then
for f in pairs(_SCINTILLA.functions) do
if f:find(prefix) then cmpls[#cmpls + 1] = f end
end
+ elseif path == 'buffer' and op == '.' then
for p in pairs(_SCINTILLA.properties) do
if p:find(prefix) then cmpls[#cmpls + 1] = p end
end
- else
- if type(tbl) ~= 'table' then return end
- for k in pairs(tbl) do
- if type(k) == 'string' and k:find(prefix) then cmpls[#cmpls + 1] = k end
- end
- if path == 'buffer' then
- if o == ':' then
- for f in pairs(_SCINTILLA.functions) do
- if f:find(prefix) then cmpls[#cmpls + 1] = f end
- end
- else
- for p in pairs(_SCINTILLA.properties) do
- if p:find(prefix) then cmpls[#cmpls + 1] = p end
- end
- end
- end
end
- table.sort(cmpls)
- gui.command_entry.show_completions(cmpls)
- return true
end
-end)
-
--- Executes Lua code on startup.
-local function execute(command)
- local f, err = load(command, nil, 'bt', env)
- if err then error(err) end
- f()
+ table.sort(cmpls)
+ M.show_completions(cmpls)
+ return true
end
-args.register('-e', '--execute', 1, execute, 'Execute Lua code')
+
+local events = events
+-- Pass command entry keys to the default keypress handler.
+-- Since the command entry is designed to be modal, command entry key bindings
+-- should stay separate from editor key bindings.
+events.connect(events.COMMAND_ENTRY_KEYPRESS, function(...)
+ if keys.MODE then return events.emit(events.KEYPRESS, ...) end
+end)
--[[ The function below is a Lua C function.
diff --git a/modules/textadept/filter_through.lua b/modules/textadept/filter_through.lua
index fbff074c..59cb77b0 100644
--- a/modules/textadept/filter_through.lua
+++ b/modules/textadept/filter_through.lua
@@ -9,11 +9,12 @@ module('_M.textadept.filter_through')]]
local cat = not WIN32 and 'cat' or 'type'
local tmpfile = _USERHOME..'/.ft'
-local filter_through_active = false
---
--- Prompts the user for a Linux, BSD, Mac OSX, or Windows shell command to
--- filter text through with standard input (stdin) as follows:
+-- Passes selected or all buffer text to string shell command *cmd* as standard
+-- input (stdin) and replaces the input text with the command's standard output
+-- (stdout).
+-- Standard input is as follows:
--
-- 1. If text is selected and spans multiple lines, all text on the lines
-- containing the selection is used. However, if the end of the selection is at
@@ -22,57 +23,39 @@ local filter_through_active = false
-- 2. If text is selected and spans a single line, only the selected text is
-- used.
-- 3. If no text is selected, the entire buffer is used.
---
--- The input text is replaced with the standard output (stdout) of the command.
+-- @param cmd The Linux, BSD, Mac OSX, or Windows shell command to filter text
+-- through.
-- @name filter_through
-function M.filter_through()
- filter_through_active = true
- gui.command_entry.focus()
-end
-
-local events = events
-
-events.connect(events.COMMAND_ENTRY_KEYPRESS, function(code)
- if filter_through_active and keys.KEYSYMS[code] == 'esc' then
- filter_through_active = false
- end
-end, 1) -- place before command_entry.lua's handler (if necessary)
-
--- Filter through.
-events.connect(events.COMMAND_ENTRY_COMMAND, function(text)
- if filter_through_active then
- local buffer = buffer
- local s, e = buffer.selection_start, buffer.selection_end
- local input
- if s ~= e then -- use selected lines as input
- local i, j = buffer:line_from_position(s), buffer:line_from_position(e)
- if i < j then
- s = buffer:position_from_line(i)
- if buffer.column[e] > 0 then e = buffer:position_from_line(j + 1) end
- end
- input = buffer:text_range(s, e)
- else -- use whole buffer as input
- input = buffer:get_text()
- end
- local f = io.open(tmpfile, 'wb')
- f:write(input)
- f:close()
- local cmd = cat..' "'..tmpfile..'" | '..text
- if WIN32 then cmd = cmd:gsub('/', '\\') end
- local p = io.popen(cmd)
- if s ~= e then
- buffer.target_start, buffer.target_end = s, e
- buffer:replace_target(p:read('*all'))
- buffer:set_sel(buffer.target_start, buffer.target_end)
- else
- buffer:set_text(p:read('*all'))
- buffer:goto_pos(s)
+function M.filter_through(cmd)
+ local buffer = buffer
+ local s, e = buffer.selection_start, buffer.selection_end
+ local input
+ if s ~= e then -- use selected lines as input
+ local i, j = buffer:line_from_position(s), buffer:line_from_position(e)
+ if i < j then
+ s = buffer:position_from_line(i)
+ if buffer.column[e] > 0 then e = buffer:position_from_line(j + 1) end
end
- p:close()
- os.remove(tmpfile)
- filter_through_active = false
- return true
+ input = buffer:text_range(s, e)
+ else -- use whole buffer as input
+ input = buffer:get_text()
end
-end, 1) -- place before command_entry.lua's handler (if necessary)
+ local f = io.open(tmpfile, 'wb')
+ f:write(input)
+ f:close()
+ local cmd = cat..' "'..tmpfile..'" | '..cmd
+ if WIN32 then cmd = cmd:gsub('/', '\\') end
+ local p = io.popen(cmd)
+ if s ~= e then
+ buffer.target_start, buffer.target_end = s, e
+ buffer:replace_target(p:read('*all'))
+ buffer:set_sel(buffer.target_start, buffer.target_end)
+ else
+ buffer:set_text(p:read('*all'))
+ buffer:goto_pos(s)
+ end
+ p:close()
+ os.remove(tmpfile)
+end
return M
diff --git a/modules/textadept/find.lua b/modules/textadept/find.lua
index d1105a7b..801c333f 100644
--- a/modules/textadept/find.lua
+++ b/modules/textadept/find.lua
@@ -1,6 +1,6 @@
-- Copyright 2007-2013 Mitchell mitchell.att.foicica.com. See LICENSE.
-local find = gui.find
+local M = gui.find
--[[ This comment is for LuaDoc.
---
@@ -60,17 +60,17 @@ local find = gui.find
module('gui.find')]]
local _L = _L
-find.find_label_text = not CURSES and _L['_Find:'] or _L['Find:']
-find.replace_label_text = not CURSES and _L['R_eplace:'] or _L['Replace:']
-find.find_next_button_text = not CURSES and _L['Find _Next'] or _L['[Next]']
-find.find_prev_button_text = not CURSES and _L['Find _Prev'] or _L['[Prev]']
-find.replace_button_text = not CURSES and _L['_Replace'] or _L['[Replace]']
-find.replace_all_button_text = not CURSES and _L['Replace _All'] or _L['[All]']
-find.match_case_label_text = not CURSES and _L['_Match case'] or _L['Case(F1)']
-find.whole_word_label_text = not CURSES and _L['_Whole word'] or _L['Word(F2)']
-find.lua_pattern_label_text = not CURSES and _L['_Lua pattern'] or
- _L['Pattern(F3)']
-find.in_files_label_text = not CURSES and _L['_In files'] or _L['Files(F4)']
+M.find_label_text = not CURSES and _L['_Find:'] or _L['Find:']
+M.replace_label_text = not CURSES and _L['R_eplace:'] or _L['Replace:']
+M.find_next_button_text = not CURSES and _L['Find _Next'] or _L['[Next]']
+M.find_prev_button_text = not CURSES and _L['Find _Prev'] or _L['[Prev]']
+M.replace_button_text = not CURSES and _L['_Replace'] or _L['[Replace]']
+M.replace_all_button_text = not CURSES and _L['Replace _All'] or _L['[All]']
+M.match_case_label_text = not CURSES and _L['_Match case'] or _L['Case(F1)']
+M.whole_word_label_text = not CURSES and _L['_Whole word'] or _L['Word(F2)']
+M.lua_pattern_label_text = not CURSES and _L['_Lua pattern'] or
+ _L['Pattern(F3)']
+M.in_files_label_text = not CURSES and _L['_In files'] or _L['Files(F4)']
-- Events.
local events, events_connect = events, events.connect
@@ -94,7 +94,7 @@ local preferred_view
-- @see find_in_files
-- @class table
-- @name FILTER
-find.FILTER = lfs.FILTER
+M.FILTER = lfs.FILTER
-- Text escape sequences with their associated characters.
-- @class table
@@ -114,7 +114,7 @@ local escapes = {
-- the user is prompted for one.
-- @see FILTER
-- @name find_in_files
-function find.find_in_files(utf8_dir)
+function M.find_in_files(utf8_dir)
if not utf8_dir then
utf8_dir = gui.dialog('fileselect',
'--title', _L['Find in Files'],
@@ -125,13 +125,13 @@ function find.find_in_files(utf8_dir)
end
if utf8_dir == '' then return end
- local text = find.find_entry_text
- if not find.lua then text = text:gsub('([().*+?^$%%[%]-])', '%%%1') end
- if not find.match_case then text = text:lower() end
- if find.whole_word then text = '%f[%w_]'..text..'%f[^%w_]' end
+ local text = M.find_entry_text
+ if not M.lua then text = text:gsub('([().*+?^$%%[%]-])', '%%%1') end
+ if not M.match_case then text = text:lower() end
+ if M.whole_word then text = '%f[%w_]'..text..'%f[^%w_]' end
local matches = {_L['Find:']..' '..text}
lfs.dir_foreach(utf8_dir, function(file)
- local match_case = find.match_case
+ local match_case = M.match_case
local line_num = 1
for line in io.lines(file) do
if (match_case and line or line:lower()):find(text) then
@@ -140,7 +140,7 @@ function find.find_in_files(utf8_dir)
end
line_num = line_num + 1
end
- end, find.FILTER, true)
+ end, M.FILTER, true)
if #matches == 1 then matches[2] = _L['No results found'] end
matches[#matches + 1] = ''
if buffer._type ~= _L['[Files Found Buffer]'] then preferred_view = view end
@@ -174,14 +174,14 @@ local function find_(text, next, flags, nowrap, wrapped)
if not flags then
flags = 0
- if find.match_case then flags = flags + c.SCFIND_MATCHCASE end
- if find.whole_word then flags = flags + c.SCFIND_WHOLEWORD end
- if find.lua then flags = flags + 8 end
- if find.in_files then flags = flags + 16 end
+ if M.match_case then flags = flags + c.SCFIND_MATCHCASE end
+ if M.whole_word then flags = flags + c.SCFIND_WHOLEWORD end
+ if M.lua then flags = flags + 8 end
+ if M.in_files then flags = flags + 16 end
end
local result
- find.captures = nil
+ M.captures = nil
if flags < 8 then
buffer:goto_pos(buffer[next and 'current_pos' or 'anchor'] + increment)
@@ -193,12 +193,12 @@ local function find_(text, next, flags, nowrap, wrapped)
local buffer_text = buffer:get_text(buffer.length)
local results = {buffer_text:find(text, buffer.anchor + increment + 1)}
if #results > 0 then
- find.captures = {table.unpack(results, 3)}
+ M.captures = {table.unpack(results, 3)}
buffer:set_sel(results[2], results[1] - 1)
end
result = results[1] or -1
else -- find in files
- find.find_in_files()
+ M.find_in_files()
return
end
@@ -222,47 +222,52 @@ local function find_(text, next, flags, nowrap, wrapped)
end
events_connect(events.FIND, find_)
--- Finds and selects text incrementally in the current buffer from a start
--- point.
+-- Finds and selects text incrementally in the current buffer from a starting
+-- position.
-- Flags other than `SCFIND_MATCHCASE` are ignored.
-- @param text The text to find.
-local function find_incremental(text)
- local flags = find.match_case and c.SCFIND_MATCHCASE or 0
- buffer:goto_pos(find.incremental_start or 0)
- find_(text, true, flags)
+-- @param next Flag indicating whether or not the search direction is forward.
+local function find_incremental(text, next)
+ buffer:goto_pos(M.incremental_start or 0)
+ find_(text, next, M.match_case and c.SCFIND_MATCHCASE or 0)
end
---
--- Begins an incremental find using the command entry.
+-- Begins an incremental search using the command entry if *text* is `nil`;
+-- otherwise continues an incremental search by searching for the next instance
+-- of string *text*.
-- Only the `match_case` find option is recognized. Normal command entry
--- functionality will be unavailable until the search is finished by pressing
--- `Esc` (`⎋` on Mac OSX | `Esc` in curses).
+-- functionality is unavailable until the search is finished by pressing `Esc`
+-- (`⎋` on Mac OSX | `Esc` in curses).
+-- @param text The text to incrementally search for, or `nil` to begin an
+-- incremental search.
-- @name find_incremental
-function find.find_incremental()
- find.incremental, find.incremental_start = true, buffer.current_pos
+function M.find_incremental(text)
+ if text then find_incremental(text, true) return end
+ M.incremental_start = buffer.current_pos
gui.command_entry.entry_text = ''
- gui.command_entry.focus()
+ gui.command_entry.enter_mode('find_incremental')
end
-events_connect(events.COMMAND_ENTRY_KEYPRESS, function(code)
- if not find.incremental then return end
- if keys.KEYSYMS[code] == 'esc' then
- find.incremental = nil
- elseif keys.KEYSYMS[code] == '\b' then
- find_incremental(gui.command_entry.entry_text:sub(1, -2))
- elseif code < 256 then
- find_incremental(gui.command_entry.entry_text..string.char(code))
- end
-end, 1) -- place before command_entry.lua's handler (if necessary)
-
--- "Find next" for incremental search.
-events_connect(events.COMMAND_ENTRY_COMMAND, function(text)
- if find.incremental then
- find.incremental_start = buffer.current_pos + 1
- find_incremental(text)
- return true
- end
-end, 1) -- place before command_entry.lua's handler (if necessary)
+---
+-- Continues an incremental search by searching for the next match starting from
+-- the current position.
+-- @see find_incremental
+-- @name find_incremental_next
+function M.find_incremental_next()
+ M.incremental_start = buffer.current_pos + 1
+ find_incremental(gui.command_entry.entry_text, true)
+end
+
+---
+-- Continues an incremental search by searching for the previous match starting
+-- from the current position.
+-- @see find_incremental
+-- @name find_incremental_prev
+function M.find_incremental_prev()
+ M.incremental_start = buffer.current_pos - 1
+ find_incremental(gui.command_entry.entry_text, false)
+end
-- Optimize for speed.
local load, pcall = load, pcall
@@ -295,11 +300,11 @@ end
-- @see find
local function replace(rtext)
if buffer:get_sel_text() == '' then return end
- if find.in_files then find.in_files = false end
+ if M.in_files then M.in_files = false end
local buffer = buffer
buffer:target_from_selection()
rtext = rtext:gsub('%%%%', '\\037') -- escape '%%'
- local captures = find.captures
+ local captures = M.captures
if captures then
for i = 1, #captures do
rtext = rtext:gsub('%%'..i, (captures[i]:gsub('%%', '%%%%')))
@@ -326,7 +331,7 @@ events_connect(events.REPLACE, replace)
-- @see find
local function replace_all(ftext, rtext)
if ftext == '' then return end
- if find.in_files then find.in_files = false end
+ if M.in_files then M.in_files = false end
local buffer = buffer
buffer:begin_undo_action()
local count = 0
@@ -389,7 +394,7 @@ events_connect(events.DOUBLE_CLICK, goto_file)
-- @param next Optional flag indicating whether or not to go to the next file.
-- The default value is `false`.
-- @name goto_file_in_list
-function find.goto_file_in_list(next)
+function M.goto_file_in_list(next)
local orig_view = _VIEWS[view]
for _, buffer in ipairs(_BUFFERS) do
if buffer._type == _L['[Files Found Buffer]'] then
diff --git a/modules/textadept/keys.lua b/modules/textadept/keys.lua
index 8fa15a19..e2d41770 100644
--- a/modules/textadept/keys.lua
+++ b/modules/textadept/keys.lua
@@ -298,7 +298,8 @@ events.connect(events.BUFFER_NEW, constantize_menu_buffer_functions)
if not RESETTING then constantize_menu_buffer_functions() end
local keys = keys
-local io, gui, gui_find, buffer, view = io, gui, gui.find, buffer, view
+local io, gui, gui_find, gui_ce = io, gui, gui.find, gui.command_entry
+local buffer, view = buffer, view
local m_textadept, m_editing = _M.textadept, _M.textadept.editing
local m_bookmarks, m_snippets = m_textadept.bookmarks, m_textadept.snippets
local OSX, c = OSX, _SCINTILLA.constants
@@ -466,13 +467,13 @@ keys[not OSX and 'cj' or 'mj'] = m_editing.goto_line
-- Tools.
keys[not OSX and (not CURSES and 'ce' or 'mc')
- or 'me'] = gui.command_entry.focus
+ or 'me'] = {gui_ce.enter_mode, 'lua_command'}
keys[not OSX and (not CURSES and 'cE' or 'mC') or 'mE'] = utils.select_command
keys[not OSX and 'cr' or 'mr'] = m_textadept.run.run
keys[not OSX and (not CURSES and 'cR' or 'cmr')
or 'mR'] = m_textadept.run.compile
keys[not OSX and (not CURSES and 'c|' or 'c\\')
- or 'm|'] = m_textadept.filter_through.filter_through
+ or 'm|'] = {gui_ce.enter_mode, 'filter_through'}
-- Adeptsense.
keys[not OSX and (not CURSES and 'c ' or 'c@')
or 'aesc'] = m_textadept.adeptsense.complete
@@ -594,4 +595,25 @@ elseif CURSES then
keys.ck = utils.cut_to_eol
end
+-- Modes.
+keys.lua_command = {
+ ['\t'] = gui_ce.complete_lua,
+ ['\n'] = {gui_ce.finish_mode, gui_ce.execute_lua}
+}
+keys.filter_through = {
+ ['\n'] = {gui_ce.finish_mode, m_textadept.filter_through.filter_through},
+}
+keys.find_incremental = {
+ ['\n'] = gui_find.find_incremental_next,
+ ['cr'] = gui_find.find_incremental_prev,
+ ['\b'] = function()
+ gui_find.find_incremental(gui_ce.entry_text:sub(1, -2))
+ return false -- propagate
+ end
+}
+setmetatable(keys.find_incremental, {__index = function(t, k)
+ if #k > 1 and k:find('^[cams]*.+$') then return end
+ gui_find.find_incremental(gui_ce.entry_text..k)
+ end})
+
return M
diff --git a/modules/textadept/menu.lua b/modules/textadept/menu.lua
index f4784b5d..583b3f46 100644
--- a/modules/textadept/menu.lua
+++ b/modules/textadept/menu.lua
@@ -119,12 +119,12 @@ M.menubar = {
{_L['_Jump to'], m_editing.goto_line},
},
{ title = _L['_Tools'],
- {_L['Command _Entry'], gui.command_entry.focus},
+ {_L['Command _Entry'], {gui.command_entry.enter_mode, 'lua_command'}},
{_L['Select Co_mmand'], utils.select_command},
SEPARATOR,
{_L['_Run'], m_textadept.run.run},
{_L['_Compile'], m_textadept.run.compile},
- {_L['_Filter Through'], _M.textadept.filter_through.filter_through},
+ {_L['_Filter Through'], {gui.command_entry.enter_mode, 'filter_through'}},
SEPARATOR,
{ title = _L['_Adeptsense'],
{_L['_Complete Symbol'], m_textadept.adeptsense.complete},