aboutsummaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/cpp/init.lua16
-rw-r--r--modules/lua/api25
-rw-r--r--modules/lua/init.lua20
-rw-r--r--modules/lua/tags7
-rw-r--r--modules/textadept/command_entry.lua5
-rw-r--r--modules/textadept/editing.lua6
-rw-r--r--modules/textadept/filter_through.lua2
-rw-r--r--modules/textadept/find.lua7
-rw-r--r--modules/textadept/keys.conf149
-rw-r--r--modules/textadept/keys.lua346
-rw-r--r--modules/textadept/keys.osx.conf149
-rw-r--r--modules/textadept/menu.lua325
12 files changed, 571 insertions, 486 deletions
diff --git a/modules/cpp/init.lua b/modules/cpp/init.lua
index a610528e..edad0d9a 100644
--- a/modules/cpp/init.lua
+++ b/modules/cpp/init.lua
@@ -10,16 +10,12 @@ module('_m.cpp', package.seeall)
-- Markdown:
-- ## Key Commands
--
--- + `Alt+L, M`: Open this module for editing.
+-- + `Ctrl+L, M` (`⌘L, M` on Mac OSX): 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.
--- + `Ctrl+Esc`: (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.
+-- + `Shift+Return` (`⇧↩`): Add ';' to line end and insert newline.
--
-- ## Fields
--
@@ -82,17 +78,15 @@ end
-- @class table
-- @name _G.keys.cpp
keys.cpp = {
- al = {
+ [keys.LANGUAGE_MODULE_PREFIX] = {
m = { io.open_file,
(_HOME..'/modules/cpp/init.lua'):iconv('UTF-8', _CHARSET) },
},
- ['s\n'] = { function()
+ ['s\n'] = function()
buffer:line_end()
buffer:add_text(';')
buffer:new_line()
- end },
- [not OSX and 'ci' or 'cesc'] = { sense.complete, sense },
- ch = { sense.show_apidoc, sense },
+ end,
}
-- Snippets.
diff --git a/modules/lua/api b/modules/lua/api
index f26ef25c..66509965 100644
--- a/modules/lua/api
+++ b/modules/lua/api
@@ -1,5 +1,5 @@
-ADD keys.ADD [string]\nThe string representing used to join together a sequence of Control, Shift,\nor Alt modifier keys.\n
-ALT keys.ALT [string]\nThe string representing the Alt key (the Apple key on Mac OSX).\n
+ADD keys.ADD [string]\nThe string representing used to join together a sequence of Control, Alt,\nMeta, or Shift modifier keys. The default is ''.\n
+ALT keys.ALT [string]\nThe string representing the Alt/option key. The default is 'a'\n
ANNOTATION_BOXED _SCINTILLA.constants.ANNOTATION_BOXED\n2\n
ANNOTATION_HIDDEN _SCINTILLA.constants.ANNOTATION_HIDDEN\n0\n
ANNOTATION_STANDARD _SCINTILLA.constants.ANNOTATION_STANDARD\n1\n
@@ -24,12 +24,13 @@ CARET_SLOP _SCINTILLA.constants.CARET_SLOP\n1\n
CARET_STRICT _SCINTILLA.constants.CARET_STRICT\n4\n
CHAR_ADDED events.CHAR_ADDED\nCalled when an ordinary text character is added to the buffer.\n * `ch`: The text character byte.\n\n
CLASS lexer.CLASS\n\n
+CLEAR keys.CLEAR [string]\nThe string representing the key sequence that clears the current keychain. The\ndefault is 'esc' (Escape).\n
COMMAND_ENTRY_COMMAND events.COMMAND_ENTRY_COMMAND\nCalled when a command is entered into the Command Entry.\n * `command`: The command text.\n\n
-COMMAND_ENTRY_KEYPRESS events.COMMAND_ENTRY_KEYPRESS\nCalled when a key is pressed in the Command Entry.\n * `code`: The key code.\n * `shift`: The Shift key is held down.\n * `ctrl`: The Control key is held down.\n * `alt`: The Alt/Apple key is held down.\n\n
+COMMAND_ENTRY_KEYPRESS events.COMMAND_ENTRY_KEYPRESS\nCalled when a key is pressed in the Command Entry.\n * `code`: The key code.\n * `shift`: The Shift key is held down.\n * `ctrl`: The Control/Command key is held down.\n * `alt`: The Alt/option key is held down.\n * `meta`: The Control key on Mac OSX is held down.\n\n
COMMENT lexer.COMMENT\n\n
COMPILE_OUTPUT events.COMPILE_OUTPUT\nCalled after a compile command is executed. When connecting to this event\n(typically from a language-specific module), connect with an index of 1 and\nreturn `true` if the event was handled and you want to override the default\nhandler that prints the output to a new view.\n * `lexer`: The lexer language.\n * `output`: The output from the command.\n\n
CONSTANT lexer.CONSTANT\n\n
-CTRL keys.CTRL [string]\nThe string representing the Control key.\n
+CTRL keys.CTRL [string]\nThe string representing the Control/Command key. The default is 'c'.\n
Carg lpeg.Carg(n)\nCreates an argument capture. This pattern matches the empty string and produces\nthe value given as the nth extra argument given in the call to lpeg.match.\n
Cb lpeg.Cb(name)\nCreates a back capture. This pattern matches the empty string and produces the\nvalues produced by the most recent group capture named name. Most recent means\nthe last complete outermost group capture with the given name. A Complete\ncapture means that the entire pattern corresponding to the capture has\nmatched. An Outermost capture means that the capture is not inside another\ncomplete capture.\n
Cc lpeg.Cc([value, ...])\nCreates a constant capture. This pattern matches the empty string and produces\nall given values as its captured values.\n
@@ -85,17 +86,19 @@ INDIC_STRAIGHTBOX _SCINTILLA.constants.INDIC_STRAIGHTBOX\n8\n
INDIC_STRIKE _SCINTILLA.constants.INDIC_STRIKE\n4\n
INDIC_TT _SCINTILLA.constants.INDIC_TT\n2\n
INVALID_POSITION _SCINTILLA.constants.INVALID_POSITION\n-1\n
-KEYPRESS events.KEYPRESS\nCalled when a key is pressed.\n * `code`: The key code.\n * `shift`: The Shift key is held down.\n * `ctrl`: The Control key is held down.\n * `alt`: The Alt/Apple key is held down.\n\n
+KEYPRESS events.KEYPRESS\nCalled when a key is pressed.\n * `code`: The key code.\n * `shift`: The Shift key is held down.\n * `ctrl`: The Control/Command key is held down.\n * `alt`: The Alt/option key is held down.\n * `meta`: The Control key on Mac OSX is held down.\n\n
KEYSYMS keys.KEYSYMS [table]\nLookup table for key values higher than 255. If a key value given to 'keypress'\nis higher than 255, this table is used to return a string representation of\nthe key if it exists.\n
KEYWORD lexer.KEYWORD\n\n
KEYWORDSET_MAX _SCINTILLA.constants.KEYWORDSET_MAX\n8\n
LANGUAGE_MODULE_LOADED events.LANGUAGE_MODULE_LOADED\nCalled when loading a language-specific module. This is useful for overriding\nits key commands since they are not available when Textadept starts. Arguments:\n * `lang`: The language lexer name.\n\n
+LANGUAGE_MODULE_PREFIX keys.LANGUAGE_MODULE_PREFIX [string]\nThe starting key command of the keychain reserved for language-specific\nmodules. Defaults to Ctrl/Cmd+L.\n
MARGIN_CLICK events.MARGIN_CLICK\nCalled when the mouse is clicked inside a margin.\n * `margin`: The margin number that was clicked.\n * `position`: The position of the start of the line in the buffer that\n corresponds to the margin click.\n * `modifiers`: The appropriate combination of\n `_SCINTILLA.constants.SCI_SHIFT`, `_SCINTILLA.constants.SCI_CTRL`,\n and `_SCINTILLA.constants.SCI_ALT` to indicate the keys that were\n held down at the time of the margin click.\n\n
MARKER_MAX _SCINTILLA.constants.MARKER_MAX\n31\n
MARK_BOOKMARK_COLOR _m.textadept.bookmarks.MARK_BOOKMARK_COLOR [number]\nThe color used for a bookmarked line in 0xBBGGRR format.\n
MARK_HIGHLIGHT_BACK _m.textadept.editing.MARK_HIGHLIGHT_BACK [number]\nThe background color used for a line containing a highlighted word in\n0xBBGGRR format.\n
MAX _m.textadept.snapopen.MAX [number]\nMaximum number of files to list. The default value is 1000.\n
MENU_CLICKED events.MENU_CLICKED\nCalled when a menu item is selected.\n * `menu_id`: The numeric ID of the menu item set in `gui.gtkmenu()`.\n\n
+META keys.META [string]\nThe string representing the Control key on Mac OSX. The default is 'm'.\n
NUMBER lexer.NUMBER\n\n
OPERATOR lexer.OPERATOR\n\n
OSX _G.OSX [bool]\nIf Textadept is running on Mac OSX, this flag is `true`.\n
@@ -668,7 +671,7 @@ SC_WRAPVISUALFLAG_START _SCINTILLA.constants.SC_WRAPVISUALFLAG_START\n2\n
SC_WRAP_CHAR _SCINTILLA.constants.SC_WRAP_CHAR\n2\n
SC_WRAP_NONE _SCINTILLA.constants.SC_WRAP_NONE\n0\n
SC_WRAP_WORD _SCINTILLA.constants.SC_WRAP_WORD\n1\n
-SHIFT keys.SHIFT [string]\nThe string representing the Shift key.\n
+SHIFT keys.SHIFT [string]\nThe string representing the Shift key. The default is 's'.\n
STRING lexer.STRING\n\n
STYLE_BRACEBAD _SCINTILLA.constants.STYLE_BRACEBAD\n35\n
STYLE_BRACELIGHT _SCINTILLA.constants.STYLE_BRACELIGHT\n34\n
@@ -987,6 +990,7 @@ get_class _m.textadept.adeptsense.get_class(sense, symbol)\nReturns the class na
get_completions _m.textadept.adeptsense.get_completions(sense, symbol, only_fields,\nonly_functions)\nReturns a list of completions for the given symbol.\n@param sense The adeptsense returned by adeptsense.new().\n@param symbol The symbol to get completions for.\n@param only_fields If true, returns list of only fields; defaults to false.\n@param only_functions If true, returns list of only functions; defaults\nto false.\n@return completion_list or nil\n
get_cur_line buffer.get_cur_line(buffer)\nRetrieve the text of the line containing the caret. Also returns the index\nof the caret on the line.\n@param buffer The focused buffer.\n@return string, number\n
get_fold_level lexer.get_fold_level(line, line_number)\nReturns the fold level for a given line. This level already has\n`SC_FOLDLEVELBASE` added to it, so you do not need to add it yourself.\n@param line_number The line number to get the fold level of.\n
+get_gdk_key keys.get_gdk_key(key_seq)\nReturns the GDK integer keycode and modifier mask for a key sequence. This\nis used internally for creating menu accelerators.\n@param key_seq The string key sequence.\n@return keycode and modifier mask\n
get_hotspot_active_back buffer.get_hotspot_active_back(buffer)\nGet the back color for active hotspots in 0xBBGGRR format.\n@param buffer The focused buffer.\n@return number\n
get_hotspot_active_fore buffer.get_hotspot_active_fore(buffer)\nGet the fore color for active hotspots.\n@param buffer The focused buffer.\n@return number\n
get_indent_amount lexer.get_indent_amount(line)\nReturns the indent amount of text for a given line.\n@param line The line number to get the indent amount of.\n
@@ -1090,7 +1094,7 @@ java _G.snippets.java [table]\nContainer for Java-specific snippets.\n
java _m.java [module]\nThe java module. It provides utilities for editing Java code. User tags\nare loaded from _USERHOME/modules/java/tags and user apis are loaded from\n_USERHOME/modules/java/api.\n
join_lines _m.textadept.editing.join_lines()\nJoins the current line with the line below.\n
keys _G.keys [module]\nManages key commands in Textadept.\n
-keys _m.textadept.keys [module]\nDefines key commands for Textadept. This set of key commands is pretty\nstandard among other text editors.\n
+keys _m.textadept.keys [module]\nDefines additional key commands for Textadept. The primary key commands\nare loaded from _USERHOME/keys.conf, _HOME/modules/textadept/keys.conf,\n_USERHOME/keys.osx.conf, or _HOME/modules/textadept/keys.osx.conf depending\non the platform by _m.textadept.menu. This module, like _m.textadept.menu,\nshould be 'require'ed last.\n
keys_unicode buffer.keys_unicode [bool]\nInterpret keyboard input as Unicode.\n
layout_cache buffer.layout_cache [number]\nThe degree of caching of layout information.\n * `_SCINTILLA.constants.SC_CACHE_NONE` (0): No lines are cached.\n * `_SCINTILLA.constants.SC_CACHE_CARET` (1): The line containing the\n text caret. This is the default.\n * `_SCINTILLA.constants.SC_CACHE_PAGE` (2): Visible lines plus the line\n containing the caret.\n * `_SCINTILLA.constants.SC_CACHE_DOCUMENT` (3): All lines in the\n document.\n\n
ldexp math.ldexp(m, e)\nReturns *m2^e* (`e` should be an integer).\n
@@ -1202,7 +1206,7 @@ math _G.math [module]\nLua math module.\n
max math.max(x, ···)\nReturns the maximum value among its arguments.\n
max_line_state buffer.max_line_state [number]\nThe last line number that has line state. (Read-only)\n
maxn table.maxn(table)\nReturns the largest positive numerical index of the given table, or zero if\nthe table has no positive numerical indices. (To do its job this function\ndoes a linear traversal of the whole table.)\n
-menu _m.textadept.menu [module]\nProvides dynamic menus for Textadept. This module, like _m.textadept.keys,\nshould be 'require'ed last.\n
+menu _m.textadept.menu [module]\nProvides dynamic menus for Textadept. It also loads key commands\nfrom _USERHOME/keys.conf, _HOME/modules/textadept/keys.conf,\n_USERHOME/keys.osx.conf, or _HOME/modules/textadept/keys.osx.conf depending on\nthe platform. This module, like _m.textadept.keys, should be 'require'ed last.\n
menubar _m.textadept.menu.menubar [table]\nContains the main menubar.\n
menubar gui.menubar [table]\nA table of GTK menus defining a menubar. (Write-only)\n
mime_types _m.textadept.mime_types [module]\nHandles file-specific settings.\n
@@ -1234,6 +1238,7 @@ oct_num lexer.oct_num\nMatches an octal number.\n
open _m.textadept.snapopen.open(utf8_paths, filter, exclusive, depth)\nQuickly open a file in set of directories.\n@param utf8_paths A UTF-8 string directory path or table of UTF-8 directory\npaths to search.\n@param filter A filter for files and folders to exclude. The filter may be\na string or table. Each filter is a Lua pattern. Any files matching a filter\nare excluded. Prefix a pattern with '!' to exclude any files that do not match\nthe filter. Directories can be excluded by adding filters to a table assigned\nto a 'folders' key in the filter table. All strings should be UTF-8 encoded.\n@param exclusive Flag indicating whether or not to exclude PATHS in the\nsearch. Defaults to false.\n@param depth Number of directories to recurse into for finding files. Defaults\nto DEFAULT_DEPTH.\n@usage _m.textadept.snapopen.open()\n@usage _m.textadept.snapopen.open(buffer.filename:match('^.+/'), nil, true)\n@usage _m.textadept.snapopen.open(nil, '!%.lua$')\n@usage _m.textadept.snapopen.open(nil, { folders = { '%.hg' } })\n
open io.open(filename [, mode])\nThis function opens a file, in the mode specified in the string `mode`. It\nreturns a new file handle, or, in case of errors, nil plus an error\nmessage. The `mode` string can be any of the following: "r": read mode (the\ndefault); "w": write mode; "a": append mode; "r+": update mode, all previous\ndata is preserved; "w+": update mode, all previous data is erased; "a+":\nappend update mode, previous data is preserved, writing is only allowed at\nthe end of file. The `mode` string can also have a '`b`' at the end, which\nis needed in some systems to open the file in binary mode. This string is\nexactly what is used in the standard C function `fopen`.\n
open_file io.open_file(utf8_filenames)\nOpens a list of files.\n@param utf8_filenames A '\\n' separated list of UTF-8-encoded filenames to\nopen. If nil, the user is prompted with a fileselect dialog.\n@usage io.open_file(utf8_encoded_filename)\n
+open_recent_file io.open_recent_file()\nPrompts the user to open a recently opened file.\n
orange lexer.colors.orange\nOrange.\n
os _G.os [module]\nLua os module.\n
output io.output([file])\nSimilar to `io.input`, but operates over the default output file.\n
@@ -1296,7 +1301,7 @@ rawset _G.rawset(table, index, value)\nSets the real value of `table[index]` to
read file:read(···)\nReads the file `file`, according to the given formats, which specify what\nto read. For each format, the function returns a string (or a number)\nwith the characters read, or nil if it cannot read data with the specified\nformat. When called without formats, it uses a default format that reads the\nentire next line (see below). The available formats are "*n": reads a number;\nthis is the only format that returns a number instead of a string. "*a":\nreads the whole file, starting at the current position. On end of file,\nit returns the empty string. "*l": reads the next line (skipping the end of\nline), returning nil on end of file. This is the default format. *number*:\nreads a string with up to this number of characters, returning nil on end\nof file. If number is zero, it reads nothing and returns an empty string,\nor nil on end of file.\n
read io.read(···)\nEquivalent to `io.input():read`.\n
read_only buffer.read_only [bool]\nRead-only mode.\n
-recent_files io.recent_files [table]\nList of recently opened files.\n
+recent_files io.recent_files [table]\nList of recently opened files. The most recent are towards the top.\n
rectangular_selection_anchor buffer.rectangular_selection_anchor [number]\nThe position of the anchor of the rectangular selection.\n
rectangular_selection_anchor_virtual_space buffer.rectangular_selection_anchor_virtual_space [number]\nThe amount of virtual space for the anchor of the rectangular selection.\n
rectangular_selection_caret buffer.rectangular_selection_caret [number]\nThe position of the caret of the rectangular selection.\n
@@ -1360,7 +1365,7 @@ select_indented_block _m.textadept.editing.select_indented_block()\nSelects inde
select_lexer _m.textadept.mime_types.select_lexer()\nPrompts the user to select a lexer from a filtered list for the current buffer.\n
select_line _m.textadept.editing.select_line()\nSelects the current line.\n
select_paragraph _m.textadept.editing.select_paragraph()\nSelects the current paragraph. Paragraphs are delimited by two or more\nconsecutive newlines.\n
-select_scope _m.textadept.editing.select_scope()\nSelects all text with the same style as under the caret.\n
+select_style _m.textadept.editing.select_style()\nSelects all text with the same style as under the caret.\n
selection_duplicate buffer.selection_duplicate(buffer)\nDuplicate the selection. If selection empty duplicate the line containing\nthe caret.\n@param buffer The focused buffer.\n
selection_end buffer.selection_end [number]\nThe position that ends the selection - this becomes the current position. This\ndoes not make the caret visible.\n
selection_is_rectangle buffer.selection_is_rectangle [bool]\nIs the selection rectangular? The alternative is the more common stream\nselection. (Read-only)\n
diff --git a/modules/lua/init.lua b/modules/lua/init.lua
index 9e0979ef..843d55ac 100644
--- a/modules/lua/init.lua
+++ b/modules/lua/init.lua
@@ -10,18 +10,14 @@ module('_m.lua', 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`.
+-- + `Ctrl+L, M` (`⌘L, M` on Mac OSX): Open this module for editing.
+-- + `Ctrl+L, G` (`⌘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.
--- + `Ctrl+Esc`: (Mac OSX) Autocomplete symbol.
--- + `Ctrl+H`: Show documentation for the selected symbol or the symbol under
--- the caret.
--
-- ## Fields
--
@@ -179,14 +175,12 @@ events.connect(events.FILE_AFTER_SAVE,
-- @class table
-- @name _G.keys.lua
keys.lua = {
- al = {
+ [keys.LANGUAGE_MODULE_PREFIX] = {
m = { io.open_file,
(_HOME..'/modules/lua/init.lua'):iconv('UTF-8', _CHARSET) },
- g = { goto_required },
+ g = goto_required,
},
- ['s\n'] = { try_to_autocomplete_end },
- [not OSX and 'ci' or 'cesc'] = { sense.complete, sense },
- ch = { sense.show_apidoc, sense },
+ ['s\n'] = try_to_autocomplete_end,
}
-- Snippets.
diff --git a/modules/lua/tags b/modules/lua/tags
index 787d6472..8e2afe9f 100644
--- a/modules/lua/tags
+++ b/modules/lua/tags
@@ -24,6 +24,7 @@ CARET_SLOP _ 0;" F class:_SCINTILLA.constants
CARET_STRICT _ 0;" F class:_SCINTILLA.constants
CHAR_ADDED _ 0;" F class:events
CLASS _ 0;" F class:lexer
+CLEAR _ 0;" F class:keys
COMMAND_ENTRY_COMMAND _ 0;" F class:events
COMMAND_ENTRY_KEYPRESS _ 0;" F class:events
COMMENT _ 0;" F class:lexer
@@ -90,12 +91,14 @@ KEYSYMS _ 0;" t class:keys
KEYWORD _ 0;" F class:lexer
KEYWORDSET_MAX _ 0;" F class:_SCINTILLA.constants
LANGUAGE_MODULE_LOADED _ 0;" F class:events
+LANGUAGE_MODULE_PREFIX _ 0;" F class:keys
MARGIN_CLICK _ 0;" F class:events
MARKER_MAX _ 0;" F class:_SCINTILLA.constants
MARK_BOOKMARK_COLOR _ 0;" F class:_m.textadept.bookmarks
MARK_HIGHLIGHT_BACK _ 0;" F class:_m.textadept.editing
MAX _ 0;" F class:_m.textadept.snapopen
MENU_CLICKED _ 0;" F class:events
+META _ 0;" F class:keys
NUMBER _ 0;" F class:lexer
OPERATOR _ 0;" F class:lexer
OSX _ 0;" F
@@ -1015,6 +1018,7 @@ get_class _ 0;" f class:_m.textadept.adeptsense
get_completions _ 0;" f class:_m.textadept.adeptsense
get_cur_line _ 0;" f class:buffer
get_fold_level _ 0;" f class:lexer
+get_gdk_key _ 0;" f class:keys
get_hotspot_active_back _ 0;" f class:buffer
get_hotspot_active_fore _ 0;" f class:buffer
get_indent_amount _ 0;" f class:lexer
@@ -1272,6 +1276,7 @@ oct_num _ 0;" F class:lexer
open _ 0;" f class:_m.textadept.snapopen
open _ 0;" f class:io
open_file _ 0;" f class:io
+open_recent_file _ 0;" f class:io
orange _ 0;" F class:lexer.colors
os _ 0;" m
os _ 0;" t
@@ -1400,7 +1405,7 @@ select_indented_block _ 0;" f class:_m.textadept.editing
select_lexer _ 0;" f class:_m.textadept.mime_types
select_line _ 0;" f class:_m.textadept.editing
select_paragraph _ 0;" f class:_m.textadept.editing
-select_scope _ 0;" f class:_m.textadept.editing
+select_style _ 0;" f class:_m.textadept.editing
selection_duplicate _ 0;" f class:buffer
selection_end _ 0;" F class:buffer
selection_is_rectangle _ 0;" F class:buffer
diff --git a/modules/textadept/command_entry.lua b/modules/textadept/command_entry.lua
index f0c771ed..b2eab2c1 100644
--- a/modules/textadept/command_entry.lua
+++ b/modules/textadept/command_entry.lua
@@ -40,11 +40,10 @@ end)
events.connect(events.COMMAND_ENTRY_KEYPRESS, function(code)
local ce = gui.command_entry
- local KEYSYMS = keys.KEYSYMS
- if KEYSYMS[code] == 'esc' then
+ if keys.KEYSYMS[code] == 'esc' then
ce.focus() -- toggle focus to hide
return true
- elseif KEYSYMS[code] == '\t' then
+ elseif keys.KEYSYMS[code] == '\t' then
local substring = ce.entry_text:match('[%w_.:]+$') or ''
local path, o, prefix = substring:match('^([%w_.:]-)([.:]?)([%w_]*)$')
local f, err = loadstring('return ('..path..')')
diff --git a/modules/textadept/editing.lua b/modules/textadept/editing.lua
index 16ead02b..885449a4 100644
--- a/modules/textadept/editing.lua
+++ b/modules/textadept/editing.lua
@@ -87,7 +87,7 @@ events.connect(events.CHAR_ADDED, function(c)
end)
-- Removes matched chars on backspace.
-events.connect(events.KEYPRESS, function(code, shift, control, alt)
+events.connect(events.KEYPRESS, function(code)
if not AUTOPAIR or K[code] ~= '\b' or buffer.selections ~= 1 then return end
local buffer = buffer
local pos = buffer.current_pos
@@ -398,7 +398,7 @@ end
---
-- Selects all text with the same style as under the caret.
-function select_scope()
+function select_style()
local buffer = buffer
local start_pos, length = buffer.current_pos, buffer.length
local base_style, style_at = buffer.style_at[start_pos], buffer.style_at
@@ -446,7 +446,7 @@ local function clear_highlighted_words()
buffer:indicator_clear_range(0, buffer.length)
end
events.connect(events.KEYPRESS,
- function(c) if K[c] == 'esc' then clear_highlighted_words() end end)
+ function(code) if K[code] == 'esc' then clear_highlighted_words() end end)
---
-- Highlights all occurances of the word under the caret and adds markers to the
diff --git a/modules/textadept/filter_through.lua b/modules/textadept/filter_through.lua
index a0cc0072..35123194 100644
--- a/modules/textadept/filter_through.lua
+++ b/modules/textadept/filter_through.lua
@@ -28,7 +28,7 @@ function filter_through()
end
events.connect(events.COMMAND_ENTRY_KEYPRESS, function(code)
- if filter_through_active and code == 0xff1b then -- escape
+ if filter_through_active and keys.KEYSYMS[code] == 'esc' then
filter_through_active = false
end
end, 1) -- place before command_entry.lua's handler (if necessary)
diff --git a/modules/textadept/find.lua b/modules/textadept/find.lua
index 4d80ae39..a0f6e299 100644
--- a/modules/textadept/find.lua
+++ b/modules/textadept/find.lua
@@ -176,13 +176,12 @@ function find.find_incremental()
end
events.connect(events.COMMAND_ENTRY_KEYPRESS, function(code)
- local K = keys.KEYSYMS
if find.incremental then
- if K[code] == 'esc' then
+ if keys.KEYSYMS[code] == 'esc' then
find.incremental = nil
- elseif code < 256 or K[code] == '\b' then
+ elseif code < 256 or keys.KEYSYMS[code] == '\b' then
local text = gui.command_entry.entry_text
- if K[code] == '\b' then
+ if keys.KEYSYMS[code] == '\b' then
find_incremental(text:sub(1, -2))
else
find_incremental(text..string.char(code))
diff --git a/modules/textadept/keys.conf b/modules/textadept/keys.conf
new file mode 100644
index 00000000..c2951fac
--- /dev/null
+++ b/modules/textadept/keys.conf
@@ -0,0 +1,149 @@
+% Windows and Linux menu key commands.
+% This set of key commands is pretty standard among other text editors.
+% Define additional key commands in _USERHOME/modules/textadept/keys.lua.
+
+% Unassigned keys (~ denotes keys reserved by the operating system):
+% c: A B C D E N p qQ T ~ V X Y ) ] } * \n
+% a: aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpP QrRsStTuUvVwWxXyYzZ_ ) ] } *+-/=~~\n\s
+% ca: aAbBcCdDeE F hHi jJkK LmMnN pPqQ t Uv xXyYzZ_"'()[]{}<>* /
+
+% CTRL = 'c' (Control ^)
+% ALT = 'a' (Alt)
+% META = [unused]
+% SHIFT = 's' (Shift ⇧)
+% ADD = ''
+% Control, Alt, Shift, and 'a' = 'caA'
+% Control, Alt, Shift, and '\t' = 'cas\t'
+
+% File
+gtk-new = cn
+gtk-open = co
+Open Recent... = cao
+Reload = cO
+gtk-save = cs
+gtk-save-as = cS
+gtk-close = cw
+Close All = cW
+Load Session... =
+Save Session... =
+gtk-quit = aq
+
+% Edit
+gtk-undo = cz
+gtk-redo = cy cZ
+gtk-cut = cx
+gtk-copy = cc
+gtk-paste = cv
+Duplicate = cd
+gtk-delete =
+gtk-select-all = ca
+Match Brace = cm
+Select to Brace = cM
+Complete Word = c\n
+Delete Word =
+Highlight Word = cH
+Complete Symbol = c\s
+Show Documentation = ch
+Toggle Block Comment = c/
+Transpose Characters = ct
+Join Lines = cJ
+Convert Indentation =
+% Selection
+% Enclose In...
+HTML Tags = a<
+HTML Single Tag = a>
+Double Quotes = a"
+Single Quotes = a'
+Parentheses = a(
+Brackets = a[
+Braces = a{
+Grow Selection = c+
+Shrink Selection = c_
+% Select In...
+Between Tags = c<
+HTML Tag = c>
+Double Quote = c"
+Single Quote = c'
+Parenthesis = c(
+Bracket = c[
+Brace = c{
+Word =
+Line = cL
+Paragraph = cP
+Indented Block = cI
+Style =
+
+% Search
+gtk-find = cf
+Find Next = cg f3
+Find Previous = cG sf3
+Replace = cr
+Replace All = cR
+Find Incremental = caf
+Find in Files = cF
+Goto Next File Found = cag
+Goto Previous File Found = caG
+gtk-jump-to = cj
+
+% Tools
+Command Entry = ce
+Run = car
+Compile = caR
+Filter Through = c|
+% Snippets
+Expand = \t
+Insert... = ck
+Previous Placeholder = s\t
+Cancel = cK
+% Bookmark
+Toggle on Current Line = cf2
+Clear All = csf2
+Next = f2
+Previous = sf2
+Goto Bookmark... = af2
+% Snapopen
+User Home = cu
+Textadept Home = cau
+Current Directory = caO
+Show Style = ci
+
+% Buffer
+Next Buffer = c\t cpgdn
+Previous Buffer = cs\t cpgup
+Switch Buffer = cb
+Toggle View EOL = ca\n ca\n\r
+Toggle Wrap Mode = ca\\
+Toggle Show Indent Guides = caI
+Toggle Use Tabs = caT
+Toggle View Whitespace = ca\s
+Toggle Virtual Space = caV
+% EOL Mode
+CRLF =
+CR =
+LF =
+% Encoding
+UTF-8 =
+ASCII =
+ISO-8859-1 =
+MacRoman =
+UTF-16 =
+Select Lexer... = cal
+Refresh Syntax Highlighting = f5
+
+% View
+Next View = ca\t
+Previous View = cas\t
+Split Vertical = caS
+Split Horizontal = cas
+Unsplit = caw
+Unsplit All = caW
+Grow View = ca+ ca=
+Shrink View = ca-
+Zoom In = c=
+Zoom Out = c-
+Reset Zoom = c0
+
+% Help
+Manual = f1
+LuaDoc = sf1
+gtk-about =
diff --git a/modules/textadept/keys.lua b/modules/textadept/keys.lua
index f51e378a..e39fa796 100644
--- a/modules/textadept/keys.lua
+++ b/modules/textadept/keys.lua
@@ -3,329 +3,39 @@
local L = locale.localize
---
--- Defines key commands for Textadept.
--- This set of key commands is pretty standard among other text editors.
+-- Defines additional key commands for Textadept.
+-- The primary key commands are loaded from _USERHOME/keys.conf,
+-- _HOME/modules/textadept/keys.conf, _USERHOME/keys.osx.conf, or
+-- _HOME/modules/textadept/keys.osx.conf depending on the platform by
+-- _m.textadept.menu.
+-- This module, like _m.textadept.menu, should be 'require'ed last.
module('_m.textadept.keys', package.seeall)
local keys = keys
-local _buffer, _view = buffer, view
-local gui, m_textadept = gui, _m.textadept
--- Utility functions used by both layouts.
-local function enclose_in_tag()
- m_textadept.editing.enclose('<', '>')
- local buffer = buffer
- local pos = buffer.current_pos
- while buffer.char_at[pos - 1] ~= 60 do pos = pos - 1 end -- '<'
- buffer:insert_text(-1, '</'..buffer:text_range(pos, buffer.current_pos))
-end
-local function any_char_mt(f)
- return setmetatable({['\0'] = {}}, {
- __index = function(t, k)
- if #k == 1 then return { f, k, k } end
- end })
-end
-local function toggle_setting(setting, i)
- local state = buffer[setting]
- if type(state) == 'boolean' then
- buffer[setting] = not state
- elseif type(state) == 'number' then
- buffer[setting] = buffer[setting] == 0 and (i or 1) or 0
- end
- events.emit(events.UPDATE_UI) -- for updating statusbar
-end
-local function show_style()
- local buffer = buffer
- local style = buffer.style_at[buffer.current_pos]
- local text = string.format("%s %s\n%s %s (%d)", L('Lexer'),
- buffer:get_lexer(), L('Style'),
- buffer:get_style_name(style), style)
- buffer:call_tip_show(buffer.current_pos, text)
-end
-
--- CTRL = 'c'
--- SHIFT = 's'
--- ALT = 'a'
--- ADD = ''
--- Control, Shift, Alt, and 'a' = 'caA'
--- Control, Shift, Alt, and '\t' = 'csa\t'
-
-if not OSX then
- -- Windows and Linux key commands.
-
- --[[
- C: D J K M T U
- A: A B D E F G H J K L M N P T U V W X Y Z
- CS: A C D G I J K L M N O Q T U V X Y Z
- SA: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
- CA: A B C D E F G H J K L M N O Q R S T U W X Y Z
- CSA: A B C D E F G H J K L M N O P Q R S T U V W X Y Z
- ]]--
-
- keys.clear_sequence = 'esc'
-
- -- File
- keys.cn = new_buffer
- keys.co = io.open_file
- -- TODO: _buffer.reload
- keys.cs = _buffer.save
- keys.cS = _buffer.save_as
- keys.cw = _buffer.close
- keys.cW = io.close_all
- -- TODO: m_textadept.session.load after prompting with open dialog
- -- TODO: m_textadept.session.save after prompting with save dialog
- keys.aq = quit
-
- -- Edit
- local m_editing = m_textadept.editing
- keys.cz = _buffer.undo
- keys.cy = _buffer.redo
- keys.cx = _buffer.cut
- keys.cc = _buffer.copy
- keys.cv = _buffer.paste
- -- Delete is delete.
- keys.ca = _buffer.select_all
- keys.ce = m_editing.match_brace
- keys.cE = { m_editing.match_brace, 'select' }
- keys['c\n'] = { m_editing.autocomplete_word, '%w_' }
- keys['c\n\r'] = { m_editing.autocomplete_word, '%w_' } -- win32
- keys.cq = m_editing.block_comment
- -- TODO: { m_editing.current_word, 'delete' }
- keys.cH = m_editing.highlight_word
- -- TODO: m_editing.transpose_chars
- -- TODO: m_editing.convert_indentation
- keys.ac = { -- enClose in...
- t = enclose_in_tag,
- T = { m_editing.enclose, '<', ' />' },
- ['"'] = { m_editing.enclose, '"', '"' },
- ["'"] = { m_editing.enclose, "'", "'" },
- ['('] = { m_editing.enclose, '(', ')' },
- ['['] = { m_editing.enclose, '[', ']' },
- ['{'] = { m_editing.enclose, '{', '}' },
- c = any_char_mt(m_editing.enclose),
- }
- keys.as = { -- select in...
- t = { m_editing.select_enclosed, '>', '<' },
- ['"'] = { m_editing.select_enclosed, '"', '"' },
- ["'"] = { m_editing.select_enclosed, "'", "'" },
- ['('] = { m_editing.select_enclosed, '(', ')' },
- ['['] = { m_editing.select_enclosed, '[', ']' },
- ['{'] = { m_editing.select_enclosed, '{', '}' },
- w = { m_editing.current_word, 'select' },
- l = m_editing.select_line,
- p = m_editing.select_paragraph,
- b = m_editing.select_indented_block,
- s = m_editing.select_scope,
- g = { m_editing.grow_selection, 1 },
- c = any_char_mt(m_editing.select_enclosed),
- }
-
- -- Search
- keys.cf = gui.find.focus -- find/replace
- keys['f3'] = gui.find.find_next
- -- Find Next is an when find pane is focused.
- -- Find Prev is ap when find pane is focused.
- -- Replace is ar when find pane is focused.
- keys.cF = gui.find.find_incremental
- -- Find in Files is ai when find pane is focused.
- -- TODO: { gui.find.goto_file_in_list, true }
- -- TODO: { gui.find.goto_file_in_list, false }
- keys.cg = m_editing.goto_line
-
- -- Tools
- keys['f2'] = gui.command_entry.focus
- -- Run
- keys.cr = m_textadept.run.run
- keys.cR = m_textadept.run.compile
- keys.ar = m_textadept.filter_through.filter_through
- -- Snippets
- keys['\t'] = m_textadept.snippets._insert
- keys['s\t'] = m_textadept.snippets._previous
- keys.cai = m_textadept.snippets._cancel_current
- keys.ai = m_textadept.snippets._select
-
- -- Buffers
- keys.cb = gui.switch_buffer
- keys['c\t'] = { _view.goto_buffer, _view, 1, false }
- keys['cs\t'] = { _view.goto_buffer, _view, -1, false }
- keys.cB = {
- e = { toggle_setting, 'view_eol' },
- w = { toggle_setting, 'wrap_mode' },
- i = { toggle_setting, 'indentation_guides' },
- ['\t'] = { toggle_setting, 'use_tabs' },
- [' '] = { toggle_setting, 'view_ws' },
- v = { toggle_setting, 'virtual_space_options', 2 },
- }
- keys.cl = m_textadept.mime_types.select_lexer
- keys['f5'] = { _buffer.colourise, _buffer, 0, -1 }
-
- -- Views
- keys.cav = {
- n = { gui.goto_view, 1, false },
- p = { gui.goto_view, -1, false },
- S = { _view.split, _view }, -- vertical
- s = { _view.split, _view, false }, -- horizontal
- w = function() view:unsplit() return true end,
- W = function() while view:unsplit() do end end,
- -- TODO: function() view.size = view.size + 10 end
- -- TODO: function() view.size = view.size - 10 end
- }
- keys.c0 = function() buffer.zoom = 0 end
-
- -- Miscellaneous not in standard menu.
- keys.ao = io.open_recent_file
- keys.caI = show_style
-
-else
- -- Mac OSX key commands
-
- --[[
- C: J M U W X Z
- A: D E H J K L T U Y
- CS: C D G H I J K L M O Q S T U V W X Y Z
- SA: A C D H I J K L M N O Q R T U V X Y
- CA: A C E J K L M N O Q S U V W X Y Z
- CSA: A C D E H J K L M N O P Q R S T U V W X Y Z
- ]]--
-
- keys.clear_sequence = 'aesc'
-
- -- File
- keys.an = new_buffer
- keys.ao = io.open_file
- -- TODO: _buffer.reload
- keys.as = _buffer.save
- keys.aS = _buffer.save_as
- keys.aw = _buffer.close
- keys.aW = { io.close_all }
- -- TODO: m_textadept.session.load after prompting with open dialog
- -- TODO: m_textadept.session.save after prompting with save dialog
- keys.aq = quit
-
- -- Edit
- local m_editing = m_textadept.editing
- keys.az = _buffer.undo
- keys.aZ = _buffer.redo
- keys.ax = _buffer.cut
- keys.ac = _buffer.copy
- keys.av = _buffer.paste
- -- Delete is delete.
- keys.aa = _buffer.select_all
- keys.cm = m_editing.match_brace
- keys.aE = { m_editing.match_brace, 'select' }
- keys.esc = { m_editing.autocomplete_word, '%w_' }
- keys.cq = m_editing.block_comment
- -- TODO: { m_editing.current_word, 'delete' }
- keys.cat = m_editing.highlight_word
- keys.ct = m_editing.transpose_chars
- -- TODO: m_editing.convert_indentation
- keys.cc = { -- enClose in...
- t = enclose_in_tag,
- T = { m_editing.enclose, '<', ' />' },
- ['"'] = { m_editing.enclose, '"', '"' },
- ["'"] = { m_editing.enclose, "'", "'" },
- ['('] = { m_editing.enclose, '(', ')' },
- ['['] = { m_editing.enclose, '[', ']' },
- ['{'] = { m_editing.enclose, '{', '}' },
- c = any_char_mt(m_editing.enclose),
- }
- keys.cs = { -- select in...
- t = { m_editing.select_enclosed, '>', '<' },
- ['"'] = { m_editing.select_enclosed, '"', '"' },
- ["'"] = { m_editing.select_enclosed, "'", "'" },
- ['('] = { m_editing.select_enclosed, '(', ')' },
- ['['] = { m_editing.select_enclosed, '[', ']' },
- ['{'] = { m_editing.select_enclosed, '{', '}' },
- w = { m_editing.current_word, 'select' },
- l = m_editing.select_line,
- p = m_editing.select_paragraph,
- b = m_editing.select_indented_block,
- s = m_editing.select_scope,
- g = { m_editing.grow_selection, 1 },
- c = any_char_mt(m_editing.select_enclosed),
- }
-
- -- Search
- keys.af = gui.find.focus -- find/replace
- keys.ag = gui.find.find_next
- keys.aG = gui.find.find_prev
- keys.ar = gui.find.replace
- keys.ai = gui.find.find_incremental
- keys.aF = function()
- gui.find.in_files = true
- gui.find.focus()
- end
- keys.cag = { gui.find.goto_file_in_list, true }
- keys.caG = { gui.find.goto_file_in_list, false }
- keys.cg = m_editing.goto_line
-
- -- Tools
- keys['f2'] = gui.command_entry.focus
- -- Run
- keys.cr = { m_textadept.run.run }
- keys.cR = { m_textadept.run.compile }
- keys.car = { m_textadept.filter_through.filter_through }
- -- Snippets
- keys['\t'] = m_textadept.snippets._insert
- keys['s\t'] = m_textadept.snippets._previous
- keys.cai = m_textadept.snippets._cancel_current
- keys.ci = m_textadept.snippets._select
-
- -- Buffers
- keys.ab = gui.switch_buffer
- keys['c\t'] = { _view.goto_buffer, _view, 1, false }
- keys['cs\t'] = { _view.goto_buffer, _view, -1, false }
- keys.aB = {
- e = { toggle_setting, 'view_eol' },
- w = { toggle_setting, 'wrap_mode' },
- i = { toggle_setting, 'indentation_guides' },
- ['\t'] = { toggle_setting, 'use_tabs' },
- [' '] = { toggle_setting, 'view_ws' },
- v = { toggle_setting, 'virtual_space_options', 2 },
- }
- keys.cl = m_textadept.mime_types.select_lexer
- keys['f5'] = { _buffer.colourise, _buffer, 0, -1 }
-
- -- Views
- keys.cv = {
- n = { gui.goto_view, 1, false },
- p = { gui.goto_view, -1, false },
- S = { _view.split, _view }, -- vertical
- s = { _view.split, _view, false }, -- horizontal
- w = function() view:unsplit() return true end,
- W = function() while view:unsplit() do end end,
- -- TODO: function() view.size = view.size + 10 end
- -- TODO: function() view.size = view.size - 10 end
- }
- keys.c0 = function() buffer.zoom = 0 end
-
- -- Miscellaneous not in standard menu.
- keys.co = io.open_recent_file
- keys.caI = show_style
-
- -- Movement/selection commands
- keys.cf = _buffer.char_right
- keys.cF = _buffer.char_right_extend
- keys.caf = _buffer.word_right
- keys.caF = _buffer.word_right_extend
- keys.cb = _buffer.char_left
- keys.cB = _buffer.char_left_extend
- keys.cab = _buffer.word_left
- keys.caB = _buffer.word_left_extend
- keys.cn = _buffer.line_down
- keys.cN = _buffer.line_down_extend
- keys.cp = _buffer.line_up
- keys.cP = _buffer.line_up_extend
- keys.ca = _buffer.vc_home
- keys.cA = _buffer.home_extend
- keys.ce = _buffer.line_end
- keys.cE = _buffer.line_end_extend
- keys.cah = _buffer.del_word_left
- keys.cd = _buffer.clear
- keys.cad = _buffer.del_word_right
- keys.ck = function()
+if OSX then
+ -- See keys.osx.conf for unassigned keys.
+ keys.mk = function()
buffer:line_end_extend()
buffer:cut()
end
- keys.cy = _buffer.paste
+ local buffer = buffer
+ keys.mf = buffer.char_right
+ keys.mF = buffer.char_right_extend
+ keys.amf = buffer.word_right
+ keys.amF = buffer.word_right_extend
+ keys.mb = buffer.char_left
+ keys.mB = buffer.char_left_extend
+ keys.amb = buffer.word_left
+ keys.amB = buffer.word_left_extend
+ keys.mn = buffer.line_down
+ keys.mN = buffer.line_down_extend
+ keys.mp = buffer.line_up
+ keys.mP = buffer.line_up_extend
+ keys.ma = buffer.vc_home
+ keys.mA = buffer.vc_home_extend
+ keys.me = buffer.line_end
+ keys.mE = buffer.line_end_extend
+ keys.md = buffer.clear
+ keys.ml = buffer.vertical_centre_caret
end
diff --git a/modules/textadept/keys.osx.conf b/modules/textadept/keys.osx.conf
new file mode 100644
index 00000000..22877373
--- /dev/null
+++ b/modules/textadept/keys.osx.conf
@@ -0,0 +1,149 @@
+% Mac OSX menu key commands.
+% This set of key commands is pretty standard among other text editors.
+% Define additional key commands in _USERHOME/modules/textadept/keys.lua.
+
+% Unassigned keys (~ denotes keys reserved by the operating system):
+% c: A B C D E ~ JkK ~M N p ~ tT U V XyY ) ] } * ~~\n~~
+% ca: aAbBcC~DeE F ~HiIjJkK L~MnN pPq~rRsStT UvVwWxXyYzZ_"'()[]{}<>*+-/= \n~~
+% m: cC D gG Hi J K L oO qQ uUv xXyYzZ_ ) ] } * /
+
+% CTRL = 'c' (Command ⌘)
+% ALT = 'a' (Alt/option ⌥)
+% META = 'm' (Control ^)
+% SHIFT = 's' (Shift ⇧)
+% ADD = ''
+% Command, Alt, Shift, and 'a' = 'caA'
+% Command, Alt, Shift, and '\t' = 'cas\t'
+
+% File
+gtk-new = cn
+gtk-open = co
+Open Recent... = cao
+Reload = cO
+gtk-save = cs
+gtk-save-as = cS
+gtk-close = cw
+Close All = cW
+Load Session... =
+Save Session... =
+gtk-quit = cq
+
+% Edit
+gtk-undo = cz
+gtk-redo = cZ
+gtk-cut = cx
+gtk-copy = cc
+gtk-paste = cv
+Duplicate = cd
+gtk-delete =
+gtk-select-all = ca
+Match Brace = mm
+Select to Brace = mM
+Complete Word = mesc
+Delete Word =
+Highlight Word = cH
+Complete Symbol = aesc
+Show Documentation = mh
+Toggle Block Comment = c/
+Transpose Characters = mt
+Join Lines = mj
+Convert Indentation =
+% Selection
+% Enclose In...
+HTML Tags = m<
+HTML Single Tag = m>
+Double Quotes = m"
+Single Quotes = m'
+Parentheses = m(
+Brackets = m[
+Braces = m{
+Grow Selection = c+
+Shrink Selection = c_
+% Select In...
+Between Tags = c<
+HTML Tag = c>
+Double Quote = c"
+Single Quote = c'
+Parenthesis = c(
+Bracket = c[
+Brace = c{
+Word =
+Line = cL
+Paragraph = cP
+Indented Block = cI
+Style =
+
+% Search
+gtk-find = cf
+Find Next = cg
+Find Previous = cG
+Replace = cr
+Replace All = cR
+Find Incremental = caf
+Find in Files = cF
+Goto Next File Found = cag
+Goto Previous File Found = caG
+gtk-jump-to = cj
+
+% Tools
+Command Entry = ce
+Run = mr
+Compile = mR
+Filter Through = c|
+% Snippets
+Expand = \t
+Insert... = a\t
+Previous Placeholder = s\t
+Cancel = as\t
+% Bookmark
+Toggle on Current Line = cf2
+Clear All = csf2
+Next = f2
+Previous = sf2
+Goto Bookmark... = af2
+% Snapopen
+User Home = cu
+Textadept Home = cau
+Current Directory = caO
+Show Style = ci
+
+% Buffer
+Next Buffer = m`
+Previous Buffer = m~
+Switch Buffer = cb
+Toggle View EOL = m\n
+Toggle Wrap Mode = m\\
+Toggle Show Indent Guides = mI
+Toggle Use Tabs = mT
+Toggle View Whitespace = m\s
+Toggle Virtual Space = mV
+% EOL Mode
+CRLF =
+CR =
+LF =
+% Encoding
+UTF-8 =
+ASCII =
+ISO-8859-1 =
+MacRoman =
+UTF-16 =
+Select Lexer... = cal
+Refresh Syntax Highlighting = f5
+
+% View
+Next View = m\t
+Previous View = ms\t
+Split Vertical = mS
+Split Horizontal = ms
+Unsplit = mw
+Unsplit All = mW
+Grow View = m+ m=
+Shrink View = m-
+Zoom In = c=
+Zoom Out = c-
+Reset Zoom = c0
+
+% Help
+Manual = f1
+LuaDoc = sf1
+gtk-about =
diff --git a/modules/textadept/menu.lua b/modules/textadept/menu.lua
index 03277491..38fb8e9e 100644
--- a/modules/textadept/menu.lua
+++ b/modules/textadept/menu.lua
@@ -1,5 +1,5 @@
-- Copyright 2007-2011 Mitchell mitchell<att>caladbolg.net. See LICENSE.
--- Modified by Robert Gieseke.
+-- Contributions from Robert Gieseke.
local L = locale.localize
local events = events
@@ -7,6 +7,9 @@ local gui = gui
---
-- Provides dynamic menus for Textadept.
+-- It also loads key commands from _USERHOME/keys.conf,
+-- _HOME/modules/textadept/keys.conf, _USERHOME/keys.osx.conf, or
+-- _HOME/modules/textadept/keys.osx.conf depending on the platform.
-- This module, like _m.textadept.keys, should be 'require'ed last.
module('_m.textadept.menu', package.seeall)
@@ -14,6 +17,28 @@ local _buffer, _view = buffer, view
local m_textadept, m_editing = _m.textadept, _m.textadept.editing
local SEPARATOR = { 'separator' }
+-- Load menu key commands.
+local K = {}
+local escapes = {
+ ['\\b'] = '\b', ['\\n'] = '\n', ['\\r'] = '\r', ['\\t'] = '\t',
+ ['\\\\'] = '\\', ['\\s'] = ' '
+}
+local conf = 'keys'..(OSX and '.osx' or '')..'.conf'
+local f = io.open(_USERHOME..'/'..conf)
+if not f then f = io.open(_HOME..'/modules/textadept/'..conf) end
+for line in f:lines() do
+ if not line:find('^%s*%%') then
+ local id, keys = line:match('^(.-)%s*=%s*(.+)$')
+ if id and keys then
+ K[id] = {}
+ for key in keys:gmatch('%S+') do
+ K[id][#K[id] + 1] = key:gsub('\\[bnrt\\s]', escapes)
+ end
+ end
+ end
+end
+f:close()
+
local function set_encoding(encoding)
buffer:set_encoding(encoding)
events.emit(events.UPDATE_UI) -- for updating statusbar
@@ -59,15 +84,15 @@ end
-- @name menubar
menubar = {
{ title = L('File'),
- { L('gtk-new'), new_buffer },
- { L('gtk-open'), io.open_file },
- { L('Open Recent...'), io.open_recent_file },
- { L('Reload'), _buffer.reload },
- { L('gtk-save'), _buffer.save },
- { L('gtk-save-as'), _buffer.save_as },
+ { L('gtk-new'), new_buffer, K['gtk-new'] },
+ { L('gtk-open'), io.open_file, K['gtk-open'] },
+ { L('Open Recent...'), io.open_recent_file, K['Open Recent...'] },
+ { L('Reload'), _buffer.reload, K['Reload'] },
+ { L('gtk-save'), _buffer.save, K['gtk-save'] },
+ { L('gtk-save-as'), _buffer.save_as, K['gtk-save-as'] },
SEPARATOR,
- { L('gtk-close'), _buffer.close },
- { L('Close All'), io.close_all },
+ { L('gtk-close'), _buffer.close, K['gtk-close'] },
+ { L('Close All'), io.close_all, K['Close All'] },
SEPARATOR,
{ L('Load Session...'), function()
local session_file = _SESSIONFILE or ''
@@ -81,7 +106,7 @@ menubar = {
if #utf8_filename > 0 then
_m.textadept.session.load(utf8_filename:iconv(_CHARSET, 'UTF-8'))
end
- end },
+ end, K['Load Session...'] },
{ L('Save Session...'), function()
local session_file = _SESSIONFILE or ''
local utf8_filename = gui.dialog('filesave',
@@ -94,38 +119,44 @@ menubar = {
if #utf8_filename > 0 then
_m.textadept.session.save(utf8_filename:iconv(_CHARSET, 'UTF-8'))
end
- end },
+ end, K['Save Session...'] },
SEPARATOR,
- { L('gtk-quit'), quit },
+ { L('gtk-quit'), quit, K['gtk-quit'] },
},
{ title = L('Edit'),
- { L('gtk-undo'), _buffer.undo },
- { L('gtk-redo'), _buffer.redo },
+ { L('gtk-undo'), _buffer.undo, K['gtk-undo'] },
+ { L('gtk-redo'), _buffer.redo, K['gtk-redo'] },
SEPARATOR,
- { L('gtk-cut'), _buffer.cut },
- { L('gtk-copy'), _buffer.copy },
- { L('gtk-paste'), _buffer.paste },
- { L('Duplicate'), _buffer.line_duplicate },
- { L('gtk-delete'), _buffer.clear },
- { L('gtk-select-all'), _buffer.select_all },
+ { L('gtk-cut'), _buffer.cut, K['gtk-cut'] },
+ { L('gtk-copy'), _buffer.copy, K['gtk-copy'] },
+ { L('gtk-paste'), _buffer.paste, K['gtk-paste'] },
+ { L('Duplicate'), _buffer.line_duplicate, K['Duplicate'] },
+ { L('gtk-delete'), _buffer.clear, K['gtk-delete'] },
+ { L('gtk-select-all'), _buffer.select_all, K['gtk-select-all'] },
SEPARATOR,
- { L('Match Brace'), m_editing.match_brace },
- { L('Select to Brace'), { m_editing.match_brace, 'select' } },
- { L('Complete Word'), { m_editing.autocomplete_word, '%w_' } },
- { L('Delete Word'), { m_editing.current_word, 'delete' } },
- { L('Highlight Word'), m_editing.highlight_word },
+ { L('Match Brace'), m_editing.match_brace, K['Match Brace'] },
+ { L('Select to Brace'), { m_editing.match_brace, 'select' },
+ K['Select to Brace'] },
+ { L('Complete Word'), { m_editing.autocomplete_word, '%w_' },
+ K['Complete Word'] },
+ { L('Delete Word'), { m_editing.current_word, 'delete' },
+ K['Delete Word'] },
+ { L('Highlight Word'), m_editing.highlight_word, K['Highlight Word'] },
{ L('Complete Symbol'), function()
local m = _m[buffer:get_lexer()]
- if m and m.adeptsense then m.adeptsense.sense:complete() end
- end },
+ if m and m.sense then m.sense:complete() end
+ end, K['Complete Symbol'] },
{ L('Show Documentation'), function()
local m = _m[buffer:get_lexer()]
- if m and m.adeptsense then m.adeptsense.sense:show_apidoc() end
- end },
- { L('Toggle Block Comment'), m_editing.block_comment },
- { L('Transpose Characters'), m_editing.transpose_chars },
- { L('Join Lines'), m_editing.join_lines },
- { L('Convert Indentation'), m_editing.convert_indentation },
+ if m and m.sense then m.sense:show_apidoc() end
+ end, K['Show Documentation'] },
+ { L('Toggle Block Comment'), m_editing.block_comment,
+ K['Toggle Block Comment'] },
+ { L('Transpose Characters'), m_editing.transpose_chars,
+ K['Transpose Characters'] },
+ { L('Join Lines'), m_editing.join_lines, K['Join Lines'] },
+ { L('Convert Indentation'), m_editing.convert_indentation,
+ K['Convert Indentation'] },
{ title = L('Selection'),
{ title = L('Enclose in...'),
{ L('HTML Tags'), function()
@@ -135,90 +166,128 @@ menubar = {
while buffer.char_at[pos - 1] ~= 60 do pos = pos - 1 end -- '<'
buffer:insert_text(-1,
'</'..buffer:text_range(pos, buffer.current_pos))
- end },
- { L('HTML Single Tag'), { m_editing.enclose, '<', ' />' } },
- { L('Double Quotes'), { m_editing.enclose, '"', '"' } },
- { L('Single Quotes'), { m_editing.enclose, "'", "'" } },
- { L('Parentheses'), { m_editing.enclose, '(', ')' } },
- { L('Brackets'), { m_editing.enclose, '[', ']' } },
- { L('Braces'), { m_editing.enclose, '{', '}' } },
+ end, K['HTML Tags'] },
+ { L('HTML Single Tag'), { m_editing.enclose, '<', ' />' },
+ K['HTML Single Tag'] },
+ { L('Double Quotes'), { m_editing.enclose, '"', '"' },
+ K['Double Quotes'] },
+ { L('Single Quotes'), { m_editing.enclose, "'", "'" },
+ K['Single Quotes'] },
+ { L('Parentheses'), { m_editing.enclose, '(', ')' }, K['Parentheses'] },
+ { L('Brackets'), { m_editing.enclose, '[', ']' }, K['Brackets'] },
+ { L('Braces'), { m_editing.enclose, '{', '}' }, K['Braces'] },
},
- { L('Grow'), { m_editing.grow_selection, 1 } },
+ { L('Grow Selection'), { m_editing.grow_selection, 1 },
+ K['Grow Selection'] },
+ { L('Shrink Selection'), { m_editing.grow_selection, -1 },
+ K['Shrink Selection'] },
},
{ title = L('Select in...'),
- { L('HTML Tag'), { m_editing.select_enclosed, '>', '<' } },
- { L('Double Quote'), { m_editing.select_enclosed, '"', '"' } },
- { L('Single Quote'), { m_editing.select_enclosed, "'", "'" } },
- { L('Parenthesis'), { m_editing.select_enclosed, '(', ')' } },
- { L('Bracket'), { m_editing.select_enclosed, '[', ']' } },
- { L('Brace'), { m_editing.select_enclosed, '{', '}' } },
- { L('Word'), { m_editing.current_word, 'select' } },
- { L('Line'), m_editing.select_line },
- { L('Paragraph'), m_editing.select_paragraph },
- { L('Indented Block'), m_editing.select_indented_block },
- { L('Scope'), m_editing.select_scope },
+ { L('Between Tags'), { m_editing.select_enclosed, '>', '<' },
+ K['Between Tags'] },
+ { L('HTML Tag'), { m_editing.select_enclosed, '<', '>' },
+ K['HTML Tag'] },
+ { L('Double Quote'), { m_editing.select_enclosed, '"', '"' },
+ K['Double Quote'] },
+ { L('Single Quote'), { m_editing.select_enclosed, "'", "'" },
+ K['Single Quote'] },
+ { L('Parenthesis'), { m_editing.select_enclosed, '(', ')' },
+ K['Parenthesis'] },
+ { L('Bracket'), { m_editing.select_enclosed, '[', ']' }, K['Bracket'] },
+ { L('Brace'), { m_editing.select_enclosed, '{', '}' }, K['Brace'] },
+ { L('Word'), { m_editing.current_word, 'select' }, K['Word'] },
+ { L('Line'), m_editing.select_line, K['Line'] },
+ { L('Paragraph'), m_editing.select_paragraph, K['Paragraph'] },
+ { L('Indented Block'), m_editing.select_indented_block,
+ K['Indented Block'] },
+ { L('Style'), m_editing.select_style, K['Style'] },
},
},
{ title = L('Search'),
- { L('gtk-find'), gui.find.focus },
- { L('Find Next'), gui.find.call_find_next },
- { L('Find Previous'), gui.find.call_find_prev },
- { L('Replace'), gui.find.call_replace },
- { L('Replace All'), gui.find.call_replace_all },
- { L('Find Incremental'), gui.find.find_incremental },
+ { L('gtk-find'), gui.find.focus, K['gtk-find'] },
+ { L('Find Next'), gui.find.find_next, K['Find Next'] },
+ { L('Find Previous'), gui.find.find_prev, K['Find Previous'] },
+ { L('Replace'), gui.find.replace, K['Replace'] },
+ { L('Replace All'), gui.find.replace_all, K['Replace All'] },
+ { L('Find Incremental'), gui.find.find_incremental, K['Find Incremental'] },
SEPARATOR,
{ L('Find in Files'), function()
gui.find.in_files = true
gui.find.focus()
- end },
- { L('Goto Next File Found'), { gui.find.goto_file_in_list, true } },
- { L('Goto Previous File Found'), { gui.find.goto_file_in_list, false } },
+ end, K['Find in Files'] },
+ { L('Goto Next File Found'), { gui.find.goto_file_in_list, true },
+ K['Goto Next File Found'] },
+ { L('Goto Previous File Found'), { gui.find.goto_file_in_list, false },
+ K['Goto Previous File Found'] },
SEPARATOR,
- { L('gtk-jump-to'), m_editing.goto_line },
+ { L('gtk-jump-to'), m_editing.goto_line, K['gtk-jump-to'] },
},
{ title = L('Tools'),
- { L('Command Entry'), gui.command_entry.focus },
+ { L('Command Entry'), gui.command_entry.focus, K['Command Entry'] },
SEPARATOR,
- { L('Run'), m_textadept.run.run },
- { L('Compile'), m_textadept.run.compile },
- { L('Filter Through'), _m.textadept.filter_through.filter_through },
+ { L('Run'), m_textadept.run.run, K['Run'] },
+ { L('Compile'), m_textadept.run.compile, K['Compile'] },
+ { L('Filter Through'), _m.textadept.filter_through.filter_through,
+ K['Filter Through'] },
SEPARATOR,
{ title = L('Snippets'),
- { L('Expand'), m_textadept.snippets._insert },
- { L('Insert...'), m_textadept.snippets._select },
- { L('Previous Placeholder'), m_textadept.snippets._previous },
- { L('Cancel'), m_textadept.snippets._cancel_current },
+ { L('Expand'), m_textadept.snippets._insert, K['Expand'] },
+ { L('Insert...'), m_textadept.snippets._select, K['Insert...'] },
+ { L('Previous Placeholder'), m_textadept.snippets._previous,
+ K['Previous Placeholder'] },
+ { L('Cancel'), m_textadept.snippets._cancel_current, K['Cancel'] },
},
{ title = L('Bookmark'),
- { L('Toggle on Current Line'), m_textadept.bookmarks.toggle },
- { L('Clear All'), m_textadept.bookmarks.clear },
- { L('Next'), m_textadept.bookmarks.goto_next },
- { L('Previous'), m_textadept.bookmarks.goto_prev },
- { L('Goto Bookmark...'), m_textadept.bookmarks.goto },
+ { L('Toggle on Current Line'), m_textadept.bookmarks.toggle,
+ K['Toggle on Current Line'] },
+ { L('Clear All'), m_textadept.bookmarks.clear, K['Clear All'] },
+ { L('Next'), m_textadept.bookmarks.goto_next, K['Next'] },
+ { L('Previous'), m_textadept.bookmarks.goto_prev, K['Previous'] },
+ { L('Goto Bookmark...'), m_textadept.bookmarks.goto,
+ K['Goto Bookmark...'] },
},
{ title = L('Snapopen'),
- { L('User Home'), { m_textadept.snapopen.open, _USERHOME } },
- { L('Textadept Home'), { m_textadept.snapopen.open, _HOME } },
+ { L('User Home'), { m_textadept.snapopen.open, _USERHOME },
+ K['User Home'] },
+ { L('Textadept Home'), { m_textadept.snapopen.open, _HOME },
+ K['Textadept Home'] },
{ L('Current Directory'), function()
if buffer.filename then
m_textadept.snapopen.open(buffer.filename:match('^(.+)[/\\]'))
end
- end },
+ end, K['Current Directory'] },
},
+ SEPARATOR,
+ { L('Show Style'), function()
+ local buffer = buffer
+ local style = buffer.style_at[buffer.current_pos]
+ local text = string.format("%s %s\n%s %s (%d)", L('Lexer'),
+ buffer:get_lexer(), L('Style'),
+ buffer:get_style_name(style), style)
+ buffer:call_tip_show(buffer.current_pos, text)
+ end , K['Show Style'] },
},
{ title = L('Buffer'),
- { L('Next Buffer'), { _view.goto_buffer, _view, 1, false } },
- { L('Previous Buffer'), { _view.goto_buffer, _view, -1, false } },
- { L('Switch Buffer'), gui.switch_buffer },
+ { L('Next Buffer'), { _view.goto_buffer, _view, 1, false },
+ K['Next Buffer'] },
+ { L('Previous Buffer'), { _view.goto_buffer, _view, -1, false },
+ K['Previous Buffer'] },
+ { L('Switch Buffer'), gui.switch_buffer, K['Switch Buffer'] },
SEPARATOR,
- { L('Toggle View EOL'), { toggle_setting, 'view_eol' } },
- { L('Toggle Wrap Mode'), { toggle_setting, 'wrap_mode' } },
- { L('Toggle Show Indentation Guides'),
- { toggle_setting, 'indentation_guides' } },
- { L('Toggle Use Tabs'), { toggle_setting, 'use_tabs' } },
- { L('Toggle View Whitespace'), { toggle_setting, 'view_ws' } },
+ { L('Toggle View EOL'), { toggle_setting, 'view_eol' },
+ K['Toggle View EOL'] },
+ { L('Toggle Wrap Mode'), { toggle_setting, 'wrap_mode' },
+ K['Toggle Wrap Mode'] },
+ { L('Toggle Show Indent Guides'),
+ { toggle_setting, 'indentation_guides' },
+ K['Toggle Show Indent Guides'] },
+ { L('Toggle Use Tabs'), { toggle_setting, 'use_tabs' },
+ K['Toggle Use Tabs'] },
+ { L('Toggle View Whitespace'), { toggle_setting, 'view_ws' },
+ K['Toggle View Whitespace'] },
{ L('Toggle Virtual Space'),
- { toggle_setting, 'virtual_space_options', 2} },
+ { toggle_setting, 'virtual_space_options', 2 },
+ K['Toggle Virtual Space'] },
SEPARATOR,
{ title = L('Indentation'),
{ '2', { set_indentation, 2 } },
@@ -227,56 +296,59 @@ menubar = {
{ '8', { set_indentation, 8 } },
},
{ title = L('EOL Mode'),
- { L('CRLF'), { set_eol_mode, 0 } },
- { L('CR'), { set_eol_mode, 1 } },
- { L('LF'), { set_eol_mode, 2 } },
+ { L('CRLF'), { set_eol_mode, 0 }, K['CRLF'] },
+ { L('CR'), { set_eol_mode, 1 }, K['CR'] },
+ { L('LF'), { set_eol_mode, 2 }, K['LF'] },
},
{ title = L('Encoding'),
- { L('UTF-8'), { set_encoding, 'UTF-8' } },
- { L('ASCII'), { set_encoding, 'ASCII' } },
- { L('ISO-8859-1'), { set_encoding, 'ISO-8859-1' } },
- { L('MacRoman'), { set_encoding, 'MacRoman' } },
- { L('UTF-16'), { set_encoding, 'UTF-16LE' } },
+ { L('UTF-8'), { set_encoding, 'UTF-8' }, K['UTF-8'] },
+ { L('ASCII'), { set_encoding, 'ASCII' }, K['ASCII'] },
+ { L('ISO-8859-1'), { set_encoding, 'ISO-8859-1' }, K['ISO-8859-1'] },
+ { L('MacRoman'), { set_encoding, 'MacRoman' }, K['MacRoman'] },
+ { L('UTF-16'), { set_encoding, 'UTF-16LE' }, K['UTF-16'] },
},
SEPARATOR,
+ { L('Select Lexer...'), m_textadept.mime_types.select_lexer,
+ K['Select Lexer...'] },
{ L('Refresh Syntax Highlighting'),
- { _buffer.colourise, _buffer, 0, -1 } },
+ { _buffer.colourise, _buffer, 0, -1 }, K['Refresh Syntax Highlighting'] },
},
{ title = L('View'),
- { L('Next View'), { gui.goto_view, 1, false } },
- { L('Previous View'), { gui.goto_view, -1, false } },
+ { L('Next View'), { gui.goto_view, 1, false }, K['Next View'] },
+ { L('Previous View'), { gui.goto_view, -1, false }, K['Previous View'] },
SEPARATOR,
- { L('Split Vertical'), { _view.split, _view } },
- { L('Split Horizontal'), { _view.split, _view, false } },
- { L('Unsplit'), function() view:unsplit() end },
- { L('Unsplit All'), function() while view:unsplit() do end end },
+ { L('Split Vertical'), { _view.split, _view }, K['Split Vertical'] },
+ { L('Split Horizontal'), { _view.split, _view, false },
+ K['Split Horizontal'] },
+ { L('Unsplit'), function() view:unsplit() end, K['Unsplit'] },
+ { L('Unsplit All'), function() while view:unsplit() do end end,
+ K['Unsplit All'] },
SEPARATOR,
- { L('Grow'),
- function() if view.size then view.size = view.size + 10 end end
- },
- { L('Shrink'),
- function() if view.size then view.size = view.size - 10 end end
- },
+ { L('Grow View'),
+ function() if view.size then view.size = view.size + 10 end end,
+ K['Grow View'] },
+ { L('Shrink View'),
+ function() if view.size then view.size = view.size - 10 end end,
+ K['Shrink View'] },
SEPARATOR,
- { L('Zoom In'), function() buffer.zoom = buffer.zoom + 1 end },
- { L('Zoom Out'), function() buffer.zoom = buffer.zoom - 1 end },
- { L('Reset Zoom'), function() buffer.zoom = 0 end },
+ { L('Zoom In'), _buffer.zoom_in, K['Zoom In'] },
+ { L('Zoom Out'), _buffer.zoom_out, K['Zoom Out'] },
+ { L('Reset Zoom'), function() buffer.zoom = 0 end, K['Reset Zoom'] },
},
-- Lexer menu inserted here
{ title = L('Help'),
{ L('Manual'),
- { open_webpage, _HOME..'/doc/manual/1_Introduction.html' } },
- { L('LuaDoc'), { open_webpage, _HOME..'/doc/index.html' } },
+ { open_webpage, _HOME..'/doc/manual/1_Introduction.html' }, K['Manual'] },
+ { L('LuaDoc'), { open_webpage, _HOME..'/doc/index.html' }, K['LuaDoc'] },
SEPARATOR,
{ L('gtk-about'),
{ gui.dialog, 'ok-msgbox', '--title', 'Textadept', '--informative-text',
- _RELEASE, '--no-cancel' }
- },
+ _RELEASE, '--no-cancel' }, K['gtk-about'] },
},
}
local lexer_menu = { title = L('Lexers') }
for _, lexer in ipairs(_m.textadept.mime_types.lexers) do
- lexer_menu[#lexer_menu + 1] = { lexer:gsub('_', '__'), { set_lexer, lexer} }
+ lexer_menu[#lexer_menu + 1] = { lexer:gsub('_', '__'), { set_lexer, lexer } }
end
table.insert(menubar, #menubar, lexer_menu) -- before 'Help'
@@ -300,6 +372,7 @@ local menu_actions = {}
local contextmenu_actions = {}
-- Creates a menu suitable for gui.gtkmenu from the menu table format.
+-- Also assigns key commands.
-- @param menu The menu to create a gtkmenu from.
-- @return gtkmenu that can be passed to gui.gtkmenu.
local function read_menu_table(menu)
@@ -309,9 +382,14 @@ local function read_menu_table(menu)
if menuitem.title then
gtkmenu[#gtkmenu + 1] = read_menu_table(menuitem)
else
+ local label, f, k = menuitem[1], menuitem[2], menuitem[3]
local menu_id = #menu_actions + 1
- gtkmenu[#gtkmenu + 1] = { menuitem[1], menu_id }
- if menuitem[2] then menu_actions[menu_id] = menuitem[2] end
+ local key, mods = keys.get_gdk_key(k and k[1])
+ gtkmenu[#gtkmenu + 1] = { label, menu_id, key, mods }
+ if f then
+ menu_actions[menu_id] = f
+ if k then for _, key in ipairs(k) do keys[key] = f end end
+ end
end
end
return gtkmenu
@@ -323,8 +401,11 @@ end
-- entry is another table that corresponds to a particular menu. A menu can
-- have a 'title' key with string value. Each menu item is either a submenu
-- (another menu table) or a table consisting of two items: string menu text
--- and an action table just like `keys`'s action table. If the menu text is
--- 'separator', a menu separator is created and no action table is required.
+-- and a function or action table just like in `keys`. The table can
+-- optionally contain 2 more number values: a GDK keycode and modifier mask
+-- for setting a menu accelerator. If the menu text is 'separator', a menu
+-- separator is created and no action table is required.
+-- @see keys.get_gdk_key
function set_menubar(menubar)
menu_actions = {}
local _menubar = {}
@@ -337,7 +418,7 @@ end
---
-- Sets gui.context_menu from the given menu table.
-- @param menu_table The menu table to create the context menu from. Each table
--- entry is either a submenu or menu text and an action table.
+-- entry is either a submenu or menu text and a function or action table.
-- @see set_menubar
function set_contextmenu(menu_table)
context_actions = {}