aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/._m.luadoc5
-rw-r--r--core/.command_entry.luadoc12
-rw-r--r--core/.find.luadoc17
-rw-r--r--core/args.lua18
-rw-r--r--core/events.lua86
-rw-r--r--core/file_io.lua131
-rw-r--r--core/gui.lua24
-rw-r--r--core/init.lua8
-rw-r--r--[-rwxr-xr-x]core/locale.conf0
-rw-r--r--init.lua5
-rw-r--r--modules/lua/commands.lua20
-rw-r--r--modules/textadept/bookmarks.lua5
-rw-r--r--modules/textadept/command_entry.lua20
-rw-r--r--modules/textadept/editing.lua159
-rw-r--r--modules/textadept/find.lua50
-rw-r--r--modules/textadept/keys.lua241
-rw-r--r--modules/textadept/menu.lua50
-rw-r--r--modules/textadept/mime_types.lua1
-rw-r--r--[-rwxr-xr-x]modules/textadept/run.lua28
-rw-r--r--[-rwxr-xr-x]modules/textadept/session.lua12
-rw-r--r--[-rwxr-xr-x]modules/textadept/snapopen.lua6
-rw-r--r--[-rwxr-xr-x]modules/textadept/snippets.lua3
-rw-r--r--src/Makefile2
-rw-r--r--src/textadept.c3
-rw-r--r--themes/dark/buffer.lua6
-rw-r--r--themes/dark/view.lua10
-rw-r--r--themes/light/buffer.lua6
-rw-r--r--themes/light/view.lua10
-rw-r--r--themes/scite/buffer.lua6
-rw-r--r--themes/scite/view.lua4
30 files changed, 442 insertions, 506 deletions
diff --git a/core/._m.luadoc b/core/._m.luadoc
index d5f52a94..c8665fad 100644
--- a/core/._m.luadoc
+++ b/core/._m.luadoc
@@ -34,6 +34,11 @@ module('_m')
-- [m_cpp]: ../modules/_m.cpp.html
-- [m_lua]: ../modules/_m.lua.html
--
+-- For language modules that have a `set_buffer_properties` function, that
+-- function is called each time a file with that language is opened. This is
+-- useful for setting `buffer.use_tabs`, `buffer.tab_width`, etc. for different
+-- languages.
+--
-- Note: While language-specific modules can only be used by files of that
-- language, they persist in Textadept's Lua state. Because of this, it is not
-- recommended to set global functions or variables and depend on them, as they
diff --git a/core/.command_entry.luadoc b/core/.command_entry.luadoc
index 93615f22..e474fa13 100644
--- a/core/.command_entry.luadoc
+++ b/core/.command_entry.luadoc
@@ -37,6 +37,18 @@ module('gui.command_entry')
-- `modules/textadept/find.lua` for the implementation.
--
-- [inc_search]: ../modules/gui.find.html#incremental
+--
+-- ## Events
+--
+-- The following is a list of all command entry events generated in
+-- `event_name(arguments)` format:
+--
+-- * **command\_entry\_command** (command)<br />
+-- Called when a command is entered into the Command Entry.
+-- - command: the string command.
+-- * **command\_entry\_keypress** (code)<br />
+-- Called when a key is pressed in the Command Entry.
+-- - code: the key code (according to `<gdk/gdkkeysyms.h>`).
--- Focuses the command entry.
function focus() end
diff --git a/core/.find.luadoc b/core/.find.luadoc
index e47eafd9..038d3943 100644
--- a/core/.find.luadoc
+++ b/core/.find.luadoc
@@ -47,6 +47,23 @@ module('gui.find')
-- names of `textadept-find-entry` and `textadept-replace-entry` respectively.
--
-- [gtkrc]: http://library.gnome.org/devel/gtk/unstable/gtk-Resource-Files.html.
+--
+-- ## Events
+--
+-- The following is a list of all find events generated in
+-- `event_name(arguments)` format:
+--
+-- * **find** (text, next)<br />
+-- Called when attempting to finding text via the Find dialog box.
+-- - text: the text to search for.
+-- - next: flat indicating whether or not the search direction is forward.
+-- * **replace** (text)<br />
+-- Called when the found text is selected and asked to be replaced.
+-- - text: the text to replace the selected text with.
+-- * **replace\_all** (find\_text, repl\_text)<br />
+-- Called when all occurances of found text are to be replaced.
+-- - find\_text: the text to search for.
+-- - repl\_text: the text to replace found text with.
--- Displays and focuses the find/replace dialog.
function focus() end
diff --git a/core/args.lua b/core/args.lua
index cd1b682f..9535fa63 100644
--- a/core/args.lua
+++ b/core/args.lua
@@ -3,6 +3,18 @@
--- Processes command line arguments for Textadept.
module('args', package.seeall)
+-- Markdown:
+--
+-- ## Events
+--
+-- The following is a list of all arg events generated in
+-- `event_name(arguments)` format:
+--
+-- * **arg\_none** ()<br />
+-- Called when no command line args have been passed to Textadept on init.
+
+local arg = arg
+
-- Contains registered command line switches.
-- @class table
-- @name switches
@@ -17,8 +29,7 @@ local switches = {}
-- @param description Description of the switch.
function register(switch1, switch2, narg, f, description)
local t = { f, narg, description }
- switches[switch1] = t
- switches[switch2] = t
+ switches[switch1], switches[switch2] = t, t
end
---
@@ -47,6 +58,7 @@ function process()
if no_args then events.emit('arg_none') end
end
+-- Shows all registered command line switches in a help dialog.
local function show_help()
local line = "%s [%d args] -- %s"
local help = {}
@@ -64,7 +76,6 @@ register('-h', '--help', 0, show_help, 'Displays this')
-- For Windows, create arg table from single command line string (arg[0]).
if WIN32 and #arg[0] > 0 then
- local lpeg = require 'lpeg'
local P, C = lpeg.P, lpeg.C
local param = P('"') * C((1 - P('"'))^0) * '"' + C((1 - P(' '))^1)
local params = lpeg.match(lpeg.Ct(param * (P(' ')^1 * param)^0), arg[0])
@@ -79,7 +90,6 @@ for i = 1, #arg do
break
end
end
-local lfs = require 'lfs'
if not lfs.attributes(userhome) then lfs.mkdir(userhome) end
if not lfs.attributes(userhome..'/init.lua') then
local f = io.open(userhome..'/init.lua', 'w')
diff --git a/core/events.lua b/core/events.lua
index 2157f58d..a0cc2bdd 100644
--- a/core/events.lua
+++ b/core/events.lua
@@ -74,7 +74,7 @@ module('events', package.seeall)
--
-- [buffer_user_list_show]: ../modules/buffer.html#buffer:user_list_show
--
--- The following is a list of all Textadept events generated in
+-- The following is a list of gui events generated in
-- `event_name(arguments)` format:
--
-- * **buffer\_new** ()<br />
@@ -91,46 +91,25 @@ module('events', package.seeall)
-- Called right before another [view][view] is switched to.
-- * **view\_after\_switch** ()<br />
-- Called right after [view][view] was switched to.
--- * **reset\_before()**<br />
+-- * **reset\_before** ()<br />
-- Called before resetting the Lua state during a call to [`reset()`][reset].
--- * **reset\_after()**<br />
+-- * **reset\_after** ()<br />
-- Called after resetting the Lua state during a call to [`reset()`][reset].
-- * **quit** ()<br />
-- Called when quitting Textadept.<br />
-- Note: Any quit handlers added must be inserted at index 1 because the
-- default quit handler in `core/events.lua` returns `true`, which ignores all
-- subsequent handlers.
--- * **keypress** (code, shift, control, alt)<br />
--- Called when a key is pressed.
--- - code: the key code (according to `<gdk/gdkkeysyms.h>`).
--- - shift: flag indicating whether or not the Shift key is pressed.
--- - control: flag indicating whether or not the Control key is pressed.
--- - alt: flag indicating whether or not the Alt/Apple key is pressed.
--- <br />
--- Note: The Alt-Option key in Mac OSX is not available.
--- * **menu\_clicked** (menu\_id)<br />
--- Called when a menu item is selected.
--- - menu\_id: the numeric ID of the menu item set in
--- [`gui.gtkmenu()`][gui_gtkmenu].
--- * **find** (text, next)<br />
--- Called when attempting to finding text via the Find dialog box.
--- - text: the text to search for.
--- - next: flat indicating whether or not the search direction is forward.
--- * **replace** (text)<br />
--- Called when the found text is selected and asked to be replaced.
--- - text: the text to replace the selected text with.
--- * **replace\_all** (find\_text, repl\_text)<br />
--- Called when all occurances of found text are to be replaced.
--- - find\_text: the text to search for.
--- - repl\_text: the text to replace found text with.
--- * **command\_entry\_keypress** (code)<br />
--- Called when a key is pressed in the Command Entry.
--- - code: the key code (according to `<gdk/gdkkeysyms.h>`).
+-- * **error** (text)<br />
+-- Called when an error occurs in the C code.
+-- - text: The error text.
+-- * **appleevent\_odoc** (uri)<br />
+-- Called when Mac OSX instructs Textadept to open a document.
+-- - uri: The URI to open.
--
-- [buffer]: ../modules/buffer.html
-- [view]: ../modules/view.html
-- [reset]: ../modules/_G.html#reset
--- [gui_gtkmenu]: ../modules/gui.html#gtkmenu
--
-- ## Example
--
@@ -231,7 +210,7 @@ connect('view_new',
local buffer = buffer
local c = _SCINTILLA.constants
- -- allow redefinitions of these Scintilla key commands
+ -- Allow redefinitions of these Scintilla key commands.
local ctrl_keys = {
'[', ']', '/', '\\', 'Z', 'Y', 'X', 'C', 'V', 'A', 'L', 'T', 'D', 'U'
}
@@ -244,9 +223,9 @@ connect('view_new',
end
if _THEME and #_THEME > 0 then
- local ret, errmsg = pcall(dofile, _THEME..'/view.lua')
- if ret then return end
- io.stderr:write(errmsg)
+ local ok, err = pcall(dofile, _THEME..'/view.lua')
+ if ok then return end
+ io.stderr:write(err)
end
end)
@@ -258,14 +237,14 @@ connect('buffer_new',
local function run()
local buffer = buffer
- -- lexer
+ -- Lexer.
buffer:set_lexer_language('lpeg')
buffer:private_lexer_call(SETDIRECTFUNCTION, buffer.direct_function)
buffer:private_lexer_call(SETDIRECTPOINTER, buffer.direct_pointer)
buffer:private_lexer_call(SETLEXERLANGUAGE, 'container')
buffer.style_bits = 8
- -- properties
+ -- Properties.
buffer.property['textadept.home'] = _HOME
buffer.property['lexer.lpeg.home'] = _LEXERPATH
buffer.property['lexer.lpeg.script'] = _HOME..'/lexers/lexer.lua'
@@ -273,21 +252,21 @@ connect('buffer_new',
buffer.property['lexer.lpeg.color.theme'] = _THEME..'/lexer.lua'
end
- -- buffer
+ -- Buffer.
buffer.code_page = _SCINTILLA.constants.SC_CP_UTF8
if _THEME and #_THEME > 0 then
- local ret, errmsg = pcall(dofile, _THEME..'/buffer.lua')
- if ret then return end
- io.stderr:write(errmsg)
+ local ok, err = pcall(dofile, _THEME..'/buffer.lua')
+ if ok then return end
+ io.stderr:write(err)
end
end
- -- normally when an error occurs, a new buffer is created with the error
+ -- Normally when an error occurs, a new buffer is created with the error
-- message, but if an error occurs here, this event would be called again
-- and again, erroring each time resulting in an infinite loop; print error
- -- to stderr instead
- local ret, errmsg = pcall(run)
- if not ret then io.stderr:write(errmsg) end
+ -- to stderr instead.
+ local ok, err = pcall(run)
+ if not ok then io.stderr:write(err) end
end)
-- Sets the title of the Textadept window to the buffer's filename.
@@ -313,17 +292,13 @@ connect('save_point_left',
end)
connect('uri_dropped',
- function(utf8_uris)
- local lfs = require 'lfs'
- for utf8_uri in utf8_uris:gmatch('[^\r\n\f]+') do
+ function(utf8_uris) -- open uri(s)
+ for utf8_uri in utf8_uris:gmatch('[^\r\n]+') do
if utf8_uri:find('^file://') then
- utf8_uri = utf8_uri:match('^file://([^\r\n\f]+)')
+ utf8_uri = utf8_uri:match('^file://([^\r\n]+)')
utf8_uri = utf8_uri:gsub('%%(%x%x)',
function(hex) return string.char(tonumber(hex, 16)) end)
- if WIN32 then
- utf8_uri = utf8_uri:sub(2, -1) -- ignore leading '/'
- utf8_uri = utf8_uri:gsub('/', '\\')
- end
+ if WIN32 then utf8_uri = utf8_uri:sub(2, -1) end -- ignore leading '/'
local uri = utf8_uri:iconv(_CHARSET, 'UTF-8')
if lfs.attributes(uri).mode ~= 'directory' then
io.open_file(utf8_uri)
@@ -353,8 +328,7 @@ connect('update_ui',
connect('margin_click',
function(margin, modifiers, position) -- toggles folding
- local line = buffer:line_from_position(position)
- buffer:toggle_fold(line)
+ buffer:toggle_fold(buffer:line_from_position(position))
end)
connect('buffer_new', function() set_title(buffer) end)
@@ -405,15 +379,13 @@ connect('reset_after', function() gui.statusbar_text = 'Lua reset' end)
connect('quit',
function() -- prompts for confirmation if any buffers are dirty
- local any = false
local list = {}
for _, buffer in ipairs(_BUFFERS) do
if buffer.dirty then
list[#list + 1] = buffer.filename or buffer._type or L('Untitled')
- any = true
end
end
- if any and
+ if #list > 0 and
gui.dialog('msgbox',
'--title', L('Quit without saving?'),
'--text', L('The following buffers are unsaved:'),
diff --git a/core/file_io.lua b/core/file_io.lua
index 74d5b71f..fded1499 100644
--- a/core/file_io.lua
+++ b/core/file_io.lua
@@ -42,7 +42,7 @@ module('io', package.seeall)
--
-- ## Events
--
--- The following is a list of all File I/O events generated in
+-- The following is a list of all file I/O events generated in
-- `event_name(arguments)` format:
--
-- * **file\_opened** (filename) <br />
@@ -55,8 +55,6 @@ module('io', package.seeall)
-- Called when a file is saved under another filename.
-- - filename: the other filename encoded in UTF-8.
-local lfs = require 'lfs'
-
---
-- List of recently opened files.
-- @class table
@@ -84,13 +82,13 @@ local function detect_encoding(text)
if b1 == 239 and b2 == 187 and b3 == 191 then
return 'UTF-8', string.char(239, 187, 191)
elseif b1 == 254 and b2 == 255 then
- return 'UTF-16BE', boms[encoding]
+ return 'UTF-16BE', boms['UTF-16BE']
elseif b1 == 255 and b2 == 254 then
- return 'UTF-16LE', boms[encoding]
+ return 'UTF-16LE', boms['UTF-16LE']
elseif b1 == 0 and b2 == 0 and b3 == 254 and b4 == 255 then
- return 'UTF-32BE', boms[encoding]
+ return 'UTF-32BE', boms['UTF-32BE']
elseif b1 == 255 and b2 == 254 and b3 == 0 and b4 == 0 then
- return 'UTF-32LE', boms[encoding]
+ return 'UTF-32LE', boms['UTF-32LE']
else
local chunk = #text > 65536 and text:sub(1, 65536) or text
if chunk:find('\0') then return 'binary' end -- binary file
@@ -116,9 +114,9 @@ local function open_helper(utf8_filename)
if not utf8_filename then return end
utf8_filename = utf8_filename:gsub('^file://', '')
if WIN32 then utf8_filename = utf8_filename:gsub('/', '\\') end
- for index, buffer in ipairs(_BUFFERS) do
+ for i, buffer in ipairs(_BUFFERS) do
if utf8_filename == buffer.filename then
- view:goto_buffer(index)
+ view:goto_buffer(i)
return
end
end
@@ -126,58 +124,54 @@ local function open_helper(utf8_filename)
local text
local filename = utf8_filename:iconv(_CHARSET, 'UTF-8')
local f, err = io.open(filename, 'rb')
- if f then
- text = f:read('*all')
- f:close()
- if not text then return end -- filename exists, but can't read it
- else
- error(err)
- end
+ if not f then error(err) end
+ text = f:read('*all')
+ f:close()
+ if not text then return end -- filename exists, but can't read it
local buffer = new_buffer()
- if text then
- -- Tries to detect character encoding and convert text from it to UTF-8.
- local encoding, encoding_bom = detect_encoding(text)
- if encoding ~= 'binary' then
- if encoding then
- if encoding_bom then text = text:sub(#encoding_bom + 1, -1) end
- text = text:iconv('UTF-8', encoding)
- else
- -- Try list of encodings.
- for _, try_encoding in ipairs(try_encodings) do
- local ret, conv = pcall(string.iconv, text, 'UTF-8', try_encoding)
- if ret then
- encoding = try_encoding
- text = conv
- break
- end
+ -- Tries to detect character encoding and convert text from it to UTF-8.
+ local encoding, encoding_bom = detect_encoding(text)
+ if encoding ~= 'binary' then
+ if encoding then
+ if encoding_bom then text = text:sub(#encoding_bom + 1, -1) end
+ text = text:iconv('UTF-8', encoding)
+ else
+ -- Try list of encodings.
+ for _, try_encoding in ipairs(try_encodings) do
+ local ret, conv = pcall(string.iconv, text, 'UTF-8', try_encoding)
+ if ret then
+ encoding = try_encoding
+ text = conv
+ break
end
- if not encoding then error(L('Encoding conversion failed.')) end
end
- else
- encoding = nil
- end
- local c = _SCINTILLA.constants
- buffer.encoding, buffer.encoding_bom = encoding, encoding_bom
- buffer.code_page = encoding and c.SC_CP_UTF8 or 0
- -- Tries to set the buffer's EOL mode appropriately based on the file.
- local s, e = text:find('\r\n?')
- if s and e then
- buffer.eol_mode = (s == e and c.SC_EOL_CR or c.SC_EOL_CRLF)
- else
- buffer.eol_mode = c.SC_EOL_LF
+ if not encoding then error(L('Encoding conversion failed.')) end
end
- buffer:add_text(text, #text)
- buffer:goto_pos(0)
- buffer:empty_undo_buffer()
- buffer.modification_time = lfs.attributes(filename).modification
+ else
+ encoding = nil
+ end
+ local c = _SCINTILLA.constants
+ buffer.encoding, buffer.encoding_bom = encoding, encoding_bom
+ buffer.code_page = encoding and c.SC_CP_UTF8 or 0
+ -- Tries to set the buffer's EOL mode appropriately based on the file.
+ local s, e = text:find('\r\n?')
+ if s and e then
+ buffer.eol_mode = (s == e and c.SC_EOL_CR or c.SC_EOL_CRLF)
+ else
+ buffer.eol_mode = c.SC_EOL_LF
end
+ buffer:add_text(text, #text)
+ buffer:goto_pos(0)
+ buffer:empty_undo_buffer()
+ buffer.modification_time = lfs.attributes(filename).modification
buffer.filename = utf8_filename
buffer:set_save_point()
events.emit('file_opened', utf8_filename)
- for index, file in ipairs(recent_files) do
+ -- Add file to recent files list, eliminating duplicates.
+ for i, file in ipairs(recent_files) do
if file == utf8_filename then
- table.remove(recent_files, index)
+ table.remove(recent_files, i)
break
end
end
@@ -200,7 +194,7 @@ function open_file(utf8_filenames)
for filename in utf8_filenames:gmatch('[^\n]+') do open_helper(filename) end
end
--- LuaDoc is in core/.buffer.lua.
+-- LuaDoc is in core/.buffer.luadoc.
local function reload(buffer)
gui.check_focused_buffer(buffer)
if not buffer.filename then return end
@@ -222,7 +216,7 @@ local function reload(buffer)
buffer.modification_time = lfs.attributes(filename).modification
end
--- LuaDoc is in core/.buffer.lua.
+-- LuaDoc is in core/.buffer.luadoc.
local function set_encoding(buffer, encoding)
gui.check_focused_buffer(buffer)
if not buffer.encoding then error(L('Cannot change binary file encoding')) end
@@ -239,7 +233,7 @@ local function set_encoding(buffer, encoding)
buffer.encoding, buffer.encoding_bom = encoding, boms[encoding]
end
--- LuaDoc is in core/.buffer.lua.
+-- LuaDoc is in core/.buffer.luadoc.
local function save(buffer)
gui.check_focused_buffer(buffer)
if not buffer.filename then return buffer:save_as() end
@@ -251,18 +245,15 @@ local function save(buffer)
end
local filename = buffer.filename:iconv(_CHARSET, 'UTF-8')
local f, err = io.open(filename, 'wb')
- if f then
- f:write(text)
- f:close()
- buffer:set_save_point()
- buffer.modification_time = lfs.attributes(filename).modification
- else
- error(err)
- end
+ if not f then error(err) end
+ f:write(text)
+ f:close()
+ buffer:set_save_point()
+ buffer.modification_time = lfs.attributes(filename).modification
if buffer._type then buffer._type = nil end
end
--- LuaDoc is in core/.buffer.lua.
+-- LuaDoc is in core/.buffer.luadoc.
local function save_as(buffer, utf8_filename)
gui.check_focused_buffer(buffer)
if not utf8_filename then
@@ -287,15 +278,15 @@ end
function save_all()
local current_buffer = buffer
local current_index
- for index, buffer in ipairs(_BUFFERS) do
- view:goto_buffer(index)
- if buffer == current_buffer then current_index = index end
+ for i, buffer in ipairs(_BUFFERS) do
+ view:goto_buffer(i)
+ if buffer == current_buffer then current_index = i end
if buffer.filename and buffer.dirty then buffer:save() end
end
view:goto_buffer(current_index)
end
--- LuaDoc is in core/.buffer.lua.
+-- LuaDoc is in core/.buffer.luadoc.
local function close(buffer)
gui.check_focused_buffer(buffer)
if buffer.dirty and
@@ -325,8 +316,7 @@ function close_all()
view:goto_buffer(#_BUFFERS)
if not buffer:close() then return false end
end
- buffer:close() -- the last one
- return true
+ return buffer:close() -- the last one
end
-- Prompts the user to reload the current file if it has been modified outside
@@ -338,6 +328,7 @@ local function update_modified_file()
local attributes = lfs.attributes(filename)
if not attributes or not buffer.modification_time then return end
if buffer.modification_time < attributes.modification then
+ buffer.modification_time = attributes.modification
if gui.dialog('yesno-msgbox',
'--title', L('Reload?'),
'--text', L('Reload modified file?'),
@@ -347,8 +338,6 @@ local function update_modified_file()
'--no-cancel',
'--no-newline') == '1' then
buffer:reload()
- else
- buffer.modification_time = attributes.modification
end
end
end
diff --git a/core/gui.lua b/core/gui.lua
index ef9892cc..2e184beb 100644
--- a/core/gui.lua
+++ b/core/gui.lua
@@ -3,7 +3,7 @@
local L = _G.locale.localize
local gui = _G.gui
--- LuaDoc is in core/.gui.lua.
+-- LuaDoc is in core/.gui.luadoc.
function gui.check_focused_buffer(buffer)
if type(buffer) ~= 'table' or not buffer.doc_pointer then
error(L('Buffer argument expected.'), 2)
@@ -12,18 +12,17 @@ function gui.check_focused_buffer(buffer)
end
end
--- LuaDoc is in core/.gui.lua.
+-- LuaDoc is in core/.gui.luadoc.
function gui._print(buffer_type, ...)
local function safe_print(...)
- local message = table.concat({...}, '\t')
local message_buffer, message_buffer_index
local message_view, message_view_index
- for index, buffer in ipairs(_BUFFERS) do
+ for i, buffer in ipairs(_BUFFERS) do
if buffer._type == buffer_type then
- message_buffer, message_buffer_index = buffer, index
- for jndex, view in ipairs(_VIEWS) do
+ message_buffer, message_buffer_index = buffer, i
+ for j, view in ipairs(_VIEWS) do
if view.doc_pointer == message_buffer.doc_pointer then
- message_view, message_view_index = view, jndex
+ message_view, message_view_index = view, j
break
end
end
@@ -42,16 +41,17 @@ function gui._print(buffer_type, ...)
else
gui.goto_view(message_view_index, true)
end
- message_buffer:append_text(message..'\n')
+ message_buffer:append_text(table.concat({...}, '\t'))
+ message_buffer:append_text('\n')
message_buffer:set_save_point()
end
- pcall(safe_print, ...) -- prevent endless loops if this errors
+ pcall(safe_print, ...) -- prevent endless loops on error
end
--- LuaDoc is in core/.gui.lua.
+-- LuaDoc is in core/.gui.luadoc.
function gui.print(...) gui._print(L('[Message Buffer]'), ...) end
--- LuaDoc is in core/.gui.lua.
+-- LuaDoc is in core/.gui.luadoc.
function gui.switch_buffer()
local items = {}
for _, buffer in ipairs(_BUFFERS) do
@@ -68,5 +68,5 @@ function gui.switch_buffer()
'--columns', 'Name', 'File',
'--items', items)
local ok, i = response:match('(%-?%d+)\n(%d+)$')
- if ok and ok ~= '2' then view:goto_buffer(tonumber(i) + 1, true) end
+ if ok == '1' then view:goto_buffer(tonumber(i) + 1, true) end
end
diff --git a/core/init.lua b/core/init.lua
index 6f2dbedb..6cd82211 100644
--- a/core/init.lua
+++ b/core/init.lua
@@ -27,12 +27,12 @@ if not _THEME:find('[/\\]') then
if not lfs.attributes(_THEME) then _THEME = _HOME..'/themes/'..theme end
end
--- LuaDoc is in core/._G.lua.
+-- LuaDoc is in core/._G.luadoc.
function _G.user_dofile(filename)
if lfs.attributes(_USERHOME..'/'..filename) then
- local ret, errmsg = pcall(dofile, _USERHOME..'/'..filename)
- if not ret then gui.print(errmsg) end
- return ret
+ local ok, err = pcall(dofile, _USERHOME..'/'..filename)
+ if not ok then gui.print(err) end
+ return ok
end
return false
end
diff --git a/core/locale.conf b/core/locale.conf
index 2f87cfbc..2f87cfbc 100755..100644
--- a/core/locale.conf
+++ b/core/locale.conf
diff --git a/init.lua b/init.lua
index b262060c..94f2a687 100644
--- a/init.lua
+++ b/init.lua
@@ -1,14 +1,13 @@
-- Copyright 2007-2010 Mitchell mitchell<att>caladbolg.net. See LICENSE.
-local paths = {
+package.path = table.concat({
_USERHOME..'/?.lua',
_USERHOME..'/modules/?.lua',
_USERHOME..'/modules/?/init.lua',
_HOME..'/modules/?.lua',
_HOME..'/modules/?/init.lua',
package.path
-}
-package.path = table.concat(paths, ';')
+}, ';');
if not user_dofile('init.lua') then require 'textadept' end
diff --git a/modules/lua/commands.lua b/modules/lua/commands.lua
index e8c11773..4857126c 100644
--- a/modules/lua/commands.lua
+++ b/modules/lua/commands.lua
@@ -124,7 +124,6 @@ function goto_required()
end
if not file then return end
file = file:sub(2, -2):gsub('%.', '/')
- local lfs = require 'lfs'
for path in package.path:gmatch('[^;]+') do
path = path:gsub('?', file)
if lfs.attributes(path) then
@@ -137,6 +136,7 @@ end
events.connect('file_before_save',
function() -- show syntax errors as annotations
if buffer:get_lexer() == 'lua' then
+ local buffer = buffer
buffer:annotation_clear_all()
local text = buffer:get_text()
local _, err = loadstring(text)
@@ -169,7 +169,7 @@ local api_files = {
['view'] = _HOME..'/core/.view.luadoc',
}
-- Add API for loaded textadept modules.
-for p, _ in pairs(package.loaded) do
+for p in pairs(package.loaded) do
if p:find('^_m%.textadept%.') then
api_files[p] = _HOME..'/modules/textadept/'..p:match('[^%.]+$')..'.lua'
end
@@ -181,11 +181,9 @@ for _, m in ipairs(lua) do
end
api_files[''] = _HOME..'/modules/lua/api/_G.luadoc'
-local lfs = require 'lfs'
-
-- Load API.
local apis = {}
-local current_doc = ''
+local current_doc = {}
local f_args = {}
for word, api_file in pairs(api_files) do
if lfs.attributes(api_file) then
@@ -204,16 +202,17 @@ for word, api_file in pairs(api_files) do
local funcs = apis[word].funcs
funcs[#funcs + 1] = n..'?1'
if f and #current_doc > 0 then
- f = f..current_doc
- current_doc = ''
+ table.insert(current_doc, 1, f)
+ f = table.concat(current_doc, '\n')
+ current_doc = {}
end
local c = line:find(':') and ':' or '.'
if word == '' then c = '' end
f_args[word..c..n] = f
elseif line:match('^%-%-%-? (.+)$') then
- current_doc = current_doc..'\n'..line:match('^%-%-%-? (.+)$')
+ current_doc[#current_doc + 1] = line:match('^%-%-%-? (.+)$')
elseif #current_doc > 0 then
- current_doc = ''
+ current_doc = {}
end
end
table.sort(apis[word].fields)
@@ -229,6 +228,7 @@ local v_xpm = '/* XPM */\nstatic char *field[] = {\n/* columns rows colors chars
-- @param pos Optional position to start from.
-- @return word.
local function prev_word(patt, pos)
+ local buffer = buffer
local e = pos or buffer.current_pos - 1
local s = e - 1
while s >= 0 and string.char(buffer.char_at[s]):find(patt) do s = s - 1 end
@@ -240,6 +240,7 @@ end
-- @param completions Table of completions.
-- @see buffer:auto_c_show.
local function auto_c_show(len, completions)
+ local buffer = buffer
buffer:clear_registered_images()
buffer:register_image(1, f_xpm)
buffer:register_image(2, v_xpm)
@@ -267,6 +268,7 @@ if type(keys) == 'table' then
},
['\n'] = { try_to_autocomplete_end },
[not OSX and 'c\n' or 'esc'] = { function() -- complete API
+ local buffer = buffer
local part = prev_word('[%w_]', buffer.current_pos)
local pos = buffer.current_pos - #part - 1
if pos > 0 then
diff --git a/modules/textadept/bookmarks.lua b/modules/textadept/bookmarks.lua
index 581390d4..bc5eac9b 100644
--- a/modules/textadept/bookmarks.lua
+++ b/modules/textadept/bookmarks.lua
@@ -49,10 +49,7 @@ end
---
-- Clears all bookmarks in the current buffer.
-function clear()
- local buffer = buffer
- buffer:marker_delete_all(MARK_BOOKMARK)
-end
+function clear() buffer:marker_delete_all(MARK_BOOKMARK) end
---
-- Goes to the next bookmark in the current buffer.
diff --git a/modules/textadept/command_entry.lua b/modules/textadept/command_entry.lua
index c18550e9..d8a48616 100644
--- a/modules/textadept/command_entry.lua
+++ b/modules/textadept/command_entry.lua
@@ -3,6 +3,9 @@
local locale = _G.locale
+-- Environment for abbreviated commands.
+-- @class table
+-- @name env
local env = setmetatable({}, {
__index = function(t, k)
local f = buffer[k]
@@ -46,37 +49,38 @@ events.connect('command_entry_keypress',
local path, o, prefix = substring:match('^([%w_.:]-)([.:]?)([%w_]*)$')
local f, err = loadstring('return ('..path..')')
if type(f) == "function" then setfenv(f, env) end
- local ret, tbl = pcall(f)
+ local ok, tbl = pcall(f)
local cmpls = {}
- if not ret then -- shorthand notation
+ prefix = '^'..prefix
+ if not ok then -- shorthand notation
for _, t in ipairs{ buffer, view, gui, _G } do
for k in pairs(t) do
- if type(k) == 'string' and k:find('^'..prefix) then
+ if type(k) == 'string' and k:find(prefix) then
cmpls[#cmpls + 1] = k
end
end
end
for f in pairs(_SCINTILLA.functions) do
- if f:find('^'..prefix) then cmpls[#cmpls + 1] = f end
+ if f:find(prefix) then cmpls[#cmpls + 1] = f end
end
for p in pairs(_SCINTILLA.properties) do
- if p:find('^'..prefix) then cmpls[#cmpls + 1] = p end
+ if p:find(prefix) then cmpls[#cmpls + 1] = p end
end
else
if type(tbl) ~= 'table' then return end
for k in pairs(tbl) do
- if type(k) == 'string' and k:find('^'..prefix) then
+ if type(k) == 'string' and k:find(prefix) then
cmpls[#cmpls + 1] = k
end
end
if path == 'buffer' then
if o == ':' then
for f in pairs(_SCINTILLA.functions) do
- if f:find('^'..prefix) then cmpls[#cmpls + 1] = f end
+ if f:find(prefix) then cmpls[#cmpls + 1] = f end
end
else
for p in pairs(_SCINTILLA.properties) do
- if p:find('^'..prefix) then cmpls[#cmpls + 1] = p end
+ if p:find(prefix) then cmpls[#cmpls + 1] = p end
end
end
end
diff --git a/modules/textadept/editing.lua b/modules/textadept/editing.lua
index c2b06ba0..12c72d05 100644
--- a/modules/textadept/editing.lua
+++ b/modules/textadept/editing.lua
@@ -52,28 +52,10 @@ INDIC_HIGHLIGHT_ALPHA = 100
-- @see block_comment
comment_string = {}
----
--- Enclosures for enclosing or selecting ranges of text.
--- Note chars and tag enclosures are generated at runtime.
--- You can add entries to the table in language-specific modules and use the
--- 'enclose' function in key commands.
--- @class table
--- @name enclosure
--- @see enclose
-enclosure = {
- dbl_quotes = { left = '"', right = '"' },
- sng_quotes = { left = "'", right = "'" },
- parens = { left = '(', right = ')' },
- brackets = { left = '[', right = ']' },
- braces = { left = '{', right = '}' },
- chars = { left = ' ', right = ' ' },
- tags = { left = '>', right = '<' },
- tag = { left = ' ', right = ' ' },
- single_tag = { left = '<', right = ' />' }
-}
-
-- Character matching.
-- Used for auto-matching parentheses, brackets, braces, and quotes.
+-- @class table
+-- @name char_matches
local char_matches = {
[40] = ')', [91] = ']', [123] = '}',
[39] = "'", [34] = '"'
@@ -81,6 +63,8 @@ local char_matches = {
-- Brace characters.
-- Used for going to matching brace positions.
+-- @class table
+-- @name braces
local braces = { -- () [] {} <>
[40] = 1, [91] = 1, [123] = 1, [60] = 1,
[41] = 1, [93] = 1, [125] = 1, [62] = 1,
@@ -88,6 +72,8 @@ local braces = { -- () [] {} <>
-- The current call tip.
-- Used for displaying call tips.
+-- @class table
+-- @name current_call_tip
local current_call_tip = {}
events.connect('char_added',
@@ -99,21 +85,20 @@ events.connect('char_added',
events.connect('keypress',
function(code, shift, control, alt) -- removes matched chars on backspace
- if AUTOPAIR and code == 0xff08 and buffer.selections == 1 then
- local buffer = buffer
- local current_pos = buffer.current_pos
- local c = buffer.char_at[current_pos - 1]
- if char_matches[c] and
- buffer.char_at[current_pos] == string.byte(char_matches[c]) then
- buffer:clear()
- end
+ if not AUTOPAIR or code ~= 0xff08 or buffer.selections ~= 1 then return end
+ local buffer = buffer
+ local current_pos = buffer.current_pos
+ local c = buffer.char_at[current_pos - 1]
+ if char_matches[c] and
+ buffer.char_at[current_pos] == string.byte(char_matches[c]) then
+ buffer:clear()
end
end)
events.connect('update_ui',
function() -- highlights matching braces
- local buffer = buffer
if not HIGHLIGHT_BRACES then return end
+ local buffer = buffer
local current_pos = buffer.current_pos
if braces[buffer.char_at[current_pos]] and
buffer:get_style_name(buffer.style_at[current_pos]) == 'operator' then
@@ -133,16 +118,14 @@ events.connect('char_added',
if not AUTOINDENT or char ~= 10 then return end
local buffer = buffer
local anchor, caret = buffer.anchor, buffer.current_pos
- local curr_line = buffer:line_from_position(caret)
- local last_line = curr_line - 1
- while last_line >= 0 and #buffer:get_line(last_line) == 1 do
- last_line = last_line - 1
- end
- if last_line >= 0 then
- local indentation = buffer.line_indentation[last_line]
- local s = buffer.line_indent_position[curr_line]
- buffer.line_indentation[curr_line] = indentation
- local e = buffer.line_indent_position[curr_line]
+ local line = buffer:line_from_position(caret)
+ local pline = line - 1
+ while pline >= 0 and #buffer:get_line(pline) == 1 do pline = pline - 1 end
+ if pline >= 0 then
+ local indentation = buffer.line_indentation[pline]
+ local s = buffer.line_indent_position[line]
+ buffer.line_indentation[line] = indentation
+ local e = buffer.line_indent_position[line]
local diff = e - s
if e > s then -- move selection on
if anchor >= s then anchor = anchor + diff end
@@ -179,6 +162,7 @@ end
-- Pops up an autocompletion list for the current word based on other words in
-- the document.
-- @param word_chars String of chars considered to be part of words.
+-- @return true if there were completions to show; false otherwise.
function autocomplete_word(word_chars)
local buffer = buffer
local caret, length = buffer.current_pos, buffer.length
@@ -241,7 +225,6 @@ end
-- Goes to the requested line.
-- @param line Optional line number to go to.
function goto_line(line)
- local buffer = buffer
if not line then
line = gui.dialog('standard-inputbox',
'--title', L('Go To'),
@@ -259,8 +242,8 @@ end
-- Strips trailing whitespace off of every line, ensures an ending newline, and
-- converts non-consistent EOLs.
function prepare_for_save()
- local buffer = buffer
if not SAVE_STRIPS_WS then return end
+ local buffer = buffer
buffer:begin_undo_action()
-- Strip trailing whitespace.
local lines = buffer.line_count
@@ -304,27 +287,21 @@ end
---
-- Transposes characters intelligently.
--- If the caret is at the end of the current word, the two characters before
--- the caret are transposed. Otherwise the characters to the left and right of
--- the caret are transposed.
+-- If the caret is at the end of a line, the two characters before the caret are
+-- transposed. Otherwise, the characters to the left and right are.
function transpose_chars()
local buffer = buffer
buffer:begin_undo_action()
- local caret = buffer.current_pos
- local char = buffer.char_at[caret - 1]
+ local pos = buffer.current_pos
+ local c1, c2 = buffer.char_at[pos - 1], buffer.char_at[pos]
buffer:delete_back()
- if caret > buffer.length or buffer.char_at[caret - 1] == 32 then
- buffer:char_left()
- else
- buffer:char_right()
- end
- buffer:insert_text(-1, string.char(char))
+ buffer:insert_text((c2 == 10 or c2 == 13) and pos - 2 or pos, string.char(c1))
buffer:end_undo_action()
- buffer:goto_pos(caret)
+ buffer:goto_pos(pos)
end
---
--- Joins the current line with the line below, eliminating whitespace.
+-- Joins the current line with the line below.
function join_lines()
local buffer = buffer
buffer:line_end()
@@ -334,77 +311,33 @@ function join_lines()
buffer:lines_join()
end
--- Returns the number to the left of the caret.
--- This is used for the enclose function.
--- @see enclose
-local function get_preceding_number()
- local buffer = buffer
- local caret = buffer.current_pos
- local char = buffer.char_at[caret - 1]
- local txt = ''
- while tonumber(string.char(char)) do
- txt = txt..string.char(char)
- caret = caret - 1
- char = buffer.char_at[caret - 1]
- end
- return tonumber(txt) or 1, #txt
-end
-
---
--- Encloses text in an enclosure set.
+-- Encloses text within a given pair of strings.
-- If text is selected, it is enclosed. Otherwise, the previous word is
--- enclosed. The n previous words can be enclosed by appending n (a number) to
--- the end of the last word. When enclosing with a character, append the
--- character to the end of the word(s). To enclose previous word(s) with n
--- characters, append n (a number) to the end of character set.
--- Examples:
--- enclose this2 -> 'enclose this' (enclose in sng_quotes)
--- enclose this2**2 -> **enclose this**
--- @param str The enclosure type in enclosure.
--- @see enclosure
--- @see get_preceding_number
-function enclose(str)
+-- enclosed.
+-- @param left The left part of the enclosure.
+-- @param right The right part of the enclosure.
+function enclose(left, right)
local buffer = buffer
buffer:begin_undo_action()
local txt = buffer:get_sel_text()
- if txt == '' then
- if str == 'chars' then
- local num_chars, len_num_chars = get_preceding_number()
- for i = 1, len_num_chars do buffer:delete_back() end
- for i = 1, num_chars do buffer:char_left_extend() end
- enclosure[str].left = buffer:get_sel_text()
- enclosure[str].right = enclosure[str].left
- buffer:delete_back()
- end
- local num_words, len_num_chars = get_preceding_number()
- for i = 1, len_num_chars do buffer:delete_back() end
- for i = 1, num_words do buffer:word_left_extend() end
+ if #txt == 0 then
+ buffer:word_left_extend()
txt = buffer:get_sel_text()
end
- local len = 0
- if str == 'tag' then
- enclosure[str].left = '<'..txt..'>'
- enclosure[str].right = '</'..txt..'>'
- len = #txt + 3
- txt = ''
- end
- local left = enclosure[str].left
- local right = enclosure[str].right
buffer:replace_sel(left..txt..right)
- if str == 'tag' then buffer:goto_pos(buffer.current_pos - len) end
buffer:end_undo_action()
end
---
--- Selects text in a specified enclosure.
--- @param str The enclosure type in enclosure.
--- @see enclosure
-function select_enclosed(str)
- if not str then return end
+-- Selects text between a given pair of strings.
+-- @param left The left part of the enclosure.
+-- @param right The right part of the enclosure.
+function select_enclosed(left, right)
local buffer = buffer
buffer:search_anchor()
- local s = buffer:search_prev(0, enclosure[str].left)
- local e = buffer:search_next(0, enclosure[str].right)
+ local s = buffer:search_prev(0, left)
+ local e = buffer:search_next(0, right)
if s and e then buffer:set_sel(s + 1, e) end
end
@@ -424,7 +357,6 @@ end
---
-- Selects the current line.
function select_line()
- local buffer = buffer
buffer:home()
buffer:line_end_extend()
end
@@ -433,7 +365,6 @@ end
-- Selects the current paragraph.
-- Paragraphs are delimited by two or more consecutive newlines.
function select_paragraph()
- local buffer = buffer
buffer:para_up()
buffer:para_down_extend()
end
@@ -467,7 +398,7 @@ function select_indented_block()
end
---
--- Selects all text with the same scope/style as under the caret.
+-- Selects all text with the same style as under the caret.
function select_scope()
local buffer = buffer
local start_pos = buffer.current_pos
diff --git a/modules/textadept/find.lua b/modules/textadept/find.lua
index db34358c..202f7b49 100644
--- a/modules/textadept/find.lua
+++ b/modules/textadept/find.lua
@@ -4,19 +4,19 @@ local L = _G.locale.localize
local events = _G.events
local find = gui.find
-local lfs = require 'lfs'
-
local MARK_FIND = 0
local MARK_FIND_COLOR = 0x4D9999
local previous_view
-- Text escape sequences with their associated characters.
+-- @class table
+-- @name escapes
local escapes = {
['\\a'] = '\a', ['\\b'] = '\b', ['\\f'] = '\f', ['\\n'] = '\n',
['\\r'] = '\r', ['\\t'] = '\t', ['\\v'] = '\v', ['\\\\'] = '\\'
}
--- LuaDoc is in core/.find.luadoc
+-- LuaDoc is in core/.find.luadoc.
function find.find_in_files(utf8_dir)
if not utf8_dir then
utf8_dir = gui.dialog('fileselect',
@@ -26,13 +26,12 @@ function find.find_in_files(utf8_dir)
(buffer.filename or ''):match('^.+[/\\]') or '',
'--no-newline')
end
- local text = find.find_entry_text
if #utf8_dir > 0 then
+ local text = find.find_entry_text
if not find.lua then text = text:gsub('([().*+?^$%%[%]-])', '%%%1') end
if not find.match_case then text = text:lower() end
if find.whole_word then text = '[^%W_]'..text..'[^%W_]' end
- local match_case = find.match_case
- local whole_word = find.whole_word
+ local match_case, whole_word = find.match_case, find.whole_word
local string_find, format = string.find, string.format
local matches = { 'Find: '..text }
function search_file(file)
@@ -48,11 +47,12 @@ function find.find_in_files(utf8_dir)
line_num = line_num + 1
end
end
+ local lfs_dir, lfs_attributes = lfs.dir, lfs.attributes
function search_dir(directory)
- for file in lfs.dir(directory) do
+ for file in lfs_dir(directory) do
if not file:find('^%.%.?$') then -- ignore . and ..
local path = directory..'/'..file
- local type = lfs.attributes(path).mode
+ local type = lfs_attributes(path).mode
if type == 'directory' then
search_dir(path)
elseif type == 'file' then
@@ -108,11 +108,7 @@ local function find_(text, next, flags, nowrap, wrapped)
if flags < 8 then
buffer:goto_pos(buffer[next and 'current_pos' or 'anchor'] + increment)
buffer:search_anchor()
- if next then
- result = buffer:search_next(flags, text)
- else
- result = buffer:search_prev(flags, text)
- end
+ result = buffer['search_'..(next and 'next' or 'prev')](buffer, flags, text)
if result ~= -1 then buffer:scroll_caret() end
elseif flags < 16 then -- lua pattern search (forward search only)
@@ -128,17 +124,13 @@ local function find_(text, next, flags, nowrap, wrapped)
end
else -- find in files
- find_in_files()
+ find.find_in_files()
return
end
if result == -1 and not nowrap and not wrapped then -- wrap the search
local anchor, pos = buffer.anchor, buffer.current_pos
- if next or flags >= 8 then
- buffer:goto_pos(0)
- else
- buffer:goto_pos(buffer.length)
- end
+ buffer:goto_pos((next or flags >= 8) and 0 or buffer.length)
gui.statusbar_text = L('Search wrapped')
result = find_(text, next, flags, true, true)
if result == -1 then
@@ -162,12 +154,11 @@ events.connect('find', find_)
local function find_incremental(text)
local c = _SCINTILLA.constants
local flags = find.match_case and c.SCFIND_MATCHCASE or 0
- --if find.lua then flags = flags + 8 end
buffer:goto_pos(find.incremental_start or 0)
find_(text, true, flags)
end
--- LuaDoc is in core/.find.lua.
+-- LuaDoc is in core/.find.luadoc.
function find.find_incremental()
find.incremental = true
find.incremental_start = buffer.current_pos
@@ -220,10 +211,10 @@ local function replace(rtext)
rtext = rtext:gsub('%%'..i, v)
end
end
- local ret, rtext = pcall(rtext.gsub, rtext, '%%(%b())',
+ local ok, rtext = pcall(rtext.gsub, rtext, '%%(%b())',
function(code)
- local ret, val = pcall(loadstring('return '..code))
- if not ret then
+ local ok, val = pcall(loadstring('return '..code))
+ if not ok then
gui.dialog('ok-msgbox',
'--title', L('Error'),
'--text', L('An error occured:'),
@@ -233,7 +224,7 @@ local function replace(rtext)
end
return val
end)
- if ret then
+ if ok then
rtext = rtext:gsub('\\037', '%%') -- unescape '%'
buffer:replace_target(rtext:gsub('\\[abfnrtv\\]', escapes))
buffer:goto_pos(buffer.target_end) -- 'find' text after this replacement
@@ -287,8 +278,7 @@ local function replace_all(ftext, rtext, flags)
buffer:set_sel(anchor, current_pos)
buffer:marker_delete_handle(end_marker)
end
- gui.statusbar_text = string.format("%d %s", tostring(count),
- L('replacement(s) made'))
+ gui.statusbar_text = string.format("%d %s", count, L('replacement(s) made'))
buffer:end_undo_action()
end
events.connect('replace_all', replace_all)
@@ -312,8 +302,8 @@ local function goto_file(pos, line_num)
local clicked_view = view
if previous_view then previous_view:focus() end
if buffer._type == L('[Files Found Buffer]') then
- -- there are at least two find in files views; find one of those views
- -- that the file was not selected from and focus it
+ -- There are at least two find in files views; find one of those views
+ -- that the file was not selected from and focus it.
for _, v in ipairs(_VIEWS) do
if v ~= clicked_view then
previous_view = v
@@ -331,7 +321,7 @@ local function goto_file(pos, line_num)
end
events.connect('double_click', goto_file)
--- LuaDoc is in core/.find.lua.
+-- LuaDoc is in core/.find.luadoc.
function find.goto_file_in_list(next)
local orig_view = view
for _, buffer in ipairs(_BUFFERS) do
diff --git a/modules/textadept/keys.lua b/modules/textadept/keys.lua
index 67512b51..ad4ed760 100644
--- a/modules/textadept/keys.lua
+++ b/modules/textadept/keys.lua
@@ -87,18 +87,18 @@ module('_m.textadept.keys', package.seeall)
-- ['ctrl+b'] = { 'char_left', 'buffer' },
-- lua = {
-- ['ctrl+c'] = { 'add_text', 'buffer', '-- ' },
--- whitespace = {
--- ['ctrl+f'] = { function() print('whitespace') end }
+-- comment = {
+-- ['ctrl+f'] = { function() print('comment') end }
-- }
-- }
-- }
--
-- The first two key commands are global and call `buffer:char_right()` and
-- `buffer:char_left()` respectively. The last two commands apply only in the
--- Lua lexer with the very last one only being available in Lua's `whitespace`
--- style. If `ctrl+f` is pressed when the current style is `whitespace` in the
+-- Lua lexer with the very last one only being available in Lua's `comment`
+-- style. If `ctrl+f` is pressed when the current style is `comment` in the
-- `lua` lexer, the global key command with the same shortcut is overridden and
--- `whitespace` is printed to standard out.
+-- `comment` is printed to standard out.
--
-- ## Problems
--
@@ -114,6 +114,20 @@ module('_m.textadept.keys', package.seeall)
-- Windows and Linux key commands are listed in the first block.
-- Mac OSX key commands are listed in the second block.
+--
+-- ## Events
+--
+-- The following is a list of all key events generated in
+-- `event_name(arguments)` format:
+--
+-- * **keypress** (code, shift, control, alt)<br />
+-- Called when a key is pressed.
+-- - code: the key code (according to `<gdk/gdkkeysyms.h>`).
+-- - shift: flag indicating whether or not the Shift key is pressed.
+-- - control: flag indicating whether or not the Control key is pressed.
+-- - alt: flag indicating whether or not the Alt/Apple key is pressed.
+-- <br />
+-- Note: The Alt-Option key in Mac OSX is not available.
-- settings
local SCOPES_ENABLED = true
@@ -127,6 +141,46 @@ local keys = _M
local b, v = 'buffer', 'view'
local gui = gui
+-- Utility functions used by both layouts.
+local function enclose_in_tag()
+ m_editing.enclose('<', '>')
+ local buffer = buffer
+ local pos = buffer.current_pos
+ while buffer.char_at[pos - 1] ~= 60 do pos = pos - 1 end -- '<'
+ buffer:insert_text(-1, '</'..buffer:text_range(pos, buffer.current_pos))
+end
+local function any_char_mt(f)
+ return setmetatable({['\0'] = {}}, {
+ __index = function(t, k)
+ if #k == 1 then return { f, k, k } end
+ end })
+end
+local function toggle_setting(setting)
+ local state = buffer[setting]
+ if type(state) == 'boolean' then
+ buffer[setting] = not state
+ elseif type(state) == 'number' then
+ buffer[setting] = buffer[setting] == 0 and 1 or 0
+ end
+ events.emit('update_ui') -- for updating statusbar
+end
+local RECENT_FILES = 1
+events.connect('user_list_selection',
+ function(type, text)
+ if type == RECENT_FILES then io.open_file(text) end
+ end)
+local function show_recent_file_list()
+ local buffer = buffer
+ local files = {}
+ for _, filename in ipairs(io.recent_files) do
+ table.insert(files, 1, filename)
+ end
+ local sep = buffer.auto_c_separator
+ buffer.auto_c_separator = ('|'):byte()
+ buffer:user_list_show(RECENT_FILES, table.concat(files, '|'))
+ buffer.auto_c_separator = sep
+end
+
-- CTRL = 'c'
-- SHIFT = 's'
-- ALT = 'a'
@@ -172,38 +226,39 @@ if not OSX then
keys.cv = { 'paste', b }
-- Delete is delete.
keys.ca = { 'select_all', b }
- keys.ce = { m_editing.match_brace }
- keys.cE = { m_editing.match_brace, 'select' }
- keys['c\n'] = { m_editing.autocomplete_word, '%w_' }
+ keys.ce = { m_editing.match_brace }
+ keys.cE = { m_editing.match_brace, 'select' }
+ keys['c\n'] = { m_editing.autocomplete_word, '%w_' }
keys['c\n\r'] = { m_editing.autocomplete_word, '%w_' } -- win32
- keys.cq = { m_editing.block_comment }
+ keys.cq = { m_editing.block_comment }
-- TODO: { m_editing.current_word, 'delete' }
keys.ch = { m_editing.highlight_word }
-- TODO: { m_editing.transpose_chars }
-- TODO: { m_editing.convert_indentation }
keys.ac = { -- enClose in...
- t = { m_editing.enclose, 'tag' },
- T = { m_editing.enclose, 'single_tag' },
- ['"'] = { m_editing.enclose, 'dbl_quotes' },
- ["'"] = { m_editing.enclose, 'sng_quotes' },
- ['('] = { m_editing.enclose, 'parens' },
- ['['] = { m_editing.enclose, 'brackets' },
- ['{'] = { m_editing.enclose, 'braces' },
- c = { m_editing.enclose, 'chars' },
+ t = { enclose_in_tag },
+ T = { m_editing.enclose, '<', ' />' },
+ ['"'] = { m_editing.enclose, '"', '"' },
+ ["'"] = { m_editing.enclose, "'", "'" },
+ ['('] = { m_editing.enclose, '(', ')' },
+ ['['] = { m_editing.enclose, '[', ']' },
+ ['{'] = { m_editing.enclose, '{', '}' },
+ c = any_char_mt(m_editing.enclose),
}
keys.as = { -- select in...
- t = { m_editing.select_enclosed, 'tags' },
- ['"'] = { m_editing.select_enclosed, 'dbl_quotes' },
- ["'"] = { m_editing.select_enclosed, 'sng_quotes' },
- ['('] = { m_editing.select_enclosed, 'parens' },
- ['['] = { m_editing.select_enclosed, 'brackets' },
- ['{'] = { m_editing.select_enclosed, 'braces' },
- w = { m_editing.current_word, 'select' },
- l = { m_editing.select_line },
- p = { m_editing.select_paragraph },
- b = { m_editing.select_indented_block },
- s = { m_editing.select_scope },
- g = { m_editing.grow_selection, 1 },
+ t = { m_editing.select_enclosed, '>', '<' },
+ ['"'] = { m_editing.select_enclosed, '"', '"' },
+ ["'"] = { m_editing.select_enclosed, "'", "'" },
+ ['('] = { m_editing.select_enclosed, '(', ')' },
+ ['['] = { m_editing.select_enclosed, '[', ']' },
+ ['{'] = { m_editing.select_enclosed, '{', '}' },
+ w = { m_editing.current_word, 'select' },
+ l = { m_editing.select_line },
+ p = { m_editing.select_paragraph },
+ b = { m_editing.select_indented_block },
+ s = { m_editing.select_scope },
+ g = { m_editing.grow_selection, 1 },
+ c = any_char_mt(m_editing.select_enclosed),
}
-- Search
@@ -236,15 +291,6 @@ if not OSX then
keys.cb = { gui.switch_buffer }
keys['c\t'] = { 'goto_buffer', v, 1, false }
keys['cs\t'] = { 'goto_buffer', v, -1, false }
- local function toggle_setting(setting)
- local state = buffer[setting]
- if type(state) == 'boolean' then
- buffer[setting] = not state
- elseif type(state) == 'number' then
- buffer[setting] = buffer[setting] == 0 and 1 or 0
- end
- events.emit('update_ui') -- for updating statusbar
- end
keys.ct.v = {
e = { toggle_setting, 'view_eol' },
w = { toggle_setting, 'wrap_mode' },
@@ -269,25 +315,7 @@ if not OSX then
keys.c0 = { function() buffer.zoom = 0 end }
-- Miscellaneous not in standard menu.
- -- Recent files.
- local RECENT_FILES = 1
- events.connect('user_list_selection',
- function(type, text)
- if type == RECENT_FILES then io.open_file(text) end
- end)
- keys.ao = {
- function()
- local buffer = buffer
- local files = {}
- for _, filename in ipairs(io.recent_files) do
- table.insert(files, 1, filename)
- end
- local sep = buffer.auto_c_separator
- buffer.auto_c_separator = ('|'):byte()
- buffer:user_list_show(RECENT_FILES, table.concat(files, '|'))
- buffer.auto_c_separator = sep
- end
- }
+ keys.ao = { show_recent_file_list }
else
-- Mac OSX key commands
@@ -336,36 +364,36 @@ else
keys.ct = { m_editing.transpose_chars }
-- TODO: { m_editing.convert_indentation }
keys.cc = { -- enClose in...
- t = { m_editing.enclose, 'tag' },
- T = { m_editing.enclose, 'single_tag' },
- ['"'] = { m_editing.enclose, 'dbl_quotes' },
- ["'"] = { m_editing.enclose, 'sng_quotes' },
- ['('] = { m_editing.enclose, 'parens' },
- ['['] = { m_editing.enclose, 'brackets' },
- ['{'] = { m_editing.enclose, 'braces' },
- c = { m_editing.enclose, 'chars' },
+ t = { enclose_in_tag },
+ T = { m_editing.enclose, '<', ' />' },
+ ['"'] = { m_editing.enclose, '"', '"' },
+ ["'"] = { m_editing.enclose, "'", "'" },
+ ['('] = { m_editing.enclose, '(', ')' },
+ ['['] = { m_editing.enclose, '[', ']' },
+ ['{'] = { m_editing.enclose, '{', '}' },
+ c = any_char_mt(m_editing.enclose),
}
keys.cs = { -- select in...
- e = { m_editing.select_enclosed },
- t = { m_editing.select_enclosed, 'tags' },
- ['"'] = { m_editing.select_enclosed, 'dbl_quotes' },
- ["'"] = { m_editing.select_enclosed, 'sng_quotes' },
- ['('] = { m_editing.select_enclosed, 'parens' },
- ['['] = { m_editing.select_enclosed, 'brackets' },
- ['{'] = { m_editing.select_enclosed, 'braces' },
- w = { m_editing.current_word, 'select' },
- l = { m_editing.select_line },
- p = { m_editing.select_paragraph },
- b = { m_editing.select_indented_block },
- s = { m_editing.select_scope },
- g = { m_editing.grow_selection, 1 },
+ t = { m_editing.select_enclosed, '>', '<' },
+ ['"'] = { m_editing.select_enclosed, '"', '"' },
+ ["'"] = { m_editing.select_enclosed, "'", "'" },
+ ['('] = { m_editing.select_enclosed, '(', ')' },
+ ['['] = { m_editing.select_enclosed, '[', ']' },
+ ['{'] = { m_editing.select_enclosed, '{', '}' },
+ w = { m_editing.current_word, 'select' },
+ l = { m_editing.select_line },
+ p = { m_editing.select_paragraph },
+ b = { m_editing.select_indented_block },
+ s = { m_editing.select_scope },
+ g = { m_editing.grow_selection, 1 },
+ c = any_char_mt(m_editing.select_enclosed),
}
-- Search
- keys.af = { gui.find.focus } -- find/replace
- keys.ag = { gui.find.find_next }
- keys.aG = { gui.find.find_prev }
- keys.ar = { gui.find.replace }
+ keys.af = { gui.find.focus } -- find/replace
+ keys.ag = { gui.find.find_next }
+ keys.aG = { gui.find.find_prev }
+ keys.ar = { gui.find.replace }
keys.ai = { gui.find.find_incremental }
keys.aF = {
function()
@@ -375,7 +403,7 @@ else
}
keys.cag = { gui.find.goto_file_in_list, true }
keys.caG = { gui.find.goto_file_in_list, false }
- keys.cg = { m_editing.goto_line }
+ keys.cg = { m_editing.goto_line }
-- Tools
keys['f2'] = { gui.command_entry.focus }
@@ -395,15 +423,6 @@ else
keys.ab = { gui.switch_buffer }
keys['c\t'] = { 'goto_buffer', v, 1, false }
keys['cs\t'] = { 'goto_buffer', v, -1, false }
- local function toggle_setting(setting)
- local state = buffer[setting]
- if type(state) == 'boolean' then
- buffer[setting] = not state
- elseif type(state) == 'number' then
- buffer[setting] = buffer[setting] == 0 and 1 or 0
- end
- events.emit('update_ui') -- for updating statusbar
- end
keys.at.v = {
e = { toggle_setting, 'view_eol' },
w = { toggle_setting, 'wrap_mode' },
@@ -428,25 +447,7 @@ else
keys.c0 = { function() buffer.zoom = 0 end }
-- Miscellaneous not in standard menu.
- -- Recent files.
- local RECENT_FILES = 1
- events.connect('user_list_selection',
- function(type, text)
- if type == RECENT_FILES then io.open_file(text) end
- end)
- keys.co = {
- function()
- local buffer = buffer
- local files = {}
- for _, filename in ipairs(io.recent_files) do
- table.insert(files, 1, filename)
- end
- local sep = buffer.auto_c_separator
- buffer.auto_c_separator = ('|'):byte()
- buffer:user_list_show(RECENT_FILES, table.concat(files, '|'))
- buffer.auto_c_separator = sep
- end
- }
+ keys.co = { show_recent_file_list }
-- Movement/selection commands
keys.cf = { 'char_right', b }
@@ -469,7 +470,7 @@ else
keys.cah = { 'del_word_left', b }
keys.cd = { 'clear', b }
keys.cad = { 'del_word_right', b }
- keys.ck = {
+ keys.ck = {
function()
buffer:line_end_extend()
buffer:cut()
@@ -568,9 +569,7 @@ local function run_key_command(lexer, scope)
end
end
- if type(f) ~= 'function' then
- error(L('Unknown command:')..tostring(f))
- end
+ if type(f) ~= 'function' then error(L('Unknown command:')..tostring(f)) end
return f(unpack(args)) == false and PROPAGATE or HALT
end
@@ -594,19 +593,9 @@ local function keypress(code, shift, control, alt)
if code < 256 then
key = string_char(code)
shift = false -- for printable characters, key is upper case
- if OSX and not shift and not control and not alt then
- local ch = string_char(code)
- -- work around native GTK-OSX's handling of Alt key
- if ch:find('[%p%d]') and #keychain == 0 then
- if buffer.anchor ~= buffer.current_pos then buffer:delete_back() end
- buffer:add_text(ch)
- events.emit('char_added', code)
- return true
- end
- end
else
- if not KEYSYMS[code] then return end
key = KEYSYMS[code]
+ if not key then return end
end
control = control and CTRL or ''
shift = shift and SHIFT or ''
diff --git a/modules/textadept/menu.lua b/modules/textadept/menu.lua
index 196d685a..436f86bb 100644
--- a/modules/textadept/menu.lua
+++ b/modules/textadept/menu.lua
@@ -10,6 +10,20 @@ local gui = _G.gui
-- This module, like _m.textadept.keys, should be 'require'ed last.
module('_m.textadept.menu', package.seeall)
+-- Markdown:
+--
+-- ## Events
+--
+-- The following is a list of all menu events generated in
+-- `event_name(arguments)` format:
+--
+-- * **menu\_clicked** (menu\_id)<br />
+-- Called when a menu item is selected.
+-- - menu\_id: the numeric ID of the menu item set in
+-- [`gui.gtkmenu()`][gui_gtkmenu].
+--
+-- [gui_gtkmenu]: ../modules/gui.html#gtkmenu
+
local SEPARATOR = 'separator'
local b, v = 'buffer', 'view'
local m_snippets = _m.textadept.snippets
@@ -121,24 +135,32 @@ menubar = {
{ L('Convert _Indentation'), { m_editing.convert_indentation } },
{ title = L('S_election'),
{ title = L('_Enclose in...'),
- { L('_HTML Tags'), { m_editing.enclose, 'tag' } },
- { L('HTML Single _Tag'), { m_editing.enclose, 'single_tag' } },
- { L('_Double Quotes'), { m_editing.enclose, 'dbl_quotes' } },
- { L('_Single Quotes'), { m_editing.enclose, 'sng_quotes' } },
- { L('_Parentheses'), { m_editing.enclose, 'parens' } },
- { L('_Brackets'), { m_editing.enclose, 'brackets' } },
- { L('B_races'), { m_editing.enclose, 'braces' } },
- { L('_Character Sequence'), { m_editing.enclose, 'chars' } },
+ { L('_HTML Tags'), {
+ function()
+ m_editing.enclose('<', '>')
+ local buffer = buffer
+ local pos = buffer.current_pos
+ while buffer.char_at[pos - 1] ~= 60 do pos = pos - 1 end -- '<'
+ buffer:insert_text(-1,
+ '</'..buffer:text_range(pos, buffer.current_pos))
+ end
+ } },
+ { L('HTML Single _Tag'), { m_editing.enclose, '<', ' />' } },
+ { L('_Double Quotes'), { m_editing.enclose, '"', '"' } },
+ { L('_Single Quotes'), { m_editing.enclose, "'", "'" } },
+ { L('_Parentheses'), { m_editing.enclose, '(', ')' } },
+ { L('_Brackets'), { m_editing.enclose, '[', ']' } },
+ { L('B_races'), { m_editing.enclose, '{', '}' } },
},
{ L('_Grow'), { m_editing.grow_selection, 1 } },
},
{ title = L('Select i_n...'),
- { L('_HTML Tag'), { m_editing.select_enclosed, 'tags' } },
- { L('_Double Quote'), { m_editing.select_enclosed, 'dbl_quotes' } },
- { L('_Single Quote'), { m_editing.select_enclosed, 'sng_quotes' } },
- { L('_Parenthesis'), { m_editing.select_enclosed, 'parens' } },
- { L('_Bracket'), { m_editing.select_enclosed, 'brackets' } },
- { L('B_race'), { m_editing.select_enclosed, 'braces' } },
+ { L('_HTML Tag'), { m_editing.select_enclosed, '>', '<' } },
+ { L('_Double Quote'), { m_editing.select_enclosed, '"', '"' } },
+ { L('_Single Quote'), { m_editing.select_enclosed, "'", "'" } },
+ { L('_Parenthesis'), { m_editing.select_enclosed, '(', ')' } },
+ { L('_Bracket'), { m_editing.select_enclosed, '[', ']' } },
+ { L('B_race'), { m_editing.select_enclosed, '{', '}' } },
{ L('_Word'), { m_editing.current_word, 'select' } },
{ L('_Line'), { m_editing.select_line } },
{ L('Para_graph'), { m_editing.select_paragraph } },
diff --git a/modules/textadept/mime_types.lua b/modules/textadept/mime_types.lua
index f066e46b..e6023995 100644
--- a/modules/textadept/mime_types.lua
+++ b/modules/textadept/mime_types.lua
@@ -114,7 +114,6 @@ lexers = {}
-- Generate lexer list
local lexers_found = {}
-local lfs = require 'lfs'
for lexer in lfs.dir(_HOME..'/lexers/') do
if lexer:find('%.lua$') and lexer ~= 'lexer.lua' then
lexers_found[lexer:match('^(.+)%.lua$')] = true
diff --git a/modules/textadept/run.lua b/modules/textadept/run.lua
index 3cae9e86..2203b129 100755..100644
--- a/modules/textadept/run.lua
+++ b/modules/textadept/run.lua
@@ -19,11 +19,9 @@ module('_m.textadept.run', package.seeall)
-- * %(filename_noext) The name of the file excluding extension.
function execute(command)
local filepath = buffer.filename:iconv(_CHARSET, 'UTF-8')
- local filedir, filename
+ local filedir, filename = '', filepath
if filepath:find('[/\\]') then
filedir, filename = filepath:match('^(.+[/\\])([^/\\]+)$')
- else
- filedir, filename = '', filepath
end
local filename_noext = filename:match('^(.+)%.')
command = command:gsub('%%%b()', {
@@ -42,6 +40,15 @@ function execute(command)
buffer:goto_pos(buffer.length)
end
+-- Executes a compile or run command.
+-- @param cmd_table Either compile_command or run_command
+local function command(cmd_table)
+ if not buffer.filename then return end
+ buffer:save()
+ local action = cmd_table[buffer.filename:match('[^.]+$')]
+ if action then execute(type(action) == 'function' and action() or action) end
+end
+
---
-- File extensions and their associated 'compile' actions.
-- Each key is a file extension whose value is a either a command line string to
@@ -55,12 +62,7 @@ compile_command = {}
-- Compiles the file as specified by its extension in the compile_command
-- table.
-- @see compile_command
-function compile()
- if not buffer.filename then return end
- buffer:save()
- local action = compile_command[buffer.filename:match('[^.]+$')]
- if action then execute(type(action) == 'function' and action() or action) end
-end
+function compile() command(compile_command) end
---
-- File extensions and their associated 'go' actions.
@@ -75,12 +77,7 @@ run_command = {}
-- Runs/executes the file as specified by its extension in the run_command
-- table.
-- @see run_command
-function run()
- if not buffer.filename then return end
- buffer:save()
- local action = run_command[buffer.filename:match('[^.]+$')]
- if action then execute(type(action) == 'function' and action() or action) end
-end
+function run() command(run_command) end
---
-- A table of error string details.
@@ -112,7 +109,6 @@ function goto_error(pos, line_num)
for _, error_detail in pairs(error_detail) do
local captures = { line:match(error_detail.pattern) }
if #captures > 0 then
- local lfs = require 'lfs'
local utf8_filename = captures[error_detail.filename]
local filename = utf8_filename:iconv(_CHARSET, 'UTF-8')
if lfs.attributes(filename) then
diff --git a/modules/textadept/session.lua b/modules/textadept/session.lua
index c8fc1d90..745638cc 100755..100644
--- a/modules/textadept/session.lua
+++ b/modules/textadept/session.lua
@@ -19,8 +19,6 @@ DEFAULT_SESSION = _USERHOME..'/session'
SAVE_ON_QUIT = true
-- end settings
-local lfs = require 'lfs'
-
---
-- Loads a Textadept session file.
-- Textadept restores split views, opened buffers, cursor information, and
@@ -33,16 +31,17 @@ function load(filename)
local not_found = {}
local f = io.open(filename or DEFAULT_SESSION, 'rb')
if not f then
- if not io.close_all() then return false end
+ io.close_all()
+ return false
end
- if not f then return false end
local current_view, splits = 1, { [0] = {} }
+ local lfs_attributes = lfs.attributes
for line in f:lines() do
if line:find('^buffer:') then
local anchor, current_pos, first_visible_line, filename =
line:match('^buffer: (%d+) (%d+) (%d+) (.+)$')
if not filename:find('^%[.+%]$') then
- if lfs.attributes(filename) then
+ if lfs_attributes(filename) then
io.open_file(filename)
else
not_found[#not_found + 1] = filename
@@ -77,8 +76,7 @@ function load(filename)
elseif line:find('^current_view:') then
local view_idx = line:match('^current_view: (%d+)')
current_view = tonumber(view_idx) or 1
- end
- if line:find('^size:') then
+ elseif line:find('^size:') then
local width, height = line:match('^size: (%d+) (%d+)$')
if width and height then gui.size = { width, height } end
end
diff --git a/modules/textadept/snapopen.lua b/modules/textadept/snapopen.lua
index f472b744..10690c75 100755..100644
--- a/modules/textadept/snapopen.lua
+++ b/modules/textadept/snapopen.lua
@@ -36,7 +36,7 @@ DEFAULT_DEPTH = 4
MAX = 1000
-- end settings
-local lfs = require 'lfs'
+local lfs_dir, lfs_attributes = lfs.dir, lfs.attributes
local DEPTH = DEFAULT_DEPTH
-- Determines whether or not the given file matches the given filter.
@@ -64,10 +64,10 @@ end
-- @param filter The filter table.
local function add_directory(dir, list, depth, filter)
local string_match, string_gsub, MAX = string.match, string.gsub, MAX
- for file in lfs.dir(dir) do
+ for file in lfs_dir(dir) do
if not string_match(file, '^%.%.?$') then
file = dir..(not WIN32 and '/' or '\\')..file
- if lfs.attributes(file).mode == 'directory' then
+ if lfs_attributes(file).mode == 'directory' then
if not exclude(file, filter.folders) and depth < DEPTH then
add_directory(file, list, depth + 1, filter)
end
diff --git a/modules/textadept/snippets.lua b/modules/textadept/snippets.lua
index 4d426532..95a80558 100755..100644
--- a/modules/textadept/snippets.lua
+++ b/modules/textadept/snippets.lua
@@ -34,6 +34,9 @@ module('_m.textadept.snippets', package.seeall)
-- and `lua`. Style names are different lexer styles, most of which are in
-- `lexers/lexer.lua`; examples are `whitespace`, `comment`, and `string`.
--
+-- Snippet text should contain spaces instead of tabs since Textadept
+-- automatically converts spaces to tabs depending on the current settings.
+--
-- ## Snippet Precedence
--
-- When searching for a snippet to expand in the `snippets` table, snippets in
diff --git a/src/Makefile b/src/Makefile
index 729e10b4..7c89335e 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -65,7 +65,7 @@ CFLAGS = -std=c99 $(DEBUG_FLAG) -O $(PLAT_FLAGS) $(INCLUDEDIRS) -W -Wall \
GTKFLAGS = $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) \
--cflags gtk+-2.0)
GTKLIBS = $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) \
- --libs gtk+-2.0 gthread-2.0)
+ --libs gtk+-2.0)
ifdef OSX
GTKLIBS += -framework Carbon -framework Cocoa -ligemacintegration
endif
diff --git a/src/textadept.c b/src/textadept.c
index ba32e109..9acb50ae 100644
--- a/src/textadept.c
+++ b/src/textadept.c
@@ -1950,7 +1950,7 @@ static int l_cf_gui_dialog(lua_State *lua) {
int i, j, k, n = lua_gettop(lua) - 1, argc = n;
for (i = 2; i < n + 2; i++)
if (lua_type(lua, i) == LUA_TTABLE) argc += lua_objlen(lua, i) - 1;
- const char *argv[argc];
+ const char **argv = malloc(argc * sizeof(const char *));
for (i = 0, j = 2; j < n + 2; j++)
if (lua_type(lua, j) == LUA_TTABLE) {
int len = lua_objlen(lua, j);
@@ -1963,6 +1963,7 @@ static int l_cf_gui_dialog(lua_State *lua) {
char *out = gcocoadialog(type, argc, argv);
lua_pushstring(lua, out);
free(out);
+ free(argv);
return 1;
}
diff --git a/themes/dark/buffer.lua b/themes/dark/buffer.lua
index 12a4e55b..8eb5971d 100644
--- a/themes/dark/buffer.lua
+++ b/themes/dark/buffer.lua
@@ -3,11 +3,11 @@
local buffer = buffer
--- folding
+-- Folding.
buffer.property['fold'] = '1'
buffer.property['fold.by.indentation'] = '1'
--- tabs and indentation
+-- Tabs and indentation.
buffer.tab_width = 2
buffer.use_tabs = false
buffer.indent = 2
@@ -15,6 +15,6 @@ buffer.tab_indents = true
buffer.back_space_un_indents = true
buffer.indentation_guides = 1
--- various
+-- Various.
buffer.auto_c_choose_single = true
buffer.additional_selection_typing = true
diff --git a/themes/dark/view.lua b/themes/dark/view.lua
index c3c68edf..5f9fb4b2 100644
--- a/themes/dark/view.lua
+++ b/themes/dark/view.lua
@@ -4,14 +4,14 @@
local c = _SCINTILLA.constants
local buffer = buffer
--- caret
+-- Caret.
buffer.caret_fore = 11184810 -- 0xAA | 0xAA << 8 | 0xAA << 16
buffer.caret_line_visible = true
buffer.caret_line_back = 4473924 -- 0x44 | 0x44 << 8 | 0x44 << 16
buffer:set_x_caret_policy(1, 20) -- CARET_SLOP
buffer:set_y_caret_policy(13, 1) -- CARET_SLOP | CARET_STRICT | CARET_EVEN
--- selection
+-- Selection.
buffer:set_sel_fore(1, 3355443) -- 0x33 | 0x33 << 8 | 0x33 << 16
buffer:set_sel_back(1, 10066329) -- 0x99 | 0x99 << 8 | 0x99 << 16
@@ -20,7 +20,7 @@ buffer.margin_width_n[0] = 4 + 3 * -- line number margin
buffer.margin_width_n[1] = 0 -- marker margin invisible
--- fold margin
+-- Fold margin.
buffer:set_fold_margin_colour(1, 11184810) -- 0xAA | 0xAA << 8 | 0xAA << 16
buffer:set_fold_margin_hi_colour(1, 11184810) -- 0xAA | 0xAA << 8 | 0xAA << 16
buffer.margin_type_n[2] = c.SC_MARGIN_SYMBOL
@@ -28,7 +28,7 @@ buffer.margin_width_n[2] = 10
buffer.margin_mask_n[2] = c.SC_MASK_FOLDERS
buffer.margin_sensitive_n[2] = true
--- fold margin markers
+-- Fold margin markers.
buffer:marker_define(c.SC_MARKNUM_FOLDEROPEN, c.SC_MARK_ARROWDOWN)
buffer:marker_set_fore(c.SC_MARKNUM_FOLDEROPEN, 0)
buffer:marker_set_back(c.SC_MARKNUM_FOLDEROPEN, 0)
@@ -41,7 +41,7 @@ buffer:marker_define(c.SC_MARKNUM_FOLDEREND, c.SC_MARK_EMPTY)
buffer:marker_define(c.SC_MARKNUM_FOLDEROPENMID, c.SC_MARK_EMPTY)
buffer:marker_define(c.SC_MARKNUM_FOLDERMIDTAIL, c.SC_MARK_EMPTY)
--- various
+-- Various.
buffer.call_tip_use_style = 0
buffer:set_fold_flags(16)
buffer.mod_event_mask = c.SC_MOD_CHANGEFOLD
diff --git a/themes/light/buffer.lua b/themes/light/buffer.lua
index 1bb9a7da..610d7f25 100644
--- a/themes/light/buffer.lua
+++ b/themes/light/buffer.lua
@@ -3,11 +3,11 @@
local buffer = buffer
--- folding
+-- Folding.
buffer.property['fold'] = '1'
buffer.property['fold.by.indentation'] = '1'
--- tabs and indentation
+-- Tabs and indentation.
buffer.tab_width = 2
buffer.use_tabs = false
buffer.indent = 2
@@ -15,6 +15,6 @@ buffer.tab_indents = true
buffer.back_space_un_indents = true
buffer.indentation_guides = 1
--- various
+-- Various.
buffer.auto_c_choose_single = true
buffer.additional_selection_typing = true
diff --git a/themes/light/view.lua b/themes/light/view.lua
index 1a684d0b..d69e9ad2 100644
--- a/themes/light/view.lua
+++ b/themes/light/view.lua
@@ -4,14 +4,14 @@
local c = _SCINTILLA.constants
local buffer = buffer
--- caret
+-- Caret.
buffer.caret_fore = 3355443 -- 0x33 | 0x33 << 8 | 0x33 << 16
buffer.caret_line_visible = true
buffer.caret_line_back = 14540253 -- 0xDD | 0xDD << 8 | 0xDD << 16
buffer:set_x_caret_policy(1, 20) -- CARET_SLOP
buffer:set_y_caret_policy(13, 1) -- CARET_SLOP | CARET_STRICT | CARET_EVEN
--- selection
+-- Selection.
buffer:set_sel_fore(1, 3355443) -- 0x33 | 0x33 << 8 | 0x33 << 16
buffer:set_sel_back(1, 10066329) -- 0x99 | 0x99 << 8 | 0x99 << 16
@@ -20,7 +20,7 @@ buffer.margin_width_n[0] = 4 + 3 * -- line number margin
buffer.margin_width_n[1] = 0 -- marker margin invisible
--- fold margin
+-- Fold margin.
buffer:set_fold_margin_colour(1, 13421772) -- 0xCC | 0xCC << 8 | 0xCC << 16
buffer:set_fold_margin_hi_colour(1, 13421772) -- 0xCC | 0xCC << 8 | 0xCC << 16
buffer.margin_type_n[2] = c.SC_MARGIN_SYMBOL
@@ -28,7 +28,7 @@ buffer.margin_width_n[2] = 10
buffer.margin_mask_n[2] = c.SC_MASK_FOLDERS
buffer.margin_sensitive_n[2] = true
--- fold margin markers
+-- Fold margin markers.
buffer:marker_define(c.SC_MARKNUM_FOLDEROPEN, c.SC_MARK_ARROWDOWN)
buffer:marker_set_fore(c.SC_MARKNUM_FOLDEROPEN, 0)
buffer:marker_set_back(c.SC_MARKNUM_FOLDEROPEN, 0)
@@ -41,7 +41,7 @@ buffer:marker_define(c.SC_MARKNUM_FOLDEREND, c.SC_MARK_EMPTY)
buffer:marker_define(c.SC_MARKNUM_FOLDEROPENMID, c.SC_MARK_EMPTY)
buffer:marker_define(c.SC_MARKNUM_FOLDERMIDTAIL, c.SC_MARK_EMPTY)
--- various
+-- Various.
buffer.call_tip_use_style = 0
buffer:set_fold_flags(16)
buffer.mod_event_mask = c.SC_MOD_CHANGEFOLD
diff --git a/themes/scite/buffer.lua b/themes/scite/buffer.lua
index a93116db..d22dd934 100644
--- a/themes/scite/buffer.lua
+++ b/themes/scite/buffer.lua
@@ -3,11 +3,11 @@
local buffer = buffer
--- folding
+-- Folding.
buffer.property['fold'] = '1'
buffer.property['fold.by.indentation'] = '1'
--- tabs and indentation
+-- Tabs and indentation.
buffer.tab_width = 2
buffer.use_tabs = false
buffer.indent = 2
@@ -15,6 +15,6 @@ buffer.tab_indents = true
buffer.back_space_un_indents = true
buffer.indentation_guides = 1
--- various
+-- Various.
buffer.auto_c_choose_single = true
buffer.additional_selection_typing = true
diff --git a/themes/scite/view.lua b/themes/scite/view.lua
index d612377d..71b4be2f 100644
--- a/themes/scite/view.lua
+++ b/themes/scite/view.lua
@@ -8,13 +8,13 @@ buffer.margin_width_n[0] = 4 * buffer:text_width(c.STYLE_LINENUMBER, "9")
buffer.caret_period = 500
--- fold margin
+-- Fold margin.
buffer.margin_type_n[2] = c.SC_MARGIN_SYMBOL
buffer.margin_width_n[2] = 16
buffer.margin_mask_n[2] = c.SC_MASK_FOLDERS
buffer.margin_sensitive_n[2] = true
--- fold margin markers
+-- Fold margin markers.
buffer:marker_define(c.SC_MARKNUM_FOLDEROPEN, c.SC_MARK_MINUS)
buffer:marker_set_fore(c.SC_MARKNUM_FOLDEROPEN, 16777215)
buffer:marker_set_back(c.SC_MARKNUM_FOLDEROPEN, 0)