diff options
author | 2010-08-21 01:14:24 -0400 | |
---|---|---|
committer | 2010-08-21 01:14:24 -0400 | |
commit | f41a788cb424b31fd687253e8db3fd448a693b4a (patch) | |
tree | d733e35486108a29afcac5d84a9adfd03dcb30c4 /modules | |
parent | 0c1718a568f4db2661ab3fc960beba22ce5ff00c (diff) | |
download | textadept-f41a788cb424b31fd687253e8db3fd448a693b4a.tar.gz textadept-f41a788cb424b31fd687253e8db3fd448a693b4a.zip |
Added Lua autocompletion support.
Diffstat (limited to 'modules')
-rw-r--r-- | modules/lua/api/_G.luadoc | 64 | ||||
-rw-r--r-- | modules/lua/api/coroutine.luadoc | 10 | ||||
-rw-r--r-- | modules/lua/api/debug.luadoc | 18 | ||||
-rw-r--r-- | modules/lua/api/io.luadoc | 50 | ||||
-rw-r--r-- | modules/lua/api/math.luadoc | 48 | ||||
-rw-r--r-- | modules/lua/api/os.luadoc | 24 | ||||
-rw-r--r-- | modules/lua/api/string.luadoc | 33 | ||||
-rw-r--r-- | modules/lua/api/table.luadoc | 22 | ||||
-rw-r--r-- | modules/lua/commands.lua | 182 |
9 files changed, 451 insertions, 0 deletions
diff --git a/modules/lua/api/_G.luadoc b/modules/lua/api/_G.luadoc new file mode 100644 index 00000000..45fbe8fc --- /dev/null +++ b/modules/lua/api/_G.luadoc @@ -0,0 +1,64 @@ +-- * `_G`: Holds global environment, setfenv changes environments. +-- * `_VERSION`: Current interpreter version "Lua 5.0". +--- Error if v nil or false, otherwise returns v. +function assert(v [, message]) +--- Set threshold to limit KBytes, default 0, may run GC. +function collectgarbage([limit]) +--- Executes as Lua chunk, default stdin, returns value. +function dofile(filename) +--- Terminates protected func, never returns, level 1(default), 2=parent. +function error(message [, level]) +--- Returns dynamic mem in use(KB), and current GC threshold(KB). +function gcinfo() +--- +-- Gets env, f can be a function or number(stack level, default=1), 0=global +-- env. +function getfenv(f) +--- Returns metatable of given object, otherwise nil. +function getmetatable(object) +--- Returns an iterator function, table t and 0. +function ipairs(t) +--- +-- Loads chunk without execution, returns chunk as function, else nil plus +-- error. +function loadfile(filename) +--- Links to dynamic library libname, returns funcname as a C function. +function loadlib(libname, funcname) +--- Loads string as chunk, returns chunk as function, else nil plus error. +function loadstring(string [, chunkname]) +--- Returns next index,value pair, if index=nil(default), returns first index. +function next(table [, index]) +--- +-- Returns the next function and table t plus a nil, iterates over all key-value +-- pairs. +function pairs(t) +--- +-- Protected mode call, catches errors, returns status code first +--(true=success). +function pcall(f, arg1, arg2, ...) +--- Prints values to stdout using tostring. +function print(e1, e2, ...) +--- Non-metamethod v1==v2, returns boolean. +function rawequal(v1, v2) +--- Non-metamethod get value of table[index], index != nil. +function rawget(table, index) +--- Non-metamethod set value of table[index], index != nil. +function rawset(table, index, value) +--- Loads package, updates _LOADED, returns boolean. +function require(packagename) +--- +-- Sets env, f can be a function or number(stack level, default=1), 0=global +-- env. +function setfenv(f, table) +--- Sets metatable, nil to remove metatable. +function setmetatable(table, metatable) +--- Convert to number, returns number, nil if non-convertible, 2<=base<=36. +function tonumber(e [, base]) +--- Convert to string, returns string. +function tostring(e) +--- Returns type of v as a string. +function type(v) +--- Returns all elements from list. +function unpack(list) +--- pcall function f with new error handler err. +function xpcall(f, err) diff --git a/modules/lua/api/coroutine.luadoc b/modules/lua/api/coroutine.luadoc new file mode 100644 index 00000000..7e60f275 --- /dev/null +++ b/modules/lua/api/coroutine.luadoc @@ -0,0 +1,10 @@ +--- Creates coroutine from function f, returns coroutine. +function create(f) +-- Continues execution of co, returns bool status plus any values. +function resume(co, val1, ...) +--- Returns co status: "running", "suspended" or "dead". +function status(co) +--- Creates coroutine with body f, returns function that resumes co. +function wrap(f) +--- Suspend execution of calling coroutine. +function yield(val1, ...) diff --git a/modules/lua/api/debug.luadoc b/modules/lua/api/debug.luadoc new file mode 100644 index 00000000..fb7c83f3 --- /dev/null +++ b/modules/lua/api/debug.luadoc @@ -0,0 +1,18 @@ +--- Enters interactive debug mode, line with only "cont" terminates. +function debug() +--- Returns current hook function, hook mask, hook count. +function gethook() +--- Returns table with information about a function. +function getinfo(function [, what]) +--- Returns name and value of local variable with index local at stack level. +function getlocal(level, local) +--- Returns name and value of upvalue with index up of function func. +function getupvalue(func, up) +--- Sets given function as a hook, mask="[crl]". +function sethook(hook, mask [, count]) +--- Sets local variable with index local at stack level with value. +function setlocal(level, local, value) +--- Sets upvalue with index up of function func with value. +function setupvalue(func, up, value) +--- Returns a string with a traceback of the call stack. +function traceback([message]) diff --git a/modules/lua/api/io.luadoc b/modules/lua/api/io.luadoc new file mode 100644 index 00000000..adf4edfe --- /dev/null +++ b/modules/lua/api/io.luadoc @@ -0,0 +1,50 @@ +--- Closes file, or the default output file. +function close([file]) +--- Flushes the default output file. +function flush() +--- +-- Opens file in text mode, sets as default input file, or returns current +-- default input file. +function input([file]) +--- Open file in read mode, returns iterator function to return lines, nil ends. +function lines([filename]) +--- Opens file in specified mode "[rawb+]", returns handle or nil. +function open(filename [, mode]) +--- +-- Opens file in text mode, sets as default output file, or returns current +-- default output file. +function output([file]) +--- Reads file according to given formats, returns read values or nil. +function read(format1, ...) +-- * `stderr`: File descriptor for STDERR. +-- * `stdin`: File descriptor for STDIN. +-- * `stdout`: File descriptor for STDOUT. +--- Returns a handle for a temporary file, opened in update mode. +function tmpfile() +--- +-- Returns "file" if obj is an open file handle, "close file" if closed, or nil +-- if not a file handle. +function type(obj) +--- Writes strings or numbers to file. +function write(value1, ...) + +--- +-- Opens a list of files. +-- @param utf8_filenames A '\n' separated list of filenames to open. If none +-- specified, the user is prompted to open files from a dialog. These paths +-- must be encoded in UTF-8. +-- @usage io.open_file(utf8_encoded_filename) +function open_file(utf8_filenames) + +--- +-- Saves all dirty buffers to their respective files. +-- @usage io.save_all() +function save_all() + +--- +-- Closes all open buffers. +-- If any buffer is dirty, the user is prompted to continue. No buffers are +-- saved automatically. They must be saved manually. +-- @usage io.close_all() +-- @return true if user did not cancel. +function close_all() diff --git a/modules/lua/api/math.luadoc b/modules/lua/api/math.luadoc new file mode 100644 index 00000000..7c84a80e --- /dev/null +++ b/modules/lua/api/math.luadoc @@ -0,0 +1,48 @@ +--- Returns absolute value of v. +function abs(v) +--- Returns arc cosine value of v in radians. +function acos(v) +--- Returns arc sine value of v in radians. +function asin(v) +--- Returns arc tangent value of v in radians. +function atan(v) +--- Returns arc tangent value of v1/v2 in radians. +function atan2(v1, v2) +--- Returns smallest integer >= v. +function ceil(v) +--- Returns cosine value of angle rad. +function cos(rad) +--- Returns angle in degrees of radians rad. +function deg(rad) +--- Returns e^v. +function exp(v) +--- Returns largest integer <= v. +function floor(v) +--- Returns mantissa [0.5,1) and exponent values of v. +function frexp(v) +--- Returns v1*2^v2. +function ldexp(v1, v2) +--- Returns natural logarithm of v. +function log(v) +--- Returns logarithm 10 of v. +function log10(v) +--- Returns maximum in a list of one or more values. +function max(v1, ...) +--- Returns minimum in a list of one or more values. +function min(v1, ...) +--- Returns remainder of v1/v2 which is v1 - iV2 for some integer i. +function mod(v1, v2) +--- Returns v1 raised to the power of v2. +function pow(v1, v2) +--- Returns angle in radians of degrees deg. +function rad(deg) +--- Returns random real [0,1), integer [1,n] or real [1,u](with n=1). +function random([n [, u]]) +--- Sets seed for pseudo-random number generator. +function randomseed(seed) +--- Returns sine value of angle rad . +function sin(rad) +--- Returns square root of v. +function sqrt(v) +--- Returns tangent value of angle rad. +function tan(rad) diff --git a/modules/lua/api/os.luadoc b/modules/lua/api/os.luadoc new file mode 100644 index 00000000..cb8ca275 --- /dev/null +++ b/modules/lua/api/os.luadoc @@ -0,0 +1,24 @@ +--- Returns CPU time used by program in seconds. +function clock() +--- Returns a string or table containing date and time, "*t" returns a table. +function date([format [, time]]) +--- Returns number of seconds from time t1 to time t2. +function difftime(t2, t1) +--- Executes command using C function system, returns status code. +function execute(command) +--- Terminates host program with optional code, default is success code. +function exit([code]) +--- Returns value of environment variable varname. nil if not defined. +function getenv(varname) +--- Deletes file with given name, nil if fails. +function remove(filename) +--- Renames file oldname to newname, nil if fails. +function rename(oldname, newname) +--- Set current locale of program, returns name of new locate or nil. +function setlocale(locale [, category]) +--- Returns current time(usually seconds) or time as represented by table. +function time([table]) +--- +-- Returns a string with a filename for a temporary file(dangerous! tmpfile is +-- better). +function tmpname() diff --git a/modules/lua/api/string.luadoc b/modules/lua/api/string.luadoc new file mode 100644 index 00000000..e1f99e82 --- /dev/null +++ b/modules/lua/api/string.luadoc @@ -0,0 +1,33 @@ +--- Returns numerical code, nil if index out of range, default i=1. +function byte(s [, i]) +--- Returns a string built from 0 or more integers. +function char(i1, i2, ...) +--- Returns binary representation of function, used with loadstring. +function dump(function) +--- Matches pattern in s, returns start,end indices, else nil. +function find(s, pattern [, init [, plain]]) +--- Returns formatted string, printf-style. +function format(formatstring, e1, e2, ...) +--- Returns iterator function that returns next captures from pattern pat on s. +function gfind(s, pat) +--- Returns copy of s with pat replaced by repl, and substitutions made. +function gsub(s, pat, repl [, n]) +--- Returns string length. +function len(s) +--- Returns string with letters in lower case. +function lower(s) +--- Returns string with n copies of string s. +function rep(s, n) +--- Returns substring from index i to j of s, default j=-1(string length). +function sub(s, i [, j]) +--- Returns string with letters in upper case. +function upper(s) + +--- +-- Converts a string from one character set to another using iconv(). +-- Valid character sets are ones GLib's g_convert() accepts, typically GNU +-- iconv's character sets. +-- @param text The text to convert. +-- @param to The character set to convert to. +-- @param from The character set to convert from. +function iconv(text, to, from) end diff --git a/modules/lua/api/table.luadoc b/modules/lua/api/table.luadoc new file mode 100644 index 00000000..81f5a369 --- /dev/null +++ b/modules/lua/api/table.luadoc @@ -0,0 +1,22 @@ +--- Returns concatenated table elements i to j separated by sep. +function concat(table [, sep [, i [, j]]]) +--- +-- Executes f(index,value) over all elements of table, returns first non-nil of +-- f. +function foreach(table, f) +--- +-- Executes f(index,value) in sequential order 1 to n, returns first non-nil of +-- f. +function foreachi(table, f) +--- +-- Returns size of table, or n field, or table.setn value, or 1 less first index +-- with nil value. +function getn(table) +--- Insert value at location pos in table, default pos=n+1. +function insert(table, [pos,] value) +--- Removes element at pos from table, default pos=n. +function remove(table [, pos]) +--- Sets size of table, n field of table if it exists. +function setn(table, n) +--- Sorts in-place elements 1 to n, comp(v1,v2) true if v1<v2, default <. +function sort(table [, comp]) diff --git a/modules/lua/commands.lua b/modules/lua/commands.lua index 0489ea56..f1902764 100644 --- a/modules/lua/commands.lua +++ b/modules/lua/commands.lua @@ -4,6 +4,68 @@ -- Commands for the lua module. module('_m.lua.commands', package.seeall) +-- Markdown: +-- ## Key Commands +-- +-- + `Alt+l, m`: Open this module for editing. +-- + `Alt+l, g`: Goto file being 'require'd on the current line. +-- + `Shift+Return`: Try to autocomplete an `if`, `for`, etc. statement with +-- `end`. +-- + `.`: When to the right of a known identifier, show an autocompletion list +-- of fields. +-- + `:`: When to the right of a known identifier, show an autocompletion list +-- of functions. +-- + `Tab`: When the caret is to the right of a `(` in a known function call, +-- show a calltip with documentation for the function. +-- +-- ## Autocompletion of Fields and Functions +-- +-- This module parses files in the `api_files` table for LuaDoc documentation. +-- Currently all Textadept and Lua identifiers are supported. +-- +-- #### Syntax +-- +-- Fields are recognized as Lua line comments of the form ``-- * `field_name` ``. +-- Functions are recognized as Lua functions of the form `function func(args)` +-- or `function namespace:func(args)`. `.`-completion shows autocompletion for +-- both fields and functions using the first function syntax. `:`-completion +-- shows completions for functions only. Any LuaDoc starting with `---` and +-- including any subsequent comments up until the function declaration will be +-- shown with a calltip when requested. +-- +-- In order to be recognized, all comments and functions MUST begin the line. +-- +-- Syntatically valid Lua code is not necessary for parsing; only the patterns +-- described above are necessary. +-- +-- For example: +-- +-- In file `~/.textadept/modules/foo/foo.luadoc`: +-- +-- -- * `bar`: Bar field. +-- +-- --- LuaDoc for bar. +-- function baz() +-- +-- --- +-- -- LuaDoc for foobar. +-- -- @param barfoo First arg. +-- function foobar(barfoo) +-- +-- --- +-- -- LuaDoc for foo:barbaz. +-- -- @param foo Foo table. +-- function foo:barbaz() +-- +-- In file `_HOME/modules/lua/commands.lua` below `api_files` declaration: +-- +-- api_files['foo'] = _USERHOME..'/modules/foo/foo.luadoc' +-- +-- In any Lua file: +-- +-- foo. -- shows autocompletion list with [bar, baz, foobar]. +-- foo: -- shows autocompletion list with [foobar, barbaz]. + local m_editing, m_run = _m.textadept.editing, _m.textadept.run -- Comment string tables use lexer names. m_editing.comment_string.lua = '--' @@ -73,6 +135,111 @@ function goto_required() end end +--- +-- LuaDoc to load API from. +-- Keys are Lua table names with LuaDoc file values. +-- @class table +-- @name api_files +local api_files = { + ['args'] = _HOME..'/core/args.lua', + ['buffer'] = _HOME..'/core/.buffer.luadoc', + ['events'] = _HOME..'/core/events.lua', + ['gui'] = _HOME..'/core/.gui.luadoc', + ['gui.find'] = _HOME..'/core/.find.luadoc', + ['gui.command_entry'] = _HOME..'/core/.command_entry.luadoc', + ['l'] = _HOME..'/lexers/lexer.lua', + ['view'] = _HOME..'/core/.view.luadoc', +} +-- Add API for loaded textadept modules. +for p, _ in pairs(package.loaded) do + if p:find('^_m%.textadept%.') then + api_files[p] = _HOME..'/modules/textadept/'..p:match('[^%.]+$')..'.lua' + end +end +-- Add Lua API +local lua = { 'coroutine', 'debug', 'io', 'math', 'os', 'string', 'table' } +for _, m in ipairs(lua) do + api_files[m] = _HOME..'/modules/lua/api/'..m..'.luadoc' +end +api_files[''] = _HOME..'/modules/lua/api/_G.luadoc' + +local lfs = require 'lfs' + +-- Load API. +local apis = {} +local current_doc = '' +local f_args = {} +for word, api_file in pairs(api_files) do + if lfs.attributes(api_file) then + apis[word] = { fields = {}, funcs = {} } + for line in io.lines(api_file) do + if line:match('^%-%- %* `([^`]+)`') then -- field + local fields = apis[word].fields + fields[#fields + 1] = line:match('^%-%- %* `([^`]+)`')..'?2' + elseif line:match('^function ') then -- function + local f, n = line:match('^function [%w_]+:(([%w_]+)%([^)]*%))') + if not f then + f, n = line:match('^function (([%w_]+)%([^)]*%))') + local fields = apis[word].fields + fields[#fields + 1] = n..'?1' + end + local funcs = apis[word].funcs + funcs[#funcs + 1] = n..'?1' + if f and #current_doc > 0 then + f = f..current_doc + 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('^%-%-%-? (.+)$') + elseif #current_doc > 0 then + current_doc = '' + end + end + table.sort(apis[word].fields) + table.sort(apis[word].funcs) + end +end + +local f_xpm = '/* XPM */\nstatic char *function[] = {\n/* columns rows colors chars-per-pixel */\n"16 16 5 1",\n" c black",\n". c #E0BC38",\n"X c #F0DC5C",\n"o c #FCFC80",\n"O c None",\n/* pixels */\n"OOOOOOOOOOOOOOOO",\n"OOOOOOOOOOOOOOOO",\n"OOOOOOOOOOOOOOOO",\n"OOOOOOOOOO OOOO",\n"OOOOOOOOO oo OO",\n"OOOOOOOO ooooo O",\n"OOOOOOO ooooo. O",\n"OOOO O XXoo.. O",\n"OOO oo XXX... O",\n"OO ooooo XX.. OO",\n"O ooooo. X. OOO",\n"O XXoo.. O OOOO",\n"O XXX... OOOOOOO",\n"O XXX.. OOOOOOOO",\n"OO X. OOOOOOOOO",\n"OOOO OOOOOOOOOO"\n};' +local v_xpm = '/* XPM */\nstatic char *field[] = {\n/* columns rows colors chars-per-pixel */\n"16 16 5 1",\n" c black",\n". c #8C748C",\n"X c #9C94A4",\n"o c #ACB4C0",\n"O c None",\n/* pixels */\n"OOOOOOOOOOOOOOOO",\n"OOOOOOOOOOOOOOOO",\n"OOOOOOOOOOOOOOOO",\n"OOOOOOOOOOOOOOOO",\n"OOOOOOOOOOOOOOOO",\n"OOOOOOOOOOOOOOOO",\n"OOOOOOOOO OOOOO",\n"OOOOOOOO oo OOO",\n"OOOOOOO ooooo OO",\n"OOOOOO ooooo. OO",\n"OOOOOO XXoo.. OO",\n"OOOOOO XXX... OO",\n"OOOOOO XXX.. OOO",\n"OOOOOOO X. OOOO",\n"OOOOOOOOO OOOOO",\n"OOOOOOOOOOOOOOOO"\n};' + +--- +-- [Local function] Returns word specified by patt behind the caret. +-- @param patt Lua pattern containing word characters. +-- @param pos Optional position to start from. +-- @return word. +local function prev_word(patt, pos) + 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 + return buffer:text_range(s + 1, e) +end + +--- +-- [Local function] Shows autocompletion list. +-- @param len Length passed to buffer:auto_c_show. +-- @param completions Table of completions. +-- @see buffer:auto_c_show. +local function auto_c_show(len, completions) + buffer:clear_registered_images() + buffer:register_image(1, f_xpm) + buffer:register_image(2, v_xpm) + buffer:auto_c_show(len, table.concat(completions, ' ')) +end + +events.connect('char_added', + function(c) -- show autocomplete list or calltip + if c == 46 or c == 58 then -- '.' or ':' + if buffer:get_lexer() ~= 'lua' then return end + local word = prev_word('[%w_%.]') + if word == '' or not apis[word] then return end + auto_c_show(0, c == 46 and apis[word].fields or apis[word].funcs) + end + end) + -- Lua-specific key commands. local keys = _G.keys if type(keys) == 'table' then @@ -83,5 +250,20 @@ if type(keys) == 'table' then g = { goto_required }, }, ['s\n'] = { try_to_autocomplete_end }, + [not MAC and 'c\n' or 'esc'] = { function() -- complete API + local part = prev_word('[%w_]', buffer.current_pos) + local pos = buffer.current_pos - #part - 1 + if pos > 0 then + local word = prev_word('[%w_%.]', pos) + if word == '' or not apis[word] then return false end -- handle normally + local c = buffer.char_at[pos] + auto_c_show(#part, c == 46 and apis[word].fields or apis[word].funcs) + end + end }, + ['\t'] = { function() -- show API calltip + local func = prev_word('[%w_%.:]') + if not f_args[func] then return false end -- handle normally + buffer:call_tip_show(buffer.current_pos, f_args[func]) + end }, } end |