diff options
author | 2016-04-02 23:35:15 -0400 | |
---|---|---|
committer | 2016-04-02 23:35:15 -0400 | |
commit | 0c4915da62a96bf6db20377ce11fa887b6271ad9 (patch) | |
tree | 4bc7d4b0722bce49aebf341841f3ab4fa8ad1dfd | |
parent | f6705b546d2f037302f2d2d95bae507e78b29d59 (diff) | |
download | textadept-0c4915da62a96bf6db20377ce11fa887b6271ad9.tar.gz textadept-0c4915da62a96bf6db20377ce11fa887b6271ad9.zip |
Code cleanup.
Do not use `ipairs()` and use more consistent variable names among other things.
-rw-r--r-- | core/args.lua | 4 | ||||
-rw-r--r-- | core/events.lua | 1 | ||||
-rw-r--r-- | core/file_io.lua | 57 | ||||
-rw-r--r-- | core/keys.lua | 4 | ||||
-rw-r--r-- | core/lfs_ext.lua | 18 | ||||
-rw-r--r-- | core/ui.lua | 88 | ||||
-rw-r--r-- | modules/ansi_c/init.lua | 4 | ||||
-rw-r--r-- | modules/lua/init.lua | 2 | ||||
-rw-r--r-- | modules/textadept/bookmarks.lua | 30 | ||||
-rw-r--r-- | modules/textadept/command_entry.lua | 8 | ||||
-rw-r--r-- | modules/textadept/editing.lua | 50 | ||||
-rw-r--r-- | modules/textadept/file_types.lua | 33 | ||||
-rw-r--r-- | modules/textadept/find.lua | 65 | ||||
-rw-r--r-- | modules/textadept/menu.lua | 28 | ||||
-rw-r--r-- | modules/textadept/run.lua | 13 | ||||
-rw-r--r-- | modules/textadept/session.lua | 55 | ||||
-rw-r--r-- | modules/textadept/snippets.lua | 4 |
17 files changed, 248 insertions, 216 deletions
diff --git a/core/args.lua b/core/args.lua index c27da28e..834ba973 100644 --- a/core/args.lua +++ b/core/args.lua @@ -50,9 +50,7 @@ local function process(arg) local switch = switches[arg[i]] if switch then local f, n = table.unpack(switch) - local args = {} - for j = i + 1, i + n do args[#args + 1] = arg[j] end - f(table.unpack(args)) + f(table.unpack(arg, i + 1, i + n)) i = i + n else io.open_file(lfs.abspath(arg[i], arg[-1])) diff --git a/core/events.lua b/core/events.lua index ceba125e..5b7c390a 100644 --- a/core/events.lua +++ b/core/events.lua @@ -270,6 +270,7 @@ local handlers = {} -- @see disconnect -- @name connect function M.connect(event, f, index) + -- Note: cannot assert() here since _L is undefined early in init process. if not event then error(_L['Undefined event name']) end if not handlers[event] then handlers[event] = {} end if handlers[event][f] then M.disconnect(event, f) end diff --git a/core/file_io.lua b/core/file_io.lua index 5f3ab513..709bf1c8 100644 --- a/core/file_io.lua +++ b/core/file_io.lua @@ -109,8 +109,11 @@ function io.open_file(filenames) if not filenames then return end for i = 1, #filenames do local filename = lfs.abspath((filenames[i]:gsub('^file://', ''))) - for j, buffer in ipairs(_BUFFERS) do - if filename == buffer.filename then view:goto_buffer(j) goto continue end + for j = 1, #_BUFFERS do + if filename == _BUFFERS[j].filename then + view:goto_buffer(j) -- already open + goto continue + end end local text = '' @@ -118,7 +121,7 @@ function io.open_file(filenames) if f then text = f:read('*a') f:close() - if not text then return end -- filename exists, but cannot read it + if not text then goto continue end -- filename exists, but cannot read it elseif lfs.attributes(filename) then error(err) end @@ -152,10 +155,13 @@ function io.open_file(filenames) events.emit(events.FILE_OPENED, filename) -- Add file to recent files list, eliminating duplicates. - for j, file in ipairs(io.recent_files) do - if file == filename then table.remove(io.recent_files, j) break end - end table.insert(io.recent_files, 1, filename) + for j = 2, #io.recent_files do + if io.recent_files[j] == filename then + table.remove(io.recent_files, j) + break + end + end ::continue:: end end @@ -244,8 +250,8 @@ end -- @name save_all_files function io.save_all_files() local current_buffer = _BUFFERS[buffer] - for i, buffer in ipairs(_BUFFERS) do - if buffer.filename and buffer.modify then + for i = 1, #_BUFFERS do + if _BUFFERS[i].filename and _BUFFERS[i].modify then view:goto_buffer(i) io.save_file() end @@ -306,17 +312,17 @@ events_connect(events.RESUME, update_modified_file) -- Prompts the user to reload the current file if it has been externally -- modified. events_connect(events.FILE_CHANGED, function() - local msg = ('"%s"\n%s'):format(buffer.filename:iconv('UTF-8', _CHARSET), - _L['has been modified. Reload it?']) local button = ui.dialogs.msgbox{ title = _L['Reload?'], text = _L['Reload modified file?'], - informative_text = msg, icon = 'gtk-dialog-question', - button1 = _L['_Yes'], button2 = _L['_No'] + informative_text = string.format('"%s"\n%s', + buffer.filename:iconv('UTF-8', _CHARSET), + _L['has been modified. Reload it?']), + icon = 'gtk-dialog-question', button1 = _L['_Yes'], button2 = _L['_No'] } if button == 1 then io.reload_file() end end) --- Closes the initial "Untitled" buffer. +-- Closes the initial "Untitled" buffer when another buffer is opened. events_connect(events.FILE_OPENED, function() local buf = _BUFFERS[1] if #_BUFFERS == 2 and not (buf.filename or buf._type or buf.modify) then @@ -330,12 +336,12 @@ end) -- @see recent_files -- @name open_recent_file function io.open_recent_file() - local utf8_filenames = {} - for _, filename in ipairs(io.recent_files) do - utf8_filenames[#utf8_filenames + 1] = filename:iconv('UTF-8', _CHARSET) + local utf8_list = {} + for i = 1, #io.recent_files do + utf8_list[#utf8_list + 1] = io.recent_files[i]:iconv('UTF-8', _CHARSET) end local button, i = ui.dialogs.filteredlist{ - title = _L['Open'], columns = _L['File'], items = utf8_filenames, + title = _L['Open'], columns = _L['File'], items = utf8_list, width = CURSES and ui.size[1] - 2 or nil } if button == 1 and i then io.open_file(io.recent_files[i]) end @@ -442,10 +448,10 @@ function io.snapopen(paths, filter, exclude_FILTER, opts) end local utf8_list = {} for i = 1, #paths do - lfs.dir_foreach(paths[i], function(file) + lfs.dir_foreach(paths[i], function(filename) if #utf8_list >= io.SNAPOPEN_MAX then return false end - file = file:gsub('^%.[/\\]', ''):iconv('UTF-8', _CHARSET) - utf8_list[#utf8_list + 1] = file + filename = filename:gsub('^%.[/\\]', '') + utf8_list[#utf8_list + 1] = filename:iconv('UTF-8', _CHARSET) end, filter, exclude_FILTER) end if #utf8_list >= io.SNAPOPEN_MAX then @@ -462,8 +468,11 @@ function io.snapopen(paths, filter, exclude_FILTER, opts) string_output = true, width = CURSES and ui.size[1] - 2 or nil } if opts then for k, v in pairs(opts) do options[k] = v end end - local button, files = ui.dialogs.filteredlist(options) - if button ~= _L['_OK'] or not files then return end - for i = 1, #files do files[i] = files[i]:iconv(_CHARSET, 'UTF-8') end - io.open_file(files) + local button, utf8_filenames = ui.dialogs.filteredlist(options) + if button ~= _L['_OK'] or not utf8_filenames then return end + local filenames = {} + for i = 1, #utf8_filenames do + filenames[i] = utf8_filenames[i]:iconv(_CHARSET, 'UTF-8') + end + io.open_file(filenames) end diff --git a/core/keys.lua b/core/keys.lua index 927491e2..ce4a2cc0 100644 --- a/core/keys.lua +++ b/core/keys.lua @@ -155,7 +155,7 @@ local keychain = {} -- @name keychain M.keychain = setmetatable({}, { __index = keychain, - __newindex = function() error("'keys.keychain' is read-only") end, + __newindex = function() error("read-only table") end, __len = function() return #keychain end }) @@ -253,7 +253,7 @@ local function keypress(code, shift, control, alt, meta) end -- PROPAGATE otherwise. end -events.connect(events.KEYPRESS, keypress, 1) +events.connect(events.KEYPRESS, keypress) --- -- Map of key bindings to commands, with language-specific key tables assigned diff --git a/core/lfs_ext.lua b/core/lfs_ext.lua index 43fe6ebc..b2b89a88 100644 --- a/core/lfs_ext.lua +++ b/core/lfs_ext.lua @@ -103,17 +103,17 @@ function lfs.dir_foreach(dir, f, filter, exclude_FILTER, n, include_dirs, level) if ext then for i = 1, #ext do ext[ext[i]] = true end end end local dir_sep, lfs_attributes = not WIN32 and '/' or '\\', lfs.attributes - for file in lfs.dir(dir) do - if not file:find('^%.%.?$') then -- ignore . and .. - file = dir..(dir ~= '/' and dir_sep or '')..file - local type = lfs_attributes(file, 'mode') - if type == 'directory' and not exclude(file, filter.folders) then - if include_dirs and f(file..dir_sep) == false then return end + for basename in lfs.dir(dir) do + if not basename:find('^%.%.?$') then -- ignore . and .. + local filename = dir..(dir ~= '/' and dir_sep or '')..basename + local mode = lfs_attributes(filename, 'mode') + if mode == 'directory' and not exclude(filename, filter.folders) then + if include_dirs and f(filename..dir_sep) == false then return end if not n or level < n then - lfs.dir_foreach(file, f, filter, nil, n, include_dirs, level + 1) + lfs.dir_foreach(filename, f, filter, nil, n, include_dirs, level + 1) end - elseif type == 'file' and not exclude(file, filter) then - if f(file) == false then return end + elseif mode == 'file' and not exclude(filename, filter) then + if f(filename) == false then return end end end end diff --git a/core/ui.lua b/core/ui.lua index 1dd403a9..de1ed2fd 100644 --- a/core/ui.lua +++ b/core/ui.lua @@ -46,8 +46,11 @@ local theme_props = {} -- @see ui._print local function _print(buffer_type, ...) local print_buffer - for _, buffer in ipairs(_BUFFERS) do - if buffer._type == buffer_type then print_buffer = buffer break end + for i = 1, #_BUFFERS do + if _BUFFERS[i]._type == buffer_type then + print_buffer = _BUFFERS[i] + break + end end if not print_buffer then if not ui.tabs then view:split() end @@ -55,11 +58,12 @@ local function _print(buffer_type, ...) print_buffer._type = buffer_type events.emit(events.FILE_OPENED) elseif not ui.SILENT_PRINT then - local index = _BUFFERS[print_buffer] - for i, view in ipairs(_VIEWS) do - if view.buffer._type == buffer_type then ui.goto_view(i) break end + for i = 1, #_VIEWS do + if _VIEWS[i].buffer._type == buffer_type then ui.goto_view(i) break end + end + if view.buffer._type ~= buffer_type then + view:goto_buffer(_BUFFERS[print_buffer]) end - if view.buffer._type ~= buffer_type then view:goto_buffer(index) end end local args, n = {...}, select('#', ...) for i = 1, n do args[i] = tostring(args[i]) end @@ -95,6 +99,7 @@ ui.dialogs = setmetatable({}, {__index = function(_, k) -- @param options Table of key-value command line options for gtdialog. -- @return Lua objects depending on the dialog kind return function(options) + -- Set up dialog defaults and convert any 1-based indices to 0-based ones. if not options.button1 then options.button1 = _L['_OK'] end local select = options.select if type(select) == 'number' then @@ -107,7 +112,7 @@ ui.dialogs = setmetatable({}, {__index = function(_, k) for option, value in pairs(options) do if value then args[#args + 1] = '--'..option:gsub('_', '-') - if value ~= true then args[#args + 1] = value end + if type(value) ~= 'boolean' then args[#args + 1] = value end end end -- Call gtdialog, stripping any trailing newline in the standard output. @@ -118,9 +123,11 @@ ui.dialogs = setmetatable({}, {__index = function(_, k) if result == '' then return nil end if not CURSES then result = result:iconv(_CHARSET, 'UTF-8') end if k == 'filesave' or not options.select_multiple then return result end - local files = {} - for file in result:gmatch('[^\n]+') do files[#files + 1] = file end - return files + local filenames = {} + for filename in result:gmatch('[^\n]+') do + filenames[#filenames + 1] = filename + end + return filenames elseif k == 'filteredlist' or k == 'optionselect' or k:find('input') and result:match('^[^\n]+\n?(.*)$'):find('\n') then local button, value = result:match('^([^\n]+)\n?(.*)$') @@ -149,16 +156,17 @@ end}) -- Prompts the user to select a buffer to switch to. -- @name switch_buffer function ui.switch_buffer() - local columns, items = {_L['Name'], _L['File']}, {} - for _, buffer in ipairs(_BUFFERS) do + local columns, utf8_list = {_L['Name'], _L['File']}, {} + for i = 1, #_BUFFERS do + local buffer = _BUFFERS[i] local filename = buffer.filename or buffer._type or _L['Untitled'] filename = filename:iconv('UTF-8', _CHARSET) local basename = buffer.filename and filename:match('[^/\\]+$') or filename - items[#items + 1] = (buffer.modify and '*' or '')..basename - items[#items + 1] = filename + utf8_list[#utf8_list + 1] = (buffer.modify and '*' or '')..basename + utf8_list[#utf8_list + 1] = filename end local button, i = ui.dialogs.filteredlist{ - title = _L['Switch Buffers'], columns = columns, items = items, + title = _L['Switch Buffers'], columns = columns, items = utf8_list, width = CURSES and ui.size[1] - 2 or nil } if button == 1 and i then view:goto_buffer(i) end @@ -185,20 +193,26 @@ end -- is `false`. -- @name goto_file function ui.goto_file(filename, split, preferred_view, sloppy) - local patt = '^'..filename..'$' + local patt = '^'..filename..'$' -- TODO: escape filename properly if sloppy then patt = filename:match('[^/\\]+$')..'$' end if #_VIEWS == 1 and split and not (view.buffer.filename or ''):find(patt) then view:split() else local other_view = _VIEWS[preferred_view] - for i, v in ipairs(_VIEWS) do - if (v.buffer.filename or ''):find(patt) then ui.goto_view(i) return end - if not other_view and v ~= view then other_view = i end + for i = 1, #_VIEWS do + if (_VIEWS[i].buffer.filename or ''):find(patt) then + ui.goto_view(i) + return + end + if not other_view and _VIEWS[i] ~= view then other_view = i end end if other_view then ui.goto_view(other_view) end end - for i, buffer in ipairs(_BUFFERS) do - if (buffer.filename or ''):find(patt) then view:goto_buffer(i) return end + for i = 1, #_BUFFERS do + if (_BUFFERS[i].filename or ''):find(patt) then + view:goto_buffer(i) + return + end end io.open_file(filename) end @@ -256,11 +270,12 @@ events_connect(events.VIEW_NEW, function() '[', ']', '/', '\\', 'Z', 'Y', 'X', 'C', 'V', 'A', 'L', 'T', 'D', 'U' } local ctrl_shift_keys = {'L', 'T', 'U', 'Z'} - for _, key in ipairs(ctrl_keys) do - buffer:clear_cmd_key(string.byte(key) + bit32.lshift(buffer.MOD_CTRL, 16)) + for i = 1, #ctrl_keys do + buffer:clear_cmd_key(string.byte(ctrl_keys[i]) + + bit32.lshift(buffer.MOD_CTRL, 16)) end - for _, key in ipairs(ctrl_shift_keys) do - buffer:clear_cmd_key(string.byte(key) + + for i = 1, #ctrl_shift_keys do + buffer:clear_cmd_key(string.byte(ctrl_shift_keys[i]) + bit32.lshift(buffer.MOD_CTRL + buffer.MOD_SHIFT, 16)) end -- Since BUFFER_NEW loads themes and settings on startup, only load them for @@ -338,10 +353,6 @@ events_connect(events.UPDATE_UI, function() col, lexer, eol, tabs, enc, bom) end) --- Updates the statusbar and titlebar for a new Scintilla document. -events_connect(events.BUFFER_NEW, function() events.emit(events.UPDATE_UI) end) -events_connect(events.BUFFER_NEW, set_title) - -- Save buffer properties. events_connect(events.BUFFER_BEFORE_SWITCH, function() local buffer = buffer @@ -374,6 +385,7 @@ local function update_bars() buffer:private_lexer_call(SETDIRECTPOINTER, buffer.direct_pointer) events.emit(events.UPDATE_UI) end +events_connect(events.BUFFER_NEW, update_bars) events_connect(events.BUFFER_AFTER_SWITCH, update_bars) events_connect(events.VIEW_AFTER_SWITCH, update_bars) @@ -410,18 +422,20 @@ events_connect(events.RESET_AFTER, -- Prompts for confirmation if any buffers are modified. events_connect(events.QUIT, function() - local list = {} - for _, buffer in ipairs(_BUFFERS) do - if buffer.modify then - local filename = buffer.filename or buffer._type or _L['Untitled'] - list[#list + 1] = filename:iconv('UTF-8', _CHARSET) + local utf8_list = {} + for i = 1, #_BUFFERS do + if _BUFFERS[i].modify then + local filename = _BUFFERS[i].filename or _BUFFERS[i]._type or + _L['Untitled'] + utf8_list[#utf8_list + 1] = filename:iconv('UTF-8', _CHARSET) end end - local cancel = #list > 0 and ui.dialogs.msgbox{ + local cancel = #utf8_list > 0 and ui.dialogs.msgbox{ title = _L['Quit without saving?'], text = _L['The following buffers are unsaved:'], - informative_text = table.concat(list, '\n'), icon = 'gtk-dialog-question', - button1 = _L['_Cancel'], button2 = _L['Quit _without saving'] + informative_text = table.concat(utf8_list, '\n'), + icon = 'gtk-dialog-question', button1 = _L['_Cancel'], + button2 = _L['Quit _without saving'] } ~= 2 if cancel then return true end -- prevent quit end) diff --git a/modules/ansi_c/init.lua b/modules/ansi_c/init.lua index 6314fea2..950479d3 100644 --- a/modules/ansi_c/init.lua +++ b/modules/ansi_c/init.lua @@ -65,8 +65,8 @@ textadept.editing.autocompleters.ansi_c = function() local fields = tag_line:match(';"\t(.*)$') if (fields:match('class:(%S+)') or fields:match('enum:(%S+)') or fields:match('struct:(%S+)') or '') == symbol then - list[#list + 1] = ("%s%s%d"):format(name, sep, - xpms[fields:sub(1, 1)]) + list[#list + 1] = string.format('%s%s%d', name, sep, + xpms[fields:sub(1, 1)]) list[name] = true elseif name == symbol and fields:match('typeref:') then -- For typeref, change the lookup symbol to the referenced name and diff --git a/modules/lua/init.lua b/modules/lua/init.lua index bc5ced65..1fb007be 100644 --- a/modules/lua/init.lua +++ b/modules/lua/init.lua @@ -58,7 +58,7 @@ textadept.editing.autocompleters.lua = function() local fields = tag_line:match(';"\t(.*)$') local k, class = fields:sub(1, 1), fields:match('class:(%S+)') or '' if class == symbol and (op ~= ':' or k == 'f') then - list[#list + 1] = ("%s%s%d"):format(name, sep, xpms[k]) + list[#list + 1] = string.format('%s%s%d', name, sep, xpms[k]) list[name] = true end end diff --git a/modules/textadept/bookmarks.lua b/modules/textadept/bookmarks.lua index 4d92fcc3..ded52fa4 100644 --- a/modules/textadept/bookmarks.lua +++ b/modules/textadept/bookmarks.lua @@ -21,7 +21,7 @@ M.MARK_BOOKMARK = _SCINTILLA.next_marker_number() -- @param line Optional line number to add or remove a bookmark on. -- @name toggle function M.toggle(on, line) - line = line or buffer:line_from_position(buffer.current_pos) + if not line then line = buffer:line_from_position(buffer.current_pos) end local f = on and buffer.marker_add or buffer.marker_delete if on == nil then -- toggle local bit, marker_mask = 2^M.MARK_BOOKMARK, buffer:marker_get(line) @@ -46,32 +46,34 @@ function M.clear() buffer:marker_delete_all(M.MARK_BOOKMARK) end -- @name goto_mark function M.goto_mark(next) if next == nil then - local marks = {} + local utf8_list, buffers = {}, {} -- List the current buffer's marks, and then all other buffers' marks. for _, current_buffer_first in ipairs{true, false} do - for i, buffer in ipairs(_BUFFERS) do - if current_buffer_first and buffer == _G.buffer or - not current_buffer_first and buffer ~= _G.buffer then + for i = 1, #_BUFFERS do + if current_buffer_first and _BUFFERS[i] == buffer or + not current_buffer_first and _BUFFERS[i] ~= buffer then + local buffer = _BUFFERS[i] local filename = (buffer.filename or buffer._type or _L['Untitled']):match('[^/\\]+$') local line = buffer:marker_next(0, 2^M.MARK_BOOKMARK) while line >= 0 do - local text = filename..':'..tostring(line + 1)..': '.. - buffer:get_line(line):match('^[^\r\n]*') - marks[#marks + 1], marks[text] = text, i + local mark = string.format('%s:%d: %s', + filename:iconv('UTF-8', _CHARSET), + line + 1, + buffer:get_line(line):match('^[^\r\n]*')) + utf8_list[#utf8_list + 1], buffers[#utf8_list + 1] = mark, i line = buffer:marker_next(line + 1, 2^M.MARK_BOOKMARK) end end end end - if #marks == 0 then return end + if #utf8_list == 0 then return end local button, mark = ui.dialogs.filteredlist{ - title = _L['Select Bookmark'], columns = _L['Bookmark'], items = marks, - string_output = true + title = _L['Select Bookmark'], columns = _L['Bookmark'], items = utf8_list } - if button ~= _L['_OK'] or not mark then return end - view:goto_buffer(marks[mark]) - textadept.editing.goto_line(mark:match('^[^:]+:(%d+):')) + if button ~= 1 or not mark then return end + view:goto_buffer(buffers[mark]) + textadept.editing.goto_line(utf8_list[mark]:match('^[^:]+:(%d+):')) else local f = next and buffer.marker_next or buffer.marker_previous local current_line = buffer:line_from_position(buffer.current_pos) diff --git a/modules/textadept/command_entry.lua b/modules/textadept/command_entry.lua index 6c7a4359..325db3cb 100644 --- a/modules/textadept/command_entry.lua +++ b/modules/textadept/command_entry.lua @@ -115,9 +115,9 @@ local env = setmetatable({}, { return f end, __newindex = function(t, k, v) - for _, t2 in ipairs{buffer, view, ui} do - if t2[k] ~= nil then t2[k] = v return end - end + if buffer[k] ~= nil then buffer[k] = v return end + if view[k] ~= nil then view[k] = v return end + if ui[k] ~= nil then ui[k] = v return end rawset(t, k, v) end, }) @@ -143,9 +143,9 @@ local function complete_lua() local line, pos = M:get_cur_line() local symbol, op, part = line:sub(1, pos):match('([%w_.]-)([%.:]?)([%w_]*)$') local ok, result = pcall((load('return ('..symbol..')', nil, 'bt', env))) + if (not ok or type(result) ~= 'table') and symbol ~= '' then return end local cmpls = {} part = '^'..part - if (not ok or type(result) ~= 'table') and symbol ~= '' then return end if not ok then -- shorthand notation local pool = { buffer, view, ui, _G, _SCINTILLA.functions, _SCINTILLA.properties diff --git a/modules/textadept/editing.lua b/modules/textadept/editing.lua index 758f792a..93c180b7 100644 --- a/modules/textadept/editing.lua +++ b/modules/textadept/editing.lua @@ -226,8 +226,7 @@ events.connect(events.FILE_BEFORE_SAVE, function() local buffer = buffer buffer:begin_undo_action() -- Strip trailing whitespace. - local lines = buffer.line_count - for line = 0, lines - 1 do + for line = 0, buffer.line_count - 1 do local s, e = buffer:position_from_line(line), buffer.line_end_position[line] local i, c = e - 1, buffer.char_at[e - 1] while i >= s and (c == 9 or c == 32) do @@ -236,8 +235,9 @@ events.connect(events.FILE_BEFORE_SAVE, function() if i < e - 1 then buffer:delete_range(i + 1, e - i - 1) end end -- Ensure ending newline. - local e = buffer:position_from_line(lines) - if lines == 1 or e > buffer:position_from_line(lines - 1) then + local e = buffer:position_from_line(buffer.line_count) + if buffer.line_count == 1 or + e > buffer:position_from_line(buffer.line_count - 1) then buffer:insert_text(e, '\n') end -- Convert non-consistent EOLs @@ -332,7 +332,7 @@ end -- the caret. Otherwise, the characters to the left and right are. -- @name transpose_chars function M.transpose_chars() - if buffer.length == 0 or buffer.current_pos == 0 then return end + if buffer.current_pos == 0 then return end local pos, char = buffer.current_pos, buffer.char_at[buffer.current_pos] if char == 10 or char == 13 or pos == buffer.length then pos = pos - 1 end buffer:set_target_range(pos - 1, pos + 1) @@ -363,14 +363,8 @@ end -- @param right The right part of the enclosure. -- @name enclose function M.enclose(left, right) - buffer:target_from_selection() - local s, e = buffer.target_start, buffer.target_end - if s == e then - buffer:set_target_range(buffer:word_start_position(s, true), - buffer:word_end_position(e, true)) - end - buffer:replace_target(left..buffer.target_text..right) - buffer:goto_pos(buffer.target_end) + if buffer.selection_empty then M.select_word() end + buffer:replace_sel(left..buffer:get_sel_text()..right) end --- @@ -439,16 +433,16 @@ end function M.convert_indentation() local buffer = buffer buffer:begin_undo_action() - for line = 0, buffer.line_count do + for line = 0, buffer.line_count - 1 do local s = buffer:position_from_line(line) local indent = buffer.line_indentation[line] local e = buffer.line_indent_position[line] local current_indentation, new_indentation = buffer:text_range(s, e), nil if buffer.use_tabs then -- Need integer division and LuaJIT does not have // operator. - new_indentation = ('\t'):rep(math.floor(indent / buffer.tab_width)) + new_indentation = string.rep('\t', math.floor(indent / buffer.tab_width)) else - new_indentation = (' '):rep(indent) + new_indentation = string.rep(' ', indent) end if current_indentation ~= new_indentation then buffer:set_target_range(s, e) @@ -510,26 +504,25 @@ end -- @name filter_through function M.filter_through(command) local s, e = buffer.selection_start, buffer.selection_end - local input - if s ~= e then -- use selected lines as input + if s ~= e then + -- Use the selected lines as input. local i, j = buffer:line_from_position(s), buffer:line_from_position(e) if i < j then s = buffer:position_from_line(i) if buffer.column[e] > 0 then e = buffer:position_from_line(j + 1) end end - input = buffer:text_range(s, e) - else -- use whole buffer as input - input = buffer:get_text() + buffer:set_target_range(s, e) + else + -- Use the whole buffer as input. + buffer:target_whole_document() end local p = spawn(command) - p:write(input) + p:write(buffer.target_text) p:close() + buffer:replace_target(p:read('*a')) if s ~= e then - buffer:set_target_range(s, e) - buffer:replace_target(p:read('*a')) buffer:set_sel(buffer.target_start, buffer.target_end) else - buffer:set_text(p:read('*a')) buffer:goto_pos(s) end end @@ -644,8 +637,11 @@ end events.connect(events.CALL_TIP_CLICK, function(position) if not api_docs then return end api_docs.pos = api_docs.pos + (position == 1 and -1 or 1) - if api_docs.pos > #api_docs then api_docs.pos = 1 end - if api_docs.pos < 1 then api_docs.pos = #api_docs end + if api_docs.pos > #api_docs then + api_docs.pos = 1 + elseif api_docs.pos < 1 then + api_docs.pos = #api_docs + end buffer:call_tip_show(buffer.current_pos, api_docs[api_docs.pos]) end) diff --git a/modules/textadept/file_types.lua b/modules/textadept/file_types.lua index 3c101d50..fd61e2e2 100644 --- a/modules/textadept/file_types.lua +++ b/modules/textadept/file_types.lua @@ -83,8 +83,8 @@ events.connect(events.BUFFER_NEW, function() buffer.get_lexer, buffer.set_lexer = get_lexer, set_lexer buffer.style_name = setmetatable({}, { __index = function(_, style_num) -- LuaDoc is in core/.buffer.luadoc - assert(style_num >= 0 and style_num <= 255, '0 <= style_num < 256') - return buffer:private_lexer_call(style_num) + return style_num >= 0 and style_num <= 255 and + buffer:private_lexer_call(style_num) or nil end, __newindex = function() error('read-only property') end }) @@ -96,24 +96,14 @@ events.connect(events.FILE_AFTER_SAVE, function(_, saved_as) if saved_as then buffer:set_lexer() end end) --- Restores the buffer's lexer. +-- 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) events.connect(events.VIEW_AFTER_SWITCH, restore_lexer) events.connect(events.VIEW_NEW, restore_lexer) events.connect(events.RESET_AFTER, restore_lexer) ---- --- Prompts the user to select a lexer for the current buffer. --- @see buffer.set_lexer --- @name select_lexer -function M.select_lexer() - local button, i = ui.dialogs.filteredlist{ - title = _L['Select Lexer'], columns = _L['Name'], items = M.lexers - } - if button == 1 and i then buffer:set_lexer(M.lexers[i]) end -end - -- Generate lexer list. local lexers_found = {} for _, dir in ipairs{_HOME..'/lexers', _USERHOME..'/lexers'} do @@ -125,7 +115,20 @@ for _, dir in ipairs{_HOME..'/lexers', _USERHOME..'/lexers'} do end end end -for lexer in pairs(lexers_found) do M.lexers[#M.lexers + 1] = lexer end +for lexer in pairs(lexers_found) do + M.lexers[#M.lexers + 1] = lexer:iconv('UTF-8', _CHARSET) +end table.sort(M.lexers) +--- +-- Prompts the user to select a lexer for the current buffer. +-- @see buffer.set_lexer +-- @name select_lexer +function M.select_lexer() + local button, i = ui.dialogs.filteredlist{ + title = _L['Select Lexer'], columns = _L['Name'], items = M.lexers + } + if button == 1 and i then buffer:set_lexer(M.lexers[i]) end +end + return M diff --git a/modules/textadept/find.lua b/modules/textadept/find.lua index a9769cb8..1ba93536 100644 --- a/modules/textadept/find.lua +++ b/modules/textadept/find.lua @@ -127,7 +127,7 @@ for k, v in pairs(escapes) do escapes[v] = k end -- 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) +local function find(text, next, flags, no_wrap, wrapped) if text == '' then return end if not flags then flags = 0 @@ -141,9 +141,9 @@ local function find_(text, next, flags, no_wrap, wrapped) -- If text is selected, assume it is from the current search and increment the -- caret appropriately for the next search. - if buffer:get_sel_text() ~= '' then - buffer:goto_pos(buffer[next and 'current_pos' or 'anchor'] + - (next and 1 or -1)) + if not buffer.selection_empty then + local pos = buffer[next and 'current_pos' or 'anchor'] + buffer:goto_pos(buffer:position_relative(pos, next and 1 or -1)) end local pos = -1 @@ -155,17 +155,20 @@ local function find_(text, next, flags, no_wrap, wrapped) elseif flags < 16 then -- Lua pattern search. -- Note: I do not trust utf8.find completely, so only use it if there are - -- UTF-8 characters in patt. Otherwise default to string.find. - local patt = text:gsub('\\[abfnrtv\\]', escapes) + -- UTF-8 characters in the pattern. Otherwise default to string.find. + local lib_find = not text:find('[\xC2-\xF4]') and string.find or utf8.find local s = next and buffer.current_pos or 0 local e = next and buffer.length or buffer.current_pos - local find = not patt:find('[\xC2-\xF4]') and string.find or utf8.find - local caps = {find(buffer:text_range(s, e), next and patt or '^.*()'..patt)} + local patt = text:gsub('\\[abfnrtv\\]', escapes) + if not next then patt = '^.*()'..patt end + local caps = {lib_find(buffer:text_range(s, e), patt)} M.captures = {table.unpack(caps, next and 3 or 4)} if #caps > 0 and caps[2] >= caps[1] then - if find == string.find then + if lib_find == string.find then + -- Positions are bytes. pos, e = s + caps[next and 1 or 3] - 1, s + caps[2] else + -- Positions are characters, which may be multiple bytes. pos = buffer:position_relative(s, caps[next and 1 or 3] - 1) e = buffer:position_relative(s, caps[2]) end @@ -181,7 +184,7 @@ local function find_(text, next, flags, no_wrap, wrapped) buffer:goto_pos(next and 0 or buffer.length) ui.statusbar_text = _L['Search wrapped'] events.emit(events.FIND_WRAPPED) - pos = find_(text, next, flags, true, true) + pos = find(text, next, flags, true, true) if pos == -1 then ui.statusbar_text = _L['No results found'] buffer:line_scroll(0, first_visible_line - buffer.first_visible_line) @@ -193,7 +196,7 @@ local function find_(text, next, flags, no_wrap, wrapped) return pos end -events.connect(events.FIND, find_) +events.connect(events.FIND, find) -- Finds and selects text incrementally in the current buffer from a starting -- position. @@ -204,10 +207,11 @@ events.connect(events.FIND, find_) -- position. local function find_incremental(text, next, anchor) if anchor then - M.incremental_start = buffer.current_pos + (next and 1 or -1) + M._incremental_start = buffer:position_relative(buffer.current_pos, + next and 1 or -1) end - buffer:goto_pos(M.incremental_start or 0) - find_(text, next, M.match_case and buffer.FIND_MATCHCASE or 0) + buffer:goto_pos(M._incremental_start or 0) + find(text, next, M.match_case and buffer.FIND_MATCHCASE or 0) end --- @@ -227,7 +231,7 @@ end -- @name find_incremental function M.find_incremental(text, next, anchor) if text then find_incremental(text, next, anchor) return end - M.incremental_start = buffer.current_pos + M._incremental_start = buffer.current_pos ui.command_entry:set_text('') ui.command_entry.enter_mode('find_incremental') end @@ -262,16 +266,17 @@ function M.find_in_files(dir) buffer.indicator_current = M.INDIC_FIND local found = false - lfs.dir_foreach(dir, function(file) + lfs.dir_foreach(dir, function(filename) local match_case = M.match_case local line_num = 1 - for line in io.lines(file) do + for line in io.lines(filename) do local s, e = (match_case and line or line:lower()):find(text) if s and e then - file = file:iconv('UTF-8', _CHARSET) - buffer:append_text(('%s:%d:%s\n'):format(file, line_num, line)) + local utf8_filename = filename:iconv('UTF-8', _CHARSET) + buffer:append_text(string.format('%s:%d:%s\n', utf8_filename, line_num, + line)) local pos = buffer:position_from_line(buffer.line_count - 2) + - #file + #tostring(line_num) + 2 + #utf8_filename + #tostring(line_num) + 2 buffer:indicator_fill_range(pos + s - 1, e - s + 1) found = true end @@ -283,7 +288,7 @@ function M.find_in_files(dir) end -- Replaces found text. --- `find_()` is called first, to select any found text. The selected text is +-- `find()` is called first, to select any found text. The selected text is -- then replaced by the specified replacement text. -- This function ignores "Find in Files". -- @param rtext The text to replace found text with. It can contain both Lua @@ -336,7 +341,7 @@ local function replace_all(ftext, rtext) local count = 0 if buffer.selection_empty then buffer:goto_pos(0) - while find_(ftext, true, nil, true) ~= -1 do + while find(ftext, true, nil, true) ~= -1 do replace(rtext) count = count + 1 end @@ -345,17 +350,17 @@ local function replace_all(ftext, rtext) buffer.indicator_current = INDIC_REPLACE buffer:indicator_fill_range(e, 1) buffer:goto_pos(s) - local pos = find_(ftext, true, nil, true) + local pos = find(ftext, true, nil, true) while pos ~= -1 and pos <= buffer:indicator_end(INDIC_REPLACE, s) do replace(rtext) count = count + 1 - pos = find_(ftext, true, nil, true) + pos = find(ftext, true, nil, true) end e = buffer:indicator_end(INDIC_REPLACE, s) buffer:set_sel(s, e > 0 and e or buffer.length) buffer:indicator_clear_range(e, 1) end - ui.statusbar_text = ("%d %s"):format(count, _L['replacement(s) made']) + ui.statusbar_text = string.format('%d %s', count, _L['replacement(s) made']) buffer:end_undo_action() end events.connect(events.REPLACE_ALL, replace_all) @@ -372,7 +377,7 @@ local function is_ff_buf(buf) return buf._type == _L['[Files Found Buffer]'] end -- or the previous one. Only applicable when *line* is `nil` or `false`. -- @name goto_file_found function M.goto_file_found(line, next) - local cur_buf, ff_view, ff_buf = _BUFFERS[buffer], nil, nil + local ff_view, ff_buf = nil, nil for i = 1, #_VIEWS do if is_ff_buf(_VIEWS[i].buffer) then ff_view = i break end end @@ -393,16 +398,16 @@ function M.goto_file_found(line, next) buffer:search_anchor() pos = f(buffer, buffer.FIND_REGEXP, '^.+:[0-9]+:.+$') end - if pos == -1 then if CURSES then view:goto_buffer(cur_buf) end return end + if pos == -1 then return end line = buffer:line_from_position(pos) end buffer:goto_line(line) -- Goto the source of the search result. - local file, line_num = buffer:get_cur_line():match('^(.+):(%d+):.+$') - if not file then if CURSES then view:goto_buffer(cur_buf) end return end + local utf8_filename, line_num = buffer:get_cur_line():match('^(.+):(%d+):.+$') + if not utf8_filename then return end textadept.editing.select_line() - ui.goto_file(file:iconv(_CHARSET, 'UTF-8'), true, preferred_view) + ui.goto_file(utf8_filename:iconv(_CHARSET, 'UTF-8'), true, preferred_view) textadept.editing.goto_line(line_num) end events.connect(events.KEYPRESS, function(code) diff --git a/modules/textadept/menu.lua b/modules/textadept/menu.lua index 7647db9d..bf32a879 100644 --- a/modules/textadept/menu.lua +++ b/modules/textadept/menu.lua @@ -250,13 +250,13 @@ local function get_gdk_key(key_seq) local modifiers = ((mods:find('s') or key:lower() ~= key) and 1 or 0) + (mods:find('c') and 4 or 0) + (mods:find('a') and 8 or 0) + (mods:find('m') and 0x10000000 or 0) - local byte = string.byte(key) - if #key > 1 or byte < 32 then + 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 byte = i break end + if s == key and i > 0xFE20 then code = i break end end end - return byte, modifiers + return code, modifiers end -- Get a string uniquely identifying a key binding. @@ -282,11 +282,11 @@ end local function read_menu_table(menu, contextmenu) local gtkmenu = {} gtkmenu.title = menu.title - for _, menuitem in ipairs(menu) do - if menuitem.title then - gtkmenu[#gtkmenu + 1] = read_menu_table(menuitem, contextmenu) + for i = 1, #menu do + if menu[i].title then + gtkmenu[#gtkmenu + 1] = read_menu_table(menu[i], contextmenu) else - local label, f = menuitem[1], menuitem[2] + local label, f = menu[i][1], menu[i][2] local menu_id = not contextmenu and #menu_actions + 1 or #contextmenu_actions + 1000 + 1 local key, mods = get_gdk_key(key_shortcuts[get_id(f)]) @@ -306,11 +306,11 @@ end -- @param items The current list of items. -- @param commands The current list of commands. local function build_command_tables(menu, title, items, commands) - for _, menuitem in ipairs(menu) do - if menuitem.title then - build_command_tables(menuitem, menuitem.title, items, commands) - elseif menuitem[1] ~= '' then - local label, f = menuitem[1], menuitem[2] + for i = 1, #menu do + if menu[i].title then + build_command_tables(menu[i], menu[i].title, items, commands) + elseif menu[i][1] ~= '' then + local label, f = menu[i][1], menu[i][2] if title then label = title..': '..label end items[#items + 1] = label:gsub('_([^_])', '%1') items[#items + 1] = key_shortcuts[get_id(f)] or '' @@ -390,7 +390,7 @@ local function set_contextmenus(buffer_menu, tab_menu) set_contextmenus(nil, menu) end) end -if not CURSES then set_contextmenus() end +set_contextmenus() --- -- Prompts the user to select a menu command to run. diff --git a/modules/textadept/run.lua b/modules/textadept/run.lua index ce2d75e2..66a57ba4 100644 --- a/modules/textadept/run.lua +++ b/modules/textadept/run.lua @@ -299,7 +299,7 @@ local function is_msg_buf(buf) return buf._type == _L['[Message Buffer]'] end -- @see cwd -- @name goto_error function M.goto_error(line, next) - local cur_buf, msg_view, msg_buf = _BUFFERS[buffer], nil, nil + local msg_view, msg_buf = nil, nil for i = 1, #_VIEWS do if is_msg_buf(_VIEWS[i].buffer) then msg_view = i break end end @@ -322,17 +322,17 @@ function M.goto_error(line, next) if wline == -1 then wline = eline else eline = wline end end line = (next and math.min or math.max)(wline, eline) - if line == -1 then if CURSES then view:goto_buffer(cur_buf) end return end + if line == -1 then return end end buffer:goto_line(line) -- Goto the warning or error and show an annotation. local error = get_error(buffer:get_line(line):match('^[^\r\n]*')) - if not error then if CURSES then view:goto_buffer(cur_buf) end return end + if not error then return end textadept.editing.select_line() ui.goto_file(M.cwd..'/'..error.filename, true, preferred_view, true) local line_num, message = error.line, error.message - buffer:goto_line(line_num - 1) + textadept.editing.goto_line(line_num) if message then buffer.annotation_text[line_num - 1] = message -- Style number 8 is the error style. @@ -411,8 +411,9 @@ events.connect(events.FILE_AFTER_SAVE, function(filename) buffer:goto_pos(buffer:find_column(captures.line, captures.column or 0)) elseif captures.line < top_line or captures.line > bottom_line then local line = buffer:line_from_position(buffer.current_pos) - buffer.annotation_text[line] = 'Line '..(captures.line + 1)..'\n'.. - captures.message + buffer.annotation_text[line] = string.format('%s %d\n%s', _L['Line:'], + captures.line + 1, + captures.message) buffer.annotation_style[line] = 8 -- error style number end end) diff --git a/modules/textadept/session.lua b/modules/textadept/session.lua index f7a5c7f9..142fffe7 100644 --- a/modules/textadept/session.lua +++ b/modules/textadept/session.lua @@ -49,16 +49,16 @@ function M.load(filename) for line in f:lines() do if line:find('^buffer:') then local patt = '^buffer: (%d+) (%d+) (%d+) (.+)$' - local anchor, current_pos, first_visible_line, file = line:match(patt) - if not file:find('^%[.+%]$') then - if lfs_attributes(file) then - io.open_file(file) + local anchor, current_pos, first_visible_line, filename = line:match(patt) + if not filename:find('^%[.+%]$') then + if lfs_attributes(filename) then + io.open_file(filename) else - not_found[#not_found + 1] = file + not_found[#not_found + 1] = filename end else - buffer.new()._type = file - events.emit(events.FILE_OPENED, file) + buffer.new()._type = filename + events.emit(events.FILE_OPENED, filename) -- close initial untitled buf end -- Restore saved buffer selection and view. anchor, current_pos = tonumber(anchor) or 0, tonumber(current_pos) or 0 @@ -72,6 +72,10 @@ function M.load(filename) for line in lines:gmatch('%d+') do buffer:marker_add(tonumber(line), textadept.bookmarks.MARK_BOOKMARK) end + elseif line:find('^size:') then + local maximized, width, height = line:match('^size: (%l+) (%d+) (%d+)$') + ui.maximized = maximized == 'true' + if not ui.maximized then ui.size = {width, height} end elseif line:find('^%s*split%d:') then local level, num, type, size = line:match('^(%s*)split(%d): (%S+) (%d+)') local view = splits[#level] and splits[#level][tonumber(num)] or view @@ -86,10 +90,6 @@ function M.load(filename) view:goto_buffer(buf_idx) elseif line:find('^current_view:') then current_view = tonumber(line:match('^current_view: (%d+)')) or 1 - elseif line:find('^size:') then - local maximized, width, height = line:match('^size: (%l*) ?(%d+) (%d+)$') - ui.maximized = maximized == 'true' - if not ui.maximized then ui.size = {width, height} end elseif line:find('^recent:') then local file = line:match('^recent: (.+)$') local recent, exists = io.recent_files, false @@ -105,7 +105,7 @@ function M.load(filename) ui.dialogs.msgbox{ title = _L['Session Files Not Found'], text = _L['The following session files were not found'], - informative_text = table.concat(not_found, '\n'), + informative_text = table.concat(not_found, '\n'):iconv('UTF-8', _CHARSET), icon = 'gtk-dialog-warning' } end @@ -132,20 +132,22 @@ function M.save(filename) } if not filename then return end local session = {} - local buffer_line = "buffer: %d %d %d %s" -- anchor, cursor, line, filename - local split_line = "%ssplit%d: %s %d" -- level, number, type, size - local view_line = "%sview%d: %d" -- level, number, doc index + local buffer_line = 'buffer: %d %d %d %s' -- anchor, cursor, line, filename + local split_line = '%ssplit%d: %s %d' -- level, number, type, size + local view_line = '%sview%d: %d' -- level, number, doc index -- Write out opened buffers. - for _, buffer in ipairs(_BUFFERS) do - local file = buffer.filename or buffer._type - if file then + for i = 1, #_BUFFERS do + local buffer = _BUFFERS[i] + local filename = buffer.filename or buffer._type + if filename then local current = buffer == view.buffer local anchor = current and 'anchor' or '_anchor' local current_pos = current and 'current_pos' or '_current_pos' local top_line = current and 'first_visible_line' or '_first_visible_line' session[#session + 1] = buffer_line:format(buffer[anchor] or 0, buffer[current_pos] or 0, - buffer[top_line] or 0, file) + buffer[top_line] or 0, + filename) -- Write out bookmarks. local lines = {} local line = buffer:marker_next(0, 2^textadept.bookmarks.MARK_BOOKMARK) @@ -159,14 +161,15 @@ function M.save(filename) -- Write out window size. Do this before writing split views since split view -- size depends on the window size. local maximized, size = tostring(ui.maximized), ui.size - session[#session + 1] = ("size: %s %d %d"):format(maximized, size[1], size[2]) + session[#session + 1] = string.format('size: %s %d %d', maximized, size[1], + size[2]) -- Write out split views. local function write_split(split, level, number) local c1, c2 = split[1], split[2] local vertical, size = tostring(split.vertical), split.size - local spaces = (' '):rep(level) + local spaces = string.rep(' ', level) session[#session + 1] = split_line:format(spaces, number, vertical, size) - spaces = (' '):rep(level + 1) + spaces = string.rep(' ', level + 1) if c1[1] and c1[2] then write_split(c1, level + 1, 1) else @@ -185,11 +188,11 @@ function M.save(filename) session[#session + 1] = view_line:format('', 1, _BUFFERS[splits.buffer]) end -- Write out the current focused view. - session[#session + 1] = ("current_view: %d"):format(_VIEWS[view]) + session[#session + 1] = string.format('current_view: %d', _VIEWS[view]) -- Write out other things. for i = 1, #io.recent_files do if i > M.MAX_RECENT_FILES then break end - session[#session + 1] = ("recent: %s"):format(io.recent_files[i]) + session[#session + 1] = string.format('recent: %s', io.recent_files[i]) end -- Write the session. local f = io.open(filename, 'wb') @@ -208,8 +211,8 @@ 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 lfs.attributes(name) then M.load(name) return end - M.load(_USERHOME..'/'..name) + if not lfs.attributes(name) then name = _USERHOME..'/'..name end + M.load(name) end, 'Load session') return M diff --git a/modules/textadept/snippets.lua b/modules/textadept/snippets.lua index e0829b1d..64b9c385 100644 --- a/modules/textadept/snippets.lua +++ b/modules/textadept/snippets.lua @@ -159,7 +159,7 @@ local function new_snippet(text, trigger) -- Convert and match indentation. local lines = {} - local indent = {[true] = '\t', [false] = (' '):rep(buffer.tab_width)} + local indent = {[true] = '\t', [false] = string.rep(' ', buffer.tab_width)} local use_tabs = buffer.use_tabs for line in (text..'\n'):gmatch('([^\r\n]*)\r?\n') do lines[#lines + 1] = line:gsub('^(%s*)', function(indentation) @@ -355,7 +355,7 @@ function M._select() local lexer = buffer:get_lexer(true) for trigger, text in pairs(snippets[lexer] or {}) do if type(text) == 'string' then - list[#list + 1] = trigger..'\0'..lexer..'\0'..text + list[#list + 1] = string.format('%s\0%s\0%s', trigger, lexer, text) end end table.sort(list) |