diff options
author | mitchell <70453897+orbitalquark@users.noreply.github.com> | 2020-11-10 11:06:53 -0500 |
---|---|---|
committer | mitchell <70453897+orbitalquark@users.noreply.github.com> | 2020-11-10 11:06:53 -0500 |
commit | 269f42273129fcfbaf67e157d8784666e0c65c9c (patch) | |
tree | 4e5e9c7568edd3834f0585f40bcf609a68ef561e | |
parent | 87a11d65ee576d965bcf432e878f191512e46bdd (diff) |
Fill `keys` and `snippet` tables with language-specific tables on init.
This allows users and language modules to easily add bindings and snippets
without stepping on each other.
-rw-r--r-- | core/._M.luadoc | 12 | ||||
-rw-r--r-- | core/keys.lua | 2 | ||||
-rw-r--r-- | docs/api.md | 32 | ||||
-rw-r--r-- | init.lua | 2 | ||||
-rw-r--r-- | modules/ansi_c/init.lua | 64 | ||||
-rw-r--r-- | modules/lua/init.lua | 33 | ||||
-rw-r--r-- | modules/lua/ta_api | 4 | ||||
-rw-r--r-- | modules/lua/ta_tags | 4 | ||||
-rw-r--r-- | modules/textadept/snippets.lua | 2 | ||||
-rw-r--r-- | test/test.lua | 20 |
10 files changed, 59 insertions, 116 deletions
diff --git a/core/._M.luadoc b/core/._M.luadoc index db7211f7..8f94a93d 100644 --- a/core/._M.luadoc +++ b/core/._M.luadoc @@ -99,13 +99,11 @@ -- and insert a new line. This command could be bound to the `Shift+Enter` (`⇧↩` -- on macOS | `S-Enter` in the terminal version) key for easy access: -- --- keys.cpp = { --- ['s\n'] = function() --- buffer:line_end() --- buffer:add_text(';') --- buffer:new_line() --- end --- } +-- keys.cpp['shift+\n'] = function() +-- buffer:line_end() +-- buffer:add_text(';') +-- buffer:new_line() +-- end -- -- When defining key bindings for other commands, you may make use of a `Ctrl+L` -- (`⌘L` on macOS | `M-L` in the terminal version) keychain. Traditionally this diff --git a/core/keys.lua b/core/keys.lua index 2d4d8781..1746d8ff 100644 --- a/core/keys.lua +++ b/core/keys.lua @@ -218,4 +218,6 @@ end) -- @name _G.keys local keys]] +for lexer in string.gmatch('actionscript ada apdl ansi_c antlr apl applescript asp autoit awk b_lang bash batch bibtex boo chuck cmake coffeescript context cpp crystal csharp css cuda desktop django dmd dockerfile dot eiffel elixir erlang faust fennel fish forth fortran fsharp gap gettext gherkin glsl gnuplot go groovy gtkrc haskell html icon idl inform ini Io java javascript jq json jsp latex ledger less lilypond lisp logtalk lua makefile matlab moonscript myrddin nemerle nim nsis objective_c pascal perl php pico8 pike pkgbuild prolog props protobuf ps pure python rails rc rebol rest rexx rhtml rstats ruby rust sass scala scheme smalltalk sml snobol4 sql tcl tex text toml vala vb vbscript verilog vhdl wsf xml yaml', '%S+') do M[lexer] = {} end + return M diff --git a/docs/api.md b/docs/api.md index 8405ff84..f9b8cd77 100644 --- a/docs/api.md +++ b/docs/api.md @@ -299,13 +299,11 @@ C++ module might have a feature to add a ';' to the end of the current line and insert a new line. This command could be bound to the `Shift+Enter` (`⇧↩` on macOS | `S-Enter` in the terminal version) key for easy access: - keys.cpp = { - ['s\n'] = function() - buffer:line_end() - buffer:add_text(';') - buffer:new_line() - end - } + keys.cpp['shift+\n'] = function() + buffer:line_end() + buffer:add_text(';') + buffer:new_line() + end When defining key bindings for other commands, you may make use of a `Ctrl+L` (`⌘L` on macOS | `M-L` in the terminal version) keychain. Traditionally this @@ -352,16 +350,6 @@ Whether or not to include snippets in autocompletion lists. ### Tables defined by `_M.ansi_c` -<a id="keys.ansi_c"></a> -#### `keys.ansi_c` - -Table of C-specific key bindings. - -<a id="snippets.ansi_c"></a> -#### `snippets.ansi_c` - -Table of C-specific snippets. - <a id="_M.ansi_c.tags"></a> #### `_M.ansi_c.tags` @@ -387,16 +375,6 @@ Whether or not to include snippets in autocompletion lists. ### Tables defined by `_M.lua` -<a id="keys.lua"></a> -#### `keys.lua` - -Container for Lua-specific key bindings. - -<a id="snippets.lua"></a> -#### `snippets.lua` - -Container for Lua-specific snippets. - <a id="_M.lua.expr_types"></a> #### `_M.lua.expr_types` @@ -49,7 +49,7 @@ setmetatable(_L,{__index=function(t,k)return rawget(t,k:gsub('_',''))or'No Local setmetatable(textadept.snippets,{__index=function(t,k)return rawget(t,k:gsub('^_',''))end}) buffer.set_theme=function(...)view:set_theme(select(2,...));events.connect(events.INITIALIZED,function()ui.dialogs.msgbox{title='Compatibility issue',text='Please change your use of "buffer:set_theme()" to "view:set_theme()"'}end)end local function en_au_to_us()for au,us in pairs{CASEINSENSITIVEBEHAVIOUR_IGNORECASE=buffer.CASEINSENSITIVEBEHAVIOR_IGNORECASE,CASEINSENSITIVEBEHAVIOUR_RESPECTCASE=buffer.CASEINSENSITIVEBEHAVIOR_RESPECTCASE,INDIC_GRADIENTCENTRE=buffer.INDIC_GRADIENTCENTER,MARGIN_COLOUR=buffer.MARGIN_COLOR,auto_c_case_insensitive_behaviour=buffer.auto_c_case_insensitive_behavior,colourise=buffer.colorize,edge_colour=buffer.edge_color,set_fold_margin_colour=function()ui.dialogs.msgbox{title='Compatibility issue',text="Please update your theme's use of renamed buffer/view fields"};return buffer.set_fold_margin_color end,set_fold_margin_hi_colour=buffer.set_fold_margin_hi_color,vertical_centre_caret=buffer.vertical_center_caret}do buffer[au]=us;view[au]=us end end;events.connect(events.BUFFER_NEW,en_au_to_us);en_au_to_us() -events.connect(events.INITIALIZED,function()if _NOCOMPAT then return end;local update_keys={};local function translate_keys(keys,new_keys)for k,v in pairs(keys)do if type(k)=='string'and k:find('^[cmas]+.$')and not k:find('ctrl')and not k:find('cmd')and not k:find('alt')and not k:find('meta')and not k:find('shift')and k~='css'then update_keys[#update_keys+1]=k;k=k:gsub('^(c?m?a?)s(.)','%1shift+%2'):gsub('^(c?m?)a(.)','%1alt+%2'):gsub('^(c?)m(.)',string.format('%%1%s%%2',OSX and'cmd+'or'meta+')):gsub('^c(.)','ctrl+%1')end rawset(new_keys,k,type(v)=='table'and translate_keys(v,setmetatable({},getmetatable(v)))or v)end return new_keys end;for k,v in pairs(translate_keys(keys,{}))do keys[k]=v end;if#update_keys>0then ui.dialogs.msgbox{title='Compatibility issue',text='Please update your keys to use the new modifiers:\n'..table.concat(update_keys,'\n')..'\n\nSet _NOCOMPAT=true to disable this warning'}end end) +events.connect(events.INITIALIZED,function()if _NOCOMPAT then return end;local update_keys={};local function translate_keys(keys,new_keys)for k,v in pairs(keys)do if type(k)=='string'and k:find('^[cmas]+.$')and not k:find('ctrl')and not k:find('cmd')and not k:find('alt')and not k:find('meta')and not k:find('shift')and k~='css'and k~='asp'and k~='sass'and k~='sml'then update_keys[#update_keys+1]=k;k=k:gsub('^(c?m?a?)s(.)','%1shift+%2'):gsub('^(c?m?)a(.)','%1alt+%2'):gsub('^(c?)m(.)',string.format('%%1%s%%2',OSX and'cmd+'or'meta+')):gsub('^c(.)','ctrl+%1')end rawset(new_keys,k,type(v)=='table'and translate_keys(v,setmetatable({},getmetatable(v)))or v)end return new_keys end;for k,v in pairs(translate_keys(keys,{}))do keys[k]=v end;if#update_keys>0then ui.dialogs.msgbox{title='Compatibility issue',text='Please update your keys to use the new modifiers:\n'..table.concat(update_keys,'\n')..'\n\nSet _NOCOMPAT=true to disable this warning'}end end) -- The remainder of this file defines default buffer and view properties and -- applies them to subsequent buffers and views. Normally, a setting like diff --git a/modules/ansi_c/init.lua b/modules/ansi_c/init.lua index 3f5288c4..af6955a6 100644 --- a/modules/ansi_c/init.lua +++ b/modules/ansi_c/init.lua @@ -85,45 +85,33 @@ for _, tags in ipairs(M.tags) do table.insert(textadept.editing.api_files.ansi_c, (tags:gsub('tags$', 'api'))) end --- Commands. - ---- --- Table of C-specific key bindings. --- @class table --- @name _G.keys.ansi_c -keys.ansi_c = {} - -- Snippets. ---- --- Table of C-specific snippets. --- @class table --- @name _G.snippets.ansi_c -snippets.ansi_c = { - func = '%1(int) %2(name)(%3(args)) {\n\t%0\n\treturn %4(0);\n}', - vfunc = 'void %1(name)(%2(args)) {\n\t%0\n}', - ['if'] = 'if (%1) {\n\t%0\n}', - eif = 'else if (%1) {\n\t%0\n}', - ['else'] = 'else {\n\t%0\n}', - ['for'] = 'for (%1; %2; %3) {\n\t%0\n}', - ['fori'] = 'for (%1(int) %2(i) = %3(0); %2 %4(<) %5(count); %2%6(++)) {\n'.. - '\t%0\n}', - ['while'] = 'while (%1) {\n\t%0\n}', - ['do'] = 'do {\n\t%0\n} while (%1);', - sw = 'switch (%1) {\n\tcase %2:\n\t\t%0\n\t\tbreak;\n}', - case = 'case %1:\n\t%0\n\tbreak;', - - st = 'struct %1(name) {\n\t%0\n};', - td = 'typedef %1(int) %2(name_t);', - tds = 'typedef struct %1(name) {\n\t%0\n} %1%2(_t);', - - def = '#define %1(name) %2(value)', - inc = '#include "%1"', - Inc = '#include <%1>', - pif = '#if %1\n%0\n#endif', - - main = 'int main(int argc, const char **argv) {\n\t%0\n\treturn 0;\n}', - printf = 'printf("%1(%s)\\n", %2);', -} +local snip = snippets.ansi_c + +snip.func = '%1(int) %2(name)(%3(args)) {\n\t%0\n\treturn %4(0);\n}' +snip.vfunc = 'void %1(name)(%2(args)) {\n\t%0\n}' +snip['if'] = 'if (%1) {\n\t%0\n}' +snip.eif = 'else if (%1) {\n\t%0\n}' +snip['else'] = 'else {\n\t%0\n}' +snip['for'] = 'for (%1; %2; %3) {\n\t%0\n}' +snip['fori'] = + 'for (%1(int) %2(i) = %3(0); %2 %4(<) %5(count); %2%6(++)) {\n\t%0\n}' +snip['while'] = 'while (%1) {\n\t%0\n}' +snip['do'] = 'do {\n\t%0\n} while (%1);' +snip.sw = 'switch (%1) {\n\tcase %2:\n\t\t%0\n\t\tbreak;\n}' +snip.case = 'case %1:\n\t%0\n\tbreak;' + +snip.st = 'struct %1(name) {\n\t%0\n};' +snip.td = 'typedef %1(int) %2(name_t);' +snip.tds = 'typedef struct %1(name) {\n\t%0\n} %1%2(_t);' + +snip.def = '#define %1(name) %2(value)' +snip.inc = '#include "%1"' +snip.Inc = '#include <%1>' +snip.pif = '#if %1\n%0\n#endif' + +snip.main = 'int main(int argc, const char **argv) {\n\t%0\n\treturn 0;\n}' +snip.printf = 'printf("%1(%s)\\n", %2);' return M diff --git a/modules/lua/init.lua b/modules/lua/init.lua index abaa36aa..d3b0c9ae 100644 --- a/modules/lua/init.lua +++ b/modules/lua/init.lua @@ -104,30 +104,17 @@ table.insert(api_files, _HOME .. '/modules/lua/api') table.insert(api_files, _USERHOME .. '/modules/lua/api') table.insert(api_files, ta_api(_HOME .. '/modules/lua/ta_api')) --- Commands. - ---- --- Container for Lua-specific key bindings. --- @class table --- @name _G.keys.lua -keys.lua = {} - -- Snippets. ---- --- Container for Lua-specific snippets. --- @class table --- @name _G.snippets.lua -snippets.lua = { - func = 'function %1(name)(%2(args))\n\t%0\nend', - ['if'] = 'if %1 then\n\t%0\nend', - eif = 'elseif %1 then\n\t', - ['for'] = 'for %1(i) = %2(1), %3(10)%4(, %5(-1)) do\n\t%0\nend', - forp = 'for %1(k), %2(v) in pairs(%3(t)) do\n\t%0\nend', - fori = 'for %1(i), %2(v) in ipairs(%3(t)) do\n\t%0\nend', - ['while'] = 'while %1 do\n\t%0\nend', - ['repeat'] = 'repeat\n\t%0\nuntil %1', - ['do'] = 'do\n\t%0\nend', -} +local snip = snippets.lua +snip.func = 'function %1(name)(%2(args))\n\t%0\nend' +snip['if'] = 'if %1 then\n\t%0\nend' +snip.eif = 'elseif %1 then\n\t' +snip['for'] = 'for %1(i) = %2(1), %3(10)%4(, %5(-1)) do\n\t%0\nend' +snip.forp = 'for %1(k), %2(v) in pairs(%3(t)) do\n\t%0\nend' +snip.fori = 'for %1(i), %2(v) in ipairs(%3(t)) do\n\t%0\nend' +snip['while'] = 'while %1 do\n\t%0\nend' +snip['repeat'] = 'repeat\n\t%0\nuntil %1' +snip['do'] = 'do\n\t%0\nend' return M diff --git a/modules/lua/ta_api b/modules/lua/ta_api index 5832ece4..1d2318b8 100644 --- a/modules/lua/ta_api +++ b/modules/lua/ta_api @@ -328,8 +328,6 @@ annotation_lines buffer.annotation_lines (table, Read-only)\nTable of the number annotation_style buffer.annotation_style (table)\nTable of style numbers for annotation text per line number.\nOnly some style attributes are active in annotations: font,\nsize/size_fractional, bold/weight, italics, fore, back, and character_set. annotation_text buffer.annotation_text (table)\nTable of annotation text per line number. annotation_visible view.annotation_visible (number)\nThe annotation visibility mode.\n\n* `view.ANNOTATION_HIDDEN`\n Annotations are invisible.\n* `view.ANNOTATION_STANDARD`\n Draw annotations left-justified with no decoration.\n* `view.ANNOTATION_BOXED`\n Indent annotations to match the annotated text and outline them with a\n box.\n* `view.ANNOTATION_INDENTED`\n Indent non-decorated annotations to match the annotated text.\n\nThe default value is `view.ANNOTATION_HIDDEN`. -ansi_c _G.keys.ansi_c (table)\nTable of C-specific key bindings. -ansi_c _G.snippets.ansi_c (table)\nTable of C-specific snippets. ansi_c _M.ansi_c (module)\nThe ansi_c module.\nIt provides utilities for editing C code. any lexer.any (pattern)\nA pattern that matches any single character. api_files textadept.editing.api_files (table)\nMap of lexer names to API documentation file tables.\nFile tables contain API file paths or functions that return such paths.\nEach line in an API file consists of a symbol name (not a fully qualified\nsymbol name), a space character, and that symbol's documentation. "\\n"\nrepresents a newline character.\n@see show_documentation @@ -656,8 +654,6 @@ load textadept.macros.load(filename)\nLoads a macro from file *filename* or the load textadept.session.load(filename)\nLoads session file *filename* or the user-selected session, returning `true`\nif a session file was opened and read.\nTextadept restores split views, opened buffers, cursor information, recent\nfiles, and bookmarks.\n@param filename Optional absolute path to the session file to load. If `nil`,\n the user is prompted for one.\n@usage textadept.session.load(filename)\n@return `true` if the session file was opened and read; `nil` otherwise. lower lexer.lower (pattern)\nA pattern that matches any lower case character ('a'-'z'). lower_case buffer.lower_case(buffer)\nConverts the selected text to lower case letters.\n@param buffer A buffer. -lua _G.keys.lua (table)\nContainer for Lua-specific key bindings. -lua _G.snippets.lua (table)\nContainer for Lua-specific snippets. lua _M.lua (module)\nThe lua module.\nIt provides utilities for editing Lua code. macros textadept.macros (module)\nA module for recording, playing, saving, and loading keyboard macros.\nMenu commands are also recorded.\nAt this time, typing into multiple cursors during macro playback is not\nsupported. main_selection buffer.main_selection (number)\nThe number of the main or most recent selection.\nOnly an existing selection can be made main. diff --git a/modules/lua/ta_tags b/modules/lua/ta_tags index dc56db4f..e5f01dcd 100644 --- a/modules/lua/ta_tags +++ b/modules/lua/ta_tags @@ -330,9 +330,7 @@ annotation_lines _HOME/core/.buffer.luadoc /^module('buffer')$/;" F class:buffer annotation_style _HOME/core/.buffer.luadoc /^module('buffer')$/;" F class:buffer annotation_text _HOME/core/.buffer.luadoc /^module('buffer')$/;" F class:buffer annotation_visible _HOME/core/.view.luadoc /^module('view')$/;" F class:view -ansi_c _HOME/modules/ansi_c/init.lua /^keys.ansi_c = {}$/;" t class:keys ansi_c _HOME/modules/ansi_c/init.lua /^module('_M.ansi_c')]]$/;" m class:_M -ansi_c _HOME/modules/ansi_c/init.lua /^snippets.ansi_c = {$/;" t class:snippets any _HOME/lexers/lexer.lua /^module('lexer')]=]$/;" F class:lexer api_files _HOME/modules/textadept/editing.lua /^M.api_files = setmetatable({}, {__index = function(t, k)$/;" t class:textadept.editing append_history _HOME/modules/textadept/command_entry.lua /^function M.append_history(f, text)$/;" f class:ui.command_entry @@ -658,9 +656,7 @@ load _HOME/modules/textadept/macros.lua /^function M.load(filename)$/;" f class: load _HOME/modules/textadept/session.lua /^function M.load(filename)$/;" f class:textadept.session lower _HOME/lexers/lexer.lua /^module('lexer')]=]$/;" F class:lexer lower_case _HOME/core/.buffer.luadoc /^function lower_case(buffer) end$/;" f class:buffer -lua _HOME/modules/lua/init.lua /^keys.lua = {}$/;" t class:keys lua _HOME/modules/lua/init.lua /^module('_M.lua')]]$/;" m class:_M -lua _HOME/modules/lua/init.lua /^snippets.lua = {$/;" t class:snippets macros _HOME/modules/textadept/macros.lua /^module('textadept.macros')]]$/;" m class:textadept main_selection _HOME/core/.buffer.luadoc /^module('buffer')$/;" F class:buffer margin_back_n _HOME/core/.view.luadoc /^module('view')$/;" F class:view diff --git a/modules/textadept/snippets.lua b/modules/textadept/snippets.lua index 2f40d219..16f95f67 100644 --- a/modules/textadept/snippets.lua +++ b/modules/textadept/snippets.lua @@ -131,7 +131,7 @@ local INDIC_CURRENTPLACEHOLDER = _SCINTILLA.next_indic_number() -- @class table -- @name snippets -- @see _G.snippets -local snippets = {} +local snippets = {actionscript={},ada={},apdl={},ansi_c={},antlr={},apl={},applescript={},asp={},autoit={},awk={},b_lang={},bash={},batch={},bibtex={},boo={},chuck={},cmake={},coffeescript={},context={},cpp={},crystal={},csharp={},css={},cuda={},desktop={},django={},dmd={},dockerfile={},dot={},eiffel={},elixir={},erlang={},faust={},fennel={},fish={},forth={},fortran={},fsharp={},gap={},gettext={},gherkin={},glsl={},gnuplot={},go={},groovy={},gtkrc={},haskell={},html={},icon={},idl={},inform={},ini={},Io={},java={},javascript={},jq={},json={},jsp={},latex={},ledger={},less={},lilypond={},lisp={},logtalk={},lua={},makefile={},matlab={},moonscript={},myrddin={},nemerle={},nim={},nsis={},objective_c={},pascal={},perl={},php={},pico8={},pike={},pkgbuild={},prolog={},props={},protobuf={},ps={},pure={},python={},rails={},rc={},rebol={},rest={},rexx={},rhtml={},rstats={},ruby={},rust={},sass={},scala={},scheme={},smalltalk={},sml={},snobol4={},sql={},tcl={},tex={},text={},toml={},vala={},vb={},vbscript={},verilog={},vhdl={},wsf={},xml={},yaml={}} -- Finds the snippet assigned to the trigger word behind the caret and returns -- the trigger word and snippet text. If *grep* is `true`, returns a table of diff --git a/test/test.lua b/test/test.lua index 8a768731..7bac8baa 100644 --- a/test/test.lua +++ b/test/test.lua @@ -578,14 +578,12 @@ function test_keys_propagation() keys.a = function() foo = true end keys.b = function() bar = true end keys.c = function() baz = true end - keys.cpp = { - a = function() end, -- halt - b = function() return false end, -- propagate - c = function() - keys.mode = 'test_mode' - return false -- propagate - end - } + keys.cpp.a = function() end -- halt + keys.cpp.b = function() return false end -- propagate + keys.cpp.c = function() + keys.mode = 'test_mode' + return false -- propagate + end buffer:set_lexer('cpp') events.emit(events.KEYPRESS, string.byte('a')) assert(not foo, 'foo set') @@ -595,7 +593,7 @@ function test_keys_propagation() assert(not baz, 'baz set') -- mode changed, so cannot propagate to keys.c assert_equal(keys.mode, 'test_mode') keys.mode = nil - keys.a, keys.b, keys.c, keys.cpp = nil, nil, nil, nil -- reset + keys.a, keys.b, keys.c, keys.cpp.a, keys.cpp.b, keys.cpp.c = nil, nil, nil, nil, nil, nil -- reset buffer:close() end @@ -608,7 +606,7 @@ function test_keys_modes() keys.mode = nil return false -- propagate end} - keys.cpp = {a = function() keys.mode = 'test_mode' end} + keys.cpp.a = function() keys.mode = 'test_mode' end events.emit(events.KEYPRESS, string.byte('a')) assert(foo, 'foo not set') assert(not keys.mode, 'key mode entered') @@ -623,7 +621,7 @@ function test_keys_modes() assert(bar, 'bar not set') assert(not keys.mode, 'key mode still active') assert(not foo, 'foo set') -- TODO: should this propagate? - keys.a, keys.test_mode, keys.cpp = nil, nil, nil -- reset + keys.a, keys.test_mode, keys.cpp.a = nil, nil, nil -- reset buffer:close() end |