aboutsummaryrefslogtreecommitdiff
path: root/modules/textadept
diff options
context:
space:
mode:
Diffstat (limited to 'modules/textadept')
-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
8 files changed, 538 insertions, 451 deletions
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 = {}