diff options
author | 2011-02-28 16:59:56 -0500 | |
---|---|---|
committer | 2011-02-28 16:59:56 -0500 | |
commit | 146faf6242a5dff7f9a7c4f295a1ce32aedbc5b8 (patch) | |
tree | 1ee109dfa5ba053abfaf1d51b273f268adc5e9cd | |
parent | ade0a0f1ff13bdccb6f0cad13449b2b13eaff70f (diff) | |
download | textadept-146faf6242a5dff7f9a7c4f295a1ce32aedbc5b8.tar.gz textadept-146faf6242a5dff7f9a7c4f295a1ce32aedbc5b8.zip |
Condense language modules into single init.lua file.
-rw-r--r-- | modules/cpp/adeptsense.lua | 32 | ||||
-rw-r--r-- | modules/cpp/commands.lua | 57 | ||||
-rw-r--r-- | modules/cpp/init.lua | 164 | ||||
-rw-r--r-- | modules/cpp/snippets.lua | 75 | ||||
-rw-r--r-- | modules/lua/adeptsense.lua | 47 | ||||
-rw-r--r-- | modules/lua/commands.lua | 124 | ||||
-rw-r--r-- | modules/lua/init.lua | 193 | ||||
-rw-r--r-- | modules/lua/snippets.lua | 19 | ||||
-rw-r--r-- | modules/textadept/adeptsense.lua | 19 | ||||
-rw-r--r-- | modules/textadept/bookmarks.lua | 2 |
10 files changed, 336 insertions, 396 deletions
diff --git a/modules/cpp/adeptsense.lua b/modules/cpp/adeptsense.lua deleted file mode 100644 index 92890ea3..00000000 --- a/modules/cpp/adeptsense.lua +++ /dev/null @@ -1,32 +0,0 @@ --- Copyright 2007-2011 Mitchell mitchell<att>caladbolg.net. See LICENSE.
-
----
--- Adeptsense for the cpp module.
--- User tags are loaded from _USERHOME/modules/cpp/tags and user apis are loaded
--- from _USERHOME/modules/cpp/api.
-module('_m.cpp.adeptsense', package.seeall)
-
-sense = _m.textadept.adeptsense.new('cpp')
-sense.ctags_kinds = {
- c = 'classes',
- d = 'functions',
- e = 'fields',
- f = 'functions',
- g = 'classes',
- m = 'fields',
- s = 'classes',
- t = 'classes'
-}
-sense.syntax.type_declarations = {
- '(%u[%w_%.]+)[%s%*&]+%_[^%w_]', -- Foo bar, Foo *bar, Foo* bar, Foo &bar, etc.
-}
-sense:add_trigger('.')
-sense:add_trigger('->')
-
--- Load user tags and apidoc.
-if lfs.attributes(_USERHOME..'/modules/cpp/tags') then
- sense:load_ctags(_USERHOME..'/modules/cpp/tags')
-end
-if lfs.attributes(_USERHOME..'/modules/cpp/api') then
- sense.api_files[#sense.api_files + 1] = _USERHOME..'/modules/cpp/api'
-end
diff --git a/modules/cpp/commands.lua b/modules/cpp/commands.lua deleted file mode 100644 index a74d83a5..00000000 --- a/modules/cpp/commands.lua +++ /dev/null @@ -1,57 +0,0 @@ --- Copyright 2007-2011 Mitchell mitchell<att>caladbolg.net. See LICENSE. - ---- --- Commands for the cpp module. -module('_m.cpp.commands', package.seeall) - --- Markdown: --- ## Key Commands --- --- + `Alt+L, M`: Open this module for editing. --- + `.`: When to the right of a known symbol, show an autocompletion list of --- fields and functions. --- + `->`: When to the right of a known symbol, show an autocompletion list of --- fields and functions. --- + `Ctrl+I`: (Windows and Linux) Autocomplete symbol. --- + `~`: (Mac OSX) Autocomplete symbol. --- + `Ctrl+H`: Show documentation for the selected symbol or the symbol under --- the caret. --- + `Shift+Return`: Add ';' to line end and insert newline. - -local m_editing, m_run = _m.textadept.editing, _m.textadept.run --- Comment string tables use lexer names. -m_editing.comment_string.cpp = '//' --- Compile and Run command tables use file extensions. -m_run.compile_command.c = - 'gcc -pedantic -Os -o "%(filename_noext)" %(filename)' -m_run.compile_command.cpp = - 'g++ -pedantic -Os -o "%(filename_noext)" %(filename)' -m_run.run_command.c = '%(filedir)%(filename_noext)' -m_run.run_command.cpp = '%(filedir)%(filename_noext)' -m_run.error_detail.c = { - pattern = '^(.-):(%d+): (.+)$', - filename = 1, line = 2, message = 3 -} - --- C++-specific key commands. -local cppsense = _m.cpp.adeptsense.sense -local keys = _G.keys -if type(keys) == 'table' then - keys.cpp = { - al = { - m = { io.open_file, - (_HOME..'/modules/cpp/init.lua'):iconv('UTF-8', _CHARSET) }, - }, - ['s\n'] = { function() - buffer:line_end() - buffer:add_text(';') - buffer:new_line() - end }, - [not OSX and 'ci' or '~'] = { cppsense.complete, cppsense }, - ch = { cppsense.show_apidoc, cppsense }, - } -end - ---- --- This module contains no functions. -function no_functions() end no_functions = nil diff --git a/modules/cpp/init.lua b/modules/cpp/init.lua index cce101a8..55555a65 100644 --- a/modules/cpp/init.lua +++ b/modules/cpp/init.lua @@ -3,28 +3,166 @@ --- -- The cpp module. -- It provides utilities for editing C/C++ code. +-- User tags are loaded from _USERHOME/modules/cpp/tags and user apis are loaded +-- from _USERHOME/modules/cpp/api. module('_m.cpp', package.seeall) -if type(_G.snippets) == 'table' then +-- Markdown: +-- ## Key Commands +-- +-- + `Alt+L, M`: Open this module for editing. +-- + `.`: When to the right of a known symbol, show an autocompletion list of +-- fields and functions. +-- + `->`: When to the right of a known symbol, show an autocompletion list of +-- fields and functions. +-- + `Ctrl+I`: (Windows and Linux) Autocomplete symbol. +-- + `~`: (Mac OSX) Autocomplete symbol. +-- + `Ctrl+H`: Show documentation for the selected symbol or the symbol under +-- the caret. +-- + `Shift+Return`: Add ';' to line end and insert newline. +-- +-- ## Fields +-- +-- * `sense`: The C/C++ [Adeptsense](_m.textadept.adeptsense.html). + +local m_editing, m_run = _m.textadept.editing, _m.textadept.run +-- Comment string tables use lexer names. +m_editing.comment_string.cpp = '//' +-- Compile and Run command tables use file extensions. +m_run.compile_command.c = + 'gcc -pedantic -Os -o "%(filename_noext)" %(filename)' +m_run.compile_command.cpp = + 'g++ -pedantic -Os -o "%(filename_noext)" %(filename)' +m_run.run_command.c = '%(filedir)%(filename_noext)' +m_run.run_command.cpp = '%(filedir)%(filename_noext)' +m_run.error_detail.c = { + pattern = '^(.-):(%d+): (.+)$', + filename = 1, line = 2, message = 3 +} + --- --- Container for C/C++-specific snippets. --- @class table --- @name snippets.cpp - _G.snippets.cpp = {} +-- Sets default buffer properties for C/C++ files. +function set_buffer_properties() + end -if type(_G.keys) == 'table' then +-- Adeptsense. + +sense = _m.textadept.adeptsense.new('cpp') +sense.ctags_kinds = { + c = 'classes', + d = 'functions', + e = 'fields', + f = 'functions', + g = 'classes', + m = 'fields', + s = 'classes', + t = 'classes' +} +sense.syntax.type_declarations = { + '(%u[%w_%.]+)[%s%*&]+%_[^%w_]', -- Foo bar, Foo *bar, Foo* bar, Foo &bar, etc. +} +sense:add_trigger('.') +sense:add_trigger('->') + +-- Load user tags and apidoc. +if lfs.attributes(_USERHOME..'/modules/cpp/tags') then + sense:load_ctags(_USERHOME..'/modules/cpp/tags') +end +if lfs.attributes(_USERHOME..'/modules/cpp/api') then + sense.api_files[#sense.api_files + 1] = _USERHOME..'/modules/cpp/api' +end + +-- Commands. + --- -- Container for C/C++-specific key commands. -- @class table --- @name keys.cpp - _G.keys.cpp = {} -end +-- @name _G.keys.cpp +_G.keys.cpp = { + al = { + m = { io.open_file, + (_HOME..'/modules/cpp/init.lua'):iconv('UTF-8', _CHARSET) }, + }, + ['s\n'] = { function() + buffer:line_end() + buffer:add_text(';') + buffer:new_line() + end }, + [not OSX and 'ci' or '~'] = { sense.complete, sense }, + ch = { sense.show_apidoc, sense }, +} -require 'cpp.adeptsense' -require 'cpp.commands' -require 'cpp.snippets' +-- Snippets. -function set_buffer_properties() +--- +-- Container for C/C++-specific snippets. +-- @class table +-- @name _G.snippets.cpp +if type(_G.snippets) == 'table' then + _G.snippets.cpp = { + rc = 'reinterpret_cast<%1>(%2(%(selected_text)))', + sc = 'static_cast<%1>(%2(%(selected_text)))', + cc = 'const_cast<%1>(%2(%(selected_text)))', + -- Lua snippets + lf = 'static int %1(function)(lua_State *%2(lua)) {\n\t%0\n\treturn 0;\n}', + ls = 'lua_State', + lgf = 'lua_getfield(%1(lua), %2(-1), %3(field));', + lgg = 'lua_getglobal(%1(lua), %2(global));', + lgt = 'lua_gettable(%1(lua), %2(-2));', + ltop = 'lua_gettop(%1(lua));', + lib = 'lua_isboolean(%1(lua), %2(-1))', + licf = 'lua_iscfunction(%1(lua), %2(-1))', + lif = 'lua_isfunctionu(%1(lua), %2(-1))', + linil = 'lua_isnil(%1(lua), %2(-1))', + linone = 'lua_isnone(%1(lua), %2(-1))', + linonen = 'lua_isnoneornil(%1(lua), %2(-1))', + lin = 'lua_isnumber(%1(lua), %2(-1))', + lis = 'lua_isstring(%1(lua), %2(-1))', + lit = 'lua_istable(%1(lua), %2(-1))', + lith = 'lua_isthread(%1(lua), %2(-1))', + liu = 'lua_isuserdata(%1(lua), %2(-1))', + llen = 'lua_objlen(%1(lua), %2(-1))', + lpop = 'lua_pop(%1(lua), %2(1));', + lpb = 'lua_pushboolean(%1(lua), %2(boolean));', + lpcc = 'lua_pushcclosure(%1(lua), %2(closure_func), %3(num_values));', + lpcf = 'lua_pushcfunction(%1(lua), %2(cfunction));', + lpi = 'lua_pushinteger(%1(lua), %2(integer));', + lplu = 'lua_pushlightuserdata(%1(lua), %2(userdata));', + lpnil = 'lua_pushnil(%1(lua));', + lpn = 'lua_pushnumber(%1(lua), %2(number));', + lps = 'lua_pushstring(%1(lua), %2(string));', + lpth = 'lua_pushthread(%1(lua));', + lpv = 'lua_pushvalue(%1(lua), %2(-1));', + lrg = 'lua_rawget(%1(lua), %2(-2));', + lrgi = 'lua_rawgeti(%1(lua), %2(-2), %3(1));', + lrs = 'lua_rawset(%1(lua), %2(-3));', + lrsi = 'lua_rawseti(%1(lua), %2(-2), %3(1));', + lr = 'lua_register(%1(lua), %2(fname), %3(cfunction));', + lsf = 'lua_setfield(%1(lua), %2(-2), %3(field));', + lsg = 'lua_setglobal(%1(lua), %2(global));', + lst = 'lua_settable(%1(lua), %2(-3));', + ltb = 'lua_toboolean(%1(lua), %2(-1))', + ltcf = 'lua_tocfunction(%1(lua), %2(-1))', + lti = 'lua_tointeger(%1(lua), %2(-1))', + ltn = 'lua_tonumber(%1(lua), %2(-1))', + ltp = 'lua_topointer(%1(lua), %2(-1))', + lts = 'lua_tostring(%1(lua), %2(-1))', + ltth = 'lua_tothread(%1(lua), %2(-1))', + ltu = 'lua_touserdata(%1(lua), %2(-1))', + lt = 'lua_type(%1(lua), %2(-1))', + llcint = 'luaL_checkint(%1(lua), %2(-1))', + llci = 'luaL_checkinteger(%1(lua), %2(-1))', + llcl = 'luaL_checklong(%1(lua), %2(-1))', + llcn = 'luaL_checknumber(%1(lua), %2(-1))', + llcs = 'luaL_checkstring(%1(lua), %2(-1))', + llcu = 'luaL_checkudata(%1(lua), %2(-1), %3(mt_name))', + llerr = 'luaL_error(%1(lua), %2(errorstring)%3(, %4(arg)));', + lloint = 'luaL_optint(%1(lua), %2(-1), %3(default))', + lloi = 'luaL_optinteger(%1(lua), %2(-1), %3(default))', + llol = 'luaL_optlong(%1(lua), %2(-1), %3(default))', + llon = 'luaL_optnumber(%1(lua), %2(-1), %3(default))', + llos = 'luaL_optstring(%1(lua), %2(-1), %3(default))', + } end diff --git a/modules/cpp/snippets.lua b/modules/cpp/snippets.lua deleted file mode 100644 index 68e4ef24..00000000 --- a/modules/cpp/snippets.lua +++ /dev/null @@ -1,75 +0,0 @@ --- Copyright 2007-2011 Mitchell mitchell<att>caladbolg.net. See LICENSE. - ---- --- Snippets for the cpp module. -module('_m.cpp.snippets', package.seeall) - -local snippets = _G.snippets - -if type(snippets) == 'table' then - snippets.cpp = { - rc = 'reinterpret_cast<%1>(%2(%(selected_text)))', - sc = 'static_cast<%1>(%2(%(selected_text)))', - cc = 'const_cast<%1>(%2(%(selected_text)))', - - -- Lua snippets - lf = 'static int %1(function)(lua_State *%2(lua)) {\n\t%0\n\treturn 0;\n}', - ls = 'lua_State', - lgf = 'lua_getfield(%1(lua), %2(-1), %3(field));', - lgg = 'lua_getglobal(%1(lua), %2(global));', - lgt = 'lua_gettable(%1(lua), %2(-2));', - ltop = 'lua_gettop(%1(lua));', - lib = 'lua_isboolean(%1(lua), %2(-1))', - licf = 'lua_iscfunction(%1(lua), %2(-1))', - lif = 'lua_isfunctionu(%1(lua), %2(-1))', - linil = 'lua_isnil(%1(lua), %2(-1))', - linone = 'lua_isnone(%1(lua), %2(-1))', - linonen = 'lua_isnoneornil(%1(lua), %2(-1))', - lin = 'lua_isnumber(%1(lua), %2(-1))', - lis = 'lua_isstring(%1(lua), %2(-1))', - lit = 'lua_istable(%1(lua), %2(-1))', - lith = 'lua_isthread(%1(lua), %2(-1))', - liu = 'lua_isuserdata(%1(lua), %2(-1))', - llen = 'lua_objlen(%1(lua), %2(-1))', - lpop = 'lua_pop(%1(lua), %2(1));', - lpb = 'lua_pushboolean(%1(lua), %2(boolean));', - lpcc = 'lua_pushcclosure(%1(lua), %2(closure_func), %3(num_values));', - lpcf = 'lua_pushcfunction(%1(lua), %2(cfunction));', - lpi = 'lua_pushinteger(%1(lua), %2(integer));', - lplu = 'lua_pushlightuserdata(%1(lua), %2(userdata));', - lpnil = 'lua_pushnil(%1(lua));', - lpn = 'lua_pushnumber(%1(lua), %2(number));', - lps = 'lua_pushstring(%1(lua), %2(string));', - lpth = 'lua_pushthread(%1(lua));', - lpv = 'lua_pushvalue(%1(lua), %2(-1));', - lrg = 'lua_rawget(%1(lua), %2(-2));', - lrgi = 'lua_rawgeti(%1(lua), %2(-2), %3(1));', - lrs = 'lua_rawset(%1(lua), %2(-3));', - lrsi = 'lua_rawseti(%1(lua), %2(-2), %3(1));', - lr = 'lua_register(%1(lua), %2(fname), %3(cfunction));', - lsf = 'lua_setfield(%1(lua), %2(-2), %3(field));', - lsg = 'lua_setglobal(%1(lua), %2(global));', - lst = 'lua_settable(%1(lua), %2(-3));', - ltb = 'lua_toboolean(%1(lua), %2(-1))', - ltcf = 'lua_tocfunction(%1(lua), %2(-1))', - lti = 'lua_tointeger(%1(lua), %2(-1))', - ltn = 'lua_tonumber(%1(lua), %2(-1))', - ltp = 'lua_topointer(%1(lua), %2(-1))', - lts = 'lua_tostring(%1(lua), %2(-1))', - ltth = 'lua_tothread(%1(lua), %2(-1))', - ltu = 'lua_touserdata(%1(lua), %2(-1))', - lt = 'lua_type(%1(lua), %2(-1))', - llcint = 'luaL_checkint(%1(lua), %2(-1))', - llci = 'luaL_checkinteger(%1(lua), %2(-1))', - llcl = 'luaL_checklong(%1(lua), %2(-1))', - llcn = 'luaL_checknumber(%1(lua), %2(-1))', - llcs = 'luaL_checkstring(%1(lua), %2(-1))', - llcu = 'luaL_checkudata(%1(lua), %2(-1), %3(mt_name))', - llerr = 'luaL_error(%1(lua), %2(errorstring)%3(, %4(arg)));', - lloint = 'luaL_optint(%1(lua), %2(-1), %3(default))', - lloi = 'luaL_optinteger(%1(lua), %2(-1), %3(default))', - llol = 'luaL_optlong(%1(lua), %2(-1), %3(default))', - llon = 'luaL_optnumber(%1(lua), %2(-1), %3(default))', - llos = 'luaL_optstring(%1(lua), %2(-1), %3(default))', - } -end diff --git a/modules/lua/adeptsense.lua b/modules/lua/adeptsense.lua deleted file mode 100644 index 9e6d86a2..00000000 --- a/modules/lua/adeptsense.lua +++ /dev/null @@ -1,47 +0,0 @@ --- Copyright 2007-2011 Mitchell mitchell<att>caladbolg.net. See LICENSE.
-
----
--- Adeptsense for the lua module.
--- User tags are loaded from _USERHOME/modules/lua/tags and user apis are loaded
--- from _USERHOME/modules/lua/api.
-module('_m.lua.adeptsense', package.seeall)
-
-sense = _m.textadept.adeptsense.new('lua')
-sense.syntax.class_definition = 'module%s*%(?%s*[\'"]([%w_%.]+)'
-sense.syntax.symbol_chars = '[%w_%.:]'
-sense.syntax.type_declarations = {}
-sense.syntax.type_assignments = {
- ['^[\'"]'] = 'string', -- foo = 'bar' or foo = "bar"
- ['^([%w_%.]+)%s*$'] = '%1' -- foo = _m.textadept.adeptsense
-}
-sense.api_files = { _HOME..'/modules/lua/api' }
-sense:add_trigger('.')
-sense:add_trigger(':', false, true)
-
--- script/update_doc generates a fake set of ctags used for autocompletion.
-sense.ctags_kinds = {
- f = 'functions',
- F = 'fields',
- m = 'classes',
- t = 'fields',
-}
-sense:load_ctags(_HOME..'/modules/lua/tags', true)
-
----
--- Shows an autocompletion list for the symbol behind the caret.
--- @param only_fields If true, returns list of only fields; defaults to false.
--- @param only_functions If true, returns list of only functions; defaults to
--- false.
-function sense:complete(only_fields, only_functions)
- local line, pos = buffer:get_cur_line()
- local symbol = line:sub(1, pos):match(self.syntax.symbol_chars..'*$')
- return self.super.complete(self, false, symbol:find(':'))
-end
-
--- Load user tags and apidoc.
-if lfs.attributes(_USERHOME..'/modules/lua/tags') then
- sense:load_ctags(_USERHOME..'/modules/lua/tags')
-end
-if lfs.attributes(_USERHOME..'/modules/lua/api') then
- sense.api_files[#sense.api_files + 1] = _USERHOME..'/modules/lua/api'
-end
diff --git a/modules/lua/commands.lua b/modules/lua/commands.lua deleted file mode 100644 index 06e1944c..00000000 --- a/modules/lua/commands.lua +++ /dev/null @@ -1,124 +0,0 @@ --- Copyright 2007-2011 Mitchell mitchell<att>caladbolg.net. See LICENSE. - ---- --- 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 symbol, show an autocompletion list of --- fields and functions. --- + `:`: When to the right of a known symbol, show an autocompletion list of --- functions only. --- + `Ctrl+I`: (Windows and Linux) Autocomplete symbol. --- + `~`: (Mac OSX) Autocomplete symbol. --- + `Ctrl+H`: Show documentation for the selected symbol or the symbol under --- the caret. - -local m_editing, m_run = _m.textadept.editing, _m.textadept.run --- Comment string tables use lexer names. -m_editing.comment_string.lua = '--' --- Compile and Run command tables use file extensions. -m_run.run_command.lua = 'lua %(filename)' -m_run.error_detail.lua = { - pattern = '^lua: (.-):(%d+): (.+)$', - filename = 1, line = 2, message = 3 -} - ---- --- Patterns for auto 'end' completion for control structures. --- @class table --- @name control_structure_patterns --- @see try_to_autocomplete_end -local control_structure_patterns = { - '^%s*for', '^%s*function', '^%s*if', '^%s*repeat', '^%s*while', - 'function%s*%b()%s*$', '^%s*local%s*function' -} - ---- --- Tries to autocomplete Lua's 'end' keyword for control structures like 'if', --- 'while', 'for', etc. --- @see control_structure_patterns -function try_to_autocomplete_end() - local buffer = buffer - local line_num = buffer:line_from_position(buffer.current_pos) - local line = buffer:get_line(line_num) - for _, patt in ipairs(control_structure_patterns) do - if line:find(patt) then - local indent = buffer.line_indentation[line_num] - buffer:begin_undo_action() - buffer:new_line() - buffer:new_line() - buffer:add_text(patt:find('repeat') and 'until' or 'end') - buffer.line_indentation[line_num + 1] = indent + buffer.indent - buffer:line_up() - buffer:line_end() - buffer:end_undo_action() - return true - end - end - return false -end - ---- --- Determines the Lua file being 'require'd, searches through package.path for --- that file, and opens it in Textadept. -function goto_required() - local line = buffer:get_cur_line() - local patterns = { 'require%s*(%b())', 'require%s*(([\'"])[^%2]+%2)' } - local file - for _, patt in ipairs(patterns) do - file = line:match(patt) - if file then break end - end - if not file then return end - file = file:sub(2, -2):gsub('%.', '/') - for path in package.path:gmatch('[^;]+') do - path = path:gsub('?', file) - if lfs.attributes(path) then - io.open_file(path:iconv('UTF-8', _CHARSET)) - break - end - end -end - -events.connect('file_after_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() - text = text:gsub('^#![^\n]+', '') -- ignore shebang line - local _, err = loadstring(text) - if err then - local line, msg = err:match('^.-:(%d+):%s*(.+)$') - if line then - buffer.annotation_visible = 2 - buffer:annotation_set_text(line - 1, msg) - buffer.annotation_style[line - 1] = 8 -- error style number - buffer:goto_line(line - 1) - end - end - end - end) - --- Lua-specific key commands. -local keys = _G.keys -local luasense = _m.lua.adeptsense.sense -if type(keys) == 'table' then - keys.lua = { - al = { - m = { io.open_file, - (_HOME..'/modules/lua/init.lua'):iconv('UTF-8', _CHARSET) }, - g = { goto_required }, - }, - ['s\n'] = { try_to_autocomplete_end }, - [not OSX and 'ci' or '~'] = { luasense.complete, luasense }, - ch = { luasense.show_apidoc, luasense }, - } -end diff --git a/modules/lua/init.lua b/modules/lua/init.lua index eb633a95..5ec8d005 100644 --- a/modules/lua/init.lua +++ b/modules/lua/init.lua @@ -3,28 +3,195 @@ --- -- The lua module. -- It provides utilities for editing Lua code. +-- User tags are loaded from _USERHOME/modules/lua/tags and user apis are loaded +-- from _USERHOME/modules/lua/api. module('_m.lua', package.seeall) -if type(_G.snippets) == 'table' then +-- 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 symbol, show an autocompletion list of +-- fields and functions. +-- + `:`: When to the right of a known symbol, show an autocompletion list of +-- functions only. +-- + `Ctrl+I`: (Windows and Linux) Autocomplete symbol. +-- + `~`: (Mac OSX) Autocomplete symbol. +-- + `Ctrl+H`: Show documentation for the selected symbol or the symbol under +-- the caret. +-- +-- ## Fields +-- +-- * `sense`: The Lua [Adeptsense](_m.textadept.adeptsense.html). + +local m_editing, m_run = _m.textadept.editing, _m.textadept.run +-- Comment string tables use lexer names. +m_editing.comment_string.lua = '--' +-- Compile and Run command tables use file extensions. +m_run.run_command.lua = 'lua %(filename)' +m_run.error_detail.lua = { + pattern = '^lua: (.-):(%d+): (.+)$', + filename = 1, line = 2, message = 3 +} + --- --- Container for Lua-specific snippets. --- @class table --- @name snippets.lua - _G.snippets.lua = {} +-- Sets default buffer properties for Lua files. +function set_buffer_properties() + end -if type(_G.keys) == 'table' then +-- Adeptsense. + +sense = _m.textadept.adeptsense.new('lua') +sense.syntax.class_definition = 'module%s*%(?%s*[\'"]([%w_%.]+)' +sense.syntax.symbol_chars = '[%w_%.:]' +sense.syntax.type_declarations = {} +sense.syntax.type_assignments = { + ['^[\'"]'] = 'string', -- foo = 'bar' or foo = "bar" + ['^([%w_%.]+)%s*$'] = '%1', -- foo = _m.textadept.adeptsense + ['^(_m%.textadept%.adeptsense)%.new'] = '%1' +} +sense.api_files = { _HOME..'/modules/lua/api' } +sense:add_trigger('.') +sense:add_trigger(':', false, true) + +-- script/update_doc generates a fake set of ctags used for autocompletion. +sense.ctags_kinds = { + f = 'functions', + F = 'fields', + m = 'classes', + t = 'fields', +} +sense:load_ctags(_HOME..'/modules/lua/tags', true) + --- --- Container for Lua-specific key commands. +-- Shows an autocompletion list for the symbol behind the caret. +-- If the symbol contains a ':', only display functions. Otherwise, display +-- both functions and fields. +function sense:complete(only_fields, only_functions) + local line, pos = buffer:get_cur_line() + local symbol = line:sub(1, pos):match(self.syntax.symbol_chars..'*$') + return self.super.complete(self, false, symbol:find(':')) +end + +-- Load user tags and apidoc. +if lfs.attributes(_USERHOME..'/modules/lua/tags') then + sense:load_ctags(_USERHOME..'/modules/lua/tags') +end +if lfs.attributes(_USERHOME..'/modules/lua/api') then + sense.api_files[#sense.api_files + 1] = _USERHOME..'/modules/lua/api' +end + +-- Commands. + +--- +-- Patterns for auto 'end' completion for control structures. -- @class table --- @name keys.lua - _G.keys.lua = {} +-- @name control_structure_patterns +-- @see try_to_autocomplete_end +local control_structure_patterns = { + '^%s*for', '^%s*function', '^%s*if', '^%s*repeat', '^%s*while', + 'function%s*%b()%s*$', '^%s*local%s*function' +} + +--- +-- Tries to autocomplete Lua's 'end' keyword for control structures like 'if', +-- 'while', 'for', etc. +-- @see control_structure_patterns +function try_to_autocomplete_end() + local buffer = buffer + local line_num = buffer:line_from_position(buffer.current_pos) + local line = buffer:get_line(line_num) + for _, patt in ipairs(control_structure_patterns) do + if line:find(patt) then + local indent = buffer.line_indentation[line_num] + buffer:begin_undo_action() + buffer:new_line() + buffer:new_line() + buffer:add_text(patt:find('repeat') and 'until' or 'end') + buffer.line_indentation[line_num + 1] = indent + buffer.indent + buffer:line_up() + buffer:line_end() + buffer:end_undo_action() + return true + end + end + return false end -require 'lua.adeptsense' -require 'lua.commands' -require 'lua.snippets' +--- +-- Determines the Lua file being 'require'd, searches through package.path for +-- that file, and opens it in Textadept. +function goto_required() + local line = buffer:get_cur_line() + local patterns = { 'require%s*(%b())', 'require%s*(([\'"])[^%2]+%2)' } + local file + for _, patt in ipairs(patterns) do + file = line:match(patt) + if file then break end + end + if not file then return end + file = file:sub(2, -2):gsub('%.', '/') + for path in package.path:gmatch('[^;]+') do + path = path:gsub('?', file) + if lfs.attributes(path) then + io.open_file(path:iconv('UTF-8', _CHARSET)) + break + end + end +end -function set_buffer_properties() +events.connect('file_after_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() + text = text:gsub('^#![^\n]+', '') -- ignore shebang line + local _, err = loadstring(text) + if err then + local line, msg = err:match('^.-:(%d+):%s*(.+)$') + if line then + buffer.annotation_visible = 2 + buffer:annotation_set_text(line - 1, msg) + buffer.annotation_style[line - 1] = 8 -- error style number + buffer:goto_line(line - 1) + end + end + end + end) + +--- +-- Container for Lua-specific key commands. +-- @class table +-- @name _G.keys.lua +_G.keys.lua = { + al = { + m = { io.open_file, + (_HOME..'/modules/lua/init.lua'):iconv('UTF-8', _CHARSET) }, + g = { goto_required }, + }, + ['s\n'] = { try_to_autocomplete_end }, + [not OSX and 'ci' or '~'] = { sense.complete, sense }, + ch = { sense.show_apidoc, sense }, +} + +-- Snippets. +if type(_G.snippets) == 'table' then +--- +-- Container for Lua-specific snippets. +-- @class table +-- @name _G.snippets.lua + _G.snippets.lua = { + l = "local %1(expr)%2( = %3(value))", + p = "print(%0)", + f = "function %1(name)(%2(args))\n\t%0\nend", + ['for'] = "for i=%1(1), %2(10)%3(, -1) do\n\t%0\nend", + fori = "for %1(i), %2(val) in ipairs(%3(table)) do\n\t%0\nend", + forp = "for %1(k), %2(v) in pairs(%3(table)) do\n\t%0\nend", + } end diff --git a/modules/lua/snippets.lua b/modules/lua/snippets.lua deleted file mode 100644 index 57b0ce89..00000000 --- a/modules/lua/snippets.lua +++ /dev/null @@ -1,19 +0,0 @@ --- Copyright 2007-2011 Mitchell mitchell<att>caladbolg.net. See LICENSE. - ---- --- Snippets for the lua module. -module('_m.lua.snippets', package.seeall) - -local snippets = _G.snippets - -if type(snippets) == 'table' then - snippets.lua = { - l = "local %1(expr)%2( = %3(value))", - p = "print(%0)", - f = "function %1(name)(%2(args))\n\t%0\nend", - ['for'] = "for i=%1(1), %2(10)%3(, -1) do\n\t%0\nend", - fori = "for %1(i), %2(val) in ipairs(%3(table)) do\n\t%0\nend", - forp = "for %1(k), %2(v) in pairs(%3(table)) do\n\t%0\nend", - } -end - diff --git a/modules/textadept/adeptsense.lua b/modules/textadept/adeptsense.lua index 560b20cb..01fb1ced 100644 --- a/modules/textadept/adeptsense.lua +++ b/modules/textadept/adeptsense.lua @@ -40,28 +40,17 @@ module('_m.textadept.adeptsense', package.seeall) -- -- #### Introduction -- --- In the language-specific module, create an Adeptsense module. +-- Open the language-specific module for editing and create a new instance of an +-- Adeptsense. -- -- $> # from either _HOME or _USERHOME: -- $> cd modules/lua/ --- $> textadept adeptsense.lua --- --- The Adeptsense should look like the following: +-- $> textadept init.lua -- --- --- Adeptsense for the lua module. --- module('_m.lua.adeptsense', package.seeall) -- sense = _m.textadept.adeptsense.new('lua') -- -- Where 'lua' is replaced by your language's name. -- --- Then edit the module's `init.lua` to include the Adeptsense. --- --- $> textadept init.lua --- --- require 'lua.adeptsense' -- add this line --- require 'lua.commands' --- require 'lua.snippets' --- -- #### Syntax Options -- -- The syntax of different languages varies so the Adeptsense must be configured @@ -261,7 +250,7 @@ module('_m.textadept.adeptsense', package.seeall) -- Since Adeptsense ignores any tags not mapped to `classes`, `functions`, or -- `fields` in [`ctags_kinds`](#ctags_kinds), it passes an unknown tag to the -- [`handle_ctag()`](#handle_ctag) function. In this case, package (`p`) tags --- are need to be handled. +-- need to be handled. -- -- function sense:handle_ctag(tag_name, file_name, ex_cmd, ext_fields) -- if ext_fields:sub(1, 1) ~= 'p' then return end -- not a package diff --git a/modules/textadept/bookmarks.lua b/modules/textadept/bookmarks.lua index 072cca67..97121547 100644 --- a/modules/textadept/bookmarks.lua +++ b/modules/textadept/bookmarks.lua @@ -85,7 +85,7 @@ function goto() line = buffer:marker_next(line + 1, 2^MARK_BOOKMARK) until line < 0 local line = gui.filteredlist(L('Select Bookmark'), 'Bookmark', markers) - if line then _m.textadept.editing.goto_line(tonumber(line:match('^%d+'))) end + if line then _m.textadept.editing.goto_line(line:match('^%d+')) end end if buffer then buffer:marker_set_back(MARK_BOOKMARK, MARK_BOOKMARK_COLOR) end |