aboutsummaryrefslogtreecommitdiffhomepage
path: root/modules/textadept
diff options
context:
space:
mode:
authorGravatar mitchell <70453897+orbitalquark@users.noreply.github.com>2021-04-11 09:34:17 -0400
committerGravatar mitchell <70453897+orbitalquark@users.noreply.github.com>2021-04-11 09:34:17 -0400
commitde3a745e1af2e441de868c2aa4849102d376acb5 (patch)
treec2d7767600dc519b2613ddecaf7e53fb5e8867a2 /modules/textadept
parent03fab17277fee7387fd93a9c2774b1ebf3f80fe4 (diff)
Initial pass reformatting all code.
Use clang-format, LuaFormatter, and 100 character limit on lines.
Diffstat (limited to 'modules/textadept')
-rw-r--r--modules/textadept/bookmarks.lua27
-rw-r--r--modules/textadept/command_entry.lua144
-rw-r--r--modules/textadept/editing.lua255
-rw-r--r--modules/textadept/file_types.lua34
-rw-r--r--modules/textadept/find.lua225
-rw-r--r--modules/textadept/history.lua87
-rw-r--r--modules/textadept/init.lua4
-rw-r--r--modules/textadept/keys.lua499
-rw-r--r--modules/textadept/macros.lua40
-rw-r--r--modules/textadept/menu.lua162
-rw-r--r--modules/textadept/run.lua348
-rw-r--r--modules/textadept/session.lua71
-rw-r--r--modules/textadept/snippets.lua334
13 files changed, 1040 insertions, 1190 deletions
diff --git a/modules/textadept/bookmarks.lua b/modules/textadept/bookmarks.lua
index b790fd09..532d1427 100644
--- a/modules/textadept/bookmarks.lua
+++ b/modules/textadept/bookmarks.lua
@@ -35,13 +35,13 @@ local function bookmarks(buffer)
end
---
--- Prompts the user to select a bookmarked line to move the caret to the
--- beginning of unless *next* is given.
--- If *next* is `true` or `false`, moves the caret to the beginning of the next
--- or previously bookmarked line, respectively.
--- @param next Optional flag indicating whether to go to the next or previous
--- bookmarked line relative to the current line. The default value is `nil`,
--- prompting the user for a bookmarked line to go to.
+-- Prompts the user to select a bookmarked line to move the caret to the beginning of unless
+-- *next* is given.
+-- If *next* is `true` or `false`, moves the caret to the beginning of the next or previously
+-- bookmarked line, respectively.
+-- @param next Optional flag indicating whether to go to the next or previous bookmarked
+-- line relative to the current line. The default value is `nil`, prompting the user for a
+-- bookmarked line to go to.
-- @name goto_mark
function M.goto_mark(next)
if next ~= nil then
@@ -49,9 +49,7 @@ function M.goto_mark(next)
local line = buffer:line_from_position(buffer.current_pos)
local BOOKMARK_BIT = 1 << M.MARK_BOOKMARK - 1
line = f(buffer, line + (next and 1 or -1), BOOKMARK_BIT)
- if line == -1 then
- line = f(buffer, (next and 1 or buffer.line_count), BOOKMARK_BIT)
- end
+ if line == -1 then line = f(buffer, (next and 1 or buffer.line_count), BOOKMARK_BIT) end
if line >= 1 then textadept.editing.goto_line(line) end
return
end
@@ -64,8 +62,8 @@ function M.goto_mark(next)
if buffer.filename then filename = filename:iconv('UTF-8', _CHARSET) end
local basename = buffer.filename and filename:match('[^/\\]+$') or filename
for line in bookmarks(buffer) do
- utf8_list[#utf8_list + 1] = string.format(
- '%s:%d: %s', basename, line, buffer:get_line(line):match('^[^\r\n]*'))
+ utf8_list[#utf8_list + 1] = string.format('%s:%d: %s', basename, line,
+ buffer:get_line(line):match('^[^\r\n]*'))
buffers[#buffers + 1] = buffer
end
::continue::
@@ -83,9 +81,8 @@ end
local lines = {}
-- Save and restore bookmarks on buffer:reload().
-events.connect(events.FILE_BEFORE_RELOAD, function()
- for line in bookmarks(buffer) do lines[#lines + 1] = line end
-end)
+events.connect(events.FILE_BEFORE_RELOAD,
+ function() for line in bookmarks(buffer) do lines[#lines + 1] = line end end)
events.connect(events.FILE_AFTER_RELOAD, function()
for _, line in ipairs(lines) do buffer:marker_add(line, M.MARK_BOOKMARK) end
lines = {} -- clear
diff --git a/modules/textadept/command_entry.lua b/modules/textadept/command_entry.lua
index 14e66a07..cecad02c 100644
--- a/modules/textadept/command_entry.lua
+++ b/modules/textadept/command_entry.lua
@@ -6,8 +6,8 @@ local M = ui.command_entry
--[[ This comment is for LuaDoc.
---
-- Textadept's Command Entry.
--- It supports multiple modes that each have their own functionality (such as
--- running Lua code and filtering text through shell commands) and history.
+-- It supports multiple modes that each have their own functionality (such as running Lua code
+-- and filtering text through shell commands) and history.
-- @field height (number)
-- The height in pixels of the command entry.
-- @field active (boolean)
@@ -18,16 +18,21 @@ module('ui.command_entry')]]
-- The current mode is in the `mode` field.
-- @class table
-- @name history
-local history = setmetatable({}, {__index = function(t, k)
- if type(k) == 'function' then t[k] = {pos = 0} else return nil end
- return t[k]
-end})
+local history = setmetatable({}, {
+ __index = function(t, k)
+ if type(k) ~= 'function' then return nil end
+ t[k] = {pos = 0}
+ return t[k]
+ end
+})
-- Cycles through command history for the current mode.
--- @param prev Flag that indicates whether to cycle to the previous command or
--- the next one.
+-- @param prev Flag that indicates whether to cycle to the previous command or the next one.
local function cycle_history(prev)
- if M:auto_c_active() then M[prev and 'line_up' or 'line_down'](M) return end
+ if M:auto_c_active() then
+ M[prev and 'line_up' or 'line_down'](M)
+ return
+ end
local mode_history = history[history.mode]
if not mode_history or prev and mode_history.pos <= 1 then return end
if not prev and mode_history.pos >= #mode_history then return end
@@ -38,14 +43,12 @@ local function cycle_history(prev)
end
---
--- Appends string *text* to the history for command entry mode *f* or the
--- current or most recent mode.
--- This should only be called if `ui.command_entry.run()` is called with a keys
--- table that has a custom binding for the Enter key ('\n').
--- Otherwise, history is automatically appended as needed.
--- @param f Optional command entry mode to append history to. This is a function
--- passed to `ui.command_entry_run()`. If omitted, uses the current or most
--- recent mode.
+-- Appends string *text* to the history for command entry mode *f* or the current or most
+-- recent mode.
+-- This should only be called if `ui.command_entry.run()` is called with a keys table that has a
+-- custom binding for the Enter key ('\n'). Otherwise, history is automatically appended as needed.
+-- @param f Optional command entry mode to append history to. This is a function passed to
+-- `ui.command_entry_run()`. If omitted, uses the current or most recent mode.
-- @param text String text to append to history.
-- @name append_history
function M.append_history(f, text)
@@ -59,9 +62,8 @@ end
---
-- A metatable with typical platform-specific key bindings for text entries.
--- 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.
+-- 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
@@ -69,8 +71,7 @@ M.editing_keys = {__index = {}}
-- Fill in default key bindings for Linux/Win32, macOS, Terminal.
local bindings = {
- -- Note: cannot use `M.cut`, `M.copy`, etc. since M is never considered the
- -- global buffer.
+ -- Note: cannot use `M.cut`, `M.copy`, etc. since M is never considered the global buffer.
[function() M:undo() end] = {'ctrl+z', 'cmd+z', 'ctrl+z'},
[function() M:undo() end] = {nil, nil, 'meta+z'},
[function() M:redo() end] = {'ctrl+y', 'cmd+Z', 'ctrl+y'},
@@ -80,7 +81,7 @@ local bindings = {
[function() M:paste() end] = {'ctrl+v', 'cmd+v', 'ctrl+v'},
[function() M:select_all() end] = {'ctrl+a', 'cmd+a', 'meta+a'},
[function() cycle_history(true) end] = {'up', 'up', 'up'},
- [cycle_history] = {'down', 'down', 'down'},
+ [cycle_history] = {'down', 'down', 'down'}, -- LuaFormatter
-- Movement keys.
[function() M:char_right() end] = {nil, 'ctrl+f', 'ctrl+f'},
[function() M:char_left() end] = {nil, 'ctrl+b', 'ctrl+b'},
@@ -104,25 +105,26 @@ local env = setmetatable({}, {
return function(...) view[k](view, ...) end -- do not return a value
end
return buffer[k] or view[k] or ui[k] or _G[k] or textadept[k]
- end,
+ end, -- LuaFormatter
__newindex = function(self, k, v)
local ok, value = pcall(function() return buffer[k] end)
if ok and value ~= nil or not ok and value:find('write-only property') then
buffer[k] = v -- buffer and view are interchangeable in this case
- return
+ elseif view[k] ~= nil then
+ view[k] = v
+ elseif ui[k] ~= nil then
+ ui[k] = v
+ else
+ rawset(self, k, v)
end
- if view[k] ~= nil then view[k] = v return end
- if ui[k] ~= nil then ui[k] = v return end
- rawset(self, k, v)
end
})
--- Executes string *code* as Lua code that is subject to an "abbreviated"
--- environment.
--- In this environment, the contents of the `buffer`, `view`, `ui`, and
--- `textadept` tables are also considered as global functions and fields.
--- Prints the results of expressions like in the Lua prompt. Also invokes bare
--- functions as commands.
+-- Executes string *code* as Lua code that is subject to an "abbreviated" environment.
+-- In this environment, the contents of the `buffer`, `view`, `ui`, and `textadept` tables are
+-- also considered as global functions and fields.
+-- Prints the results of expressions like in the Lua prompt. Also invokes bare functions as
+-- commands.
-- @param code The Lua code to execute.
local function run_lua(code)
local f, errmsg = load('return ' .. code, nil, 't', env)
@@ -131,15 +133,12 @@ local function run_lua(code)
if type(result) == 'function' then result = result() end
if type(result) == 'table' then
local items = {}
- for k, v in pairs(result) do
- items[#items + 1] = string.format('%s = %s', k, v)
- end
+ for k, v in pairs(result) do items[#items + 1] = string.format('%s = %s', k, v) end
table.sort(items)
result = string.format('{%s}', table.concat(items, ', '))
if view.edge_column > 0 and #result > view.edge_column then
local indent = string.rep(' ', buffer.tab_width)
- result = string.format(
- '{\n%s%s\n}', indent, table.concat(items, ',\n' .. indent))
+ result = string.format('{\n%s%s\n}', indent, table.concat(items, ',\n' .. indent))
end
end
if result ~= nil or code:find('^return ') then ui.print(result) end
@@ -147,15 +146,13 @@ local function run_lua(code)
end
args.register('-e', '--execute', 1, run_lua, 'Execute Lua code')
--- Shows a set of Lua code completions for the entry's text, subject to an
--- "abbreviated" environment where the contents of the `buffer`, `view`, and
--- `ui` tables are also considered as globals.
+-- Shows a set of Lua code completions for the entry's text, subject to an "abbreviated"
+-- environment where the contents of the `buffer`, `view`, and `ui` tables are also considered
+-- as globals.
local function complete_lua()
local line, pos = M:get_cur_line()
- local symbol, op, part = line:sub(1, pos - 1):match(
- '([%w_.]-)([%.:]?)([%w_]*)$')
- local ok, result = pcall(
- (load(string.format('return (%s)', symbol), nil, 't', env)))
+ local symbol, op, part = line:sub(1, pos - 1):match('([%w_.]-)([%.:]?)([%w_]*)$')
+ local ok, result = pcall((load(string.format('return (%s)', symbol), nil, 't', env)))
if (not ok or type(result) ~= 'table') and symbol ~= '' then return end
local cmpls = {}
part = '^' .. part
@@ -163,23 +160,20 @@ local function complete_lua()
local sep = string.char(M.auto_c_type_separator)
if not ok or symbol == 'buffer' or symbol == 'view' then
local sci = _SCINTILLA
- local global_envs = not ok and {
- buffer, view, ui, _G, textadept, sci.functions, sci.properties,
- sci.constants
- } or op == ':' and {sci.functions} or {sci.properties, sci.constants}
+ local global_envs = not ok and
+ {buffer, view, ui, _G, textadept, sci.functions, sci.properties, sci.constants} or op == ':' and
+ {sci.functions} or {sci.properties, sci.constants}
for _, env in ipairs(global_envs) do
for k, v in pairs(env) do
if type(k) ~= 'string' or not k:find(part) then goto continue end
- local xpm = (type(v) == 'function' or env == sci.functions) and
- XPM.METHOD or XPM.VARIABLE
+ local xpm = (type(v) == 'function' or env == sci.functions) and XPM.METHOD or XPM.VARIABLE
cmpls[#cmpls + 1] = k .. sep .. xpm
::continue::
end
end
else
for k, v in pairs(result) do
- if type(k) == 'string' and k:find(part) and
- (op == '.' or type(v) == 'function') then
+ if type(k) == 'string' and k:find(part) and (op == '.' or type(v) == 'function') then
local xpm = type(v) == 'function' and XPM.METHOD or XPM.VARIABLE
cmpls[#cmpls + 1] = k .. sep .. xpm
end
@@ -198,28 +192,22 @@ local lua_keys = {['\t'] = complete_lua}
local prev_key_mode
---
--- Opens the command entry, subjecting it to any key bindings defined in table
--- *keys*, highlighting text with lexer name *lang*, 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.
+-- Opens the command entry, subjecting it to any key bindings defined in table *keys*,
+-- highlighting text with lexer name *lang*, 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 *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 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.
+-- The command entry does not respond to Textadept's default key bindings, but instead to the
+-- key bindings defined in *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 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 lang 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`.
+-- @param lang 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
@@ -262,8 +250,8 @@ M.focus = function()
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.
+-- 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
for i = 1, M.margins do M.margin_width_n[i] = 0 end
@@ -271,8 +259,8 @@ events.connect(events.INITIALIZED, function()
for key, f in pairs(keys) do
if f ~= textadept.editing.show_documentation then goto continue end
lua_keys[key] = function()
- -- Temporarily change _G.buffer and _G.view since ui.command_entry is
- -- the "active" buffer and view.
+ -- Temporarily change _G.buffer and _G.view since ui.command_entry is the "active" buffer
+ -- and view.
local orig_buffer, orig_view = _G.buffer, _G.view
_G.buffer, _G.view = ui.command_entry, ui.command_entry
textadept.editing.show_documentation()
diff --git a/modules/textadept/editing.lua b/modules/textadept/editing.lua
index 7ff771a2..1b4a51ba 100644
--- a/modules/textadept/editing.lua
+++ b/modules/textadept/editing.lua
@@ -9,8 +9,7 @@ local M = {}
-- Match the previous line's indentation level after inserting a new line.
-- The default value is `true`.
-- @field strip_trailing_spaces (bool)
--- Strip trailing whitespace before saving files. (Does not apply to binary
--- files.)
+-- Strip trailing whitespace before saving files. (Does not apply to binary files.)
-- The default value is `false`.
-- @field autocomplete_all_words (bool)
-- Autocomplete the current word using words from all open buffers.
@@ -28,8 +27,8 @@ local M = {}
--
-- The default value is `textadept.editing.HIGHLIGHT_NONE`.
-- @field auto_enclose (bool)
--- Whether or not to auto-enclose selected text when typing a punctuation
--- character, taking [`textadept.editing.auto_pairs`]() into account.
+-- Whether or not to auto-enclose selected text when typing a punctuation character, taking
+-- [`textadept.editing.auto_pairs`]() into account.
-- The default value is `false`.
-- @field INDIC_BRACEMATCH (number)
-- The matching brace highlight indicator number.
@@ -46,6 +45,7 @@ M.auto_enclose = false
M.INDIC_BRACEMATCH = _SCINTILLA.next_indic_number()
M.INDIC_HIGHLIGHT = _SCINTILLA.next_indic_number()
+-- LuaFormatter off
---
-- Map of image names to registered image numbers.
-- @field CLASS The image number for classes.
@@ -59,6 +59,7 @@ M.INDIC_HIGHLIGHT = _SCINTILLA.next_indic_number()
-- @class table
-- @name XPM_IMAGES
M.XPM_IMAGES = {not CURSES and '/* XPM */static char *class[] = {/* columns rows colors chars-per-pixel */"16 16 10 1 "," c #000000",". c #001CD0","X c #008080","o c #0080E8","O c #00C0C0","+ c #24D0FC","@ c #00FFFF","# c #A4E8FC","$ c #C0FFFF","% c None",/* pixels */"%%%%% %%%%%%%%%","%%%% ## %%%%%%%","%%% ###++ %%%%%%","%% +++++. %%%%","%% oo++.. $$ %%","%% ooo.. $$$@@ %","%% ooo. @@@@@X %","%%% . OO@@XX %","%%% ## OOOXXX %","%% ###++ OOXX %%","% +++++. OX %%%","% oo++.. % %%%%","% ooo... %%%%%%%","% ooo.. %%%%%%%%","%% o. %%%%%%%%%","%%%% %%%%%%%%%%"};' or '*',not CURSES and '/* XPM */static char *namespace[] = {/* columns rows colors chars-per-pixel */"16 16 7 1 "," c #000000",". c #1D1D1D","X c #393939","o c #555555","O c #A8A8A8","+ c #AAAAAA","@ c None",/* pixels */"@@@@@@@@@@@@@@@@","@@@@+@@@@@@@@@@@","@@@.o@@@@@@@@@@@","@@@ +@@@@@@@@@@@","@@@ +@@@@@@@@@@@","@@+.@@@@@@@+@@@@","@@+ @@@@@@@o.@@@","@@@ +@@@@@@+ @@@","@@@ +@@@@@@+ @@@","@@@.X@@@@@@@.+@@","@@@@+@@@@@@@ @@@","@@@@@@@@@@@+ @@@","@@@@@@@@@@@+ @@@","@@@@@@@@@@@X.@@@","@@@@@@@@@@@+@@@@","@@@@@@@@@@@@@@@@"};' or '@',not CURSES and '/* XPM */static char *method[] = {/* columns rows colors chars-per-pixel */"16 16 5 1 "," c #000000",". c #E0BC38","X c #F0DC5C","o c #FCFC80","O c None",/* pixels */"OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOO OOOO","OOOOOOOOO oo OO","OOOOOOOO ooooo O","OOOOOOO ooooo. O","OOOO O XXoo.. O","OOO oo XXX... O","OO ooooo XX.. OO","O ooooo. X. OOO","O XXoo.. O OOOO","O XXX... OOOOOOO","O XXX.. OOOOOOOO","OO X. OOOOOOOOO","OOOO OOOOOOOOOO"};' or '+',not CURSES and '/* XPM */static char *signal[] = {/* columns rows colors chars-per-pixel */"16 16 6 1 "," c #000000",". c #FF0000","X c #E0BC38","o c #F0DC5C","O c #FCFC80","+ c None",/* pixels */"++++++++++++++++","++++++++++++++++","++++++++++++++++","++++++++++ ++++","+++++++++ OO ++","++++++++ OOOOO +","+++++++ OOOOOX +","++++ + ooOOXX +","+++ OO oooXXX +","++ OOOOO ooXX ++","+ OOOOOX oX +++","+ ooOOXX + ++++","+ oooXXX +++++++","+ oooXX +++++..+","++ oX ++++++..+","++++ ++++++++++"};' or '~',not CURSES and '/* XPM */static char *slot[] = {/* columns rows colors chars-per-pixel */"16 16 5 1 "," c #000000",". c #E0BC38","X c #F0DC5C","o c #FCFC80","O c None",/* pixels */"OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOO OOOO","OOOOOOOOO oo OO","OOOOOOOO ooooo O","OOOOOOO ooooo. O","OOOO O XXoo.. O","OOO oo XXX... O","OO ooooo XX.. OO","O ooooo. X. OOO","O XXoo.. O OOOO","O XXX... OOOOOOO","O XXX.. OOOOO ","OO X. OOOOOO O ","OOOO OOOOOOO "};' or '-',not CURSES and '/* XPM */static char *variable[] = {/* columns rows colors chars-per-pixel */"16 16 5 1 "," c #000000",". c #8C748C","X c #9C94A4","o c #ACB4C0","O c None",/* pixels */"OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOO OOOOO","OOOOOOOO oo OOO","OOOOOOO ooooo OO","OOOOOO ooooo. OO","OOOOOO XXoo.. OO","OOOOOO XXX... OO","OOOOOO XXX.. OOO","OOOOOOO X. OOOO","OOOOOOOOO OOOOO","OOOOOOOOOOOOOOOO"};' or '.',not CURSES and '/* XPM */static char *struct[] = {/* columns rows colors chars-per-pixel */"16 16 14 1 "," c #000000",". c #008000","X c #00C000","o c #00FF00","O c #808000","+ c #C0C000","@ c #FFFF00","# c #008080","$ c #00C0C0","% c #00FFFF","& c #C0FFC0","* c #FFFFC0","= c #C0FFFF","- c None",/* pixels */"----- ---------","---- && -------","--- &&&oo ------","-- ooooo. ----","-- XXoo.. == --","-- XXX.. ===%% -","-- XXX. %%%%%# -","--- . $$%%## -","--- ** $$$### -","-- ***@@ $$## --","- @@@@@O $# ---","- ++@@OO - ----","- +++OOO -------","- +++OO --------","-- +O ---------","---- ----------"};' or '}',not CURSES and '/* XPM */static char *typedef[] = {/* columns rows colors chars-per-pixel */"16 16 10 1 "," c #000000",". c #404040","X c #6D6D6D","o c #777777","O c #949494","+ c #ACACAC","@ c #BBBBBB","# c #DBDBDB","$ c #EEEEEE","% c None",/* pixels */"%%%%% %%%%%%%%%","%%%% ## %%%%%%%","%%% ###++ %%%%%%","%% +++++. %%%%","%% oo++.. $$ %%","%% ooo.. $$$@@ %","%% ooo. @@@@@X %","%%% . OO@@XX %","%%% ## OOOXXX %","%% ###++ OOXX %%","% +++++. OX %%%","% oo++.. % %%%%","% ooo... %%%%%%%","% ooo.. %%%%%%%%","%% o. %%%%%%%%%","%%%% %%%%%%%%%%"};' or ':',CLASS=1,NAMESPACE=2,METHOD=3,SIGNAL=4,SLOT=5,VARIABLE=6,STRUCT=7,TYPEDEF=8}
+-- LuaFormatter on
events.connect(events.VIEW_NEW, function()
local view = buffer ~= ui.command_entry and view or ui.command_entry
for name, i in pairs(M.XPM_IMAGES) do
@@ -67,21 +68,23 @@ events.connect(events.VIEW_NEW, function()
end)
for _ = 1, #M.XPM_IMAGES do _SCINTILLA.next_image_type() end -- sync
+-- LuaFormatter off
---
--- Map of lexer names to line comment strings for programming languages, used by
--- the `toggle_comment()` function.
--- Keys are lexer names and values are either the language's line comment
--- prefixes or block comment delimiters separated by a '|' character.
+-- Map of lexer names to line comment strings for programming languages, used by the
+-- `toggle_comment()` function.
+-- Keys are lexer names and values are either the language's line comment prefixes or block
+-- comment delimiters separated by a '|' character.
-- @class table
-- @name comment_string
-- @see toggle_comment
M.comment_string = {actionscript='//',ada='--',apdl='!',ansi_c='/*|*/',antlr='//',apl='#',applescript='--',asp='\'',autoit=';',awk='#',b_lang='//',bash='#',batch=':',bibtex='%',boo='#',chuck='//',clojure=';',cmake='#',coffeescript='#',context='%',cpp='//',crystal='#',csharp='//',css='/*|*/',cuda='//',desktop='#',django='{#|#}',dmd='//',dockerfile='#',dot='//',eiffel='--',elixir='#',elm='--',erlang='%',fantom='//',faust='//',fennel=';',fish='#',forth='|\\',fortran='!',fsharp='//',fstab='#',gap='#',gettext='#',gherkin='#',glsl='//',gnuplot='#',go='//',groovy='//',gtkrc='#',haskell='--',html='<!--|-->',icon='#',idl='//',inform='!',ini='#',Io='#',java='//',javascript='//',jq='#',json='/*|*/',jsp='//',julia='#',latex='%',ledger='#',less='//',lilypond='%',lisp=';',logtalk='%',lua='--',makefile='#',matlab='#',meson='#',moonscript='--',myrddin='//',nemerle='//',networkd='#',nim='#',nsis='#',objective_c='//',pascal='//',perl='#',php='//',pico8='//',pike='//',pkgbuild='#',pony='//',prolog='%',props='#',protobuf='//',ps='%',pure='//',python='#',rails='#',rc='#',reason='//',rebol=';',rest='.. ',rexx='--',rhtml='<!--|-->',routeros='#',rstats='#',ruby='#',rust='//',sass='//',scala='//',scheme=';',smalltalk='"|"',sml='(*)',snobol4='#',spin="'",sql='--',systemd='#',tcl='#',tex='%',text='',toml='#',typescript='//',vala='//',vb='\'',vbscript='\'',verilog='//',vhdl='--',wsf='<!--|-->',xml='<!--|-->',xs='#',xtend='//',yaml='#',zig='//'}
+-- LuaFormatter on
---
-- Map of auto-paired characters like parentheses, brackets, braces, and quotes.
--- The ASCII values of opening characters are assigned to strings that contain
--- complement characters. The default auto-paired characters are "()", "[]",
--- "{}", "&apos;&apos;", and "&quot;&quot;".
+-- The ASCII values of opening characters are assigned to strings that contain complement
+-- characters. The default auto-paired characters are "()", "[]", "{}", "&apos;&apos;", and
+-- "&quot;&quot;".
-- @class table
-- @name auto_pairs
-- @usage textadept.editing.auto_pairs[60] = '>' -- pair '<' and '>'
@@ -90,8 +93,8 @@ M.auto_pairs = {[40] = ')', [91] = ']', [123] = '}', [39] = "'", [34] = '"'}
---
-- Table of brace characters to highlight.
--- The ASCII values of brace characters are keys and are assigned non-`nil`
--- values. The default brace characters are '(', ')', '[', ']', '{', and '}'.
+-- The ASCII values of brace characters are keys and are assigned non-`nil` values. The default
+-- brace characters are '(', ')', '[', ']', '{', and '}'.
-- @class table
-- @name brace_matches
-- @usage textadept.editing.brace_matches[60] = true -- '<'
@@ -100,8 +103,8 @@ M.brace_matches = {[40] = 1, [41] = 1, [91] = 1, [93] = 1, [123] = 1, [125] = 1}
---
-- Table of characters to move over when typed.
--- The ASCII values of characters are keys and are assigned non-`nil` values.
--- The default characters are ')', ']', '}', '&apos;', and '&quot;'.
+-- The ASCII values of characters are keys and are assigned non-`nil` values. The default
+-- characters are ')', ']', '}', '&apos;', and '&quot;'.
-- @class table
-- @name typeover_chars
-- @usage textadept.editing.typeover_chars[62] = true -- '>'
@@ -109,12 +112,10 @@ M.typeover_chars = {[41] = 1, [93] = 1, [125] = 1, [39] = 1, [34] = 1}
---
-- Map of autocompleter names to autocompletion functions.
--- Names are typically lexer names and autocompletion functions typically
--- autocomplete symbols.
--- Autocompletion functions must return two values: the number of characters
--- behind the caret that are used as the prefix of the entity to be
--- autocompleted, and a list of completions to be shown. Autocompletion lists
--- are sorted automatically.
+-- Names are typically lexer names and autocompletion functions typically autocomplete symbols.
+-- Autocompletion functions must return two values: the number of characters behind the caret
+-- that are used as the prefix of the entity to be autocompleted, and a list of completions to
+-- be shown. Autocompletion lists are sorted automatically.
-- @class table
-- @name autocompleters
-- @see autocomplete
@@ -122,20 +123,20 @@ M.autocompleters = {}
---
-- Map of lexer names to API documentation file tables.
--- File tables contain API file paths or functions that return such paths.
--- Each line in an API file consists of a symbol name (not a fully qualified
--- symbol name), a space character, and that symbol's documentation. "\n"
--- represents a newline character.
+-- File tables contain API file paths or functions that return such paths. Each line in an
+-- API file consists of a symbol name (not a fully qualified symbol name), a space character,
+-- and that symbol's documentation. "\n" represents a newline character.
-- @class table
-- @name api_files
-- @see show_documentation
-M.api_files = setmetatable({}, {__index = function(t, k)
- t[k] = {}
- return t[k]
-end})
+M.api_files = setmetatable({}, {
+ __index = function(t, k)
+ t[k] = {}
+ return t[k]
+ end
+})
--- Matches characters specified in auto_pairs, taking multiple selections into
--- account.
+-- Matches characters specified in auto_pairs, taking multiple selections into account.
events.connect(events.CHAR_ADDED, function(code)
if not M.auto_pairs or not M.auto_pairs[code] then return end
buffer:begin_undo_action()
@@ -149,8 +150,7 @@ end)
-- Removes matched chars on backspace, taking multiple selections into account.
events.connect(events.KEYPRESS, function(code)
- if M.auto_pairs and keys.KEYSYMS[code] == '\b' and
- not ui.command_entry.active then
+ if M.auto_pairs and keys.KEYSYMS[code] == '\b' and not ui.command_entry.active then
buffer:begin_undo_action()
for i = 1, buffer.selections do
local pos = buffer.selection_n_caret[i]
@@ -206,17 +206,14 @@ events.connect(events.UPDATE_UI, function(updated)
buffer.search_flags = buffer.FIND_MATCHCASE | buffer.FIND_WHOLEWORD
buffer:target_whole_document()
while buffer:search_in_target(word) ~= -1 do
- buffer:indicator_fill_range(
- buffer.target_start, buffer.target_end - buffer.target_start)
+ buffer:indicator_fill_range(buffer.target_start, buffer.target_end - buffer.target_start)
buffer:set_target_range(buffer.target_end, buffer.length + 1)
end
end)
--- Moves over typeover characters when typed, taking multiple selections into
--- account.
+-- Moves over typeover characters when typed, taking multiple selections into account.
events.connect(events.KEYPRESS, function(code)
- if M.typeover_chars and M.typeover_chars[code] and
- not ui.command_entry.active then
+ if M.typeover_chars and M.typeover_chars[code] and not ui.command_entry.active then
local handled = false
for i = 1, buffer.selections do
local s, e = buffer.selection_n_start[i], buffer.selection_n_end[i]
@@ -234,7 +231,7 @@ events.connect(events.CHAR_ADDED, function(code)
if not M.auto_indent or code ~= string.byte('\n') then return end
local line = buffer:line_from_position(buffer.current_pos)
if line > 1 and buffer:get_line(line - 1):find('^[\r\n]+$') and
- buffer:get_line(line):find('^[^\r\n]') then
+ buffer:get_line(line):find('^[^\r\n]') then
return -- do not auto-indent when pressing enter from start of previous line
end
local i = line - 1
@@ -245,8 +242,8 @@ events.connect(events.CHAR_ADDED, function(code)
end
end)
--- Enables and disables bracketed paste mode in curses and disables auto-pair
--- and auto-indent while pasting.
+-- Enables and disables bracketed paste mode in curses and disables auto-pair and auto-indent
+-- while pasting.
if CURSES and not WIN32 then
local function enable_br_paste() io.stdout:write('\x1b[?2004h'):flush() end
local function disable_br_paste() io.stdout:write('\x1b[?2004l'):flush() end
@@ -267,8 +264,8 @@ if CURSES and not WIN32 then
end)
end
--- Prepares the buffer for saving to a file by stripping trailing whitespace,
--- ensuring a final newline, and normalizing line endings.
+-- Prepares the buffer for saving to a file by stripping trailing whitespace, ensuring a final
+-- newline, and normalizing line endings.
events.connect(events.FILE_BEFORE_SAVE, function()
if not M.strip_trailing_spaces or not buffer.encoding then return end
buffer:begin_undo_action()
@@ -289,8 +286,8 @@ events.connect(events.FILE_BEFORE_SAVE, function()
end)
---
--- Pastes the text from the clipboard, taking into account the buffer's
--- indentation settings and the indentation of the current and preceding lines.
+-- Pastes the text from the clipboard, taking into account the buffer's indentation settings
+-- and the indentation of the current and preceding lines.
-- @name paste_reindent
function M.paste_reindent()
local line = buffer:line_from_position(buffer.selection_start)
@@ -307,31 +304,25 @@ function M.paste_reindent()
text = text:gsub('\n([ \t]+)', function(indentation)
if indentation:find('^\t') then
return buffer.use_tabs and '\n' .. indentation or
- '\n' .. indentation:gsub('\t', string.rep(' ', buffer.tab_width))
+ ('\n' .. indentation:gsub('\t', string.rep(' ', buffer.tab_width)))
else
tab_width = math.min(tab_width, #indentation)
local indent = math.floor(#indentation / tab_width)
local spaces = string.rep(' ', math.fmod(#indentation, tab_width))
- return string.format(
- '\n%s%s', buffer.use_tabs and string.rep('\t', indent) or
+ return string.format('\n%s%s', buffer.use_tabs and string.rep('\t', indent) or
string.rep(' ', buffer.tab_width):rep(indent), spaces)
end
end)
- -- Re-indent according to whichever of the current and preceding lines has the
- -- higher indentation amount. However, if the preceding line is a fold header,
- -- indent by an extra level.
+ -- Re-indent according to whichever of the current and preceding lines has the higher indentation
+ -- amount. However, if the preceding line is a fold header, indent by an extra level.
local i = line - 1
while i >= 1 and buffer:get_line(i):find('^[\r\n]+$') do i = i - 1 end
- if i < 1 or buffer.line_indentation[i] < buffer.line_indentation[line] then
- i = line
- end
- local indentation = buffer:text_range(
- buffer:position_from_line(i), buffer.line_indent_position[i])
- local fold_header =
- i ~= line and buffer.fold_level[i] & buffer.FOLDLEVELHEADERFLAG > 0
+ if i < 1 or buffer.line_indentation[i] < buffer.line_indentation[line] then i = line end
+ local indentation =
+ buffer:text_range(buffer:position_from_line(i), buffer.line_indent_position[i])
+ local fold_header = i ~= line and buffer.fold_level[i] & buffer.FOLDLEVELHEADERFLAG > 0
if fold_header then
- indentation = indentation ..
- (buffer.use_tabs and '\t' or string.rep(' ', buffer.tab_width))
+ indentation = indentation .. (buffer.use_tabs and '\t' or string.rep(' ', buffer.tab_width))
end
text = text:gsub('\n', '\n' .. indentation)
-- Paste the text and adjust first and last line indentation accordingly.
@@ -374,9 +365,7 @@ function M.toggle_comment()
local uncomment = buffer:text_range(p, p + #prefix) == prefix
if not uncomment then
buffer:insert_text(p, prefix)
- if suffix ~= '' then
- buffer:insert_text(buffer.line_end_position[line], suffix)
- end
+ if suffix ~= '' then buffer:insert_text(buffer.line_end_position[line], suffix) end
else
buffer:delete_range(p, #prefix)
if suffix ~= '' then
@@ -392,20 +381,23 @@ function M.toggle_comment()
-- Keep the anchor and caret on the first line as necessary.
local start_pos = buffer:position_from_line(s)
anchor, pos = math.max(anchor, start_pos), math.max(pos, start_pos)
- if s ~= e then buffer:set_sel(anchor, pos) else buffer:goto_pos(pos) end
+ if s ~= e then
+ buffer:set_sel(anchor, pos)
+ else
+ buffer:goto_pos(pos)
+ end
end
---
--- Moves the caret to the beginning of line number *line* or the user-specified
--- line, ensuring *line* is visible.
--- @param line Optional line number to go to. If `nil`, the user is prompted for
--- one.
+-- Moves the caret to the beginning of line number *line* or the user-specified line, ensuring
+-- *line* is visible.
+-- @param line Optional line number to go to. If `nil`, the user is prompted for one.
-- @name goto_line
function M.goto_line(line)
if not assert_type(line, 'number/nil', 1) then
local button, value = ui.dialogs.inputbox{
- title = _L['Go To'], informative_text = _L['Line Number:'],
- button1 = _L['OK'], button2 = _L['Cancel']
+ title = _L['Go To'], informative_text = _L['Line Number:'], button1 = _L['OK'],
+ button2 = _L['Cancel']
}
line = tonumber(value)
if button ~= 1 or not line then return end
@@ -413,14 +405,13 @@ function M.goto_line(line)
view:ensure_visible_enforce_policy(line)
buffer:goto_line(line)
end
-args.register('-l', '--line', 1, function(line)
- M.goto_line(tonumber(line) or line)
-end, 'Go to line')
+args.register('-l', '--line', 1, function(line) M.goto_line(tonumber(line) or line) end,
+ 'Go to line')
---
-- Transposes characters intelligently.
--- If the caret is at the end of a line, transposes the two characters before
--- the caret. Otherwise, the characters to the left and right are.
+-- If the caret is at the end of a line, transposes the two characters before the caret. Otherwise,
+-- the characters to the left and right are.
-- @name transpose_chars
function M.transpose_chars()
local pos = buffer.current_pos
@@ -434,10 +425,8 @@ function M.transpose_chars()
end
---
--- Joins the currently selected lines or the current line with the line below
--- it.
--- As long as any part of a line is selected, the entire line is eligible for
--- joining.
+-- Joins the currently selected lines or the current line with the line below it.
+-- As long as any part of a line is selected, the entire line is eligible for joining.
-- @name join_lines
function M.join_lines()
buffer:target_from_selection()
@@ -450,8 +439,8 @@ function M.join_lines()
end
---
--- Encloses the selected text or the current word within strings *left* and
--- *right*, taking multiple selections into account.
+-- Encloses the selected text or the current word within strings *left* and *right*, taking
+-- multiple selections into account.
-- @param left The left part of the enclosure.
-- @param right The right part of the enclosure.
-- @name enclose
@@ -475,8 +464,8 @@ end
-- Enclose selected text in punctuation or auto-paired characters.
events.connect(events.KEYPRESS, function(code, shift, ctrl, alt, cmd)
- if M.auto_enclose and not buffer.selection_empty and code < 256 and
- not ctrl and not alt and not cmd and not ui.command_entry.active then
+ if M.auto_enclose and not buffer.selection_empty and code < 256 and not ctrl and not alt and
+ not cmd and not ui.command_entry.active then
local char = string.char(code)
if char:find('^%P') then return end -- not punctuation
M.enclose(char, M.auto_pairs[code] or char)
@@ -486,11 +475,9 @@ end, 1)
---
-- Selects the text between strings *left* and *right* that enclose the caret.
--- If that range is already selected, toggles between selecting *left* and
--- *right* as well.
--- If *left* and *right* are not provided, they are assumed to be one of the
--- delimiter pairs specified in `auto_pairs` and are inferred from the current
--- position or selection.
+-- If that range is already selected, toggles between selecting *left* and *right* as well.
+-- If *left* and *right* are not provided, they are assumed to be one of the delimiter pairs
+-- specified in `auto_pairs` and are inferred from the current position or selection.
-- @param left Optional left part of the enclosure.
-- @param right Optional right part of the enclosure.
-- @see auto_pairs
@@ -511,7 +498,7 @@ function M.select_enclosed(left, right)
e = buffer:brace_match(s, 0)
break
elseif M.brace_matches[buffer.char_at[s]] or
- buffer.style_at[s] == buffer.style_at[buffer.selection_start] then
+ (buffer.style_at[s] == buffer.style_at[buffer.selection_start]) then
buffer.search_flags = 0
buffer:set_target_range(s + 1, buffer.length + 1)
if buffer:search_in_target(match) >= buffer.selection_end - 1 then
@@ -529,19 +516,16 @@ function M.select_enclosed(left, right)
end
---
--- Selects the current word or, if *all* is `true`, all occurrences of the
--- current word.
--- If a word is already selected, selects the next occurrence as a multiple
--- selection.
--- @param all Whether or not to select all occurrences of the current word.
--- The default value is `false`.
+-- Selects the current word or, if *all* is `true`, all occurrences of the current word.
+-- If a word is already selected, selects the next occurrence as a multiple selection.
+-- @param all Whether or not to select all occurrences of the current word. The default value is
+-- `false`.
-- @see buffer.word_chars
-- @name select_word
function M.select_word(all)
buffer:target_whole_document()
buffer.search_flags = buffer.FIND_MATCHCASE
- if buffer.selection_empty or
- buffer:is_range_word(buffer.selection_start, buffer.selection_end) then
+ if buffer.selection_empty or buffer:is_range_word(buffer.selection_start, buffer.selection_end) then
buffer.search_flags = buffer.search_flags | buffer.FIND_WHOLEWORD
if all then buffer:multiple_select_add_next() end -- select word first
end
@@ -568,9 +552,8 @@ end
---
-- Converts indentation between tabs and spaces according to `buffer.use_tabs`.
--- If `buffer.use_tabs` is `true`, `buffer.tab_width` indenting spaces are
--- converted to tabs. Otherwise, all indenting tabs are converted to
--- `buffer.tab_width` spaces.
+-- If `buffer.use_tabs` is `true`, `buffer.tab_width` indenting spaces are converted to tabs.
+-- Otherwise, all indenting tabs are converted to `buffer.tab_width` spaces.
-- @see buffer.use_tabs
-- @name convert_indentation
function M.convert_indentation()
@@ -596,20 +579,19 @@ function M.convert_indentation()
end
---
--- Passes the selected text or all buffer text to string shell command *command*
--- as standard input (stdin) and replaces the input text with the command's
--- standard output (stdout). *command* may contain shell pipes ('|').
+-- Passes the selected text or all buffer text to string shell command *command* as standard input
+-- (stdin) and replaces the input text with the command's standard output (stdout). *command*
+-- may contain shell pipes ('|').
-- Standard input is as follows:
--
-- 1. If no text is selected, the entire buffer is used.
--- 2. If text is selected and spans a single line, only the selected text is
--- used.
--- 3. If text is selected and spans multiple lines, all text on the lines that
--- have text selected is passed as stdin. However, if the end of the selection
--- is at the beginning of a line, only the line ending delimiters from the
--- previous line are included. The rest of the line is excluded.
--- @param command The Linux, BSD, macOS, or Windows shell command to filter text
--- through. May contain pipes.
+-- 2. If text is selected and spans a single line, only the selected text is used.
+-- 3. If text is selected and spans multiple lines, all text on the lines that have text selected
+-- is passed as stdin. However, if the end of the selection is at the beginning of a line,
+-- only the line ending delimiters from the previous line are included. The rest of the line
+-- is excluded.
+-- @param command The Linux, BSD, macOS, or Windows shell command to filter text through. May
+-- contain pipes.
-- @name filter_through
function M.filter_through(command)
assert(not (WIN32 and CURSES), 'not implemented in this environment')
@@ -627,12 +609,14 @@ function M.filter_through(command)
end
buffer:set_target_range(s, e)
end
+ -- LuaFormatter off
local commands = lpeg.match(lpeg.Ct(lpeg.P{
lpeg.C(lpeg.V('command')) * ('|' * lpeg.C(lpeg.V('command')))^0,
command = (1 - lpeg.S('"\'|') + lpeg.V('str'))^1,
str = '"' * (1 - lpeg.S('"\\') + lpeg.P('\\') * 1)^0 * lpeg.P('"')^-1 +
- "'" * (1 - lpeg.S("'\\") + lpeg.P('\\') * 1)^0 * lpeg.P("'")^-1,
+ "'" * (1 - lpeg.S("'\\") + lpeg.P('\\') * 1)^0 * lpeg.P("'")^-1
}), command)
+ -- LuaFormatter on
local output = buffer.target_text
for i = 1, #commands do
local p = assert(os.spawn(commands[i]:match('^%s*(.-)%s*$')))
@@ -640,21 +624,23 @@ function M.filter_through(command)
p:close()
output = p:read('a') or ''
if p:wait() ~= 0 then
- ui.statusbar_text = string.format(
- '"%s" %s', commands[i], _L['returned non-zero status'])
+ ui.statusbar_text = string.format('"%s" %s', commands[i], _L['returned non-zero status'])
return
end
end
buffer:replace_target(output:iconv('UTF-8', _CHARSET))
- if s == e then buffer:goto_pos(s) return end
+ if s == e then
+ buffer:goto_pos(s)
+ return
+ end
buffer:set_sel(buffer.target_start, buffer.target_end)
end
---
--- Displays an autocompletion list provided by the autocompleter function
--- associated with string *name*, and returns `true` if completions were found.
--- @param name The name of an autocompleter function in the `autocompleters`
--- table to use for providing autocompletions.
+-- Displays an autocompletion list provided by the autocompleter function associated with string
+-- *name*, and returns `true` if completions were found.
+-- @param name The name of an autocompleter function in the `autocompleters` table to use for
+-- providing autocompletions.
-- @name autocomplete
-- @see autocompleters
function M.autocomplete(name)
@@ -662,14 +648,12 @@ function M.autocomplete(name)
local len_entered, list = M.autocompleters[name]()
if not len_entered or not list or #list == 0 then return end
buffer.auto_c_order = buffer.ORDER_PERFORMSORT
- buffer:auto_c_show(
- len_entered, table.concat(list, string.char(buffer.auto_c_separator)))
+ buffer:auto_c_show(len_entered, table.concat(list, string.char(buffer.auto_c_separator)))
return true
end
--- Returns for the word part behind the caret a list of whole word completions
--- constructed from the current buffer or all open buffers (depending on
--- `M.autocomplete_all_words`).
+-- Returns for the word part behind the caret a list of whole word completions constructed from
+-- the current buffer or all open buffers (depending on `M.autocomplete_all_words`).
-- If `buffer.auto_c_ignore_case` is `true`, completions are not case-sensitive.
-- @see buffer.word_chars
-- @see autocomplete
@@ -698,20 +682,23 @@ end
local api_docs
---
--- Displays a call tip with documentation for the symbol under or directly
--- behind position *pos* or the caret position.
+-- Displays a call tip with documentation for the symbol under or directly behind position *pos*
+-- or the caret position.
-- Documentation is read from API files in the `api_files` table.
-- If a call tip is already shown, cycles to the next one if it exists.
-- Symbols are determined by using `buffer.word_chars`.
--- @param pos Optional position of the symbol to show documentation for. If
--- omitted, the caret position is used.
--- @param ignore_case Optional flag that indicates whether or not to search
--- API files case-insensitively for symbols. The default value is `false`.
+-- @param pos Optional position of the symbol to show documentation for. If omitted, the caret
+-- position is used.
+-- @param ignore_case Optional flag that indicates whether or not to search API files
+-- case-insensitively for symbols. The default value is `false`.
-- @name show_documentation
-- @see api_files
-- @see buffer.word_chars
function M.show_documentation(pos, ignore_case)
- if view:call_tip_active() then events.emit(events.CALL_TIP_CLICK) return end
+ if view:call_tip_active() then
+ events.emit(events.CALL_TIP_CLICK)
+ return
+ end
local api_files = M.api_files[buffer:get_lexer(true)]
if not api_files then return end
if not assert_type(pos, 'number/nil', 1) then pos = buffer.current_pos end
@@ -739,8 +726,8 @@ function M.show_documentation(pos, ignore_case)
::continue::
end
end
- -- Search backwards for an open function call and show API documentation for
- -- that function as well.
+ -- Search backwards for an open function call and show API documentation for that function
+ -- as well.
while s > 1 and buffer.char_at[s] ~= 40 do s = s - 1 end -- '('
e = buffer:brace_match(s, 0)
if s > 1 and (e == -1 or e >= pos) then
diff --git a/modules/textadept/file_types.lua b/modules/textadept/file_types.lua
index bd5a8a04..ac9c88f9 100644
--- a/modules/textadept/file_types.lua
+++ b/modules/textadept/file_types.lua
@@ -7,8 +7,8 @@ local M = {}
-- Handles file type detection for Textadept.
-- @field _G.events.LEXER_LOADED (string)
-- Emitted after loading a language lexer.
--- This is useful for overriding a language module's key bindings or other
--- properties since the module is not loaded when Textadept starts.
+-- This is useful for overriding a language module's key bindings or other properties since
+-- the module is not loaded when Textadept starts.
-- Arguments:
--
-- * _`name`_: The language lexer's name.
@@ -17,10 +17,11 @@ module('textadept.file_types')]]
-- Events.
events.LEXER_LOADED = 'lexer_loaded'
+-- LuaFormatter off
---
-- Map of file extensions to their associated lexer names.
--- If the file type is not recognized by its first-line, each file extension is
--- matched against the file's extension.
+-- If the file type is not recognized by its first-line, each file extension is matched against
+-- the file's extension.
-- @class table
-- @name extensions
M.extensions = {--[[Actionscript]]as='actionscript',asc='actionscript',--[[Ada]]adb='ada',ads='ada',--[[ANTLR]]g='antlr',g4='antlr',--[[APDL]]ans='apdl',inp='apdl',mac='apdl',--[[APL]]apl='apl',--[[Applescript]]applescript='applescript',--[[ASM]]asm='asm',ASM='asm',s='asm',S='asm',--[[ASP]]asa='asp',asp='asp',hta='asp',--[[AutoIt]]au3='autoit',a3x='autoit',--[[AWK]]awk='awk',--[[Batch]]bat='batch',cmd='batch',--[[BibTeX]]bib='bibtex',--[[Boo]]boo='boo',--[[C#]]cs='csharp',--[[C/C++]]c='ansi_c',cc='cpp',C='ansi_c',cpp='cpp',cxx='cpp',['c++']='cpp',h='cpp',hh='cpp',hpp='cpp',hxx='cpp',['h++']='cpp',--[[ChucK]]ck='chuck',--[[Clojure]]clj='clojure',cljs='clojure',cljc='clojure',edn='clojure',--[[CMake]]cmake='cmake',['cmake.in']='cmake',ctest='cmake',['ctest.in']='cmake',--[[CoffeeScript]]coffee='coffeescript',--[[Crystal]]cr='crystal',--[[CSS]]css='css',--[[CUDA]]cu='cuda',cuh='cuda',--[[D]]d='dmd',di='dmd',--[[Dart]]dart='dart',--[[Desktop]]desktop='desktop',--[[diff]]diff='diff',patch='diff',--[[Dockerfile]]Dockerfile='dockerfile',--[[dot]]dot='dot',--[[Eiffel]]e='eiffel',eif='eiffel',--[[Elixir]]ex='elixir',exs='elixir',--[[Elm]]elm='elm',--[[Erlang]]erl='erlang',hrl='erlang',--[[F#]]fs='fsharp',--[[Fantom]]fan='fantom',--[[Faust]]dsp='faust',--[[Fennel]]fnl='fennel',--[[Fish]]fish='fish',--[[Forth]]forth='forth',frt='forth',--[[Fortran]]f='fortran',['for']='fortran',ftn='fortran',fpp='fortran',f77='fortran',f90='fortran',f95='fortran',f03='fortran',f08='fortran',--[[fstab]]fstab='fstab',--[[Gap]]g='gap',gd='gap',gi='gap',gap='gap',--[[Gettext]]po='gettext',pot='gettext',--[[Gherkin]]feature='gherkin',--[[GLSL]]glslf='glsl',glslv='glsl',--[[GNUPlot]]dem='gnuplot',plt='gnuplot',--[[Go]]go='go',--[[Groovy]]groovy='groovy',gvy='groovy',--[[Gtkrc]]gtkrc='gtkrc',--[[Haskell]]hs='haskell',--[[HTML]]htm='html',html='html',shtm='html',shtml='html',xhtml='html',vue='html',--[[Icon]]icn='icon',--[[IDL]]idl='idl',odl='idl',--[[Inform]]inf='inform',ni='inform',--[[ini]]cfg='ini',cnf='ini',inf='ini',ini='ini',reg='ini',--[[Io]]io='io_lang',--[[Java]]bsh='java',java='java',--[[Javascript]]js='javascript',jsfl='javascript',--[[jq]]jq='jq',--[[JSON]]json='json',--[[JSP]]jsp='jsp',--[[Julia]]jl='julia',--[[LaTeX]]bbl='latex',dtx='latex',ins='latex',ltx='latex',tex='latex',sty='latex',--[[Ledger]]ledger='ledger',journal='ledger',--[[LESS]]less='less',--[[LilyPond]]lily='lilypond',ly='lilypond',--[[Lisp]]cl='lisp',el='lisp',lisp='lisp',lsp='lisp',--[[Literate Coffeescript]]litcoffee='litcoffee',--[[Logtalk]]lgt='logtalk',--[[Lua]]lua='lua',--[[Makefile]]GNUmakefile='makefile',iface='makefile',mak='makefile',makefile='makefile',Makefile='makefile',--[[Man]]['1']='man',['2']='man',['3']='man',['4']='man',['5']='man',['6']='man',['7']='man',['8']='man',['9']='man',['1x']='man',['2x']='man',['3x']='man',['4x']='man',['5x']='man',['6x']='man',['7x']='man',['8x']='man',['9x']='man',--[[Markdown]]md='markdown',--[[Meson]]['meson.build']='meson',--[[MoonScript]]moon='moonscript',--[[Myrddin]]myr='myrddin',--[[Nemerle]]n='nemerle',--[[Networkd]]link='networkd',network='networkd',netdev='networkd',--[[Nim]]nim='nim',--[[NSIS]]nsh='nsis',nsi='nsis',nsis='nsis',--[[Objective C]]m='objective_c',mm='objective_c',objc='objective_c',--[[OCaml]]caml='caml',ml='caml',mli='caml',mll='caml',mly='caml',--[[Pascal]]dpk='pascal',dpr='pascal',p='pascal',pas='pascal',--[[Perl]]al='perl',perl='perl',pl='perl',pm='perl',pod='perl',--[[PHP]]inc='php',php='php',php3='php',php4='php',phtml='php',--[[PICO-8]]p8='pico8',--[[Pike]]pike='pike',pmod='pike',--[[PKGBUILD]]PKGBUILD='pkgbuild',--[[Pony]]pony='pony',--[[Postscript]]eps='ps',ps='ps',--[[PowerShell]]ps1='powershell',--[[Prolog]]prolog='prolog',--[[Properties]]props='props',properties='props',--[[Protobuf]]proto='protobuf',--[[Pure]]pure='pure',--[[Python]]sc='python',py='python',pyw='python',--[[R]]R='rstats',Rout='rstats',Rhistory='rstats',Rt='rstats',['Rout.save']='rstats',['Rout.fail']='rstats',S='rstats',--[[Reason]]re='reason',--[[REBOL]]r='rebol',reb='rebol',--[[reST]]rst='rest',--[[Rexx]]orx='rexx',rex='rexx',--[[RHTML]]erb='rhtml',rhtml='rhtml',--[[RouterOS]]rsc='routeros',--[[Ruby]]Rakefile='ruby',rake='ruby',rb='ruby',rbw='ruby',--[[Rust]]rs='rust',--[[Sass CSS]]sass='sass',scss='sass',--[[Scala]]scala='scala',--[[Scheme]]sch='scheme',scm='scheme',--[[Shell]]bash='bash',bashrc='bash',bash_profile='bash',configure='bash',csh='bash',ksh='bash',mksh='bash',sh='bash',zsh='bash',--[[Smalltalk]]changes='smalltalk',st='smalltalk',sources='smalltalk',--[[SML]]sml='sml',fun='sml',sig='sml',--[[SNOBOL4]]sno='snobol4',SNO='snobol4',--[[Spin]]spin='spin',--[[SQL]]ddl='sql',sql='sql',--[[Systemd]]automount='systemd',device='systemd',mount='systemd',path='systemd',scope='systemd',service='systemd',slice='systemd',socket='systemd',swap='systemd',target='systemd',timer='systemd',--[[TaskPaper]]taskpaper='taskpaper',--[[Tcl]]tcl='tcl',tk='tcl',--[[Texinfo]]texi='texinfo',--[[TOML]]toml='toml',--[[Txt2tags]]t2t='txt2tags',--[[TypeScript]]ts='typescript',--[[Vala]]vala='vala',--[[vCard]]vcf='vcard',vcard='vcard',--[[Verilog]]v='verilog',ver='verilog',--[[VHDL]]vh='vhdl',vhd='vhdl',vhdl='vhdl',--[[Visual Basic]]asa='vb',bas='vb',cls='vb',ctl='vb',dob='vb',dsm='vb',dsr='vb',frm='vb',pag='vb',vb='vb',vba='vb',vbs='vb',--[[WSF]]wsf='wsf',--[[XML]]dtd='xml',svg='xml',xml='xml',xsd='xml',xsl='xml',xslt='xml',xul='xml',--[[Xs]]xs='xs',xsin='xs',xsrc='xs',--[[Xtend]]xtend='xtend',--[[YAML]]yaml='yaml',yml='yaml',--[[Zig]]zig='zig'}
@@ -31,6 +32,7 @@ M.extensions = {--[[Actionscript]]as='actionscript',asc='actionscript',--[[Ada]]
-- @class table
-- @name patterns
M.patterns = {['^#!.+[/ ][gm]?awk']='awk',['^#!.+[/ ]lua']='lua',['^#!.+[/ ]octave']='matlab',['^#!.+[/ ]perl']='perl',['^#!.+[/ ]php']='php',['^#!.+[/ ]python']='python',['^#!.+[/ ]ruby']='ruby',['^#!.+[/ ]bash']='bash',['^#!.+/m?ksh']='bash',['^#!.+/sh']='bash',['^%s*class%s+%S+%s*<%s*ApplicationController']='rails',['^%s*class%s+%S+%s*<%s*ActionController::Base']='rails',['^%s*class%s+%S+%s*<%s*ActiveRecord::Base']='rails',['^%s*class%s+%S+%s*<%s*ActiveRecord::Migration']='rails',['^%s*<%?xml%s']='xml',['^#cloud%-config']='yaml'}
+-- LuaFormatter on
local GETLEXERLANGUAGE = _SCINTILLA.properties.lexer_language[1]
-- LuaDoc is in core/.buffer.luadoc.
@@ -39,16 +41,13 @@ local function get_lexer(buffer, current)
return current and name:match('[^/]+$') or name:match('^[^/]+')
end
--- Attempts to detect the language based on a buffer's first line of text or
--- that buffer's filename.
+-- Attempts to detect the language based on a buffer's first line of text or that buffer's filename.
-- @param buffer The buffer to detect the language of.
-- @return lexer name or nil
local function detect_language(buffer)
local line = buffer:get_line(1)
-- Detect from first line.
- for patt, lexer_name in pairs(M.patterns) do
- if line:find(patt) then return lexer_name end
- end
+ for patt, lexer_name in pairs(M.patterns) do if line:find(patt) then return lexer_name end end
-- Detect from file extension.
return buffer.filename and M.extensions[buffer.filename:match('[^/\\.]+$')]
end
@@ -75,18 +74,15 @@ local function set_lexer(buffer, name)
end
-- Gives new buffers lexer-specific functions.
-events.connect(events.BUFFER_NEW, function()
- buffer.get_lexer, buffer.set_lexer = get_lexer, set_lexer
-end, 1)
+events.connect(events.BUFFER_NEW,
+ function() buffer.get_lexer, buffer.set_lexer = get_lexer, set_lexer end, 1)
-- Auto-detect lexer on file open or save as.
events.connect(events.FILE_OPENED, function() buffer:set_lexer() end)
-events.connect(events.FILE_AFTER_SAVE, function(_, saved_as)
- if saved_as then buffer:set_lexer() end
-end)
+events.connect(events.FILE_AFTER_SAVE,
+ function(_, saved_as) if saved_as then buffer:set_lexer() end end)
--- Restores the buffer's lexer, primarily for the side-effect of emitting
--- `events.LEXER_LOADED`.
+-- Restores the buffer's lexer, primarily for the side-effect of emitting `events.LEXER_LOADED`.
local function restore_lexer() buffer:set_lexer(buffer._lexer) end
events.connect(events.BUFFER_AFTER_SWITCH, restore_lexer, 1)
events.connect(events.VIEW_AFTER_SWITCH, restore_lexer)
@@ -100,9 +96,7 @@ local LEXERNAMES = _SCINTILLA.functions.property_names[1]
-- @name select_lexer
function M.select_lexer()
local lexers = {}
- for name in buffer:private_lexer_call(LEXERNAMES):gmatch('[^\n]+') do
- lexers[#lexers + 1] = name
- end
+ for name in buffer:private_lexer_call(LEXERNAMES):gmatch('[^\n]+') do lexers[#lexers + 1] = name end
local button, i = ui.dialogs.filteredlist{
title = _L['Select Lexer'], columns = _L['Name'], items = lexers
}
diff --git a/modules/textadept/find.lua b/modules/textadept/find.lua
index 31624503..0d90885f 100644
--- a/modules/textadept/find.lua
+++ b/modules/textadept/find.lua
@@ -9,14 +9,12 @@ local M = ui.find
-- The text in the "Find" entry.
-- @field replace_entry_text (string)
-- The text in the "Replace" entry.
--- When searching for text in a directory of files, this is the current file
--- and directory filter.
+-- When searching for text in a directory of files, this is the current file and directory filter.
-- @field match_case (bool)
-- Match search text case sensitively.
-- The default value is `false`.
-- @field whole_word (bool)
--- Match search text only when it is surrounded by non-word characters in
--- searches.
+-- Match search text only when it is surrounded by non-word characters in searches.
-- The default value is `false`.
-- @field regex (bool)
-- Interpret search text as a Regular Expression.
@@ -60,23 +58,21 @@ local M = ui.find
-- @field active (boolean)
-- Whether or not the Find & Replace pane is active.
-- @field highlight_all_matches (boolean)
--- Whether or not to highlight all occurrences of found text in the current
--- buffer.
+-- Whether or not to highlight all occurrences of found text in the current buffer.
-- The default value is `false`.
-- @field INDIC_FIND (number)
-- The find results highlight indicator number.
-- @field _G.events.FIND_RESULT_FOUND (string)
--- Emitted when a result is found. It is selected and has been scrolled into
--- view.
+-- Emitted when a result is found. It is selected and has been scrolled into view.
-- Arguments:
--
-- * _`find_text`_: The text originally searched for.
-- @field _G.events.FIND_WRAPPED (string)
--- Emitted when a text search wraps (passes through the beginning of the
--- buffer), either from bottom to top (when searching for a next occurrence),
--- or from top to bottom (when searching for a previous occurrence).
--- This is useful for implementing a more visual or audible notice when a
--- search wraps in addition to the statusbar message.
+-- Emitted when a text search wraps (passes through the beginning of the buffer), either
+-- from bottom to top (when searching for a next occurrence), or from top to bottom (when
+-- searching for a previous occurrence).
+-- This is useful for implementing a more visual or audible notice when a search wraps in
+-- addition to the statusbar message.
module('ui.find')]]
local _L = _L
@@ -97,31 +93,29 @@ M.INDIC_FIND = _SCINTILLA.next_indic_number()
local find_events = {'find_result_found', 'find_wrapped'}
for _, v in ipairs(find_events) do events[v:upper()] = v end
--- When finding in files, note the current view since results are shown in a
--- split view. Jumping between results should be done in the original view.
+-- When finding in files, note the current view since results are shown in a split view. Jumping
+-- between results should be done in the original view.
local preferred_view
---
-- Map of directory paths to filters used in `ui.find.find_in_files()`.
--- This table is updated when the user manually specifies a filter in the
--- "Filter" entry during an "In files" search.
+-- This table is updated when the user manually specifies a filter in the "Filter" entry during
+-- an "In files" search.
-- @class table
-- @name find_in_files_filters
-- @see find_in_files
M.find_in_files_filters = {}
--- Keep track of find text and found text so that "replace all" works as
--- expected during a find session ("replace all" with selected text normally
--- does "replace in selection"). Also track find text for incremental find (if
--- text has changed, the user is still typing; if text is the same, the user
--- clicked "Find Next" or "Find Prev"). Keep track of repl_text for
--- non-"In files" in order to restore it from filter text as necessary.
+-- Keep track of find text and found text so that "replace all" works as expected during a find
+-- session ("replace all" with selected text normally does "replace in selection"). Also track
+-- find text for incremental find (if text has changed, the user is still typing; if text is
+-- the same, the user clicked "Find Next" or "Find Prev"). Keep track of repl_text for non-"In
+-- files" in order to restore it from filter text as necessary.
local find_text, found_text, repl_text = nil, nil, ui.find.replace_entry_text
-- Returns a reasonable initial directory for use with Find in Files.
local function ff_dir()
- return io.get_project_root() or (buffer.filename or ''):match('^.+[/\\]') or
- lfs.currentdir()
+ return io.get_project_root() or (buffer.filename or ''):match('^.+[/\\]') or lfs.currentdir()
end
local orig_focus = M.focus
@@ -139,22 +133,21 @@ function M.focus(options)
if M.in_files then
if not already_in_files then repl_text = M.replace_entry_text end -- save
local filter = M.find_in_files_filters[ff_dir()] or lfs.default_filter
- M.replace_entry_text = type(filter) == 'string' and filter or
- table.concat(filter, ',')
+ M.replace_entry_text = type(filter) == 'string' and filter or table.concat(filter, ',')
elseif M.replace_entry_text ~= repl_text then
M.replace_entry_text = repl_text -- restore
end
orig_focus()
end
--- Returns a bit-mask of search flags to use in Scintilla search functions based
--- on the checkboxes in the find box.
+-- Returns a bit-mask of search flags to use in Scintilla search functions based on the checkboxes
+-- in the find box.
-- The "Find in Files" flag is unused by Scintilla, but used by Textadept.
-- @return search flag bit-mask
local function get_flags()
return (M.match_case and buffer.FIND_MATCHCASE or 0) |
- (M.whole_word and buffer.FIND_WHOLEWORD or 0) |
- (M.regex and buffer.FIND_REGEXP or 0) | (M.in_files and 1 << 31 or 0)
+ (M.whole_word and buffer.FIND_WHOLEWORD or 0) | (M.regex and buffer.FIND_REGEXP or 0) |
+ (M.in_files and 1 << 31 or 0)
end
-- Returns whether or not the given buffer is a files found buffer.
@@ -174,20 +167,22 @@ local incremental_orig_pos
-- Finds and selects text in the current buffer.
-- @param text The text to find.
-- @param next Flag indicating whether or not the search direction is forward.
--- @param flags Search flags. This is a bit-mask of 4 flags:
--- `buffer.FIND_MATCHCASE`, `buffer.FIND_WHOLEWORD`, `buffer.FIND_REGEXP`, and
--- 1 << 31 (in files), each joined with binary OR.
--- If `nil`, this is determined based on the checkboxes in the find box.
+-- @param flags Search flags. This is a bit-mask of 4 flags: `buffer.FIND_MATCHCASE`,
+-- `buffer.FIND_WHOLEWORD`, `buffer.FIND_REGEXP`, and 1 << 31 (in files), each joined with
+-- binary OR. If `nil`, this is determined based on the checkboxes in the find box.
-- @param no_wrap Flag indicating whether or not the search will not wrap.
--- @param wrapped Utility flag indicating whether or not the search has wrapped
--- for displaying useful statusbar information. This flag is used and set
--- internally, and should not be set otherwise.
+-- @param wrapped Utility flag indicating whether or not the search has wrapped for displaying
+-- useful statusbar information. This flag is used and set internally, and should not be
+-- set otherwise.
-- @return position of the found text or `-1`
local function find(text, next, flags, no_wrap, wrapped)
-- Note: cannot use assert_type(), as event errors are handled silently.
if text == '' then return end
if not flags then flags = get_flags() end
- if flags >= 1 << 31 then M.find_in_files() return end -- not performed here
+ if flags >= 1 << 31 then
+ M.find_in_files() -- performed here
+ return
+ end
local first_visible_line = view.first_visible_line -- for 'no results found'
if not is_ff_buf(buffer) then clear_highlighted_matches() end
@@ -205,8 +200,8 @@ local function find(text, next, flags, no_wrap, wrapped)
incremental_orig_pos = nil
end
- -- If text is selected, assume it is from the current search and move the
- -- caret appropriately for the next search.
+ -- If text is selected, assume it is from the current search and move the caret appropriately
+ -- for the next search.
buffer:goto_pos(next and buffer.selection_end or buffer.selection_start)
-- Scintilla search.
@@ -256,45 +251,39 @@ events.connect(events.FIND_RESULT_FOUND, function(text)
if s == buffer.current_pos then current = count end
end
ui.statusbar_text = string.format('%s %d/%d', _L['Match'], current, count)
- -- For regex searches, `buffer.tag` was clobbered. It needs to be filled in
- -- again for any subsequent replace operations that need it.
+ -- For regex searches, `buffer.tag` was clobbered. It needs to be filled in again for any
+ -- subsequent replace operations that need it.
if ui.find.regex then
buffer:set_target_range(buffer.selection_start, buffer.length + 1)
buffer:search_in_target(text)
end
end)
-events.connect(
- events.FIND_WRAPPED, function() ui.statusbar_text = _L['Search wrapped'] end)
+events.connect(events.FIND_WRAPPED, function() ui.statusbar_text = _L['Search wrapped'] 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.
--- Use the `find_entry_text`, `match_case`, `whole_word`, and `regex` fields to
--- set the search text and option flags, respectively.
+-- 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.
+-- Use the `find_entry_text`, `match_case`, `whole_word`, and `regex` fields to set the search
+-- text and option flags, respectively.
-- A filter determines which files to search in, with the default filter being
--- `ui.find.find_in_files_filters[dir]` (if it exists) or `lfs.default_filter`.
--- A filter consists of Lua patterns that match file and directory paths to
--- include or exclude. Patterns are inclusive by default. Exclusive patterns
--- begin with a '!'. If no inclusive patterns are given, any filename is
--- initially considered. As a convenience, file extensions can be specified
--- literally instead of as a Lua pattern (e.g. '.lua' vs. '%.lua$'), and '/'
--- also matches the Windows directory separator ('[/\\]' is not needed).
--- If *filter* is `nil`, the filter from the `ui.find.find_in_files_filters`
--- table for *dir* is used. If that filter does not exist, `lfs.default_filter`
--- is used.
--- @param dir Optional directory path to search. If `nil`, the user is prompted
--- for one.
--- @param filter Optional filter for files and directories to exclude. The
--- default value is `lfs.default_filter` unless a filter for *dir* is defined
--- in `ui.find.find_in_files_filters`.
+-- `ui.find.find_in_files_filters[dir]` (if it exists) or `lfs.default_filter`. A filter consists
+-- of Lua patterns that match file and directory paths to include or exclude. Patterns are
+-- inclusive by default. Exclusive patterns begin with a '!'. If no inclusive patterns are given,
+-- any filename is initially considered. As a convenience, file extensions can be specified
+-- literally instead of as a Lua pattern (e.g. '.lua' vs. '%.lua$'), and '/' also matches the
+-- Windows directory separator ('[/\\]' is not needed). If *filter* is `nil`, the filter from
+-- the `ui.find.find_in_files_filters` table for *dir* is used. If that filter does not exist,
+-- `lfs.default_filter` is used.
+-- @param dir Optional directory path to search. If `nil`, the user is prompted for one.
+-- @param filter Optional filter for files and directories to exclude. The default value is
+-- `lfs.default_filter` unless a filter for *dir* is defined in `ui.find.find_in_files_filters`.
-- @see find_in_files_filters
-- @name find_in_files
function M.find_in_files(dir, filter)
if not assert_type(dir, 'string/nil', 1) then
dir = ui.dialogs.fileselect{
- title = _L['Select Directory'], select_only_directories = true,
- with_directory = ff_dir()
+ title = _L['Select Directory'], select_only_directories = true, with_directory = ff_dir()
}
if not dir then return end
end
@@ -310,10 +299,10 @@ function M.find_in_files(dir, filter)
if buffer._type ~= _L['[Files Found Buffer]'] then preferred_view = view end
ui.silent_print = false
- ui._print(_L['[Files Found Buffer]'], string.format(
- '%s %s\n%s %s\n%s %s', _L['Find:']:gsub('_', ''), M.find_entry_text,
- _L['Directory:'], dir, _L['Filter:']:gsub('_', ''),
- type(filter) == 'string' and filter or table.concat(filter, ',')))
+ ui._print(_L['[Files Found Buffer]'],
+ string.format('%s %s\n%s %s\n%s %s', _L['Find:']:gsub('_', ''), M.find_entry_text,
+ _L['Directory:'], dir, _L['Filter:']:gsub('_', ''),
+ type(filter) == 'string' and filter or table.concat(filter, ',')))
buffer.indicator_current = M.INDIC_FIND
-- Determine which files to search.
@@ -342,18 +331,15 @@ function M.find_in_files(dir, filter)
found = true
if binary == nil then binary = buffer:text_range(1, 65536):find('\0') end
if binary then
- _G.buffer:add_text(string.format(
- '%s:1:%s\n', utf8_filenames[i], _L['Binary file matches.']))
+ _G.buffer:add_text(string.format('%s:1:%s\n', utf8_filenames[i], _L['Binary file matches.']))
break
end
local line_num = buffer:line_from_position(buffer.target_start)
local line = buffer:get_line(line_num)
- _G.buffer:add_text(
- string.format('%s:%d:%s', utf8_filenames[i], line_num, line))
- local pos = _G.buffer.current_pos - #line +
- buffer.target_start - buffer:position_from_line(line_num)
- _G.buffer:indicator_fill_range(
- pos, buffer.target_end - buffer.target_start)
+ _G.buffer:add_text(string.format('%s:%d:%s', utf8_filenames[i], line_num, line))
+ local pos = _G.buffer.current_pos - #line + buffer.target_start -
+ buffer:position_from_line(line_num)
+ _G.buffer:indicator_fill_range(pos, buffer.target_end - buffer.target_start)
if not line:find('\n$') then _G.buffer:add_text('\n') end
buffer:set_target_range(buffer.target_end, buffer.length + 1)
end
@@ -365,36 +351,33 @@ function M.find_in_files(dir, filter)
return i * 100 / #filenames, utf8_filenames[i]
end)
buffer:close(true) -- temporary buffer
- ui._print(
- _L['[Files Found Buffer]'],
- stopped and _L['Find in Files aborted'] .. '\n' or
- not found and _L['No results found'] .. '\n' or '')
+ local status = stopped and _L['Find in Files aborted'] or not found and _L['No results found']
+ ui._print(_L['[Files Found Buffer]'], status and status .. '\n' or '')
end
local P, V, C, upper, lower = lpeg.P, lpeg.V, lpeg.C, string.upper, string.lower
local esc = {b = '\b', f = '\f', n = '\n', r = '\r', t = '\t', v = '\v'}
local re_patt = lpeg.Cs(P{
(V('text') + V('u') + V('l') + V('U') + V('L') + V('esc'))^1,
- text = (1 - '\\' * lpeg.S('uUlLEbfnrtv'))^1,
+ text = (1 - '\\' * lpeg.S('uUlLEbfnrtv'))^1, -- LuaFormatter
u = '\\u' * C(1) / upper, l = '\\l' * C(1) / lower,
U = P('\\U') / '' * (V('text') / upper + V('u') + V('l'))^0 * V('E')^-1,
- L = P('\\L') / '' * (V('text') / lower + V('u') + V('l'))^0 * V('E')^-1,
+ L = P('\\L') / '' * (V('text') / lower + V('u') + V('l'))^0 * V('E')^-1, -- LuaFormatter
E = P('\\E') / '', esc = '\\' * C(1) / esc
})
-- Returns string *text* with the following sequences unescaped:
-- * "\uXXXX" sequences replaced with the equivalent UTF-8 character.
--- * "\d" sequences replaced with the text of capture number *d* from the
--- regular expression (or the entire match for *d* = 0).
--- * "\U" and "\L" sequences convert everything up to the next "\U", "\L", or
--- "\E" to uppercase and lowercase, respectively.
--- * "\u" and "\l" sequences convert the next character to uppercase and
--- lowercase, respectively. They may appear within "\U" and "\L" constructs.
+-- * "\d" sequences replaced with the text of capture number *d* from the regular expression
+-- (or the entire match for *d* = 0).
+-- * "\U" and "\L" sequences convert everything up to the next "\U", "\L", or "\E" to uppercase
+-- and lowercase, respectively.
+-- * "\u" and "\l" sequences convert the next character to uppercase and lowercase, respectively.
+-- They may appear within "\U" and "\L" constructs.
-- @param text String text to unescape.
-- @return unescaped text
local function unescape(text)
- text = text:gsub('%f[\\]\\u(%x%x%x%x)', function(code)
- return utf8.char(tonumber(code, 16))
- end):gsub('\\0', buffer.target_text):gsub('\\(%d)', buffer.tag)
+ text = text:gsub('%f[\\]\\u(%x%x%x%x)', function(code) return utf8.char(tonumber(code, 16)) end)
+ :gsub('\\0', buffer.target_text):gsub('\\(%d)', buffer.tag)
return re_patt:match(text) or text
end
@@ -408,14 +391,13 @@ end)
local INDIC_REPLACE = _SCINTILLA.next_indic_number()
-- Replaces all found text in the current buffer (ignores "Find in Files").
--- If any text is selected (other than text just found), only found text in that
--- selection is replaced.
+-- If any text is selected (other than text just found), only found text in that selection
+-- is replaced.
events.connect(events.REPLACE_ALL, function(ftext, rtext)
if ftext == '' then return end
local count = 0
local s, e = buffer.selection_start, buffer.selection_end
- local replace_in_sel =
- s ~= e and (ftext ~= find_text or buffer:get_sel_text() ~= found_text)
+ local replace_in_sel = s ~= e and (ftext ~= find_text or buffer:get_sel_text() ~= found_text)
if replace_in_sel then
buffer.indicator_current = INDIC_REPLACE
buffer:indicator_fill_range(e, 1)
@@ -427,8 +409,8 @@ events.connect(events.REPLACE_ALL, function(ftext, rtext)
buffer:begin_undo_action()
buffer.search_flags = get_flags()
buffer:set_target_range(not replace_in_sel and 1 or s, buffer.length + 1)
- while buffer:search_in_target(ftext) ~= -1 and (not replace_in_sel or
- buffer.target_end <= buffer:indicator_end(INDIC_REPLACE, s) or EOF) do
+ while buffer:search_in_target(ftext) ~= -1 and
+ (not replace_in_sel or buffer.target_end <= buffer:indicator_end(INDIC_REPLACE, s) or EOF) do
if buffer.target_start == buffer.target_end then break end -- prevent loops
buffer:replace_target(not M.regex and rtext or unescape(rtext))
count = count + 1
@@ -446,30 +428,39 @@ events.connect(events.REPLACE_ALL, function(ftext, rtext)
end)
---
--- Jumps to the source of the find in files search result on line number
--- *line_num* in the buffer titled "Files Found" or, if *line_num* is `nil`,
--- jumps to the next or previous search result, depending on boolean *next*.
--- @param line_num Optional line number in the files found buffer that contains
--- the search result to go to. This parameter may be omitted completely.
--- @param next Optional flag indicating whether to go to the next search result
--- or the previous one. Only applicable when *line_num* is `nil`.
+-- Jumps to the source of the find in files search result on line number *line_num* in the buffer
+-- titled "Files Found" or, if *line_num* is `nil`, jumps to the next or previous search result,
+-- depending on boolean *next*.
+-- @param line_num Optional line number in the files found buffer that contains the search
+-- result to go to. This parameter may be omitted completely.
+-- @param next Optional flag indicating whether to go to the next search result or the previous
+-- one. Only applicable when *line_num* is `nil`.
-- @name goto_file_found
function M.goto_file_found(line_num, next)
if type(line_num) == 'boolean' then line_num, next = nil, line_num end
local ff_view, ff_buf = nil, nil
for i = 1, #_VIEWS do
- if is_ff_buf(_VIEWS[i].buffer) then ff_view = _VIEWS[i] break end
+ if is_ff_buf(_VIEWS[i].buffer) then
+ ff_view = _VIEWS[i]
+ break
+ end
end
for i = 1, #_BUFFERS do
- if is_ff_buf(_BUFFERS[i]) then ff_buf = _BUFFERS[i] break end
+ if is_ff_buf(_BUFFERS[i]) then
+ ff_buf = _BUFFERS[i]
+ break
+ end
end
if not ff_view and not ff_buf then return end
- if ff_view then ui.goto_view(ff_view) else view:goto_buffer(ff_buf) end
+ if ff_view then
+ ui.goto_view(ff_view)
+ else
+ view:goto_buffer(ff_buf)
+ end
- -- If no line number was given, find the next search result, wrapping as
- -- necessary.
+ -- If no line number was given, find the next search result, wrapping as necessary.
if not assert_type(line_num, 'number/nil', 1) and next ~= nil then
- if next then buffer:line_end() else buffer:home() end
+ buffer[next and 'line_end' or 'home'](buffer)
buffer:search_anchor()
local f = next and buffer.search_next or buffer.search_prev
local pos = f(buffer, buffer.FIND_REGEXP, '^.+:\\d+:.+$')
@@ -487,7 +478,8 @@ function M.goto_file_found(line_num, next)
local line = buffer:get_cur_line()
local utf8_filename, pos
utf8_filename, line_num, pos = line:match('^(.+):(%d+):()')
- if not utf8_filename then return else line_num = tonumber(line_num) end
+ if not utf8_filename then return end
+ line_num = tonumber(line_num)
textadept.editing.select_line()
pos = buffer.selection_start + pos - 1 -- absolute pos of result text on line
local s = buffer:indicator_end(M.INDIC_FIND, buffer.selection_start)
@@ -508,9 +500,8 @@ events.connect(events.KEYPRESS, function(code)
M.goto_file_found(buffer:line_from_position(buffer.current_pos))
return true
end)
-events.connect(events.DOUBLE_CLICK, function(_, line)
- if is_ff_buf(buffer) then M.goto_file_found(line) end
-end)
+events.connect(events.DOUBLE_CLICK,
+ function(_, line) if is_ff_buf(buffer) then M.goto_file_found(line) end end)
--[[ The functions below are Lua C functions.
diff --git a/modules/textadept/history.lua b/modules/textadept/history.lua
index 0c6113e4..da9f5885 100644
--- a/modules/textadept/history.lua
+++ b/modules/textadept/history.lua
@@ -4,14 +4,13 @@ local M = {}
--[[ This comment is for LuaDoc.
---
--- Records buffer positions within Textadept views over time and allows for
--- navigating through that history.
+-- Records buffer positions within Textadept views over time and allows for navigating through
+-- that history.
--
--- This module listens for text edit events and buffer switch events. Each time
--- an insertion or deletion occurs, its location is recorded in the current
--- view's location history. If the edit is close enough to the previous record,
--- the previous record is amended. Each time a buffer switch occurs, the before
--- and after locations are also recorded.
+-- This module listens for text edit events and buffer switch events. Each time an insertion
+-- or deletion occurs, its location is recorded in the current view's location history. If the
+-- edit is close enough to the previous record, the previous record is amended. Each time a
+-- buffer switch occurs, the before and after locations are also recorded.
-- @field minimum_line_distance (number)
-- The minimum number of lines between distinct history records.
-- The default value is `3`.
@@ -24,14 +23,15 @@ M.minimum_line_distance = 3
M.maximum_history_size = 100
-- Map of views to their history records.
--- Each record has a `pos` field that points to the current history position in
--- the associated view.
+-- Each record has a `pos` field that points to the current history position in the associated view.
-- @class table
-- @name view_history
-local view_history = setmetatable({}, {__index = function(t, view)
- t[view] = {pos = 0}
- return t[view]
-end})
+local view_history = setmetatable({}, {
+ __index = function(t, view)
+ t[view] = {pos = 0}
+ return t[view]
+ end
+})
-- Listens for text insertion and deletion events and records their locations.
events.connect(events.MODIFIED, function(position, mod, text, length)
@@ -50,8 +50,7 @@ events.connect(events.MODIFIED, function(position, mod, text, length)
M.record(nil, buffer:line_from_position(position), buffer.column[position])
end)
--- Do not record positions during buffer switches when jumping backwards or
--- forwards.
+-- Do not record positions during buffer switches when jumping backwards or forwards.
local jumping = false
-- Jumps to the given record in the current view's history.
@@ -64,8 +63,7 @@ local function jump(record)
else
for _, buffer in ipairs(_BUFFERS) do
if buffer.filename == filename or buffer._type == filename or
- not buffer.filename and not buffer._type and
- filename == _L['Untitled'] then
+ (not buffer.filename and not buffer._type and filename == _L['Untitled']) then
view:goto_buffer(buffer)
break
end
@@ -84,12 +82,15 @@ function M.back()
local record = history[history.pos]
local line = buffer:line_from_position(buffer.current_pos)
if buffer.filename ~= record.filename and buffer._type ~= record.filename or
- math.abs(record.line - line) > M.minimum_line_distance then
- -- When navigated away from the most recent record, and if that record is
- -- not a soft record, jump back to it first, then navigate backwards.
- if not record.soft then jump(record) return end
- -- Otherwise, update the soft record with the current position and
- -- immediately navigate backwards.
+ math.abs(record.line - line) > M.minimum_line_distance then
+ -- When navigated away from the most recent record, and if that record is not a soft record,
+ -- jump back to it first, then navigate backwards.
+ if not record.soft then
+ jump(record)
+ return
+ end
+ -- Otherwise, update the soft record with the current position and immediately navigate
+ -- backwards.
M.record(record.filename, nil, nil, record.soft)
end
if history.pos > 1 then history.pos = history.pos - 1 end
@@ -110,15 +111,14 @@ end
---
-- Records the given location in the current view's history.
--- @param filename Optional string filename, buffer type, or identifier of the
--- buffer to store. If `nil`, uses the current buffer.
--- @param line Optional Integer line number to store. If `nil`, uses the current
--- line.
--- @param column Optional integer column number on line *line* to store. If
--- `nil`, uses the current column.
--- @param soft Optional flag that indicates whether or not this record should be
--- skipped when navigating backward towards it, and updated when navigating
--- away from it. The default value is `false`.
+-- @param filename Optional string filename, buffer type, or identifier of the buffer to store. If
+-- `nil`, uses the current buffer.
+-- @param line Optional Integer line number to store. If `nil`, uses the current line.
+-- @param column Optional integer column number on line *line* to store. If `nil`, uses the
+-- current column.
+-- @param soft Optional flag that indicates whether or not this record should be skipped when
+-- navigating backward towards it, and updated when navigating away from it. The default
+-- value is `false`.
-- @name record
function M.record(filename, line, column, soft)
if not assert_type(filename, 'string/nil', 1) then
@@ -127,17 +127,14 @@ function M.record(filename, line, column, soft)
if not assert_type(line, 'number/nil', 2) then
line = buffer:line_from_position(buffer.current_pos)
end
- if not assert_type(column, 'number/nil', 3) then
- column = buffer.column[buffer.current_pos]
- end
+ if not assert_type(column, 'number/nil', 3) then column = buffer.column[buffer.current_pos] end
local history = view_history[view]
if #history > 0 then
local record = history[history.pos]
if filename == record.filename and
- (math.abs(record.line - line) <= M.minimum_line_distance or
- record.soft) then
- -- If the most recent record is close enough (distance-wise), or if that
- -- record is a soft record, update it instead of recording a new one.
+ (math.abs(record.line - line) <= M.minimum_line_distance or record.soft) then
+ -- If the most recent record is close enough (distance-wise), or if that record is a soft
+ -- record, update it instead of recording a new one.
record.line, record.column = line, column
record.soft = soft and record.soft
return
@@ -146,17 +143,13 @@ function M.record(filename, line, column, soft)
if history.pos < #history then
for i = history.pos + 1, #history do history[i] = nil end -- clear forward
end
- history[#history + 1] = {
- filename = filename, line = line, column = column, soft = soft
- }
+ history[#history + 1] = {filename = filename, line = line, column = column, soft = soft}
if #history > M.maximum_history_size then table.remove(history, 1) end
history.pos = #history
end
-- Softly record positions when switching between buffers.
-local function record_switch()
- if not jumping then M.record(nil, nil, nil, true) end
-end
+local function record_switch() if not jumping then M.record(nil, nil, nil, true) end end
events.connect(events.BUFFER_BEFORE_SWITCH, record_switch)
events.connect(events.BUFFER_AFTER_SWITCH, record_switch)
events.connect(events.FILE_OPENED, record_switch)
@@ -164,8 +157,6 @@ events.connect(events.FILE_OPENED, record_switch)
---
-- Clears all view history.
-- @name clear
-function M.clear()
- for view in pairs(view_history) do view_history[view] = {pos = 0} end
-end
+function M.clear() for view in pairs(view_history) do view_history[view] = {pos = 0} end end
return M
diff --git a/modules/textadept/init.lua b/modules/textadept/init.lua
index 6ba747a0..d2bde80c 100644
--- a/modules/textadept/init.lua
+++ b/modules/textadept/init.lua
@@ -10,8 +10,8 @@ textadept = M -- forward declaration
module('textadept')]]
local modules = {
- 'bookmarks', 'command_entry', 'editing', 'file_types', 'find', 'history',
- 'macros', 'run', 'session', 'snippets', --[[need to be last]] 'menu', 'keys'
+ 'bookmarks', 'command_entry', 'editing', 'file_types', 'find', 'history', 'macros', 'run',
+ 'session', 'snippets', --[[need to be last]] 'menu', 'keys'
}
for _, name in ipairs(modules) do M[name] = require('textadept.' .. name) end
M.command_entry, M.find = nil, nil -- ui.command_entry, ui.find
diff --git a/modules/textadept/keys.lua b/modules/textadept/keys.lua
index 5cae6988..b50503cb 100644
--- a/modules/textadept/keys.lua
+++ b/modules/textadept/keys.lua
@@ -5,214 +5,214 @@ local M = {}
--[[ This comment is for LuaDoc.
---
-- Defines key bindings for Textadept.
--- This set of key bindings is pretty standard among other text editors, at
--- least for basic editing commands and movements.
+-- This set of key bindings is pretty standard among other text editors, at least for basic
+-- editing commands and movements.
--
-- ### Key Bindings
--
--- Win32, Linux, BSD|macOS|Terminal|Command
--- -----------------|-----|--------|--------
--- **File** | | |
--- Ctrl+N |⌘N |M-^N |New file
--- Ctrl+O |⌘O |^O |Open file
--- Ctrl+Alt+O |^⌘O |M-^O |Open recent file...
--- Ctrl+Shift+O |⌘⇧O |M-O |Reload file
--- Ctrl+S |⌘S |^S |Save file
--- Ctrl+Shift+S |⌘⇧S |M-^S |Save file as..
--- None |None |None |Save all files
--- Ctrl+W |⌘W |^W |Close file
--- Ctrl+Shift+W |⌘⇧W |M-^W |Close all files
--- None |None |None |Load session...
--- None |None |None |Save session...
--- Ctrl+Q |⌘Q |^Q |Quit
--- **Edit** | | |
--- Ctrl+Z<br/>Alt+Bksp |⌘Z |^Z^(†)<br/>M-Z|Undo
--- Ctrl+Y<br/>Ctrl+Shift+Z|⌘⇧Z |^Y<br/>M-S-Z |Redo
--- Ctrl+X<br/>Shift+Del |⌘X<br/>⇧⌦|^X |Cut
--- Ctrl+C<br/>Ctrl+Ins |⌘C |^C |Copy
--- Ctrl+V<br/>Shift+Ins |⌘V |^V |Paste
--- Ctrl+Shift+V |⌘⇧V |M-V |Paste Reindent
--- Ctrl+D |⌘D |None |Duplicate line
--- Del |⌦<br/>^D |Del<br/>^D |Delete
--- Alt+Del |^⌦ |M-Del<br/>M-D |Delete word
--- Ctrl+A |⌘A |M-A |Select all
--- Ctrl+M |^M |M-M |Match brace
--- Ctrl+Enter |^Esc |M-Enter^(‡) |Complete word
--- Ctrl+/ |^/ |M-/ |Toggle block comment
--- Ctrl+T |^T |^T |Transpose characters
--- Ctrl+Shift+J |^J |M-J |Join lines
--- Ctrl+&#124; |⌘&#124; |^\ |Filter text through
--- Ctrl+Shift+M |^⇧M |M-S-M |Select between delimiters
--- Ctrl+< |⌘< |M-< |Select between XML tags
--- Ctrl+> |⌘> |None |Select in XML tag
--- Ctrl+Shift+D |⌘⇧D |M-S-W |Select word
--- Ctrl+Shift+N |⌘⇧N |M-S-N |Select line
--- Ctrl+Shift+P |⌘⇧P |M-S-P |Select paragraph
--- Ctrl+Alt+U |^U |M-^U |Upper case selection
--- Ctrl+Alt+Shift+U |^⇧U |M-^L |Lower case selection
--- Alt+< |^< |M-> |Enclose as XML tags
--- Alt+> |^> |None |Enclose as single XML tag
--- Alt+" |^" |None |Enclose in double quotes
--- Alt+' |^' |None |Enclose in single quotes
--- Alt+( |^( |M-) |Enclose in parentheses
--- Alt+[ |^[ |M-] |Enclose in brackets
--- Alt+{ |^{ |M-} |Enclose in braces
--- Ctrl+Shift+Up |^⇧⇡ |S-^Up |Move selected lines up
--- Ctrl+Shift+Down |^⇧⇣ |S-^Down |Move selected lines down
--- Alt+, |^, |M-, |Navigate backward
--- Alt+. |^. |M-. |Navigate forward
--- None |None |None |Record location
--- None |None |None |Clear navigation history
--- Ctrl+P |⌘, |M-~ |Preferences
--- **Search** | | |
--- Ctrl+F |⌘F |M-F<br/>M-S-F|Find
--- Ctrl+G<br/>F3 |⌘G |M-G |Find next
--- Ctrl+Shift+G<br/>Shift+F3|⌘⇧G |M-S-G |Find previous
--- Ctrl+Alt+R |^R |M-R |Replace
--- Ctrl+Alt+Shift+R |^⇧R |M-S-R |Replace all
--- Ctrl+Alt+F |^⌘F |M-^F |Find incremental
--- Ctrl+Shift+F |⌘⇧F |None |Find in files
--- Ctrl+Alt+G |^⌘G |None |Goto next file found
--- Ctrl+Alt+Shift+G |^⌘⇧G|None |Goto previous file found
--- Ctrl+J |⌘J |^J |Jump to line
--- **Tools** | | |
--- Ctrl+E |⌘E |M-C |Command entry
--- Ctrl+Shift+E |⌘⇧E |M-S-C |Select command
--- Ctrl+R |⌘R |^R |Run
--- Ctrl+Shift+R |⌘⇧R |M-^R |Compile
--- Ctrl+Shift+A |⌘⇧A |None |Set Arguments...
--- Ctrl+Shift+B |⌘⇧B |M-^B |Build
--- Ctrl+Shift+T |⌘⇧T |M-^T |Run tests
--- Ctrl+Shift+X |⌘⇧X |M-^X |Stop
--- Ctrl+Alt+E |^⌘E |M-X |Next Error
--- Ctrl+Alt+Shift+E|^⌘⇧E |M-S-X |Previous Error
--- Ctrl+F2 |⌘F2 |F1 |Toggle bookmark
--- Ctrl+Shift+F2 |⌘⇧F2 |F6 |Clear bookmarks
--- F2 |F2 |F2 |Next bookmark
--- Shift+F2 |⇧F2 |F3 |Previous bookmark
--- Alt+F2 |⌥F2 |F4 |Goto bookmark...
--- F9 |F9 |F9 |Start/stop recording macro
--- Shift+F9 |⇧F9 |F10 |Play recorded macro
--- Ctrl+U |⌘U |^U |Quickly open `_USERHOME`
--- None |None |None |Quickly open `_HOME`
--- Ctrl+Alt+Shift+O|^⌘⇧O |M-S-O |Quickly open current directory
--- Ctrl+Alt+Shift+P|^⌘⇧P |M-^P |Quickly open current project
--- Ctrl+Shift+K |⌥⇧⇥ |M-S-K |Insert snippet...
--- Tab |⇥ |Tab |Expand snippet or next placeholder
--- Shift+Tab |⇧⇥ |S-Tab |Previous snippet placeholder
--- Esc |Esc |Esc |Cancel snippet
--- Ctrl+K |⌥⇥ |M-K |Complete trigger word
--- Ctrl+Space |⌥Esc |^Space |Complete symbol
--- Ctrl+H |^H |M-H<br/>M-S-H|Show documentation
--- Ctrl+I |⌘I |M-S-I |Show style
--- **Buffer** | | |
--- Ctrl+Tab |^⇥ |M-N |Next buffer
--- Ctrl+Shift+Tab |^⇧⇥ |M-P |Previous buffer
--- Ctrl+B |⌘B |M-B<br/>M-S-B|Switch to buffer...
--- None |None |None |Tab width: 2
--- None |None |None |Tab width: 3
--- None |None |None |Tab width: 4
--- None |None |None |Tab width: 8
--- Ctrl+Alt+Shift+T|^⇧T |M-T<br/>M-S-T|Toggle use tabs
--- Ctrl+Alt+I |^I |M-I |Convert indentation
--- None |None |None |CR+LF EOL mode
--- None |None |None |LF EOL mode
--- None |None |None |UTF-8 encoding
--- None |None |None |ASCII encoding
--- None |None |None |CP-1252 encoding
--- None |None |None |UTF-16 encoding
--- Ctrl+Alt+\\ |^\\ |None |Toggle wrap mode
--- Ctrl+Alt+Shift+S|^⇧S |None |Toggle view whitespace
--- Ctrl+Shift+L |⌘⇧L |M-S-L |Select lexer...
--- **View** | | |
--- Ctrl+Alt+N |^⌥⇥ |M-^V N |Next view
--- Ctrl+Alt+P |^⌥⇧⇥ |M-^V P |Previous view
--- Ctrl+Alt+S<br/>Ctrl+Alt+H|^S |M-^V S<br/>M-^V H|Split view horizontal
--- Ctrl+Alt+V |^V |M-^V V |Split view vertical
--- Ctrl+Alt+W |^W |M-^V W |Unsplit view
--- Ctrl+Alt+Shift+W |^⇧W |M-^V S-W |Unsplit all views
--- Ctrl+Alt++<br/>Ctrl+Alt+=|^+<br/>^=|M-^V +<br/>M-^V =|Grow view
--- Ctrl+Alt+- |^- |M-^V - |Shrink view
--- Ctrl+* |⌘* |M-* |Toggle current fold
--- Ctrl+Alt+Shift+I |^⇧I |N/A |Toggle indent guides
--- Ctrl+Alt+Shift+V |^⇧V |None |Toggle virtual space
--- Ctrl+= |⌘= |N/A |Zoom in
--- Ctrl+- |⌘- |N/A |Zoom out
--- Ctrl+0 |⌘0 |N/A |Reset zoom
--- **Help**| | |
--- F1 |F1 |None|Open manual
--- Shift+F1|⇧F1 |None|Open LuaDoc
--- None |None|None|About
--- **Movement** | | |
--- Down |⇣<br/>^N |^N<br/>Down |Line down
--- Shift+Down |⇧⇣<br/>^⇧N |S-Down |Line down extend selection
--- Ctrl+Down |^⇣ |^Down |Scroll line down
--- Alt+Shift+Down |⌥⇧⇣ |M-S-Down |Line down extend rect. selection
--- Up |⇡<br/>^P |^P<br/>Up |Line up
--- Shift+Up |⇧⇡<br/>^⇧P |S-Up |Line up extend selection
--- Ctrl+Up |^⇡ |^Up |Scroll line up
--- Alt+Shift+Up |⌥⇧⇡ |M-S-Up |Line up extend rect. selection
--- Left |⇠<br/>^B |^B<br/>Left |Char left
--- Shift+Left |⇧⇠<br/>^⇧B |S-Left |Char left extend selection
--- Ctrl+Left |⌥⇠<br/>^⌘B |^Left |Word left
--- Ctrl+Shift+Left |^⇧⇠<br/>^⌘⇧B|S-^Left |Word left extend selection
--- Alt+Shift+Left |⌥⇧⇠ |M-S-Left |Char left extend rect. selection
--- Right |⇢<br/>^F |^F<br/>Right|Char right
--- Shift+Right |⇧⇢<br/>^⇧F |S-Right |Char right extend selection
--- Ctrl+Right |⌥⇢<br/>^⌘F |^Right |Word right
--- Ctrl+Shift+Right|^⇧⇢<br/>^⌘⇧F|S-^Right |Word right extend selection
--- Alt+Shift+Right |⌥⇧⇢ |M-S-Right |Char right extend rect. selection
--- Home |⌘⇠<br/>^A |^A<br/>Home |Line start
--- Shift+Home |⌘⇧⇠<br/>^⇧A |M-S-A |Line start extend selection
--- Ctrl+Home |⌘⇡<br/>⌘↖ |M-^A |Document start
--- Ctrl+Shift+Home |⌘⇧⇡<br/>⌘⇧↖ |None |Document start extend selection
--- Alt+Shift+Home |⌥⇧↖ |None |Line start extend rect. selection
--- End |⌘⇢<br/>^E |^E<br/>End |Line end
--- Shift+End |⌘⇧⇢<br/>^⇧E |M-S-E |Line end extend selection
--- Ctrl+End |⌘⇣<br/>⌘↘ |M-^E |Document end
--- Ctrl+Shift+End |⌘⇧⇣<br/>⌘⇧↘ |None |Document end extend selection
--- Alt+Shift+End |⌥⇧↘ |None |Line end extend rect. selection
--- PgUp |⇞ |PgUp |Page up
--- Shift+PgUp |⇧⇞ |M-S-U |Page up extend selection
--- Alt+Shift+PgUp |⌥⇧⇞ |None |Page up extend rect. selection
--- PgDn |⇟ |PgDn |Page down
--- Shift+PgDn |⇧⇟ |M-S-D |Page down extend selection
--- Alt+Shift+PgDn |⌥⇧⇟ |None |Page down extend rect. selection
--- Ctrl+Del |⌘⌦ |^Del |Delete word right
--- Ctrl+Shift+Del |⌘⇧⌦ |S-^Del |Delete line right
--- Ins |Ins |Ins |Toggle overtype
--- Bksp |⌫<br/>⇧⌫ |^H<br/>Bksp |Delete back
--- Ctrl+Bksp |⌘⌫ |None |Delete word left
--- Ctrl+Shift+Bksp |⌘⇧⌫ |None |Delete line left
--- Tab |⇥ |Tab<br/>^I |Insert tab or indent
--- Shift+Tab |⇧⇥ |S-Tab |Dedent
--- None |^K |^K |Cut to line end
--- None |^L |None |Center line vertically
--- N/A |N/A |^^ |Mark text at the caret position
--- N/A |N/A |^] |Swap caret and mark anchor
--- **UTF-8 Input** | | |
--- Ctrl+Shift+U *xxxx* Enter|⌘⇧U *xxxx* ↩|M-U *xxxx* Enter|Insert U-*xxxx* char.
--- **Find Fields**| | |
--- Left |⇠<br/>^B |^B<br/>Left |Cursor left
--- Right |⇢<br/>^F |^F<br/>Right|Cursor right
--- Del |⌦ |Del |Delete forward
--- Bksp |⌫ |^H<br/>Bksp |Delete back
--- Ctrl+V |⌘V |^V |Paste
--- N/A |N/A |^X |Cut all
--- N/A |N/A |^Y |Copy all
--- N/A |N/A |^U |Erase all
--- Home |↖<br/>⌘⇠<br/>^A|^A |Home
--- End |↘<br/>⌘⇢<br/>^E|^E |End
--- N/A |N/A |^T |Transpose characters
--- N/A |N/A |Tab |Toggle find/replace buttons
--- Tab |⇥ |Down |Focus replace field
--- Shift+Tab |⇧⇥ |Up |Focus find field
--- Up |⇡ |^P |Cycle back through history
--- Down |⇣ |^N |Cycle forward through history
--- N/A |N/A |F1 |Toggle "Match Case"
--- N/A |N/A |F2 |Toggle "Whole Word"
--- N/A |N/A |F3 |Toggle "Regex"
--- N/A |N/A |F4 |Toggle "Find in Files"
+-- Win32, Linux, BSD | macOS | Terminal | Command
+-- -|-|-|-
+-- **File**|||
+-- Ctrl+N | ⌘N | M-^N | New file
+-- Ctrl+O | ⌘O | ^O | Open file
+-- Ctrl+Alt+O | ^⌘O | M-^O | Open recent file...
+-- Ctrl+Shift+O | ⌘⇧O | M-O | Reload file
+-- Ctrl+S | ⌘S | ^S | Save file
+-- Ctrl+Shift+S | ⌘⇧S | M-^S | Save file as..
+-- None | None | None | Save all files
+-- Ctrl+W | ⌘W | ^W | Close file
+-- Ctrl+Shift+W | ⌘⇧W | M-^W | Close all files
+-- None | None | None | Load session...
+-- None | None | None | Save session...
+-- Ctrl+Q | ⌘Q | ^Q | Quit
+-- **Edit**| | |
+-- Ctrl+Z<br/>Alt+Bksp | ⌘Z | ^Z^(†)<br/>M-Z | Undo
+-- Ctrl+Y<br/>Ctrl+Shift+Z | ⌘⇧Z | ^Y<br/>M-S-Z | Redo
+-- Ctrl+X<br/>Shift+Del | ⌘X<br/>⇧⌦ | ^X | Cut
+-- Ctrl+C<br/>Ctrl+Ins | ⌘C | ^C | Copy
+-- Ctrl+V<br/>Shift+Ins | ⌘V | ^V | Paste
+-- Ctrl+Shift+V | ⌘⇧V | M-V | Paste Reindent
+-- Ctrl+D | ⌘D | None | Duplicate line
+-- Del | ⌦<br/>^D | Del<br/>^D | Delete
+-- Alt+Del | ^⌦ | M-Del<br/>M-D | Delete word
+-- Ctrl+A | ⌘A | M-A | Select all
+-- Ctrl+M | ^M | M-M | Match brace
+-- Ctrl+Enter | ^Esc | M-Enter^(‡) | Complete word
+-- Ctrl+/ | ^/ | M-/ | Toggle block comment
+-- Ctrl+T | ^T | ^T | Transpose characters
+-- Ctrl+Shift+J | ^J | M-J | Join lines
+-- Ctrl+&#124; | ⌘&#124; | ^\ | Filter text through
+-- Ctrl+Shift+M | ^⇧M | M-S-M | Select between delimiters
+-- Ctrl+< | ⌘< | M-< | Select between XML tags
+-- Ctrl+> | ⌘> | None | Select in XML tag
+-- Ctrl+Shift+D | ⌘⇧D | M-S-W | Select word
+-- Ctrl+Shift+N | ⌘⇧N | M-S-N | Select line
+-- Ctrl+Shift+P | ⌘⇧P | M-S-P | Select paragraph
+-- Ctrl+Alt+U | ^U | M-^U | Upper case selection
+-- Ctrl+Alt+Shift+U | ^⇧U | M-^L | Lower case selection
+-- Alt+< | ^< | M-> | Enclose as XML tags
+-- Alt+> | ^> | None | Enclose as single XML tag
+-- Alt+" | ^" | None | Enclose in double quotes
+-- Alt+' | ^' | None | Enclose in single quotes
+-- Alt+( | ^( | M-) | Enclose in parentheses
+-- Alt+[ | ^[ | M-] | Enclose in brackets
+-- Alt+{ | ^{ | M-} | Enclose in braces
+-- Ctrl+Shift+Up | ^⇧⇡ | S-^Up | Move selected lines up
+-- Ctrl+Shift+Down | ^⇧⇣ | S-^Down | Move selected lines down
+-- Alt+, | ^, | M-, | Navigate backward
+-- Alt+. | ^. | M-. | Navigate forward
+-- None | None | None | Record location
+-- None | None | None | Clear navigation history
+-- Ctrl+P | ⌘, | M-~ | Preferences
+-- **Search**| | |
+-- Ctrl+F | ⌘F | M-F<br/>M-S-F | Find
+-- Ctrl+G<br/>F3 | ⌘G | M-G | Find next
+-- Ctrl+Shift+G<br/>Shift+F3 | ⌘⇧G | M-S-G | Find previous
+-- Ctrl+Alt+R | ^R | M-R | Replace
+-- Ctrl+Alt+Shift+R | ^⇧R | M-S-R | Replace all
+-- Ctrl+Alt+F | ^⌘F | M-^F | Find incremental
+-- Ctrl+Shift+F | ⌘⇧F | None | Find in files
+-- Ctrl+Alt+G | ^⌘G | None | Goto next file found
+-- Ctrl+Alt+Shift+G | ^⌘⇧G | None | Goto previous file found
+-- Ctrl+J | ⌘J | ^J | Jump to line
+-- **Tools**| | |
+-- Ctrl+E | ⌘E | M-C | Command entry
+-- Ctrl+Shift+E | ⌘⇧E | M-S-C | Select command
+-- Ctrl+R | ⌘R | ^R | Run
+-- Ctrl+Shift+R | ⌘⇧R | M-^R | Compile
+-- Ctrl+Shift+A | ⌘⇧A | None | Set Arguments...
+-- Ctrl+Shift+B | ⌘⇧B | M-^B | Build
+-- Ctrl+Shift+T | ⌘⇧T | M-^T | Run tests
+-- Ctrl+Shift+X | ⌘⇧X | M-^X | Stop
+-- Ctrl+Alt+E | ^⌘E | M-X | Next Error
+-- Ctrl+Alt+Shift+E | ^⌘⇧E | M-S-X | Previous Error
+-- Ctrl+F2 | ⌘F2 | F1 | Toggle bookmark
+-- Ctrl+Shift+F2 | ⌘⇧F2 | F6 | Clear bookmarks
+-- F2 | F2 | F2 | Next bookmark
+-- Shift+F2 | ⇧F2 | F3 | Previous bookmark
+-- Alt+F2 | ⌥F2 | F4 | Goto bookmark...
+-- F9 | F9 | F9 | Start/stop recording macro
+-- Shift+F9 | ⇧F9 | F10 | Play recorded macro
+-- Ctrl+U | ⌘U | ^U | Quickly open `_USERHOME`
+-- None | None | None | Quickly open `_HOME`
+-- Ctrl+Alt+Shift+O | ^⌘⇧O | M-S-O | Quickly open current directory
+-- Ctrl+Alt+Shift+P | ^⌘⇧P | M-^P | Quickly open current project
+-- Ctrl+Shift+K | ⌥⇧⇥ | M-S-K | Insert snippet...
+-- Tab | ⇥ | Tab | Expand snippet or next placeholder
+-- Shift+Tab | ⇧⇥ | S-Tab | Previous snippet placeholder
+-- Esc | Esc | Esc | Cancel snippet
+-- Ctrl+K | ⌥⇥ | M-K | Complete trigger word
+-- Ctrl+Space | ⌥Esc | ^Space | Complete symbol
+-- Ctrl+H | ^H | M-H<br/>M-S-H | Show documentation
+-- Ctrl+I | ⌘I | M-S-I | Show style
+-- **Buffer**| | |
+-- Ctrl+Tab | ^⇥ | M-N | Next buffer
+-- Ctrl+Shift+Tab | ^⇧⇥ | M-P | Previous buffer
+-- Ctrl+B | ⌘B | M-B<br/>M-S-B | Switch to buffer...
+-- None | None | None | Tab width: 2
+-- None | None | None | Tab width: 3
+-- None | None | None | Tab width: 4
+-- None | None | None | Tab width: 8
+-- Ctrl+Alt+Shift+T | ^⇧T | M-T<br/>M-S-T | Toggle use tabs
+-- Ctrl+Alt+I | ^I | M-I | Convert indentation
+-- None | None | None | CR+LF EOL mode
+-- None | None | None | LF EOL mode
+-- None | None | None | UTF-8 encoding
+-- None | None | None | ASCII encoding
+-- None | None | None | CP-1252 encoding
+-- None | None | None | UTF-16 encoding
+-- Ctrl+Alt+\\ | ^\\ | None | Toggle wrap mode
+-- Ctrl+Alt+Shift+S | ^⇧S | None | Toggle view whitespace
+-- Ctrl+Shift+L | ⌘⇧L | M-S-L | Select lexer...
+-- **View**| | |
+-- Ctrl+Alt+N | ^⌥⇥ | M-^V N | Next view
+-- Ctrl+Alt+P | ^⌥⇧⇥ | M-^V P | Previous view
+-- Ctrl+Alt+S<br/>Ctrl+Alt+H | ^S | M-^V S<br/>M-^V H | Split view horizontal
+-- Ctrl+Alt+V | ^V | M-^V V | Split view vertical
+-- Ctrl+Alt+W | ^W | M-^V W | Unsplit view
+-- Ctrl+Alt+Shift+W | ^⇧W | M-^V S-W | Unsplit all views
+-- Ctrl+Alt++<br/>Ctrl+Alt+= | ^+<br/>^= | M-^V +<br/>M-^V = | Grow view
+-- Ctrl+Alt+- | ^- | M-^V - | Shrink view
+-- Ctrl+* | ⌘* | M-* | Toggle current fold
+-- Ctrl+Alt+Shift+I | ^⇧I | N/A | Toggle indent guides
+-- Ctrl+Alt+Shift+V | ^⇧V | None | Toggle virtual space
+-- Ctrl+= | ⌘= | N/A | Zoom in
+-- Ctrl+- | ⌘- | N/A | Zoom out
+-- Ctrl+0 | ⌘0 | N/A | Reset zoom
+-- **Help**|| |
+-- F1 | F1 | None | Open manual
+-- Shift+F1 | ⇧F1 | None | Open LuaDoc
+-- None | None | None | About
+-- **Movement**| | |
+-- Down | ⇣<br/>^N | ^N<br/>Down | Line down
+-- Shift+Down | ⇧⇣<br/>^⇧N | S-Down | Line down extend selection
+-- Ctrl+Down | ^⇣ | ^Down | Scroll line down
+-- Alt+Shift+Down | ⌥⇧⇣ | M-S-Down | Line down extend rect. selection
+-- Up | ⇡<br/>^P | ^P<br/>Up | Line up
+-- Shift+Up | ⇧⇡<br/>^⇧P | S-Up | Line up extend selection
+-- Ctrl+Up | ^⇡ | ^Up | Scroll line up
+-- Alt+Shift+Up | ⌥⇧⇡ | M-S-Up | Line up extend rect. selection
+-- Left | ⇠<br/>^B | ^B<br/>Left | Char left
+-- Shift+Left | ⇧⇠<br/>^⇧B | S-Left | Char left extend selection
+-- Ctrl+Left | ⌥⇠<br/>^⌘B | ^Left | Word left
+-- Ctrl+Shift+Left | ^⇧⇠<br/>^⌘⇧B | S-^Left | Word left extend selection
+-- Alt+Shift+Left | ⌥⇧⇠ | M-S-Left | Char left extend rect. selection
+-- Right | ⇢<br/>^F | ^F<br/>Right | Char right
+-- Shift+Right | ⇧⇢<br/>^⇧F | S-Right | Char right extend selection
+-- Ctrl+Right | ⌥⇢<br/>^⌘F | ^Right | Word right
+-- Ctrl+Shift+Right | ^⇧⇢<br/>^⌘⇧F | S-^Right | Word right extend selection
+-- Alt+Shift+Right | ⌥⇧⇢ | M-S-Right | Char right extend rect. selection
+-- Home | ⌘⇠<br/>^A | ^A<br/>Home | Line start
+-- Shift+Home | ⌘⇧⇠<br/>^⇧A | M-S-A | Line start extend selection
+-- Ctrl+Home | ⌘⇡<br/>⌘↖ | M-^A | Document start
+-- Ctrl+Shift+Home | ⌘⇧⇡<br/>⌘⇧↖ | None | Document start extend selection
+-- Alt+Shift+Home | ⌥⇧↖ | None | Line start extend rect. selection
+-- End | ⌘⇢<br/>^E | ^E<br/>End | Line end
+-- Shift+End | ⌘⇧⇢<br/>^⇧E | M-S-E | Line end extend selection
+-- Ctrl+End | ⌘⇣<br/>⌘↘ | M-^E | Document end
+-- Ctrl+Shift+End | ⌘⇧⇣<br/>⌘⇧↘ | None | Document end extend selection
+-- Alt+Shift+End | ⌥⇧↘ | None | Line end extend rect. selection
+-- PgUp | ⇞ | PgUp | Page up
+-- Shift+PgUp | ⇧⇞ | M-S-U | Page up extend selection
+-- Alt+Shift+PgUp | ⌥⇧⇞ | None | Page up extend rect. selection
+-- PgDn | ⇟ | PgDn | Page down
+-- Shift+PgDn | ⇧⇟ | M-S-D | Page down extend selection
+-- Alt+Shift+PgDn | ⌥⇧⇟ | None | Page down extend rect. selection
+-- Ctrl+Del | ⌘⌦ | ^Del | Delete word right
+-- Ctrl+Shift+Del | ⌘⇧⌦ | S-^Del | Delete line right
+-- Ins | Ins | Ins | Toggle overtype
+-- Bksp | ⌫<br/>⇧⌫ | ^H<br/>Bksp | Delete back
+-- Ctrl+Bksp | ⌘⌫ | None | Delete word left
+-- Ctrl+Shift+Bksp | ⌘⇧⌫ | None | Delete line left
+-- Tab | ⇥ | Tab<br/>^I | Insert tab or indent
+-- Shift+Tab | ⇧⇥ | S-Tab | Dedent
+-- None | ^K | ^K | Cut to line end
+-- None | ^L | None | Center line vertically
+-- N/A | N/A | ^^ | Mark text at the caret position
+-- N/A | N/A | ^] | Swap caret and mark anchor
+-- **UTF-8 Input**|||
+-- Ctrl+Shift+U *xxxx* Enter | ⌘⇧U *xxxx* ↩ | M-U *xxxx* Enter | Insert U-*xxxx* char.
+-- **Find Fields**|||
+-- Left | ⇠<br/>^B | ^B<br/>Left | Cursor left
+-- Right | ⇢<br/>^F | ^F<br/>Right | Cursor right
+-- Del | ⌦ | Del | Delete forward
+-- Bksp | ⌫ | ^H<br/>Bksp | Delete back
+-- Ctrl+V | ⌘V | ^V | Paste
+-- N/A | N/A | ^X | Cut all
+-- N/A | N/A | ^Y | Copy all
+-- N/A | N/A | ^U | Erase all
+-- Home | ↖<br/>⌘⇠<br/>^A | ^A | Home
+-- End | ↘<br/>⌘⇢<br/>^E | ^E | End
+-- N/A | N/A | ^T | Transpose characters
+-- N/A | N/A | Tab | Toggle find/replace buttons
+-- Tab | ⇥ | Down | Focus replace field
+-- Shift+Tab | ⇧⇥ | Up | Focus find field
+-- Up | ⇡ | ^P | Cycle back through history
+-- Down | ⇣ | ^N | Cycle forward through history
+-- N/A | N/A | F1 | Toggle "Match Case"
+-- N/A | N/A | F2 | Toggle "Whole Word"
+-- N/A | N/A | F3 | Toggle "Regex"
+-- N/A | N/A | F4 | Toggle "Find in Files"
--
-- †: Some terminals interpret ^Z as suspend; see FAQ for workaround.
--
@@ -251,13 +251,12 @@ module('textadept.keys')]]
-- Key bindings available depend on your implementation of curses.
--
-- For ncurses (Linux, macOS, BSD):
--- * The only Control keys recognized are 'ctrl+a'-'ctrl+z', 'ctrl+ ',
--- 'ctrl+\\', 'ctrl+]', 'ctrl+^', and 'ctrl+_'.
+-- * The only Control keys recognized are 'ctrl+a'-'ctrl+z', 'ctrl+ ', 'ctrl+\\', 'ctrl+]',
+-- 'ctrl+^', and 'ctrl+_'.
-- * Control+Shift and Control+Meta+Shift keys are not recognized.
-- * Modifiers for function keys F1-F12 are not recognized.
-- For pdcurses (Win32):
--- * Many Control+Symbol keys are not recognized, but most
--- Control+Shift+Symbol keys are.
+-- * Many Control+Symbol keys are not recognized, but most Control+Shift+Symbol keys are.
-- * Ctrl+Meta+Symbol keys are not recognized.
--
-- Unassigned keys (~ denotes keys reserved by the operating system):
@@ -272,8 +271,7 @@ module('textadept.keys')]]
-- Control, Meta, and 'a' = 'ctrl+meta+a'
local _L = _L
--- Returns the menu command associated with the '/'-separated string of menu
--- labels.
+-- Returns the menu command associated with the '/'-separated string of menu labels.
-- Labels are automatically localized.
-- @param labels Path to the menu command.
-- @usage m('Edit/Select/Select in XML Tag')
@@ -283,6 +281,7 @@ local function m(labels)
return menu[2]
end
+-- LuaFormatter off
-- Bindings for Linux/Win32, macOS, Terminal.
local bindings = {
-- File.
@@ -311,15 +310,13 @@ local bindings = {
[m('Edit/Delete Word')] = {'alt+del', 'ctrl+del', {'meta+del', 'meta+d'}},
[buffer.select_all] = {'ctrl+a', 'cmd+a', 'meta+a'},
[m('Edit/Match Brace')] = {'ctrl+m', 'ctrl+m', 'meta+m'},
- [m('Edit/Complete Word')] =
- {'ctrl+\n', 'ctrl+esc', {'ctrl+meta+j', 'ctrl+\n'}},
+ [m('Edit/Complete Word')] = {'ctrl+\n', 'ctrl+esc', {'ctrl+meta+j', 'ctrl+\n'}},
[textadept.editing.toggle_comment] = {'ctrl+/', 'ctrl+/', 'meta+/'},
[textadept.editing.transpose_chars] = {'ctrl+t', 'ctrl+t', 'ctrl+t'},
[textadept.editing.join_lines] = {'ctrl+J', 'ctrl+j', 'meta+j'},
[m('Edit/Filter Through')] = {'ctrl+|', 'cmd+|', 'ctrl+\\'},
-- Select.
- [m('Edit/Select/Select between Matching Delimiters')] =
- {'ctrl+M', 'ctrl+M', 'meta+M'},
+ [m('Edit/Select/Select between Matching Delimiters')] = {'ctrl+M', 'ctrl+M', 'meta+M'},
[m('Edit/Select/Select between XML Tags')] = {'ctrl+<', 'cmd+<', 'meta+<'},
[m('Edit/Select/Select in XML Tag')] = {'ctrl+>', 'cmd+>', nil},
[textadept.editing.select_word] = {'ctrl+D', 'cmd+D', 'meta+W'},
@@ -335,10 +332,8 @@ local bindings = {
[m('Edit/Selection/Enclose in Parentheses')] = {'alt+(', 'ctrl+(', 'meta+)'},
[m('Edit/Selection/Enclose in Brackets')] = {'alt+[', 'ctrl+[', 'meta+]'},
[m('Edit/Selection/Enclose in Braces')] = {'alt+{', 'ctrl+{', 'meta+}'},
- [buffer.move_selected_lines_up] =
- {'ctrl+shift+up', 'ctrl+shift+up', 'ctrl+shift+up'},
- [buffer.move_selected_lines_down] =
- {'ctrl+shift+down', 'ctrl+shift+down', 'ctrl+shift+down'},
+ [buffer.move_selected_lines_up] = {'ctrl+shift+up', 'ctrl+shift+up', 'ctrl+shift+up'},
+ [buffer.move_selected_lines_down] = {'ctrl+shift+down', 'ctrl+shift+down', 'ctrl+shift+down'},
-- History.
[textadept.history.back] = {'alt+,', 'ctrl+,', 'meta+,'},
[textadept.history.forward] = {'alt+.', 'ctrl+.', 'meta+.'},
@@ -385,11 +380,9 @@ local bindings = {
[textadept.macros.record] = {'f9', 'f9', 'f9'},
[textadept.macros.play] = {'shift+f9', 'shift+f9', 'f10'},
-- Quick Open.
- [m('Tools/Quick Open/Quickly Open User Home')] =
- {'ctrl+u', 'cmd+u', 'ctrl+u'},
+ [m('Tools/Quick Open/Quickly Open User Home')] = {'ctrl+u', 'cmd+u', 'ctrl+u'},
-- TODO: m('Tools/Quickly Open Textadept Home')
- [m('Tools/Quick Open/Quickly Open Current Directory')] =
- {'ctrl+alt+O', 'ctrl+cmd+O', 'meta+O'},
+ [m('Tools/Quick Open/Quickly Open Current Directory')] = {'ctrl+alt+O', 'ctrl+cmd+O', 'meta+O'},
[io.quick_open] = {'ctrl+alt+P', 'ctrl+cmd+P', 'ctrl+meta+p'},
-- Snippets.
[textadept.snippets.select] = {'ctrl+K', 'shift+alt+\t', 'meta+K'},
@@ -399,8 +392,7 @@ local bindings = {
[m('Tools/Snippets/Complete Trigger Word')] = {'ctrl+k', 'alt+\t', 'meta+k'},
-- Other.
[m('Tools/Complete Symbol')] = {'ctrl+ ', 'alt+esc', 'ctrl+ '},
- [textadept.editing.show_documentation] =
- {'ctrl+h', 'ctrl+h', {'meta+h', 'meta+H'}},
+ [textadept.editing.show_documentation] = {'ctrl+h', 'ctrl+h', {'meta+h', 'meta+H'}},
[m('Tools/Show Style')] = {'ctrl+i', 'cmd+i', 'meta+I'},
-- Buffer.
@@ -412,8 +404,7 @@ local bindings = {
-- TODO: m('Buffer/Indentation/Tab width: 3')
-- TODO: m('Buffer/Indentation/Tab width: 4')
-- TODO: m('Buffer/Indentation/Tab width: 8')
- [m('Buffer/Indentation/Toggle Use Tabs')] =
- {'ctrl+alt+T', 'ctrl+T', {'meta+t', 'meta+T'}},
+ [m('Buffer/Indentation/Toggle Use Tabs')] = {'ctrl+alt+T', 'ctrl+T', {'meta+t', 'meta+T'}},
[textadept.editing.convert_indentation] = {'ctrl+alt+i', 'ctrl+i', 'meta+i'},
-- EOL Mode.
-- TODO: m('Buffer/EOL Mode/CRLF')
@@ -430,13 +421,11 @@ local bindings = {
-- View.
[m('View/Next View')] = {'ctrl+alt+n', 'ctrl+alt+\t', nil},
[m('View/Previous View')] = {'ctrl+alt+p', 'ctrl+alt+shift+\t', nil},
- [m('View/Split View Horizontal')] =
- {{'ctrl+alt+s', 'ctrl+alt+h'}, 'ctrl+s', nil},
+ [m('View/Split View Horizontal')] = {{'ctrl+alt+s', 'ctrl+alt+h'}, 'ctrl+s', nil},
[m('View/Split View Vertical')] = {'ctrl+alt+v', 'ctrl+v', nil},
[m('View/Unsplit View')] = {'ctrl+alt+w', 'ctrl+w', nil},
[m('View/Unsplit All Views')] = {'ctrl+alt+W', 'ctrl+W', nil},
- [m('View/Grow View')] =
- {{'ctrl+alt++', 'ctrl+alt+='}, {'ctrl++', 'ctrl+='}, nil},
+ [m('View/Grow View')] = {{'ctrl+alt++', 'ctrl+alt+='}, {'ctrl++', 'ctrl+='}, nil},
[m('View/Shrink View')] = {'ctrl+alt+-', 'ctrl+-', nil},
[m('View/Toggle Current Fold')] = {'ctrl+*', 'cmd+*', 'meta+*'},
[m('View/Toggle Show Indent Guides')] = {'ctrl+alt+I', 'ctrl+I', nil},
@@ -450,34 +439,27 @@ local bindings = {
[m('Help/Show LuaDoc')] = {'shift+f1', 'shift+f1', nil},
-- Movement commands.
- -- Unbound keys are handled by Scintilla, but when playing back a macro, this
- -- is not possible. Define some useful default key bindings so Scintilla does
- -- not have to handle them. Note that Scintilla still will handle some keys.
+ -- Unbound keys are handled by Scintilla, but when playing back a macro, this is not possible.
+ -- Define some useful default key bindings so Scintilla does not have to handle them. Note
+ -- that Scintilla still will handle some keys.
[buffer.line_down] = {'down', {'down', 'ctrl+n'}, {'down', 'ctrl+n'}},
- [buffer.line_down_extend] =
- {'shift+down', {'shift+down', 'ctrl+N'}, 'shift+down'},
+ [buffer.line_down_extend] = {'shift+down', {'shift+down', 'ctrl+N'}, 'shift+down'},
[buffer.line_up] = {'up', {'up', 'ctrl+p'}, {'up', 'ctrl+p'}},
[buffer.line_up_extend] = {'shift+up', {'shift+up', 'ctrl+P'}, 'shift+up'},
[buffer.char_left] = {'left', {'left', 'ctrl+b'}, {'left', 'ctrl+b'}},
- [buffer.char_left_extend] =
- {'shift+left', {'shift+left', 'ctrl+B'}, 'shift+left'},
+ [buffer.char_left_extend] = {'shift+left', {'shift+left', 'ctrl+B'}, 'shift+left'},
[buffer.word_left] = {'ctrl+left', {'alt+left', 'ctrl+cmd+b'}, 'ctrl+left'},
[buffer.word_left_extend] =
{'ctrl+shift+left', {'ctrl+shift+left', 'ctrl+cmd+B'}, 'ctrl+shift+left'},
[buffer.char_right] = {'right', {'right', 'ctrl+f'}, {'right', 'ctrl+f'}},
- [buffer.char_right_extend] =
- {'shift+right', {'shift+right', 'ctrl+F'}, 'shift+right'},
- [buffer.word_right] =
- {'ctrl+right', {'alt+right', 'ctrl+cmd+f'}, 'ctrl+right'},
- [buffer.word_right_end_extend] = {
- 'ctrl+shift+right', {'ctrl+shift+right', 'ctrl+cmd+F'}, 'ctrl+shift+right'
- },
+ [buffer.char_right_extend] = {'shift+right', {'shift+right', 'ctrl+F'}, 'shift+right'},
+ [buffer.word_right] = {'ctrl+right', {'alt+right', 'ctrl+cmd+f'}, 'ctrl+right'},
+ [buffer.word_right_end_extend] =
+ {'ctrl+shift+right', {'ctrl+shift+right', 'ctrl+cmd+F'}, 'ctrl+shift+right'},
[buffer.vc_home] = {'home', {'cmd+left', 'ctrl+a'}, {'home', 'ctrl+a'}},
- [buffer.vc_home_extend] =
- {'shift+home', {'cmd+shift+left', 'ctrl+A'}, 'meta+A'},
+ [buffer.vc_home_extend] = {'shift+home', {'cmd+shift+left', 'ctrl+A'}, 'meta+A'},
[buffer.line_end] = {'end', {'cmd+right', 'ctrl+e'}, {'end', 'ctrl+e'}},
- [buffer.line_end_extend] =
- {'shift+end', {'cmd+shift+right', 'ctrl+E'}, 'meta+E'},
+ [buffer.line_end_extend] = {'shift+end', {'cmd+shift+right', 'ctrl+E'}, 'meta+E'},
[view.vertical_center_caret] = {nil, 'ctrl+l', nil},
[buffer.page_up_extend] = {nil, nil, 'meta+U'},
[buffer.page_down_extend] = {nil, nil, 'meta+D'},
@@ -486,11 +468,10 @@ local bindings = {
[function()
buffer:line_end_extend()
- if not buffer.selection_empty then buffer:cut() else buffer:clear() end
+ buffer[not buffer.selection_empty and 'cut' or 'clear'](buffer)
end] = {nil, 'ctrl+k', 'ctrl+k'},
[buffer.del_word_right] = {'ctrl+del', 'cmd+del', 'ctrl+del'},
- [buffer.del_line_right] =
- {'ctrl+shift+del', 'cmd+shift+del', 'ctrl+shift+del'},
+ [buffer.del_line_right] = {'ctrl+shift+del', 'cmd+shift+del', 'ctrl+shift+del'},
[buffer.delete_back] = {'\b', '\b', {'\b', 'ctrl+h'}},
[buffer.del_word_left] = {'ctrl+\b', 'cmd+\b', nil},
[buffer.del_line_left] = {'ctrl+shift+\b', 'cmd+shift+\b', nil},
@@ -500,10 +481,10 @@ local bindings = {
-- Other.
-- UTF-8 input.
[function()
- ui.command_entry.run(
- function(code) buffer:add_text(utf8.char(tonumber(code, 16))) end)
+ ui.command_entry.run(function(code) buffer:add_text(utf8.char(tonumber(code, 16))) end)
end] = {nil, 'cmd+U', 'meta+u'}
}
+-- LuaFormatter on
local keys, plat = keys, CURSES and 3 or OSX and 2 or 1
for f, plat_keys in pairs(bindings) do
@@ -517,16 +498,14 @@ end
if CURSES then
keys['ctrl+meta+v'] = {
- n = m('View/Next View'), p = m('View/Previous View'),
- s = m('View/Split View Horizontal'), h = m('View/Split View Horizontal'),
- v = m('View/Split View Vertical'), w = m('View/Unsplit View'),
- W = m('View/Unsplit All Views'), ['+'] = m('View/Grow View'),
+ n = m('View/Next View'), p = m('View/Previous View'), s = m('View/Split View Horizontal'),
+ h = m('View/Split View Horizontal'), v = m('View/Split View Vertical'),
+ w = m('View/Unsplit View'), W = m('View/Unsplit All Views'), ['+'] = m('View/Grow View'),
['='] = m('View/Grow View'), ['-'] = m('View/Shrink View')
}
end
--- GTK-OSX reports Fn-key as a single keycode which confuses Scintilla. Do
--- not propagate it.
+-- GTK-OSX reports Fn-key as a single keycode which confuses Scintilla. Do not propagate it.
if OSX then keys.fn = function() return true end end
return M
diff --git a/modules/textadept/macros.lua b/modules/textadept/macros.lua
index 90729335..9df07421 100644
--- a/modules/textadept/macros.lua
+++ b/modules/textadept/macros.lua
@@ -4,34 +4,30 @@
---
-- A module for recording, playing, saving, and loading keyboard macros.
-- Menu commands are also recorded.
--- At this time, typing into multiple cursors during macro playback is not
--- supported.
+-- At this time, typing into multiple cursors during macro playback is not supported.
module('textadept.macros')]]
local M = {}
local recording, macro
--- List of commands bound to keys to ignore during macro recording, as the
--- command(s) ultimately executed will be recorded in some form.
+-- List of commands bound to keys to ignore during macro recording, as the command(s) ultimately
+-- executed will be recorded in some form.
local ignore
events.connect(events.INITIALIZED, function()
local m_tools = textadept.menu.menubar[_L['Tools']]
ignore = {
textadept.menu.menubar[_L['Search']][_L['Find']][2],
textadept.menu.menubar[_L['Search']][_L['Find Incremental']][2],
- m_tools[_L['Select Command']][2],
- m_tools[_L['Macros']][_L['Start/Stop Recording']][2]
+ m_tools[_L['Select Command']][2], m_tools[_L['Macros']][_L['Start/Stop Recording']][2]
}
end)
-- Event handlers for recording macro-able events.
-local function event_recorder(event)
- return function(...) macro[#macro + 1] = {event, ...} end
-end
+local function event_recorder(event) return function(...) macro[#macro + 1] = {event, ...} end end
local event_recorders = {
[events.KEYPRESS] = function(code, shift, control, alt, cmd)
- -- Not every keypress should be recorded (e.g. toggling macro recording).
- -- Use very basic key handling to try to identify key bindings to ignore.
+ -- Not every keypress should be recorded (e.g. toggling macro recording). Use very basic
+ -- key handling to try to identify key bindings to ignore.
local key = code < 256 and string.char(code) or keys.KEYSYMS[code]
if key then
if shift and code >= 32 and code < 256 then shift = false end
@@ -40,11 +36,11 @@ local event_recorders = {
for i = 1, #ignore do if keys[key_seq] == ignore[i] then return end end
end
macro[#macro + 1] = {events.KEYPRESS, code, shift, control, alt, cmd}
- end,
+ end, -- LuaFormatter
[events.MENU_CLICKED] = event_recorder(events.MENU_CLICKED),
[events.CHAR_ADDED] = event_recorder(events.CHAR_ADDED),
- [events.FIND] = event_recorder(events.FIND),
- [events.REPLACE] = event_recorder(events.REPLACE),
+ [events.FIND] = event_recorder(events.FIND), -- LuaFormatter
+ [events.REPLACE] = event_recorder(events.REPLACE), -- LuaFormatter
[events.UPDATE_UI] = function()
if #keys.keychain == 0 then ui.statusbar_text = _L['Macro recording'] end
end
@@ -71,9 +67,9 @@ end
-- @name play
function M.play()
if recording or not macro then return end
- -- If this function is run as a key command, `keys.keychain` cannot be cleared
- -- until this function returns. Emit 'esc' to forcibly clear it so subsequent
- -- keypress events can be properly handled.
+ -- If this function is run as a key command, `keys.keychain` cannot be cleared until this
+ -- function returns. Emit 'esc' to forcibly clear it so subsequent keypress events can be
+ -- properly handled.
events.emit(events.KEYPRESS, not CURSES and 0xFF1B or 7) -- 'esc'
for _, event in ipairs(macro) do
if event[1] == events.CHAR_ADDED then
@@ -86,8 +82,8 @@ end
---
-- Saves a recorded macro to file *filename* or the user-selected file.
--- @param filename Optional filename to save the recorded macro to. If `nil`,
--- the user is prompted for one.
+-- @param filename Optional filename to save the recorded macro to. If `nil`, the user is
+-- prompted for one.
-- @name save
function M.save(filename)
if recording or not macro then return end
@@ -102,8 +98,7 @@ function M.save(filename)
for _, event in ipairs(macro) do
f:write(string.format('{%q,', event[1]))
for i = 2, #event do
- f:write(string.format(
- type(event[i]) == 'string' and '%q,' or '%s,', event[i]))
+ f:write(string.format(type(event[i]) == 'string' and '%q,' or '%s,', event[i]))
end
f:write('},\n')
end
@@ -112,8 +107,7 @@ end
---
-- Loads a macro from file *filename* or the user-selected file.
--- @param filename Optional macro file to load. If `nil`, the user is prompted
--- for one.
+-- @param filename Optional macro file to load. If `nil`, the user is prompted for one.
-- @name load
function M.load(filename)
if recording then return end
diff --git a/modules/textadept/menu.lua b/modules/textadept/menu.lua
index cd56cf73..54195bd9 100644
--- a/modules/textadept/menu.lua
+++ b/modules/textadept/menu.lua
@@ -6,19 +6,20 @@ local M = {}
--[[ This comment is for LuaDoc.
---
-- Defines the menus used by Textadept.
--- Menus are simply tables of menu items and submenus and may be edited in
--- place. A menu item itself is a table whose first element is a menu label and
--- whose second element is a menu command to run. Submenus have `title` keys
--- assigned to string text.
+-- Menus are simply tables of menu items and submenus and may be edited in place. A menu item
+-- itself is a table whose first element is a menu label and whose second element is a menu
+-- command to run. Submenus have `title` keys assigned to string text.
module('textadept.menu')]]
local _L, SEPARATOR = _L, {''}
--- The following buffer and view functions need to be made constant in order for
--- menu items to identify the key associated with the functions.
+-- LuaFormatter off
+-- The following buffer and view functions need to be made constant in order for menu items to
+-- identify the key associated with the functions.
local menu_buffer_functions = {'undo','redo','cut','copy','paste','line_duplicate','clear','select_all','upper_case','lower_case','move_selected_lines_up','move_selected_lines_down'}
for _, f in ipairs(menu_buffer_functions) do buffer[f] = buffer[f] end
view.zoom_in, view.zoom_out = view.zoom_in, view.zoom_out
+-- LuaFormatter on
-- Commonly used functions in menu commands.
local sel_enc = textadept.editing.select_enclosed
@@ -41,10 +42,11 @@ local function open_page(url)
os.spawn(string.format('%s "%s"', cmd, not OSX and url or 'file://' .. url))
end
+-- LuaFormatter off
---
-- The default main menubar.
--- Individual menus, submenus, and menu items can be retrieved by name in
--- addition to table index number.
+-- Individual menus, submenus, and menu items can be retrieved by name in addition to table
+-- index number.
-- @class table
-- @name menubar
-- @usage textadept.menu.menubar[_L['File']][_L['New']]
@@ -89,9 +91,7 @@ local default_menubar = {
local match_pos = buffer:brace_match(buffer.current_pos, 0)
if match_pos ~= -1 then buffer:goto_pos(match_pos) end
end},
- {_L['Complete Word'], function()
- textadept.editing.autocomplete('word')
- end},
+ {_L['Complete Word'], function() textadept.editing.autocomplete('word') end},
{_L['Toggle Block Comment'], textadept.editing.toggle_comment},
{_L['Transpose Characters'], textadept.editing.transpose_chars},
{_L['Join Lines'], textadept.editing.join_lines},
@@ -156,9 +156,7 @@ local default_menubar = {
SEPARATOR,
{_L['Find in Files'], function() ui.find.focus{in_files = true} end},
{_L['Goto Next File Found'], function() ui.find.goto_file_found(true) end},
- {_L['Goto Previous File Found'], function()
- ui.find.goto_file_found(false)
- end},
+ {_L['Goto Previous File Found'], function() ui.find.goto_file_found(false) end},
SEPARATOR,
{_L['Jump to'], textadept.editing.goto_line}
},
@@ -181,9 +179,7 @@ local default_menubar = {
{_L['Toggle Bookmark'], textadept.bookmarks.toggle},
{_L['Clear Bookmarks'], textadept.bookmarks.clear},
{_L['Next Bookmark'], function() textadept.bookmarks.goto_mark(true) end},
- {_L['Previous Bookmark'], function()
- textadept.bookmarks.goto_mark(false)
- end},
+ {_L['Previous Bookmark'], function() textadept.bookmarks.goto_mark(false) end},
{_L['Goto Bookmark...'], textadept.bookmarks.goto_mark},
},
{
@@ -199,8 +195,7 @@ local default_menubar = {
{_L['Quickly Open User Home'], function() io.quick_open(_USERHOME) end},
{_L['Quickly Open Textadept Home'], function() io.quick_open(_HOME) end},
{_L['Quickly Open Current Directory'], function()
- if not buffer.filename then return end
- io.quick_open(buffer.filename:match('^(.+)[/\\]'))
+ if buffer.filename then io.quick_open(buffer.filename:match('^(.+)[/\\]')) end
end},
{_L['Quickly Open Current Project'], io.quick_open},
},
@@ -211,25 +206,18 @@ local default_menubar = {
{_L['Previous Snippet Placeholder'], textadept.snippets.previous},
{_L['Cancel Snippet'], textadept.snippets.cancel_current},
SEPARATOR,
- {_L['Complete Trigger Word'], function()
- textadept.editing.autocomplete('snippets')
- end}
+ {_L['Complete Trigger Word'], function() textadept.editing.autocomplete('snippets') end}
},
SEPARATOR,
- {_L['Complete Symbol'], function()
- textadept.editing.autocomplete(buffer:get_lexer(true))
- end},
+ {_L['Complete Symbol'], function() textadept.editing.autocomplete(buffer:get_lexer(true)) end},
{_L['Show Documentation'], textadept.editing.show_documentation},
{_L['Show Style'], function()
- local char = buffer:text_range(
- buffer.current_pos, buffer:position_after(buffer.current_pos))
+ local char = buffer:text_range(buffer.current_pos, buffer:position_after(buffer.current_pos))
if char == '' then return end -- end of buffer
local bytes = string.rep(' 0x%X', #char):format(char:byte(1, #char))
local style = buffer.style_at[buffer.current_pos]
- local text = string.format(
- "'%s' (U+%04X:%s)\n%s %s\n%s %s (%d)", char, utf8.codepoint(char),
- bytes, _L['Lexer'], buffer:get_lexer(true), _L['Style'],
- buffer:name_of_style(style), style)
+ local text = string.format("'%s' (U+%04X:%s)\n%s %s\n%s %s (%d)", char, utf8.codepoint(char),
+ bytes, _L['Lexer'], buffer:get_lexer(true), _L['Style'], buffer:name_of_style(style), style)
view:call_tip_show(buffer.current_pos, text)
end}
},
@@ -299,12 +287,11 @@ local default_menubar = {
end},
SEPARATOR,
{_L['Toggle Show Indent Guides'], function()
- view.indentation_guides =
- view.indentation_guides == 0 and view.IV_LOOKBOTH or 0
+ view.indentation_guides = view.indentation_guides == 0 and view.IV_LOOKBOTH or 0
end},
{_L['Toggle Virtual Space'], function()
- buffer.virtual_space_options =
- buffer.virtual_space_options == 0 and buffer.VS_USERACCESSIBLE or 0
+ buffer.virtual_space_options = buffer.virtual_space_options == 0 and
+ buffer.VS_USERACCESSIBLE or 0
end},
SEPARATOR,
{_L['Zoom In'], view.zoom_in},
@@ -327,8 +314,7 @@ local default_menubar = {
---
-- The default right-click context menu.
--- Submenus, and menu items can be retrieved by name in addition to table index
--- number.
+-- Submenus, and menu items can be retrieved by name in addition to table index number.
-- @class table
-- @name context_menu
-- @usage textadept.menu.context_menu[#textadept.menu.context_menu + 1] = {...}
@@ -346,8 +332,7 @@ local default_context_menu = {
---
-- The default tabbar context menu.
--- Submenus, and menu items can be retrieved by name in addition to table index
--- number.
+-- Submenus, and menu items can be retrieved by name in addition to table index number.
-- @class table
-- @name tab_context_menu
local default_tab_context_menu = {
@@ -358,6 +343,7 @@ local default_tab_context_menu = {
SEPARATOR,
{_L['Reload'], buffer.reload},
}
+-- LuaFormatter on
-- Table of proxy tables for menus.
local proxies = {}
@@ -378,7 +364,10 @@ local function get_gdk_key(key_seq)
local code = string.byte(key)
if #key > 1 or code < 32 then
for i, s in pairs(keys.KEYSYMS) do
- if s == key and i > 0xFE20 then code = i break end
+ if s == key and i > 0xFE20 then
+ code = i
+ break
+ end
end
end
return code, modifiers
@@ -387,8 +376,8 @@ end
-- Creates a menu suitable for `ui.menu()` from the menu table format.
-- Also assigns key bindings.
-- @param menu The menu to create a GTK menu from.
--- @param contextmenu Flag indicating whether or not the menu is a context menu.
--- If so, menu_id offset is 1000. The default value is `false`.
+-- @param contextmenu Flag indicating whether or not the menu is a context menu. If so, menu_id
+-- offset is 1000. The default value is `false`.
-- @return GTK menu that can be passed to `ui.menu()`.
-- @see ui.menu
local function read_menu_table(menu, contextmenu)
@@ -397,8 +386,7 @@ local function read_menu_table(menu, contextmenu)
if item.title then
gtkmenu[#gtkmenu + 1] = read_menu_table(item, contextmenu)
else -- item = {label, function}
- local menu_id =
- not contextmenu and #menu_items + 1 or #contextmenu_items + 1000 + 1
+ local menu_id = not contextmenu and #menu_items + 1 or #contextmenu_items + 1000 + 1
local key, mods = get_gdk_key(key_shortcuts[tostring(item[2])])
gtkmenu[#gtkmenu + 1] = {item[1], menu_id, key, mods}
if item[2] then
@@ -410,13 +398,12 @@ local function read_menu_table(menu, contextmenu)
return gtkmenu
end
--- Returns a proxy table for menu table *menu* such that when a menu item is
--- changed or added, *update* is called to update the menu in the UI.
+-- Returns a proxy table for menu table *menu* such that when a menu item is changed or added,
+-- *update* is called to update the menu in the UI.
-- @param menu The menu or table of menus to create a proxy for.
--- @param update The function to call to update the menu in the UI when a menu
--- item is changed or added.
--- @param menubar Used internally to keep track of the top-level menu for
--- calling *update* with.
+-- @param update The function to call to update the menu in the UI when a menu item is changed
+-- or added.
+-- @param menubar Used internally to keep track of the top-level menu for calling *update* with.
local function proxy_menu(menu, update, menubar)
return setmetatable({}, {
__index = function(_, k)
@@ -425,60 +412,59 @@ local function proxy_menu(menu, update, menubar)
v = menu[k]
elseif type(k) == 'string' then
for _, item in ipairs(menu) do
- if item.title == k or item[1] == k then v = item break end
+ if item.title == k or item[1] == k then
+ v = item
+ break
+ end
end
end
return type(v) == 'table' and proxy_menu(v, update, menubar or menu) or v
- end,
+ end, -- LuaFormatter
__newindex = function(_, k, v)
menu[k] = getmetatable(v) and getmetatable(v).menu or v
- -- After adding or removing menus or menu items, update the menubar or
- -- context menu. When updating a menu item's function, do nothing extra.
+ -- After adding or removing menus or menu items, update the menubar or context menu. When
+ -- updating a menu item's function, do nothing extra.
if type(v) ~= 'function' then update(menubar or menu) end
- end,
- __len = function() return #menu end,
- menu = menu -- store existing menu for copying (e.g. m[#m + 1] = m[#m])
+ end, __len = function() return #menu end, menu = menu -- store existing menu for copying (e.g. m[#m + 1] = m[#m])
})
end
-- Sets `ui.menubar` from menu table *menubar*.
--- Each menu is an ordered list of menu items and has a `title` key for the
--- title text. Menu items are tables containing menu text and either a function
--- to call or a table containing a function with its parameters to call when an
--- item is clicked. Menu items may also be sub-menus, ordered lists of menu
--- items with an additional `title` key for the sub-menu's title text.
--- @param menubar The table of menu tables to create the menubar from. If `nil`,
--- clears the menubar from view, but keeps it intact in order for
--- `M.select_command()` to function properly.
+-- Each menu is an ordered list of menu items and has a `title` key for the title text. Menu
+-- items are tables containing menu text and either a function to call or a table containing a
+-- function with its parameters to call when an item is clicked. Menu items may also be sub-menus,
+-- ordered lists of menu items with an additional `title` key for the sub-menu's title text.
+-- @param menubar The table of menu tables to create the menubar from. If `nil`, clears the
+-- menubar from view, but keeps it intact in order for `M.select_command()` to function properly.
-- @see ui.menubar
-- @see ui.menu
local function set_menubar(menubar)
- if not menubar then ui.menubar = {} return end
+ if not menubar then
+ ui.menubar = {}
+ return
+ end
key_shortcuts, menu_items = {}, {} -- reset
for key, f in pairs(keys) do key_shortcuts[tostring(f)] = key end
local _menubar = {}
- for _, menu in ipairs(menubar) do
- _menubar[#_menubar + 1] = ui.menu(read_menu_table(menu))
- end
+ for _, menu in ipairs(menubar) do _menubar[#_menubar + 1] = ui.menu(read_menu_table(menu)) end
ui.menubar = _menubar
proxies.menubar = proxy_menu(menubar, set_menubar)
end
events.connect(events.INITIALIZED, function() set_menubar(default_menubar) end)
-- Define menu proxy for use by keys.lua and user scripts.
--- Do not use an update function because this is expensive at startup, and
--- `events.INITIALIZED` will create the first visible menubar and proper proxy.
+-- Do not use an update function because this is expensive at startup, and `events.INITIALIZED`
+-- will create the first visible menubar and proper proxy.
proxies.menubar = proxy_menu(default_menubar, function() end)
--- Sets `ui.context_menu` and `ui.tab_context_menu` from menu item lists
--- *buffer_menu* and *tab_menu*, respectively.
--- Menu items are tables containing menu text and either a function to call or
--- a table containing a function with its parameters to call when an item is
--- clicked. Menu items may also be sub-menus, ordered lists of menu items with
--- an additional `title` key for the sub-menu's title text.
--- @param buffer_menu Optional menu table to create the buffer context menu
--- from. If `nil`, uses the default context menu.
--- @param tab_menu Optional menu table to create the tabbar context menu from.
--- If `nil`, uses the default tab context menu.
+-- Sets `ui.context_menu` and `ui.tab_context_menu` from menu item lists *buffer_menu* and
+-- *tab_menu*, respectively.
+-- Menu items are tables containing menu text and either a function to call or a table containing a
+-- function with its parameters to call when an item is clicked. Menu items may also be sub-menus,
+-- ordered lists of menu items with an additional `title` key for the sub-menu's title text.
+-- @param buffer_menu Optional menu table to create the buffer context menu from. If `nil`,
+-- uses the default context menu.
+-- @param tab_menu Optional menu table to create the tabbar context menu from. If `nil`, uses
+-- the default tab context menu.
-- @see ui.context_menu
-- @see ui.tab_context_menu
-- @see ui.menu
@@ -497,9 +483,8 @@ local function set_contextmenus(buffer_menu, tab_menu)
end
events.connect(events.INITIALIZED, set_contextmenus)
-- Define menu proxies for use by user scripts.
--- Do not use an update function because this is expensive at startup, and
--- `events.INITIALIZED` will create these visible menus and their proper
--- proxies.
+-- Do not use an update function because this is expensive at startup, and `events.INITIALIZED`
+-- will create these visible menus and their proper proxies.
proxies.context_menu = proxy_menu(default_context_menu, function() end)
proxies.tab_context_menu = proxy_menu(default_tab_context_menu, function() end)
@@ -522,8 +507,7 @@ function M.select_command()
if item.title then
build_command_tables(item)
elseif item[1] ~= '' then -- item = {label, function}
- local label =
- menu.title and string.format('%s: %s', menu.title, item[1]) or item[1]
+ local label = menu.title and string.format('%s: %s', menu.title, item[1]) or item[1]
items[#items + 1] = label:gsub('_([^_])', '%1')
items[#items + 1] = key_shortcuts[tostring(item[2])] or ''
end
@@ -531,15 +515,13 @@ function M.select_command()
end
build_command_tables(getmetatable(M.menubar).menu)
local button, i = ui.dialogs.filteredlist{
- title = _L['Run Command'], columns = {_L['Command'], _L['Key Binding']},
- items = items
+ title = _L['Run Command'], columns = {_L['Command'], _L['Key Binding']}, items = items
}
if button == 1 and i then events.emit(events.MENU_CLICKED, i) end
end
return setmetatable(M, {
- __index = function(_, k) return proxies[k] or rawget(M, k) end,
- __newindex = function(_, k, v)
+ __index = function(_, k) return proxies[k] or rawget(M, k) end, __newindex = function(_, k, v)
if k == 'menubar' then
set_menubar(v)
elseif k == 'context_menu' then
diff --git a/modules/textadept/run.lua b/modules/textadept/run.lua
index 3e0b4295..d39e7919 100644
--- a/modules/textadept/run.lua
+++ b/modules/textadept/run.lua
@@ -5,14 +5,12 @@ local M = {}
--[[ This comment is for LuaDoc.
---
-- Compile and run source code files with Textadept.
--- [Language modules](#compile-and-run) may tweak the `compile_commands`,
--- `run_commands`, and `error_patterns` tables for particular languages.
--- The user may tweak `build_commands` and `test_commands` for particular
--- projects.
+-- [Language modules](#compile-and-run) may tweak the `compile_commands`, `run_commands`, and
+-- `error_patterns` tables for particular languages.
+-- The user may tweak `build_commands` and `test_commands` for particular projects.
-- @field run_in_background (bool)
-- Run shell commands silently in the background.
--- This only applies when the message buffer is open, though it does not have
--- to be visible.
+-- This only applies when the message buffer is open, though it does not have to be visible.
-- The default value is `false`.
-- @field MARK_WARNING (number)
-- The run or compile warning marker number.
@@ -20,34 +18,32 @@ local M = {}
-- The run or compile error marker number.
-- @field _G.events.COMPILE_OUTPUT (string)
-- Emitted when executing a language's compile shell command.
--- By default, compiler output is printed to the message buffer. In order to
--- override this behavior, connect to the event with an index of `1` and
--- return `true`.
+-- By default, compiler output is printed to the message buffer. In order to override this
+-- behavior, connect to the event with an index of `1` and return `true`.
-- Arguments:
--
-- * `output`: A line of string output from the command.
--- * `ext_or_lexer`: The file extension or lexer name associated with the
--- executed compile command.
+-- * `ext_or_lexer`: The file extension or lexer name associated with the executed compile
+-- command.
-- @field _G.events.RUN_OUTPUT (string)
-- Emitted when executing a language's run shell command.
--- By default, output is printed to the message buffer. In order to override
--- this behavior, connect to the event with an index of `1` and return `true`.
+-- By default, output is printed to the message buffer. In order to override this behavior,
+-- connect to the event with an index of `1` and return `true`.
-- Arguments:
--
-- * `output`: A line of string output from the command.
--- * `ext_or_lexer`: The file extension or lexer name associated with the
--- executed run command.
+-- * `ext_or_lexer`: The file extension or lexer name associated with the executed run command.
-- @field _G.events.BUILD_OUTPUT (string)
-- Emitted when executing a project's build shell command.
--- By default, output is printed to the message buffer. In order to override
--- this behavior, connect to the event with an index of `1` and return `true`.
+-- By default, output is printed to the message buffer. In order to override this behavior,
+-- connect to the event with an index of `1` and return `true`.
-- Arguments:
--
-- * `output`: A line of string output from the command.
-- @field _G.events.TEST_OUTPUT (string)
-- Emitted when executing a project's shell command for running tests.
--- By default, output is printed to the message buffer. In order to override
--- this behavior, connect to the event with an index of `1` and return `true`.
+-- By default, output is printed to the message buffer. In order to override this behavior,
+-- connect to the event with an index of `1` and return `true`.
-- Arguments:
--
-- * `output`: A line of string output from the command.
@@ -59,26 +55,23 @@ M.MARK_WARNING = _SCINTILLA.next_marker_number()
M.MARK_ERROR = _SCINTILLA.next_marker_number()
-- Events.
-local run_events = {
- 'compile_output', 'run_output', 'build_output', 'test_output'
-}
+local run_events = {'compile_output', 'run_output', 'build_output', 'test_output'}
for _, v in ipairs(run_events) do events[v:upper()] = v end
--- Keep track of: the last process spawned in order to kill it if requested; the
--- cwd of that process in order to jump to relative file paths in recognized
--- warning or error messages; and the view the process was spawned from in order
--- to jump to messages (which are displayed in a split view) in the original
--- view.
+-- Keep track of: the last process spawned in order to kill it if requested; the cwd of that
+-- process in order to jump to relative file paths in recognized warning or error messages;
+-- and the view the process was spawned from in order to jump to messages (which are displayed
+-- in a split view) in the original view.
local proc, cwd, preferred_view
--- Scans the given message for a warning or error message and, if one is found,
--- returns table of the warning/error's details.
--- @param message The message to parse for warnings or errors. The message
--- is assumed to be encoded in _CHARSET.
--- @param ext_or_lexer Optional file extension or lexer name associated with the
--- shell command that produced the warning/error.
--- @return error details table with 'filename', 'line', 'column', and 'message'
--- fields along with a 'warning' flag.
+-- Scans the given message for a warning or error message and, if one is found, returns table
+-- of the warning/error's details.
+-- @param message The message to parse for warnings or errors. The message is assumed to be
+-- encoded in _CHARSET.
+-- @param ext_or_lexer Optional file extension or lexer name associated with the shell command
+-- that produced the warning/error.
+-- @return error details table with 'filename', 'line', 'column', and 'message' fields along
+-- with a 'warning' flag.
-- @see error_patterns
local function scan_for_error(message, ext_or_lexer)
for key, patterns in pairs(M.error_patterns) do
@@ -99,15 +92,13 @@ local function scan_for_error(message, ext_or_lexer)
i = i + 1
end
local lower_message = message:lower()
- detail.warning =
- (lower_message:find('warning') or lower_message:find('note')) and
+ detail.warning = (lower_message:find('warning') or lower_message:find('note')) and
not lower_message:find('error')
- -- Compile and run commands specify the file extension or lexer name used
- -- to determine the command, so the error patterns used are guaranteed to
- -- be correct. Build and test commands have no such context and instead
- -- iterate through all possible error patterns. Only consider the
- -- error/warning valid if the extracted filename's extension or lexer name
- -- matches the error pattern's extension or lexer name.
+ -- Compile and run commands specify the file extension or lexer name used to determine
+ -- the command, so the error patterns used are guaranteed to be correct. Build and
+ -- test commands have no such context and instead iterate through all possible error
+ -- patterns. Only consider the error/warning valid if the extracted filename's extension
+ -- or lexer name matches the error pattern's extension or lexer name.
if ext_or_lexer then return detail end
local ext = detail.filename:match('[^/\\.]+$')
local lexer_name = textadept.file_types.extensions[ext]
@@ -120,33 +111,30 @@ local function scan_for_error(message, ext_or_lexer)
end
-- Prints an output line from a compile, run, build, or test shell command.
--- Assume output is UTF-8 unless there's a recognized warning or error message.
--- In that case assume it is encoded in _CHARSET and mark it.
+-- Assume output is UTF-8 unless there's a recognized warning or error message. In that case
+-- assume it is encoded in _CHARSET and mark it.
-- All stdout and stderr from the command is printed silently.
-- @param line The output line to print.
--- @param ext_or_lexer Optional file extension or lexer name associated with the
--- executed command. This is used for better error detection in compile and
--- run commands.
+-- @param ext_or_lexer Optional file extension or lexer name associated with the executed command.
+-- This is used for better error detection in compile and run commands.
local function print_line(line, ext_or_lexer)
local error = scan_for_error(line, ext_or_lexer)
- ui.silent_print = M.run_in_background or ext_or_lexer or
- not line:find('^> ') or line:find('^> exit')
+ ui.silent_print = M.run_in_background or ext_or_lexer or not line:find('^> ') or
+ line:find('^> exit')
ui.print(not error and line or line:iconv('UTF-8', _CHARSET))
ui.silent_print = false
if error then
-- Current position is one line below the error due to ui.print()'s '\n'.
- buffer:marker_add(
- buffer.line_count - 1, error.warning and M.MARK_WARNING or M.MARK_ERROR)
+ buffer:marker_add(buffer.line_count - 1, error.warning and M.MARK_WARNING or M.MARK_ERROR)
end
end
local output_buffer
--- Prints the output from a compile, run, build, or test shell command as a
--- series of lines, performing buffering as needed.
+-- Prints the output from a compile, run, build, or test shell command as a series of lines,
+-- performing buffering as needed.
-- @param output The output to print, or `nil` to flush any buffered output.
--- @param ext_or_lexer Optional file extension or lexer name associated with the
--- executed command. This is used for better error detection in compile and
--- run commands.
+-- @param ext_or_lexer Optional file extension or lexer name associated with the executed command.
+-- This is used for better error detection in compile and run commands.
local function print_output(output, ext_or_lexer)
if output then
if output_buffer then output = output_buffer .. output end
@@ -162,17 +150,15 @@ local function print_output(output, ext_or_lexer)
end
end
--- Runs command *command* in working directory *dir*, emitting events of type
--- *event* with any output received.
--- @param command String command to run, or a function returning such a string
--- and optional working directory and environment table. A returned working
--- directory overrides *dir*.
+-- Runs command *command* in working directory *dir*, emitting events of type *event* with any
+-- output received.
+-- @param command String command to run, or a function returning such a string and optional
+-- working directory and environment table. A returned working directory overrides *dir*.
-- @param dir String working directory to run *command* in.
-- @param event String event name to emit command output with.
-- @param macros Optional table of '%[char]' macros to expand within *command*.
--- @param ext_or_lexer Optional file extension or lexer name associated with the
--- executed command. This is used for better error detection in compile and
--- run commands.
+-- @param ext_or_lexer Optional file extension or lexer name associated with the executed command.
+-- This is used for better error detection in compile and run commands.
local function run_command(command, dir, event, macros, ext_or_lexer)
local working_dir, env
if type(command) == 'function' then command, working_dir, env = command() end
@@ -183,10 +169,12 @@ local function run_command(command, dir, event, macros, ext_or_lexer)
cwd = (working_dir or dir):gsub('[/\\]$', '')
events.emit(event, string.format('> cd %s\n', cwd))
events.emit(event, string.format('> %s\n', command:iconv('UTF-8', _CHARSET)))
- local args = {command, cwd, emit, emit, function(status)
- emit() -- flush
- events.emit(event, string.format('> exit status: %d\n', status))
- end}
+ local args = {
+ command, cwd, emit, emit, function(status)
+ emit() -- flush
+ events.emit(event, string.format('> exit status: %d\n', status))
+ end
+ }
if env then table.insert(args, 3, env) end
proc = assert(os.spawn(table.unpack(args)))
end
@@ -204,21 +192,18 @@ local function compile_or_run(filename, commands)
textadept.file_types.extensions[ext]
local command = commands[filename] or commands[ext] or commands[lang]
local dirname, basename = '', filename
- if filename:find('[/\\]') then
- dirname, basename = filename:match('^(.+)[/\\]([^/\\]+)$')
- end
- local event = commands == M.compile_commands and events.COMPILE_OUTPUT or
- events.RUN_OUTPUT
+ if filename:find('[/\\]') then dirname, basename = filename:match('^(.+)[/\\]([^/\\]+)$') end
+ local event = commands == M.compile_commands and events.COMPILE_OUTPUT or events.RUN_OUTPUT
local macros = {
- ['%p'] = filename, ['%d'] = dirname, ['%f'] = basename,
- ['%e'] = basename:match('^(.+)%.') -- no extension
+ ['%p'] = filename, ['%d'] = dirname, ['%f'] = basename, ['%e'] = basename:match('^(.+)%.') -- no extension
}
run_command(command, dirname, event, macros, commands[ext] and ext or lang)
end
+-- LuaFormatter off
---
--- Map of filenames, file extensions, and lexer names to their associated
--- "compile" shell command line strings or functions that return such strings.
+-- Map of filenames, file extensions, and lexer names to their associated "compile" shell
+-- command line strings or functions that return such strings.
-- Command line strings may have the following macros:
--
-- + `%f`: The file's name, including its extension.
@@ -226,21 +211,21 @@ end
-- + `%d`: The file's directory path.
-- + `%p`: The file's full path.
--
--- Functions may also return a working directory and process environment table
--- to operate in. By default, the working directory is the current file's parent
--- directory and the environment is Textadept's environment.
+-- Functions may also return a working directory and process environment table to operate in. By
+-- default, the working directory is the current file's parent directory and the environment
+-- is Textadept's environment.
-- @class table
-- @name compile_commands
M.compile_commands = {actionscript='mxmlc "%f"',ada='gnatmake "%f"',ansi_c='gcc -o "%e" "%f"',antlr='antlr4 "%f"',g='antlr3 "%f"',applescript='osacompile "%f" -o "%e.scpt"',asm='nasm "%f"'--[[ && ld "%e.o" -o "%e"']],boo='booc "%f"',caml='ocamlc -o "%e" "%f"',csharp=WIN32 and 'csc "%f"' or 'mcs "%f"',coffeescript='coffee -c "%f"',context='context --nonstopmode "%f"',cpp='g++ -o "%e" "%f"',cuda=WIN32 and 'nvcc -o "%e.exe" "%f"' or 'nvcc -o "%e" "%f"',dmd='dmd "%f"',dot='dot -Tps "%f" -o "%e.ps"',eiffel='se c "%f"',elixir='elixirc "%f"',erlang='erl -compile "%e"',faust='faust -o "%e.cpp" "%f"',fsharp=WIN32 and 'fsc.exe "%f"' or 'mono fsc.exe "%f"',fortran='gfortran -o "%e" "%f"',gap='gac -o "%e" "%f"',go='go build "%f"',groovy='groovyc "%f"',haskell=WIN32 and 'ghc -o "%e.exe" "%f"' or 'ghc -o "%e" "%f"',inform=function() return 'inform -c "'..buffer.filename:match('^(.+%.inform[/\\])Source')..'"' end,java='javac "%f"',ltx='pdflatex -file-line-error -halt-on-error "%f"',less='lessc --no-color "%f" "%e.css"',lilypond='lilypond "%f"',lisp='clisp -c "%f"',litcoffee='coffee -c "%f"',lua='luac -o "%e.luac" "%f"',moon='moonc "%f"',markdown='markdown "%f" > "%e.html"',myr='mbld -b "%e" "%f"',nemerle='ncc "%f" -out:"%e.exe"',nim='nim c "%f"',nsis='MakeNSIS "%f"',objective_c='gcc -o "%e" "%f"',pascal='fpc "%f"',perl='perl -c "%f"',php='php -l "%f"',pony='ponyc "%f"',prolog='gplc --no-top-level "%f"',python='python -m py_compile "%f"',ruby='ruby -c "%f"',rust='rustc "%f"',sass='sass "%f" "%e.css"',scala='scalac "%f"',sml='mlton "%f"',tex='pdflatex -file-line-error -halt-on-error "%f"',typescript='tsc "%f"',vala='valac "%f"',vb=WIN32 and 'vbc "%f"' or 'vbnc "%f"',zig='zig build-exe "%f"'}
+-- LuaFormatter on
---
--- Compiles file *filename* or the current file using an appropriate shell
--- command from the `compile_commands` table.
--- The shell command is determined from the file's filename, extension, or
--- language in that order.
+-- Compiles file *filename* or the current file using an appropriate shell command from the
+-- `compile_commands` table.
+-- The shell command is determined from the file's filename, extension, or language in that order.
-- Emits `COMPILE_OUTPUT` events.
--- @param filename Optional path to the file to compile. The default value is
--- the current file's filename.
+-- @param filename Optional path to the file to compile. The default value is the current
+-- file's filename.
-- @see compile_commands
-- @see _G.events
-- @name compile
@@ -251,9 +236,10 @@ function M.compile(filename)
end
events.connect(events.COMPILE_OUTPUT, print_output)
+-- LuaFormatter off
---
--- Map of filenames, file extensions, and lexer names to their associated "run"
--- shell command line strings or functions that return strings.
+-- Map of filenames, file extensions, and lexer names to their associated "run" shell command
+-- line strings or functions that return strings.
-- Command line strings may have the following macros:
--
-- + `%f`: The file's name, including its extension.
@@ -261,21 +247,21 @@ events.connect(events.COMPILE_OUTPUT, print_output)
-- + `%d`: The file's directory path.
-- + `%p`: The file's full path.
--
--- Functions may also return a working directory and process environment table
--- to operate in. By default, the working directory is the current file's parent
--- directory and the environment is Textadept's environment.
+-- Functions may also return a working directory and process environment table to operate in. By
+-- default, the working directory is the current file's parent directory and the environment
+-- is Textadept's environment.
-- @class table
-- @name run_commands
M.run_commands = {actionscript=WIN32 and 'start "" "%e.swf"' or OSX and 'open "file://%e.swf"' or 'xdg-open "%e.swf"',ada=WIN32 and '"%e"' or './"%e"',ansi_c=WIN32 and '"%e"' or './"%e"',applescript='osascript "%f"',asm='./"%e"',awk='awk -f "%f"',batch='"%f"',boo='booi "%f"',caml='ocamlrun "%e"',csharp=WIN32 and '"%e"' or 'mono "%e.exe"',chuck='chuck "%f"',clojure='clj -M "%f"',cmake='cmake -P "%f"',coffeescript='coffee "%f"',context=WIN32 and 'start "" "%e.pdf"' or OSX and 'open "%e.pdf"' or 'xdg-open "%e.pdf"',cpp=WIN32 and '"%e"' or './"%e"',crystal='crystal "%f"',cuda=WIN32 and '"%e"' or './"%e"',dart='dart "%f"',dmd=WIN32 and '"%e"' or './"%e"',eiffel="./a.out",elixir='elixir "%f"',fsharp=WIN32 and '"%e"' or 'mono "%e.exe"',fantom='fan "%f"',fennel='fennel "%f"',forth='gforth "%f" -e bye',fortran=WIN32 and '"%e"' or './"%e"',gnuplot='gnuplot "%f"',go='go run "%f"',groovy='groovy "%f"',haskell=WIN32 and '"%e"' or './"%e"',html=WIN32 and 'start "" "%f"' or OSX and 'open "file://%f"' or 'xdg-open "%f"',icon='icont "%e" -x',idl='idl -batch "%f"',Io='io "%f"',java='java "%e"',javascript='node "%f"',jq='jq -f "%f"',julia='julia "%f"',ltx=WIN32 and 'start "" "%e.pdf"' or OSX and 'open "%e.pdf"' or 'xdg-open "%e.pdf"',less='lessc --no-color "%f"',lilypond=WIN32 and 'start "" "%e.pdf"' or OSX and 'open "%e.pdf"' or 'xdg-open "%e.pdf"',lisp='clisp "%f"',litcoffee='coffee "%f"',lua='lua -e "io.stdout:setvbuf(\'no\')" "%f"',makefile=WIN32 and 'nmake -f "%f"' or 'make -f "%f"',markdown='markdown "%f"',moon='moon "%f"',myr=WIN32 and '"%e"' or './"%e"',nemerle=WIN32 and '"%e"' or 'mono "%e.exe"',nim='nim c -r "%f"',objective_c=WIN32 and '"%e"' or './"%e"',pascal=WIN32 and '"%e"' or './"%e"',perl='perl "%f"',php='php "%f"',pike='pike "%f"',pkgbuild='makepkg -p "%f"',pony=WIN32 and '"%e"' or './"%e"',prolog=WIN32 and '"%e"' or './"%e"',pure='pure "%f"',python=function() return buffer:get_line(1):find('^#!.-python3') and 'python3 -u "%f"' or 'python -u "%f"' end,rstats=WIN32 and 'Rterm -f "%f"' or 'R -f "%f"',rebol='REBOL "%f"',rexx=WIN32 and 'rexx "%f"' or 'regina "%f"',ruby='ruby "%f"',rust=WIN32 and '"%e"' or './"%e"',sass='sass "%f"',scala='scala "%e"',bash='bash "%f"',csh='tcsh "%f"',ksh='ksh "%f"',mksh='mksh "%f"',sh='sh "%f"',zsh='zsh "%f"',rc='rc "%f"',smalltalk='gst "%f"',sml=WIN32 and '"%e"' or './"%e"',snobol4='snobol4 -b "%f"',tcl='tclsh "%f"',tex=WIN32 and 'start "" "%e.pdf"' or OSX and 'open "%e.pdf"' or 'xdg-open "%e.pdf"',vala=WIN32 and '"%e"' or './"%e"',vb=WIN32 and '"%e"' or 'mono "%e.exe"',xs='xs "%f"',zig=WIN32 and '"%e"' or './"%e"'}
+-- LuaFormatter on
---
--- Runs file *filename* or the current file using an appropriate shell command
--- from the `run_commands` table.
--- The shell command is determined from the file's filename, extension, or
--- language in that order.
+-- Runs file *filename* or the current file using an appropriate shell command from the
+-- `run_commands` table.
+-- The shell command is determined from the file's filename, extension, or language in that order.
-- Emits `RUN_OUTPUT` events.
--- @param filename Optional path to the file to run. The default value is the
--- current file's filename.
+-- @param filename Optional path to the file to run. The default value is the current file's
+-- filename.
-- @see run_commands
-- @see _G.events
-- @name run
@@ -287,15 +273,15 @@ end
events.connect(events.RUN_OUTPUT, print_output)
---
--- Appends the command line argument strings *run* and *compile* to their
--- respective run and compile commands for file *filename* or the current file.
--- If either is `nil`, prompts the user for missing the arguments. Each filename
--- has its own set of compile and run arguments.
+-- Appends the command line argument strings *run* and *compile* to their respective run and
+-- compile commands for file *filename* or the current file.
+-- If either is `nil`, prompts the user for missing the arguments. Each filename has its own
+-- set of compile and run arguments.
-- @param filename Optional path to the file to set run/compile arguments for.
--- @param run Optional string run arguments to set. If `nil`, the user is
--- prompted for them. Pass the empty string for no run arguments.
--- @param compile Optional string compile arguments to set. If `nil`, the user
--- is prompted for them. Pass the empty string for no compile arguments.
+-- @param run Optional string run arguments to set. If `nil`, the user is prompted for them. Pass
+-- the empty string for no run arguments.
+-- @param compile Optional string compile arguments to set. If `nil`, the user is prompted
+-- for them. Pass the empty string for no compile arguments.
-- @see run_commands
-- @see compile_commands
-- @name set_arguments
@@ -308,52 +294,49 @@ function M.set_arguments(filename, run, compile)
assert_type(compile, 'string/nil', 3)
local base_commands, utf8_args = {}, {}
for i, commands in ipairs{M.run_commands, M.compile_commands} do
- -- Compare the base run/compile command with the one for the current
- -- file. The difference is any additional arguments set previously.
- base_commands[i] = commands[filename:match('[^.]+$')] or
- commands[buffer:get_lexer()] or ''
+ -- Compare the base run/compile command with the one for the current file. The difference
+ -- is any additional arguments set previously.
+ base_commands[i] = commands[filename:match('[^.]+$')] or commands[buffer:get_lexer()] or ''
local current_command = commands[filename] or ''
- local args = (i == 1 and run or compile) or
- current_command:sub(#base_commands[i] + 2)
+ local args = (i == 1 and run or compile) or current_command:sub(#base_commands[i] + 2)
utf8_args[i] = args:iconv('UTF-8', _CHARSET)
end
if not run or not compile then
local button
button, utf8_args = ui.dialogs.inputbox{
- title = _L['Set Arguments...']:gsub('_', ''), informative_text = {
- _L['Command line arguments'], _L['For Run:'], _L['For Compile:']
- }, text = utf8_args, width = not CURSES and 400 or nil
+ title = _L['Set Arguments...']:gsub('_', ''),
+ informative_text = {_L['Command line arguments'], _L['For Run:'], _L['For Compile:']},
+ text = utf8_args, width = not CURSES and 400 or nil
}
if button ~= 1 then return end
end
for i, commands in ipairs{M.run_commands, M.compile_commands} do
- -- Add the additional arguments to the base run/compile command and set
- -- the new command to be the one used for the current file.
+ -- Add the additional arguments to the base run/compile command and set the new command to
+ -- be the one used for the current file.
commands[filename] = string.format('%s %s', base_commands[i],
utf8_args[i]:iconv(_CHARSET, 'UTF-8'))
end
end
+-- LuaFormatter off
---
--- Map of project root paths and "makefiles" to their associated "build" shell
--- command line strings or functions that return such strings.
--- Functions may also return a working directory and process environment table
--- to operate in. By default, the working directory is the project's root
--- directory and the environment is Textadept's environment.
+-- Map of project root paths and "makefiles" to their associated "build" shell command line
+-- strings or functions that return such strings.
+-- Functions may also return a working directory and process environment table to operate
+-- in. By default, the working directory is the project's root directory and the environment
+-- is Textadept's environment.
-- @class table
-- @name build_commands
M.build_commands = {--[[Ant]]['build.xml']='ant',--[[Dockerfile]]Dockerfile='docker build .',--[[Make]]Makefile='make',GNUmakefile='make',makefile='make',--[[Meson]]['meson.build']='meson compile',--[[Maven]]['pom.xml']='mvn',--[[Ruby]]Rakefile='rake'}
+-- LuaFormatter on
---
--- Builds the project whose root path is *root_directory* or the current project
--- using the shell command from the `build_commands` table.
--- If a "makefile" type of build file is found, prompts the user for the full
--- build command.
--- The current project is determined by either the buffer's filename or the
--- current working directory.
+-- Builds the project whose root path is *root_directory* or the current project using the
+-- shell command from the `build_commands` table.
+-- If a "makefile" type of build file is found, prompts the user for the full build command. The
+-- current project is determined by either the buffer's filename or the current working directory.
-- Emits `BUILD_OUTPUT` events.
--- @param root_directory The path to the project to build. The default value is
--- the current project.
+-- @param root_directory The path to the project to build. The default value is the current project.
-- @see build_commands
-- @see _G.events
-- @name build
@@ -368,8 +351,8 @@ function M.build(root_directory)
for build_file, build_command in pairs(M.build_commands) do
if lfs.attributes(string.format('%s/%s', root_directory, build_file)) then
local button, utf8_command = ui.dialogs.inputbox{
- title = _L['Command'], informative_text = root_directory,
- text = build_command, button1 = _L['OK'], button2 = _L['Cancel']
+ title = _L['Command'], informative_text = root_directory, text = build_command,
+ button1 = _L['OK'], button2 = _L['Cancel']
}
if button == 1 then command = utf8_command:iconv(_CHARSET, 'UTF-8') end
break
@@ -381,23 +364,23 @@ end
events.connect(events.BUILD_OUTPUT, print_output)
---
--- Map of project root paths to their associated "test" shell command line
--- strings or functions that return such strings.
--- Functions may also return a working directory and process environment table
--- to operate in. By default, the working directory is the project's root
--- directory and the environment is Textadept's environment.
+-- Map of project root paths to their associated "test" shell command line strings or functions
+-- that return such strings.
+-- Functions may also return a working directory and process environment table to operate
+-- in. By default, the working directory is the project's root directory and the environment
+-- is Textadept's environment.
-- @class table
-- @name test_commands
M.test_commands = {}
---
--- Runs tests for the project whose root path is *root_directory* or the current
--- project using the shell command from the `test_commands` table.
--- The current project is determined by either the buffer's filename or the
--- current working directory.
+-- Runs tests for the project whose root path is *root_directory* or the current project using
+-- the shell command from the `test_commands` table.
+-- The current project is determined by either the buffer's filename or the current working
+-- directory.
-- Emits `TEST_OUTPUT` events.
--- @param root_directory The path to the project to run tests for. The default
--- value is the current project.
+-- @param root_directory The path to the project to run tests for. The default value is the
+-- current project.
-- @see test_commands
-- @see _G.events
-- @name test
@@ -407,8 +390,7 @@ function M.test(root_directory)
if not root_directory then return end
end
for i = 1, #_BUFFERS do _BUFFERS[i]:annotation_clear_all() end
- run_command(
- M.test_commands[root_directory], root_directory, events.TEST_OUTPUT)
+ run_command(M.test_commands[root_directory], root_directory, events.TEST_OUTPUT)
end
events.connect(events.TEST_OUTPUT, print_output)
@@ -422,56 +404,63 @@ local function is_msg_buf(buf) return buf._type == _L['[Message Buffer]'] end
-- Send line as input to process stdin on return.
events.connect(events.CHAR_ADDED, function(code)
- if code == string.byte('\n') and proc and proc:status() == 'running' and
- is_msg_buf(buffer) then
+ if code == string.byte('\n') and proc and proc:status() == 'running' and is_msg_buf(buffer) then
local line_num = buffer:line_from_position(buffer.current_pos) - 1
proc:write(buffer:get_line(line_num))
end
end)
+-- LuaFormatter off
---
--- Map of file extensions and lexer names to their associated lists of string
--- patterns that match warning and error messages emitted by compile and run
--- commands for those file extensions and lexers.
--- Patterns match single lines and contain captures for a filename, line number,
--- column number (optional), and warning or error message (optional).
--- Double-clicking a warning or error message takes the user to the source of
--- that warning/error.
--- Note: `(.-)` captures in patterns are interpreted as filenames; `(%d+)`
--- captures are interpreted as line numbers first, and then column numbers; and
--- any other capture is treated as warning/error message text.
+-- Map of file extensions and lexer names to their associated lists of string patterns that
+-- match warning and error messages emitted by compile and run commands for those file extensions
+-- and lexers.
+-- Patterns match single lines and contain captures for a filename, line number, column number
+-- (optional), and warning or error message (optional). Double-clicking a warning or error
+-- message takes the user to the source of that warning/error.
+-- Note: `(.-)` captures in patterns are interpreted as filenames; `(%d+)` captures are
+-- interpreted as line numbers first, and then column numbers; and any other capture is treated
+-- as warning/error message text.
-- @class table
-- @name error_patterns
M.error_patterns = {actionscript={'^(.-)%((%d+)%): col: (%d+) (.+)$'},ada={'^(.-):(%d+):(%d+):%s*(.*)$','^[^:]+: (.-):(%d+) (.+)$'},ansi_c={'^(.-):(%d+):(%d+): (.+)$'},antlr={'^error%(%d+%): (.-):(%d+):(%d+): (.+)$','^warning%(%d+%): (.-):(%d+):(%d+): (.+)$'},--[[ANTLR]]g={'^error%(%d+%): (.-):(%d+):(%d+): (.+)$','^warning%(%d+%): (.-):(%d+):(%d+): (.+)$'},asm={'^(.-):(%d+): (.+)$'},awk={'^awk: (.-):(%d+): (.+)$'},boo={'^(.-)%((%d+),(%d+)%): (.+)$'},caml={'^%s*File "(.-)", line (%d+), characters (%d+)'},chuck={'^(.-)line%((%d+)%)%.char%((%d+)%): (.+)$'},clojure={' error .- at .-%((.-):(%d+)'},cmake={'^CMake Error at (.-):(%d+)','^(.-):(%d+):$'},coffeescript={'^(.-):(%d+):(%d+): (.+)$'},context={'error on line (%d+) in file (.-): (.+)$'},cpp={'^(.-):(%d+):(%d+): (.+)$'},csharp={'^(.-)%((%d+),(%d+)%): (.+)$'},cuda={'^(.-)%((%d+)%): (error.+)$'},dart={"^'(.-)': error: line (%d+) pos (%d+): (.+)$",'%(file://(.-):(%d+):(%d+)%)'},dmd={'^(.-)%((%d+)%): (Error.+)$'},dot={'^Warning: (.-): (.+) in line (%d+)'},eiffel={'^Line (%d+) columns? .- in .- %((.-)%):$','^line (%d+) column (%d+) file (.-)$'},elixir={'^(.-):(%d+): (.+)$','Error%) (.-):(%d+): (.+)$'},erlang={'^(.-):(%d+): (.+)$'},fantom={'^(.-)%((%d+),(%d+)%): (.+)$'},faust={'^(.-):(%d+):(.+)$'},fennel={'^%S+ error in (.-):(%d+)'},forth={'^(.-):(%d+): (.+)$'},fortran={'^(.-):(%d+)%D+(%d+):%s*(.*)$'},fsharp={'^(.-)%((%d+),(%d+)%): (.+)$'},gap={'^(.+) in (.-) line (%d+)$'},gnuplot={'^"(.-)", line (%d+): (.+)$'},go={'^(.-):(%d+):(%d+): (.+)$'},groovy={'^%s+at .-%((.-):(%d+)%)$','^(.-):(%d+): (.+)$'},haskell={'^(.-):(%d+):(%d+):%s*(.*)$'},icon={'^File (.-); Line (%d+) # (.+)$','^.-from line (%d+) in (.-)$'},java={'^%s+at .-%((.-):(%d+)%)$','^(.-):(%d+): (.+)$'},javascript={'^%s+at .-%((.-):(%d+):(%d+)%)$','^%s+at (.-):(%d+):(%d+)$','^(.-):(%d+):?$'},jq={'^jq: error: (.+) at (.-), line (%d+)'},julia={'^%s+%[%d+%].- at (.-):(%d+)$'},ltx={'^(.-):(%d+): (.+)$'},less={'^(.+) in (.-) on line (%d+), column (%d+):$'},lilypond={'^(.-):(%d+):(%d+):%s*(.*)$'},litcoffee={'^(.-):(%d+):(%d+): (.+)$'},lua={'^luac?: (.-):(%d+): (.+)$'},makefile={'^(.-):(%d+): (.+)$'},nemerle={'^(.-)%((%d+),(%d+)%): (.+)$'},nim={'^(.-)%((%d+), (%d+)%) (%w+:.+)$'},objective_c={'^(.-):(%d+):(%d+): (.+)$'},pascal={'^(.-)%((%d+),(%d+)%) (%w+:.+)$'},perl={'^(.+) at (.-) line (%d+)'},php={'^(.+) in (.-) on line (%d+)$'},pike={'^(.-):(%d+):(.+)$'},pony={'^(.-):(%d+):(%d+): (.+)$'},prolog={'^(.-):(%d+):(%d+): (.+)$','^(.-):(%d+): (.+)$'},pure={'^(.-), line (%d+): (.+)$'},python={'^%s*File "(.-)", line (%d+)'},rexx={'^Error %d+ running "(.-)", line (%d+): (.+)$'},ruby={'^%s+from (.-):(%d+):','^(.-):(%d+):%s*(.+)$'},rust={'^(.-):(%d+):(%d+): (.+)$',"panicked at '([^']+)', (.-):(%d+)"},sass={'^WARNING on line (%d+) of (.-):$','^%s+on line (%d+) of (.-)$'},scala={'^%s+at .-%((.-):(%d+)%)$','^(.-):(%d+): (.+)$'},sh={'^(.-): (%d+): %1: (.+)$'},bash={'^(.-): line (%d+): (.+)$'},zsh={'^(.-):(%d+): (.+)$'},smalltalk={'^(.-):(%d+): (.+)$','%((.-):(%d+)%)$'},snobol4={'^(.-):(%d+): (.+)$'},tcl={'^%s*%(file "(.-)" line (%d+)%)$'},tex={'^(.-):(%d+): (.+)$'},typescript={'^(.-):(%d+):(%d+) %- (.+)$'},vala={'^(.-):(%d+)%.(%d+)[%-%.%d]+: (.+)$','^(.-):(%d+):(%d+): (.+)$'},vb={'^(.-)%((%d+),(%d+)%): (.+)$'},xs={'^(.-):(%d+)%S* (.+)$'},zig={'^(.-):(%d+):(%d+): (.+)$'}}
-- Note: APDL,IDL,REBOL,RouterOS,Spin,Verilog,VHDL are proprietary.
-- Note: ASP,CSS,Desktop,diff,django,elm,fstab,gettext,Gtkrc,HTML,ini,JSON,JSP,Markdown,Networkd,Postscript,Properties,R,Reason,RHTML,Systemd,XML don't have parse-able errors.
-- Note: Batch,BibTeX,ConTeXt,Dockerfile,GLSL,Inform,Io,Lisp,MoonScript,Scheme,SQL,TeX cannot be parsed for one reason or another.
+-- LuaFormatter on
---
--- Jumps to the source of the recognized compile/run warning or error on line
--- number *line_num* in the message buffer.
--- If *line_num* is `nil`, jumps to the next or previous warning or error,
--- depending on boolean *next*. Displays an annotation with the warning or error
--- message if possible.
--- @param line_num Optional line number in the message buffer that contains the
--- compile/run warning or error to go to. This parameter may be omitted
--- completely.
--- @param next Optional flag indicating whether to go to the next recognized
--- warning/error or the previous one. Only applicable when *line_num* is
--- `nil`.
+-- Jumps to the source of the recognized compile/run warning or error on line number *line_num*
+-- in the message buffer.
+-- If *line_num* is `nil`, jumps to the next or previous warning or error, depending on boolean
+-- *next*. Displays an annotation with the warning or error message if possible.
+-- @param line_num Optional line number in the message buffer that contains the compile/run
+-- warning or error to go to. This parameter may be omitted completely.
+-- @param next Optional flag indicating whether to go to the next recognized warning/error or
+-- the previous one. Only applicable when *line_num* is `nil`.
-- @see error_patterns
-- @name goto_error
function M.goto_error(line_num, next)
if type(line_num) == 'boolean' then line_num, next = nil, line_num end
local msg_view, msg_buf = nil, nil
for i = 1, #_VIEWS do
- if is_msg_buf(_VIEWS[i].buffer) then msg_view = _VIEWS[i] break end
+ if is_msg_buf(_VIEWS[i].buffer) then
+ msg_view = _VIEWS[i]
+ break
+ end
end
for i = 1, #_BUFFERS do
- if is_msg_buf(_BUFFERS[i]) then msg_buf = _BUFFERS[i] break end
+ if is_msg_buf(_BUFFERS[i]) then
+ msg_buf = _BUFFERS[i]
+ break
+ end
end
if not msg_view and not msg_buf then return end
- if msg_view then ui.goto_view(msg_view) else view:goto_buffer(msg_buf) end
+ if msg_view then
+ ui.goto_view(msg_view)
+ else
+ view:goto_buffer(msg_buf)
+ end
-- If no line number was given, find the next warning or error marker.
if not assert_type(line_num, 'number/nil', 1) and next ~= nil then
@@ -486,7 +475,11 @@ function M.goto_error(line_num, next)
wline = f(buffer, next and 1 or buffer.line_count, WARN_BIT)
eline = f(buffer, next and 1 or buffer.line_count, ERROR_BIT)
elseif wline == -1 or eline == -1 then
- if wline == -1 then wline = eline else eline = wline end
+ if wline == -1 then
+ wline = eline
+ else
+ eline = wline
+ end
end
line_num = (next and math.min or math.max)(wline, eline)
if line_num == -1 and not wrapped then
@@ -508,9 +501,7 @@ function M.goto_error(line_num, next)
local sloppy = not detail.filename:find(not WIN32 and '^/' or '^%a:[/\\]')
ui.goto_file(detail.filename, true, preferred_view, sloppy)
textadept.editing.goto_line(detail.line)
- if detail.column then
- buffer:goto_pos(buffer:find_column(detail.line, detail.column))
- end
+ if detail.column then buffer:goto_pos(buffer:find_column(detail.line, detail.column)) end
if not detail.message then return end
buffer.annotation_text[detail.line] = detail.message
if detail.warning then return end
@@ -518,13 +509,12 @@ function M.goto_error(line_num, next)
end
events.connect(events.KEYPRESS, function(code)
if keys.KEYSYMS[code] == '\n' and is_msg_buf(buffer) and
- scan_for_error(buffer:get_cur_line():match('^[^\r\n]*')) then
+ scan_for_error(buffer:get_cur_line():match('^[^\r\n]*')) then
M.goto_error(buffer:line_from_position(buffer.current_pos))
return true
end
end)
-events.connect(events.DOUBLE_CLICK, function(_, line)
- if is_msg_buf(buffer) then M.goto_error(line) end
-end)
+events.connect(events.DOUBLE_CLICK,
+ function(_, line) if is_msg_buf(buffer) then M.goto_error(line) end end)
return M
diff --git a/modules/textadept/session.lua b/modules/textadept/session.lua
index 96f6e969..bf19e78e 100644
--- a/modules/textadept/session.lua
+++ b/modules/textadept/session.lua
@@ -7,23 +7,21 @@ local M = {}
-- Session support for Textadept.
-- @field save_on_quit (bool)
-- Save the session when quitting.
--- The default value is `true` unless the user passed the command line switch
--- `-n` or `--nosession` to Textadept.
+-- The default value is `true` unless the user passed the command line switch `-n` or
+-- `--nosession` to Textadept.
-- @field _G.events.SESSION_SAVE (string)
-- Emitted when saving a session.
-- Arguments:
--
--- * `session`: Table of session data to save. All handlers will have access
--- to this same table, and Textadept's default handler reserves the use of
--- some keys.
--- Note that functions, userdata, and circular table values cannot be saved.
--- The latter case is not recognized at all, so beware.
+-- * `session`: Table of session data to save. All handlers will have access to this same
+-- table, and Textadept's default handler reserves the use of some keys.
+-- Note that functions, userdata, and circular table values cannot be saved. The latter
+-- case is not recognized at all, so beware.
-- @field _G.events.SESSION_LOAD (string)
-- Emitted when loading a session.
-- Arguments:
--
--- * `session`: Table of session data to load. All handlers will have access
--- to this same table.
+-- * `session`: Table of session data to load. All handlers will have access to this same table.
module('textadept.session')]]
M.save_on_quit = true
@@ -35,12 +33,11 @@ for _, v in ipairs(session_events) do events[v:upper()] = v end
local session_file = _USERHOME .. (not CURSES and '/session' or '/session_term')
---
--- Loads session file *filename* or the user-selected session, returning `true`
--- if a session file was opened and read.
--- Textadept restores split views, opened buffers, cursor information, recent
--- files, and bookmarks.
--- @param filename Optional absolute path to the session file to load. If `nil`,
--- the user is prompted for one.
+-- Loads session file *filename* or the user-selected session, returning `true` if a session
+-- file was opened and read.
+-- Textadept restores split views, opened buffers, cursor information, recent files, and bookmarks.
+-- @param filename Optional absolute path to the session file to load. If `nil`, the user is
+-- prompted for one.
-- @return `true` if the session file was opened and read; `nil` otherwise.
-- @usage textadept.session.load(filename)
-- @name load
@@ -116,24 +113,18 @@ function M.load(filename)
return true
end
-- Load session when no args are present.
-local function load_default_session()
- if M.save_on_quit then M.load(session_file) end
-end
+local function load_default_session() if M.save_on_quit then M.load(session_file) end end
events.connect(events.ARG_NONE, load_default_session)
-- Returns value *val* serialized as a string.
-- This is a very simple implementation suitable for session saving only.
--- Ignores function, userdata, and thread types, and does not handle circular
--- tables.
+-- Ignores function, userdata, and thread types, and does not handle circular tables.
local function _tostring(val)
if type(val) == 'table' then
local t = {}
- for k, v in pairs(val) do
- t[#t + 1] = string.format('[%s]=%s,', _tostring(k), _tostring(v))
- end
+ for k, v in pairs(val) do t[#t + 1] = string.format('[%s]=%s,', _tostring(k), _tostring(v)) end
return string.format('{%s}', table.concat(t))
- elseif type(val) == 'function' or type(val) == 'userdata' or
- type(val) == 'thread' then
+ elseif type(val) == 'function' or type(val) == 'userdata' or type(val) == 'thread' then
val = nil
end
return type(val) == 'string' and string.format('%q', val) or tostring(val)
@@ -141,12 +132,11 @@ end
---
-- Saves the session to file *filename* or the user-selected file.
--- Saves split views, opened buffers, cursor information, recent files, and
--- bookmarks.
+-- Saves split views, opened buffers, cursor information, recent files, and bookmarks.
-- Upon quitting, the current session is saved to *filename* again, unless
-- `textadept.session.save_on_quit` is `false`.
--- @param filename Optional absolute path to the session file to save. If `nil`,
--- the user is prompted for one.
+-- @param filename Optional absolute path to the session file to save. If `nil`, the user is
+-- prompted for one.
-- @usage textadept.session.save(filename)
-- @name save
function M.save(filename)
@@ -174,7 +164,7 @@ function M.save(filename)
filename = buffer.filename or buffer._type,
anchor = current and buffer.anchor or buffer._anchor or 1,
current_pos = current and buffer.current_pos or buffer._current_pos or 1,
- top_line = current and view.first_visible_line or buffer._top_line or 1,
+ top_line = current and view.first_visible_line or buffer._top_line or 1
}
local bookmarks = {}
local BOOKMARK_BIT = 1 << textadept.bookmarks.MARK_BOOKMARK - 1
@@ -193,13 +183,11 @@ function M.save(filename)
-- Serialize views.
local function serialize_split(split)
return split.buffer and _BUFFERS[split.buffer] or {
- serialize_split(split[1]), serialize_split(split[2]),
- vertical = split.vertical, size = split.size
+ serialize_split(split[1]), serialize_split(split[2]), vertical = split.vertical,
+ size = split.size
}
end
- session.views = {
- serialize_split(ui.get_split_table()), current = _VIEWS[view]
- }
+ session.views = {serialize_split(ui.get_split_table()), current = _VIEWS[view]}
-- Serialize recent files.
session.recent_files = io.recent_files
@@ -209,19 +197,14 @@ function M.save(filename)
session_file = filename
end
-- Saves session on quit.
-events.connect(events.QUIT, function()
- if M.save_on_quit then M.save(session_file) end
-end, 1)
+events.connect(events.QUIT, function() if M.save_on_quit then M.save(session_file) end end, 1)
-- Does not save session on quit.
-args.register('-n', '--nosession', 0, function()
- M.save_on_quit = false
-end, 'No session functionality')
+args.register('-n', '--nosession', 0, function() M.save_on_quit = false end,
+ 'No session functionality')
-- Loads the given session on startup.
args.register('-s', '--session', 1, function(name)
- if not lfs.attributes(name) then
- name = string.format('%s/%s', _USERHOME, name)
- end
+ if not lfs.attributes(name) then name = string.format('%s/%s', _USERHOME, name) end
M.load(name)
events.disconnect(events.ARG_NONE, load_default_session)
end, 'Load session')
diff --git a/modules/textadept/snippets.lua b/modules/textadept/snippets.lua
index 40d2febb..e900f2b4 100644
--- a/modules/textadept/snippets.lua
+++ b/modules/textadept/snippets.lua
@@ -8,57 +8,53 @@ local M = {}
--
-- ### Overview
--
--- Define snippets in the global `snippets` table in key-value pairs. Each pair
--- consists of either a string trigger word and its snippet text, or a string
--- lexer name (from the *lexers/* directory) with a table of trigger words and
--- snippet texts. When searching for a snippet to insert based on a trigger
--- word, Textadept considers snippets in the current lexer to have priority,
--- followed by the ones in the global table. This means if there are two
--- snippets with the same trigger word, Textadept inserts the one specific to
--- the current lexer, not the global one.
+-- Define snippets in the global `snippets` table in key-value pairs. Each pair consists of
+-- either a string trigger word and its snippet text, or a string lexer name (from the *lexers/*
+-- directory) with a table of trigger words and snippet texts. When searching for a snippet to
+-- insert based on a trigger word, Textadept considers snippets in the current lexer to have
+-- priority, followed by the ones in the global table. This means if there are two snippets
+-- with the same trigger word, Textadept inserts the one specific to the current lexer, not
+-- the global one.
--
-- ### Special Sequences
--
-- #### `%`*n*`(`*text*`)`
--
--- Represents a placeholder, where *n* is an integer and *text* is default
--- placeholder text. Textadept moves the caret to placeholders in numeric order
--- each time it calls [`textadept.snippets.insert()`](), finishing at either
--- the "%0" placeholder if it exists or at the end of the snippet. Examples are
+-- Represents a placeholder, where *n* is an integer and *text* is default placeholder
+-- text. Textadept moves the caret to placeholders in numeric order each time it calls
+-- [`textadept.snippets.insert()`](), finishing at either the "%0" placeholder if it exists or
+-- at the end of the snippet. Examples are
--
-- snippets['foo'] = 'foobar%1(baz)'
-- snippets['bar'] = 'start\n\t%0\nend'
--
-- #### `%`*n*`{`*list*`}`
--
--- Also represents a placeholder (where *n* is an integer), but presents a list
--- of choices for placeholder text constructed from comma-separated *list*.
--- Examples are
+-- Also represents a placeholder (where *n* is an integer), but presents a list of choices for
+-- placeholder text constructed from comma-separated *list*. Examples are
--
-- snippets['op'] = 'operator(%1(1), %2(1), "%3{add,sub,mul,div}")'
--
-- #### `%`*n*
--
--- Represents a mirror, where *n* is an integer. Mirrors with the same *n* as a
--- placeholder mirror any user input in the placeholder. If no placeholder
--- exists for *n*, the first occurrence of that mirror in the snippet becomes
--- the placeholder, but with no default text. Examples are
+-- Represents a mirror, where *n* is an integer. Mirrors with the same *n* as a placeholder mirror
+-- any user input in the placeholder. If no placeholder exists for *n*, the first occurrence
+-- of that mirror in the snippet becomes the placeholder, but with no default text. Examples are
--
-- snippets['foo'] = '%1(mirror), %1, on the wall'
-- snippets['q'] = '"%1"'
--
-- #### `%`*n*`<`*Lua code*`>`<br/>`%`*n*`[`*Shell code*`]`
--
--- Represents a transform, where *n* is an integer that has an associated
--- placeholder, *Lua code* is arbitrary Lua code, and *Shell code* is arbitrary
--- Shell code. Textadept executes the code as text is typed into placeholder
--- *n*. If the transform omits *n*, Textadept executes the transform's code the
--- moment the editor inserts the snippet.
+-- Represents a transform, where *n* is an integer that has an associated placeholder, *Lua code*
+-- is arbitrary Lua code, and *Shell code* is arbitrary Shell code. Textadept executes the code
+-- as text is typed into placeholder *n*. If the transform omits *n*, Textadept executes the
+-- transform's code the moment the editor inserts the snippet.
--
--- Textadept runs Lua code in its Lua State and replaces the transform with the
--- code's return text. The code may use the temporary `text` and `selected_text`
--- global variables which contain placeholder *n*'s text and the text originally
--- selected when the snippet was inserted, respectively. An example is
+-- Textadept runs Lua code in its Lua State and replaces the transform with the code's return
+-- text. The code may use the temporary `text` and `selected_text` global variables which
+-- contain placeholder *n*'s text and the text originally selected when the snippet was inserted,
+-- respectively. An example is
--
-- snippets['attr'] = [[
-- %1(int) %2(foo) = %3;
@@ -71,29 +67,27 @@ local M = {}
-- }
-- ]]
--
--- Textadept executes shell code using Lua's [`io.popen()`][] and replaces the
--- transform with the process' standard output (stdout). The code may use a `%`
--- character to represent placeholder *n*'s text. An example is
+-- Textadept executes shell code using Lua's [`io.popen()`][] and replaces the transform with the
+-- process' standard output (stdout). The code may use a `%` character to represent placeholder
+-- *n*'s text. An example is
--
-- snippets['env'] = '$%1(HOME) = %1[echo $%]'
--
-- #### `%%`
--
--- Stands for a single '%' since '%' by itself has a special meaning in
--- snippets.
+-- Stands for a single '%' since '%' by itself has a special meaning in snippets.
--
-- #### `%(`<br/>`%{`
--
--- Stands for a single '(' or '{', respectively, after a `%`*n* mirror.
--- Otherwise, the mirror would be interpreted as a placeholder or transform.
--- Note: it is currently not possible to escape a '<' or '[' immediately after
--- a `%`*n* mirror due to `%<...>` and `%[...]` sequences being interpreted as
--- code to execute.
+-- Stands for a single '(' or '{', respectively, after a `%`*n* mirror. Otherwise, the mirror
+-- would be interpreted as a placeholder or transform. Note: it is currently not possible to
+-- escape a '<' or '[' immediately after a `%`*n* mirror due to `%<...>` and `%[...]` sequences
+-- being interpreted as code to execute.
--
-- #### `\t`
--
--- A single unit of indentation based on the buffer's indentation settings
--- ([`buffer.use_tabs`]() and [`buffer.tab_width`]()).
+-- A single unit of indentation based on the buffer's indentation settings ([`buffer.use_tabs`]()
+-- and [`buffer.tab_width`]()).
--
-- #### `\n`
--
@@ -112,12 +106,12 @@ M.INDIC_PLACEHOLDER = _SCINTILLA.next_indic_number()
---
-- List of directory paths to look for snippet files in.
--- Filenames are of the form *lexer.trigger.ext* or *trigger.ext* (*.ext* is an
--- optional, arbitrary file extension). If the global `snippets` table does not
--- contain a snippet for a given trigger, this table is consulted for a matching
--- filename, and the contents of that file is inserted as a snippet.
--- Note: If a directory has multiple snippets with the same trigger, the snippet
--- chosen for insertion is not defined and may not be constant.
+-- Filenames are of the form *lexer.trigger.ext* or *trigger.ext* (*.ext* is an optional,
+-- arbitrary file extension). If the global `snippets` table does not contain a snippet for
+-- a given trigger, this table is consulted for a matching filename, and the contents of that
+-- file is inserted as a snippet.
+-- Note: If a directory has multiple snippets with the same trigger, the snippet chosen for
+-- insertion is not defined and may not be constant.
-- @class table
-- @name paths
M.paths = {}
@@ -125,37 +119,35 @@ M.paths = {}
local INDIC_SNIPPET = _SCINTILLA.next_indic_number()
local INDIC_CURRENTPLACEHOLDER = _SCINTILLA.next_indic_number()
-
--- Map of snippet triggers with their snippet text or functions that return such
--- text, with language-specific snippets tables assigned to a lexer name key.
+-- LuaFormatter off
+-- Map of snippet triggers with their snippet text or functions that return such text, with
+-- language-specific snippets tables assigned to a lexer name key.
-- @class table
-- @name snippets
-- @see _G.snippets
local snippets = {actionscript={},ada={},apdl={},ansi_c={},antlr={},apl={},applescript={},asp={},autoit={},awk={},b_lang={},bash={},batch={},bibtex={},boo={},chuck={},clojure={},cmake={},coffeescript={},context={},cpp={},crystal={},csharp={},css={},cuda={},desktop={},django={},dmd={},dockerfile={},dot={},eiffel={},elixir={},elm={},erlang={},fantom={},faust={},fennel={},fish={},forth={},fortran={},fsharp={},fstab={},gap={},gettext={},gherkin={},glsl={},gnuplot={},go={},groovy={},gtkrc={},haskell={},html={},icon={},idl={},inform={},ini={},Io={},java={},javascript={},jq={},json={},jsp={},julia={},latex={},ledger={},less={},lilypond={},lisp={},logtalk={},lua={},makefile={},matlab={},meson={},moonscript={},myrddin={},nemerle={},networkd={},nim={},nsis={},objective_c={},pascal={},perl={},php={},pico8={},pike={},pkgbuild={},pony={},prolog={},props={},protobuf={},ps={},pure={},python={},rails={},rc={},reason={},rebol={},rest={},rexx={},rhtml={},routeros={},rstats={},ruby={},rust={},sass={},scala={},scheme={},smalltalk={},sml={},snobol4={},spin={},sql={},systemd={},tcl={},tex={},text={},toml={},typescript={},vala={},vb={},vbscript={},verilog={},vhdl={},wsf={},xml={},xs={},xtend={},yaml={},zig={}}
-
--- Finds the snippet assigned to the trigger word behind the caret and returns
--- the trigger word and snippet text. If *grep* is `true`, returns a table of
--- snippets (trigger-text key-value pairs) that match the trigger word
--- instead of snippet text.
--- Snippets are searched for in the global snippets table followed by snippet
--- directories. Lexer-specific snippets are preferred.
--- @param grep Flag that indicates whether or not to return a table of snippets
--- that match the trigger word.
--- @param no_trigger Flag that indicates whether or not to ignore the trigger
--- word and return all snippets.
+-- LuaFormatter on
+
+-- Finds the snippet assigned to the trigger word behind the caret and returns the trigger word
+-- and snippet text.
+-- If *grep* is `true`, returns a table of snippets (trigger-text key-value pairs) that match
+-- the trigger word instead of snippet text. Snippets are searched for in the global snippets
+-- table followed by snippet directories. Lexer-specific snippets are preferred.
+-- @param grep Flag that indicates whether or not to return a table of snippets that match the
+-- trigger word.
+-- @param no_trigger Flag that indicates whether or not to ignore the trigger word and return
+-- all snippets.
-- @return trigger word, snippet text or table of matching snippets
local function find_snippet(grep, no_trigger)
local matching_snippets = {}
- local trigger = not no_trigger and buffer:text_range(
- buffer:word_start_position(buffer.current_pos), buffer.current_pos) or ''
+ local trigger = not no_trigger and
+ buffer:text_range(buffer:word_start_position(buffer.current_pos), buffer.current_pos) or ''
if no_trigger then grep = true end
local lang = buffer:get_lexer(true)
local name_patt = '^' .. trigger
-- Search in the snippet tables.
local snippet_tables = {snippets}
- if type(snippets[lang]) == 'table' then
- table.insert(snippet_tables, 1, snippets[lang])
- end
+ if type(snippets[lang]) == 'table' then table.insert(snippet_tables, 1, snippets[lang]) end
for _, snippets in ipairs(snippet_tables) do
if not grep and snippets[trigger] then return trigger, snippets[trigger] end
if not grep then goto continue end
@@ -169,14 +161,12 @@ local function find_snippet(grep, no_trigger)
-- Search in snippet files.
for i = 1, #M.paths do
for basename in lfs.dir(M.paths[i]) do
- -- Snippet files are either of the form "lexer.trigger.ext" or
- -- "trigger.ext". Prefer "lexer."-prefixed snippets.
+ -- Snippet files are either of the form "lexer.trigger.ext" or "trigger.ext". Prefer
+ -- "lexer."-prefixed snippets.
local p1, p2, p3 = basename:match('^([^.]+)%.?([^.]*)%.?([^.]*)$')
- if not grep and
- (p1 == lang and p2 == trigger or p1 == trigger and p3 == '') or
- grep and
- (p1 == lang and p2 and p2:find(name_patt) or
- p1 and p1:find(name_patt) and p3 == '') then
+ if not grep and (p1 == lang and p2 == trigger or p1 == trigger and p3 == '') or
+ (grep and
+ (p1 == lang and p2 and p2:find(name_patt) or p1 and p1:find(name_patt) and p3 == '')) then
local f = io.open(string.format('%s/%s', M.paths[i], basename))
text = f:read('a')
f:close()
@@ -185,26 +175,25 @@ local function find_snippet(grep, no_trigger)
end
end
end
- if not grep then return nil, nil else return trigger, matching_snippets end
+ if not grep then return nil, nil end
+ return trigger, matching_snippets
end
-- A snippet object.
-- @field trigger The word that triggered this snippet.
--- @field original_sel_text The text originally selected when this snippet was
--- inserted.
+-- @field original_sel_text The text originally selected when this snippet was inserted.
-- @field start_pos This snippet's start position.
--- @field end_pos This snippet's end position. This is a metafield that is
--- computed based on the `INDIC_SNIPPET` sentinel.
--- @field placeholder_pos The beginning of the current placeholder in this
--- snippet. This is used by transforms to identify text to transform. This is
--- a metafield that is computed based on `INDIC_CURRENTPLACEHOLDER`.
+-- @field end_pos This snippet's end position. This is a metafield that is computed based on the
+-- `INDIC_SNIPPET` sentinel.
+-- @field placeholder_pos The beginning of the current placeholder in this snippet. This is used
+-- by transforms to identify text to transform. This is a metafield that is computed based on
+-- `INDIC_CURRENTPLACEHOLDER`.
-- @field index This snippet's current placeholder index.
-- @field max_index The number of different placeholders in this snippet.
--- @field snapshots A record of this snippet's text over time. The snapshot for
--- a given placeholder index contains the state of the snippet with all
--- placeholders of that index filled in (prior to moving to the next
--- placeholder index). Snippet state consists of a `text` string field and a
--- `placeholders` table field.
+-- @field snapshots A record of this snippet's text over time. The snapshot for a given
+-- placeholder index contains the state of the snippet with all placeholders of that index
+-- filled in (prior to moving to the next placeholder index). Snippet state consists of a
+-- `text` string field and a `placeholders` table field.
-- @class table
-- @name snippet
local snippet = {}
@@ -218,8 +207,8 @@ local stack = {}
function snippet.new(text, trigger)
local snip = setmetatable({
trigger = trigger, original_sel_text = buffer:get_sel_text(),
- start_pos = buffer.selection_start - (trigger and #trigger or 0), index = 0,
- max_index = 0, snapshots = {}
+ start_pos = buffer.selection_start - (trigger and #trigger or 0), index = 0, max_index = 0,
+ snapshots = {}
}, snippet)
-- Convert and match indentation.
@@ -246,10 +235,10 @@ function snippet.new(text, trigger)
local C, Cp, Ct, Cg, Cc = lpeg.C, lpeg.Cp, lpeg.Ct, lpeg.Cg, lpeg.Cc
local patt = P{
V('plain_text') * V('placeholder') * Cp() + V('plain_text') * -1,
- plain_text = C(((P(1) - '%' + '%' * S('({'))^1 + '%%')^0),
- placeholder = Ct(
- '%' * (V('index')^-1 * (V('angles') + V('brackets') + V('braces')) *
- V('transform') + V('index') * (V('parens') + V('simple')))),
+ plain_text = C(((P(1) - '%' + '%' * S('({'))^1 + '%%')^0), -- LuaFormatter
+ placeholder = Ct('%' *
+ (V('index')^-1 * (V('angles') + V('brackets') + V('braces')) * V('transform') + V('index') *
+ (V('parens') + V('simple')))), -- LuaFormatter
index = Cg(R('09')^1 / tonumber, 'index'),
parens = '(' * Cg((1 - S('()') + V('parens'))^0, 'default') * ')',
simple = Cg(Cc(true), 'simple'), transform = Cg(Cc(true), 'transform'),
@@ -259,22 +248,21 @@ function snippet.new(text, trigger)
}
-- A snippet placeholder.
-- Each placeholder is stored in a snippet snapshot.
- -- @field id This placeholder's unique ID. This field is used as an
- -- indicator's value for identification purposes.
+ -- @field id This placeholder's unique ID. This field is used as an indicator's value for
+ -- identification purposes.
-- @field index This placeholder's index.
-- @field default This placeholder's default text, if any.
- -- @field transform Whether or not this placeholder is a transform (containing
- -- either Lua or Shell code).
+ -- @field transform Whether or not this placeholder is a transform (containing either Lua or
+ -- Shell code).
-- @field lua_code The Lua code of this transform.
-- @field sh_code The Shell code of this transform.
-- @field choice A list of options to insert from an autocompletion list.
- -- @field position This placeholder's initial position in its snapshot. This
- -- field will not update until the next snapshot is taken. Use
- -- `snippet:each_placeholder()` to determine a placeholder's current
- -- position.
- -- @field length This placeholder's initial length in its snapshot. This field
- -- will never update. Use `buffer:indicator_end()` in conjunction with
- -- `snippet:each_placeholder()` to determine a placeholder's current length.
+ -- @field position This placeholder's initial position in its snapshot. This field will not
+ -- update until the next snapshot is taken. Use `snippet:each_placeholder()` to determine
+ -- a placeholder's current position.
+ -- @field length This placeholder's initial length in its snapshot. This field will never
+ -- update. Use `buffer:indicator_end()` in conjunction with `snippet:each_placeholder()`
+ -- to determine a placeholder's current length.
-- @class table
-- @name placeholder
local text_part, placeholder, e = patt:match(text)
@@ -285,17 +273,14 @@ function snippet.new(text, trigger)
placeholder.id = #snapshot.placeholders + 1
snapshot.placeholders[#snapshot.placeholders + 1] = placeholder
end
- if text_part ~= '' then
- snapshot.text = snapshot.text .. text_part:gsub('%%(%p)', '%1')
- end
+ if text_part ~= '' then snapshot.text = snapshot.text .. text_part:gsub('%%(%p)', '%1') end
placeholder.position = #snapshot.text
if placeholder.default then
if placeholder.default:find('%%%d+') then
- -- Parses out embedded placeholders, adding them to this snippet's
- -- snapshot.
+ -- Parses out embedded placeholders, adding them to this snippet's snapshot.
-- @param s The placeholder string to parse.
- -- @param start_pos The absolute position in the snippet `s` starts
- -- from. All computed positions are anchored from here.
+ -- @param start_pos The absolute position in the snippet `s` starts from. All computed
+ -- positions are anchored from here.
-- @return plain text from `s` (i.e. no placeholder markup)
local function process_placeholders(s, start_pos)
-- Processes a placeholder capture from LPeg.
@@ -306,8 +291,7 @@ function snippet.new(text, trigger)
position = start_pos + position - 1
if default then
-- Process sub-placeholders starting at the index after '%n('.
- default = process_placeholders(
- default:sub(2, -2), position + #index + 2)
+ default = process_placeholders(default:sub(2, -2), position + #index + 2)
end
index = tonumber(index)
if index > snip.max_index then snip.max_index = index end
@@ -323,8 +307,7 @@ function snippet.new(text, trigger)
parens = '(' * (1 - S('()') + V('parens'))^0 * ')'
}, s)
end
- placeholder.default = process_placeholders(
- placeholder.default, placeholder.position)
+ placeholder.default = process_placeholders(placeholder.default, placeholder.position)
end
snapshot.text = snapshot.text .. placeholder.default
elseif placeholder.transform and not placeholder.index then
@@ -336,9 +319,7 @@ function snippet.new(text, trigger)
placeholder.position = snip.start_pos + placeholder.position -- absolute
text_part, placeholder, e = patt:match(text, e)
end
- if text_part ~= '' then
- snapshot.text = snapshot.text .. text_part:gsub('%%(%p)', '%1')
- end
+ if text_part ~= '' then snapshot.text = snapshot.text .. text_part:gsub('%%(%p)', '%1') end
snip.snapshots[0] = snapshot
-- Insert the snippet into the buffer and mark its end position.
@@ -359,20 +340,19 @@ function snippet:__index(k)
local end_pos = buffer:indicator_end(INDIC_SNIPPET, self.start_pos)
return end_pos > self.start_pos and end_pos or self.start_pos
elseif k == 'placeholder_pos' then
- -- Normally the marker is one character behind the placeholder. However
- -- it will not exist at all if the placeholder is at the beginning of the
- -- snippet. Also account for the marker being at the beginning of the
- -- snippet. (If so, pos will point to the correct position.)
+ -- Normally the marker is one character behind the placeholder. However it will not exist
+ -- at all if the placeholder is at the beginning of the snippet. Also account for the marker
+ -- being at the beginning of the snippet. (If so, pos will point to the correct position.)
local pos = buffer:indicator_end(INDIC_CURRENTPLACEHOLDER, self.start_pos)
if pos == 1 then pos = self.start_pos end
- return buffer:indicator_all_on_for(pos) &
- 1 << INDIC_CURRENTPLACEHOLDER - 1 > 0 and pos + 1 or pos
+ return buffer:indicator_all_on_for(pos) & 1 << INDIC_CURRENTPLACEHOLDER - 1 > 0 and pos + 1 or
+ pos
end
return getmetatable(self)[k]
end
--- Inserts the current snapshot (based on `self.index`) of this snippet into
--- the buffer and marks placeholders.
+-- Inserts the current snapshot (based on `self.index`) of this snippet into the buffer and
+-- marks placeholders.
function snippet:insert()
buffer:set_target_range(self.start_pos, self.end_pos)
buffer:replace_target(self.snapshots[self.index].text)
@@ -383,22 +363,19 @@ function snippet:insert()
end
end
--- Jumps to the next placeholder in this snippet and adds additional carets
--- at mirrors.
+-- Jumps to the next placeholder in this snippet and adds additional carets at mirrors.
function snippet:next()
if buffer:auto_c_active() then buffer:auto_c_complete() end
- -- Take a snapshot of the current state in order to restore it later if
- -- necessary.
+ -- Take a snapshot of the current state in order to restore it later if necessary.
if self.index > 0 and self.start_pos < self.end_pos then
local text = buffer:text_range(self.start_pos, self.end_pos)
local placeholders = {}
for pos, ph in self:each_placeholder() do
- -- Only the position of placeholders changes between snapshots; save it
- -- and keep all other existing properties.
- -- Note that nested placeholders will return the same placeholder id
- -- twice: once before a nested placeholder, and again after. (e.g.
- -- [foo[bar]baz] will will return the '[foo' and 'baz]' portions of the
- -- same placeholder.) Only process the first occurrence.
+ -- Only the position of placeholders changes between snapshots; save it and keep all
+ -- other existing properties.
+ -- Note that nested placeholders will return the same placeholder id twice: once before
+ -- a nested placeholder, and again after. (e.g. [foo[bar]baz] will will return the '[foo'
+ -- and 'baz]' portions of the same placeholder.) Only process the first occurrence.
if placeholders[ph.id] then goto continue end
placeholders[ph.id] = setmetatable({position = pos}, {
__index = self.snapshots[self.index - 1].placeholders[ph.id]
@@ -413,8 +390,11 @@ function snippet:next()
local ph = select(2, self:each_placeholder(self.index, 'default')()) or
select(2, self:each_placeholder(self.index, 'choice')()) or
select(2, self:each_placeholder(self.index, 'simple')()) or
- self.index == 0 and {position = self.end_pos, length = 0}
- if not ph then self:next() return end -- try next placeholder
+ (self.index == 0 and {position = self.end_pos, length = 0})
+ if not ph then
+ self:next() -- try next placeholder
+ return
+ end
-- Mark the position of the placeholder so transforms can identify it.
buffer.indicator_current = INDIC_CURRENTPLACEHOLDER
@@ -461,10 +441,13 @@ function snippet:next()
if self.index == 0 then self:finish() end
end
--- Jumps to the previous placeholder in this snippet and restores the state
--- associated with that placeholder.
+-- Jumps to the previous placeholder in this snippet and restores the state associated with
+-- that placeholder.
function snippet:previous()
- if self.index < 2 then self:finish(true) return end
+ if self.index < 2 then
+ self:finish(true)
+ return
+ end
self.index = self.index - 2
self:insert()
self:next()
@@ -472,8 +455,8 @@ end
-- Finishes or cancels this snippet depending on boolean *canceling*.
-- The snippet cleans up after itself regardless.
--- @param canceling Whether or not to cancel inserting this snippet. When
--- `true`, the buffer is restored to its state prior to snippet expansion.
+-- @param canceling Whether or not to cancel inserting this snippet. When `true`, the buffer
+-- is restored to its state prior to snippet expansion.
function snippet:finish(canceling)
local s, e = self.start_pos, self.end_pos
if e ~= s then buffer:delete_range(e, 1) end -- clear initial padding space
@@ -487,47 +470,42 @@ function snippet:finish(canceling)
stack[#stack] = nil
end
--- Returns a generator that returns each placeholder's position and state for
--- all placeholders in this snippet.
--- DO NOT modify the buffer while this generator is running. Doing so will
--- affect the generator's state and cause errors. Re-run the generator each
--- time a buffer edit is made (e.g. via `goto`).
+-- Returns a generator that returns each placeholder's position and state for all placeholders
+-- in this snippet.
+-- DO NOT modify the buffer while this generator is running. Doing so will affect the generator's
+-- state and cause errors. Re-run the generator each time a buffer edit is made (e.g. via `goto`).
-- @param index Optional placeholder index to constrain results to.
-- @param type Optional placeholder type to constrain results to.
function snippet:each_placeholder(index, type)
- local snapshot =
- self.snapshots[self.index > 0 and self.index - 1 or #self.snapshots]
+ local snapshot = self.snapshots[self.index > 0 and self.index - 1 or #self.snapshots]
local i = self.start_pos
return function()
local s = buffer:indicator_end(M.INDIC_PLACEHOLDER, i)
while s > 1 and s <= self.end_pos do
if buffer:indicator_all_on_for(i) & 1 << M.INDIC_PLACEHOLDER - 1 > 0 then
- -- This next indicator comes directly after the previous one; adjust
- -- start and end positions to compensate.
+ -- This next indicator comes directly after the previous one; adjust start and end
+ -- positions to compensate.
s, i = buffer:indicator_start(M.INDIC_PLACEHOLDER, i), s
else
i = buffer:indicator_end(M.INDIC_PLACEHOLDER, s)
end
local id = buffer:indicator_value_at(M.INDIC_PLACEHOLDER, s)
local ph = snapshot.placeholders[id]
- if ph and (not index or ph.index == index) and (not type or ph[type]) then
- return s, ph
- end
+ if ph and (not index or ph.index == index) and (not type or ph[type]) then return s, ph end
s = buffer:indicator_end(M.INDIC_PLACEHOLDER, i)
end
end
end
--- Returns the result of executing Lua or Shell code, in placeholder table
--- *placeholder*, in the context of this snippet.
+-- Returns the result of executing Lua or Shell code, in placeholder table *placeholder*,
+-- in the context of this snippet.
-- @param placeholder The placeholder that contains code to execute.
function snippet:execute_code(placeholder)
local s, e = self.placeholder_pos, buffer.selection_end
if s > e then s, e = e, s end
local text = self.index and buffer:text_range(s, e) or '' -- %<...>, %[...]
if placeholder.lua_code then
- local env = setmetatable(
- {text = text, selected_text = self.original_sel_text}, {__index = _G})
+ local env = setmetatable({text = text, selected_text = self.original_sel_text}, {__index = _G})
local f, result = load('return ' .. placeholder.lua_code, nil, 't', env)
return f and select(2, pcall(f)) or result or ''
elseif placeholder.sh_code then
@@ -571,13 +549,11 @@ function snippet:update_transforms()
end
---
--- Inserts snippet text *text* or the snippet assigned to the trigger word
--- behind the caret.
--- Otherwise, if a snippet is active, goes to the active snippet's next
--- placeholder. Returns `false` if no action was taken.
--- @param text Optional snippet text to insert. If `nil`, attempts to insert a
--- new snippet based on the trigger, the word behind caret, and the current
--- lexer.
+-- Inserts snippet text *text* or the snippet assigned to the trigger word behind the caret.
+-- Otherwise, if a snippet is active, goes to the active snippet's next placeholder. Returns
+-- `false` if no action was taken.
+-- @param text Optional snippet text to insert. If `nil`, attempts to insert a new snippet
+-- based on the trigger, the word behind caret, and the current lexer.
-- @return `false` if no action was taken; `nil` otherwise.
-- @see buffer.word_chars
-- @name insert
@@ -589,17 +565,18 @@ function M.insert(text)
assert_type(text, 'string/nil', trigger or '?')
end
if text then snippet.new(text, trigger) end
- if #stack > 0 then stack[#stack]:next() else return false end
+ if #stack == 0 then return false end
+ stack[#stack]:next()
end
---
--- Jumps back to the previous snippet placeholder, reverting any changes from
--- the current one.
+-- Jumps back to the previous snippet placeholder, reverting any changes from the current one.
-- Returns `false` if no snippet is active.
-- @return `false` if no snippet is active; `nil` otherwise.
-- @name previous
function M.previous()
- if #stack > 0 then stack[#stack]:previous() else return false end
+ if #stack == 0 then return false end
+ stack[#stack]:previous()
end
---
@@ -608,12 +585,13 @@ end
-- @return `false` if no snippet is active; `nil` otherwise.
-- @name cancel_current
function M.cancel_current()
- if #stack > 0 then stack[#stack]:finish(true) else return false end
+ if #stack == 0 then return false end
+ stack[#stack]:finish(true)
end
---
--- Prompts the user to select a snippet to insert from a list of global and
--- language-specific snippets.
+-- Prompts the user to select a snippet to insert from a list of global and language-specific
+-- snippets.
-- @name select
function M.select()
local all_snippets, items = {}, {}
@@ -625,8 +603,7 @@ function M.select()
items[#items + 1], items[#items + 2] = trigger, all_snippets[trigger]
end
local button, i = ui.dialogs.filteredlist{
- title = _L['Select Snippet'], columns = {_L['Trigger'], _L['Snippet Text']},
- items = items
+ title = _L['Select Snippet'], columns = {_L['Trigger'], _L['Snippet Text']}, items = items
}
if button == 1 and i then M.insert(items[i * 2]) end
end
@@ -634,9 +611,7 @@ end
-- Update snippet transforms when text is added or deleted.
events.connect(events.UPDATE_UI, function(updated)
if #stack == 0 then return end
- if updated & buffer.UPDATE_CONTENT > 0 then
- stack[#stack]:update_transforms()
- end
+ if updated & buffer.UPDATE_CONTENT > 0 then stack[#stack]:update_transforms() end
if #keys.keychain == 0 then ui.statusbar_text = _L['Snippet active'] end
end)
@@ -645,8 +620,7 @@ events.connect(events.VIEW_NEW, function()
view.indic_style[INDIC_CURRENTPLACEHOLDER] = view.INDIC_HIDDEN
end)
--- Returns for the word behind the caret a list of snippet trigger word
--- completions.
+-- Returns for the word behind the caret a list of snippet trigger word completions.
-- @see textadept.editing.autocomplete
textadept.editing.autocompleters.snippet = function()
local list, trigger, snippets = {}, find_snippet(true)
@@ -657,8 +631,8 @@ textadept.editing.autocompleters.snippet = function()
end
---
--- Map of snippet triggers with their snippet text or functions that return such
--- text, with language-specific snippets tables assigned to a lexer name key.
+-- Map of snippet triggers with their snippet text or functions that return such text, with
+-- language-specific snippets tables assigned to a lexer name key.
-- @class table
-- @name _G.snippets
_G.snippets = snippets