aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/events.lua12
-rw-r--r--core/keys.lua134
-rw-r--r--core/locale.conf16
-rw-r--r--doc/manual/10_Advanced.md18
-rw-r--r--doc/manual/14_Appendix.md311
-rw-r--r--doc/manual/1_Introduction.md5
-rw-r--r--doc/manual/3_UserInterface.md4
-rw-r--r--doc/manual/4_WorkingWithFiles.md34
-rw-r--r--doc/manual/5_FileNavigation.md11
-rw-r--r--doc/manual/6_AdeptEditing.md86
-rw-r--r--doc/manual/7_Modules.md24
-rw-r--r--doc/manual/9_Preferences.md21
-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
-rwxr-xr-xscripts/update_doc6
-rw-r--r--src/textadept.c18
26 files changed, 971 insertions, 786 deletions
diff --git a/core/events.lua b/core/events.lua
index cea75a71..89092dfe 100644
--- a/core/events.lua
+++ b/core/events.lua
@@ -64,9 +64,9 @@ module('events', package.seeall)
-- Entry.<br />
-- * `code`: The key code.
-- * `shift`: The Shift key is held down.
--- * `ctrl`: The Control key is held down.
--- * `alt`: The Alt/Apple key is held down.
--- * `option`: The Alt/Option key on Mac OSX is held down.
+-- * `ctrl`: The Control/Command key is held down.
+-- * `alt`: The Alt/option key is held down.
+-- * `meta`: The Control key on Mac OSX is held down.
-- * `DOUBLE_CLICK`: Called when the mouse button is double-clicked.<br />
-- * `position`: The text position of the double click.
-- * `line`: The line of the double click.
@@ -113,9 +113,9 @@ module('events', package.seeall)
-- * `KEYPRESS`: Called when a key is pressed.<br />
-- * `code`: The key code.
-- * `shift`: The Shift key is held down.
--- * `ctrl`: The Control key is held down.
--- * `alt`: The Alt/Apple key is held down.
--- * `option`: The Alt/Option key on Mac OSX is held down.
+-- * `ctrl`: The Control/Command key is held down.
+-- * `alt`: The Alt/option key is held down.
+-- * `meta`: The Control key on Mac OSX is held down.
-- * `MARGIN_CLICK`: Called when the mouse is clicked inside a margin.<br />
-- * `margin`: The margin number that was clicked.
-- * `position`: The position of the start of the line in the buffer that
diff --git a/core/keys.lua b/core/keys.lua
index 7b121e3a..1ce7be82 100644
--- a/core/keys.lua
+++ b/core/keys.lua
@@ -20,18 +20,18 @@ module('keys', package.seeall)
-- Language names are the names of the lexer files in `lexers/` such as `cpp`
-- and `lua`.
--
--- A key command string is built from a combination of the `CTRL`, `SHIFT`,
--- `ALT`, `OPTION`, and `ADD` constants as well as the pressed key itself. The
--- value of `ADD` is inserted between each of `CTRL`, `SHIFT`, `ALT`, `OPTION`,
+-- A key command string is built from a combination of the `CTRL`, `ALT`,
+-- `META`, `SHIFT`, and `ADD` constants as well as the pressed key itself. The
+-- value of `ADD` is inserted between each of `CTRL`, `ALT`, `META`, `SHIFT`,
-- and the key. For example:
--
-- -- keys.lua:
-- CTRL = 'Ctrl'
--- SHIFT = 'Shift'
-- ALT = 'Alt'
--- OPTION = 'Option'
+-- SHIFT = 'Shift'
+-- META = 'Meta'
-- ADD = '+'
--- -- pressing control, shift, alt and 'a' yields: 'Ctrl+Shift+Alt+A'
+-- -- pressing control, alt, shift, and 'a' yields: 'Ctrl+Alt+Shift+A'
--
-- For key values less than 255, Lua's [`string.char()`][string_char] is used to
-- determine the key's string representation. Otherwise, the
@@ -47,18 +47,25 @@ module('keys', package.seeall)
--
-- Key commands can be chained like in Emacs using keychain sequences. By
-- default, the `Esc` key (`Apple+Esc` on Mac OSX) cancels the current keychain,
--- but it can be redefined by setting the `keys.clear_sequence` field.
--- Naturally, the clear sequence cannot be chained.
+-- but it can be redefined by setting the `keys.CLEAR` field. Naturally, the
+-- clear sequence cannot be chained.
--
-- ## Settings
--
--- * `CTRL` [string]: The string representing the Control key.
--- * `SHIFT` [string]: The string representing the Shift key.
--- * `ALT` [string]: The string representing the Alt key (the Apple key on Mac
--- OSX).
--- * `OPTION` [string]: The string representing the Alt/Option key on Mac OSX.
+-- * `CTRL` [string]: The string representing the Control/Command key. The
+-- default is 'c'.
+-- * `ALT` [string]: The string representing the Alt/option key. The default is
+-- 'a'
+-- * `META` [string]: The string representing the Control key on Mac OSX. The
+-- default is 'm'.
+-- * `SHIFT` [string]: The string representing the Shift key. The default is
+-- 's'.
-- * `ADD` [string]: The string representing used to join together a sequence of
--- Control, Shift, or Alt modifier keys.
+-- Control, Alt, Meta, or Shift modifier keys. The default is ''.
+-- * `CLEAR` [string]: The string representing the key sequence that clears the
+-- current keychain. The default is 'esc' (Escape).
+-- * `LANGUAGE_MODULE_PREFIX` [string]: The starting key command of the keychain
+-- reserved for language-specific modules. Defaults to Ctrl/Cmd+L.
--
-- ## Key Command Precedence
--
@@ -68,10 +75,10 @@ module('keys', package.seeall)
-- ## Example
--
-- keys = {
--- ['ctrl+f'] = { 'char_right', 'buffer' },
--- ['ctrl+b'] = { 'char_left', 'buffer' },
+-- ['ctrl+f'] = buffer.char_right
+-- ['ctrl+b'] = buffer.char_left,
-- lua = {
--- ['ctrl+f'] = { 'add_text', 'buffer', 'function' },
+-- ['ctrl+f'] = { buffer.add_text, buffer, 'function' },
-- }
-- }
--
@@ -89,13 +96,16 @@ module('keys', package.seeall)
-- settings
local ADD = ''
local CTRL = 'c'..ADD
-local SHIFT = 's'..ADD
local ALT = 'a'..ADD
-local OPTION = 'o'..ADD
+local META = 'm'..ADD
+local SHIFT = 's'..ADD
+CLEAR = 'esc'
+LANGUAGE_MODULE_PREFIX = CTRL..'l'
-- end settings
-- Optimize for speed.
local string = string
+local string_byte = string.byte
local string_char = string.char
local xpcall = xpcall
local next = next
@@ -112,26 +122,50 @@ local error = function(e) events.emit(events.ERROR, e) end
-- @class table
-- @name KEYSYMS
KEYSYMS = { -- from <gdk/gdkkeysyms.h>
- [65056] = '\t', -- backtab; will be 'shift'ed
- [65288] = '\b',
- [65289] = '\t',
- [65293] = '\n',
- [65307] = 'esc',
- [65535] = 'del',
- [65360] = 'home',
- [65361] = 'left',
- [65362] = 'up',
- [65363] = 'right',
- [65364] = 'down',
- [65365] = 'pup',
- [65366] = 'pdown',
- [65367] = 'end',
- [65379] = 'ins',
- [65470] = 'f1', [65471] = 'f2', [65472] = 'f3', [65473] = 'f4',
- [65474] = 'f5', [65475] = 'f6', [65476] = 'f7', [65477] = 'f8',
- [65478] = 'f9', [65479] = 'f10', [65480] = 'f11', [65481] = 'f12',
+ [0xFE20] = '\t', -- backtab; will be 'shift'ed
+ [0xFF08] = '\b',
+ [0xFF09] = '\t',
+ [0xFF0D] = '\n',
+ [0xFF1B] = 'esc',
+ [0xFFFF] = 'del',
+ [0xFF50] = 'home',
+ [0xFF51] = 'left',
+ [0xFF52] = 'up',
+ [0xFF53] = 'right',
+ [0xFF54] = 'down',
+ [0xFF55] = 'pgup',
+ [0xFF56] = 'pgdn',
+ [0xFF57] = 'end',
+ [0xFF63] = 'ins',
+ [0xFFBE] = 'f1', [0xFFBF] = 'f2', [0xFFC0] = 'f3', [0xFFC1] = 'f4',
+ [0xFFC2] = 'f5', [0xFFC3] = 'f6', [0xFFC4] = 'f7', [0xFFC5] = 'f8',
+ [0xFFC6] = 'f9', [0xFFC7] = 'f10', [0xFFC8] = 'f11', [0xFFC9] = 'f12',
}
+---
+-- Returns the GDK integer keycode and modifier mask for a key sequence.
+-- This is used internally for creating menu accelerators.
+-- @param key_seq The string key sequence.
+-- @return keycode and modifier mask
+function get_gdk_key(key_seq)
+ if not key_seq then return nil end
+ local mods, key = key_seq:match('^([cams]*)(.+)$')
+ if not mods or not key then return nil end
+ local modifiers = ((mods:find('s') or key:lower() ~= key) and 1 or 0) +
+ (mods:find('c') and 4 or 0) + (mods:find('a') and 8 or 0) +
+ (mods:find('m') and 128 or 0)
+ local byte = string_byte(key)
+ if #key > 1 or byte < 32 then
+ for i, s in pairs(KEYSYMS) do
+ if s == key and i ~= 0xFE20 then
+ byte = i
+ break
+ end
+ end
+ end
+ return byte, modifiers
+end
+
-- The current key sequence.
local keychain = {}
@@ -189,18 +223,15 @@ end
-- It is called every time a key is pressed, and based on lexer, executes a
-- command. The command is looked up in the global 'keys' key command table.
-- @param code The keycode.
--- @param shift Flag indicating whether or not the shift modifier is pressed.
--- @param control Flag indicating whether or not the control modifier is
--- pressed.
--- @param alt Flag indicating whether or not the alt/apple modifier is pressed.
--- @param option Flag indicating whether the alt/option key is pressed. (Only
--- on Mac OSX.)
--- @return whatever the executed command returns, true by default. A true
--- return value will tell Textadept not to handle the key afterwords.
-local function keypress(code, shift, control, alt, option)
+-- @param shift Whether or not the Shift modifier is pressed.
+-- @param control Whether or not the Control/Command modifier is pressed.
+-- @param alt Whether or not the Alt/option modifier is pressed.
+-- @param meta Whether or not the Control modifier on Mac OSX is pressed.
+-- @return true to stop handling the key; nil otherwise.
+local function keypress(code, shift, control, alt, meta)
local buffer = buffer
local key
- --print(code, string.char(code))
+ --print(code, keys.KEYSYMS[ch], shift, control, alt, meta)
if code < 256 then
key = string_char(code)
shift = false -- for printable characters, key is upper case
@@ -209,12 +240,13 @@ local function keypress(code, shift, control, alt, option)
if not key then return end
end
control = control and CTRL or ''
- shift = shift and SHIFT or ''
alt = alt and ALT or ''
- option = option and OPTION or ''
- local key_seq = control..shift..alt..option..key
+ meta = meta and META or ''
+ shift = shift and SHIFT or ''
+ local key_seq = control..alt..meta..shift..key
+ --print(key_seq)
- if #keychain > 0 and key_seq == keys.clear_sequence then
+ if #keychain > 0 and key_seq == keys.CLEAR then
clear_key_sequence()
return true
end
diff --git a/core/locale.conf b/core/locale.conf
index 9cba204a..6b343f1c 100644
--- a/core/locale.conf
+++ b/core/locale.conf
@@ -117,7 +117,7 @@ Delete Word = De_lete Word
Highlight Word = _Highlight Word
Complete Symbol = Complete S_ymbol
Show Documentation = Show D_ocumentation
-Block (Un)comment = Bloc_k (Un)comment
+Toggle Block Comment = Toggle Bloc_k Comment
Transpose Characters = T_ranspose Characters
Join Lines = _Join Lines
Convert Indentation = Convert _Indentation
@@ -130,8 +130,10 @@ Single Quotes = _Single Quotes
Parentheses = _Parentheses
Brackets = _Brackets
Braces = B_races
-Grow = _Grow
+Grow Selection = _Grow Selection
+Shrink Selection = _Shrink Selection
Select in... = _Select in...
+Between Tags = Between _Tags
HTML Tag = _HTML Tag
Double Quote = _Double Quote
Single Quote = _Single Quote
@@ -174,13 +176,14 @@ Snapopen = Snap_open
User Home = _User Home
Textadept Home = _Textadept Home
Current Directory = _Current Directory
+Show Style = Show St_yle
Buffer = _Buffer
Next Buffer = _Next Buffer
Previous Buffer = _Previous Buffer
Switch Buffer = Switch _Buffer
Toggle View EOL = Toggle View _EOL
Toggle Wrap Mode = Toggle _Wrap Mode
-Toggle Show Indentation Guides = Toggle Show Indentation _Guides
+Toggle Show Indent Guides = Toggle Show Indent _Guides
Toggle Use Tabs = Toggle Use _Tabs
Toggle View Whitespace = Toggle View White_space
Toggle Virtual Space = Toggle _Virtual Space
@@ -196,6 +199,7 @@ ISO-8859-1 = ISO-8859-1
MacRoman = MacRoman
UTF-16 = UTF-16
Refresh Syntax Highlighting = _Refresh Syntax Highlighting
+Select Lexer... = Select _Lexer...
View = _View
Next View = _Next View
Previous View = _Previous View
@@ -203,8 +207,8 @@ Split Vertical = Split _Vertical
Split Horizontal = Split _Horizontal
Unsplit = _Unsplit
Unsplit All = Unsplit _All
-Grow = _Grow
-Shrink = _Shrink
+Grow View = _Grow View
+Shrink View = _Shrink View
Zoom In = Zoom _In
Zoom Out = Zoom _Out
Reset Zoom = _Reset Zoom
@@ -212,7 +216,7 @@ Help = _Help
Manual = _Manual
LuaDoc = _LuaDoc
gtk-about = gtk-about
-Lexers = Le_xers
+Lexers = _Lexers
Unknown command: = Unknown command:
% modules/textadept/mime_types.lua
diff --git a/doc/manual/10_Advanced.md b/doc/manual/10_Advanced.md
index a24c0bdf..274f6293 100644
--- a/doc/manual/10_Advanced.md
+++ b/doc/manual/10_Advanced.md
@@ -2,11 +2,11 @@
## Command Entry
-Access to the Lua state is available through the command entry. Press `F2` to
-access it. It is useful for debugging, inspecting, and entering buffer or view
-commands. If you try to cause instability in Textadept's Lua state, you might
-very well succeed so be careful. For more information, see the
-[scripting](11_Scripting.html) page.
+Access to the Lua state is available through the command entry. Press `Ctrl+E`
+(`⌘E` on Mac OSX) to access it. It is useful for debugging, inspecting, and
+entering buffer or view commands. If you try to cause instability in Textadept's
+Lua state, you might very well succeed so be careful. For more information, see
+the [scripting](11_Scripting.html) page.
Abbreviated commands for the `buffer`, `view` and `gui` are available. So
`buffer:append_text('foo')` can be shortened to `append_text('foo')`. `print()`
@@ -18,8 +18,8 @@ Lua's `print()`.
#### Tab Completion
Tab-completion for functions, variables, tables, etc. is available. Press the
-`Tab` key to display a list of available completions. Use the arrow keys to make
-a selection and press `Enter` to insert it.
+`Tab` (`⇥`) key to display a list of available completions. Use the arrow keys
+to make a selection and press `Enter` (`↩`) to insert it.
![Command Completion](images/commandentrycompletion.png)
@@ -39,8 +39,8 @@ buffer (or a selection). You could do the following from the command entry:
ls={}; for l in buffer:get_text():gmatch('[^\n]+') do ls[#ls+1]=l end;
table.sort(ls); buffer:set_text(table.concat(ls, '\n'))
-A simpler way would be to press `Alt+R` (`Ctrl+Apple+R` on Mac OSX), enter the
-shell command `sort`, and hit `Enter`.
+A simpler way would be to press `Ctrl+|` (`⌘|` on Mac OSX), enter the shell
+command `sort`, and hit `Enter` (`↩`).
The standard input (stdin) for shell commands is determined as follows:
diff --git a/doc/manual/14_Appendix.md b/doc/manual/14_Appendix.md
index 82ab7d69..83dab56c 100644
--- a/doc/manual/14_Appendix.md
+++ b/doc/manual/14_Appendix.md
@@ -2,146 +2,177 @@
## Key Bindings
-<table>
- <tr><th>Linux / Win32</th><th>Mac OSX</th><th>Command</th></tr>
- <tr><td colspan='3'><strong>File</strong></td></tr>
- <tr><td>Ctrl+N</td><td>Apple+N</td><td>New file</td></tr>
- <tr><td>Ctrl+O</td><td>Apple+O</td><td>Open file</td></tr>
- <tr><td>Alt+O</td><td>Ctrl+O</td><td>Open recent file</td></tr>
- <tr><td>None</td><td>None</td><td>Reload file</td></tr>
- <tr><td>Ctrl+S</td><td>Apple+S</td><td>Save file</td></tr>
- <tr><td>Ctrl+Shift+S</td><td>Apple+Shift+S</td><td>Save file as</td></tr>
- <tr><td>Ctrl+W</td><td>Apple+W</td><td>Close file</td></tr>
- <tr><td>Ctrl+Shift+W</td><td>Apple+Shift+W</td><td>Close all</td></tr>
- <tr><td>None</td><td>None</td><td>Load Session</td></tr>
- <tr><td>None</td><td>None</td><td>Save Session</td></tr>
- <tr><td>Alt+Q</td><td>Apple+Q</td><td>Quit textadept</td></tr>
- <tr><td colspan='3'><strong>Edit</strong></td></tr>
- <tr><td>Ctrl+Z</td><td>Apple+Z</td><td>Undo</td></tr>
- <tr><td>Ctrl+Y</td><td>Apple+Shift+Z</td><td>Redo</td></tr>
- <tr><td>Ctrl+X<br/>Shift+Del</td><td>Apple+X<br/>Shift+Del</td><td>Cut</td></tr>
- <tr><td>Ctrl+C<br/>Ctrl+Shift+Insert</td><td>Apple+C<br/>Ctrl+Shift+Insert</td><td>Copy</td></tr>
- <tr><td>Ctrl+V<br/>Shift+Insert</td><td>Apple+V<br/>Shift+Insert</td><td>Paste</td></tr>
- <tr><td>Ctrl+A</td><td>Apple+A</td><td>Select All</td></tr>
- <tr><td>Ctrl+E</td><td>Ctrl+M</td><td>Go to matching brace</td></tr>
- <tr><td>Ctrl+Shift+E</td><td>Apple+Shift+E</td><td>Select to matching brace</td></tr>
- <tr><td>Ctrl+Return</td><td>Escape</td><td>Autocomplete word in file</td></tr>
- <tr><td>Ctrl+I</td><td>Ctrl+Escape</td><td>Autocomplete symbol for supported languages</td></tr>
- <tr><td>Ctrl+H</td><td>Ctrl+H</td><td>Show symbol apidoc for supported languages</td></tr>
- <tr><td>Ctrl+Q</td><td>Ctrl+Q</td><td>Block comment/uncomment</td></tr>
- <tr><td>None</td><td>None</td><td>Delete word</td></tr>
- <tr><td>Ctrl+Shift+H</td><td>Ctrl+Apple+T</td><td>Highlight word occurances</td></tr>
- <tr><td>None</td><td>Ctrl+T</td><td>Transpose characters</td></tr>
- <tr><td>None</td><td>None</td><td>Convert indentation</td></tr>
- <tr><td>None</td><td>Ctrl+K</td><td>Cut to end of line</td></tr>
- <tr><td>None</td><td>Ctrl+Y</td><td>Paste text cut</td></tr>
- <tr><td>Alt+C, T</td><td>Ctrl+C, T</td><td>Enclose word or selection in XML tag</td></tr>
- <tr><td>Alt+C, Shift+T</td><td>Ctrl+C, Shift+T</td><td>Enclose word or selection in single XML tag</td></tr>
- <tr><td>Alt+C, "</td><td>Ctrl+C, "</td><td>Enclose word or selection in double quotes</td></tr>
- <tr><td>Alt+C, '</td><td>Ctrl+C, '</td><td>Enclose word or selection in single quotes</td></tr>
- <tr><td>Alt+C, (</td><td>Ctrl+C, (</td><td>Enclose word or selection in parenthesis</td></tr>
- <tr><td>Alt+C, [</td><td>Ctrl+C, [</td><td>Enclose word or selection in brackets</td></tr>
- <tr><td>Alt+C, {</td><td>Ctrl+C, {</td><td>Enclose word or selection in braces</td></tr>
- <tr><td>Alt+C, C, &lt;char&gt;</td><td>Ctrl+C, C, &lt;char&gt;</td><td>Enclose word or selection in character</td></tr>
- <tr><td>Alt+S, T</td><td>Ctrl+S, T</td><td>Select between XML tags</td></tr>
- <tr><td>Alt+S, "</td><td>Ctrl+S, "</td><td>Select between double quotes</td></tr>
- <tr><td>Alt+S, '</td><td>Ctrl+S, '</td><td>Select between single quotes</td></tr>
- <tr><td>Alt+S, (</td><td>Ctrl+S, (</td><td>Select between parenthesis</td></tr>
- <tr><td>Alt+S, [</td><td>Ctrl+S, [</td><td>Select between brackets</td></tr>
- <tr><td>Alt+S, {</td><td>Ctrl+S, {</td><td>Select between braces</td></tr>
- <tr><td>Alt+S, W</td><td>Ctrl+S, W</td><td>Select word</td></tr>
- <tr><td>Alt+S, L</td><td>Ctrl+S, L</td><td>Select line</td></tr>
- <tr><td>Alt+S, P</td><td>Ctrl+S, P</td><td>Select paragraph</td></tr>
- <tr><td>Alt+S, S</td><td>Ctrl+S, S</td><td>Select scope (style)</td></tr>
- <tr><td>Alt+S, G</td><td>Ctrl+S, G</td><td>Grow selection by a character on each end</td></tr>
- <tr><td>Alt+S, C, &lt;char&gt;</td><td>Ctrl+S, C, &lt;char&gt;</td><td>Select between characters</td></tr>
- <tr><td>Insert</td><td>Insert</td><td>Toggle overtype</td></tr>
- <tr><td>Ctrl+Alt+Shift+I</td><td>Ctrl+Apple+Shift+I</td><td>Show style</td></tr>
- <tr><td colspan='3'><strong>Search</strong></td></tr>
- <tr><td>Ctrl+F</td><td>Apple+F</td><td>Find</td></tr>
- <tr><td>F3</td><td>Apple+G</td><td>Find next</td></tr>
- <tr><td>None</td><td>Apple+Shift+G</td><td>Find prev</td></tr>
- <tr><td>None</td><td>Apple+R</td><td>Replace</td></tr>
- <tr><td>Ctrl+Shift+F</td><td>Apple+I</td><td>Find incremental</td></tr>
- <tr><td>None</td><td>Apple+Shift+F</td><td>Find in files</td></tr>
- <tr><td>None</td><td>Ctrl+Apple+G</td><td>Goto next file in list</td></tr>
- <tr><td>None</td><td>Ctrl+Apple+Shift+G</td><td>Goto prev file in list</td></tr>
- <tr><td>Ctrl+G</td><td>Ctrl+G</td><td>Goto line</td></tr>
- <tr><td colspan='3'><strong>Tools</strong></td></tr>
- <tr><td>F2</td><td>F2</td><td>Focus Lua command entry</td></tr>
- <tr><td>Ctrl+R</td><td>Ctrl+R</td><td>Run file</td></tr>
- <tr><td>Ctrl+Shift+R</td><td>Ctrl+Shift+R</td><td>Compile file</td></tr>
- <tr><td>Alt+R</td><td>Ctrl+Apple+R</td><td>Filter through shell command</td></tr>
- <tr><td>Tab</td><td>Tab</td><td>Expand snippet or next placeholder or indent text</td></tr>
- <tr><td>Alt+I</td><td>Ctrl+I</td><td>Select snippet to insert</td></tr>
- <tr><td>Shift+Tab</td><td>Shift+Tab</td><td>Previous snippet placeholder or dedent text</td></tr>
- <tr><td>Ctrl+Alt+I</td><td>Ctrl+Apple+I</td><td>Cancel current snippet</td></tr>
- <tr><td colspan='3'><strong>Buffers</strong></td></tr>
- <tr><td>Ctrl+B</td><td>Apple+B</td><td>Switch buffers</td></tr>
- <tr><td>Ctrl+Tab</td><td>Ctrl+Tab</td><td>Next buffer</td></tr>
- <tr><td>Ctrl+Shift+Tab</td><td>Ctrl+Shift+Tab</td><td>Prev buffer</td></tr>
- <tr><td>Ctrl+Shift+B, E</td><td>Apple+Shift+B, E</td><td>Toggle show end of line</td></tr>
- <tr><td>Ctrl+Shift+B, W</td><td>Apple+Shift+B, W</td><td>Toggle show whitespace</td></tr>
- <tr><td>Ctrl+Shift+B, I</td><td>Apple+Shift+B, I</td><td>Toggle show indentation guides</td></tr>
- <tr><td>Ctrl+Shift+B, Tab</td><td>Apple+Shift+B, Tab</td><td>Toggle use tabs or spaces</td></tr>
- <tr><td>Ctrl+Shift+B, Space</td><td>Apple+Shift+B, Space</td><td>Toggle show whitespace</td></tr>
- <tr><td>Ctrl+Shift+B, V</td><td>Apple+Shift+B, V</td><td>Toggle use virtual space</td></tr>
- <tr><td>Ctrl+L</td><td>Ctrl+L</td><td>Select lexer</td></tr>
- <tr><td>F5</td><td>F5</td><td>Refresh syntax highlighting</td></tr>
- <tr><td colspan='3'><strong>Split Views</strong></td></tr>
- <tr><td>Ctrl+Alt+V, N</td><td>Ctrl+V, N</td><td>Next view</td></tr>
- <tr><td>Ctrl+Alt+V, P</td><td>Ctrl+V, P</td><td>Prev view</td></tr>
- <tr><td>Ctrl+Alt+V, S</td><td>Ctrl+V, S</td><td>Split view horizontal</td></tr>
- <tr><td>Ctrl+Alt+V, Shift+S</td><td>Ctrl+V, Shift+S</td><td>Split view vertica</td></tr>
- <tr><td>Ctrl+Alt+V, W</td><td>Ctrl+V, W</td><td>Unsplit view</td></tr>
- <tr><td>Ctrl+Alt+V, Shift+W</td><td>Ctrl+V, Shift+W</td><td>Unsplit all views</td></tr>
- <tr><td>None</td><td>None</td><td>Grow split view</td></tr>
- <tr><td>None</td><td>None</td><td>Shrink split view</td></tr>
- <tr><td>Ctrl+Plus</td><td>Ctrl+Plus</td><td>Zoom in</td></tr>
- <tr><td>Ctrl+Minus</td><td>Ctrl+Minus</td><td>Zoom out</td></tr>
- <tr><td>Ctrl+0</td><td>Ctrl+0</td><td>Zoom normal</td></tr>
- <tr><td colspan='3'><strong>Movement</strong></td></tr>
- <tr><td>Right</td><td>Right<br/>Ctrl+F</td><td>Next character</td></tr>
- <tr><td>Shift+Right</td><td>Shift+Right<br/>Ctrl+Shift+F</td><td>Select next character</td></tr>
- <tr><td>Ctrl+Right</td><td>Ctrl+Right<br/>Ctrl+Apple+F</td><td>Next word</td></tr>
- <tr><td>Ctrl+Shift+Right</td><td>Ctrl+Shift+Right<br/>Ctrl+Apple+Shift+F</td><td>Select next word</td></tr>
- <tr><td>Alt+Shift+Right</td><td>Apple+Shift+Right</td><td>Rectangular select next character</td></tr>
- <tr><td>Left</td><td>Left<br/>Ctrl+B</td><td>Prev character</td></tr>
- <tr><td>Shift+Left</td><td>Shift+Left<br/>Ctrl+Shift+B</td><td>Select prev character</td></tr>
- <tr><td>Ctrl+Left</td><td>Ctrl+Left<br/>Ctrl+Apple+B</td><td>Prev word</td></tr>
- <tr><td>Ctrl+Shift+Left</td><td>Ctrl+Shift+Left<br/>Ctrl+Apple+Shift+B</td><td>Select prev word</td></tr>
- <tr><td>Alt+Shift+Left</td><td>Apple+Shift+Left</td><td>Rectangular select prev character</td></tr>
- <tr><td>Down</td><td>Down<br/>Ctrl+N</td><td>Next line</td></tr>
- <tr><td>Shift+Down</td><td>Shift+Down<br/>Ctrl+Shift+N</td><td>Select next line</td></tr>
- <tr><td>Ctrl+Down</td><td>Ctrl+Down</td><td>Scroll line down</td></tr>
- <tr><td>Ctrl+Shift+Down</td><td>Ctrl+Shift+Down</td><td>Rectangular select next line</td></tr>
- <tr><td>Up</td><td>Up<br/>Ctrl+P</td><td>Next character</td></tr>
- <tr><td>Shift+Up</td><td>Shift+Up<br/>Ctrl+Shift+P</td><td>Select prev line</td></tr>
- <tr><td>Ctrl+Up</td><td>Ctrl+Up</td><td>Scroll line up</td></tr>
- <tr><td>Ctrl+Shift+Up</td><td>Ctrl+Shift+Up</td><td>Rectangular select prev line</td></tr>
- <tr><td>Home</td><td>Home<br/>Ctrl+A</td><td>Goto beginning of line</td></tr>
- <tr><td>Shift+Home</td><td>Shift+Home<br/>Ctrl+Shift+A</td><td>Select to beginning of line</td></tr>
- <tr><td>Ctrl+Home</td><td>Ctrl+Home</td><td>Goto document start</td></tr>
- <tr><td>Ctrl+Shift+Home</td><td>Ctrl+Shift+Home</td><td>Select to file start</td></tr>
- <tr><td>Alt+Shift+Home</td><td>Apple+Shift+Home</td><td>Rectangular select to beginning of line</td></tr>
- <tr><td>End</td><td>End<br/>Ctrl+E</td><td>Goto end of line</td></tr>
- <tr><td>Shift+End</td><td>Shift+End<br/>Ctrl+Shift+E</td><td>Select to end of line</td></tr>
- <tr><td>Ctrl+End</td><td>Ctrl+End</td><td>Goto file end</td></tr>
- <tr><td>Ctrl+Shift+End</td><td>Ctrl+Shift+End</td><td>Select to file end</td></tr>
- <tr><td>Alt+Shift+End</td><td>Apple+Shift+End</td><td>Rectangular select to end of line</td></tr>
- <tr><td>Backspace<br/>Shift+Backspace</td><td>Backspace<br/>Shift+Backspace<br/>Ctrl+H</td><td>Delete previous character</td></tr>
- <tr><td>Ctrl+Backspace</td><td>Ctrl+Backspace<br/>Ctrl+Apple+H</td><td>Delete previous word</td></tr>
- <tr><td>Ctrl+Shift+Backspace</td><td>Ctrl+Shift+Backspace</td><td>Delete to beginning of line</td></tr>
- <tr><td>Del</td><td>Del<br/>Ctrl+D</td><td>Delete next character</td></tr>
- <tr><td>Ctrl+Del</td><td>Ctrl+Del<br/>Ctrl+Apple+D</td><td>Delete next word</td></tr>
- <tr><td>Ctrl+Shift+Del</td><td>Ctrl+Shift+Del</td><td>Delete to end of line</td></tr>
- <tr><td>Page Up</td><td>Page Up</td><td>Page up</td></tr>
- <tr><td>Shift+Page Up</td><td>Shift+Page Up</td><td>Select page up</td></tr>
- <tr><td>Alt+Shift+Page Up</td><td>Apple+Shift+Page Up</td><td>Rectangular select page up</td></tr>
- <tr><td>Page Down</td><td>Page Down</td><td>Page down</td></tr>
- <tr><td>Shift+Page Down</td><td>Shift+Page Down</td><td>Select page down</td></tr>
- <tr><td>Alt+Shift+Page Down</td><td>Apple+Shift+Page Down</td><td>Rectangular select page down</td></tr>
-</table>
+Linux / Win32 | Mac OSX | Command |
+--------------|---------|---------|
+**File** |||
+Ctrl+N |⌘N |New file
+Ctrl+O |⌘O |Open file
+Ctrl+Alt+O |⌘⌥O |Open recent file...
+Ctrl+Shift+O|⌘⇧O |Reload file
+Ctrl+S |⌘S |Save file
+Ctrl+Shift+S|⌘⇧S |Save file as..
+Ctrl+W |⌘W |Close file
+Ctrl+Shift+W|⌘⇧W |Close all files
+None |None|Load session...
+None |None|Load session...
+Alt+Q |⌘Q |Quit
+
+**Edit** |||
+Ctrl+Z<br/>Alt+Backspace|⌘Z |Undo
+Ctrl+Y<br/>Ctrl+Shift+Z |⌘⇧Z |Redo
+Ctrl+X<br/>Shift+Del |⌘X<br/>⇧⌦|Cut
+Ctrl+C<br/>Ctrl+Ins |⌘C |Copy
+Ctrl+V<br/>Shift+Ins |⌘V |Paste
+Ctrl+D |⌘D |Duplicate line
+Del |⌦<br/>^D |Delete
+Ctrl+A |⌘A |Select all
+Ctrl+M |^M |Match brace
+Ctrl+Shift+M |^⇧M |Select to brace
+Ctrl+Enter |^⎋ |Complete word
+None |None |Delete word
+Ctrl+Shift+H |⌘⇧H |Highlight word
+Ctrl+Space |⌥⎋ |Complete symbol
+Ctrl+H |^H |Show documentation
+Ctrl+/ |^/ |Toggle block comment
+Ctrl+T |^T |Transpose characters
+Ctrl+Shift+J |^J |Join lines
+None |None |Convert indentation
+Alt+< |^< |Enclose in XML tags
+Alt+> |^> |Enclose in single XML tag
+Alt+" |^" |Enclose in double quotes
+Alt+' |^' |Enclose in single quotes
+Alt+( |^( |Enclose in parentheses
+Alt+[ |^[ |Enclose in brackets
+Alt+{ |^{ |Enclose in braces
+Ctrl++ |⌘+ |Grow selection by 1 on either side
+Ctrl+\_ |⌘\_ |Shrink selection by 1 on either side
+Ctrl+< |⌘< |Select between XML tags
+Ctrl+> |⌘> |Select in XML tag
+Ctrl+" |⌘" |Select in double quotes
+Ctrl+' |⌘' |Select in single quotes
+Ctrl+( |⌘( |Select in parentheses
+Ctrl+[ |⌘[ |Select in brackets
+Ctrl+{ |⌘{ |Select in braces
+None |None |Select word
+Ctrl+Shift+L |⌘⇧L |Select line
+Ctrl+Shift+P |⌘⇧P |Select paragraph
+Ctrl+Shift+I |⌘⇧I |Select indented block
+None |None |Select style
+
+**Search** |||
+Ctrl+F |⌘F |Find
+Ctrl+G<br/>F3 |⌘G |Find next
+Ctrl+Shift+G<br/>Shift+F3|⌘⇧G |Find previous
+Ctrl+R |⌘R |Replace
+Ctrl+Shift+R |⌘⇧R |Replace all
+Ctrl+Alt+F |⌘⌥F |Find incremental
+Ctrl+Shift+F |⌘⇧F |Find in files
+Ctrl+Alt+G |⌘⌥G |Goto next file found
+Ctrl+Alt+Shift+G |⌘⌥⇧G|Goto previous file found
+Ctrl+J |⌘J |Jump to line
+
+**Tools** |||
+Ctrl+E |⌘E |Command entry
+Ctrl+Alt+R |^R |Run
+Ctrl+Alt+Shift+R|^⇧R |Compile
+Ctrl+&#124; |⌘&#124;|Filter text through
+Tab |⇥ |Expand snippet or next placeholder
+Ctrl+K |⌥⇥ |Insert snippet...
+Shift+Tab |⇧⇥ |Previous snippet placeholder
+Ctrl+Shift+K |⌥⇧⇥ |Cancel snippet
+Ctrl+F2 |⌘F2 |Toggle bookmark
+Ctrl+Shift+F2 |⌘⇧F2 |Clear bookmarks
+F2 |F2 |Next bookark
+Shift+F2 |⇧F2 |Previous bookmark
+Alt+F2 |⌥F2 |Goto bookmark...
+Ctrl+U |⌘U |Snapopen `_USERHOME`
+Ctrl+Alt+U |⌘⌥U |Snapopen `_HOME`
+Ctrl+Alt+Shift+O|⌘⌥⇧O |Snapopen current directory
+Ctrl+I |⌘I |Show style
+
+**Buffer** |||
+Ctrl+Tab<br/>Ctrl+PageDown |^\` |Next buffer
+Ctrl+Shift+Tab<br/>Ctrl+PageUp|^~ |Previous buffer
+Ctrl+B |⌘B |Switch buffer
+Ctrl+Alt+Enter |^↩ |Toggle view EOL
+Ctrl+Alt+\\ |^\\ |Toggle wrap mode
+Ctrl+Alt+Shift+I |^⇧I |Toggle show indent guides
+Ctrl+Alt+Shift+T |^⇧T |Toggle use tabs
+Ctrl+Alt+Space |^Space|Toggle view whitespace
+Ctrl+Alt+Shift+V |^⇧V |Toggle virtual space
+None |None |`CRLF` EOL mode
+None |None |`CR` EOL mode
+None |None |`LF` EOL mode
+None |None |`UTF-8` encoding
+None |None |`ASCII` encoding
+None |None |`ISO-8859-1` encoding
+None |None |`UTF-16` encoding
+Ctrl+Alt+L |⌘⌥L |Select lexer...
+F5 |F5 |Refresh syntax highlighting
+
+**View** |||
+Ctrl+Alt+Tab |^⇥ |Next view
+Ctrl+Alt+Shift+Tab |^⇧⇥ |Previous view
+Ctrl+Alt+Shift+S |^⇧S |Split vertical
+Ctrl+Alt+S |^S |Split horizontal
+Ctrl+Alt+W |^W |Unsplit view
+Ctrl+Alt+Shift+W |^⇧W |Unsplit all views
+Ctrl+Alt++<br/>Ctrl+Alt+=|^+<br/>^=|Grow view
+Ctrl+Alt+- |^- |Shrink view
+Ctrl+= |⌘= |Zoom in
+Ctrl+- |⌘- |Zoom out
+Ctrl+0 |⌘0 |Reset zoom
+
+**Help** |||
+F1 |F1 |Open manual
+Shift+F1|⇧F1 |Open LuaDoc
+None |None|About
+
+**Movement** |||
+Down |⇣<br/>^N |Line down
+Shift+Down |⇧⇣<br/>^⇧N |Line down extend selection
+Ctrl+Down |⌘↘ |Scroll line down
+Alt+Shift+Down |⌥⇧⇣ |Line down extend rect. selection
+Up |⇡<br/>^P |Line up
+Shift+Up |⇧⇡<br/>^⇧P |Line up extend selection
+Ctrl+Up |⌘↖ |Scroll line up
+Alt+Shift+Up |⌥⇧⇡ |Line up extend rect. selection
+Left |⇠<br/>^B |Char left
+Shift+Left |⇧⇠<br/>^⇧B |Char left extend selection
+Ctrl+Left |^⇠<br/>^⌥B |Word left
+Ctrl+Shift+Left |^⇧⇠<br/>^⌥⇧B|Word left extend selection
+Alt+Shift+Left |⌥⇧⇠ |Char left extend rect. selection
+Right |⇢<br/>^F |Char right
+Shift+Right |⇧⇢<br/>^⇧F |Char right extend selection
+Ctrl+Right |^⇢<br/>^⌥F |Word right
+Ctrl+Shift+Right |^⇧⇢<br/>^⌥⇧F|Word right extend selection
+Alt+Shift+Right |⌥⇧⇢ |Char right extend rect. selection
+Home |⌘⇠<br/>^A |Line start
+Shift+Home |⌘⇧⇠<br/>^⇧A |Line start extend selection
+Ctrl+Home |⌘⇡<br/>↖ |Document start
+Ctrl+Shift+Home |⌘⇧⇡<br/>⇧↖ |Document start extend selection
+Alt+Shift+Home |⌥⇧↖ |Line start extend rect. selection
+End |⌘⇢<br/>^E |Line end
+Shift+End |⌘⇧⇢<br/>^⇧E |Line end extend selection
+Ctrl+End |⌘⇣<br/>↘ |Document end
+Ctrl+Shift+End |⌘⇧⇣<br/>⇧↘ |Document end extend selection
+Alt+Shift+End |⌥⇧↘ |Line end extend rect. selection
+PageUp |⇞ |Page up
+Shift+PageUp |⇧⇞ |Page up extend selection
+Alt+Shift+PageUp |⌥⇧⇞ |Page up extend rect. selection
+PageDown |⇟ |Page down
+Shift+PageDown |⇧⇟ |Page down extend selection
+Alt+Shift+PageDown |⌥⇧⇟ |Page down extend rect. selection
+Ctrl+Del |⌥⌦ |Delete word right
+Ctrl+Shift+Del |⌘⌦ |Delete line right
+Ins |Ins |Toggle overtype
+Backspace<br/>Shift+Backspace|⌫<br/>⇧⌫ |Delete back
+Ctrl+Backspace |⌥⌫ |Delete word left
+Ctrl+Shift+Backspace |⌘⌫ |Delete line left
+Tab |⇥ |Insert tab or indent
+Shift+Tab |⇧⇥ |Dedent
+None |^K |Cut to line end
+None |^L |Center line vertically
## Lua Patterns
diff --git a/doc/manual/1_Introduction.md b/doc/manual/1_Introduction.md
index 610a8e81..4e0b17dd 100644
--- a/doc/manual/1_Introduction.md
+++ b/doc/manual/1_Introduction.md
@@ -58,6 +58,11 @@ customization and extensibility from the start; the features come after that.
`Ctrl+N, N` vs. `Ctrl+N, Shift+N`. In the first key chain, `Control` and `N`
are pressed followed by `N` with no modifiers. The second has `Control` and
`N` pressed followed by `Shift` and `N`.
+* When mentioning key commands, the Mac OSX equivalent will often be shown in
+ parenthesis. It may be tempting to assume that some Windows/Linux keys map to
+ Mac OSX's (e.g `Ctrl` to `⌘`), but this is not always the case. Please do not
+ view the key equivalents as translations of one another, but rather as
+ separate entities. This will minimize confusion.
## Features at a Glance
diff --git a/doc/manual/3_UserInterface.md b/doc/manual/3_UserInterface.md
index 14a6169b..e71eecce 100644
--- a/doc/manual/3_UserInterface.md
+++ b/doc/manual/3_UserInterface.md
@@ -11,8 +11,8 @@ More in-depth discussion about some of them is provided later in the manual.
## Menubar
-The completely customizable (and optional!) menubar typically provides access to
-all of Textadept's features.
+The completely customizable (and optional!) menubar provides access to all of
+Textadept's features.
## Editor View
diff --git a/doc/manual/4_WorkingWithFiles.md b/doc/manual/4_WorkingWithFiles.md
index a8afd25b..095dba55 100644
--- a/doc/manual/4_WorkingWithFiles.md
+++ b/doc/manual/4_WorkingWithFiles.md
@@ -10,13 +10,13 @@ question of where to place the bar (above, below, or to one side) and how many
to have (one for each split view or a single one under the menubar).
You can see which buffer is active by looking at Textadept's titlebar. Pressing
-`Ctrl+Tab` cycles to the next buffer and `Ctrl+Shift+Tab` cycles to the previous
-one.
+`Ctrl+Tab` (``^` `` on Mac OSX) cycles to the next buffer and `Ctrl+Shift+Tab`
+(`^~`) cycles to the previous one.
## Buffer Browser
-To move quickly between buffers, press `Ctrl+B` (`Apple+B` on Mac OSX) to open
-the buffer browser.
+To move quickly between buffers, press `Ctrl+B` (`⌘B` on Mac OSX) to open the
+buffer browser.
![Buffer Browser](images/bufferbrowser.png)
@@ -30,17 +30,17 @@ wildcards. You can also just use the arrow keys. Pressing `Enter` or clicking
## Split Views
Textadept allows you to split the editor window as many times as you like either
-horizontally or vertically. `Ctrl+Alt+V, Shift+S` splits vertically
-(side-by-side) and `Ctrl+Alt+V, S` splits horizontally (`Ctrl+V, Shift+S` and
-`Ctrl+V, S` respectively on Mac OSX). You can resize the splitter bar by
-clicking and dragging with the mouse. The same file can be worked with in
-multiple split views.
+horizontally or vertically. `Ctrl+Alt+Shift+S` splits vertically (side-by-side)
+and `Ctrl+Alt+S` splits horizontally (`^⇧S` and `^S` respectively on Mac OSX).
+You can resize the splitter bar by clicking and dragging with the mouse or
+using `Ctrl+Alt++` and `Ctrl+Alt+-` (`^+` and `^-`). The same file can be worked
+with in multiple split views.
-Pressing `Ctrl+Alt+V, N` (`Ctrl+V, N` on Mac OSX) goes to the next view and
-`Ctrl+Alt+V, P` goes to the previous one.
+Pressing `Ctrl+Alt+Tab` (`^⇥` on Mac OSX) goes to the next view and
+`Ctrl+Alt+Shift+Tab` (`^⇧⇥`) goes to the previous one.
-To unsplit a view, enter the view to keep open and press `Ctrl+Alt+V, W`
-(`Ctrl+V, W` on Mac OSX). To unsplit all views, use `Ctrl+Alt+V, Shift+W`.
+To unsplit a view, enter the view to keep open and press `Ctrl+Alt+W` (`^W` on
+Mac OSX). To unsplit all views, use `Ctrl+Alt+Shift+W` (`^⇧W`).
## Sessions
@@ -58,8 +58,10 @@ scroll positions in each buffer, and Textadept's window size.
A quicker, though slightly more limited alternative to the standard
`File -> Open` dialog is snapopen. It behaves like the buffer browser, but
displays a list of files to open, including files in subdirectories. You can
-snapopen the current file's directory from the `Tools -> Snapopen -> Current
-Directory` menu. Snapopen is pretty limited from the menu, but more versatile
-in scripts. See its [LuaDoc](../modules/_m.textadept.snapopen.html).
+snapopen the current file's directory with `Ctrl+Alt+Shift+O` (`⌘⌥⇧O` on Mac
+OSX) or from the `Tools -> Snapopen -> Current Directory` menu. Snapopen is
+pretty limited from the menu, but more versatile in scripts. See its
+[LuaDoc](../modules/_m.textadept.snapopen.html). `Ctrl+U` (`⌘U`) snaps open
+`~/.textadept/` and `Ctrl+Alt+U` (`⌘⌥U`) snaps open Textadept's home directory.
![Snapopen](images/snapopen.png)
diff --git a/doc/manual/5_FileNavigation.md b/doc/manual/5_FileNavigation.md
index 6b88af8d..ed0e5539 100644
--- a/doc/manual/5_FileNavigation.md
+++ b/doc/manual/5_FileNavigation.md
@@ -3,18 +3,19 @@
## Bookmarks
You can place bookmarks on lines in buffers to jump back to them later. Use the
-`Tools -> Bookmark` menu options to do so.
+`Tools -> Bookmark` menu options or key commands to do so.
## Goto Line
-To jump to a specific line in a file, press `Ctrl+G` and specify the line number
-in the prompt and press `Enter` or click `OK`.
+To jump to a specific line in a file, press `Ctrl+J` (`⌘J` on Mac OSX) and
+specify the line number in the prompt and press `Enter` (`↩`) or click `OK`.
## Goto Matching Brace
By default, Textadept will highlight the matching brace characters under the
-caret : `(`, `)`, `[`, `]`, `{`, `}`, `<`, and `>`. Pressing `Ctrl+E` (`Ctrl+M`
-in Mac OSX) moves the caret to that matching brace.
+caret : `(`, `)`, `[`, `]`, `{`, `}`, `<`, and `>`. Pressing `Ctrl+M` (`^M` on
+Mac OSX) moves the caret to that matching brace and `Ctrl+Shift+M` (`^⇧M`)
+extends the selection.
![Matching Braces](images/matchingbrace.png)
diff --git a/doc/manual/6_AdeptEditing.md b/doc/manual/6_AdeptEditing.md
index 49f16e74..9b05ce28 100644
--- a/doc/manual/6_AdeptEditing.md
+++ b/doc/manual/6_AdeptEditing.md
@@ -11,16 +11,16 @@ modified in your [preferences](9_Preferences.html#key_commands).
Usually, quote (`'`, `"`) and brace (`(`, `[`, `{`) characters go together in
pairs. By default, Textadept automatically inserts the complement character when
the first is typed. Similarly, the complement is deleted when you press
-`Backspace` over the first. See the
+`Backspace` (`⌫`) over the first. See the
[preferences](9_Preferences.html#module_settings) page if you would like to
disable this.
## Word Completion
Textadept provides buffer-based word completion. Start typing a word, press
-`Ctrl+Return` (`Esc` on Mac OSX), and a list of suggested completions based on
+`Ctrl+Return` (`^⎋` on Mac OSX), and a list of suggested completions based on
words in the current document is provided. Continuing to type changes the
-suggestion. Press `Return` to complete the selected word.
+suggestion. Press `Return` (`↩`) to complete the selected word.
![Word Completion](images/wordcompletion.png)
@@ -30,8 +30,8 @@ Textadept has the capability to autocomplete symbols for programming languages
and display API documentation. Lua is of course supported extremely well and
other languages have basic support with the help of
[ctags](http://ctags.sf.net). Symbol completion is available by pressing
-`Ctrl+I` (`Ctrl+Esc` on Mac OSX). Documentation for symbols is available with
-`Ctrl+H`.
+`Ctrl+Space` (`⌥⎋` on Mac OSX). Documentation for symbols is available with
+`Ctrl+H` (`^H`).
![Adeptsense Lua](images/adeptsense_lua.png)
&nbsp;&nbsp;&nbsp;&nbsp;
@@ -44,28 +44,36 @@ the [LuaDoc](../modules/_m.textadept.adeptsense.html).
## Find and Replace
-`Ctrl+F` (`Apple+F` on Mac OSX) brings up the Find/Replace dialog. In addition
-to offering the usual find and replace, Textadept allows you to find with [Lua
+`Ctrl+F` (`⌘F` on Mac OSX) brings up the Find/Replace dialog. In addition to
+offering the usual find and replace, Textadept allows you to find with [Lua
patterns](14_Appendix.html#lua_patterns) and replace with Lua captures and even
Lua code! For example: replacing all `(%w+)` with `%(string.upper('%1'))`
capitalizes all words in the buffer. Lua captures (`%n`) are only available from
a Lua pattern search, but embedded Lua code enclosed in `%()` is always allowed.
+Note the `Ctrl+G`, `Ctrl+Shift+G`, `Ctrl+R`, `Ctrl+Shift+R` key commands for
+find next, find previous, replace, and replace all (`⌘G`, `⌘⇧G`, `⌘R`, `⌘⇧R`
+respectively on Mac OSX) only work when the Find/Replace dialog is hidden. When
+it is visible, use the button mnemonics: `Alt+N`, `Alt+P`, `Alt+R`, and `Alt+A`
+(`⌘N`, `⌘P`, `⌘R`, `⌘A`) for English locale.
+
#### Find in Files
-Find in Files (`Apple+Shift+F` on Mac OSX) will prompt for a directory to
-search. The results are displayed in a new buffer. Double-clicking a search
-result jumps to it in the file. Replace in Files is not supported. You will have
-to `Find in Files` first, and then `Replace All` for each file a result is found
-in. The `Match Case`, `Whole Word`, and `Lua pattern` flags still apply.
+`Ctrl+Shift+F` brings up Find in Files (`⌘⇧F` on Mac OSX) and will prompt for a
+directory to search. The results are displayed in a new buffer. Double-clicking
+a search result jumps to it in the file. You can also use the `Ctrl+Alt+G` and
+`Ctrl+Alt+Shift+G` (`⌘⌥G` and `⌘⌥⇧G` on Mac OSX) key commands. Replace in Files
+is not supported. You will have to `Find in Files` first, and then `Replace All`
+for each file a result is found in. The `Match Case`, `Whole Word`, and
+`Lua pattern` flags still apply.
![Find in Files](images/findinfiles.png)
#### Find Incremental
-You can start an incremental search by pressing `Ctrl+Shift+F` (`Apple+I` on Mac
-OSX). Incremental search searches the buffer as you type. Only the `Match Case`
-option is recognized.
+You can start an incremental search by pressing `Ctrl+Alt+F` (`⌘⌥F` on Mac OSX).
+Incremental search searches the buffer as you type. Only the `Match Case` option
+is recognized.
#### Replace in Selection
@@ -78,8 +86,8 @@ then `Replace All`.
#### Increase or Decrease Indent Level
The amount of indentation for a selected set of lines is increased by pressing
-`Tab` and decreased by pressing `Shift+Tab`. Using these key sequences when no
-selection is present does not have the same effect.
+`Tab` (`⇥`) and decreased by pressing `Shift+Tab` (`⇧⇥`). Using these key
+sequences when no selection is present does not have the same effect.
#### Change Indent Size
@@ -91,9 +99,9 @@ Textadept shows what it is using for indentation in the document statusbar.
#### Using Tabs Instead of Spaces
-You can use tabs instead of the default spaces by pressing `Ctrl+T, V, Tab`
-(Apple+T, V, Tab on Mac OSX) or using the `Buffer -> Toggle Use Tabs` menu.
-Textadept shows what it is using for indentation in the document statusbar.
+You can use tabs instead of the default spaces by pressing `Ctrl+Alt+Shift+T`
+(`^⇧T` on Mac OSX) or using the `Buffer -> Toggle Use Tabs` menu. Textadept
+shows what it is using for indentation in the document statusbar.
The default option is usually set by a [language-specific
module](7_Modules.html#buffer_properties) or the [theme](8_Themes.html#buffer).
@@ -108,8 +116,8 @@ all tabs are converted to spaces.
#### Rectangular Selection
-Holding `Alt+Shift` (`Apple+Shift` on Mac OSX) and pressing the arrow keys
-enables rectangular selections to be made. Start typing to type on each line.
+Holding `Alt+Shift` (`⌥⇧` on Mac OSX) and pressing the arrow keys enables
+rectangular selections to be made. Start typing to type on each line.
![Rectangular Selection](images/rectangularselection.png)
&nbsp;&nbsp;&nbsp;&nbsp;
@@ -121,36 +129,28 @@ Clicking the mouse at a point in the buffer while holding `Control` places an
additional caret at that point. Clicking and dragging while holding `Control`
creates multiple selections. Start typing to enter text at each selection.
+This is currently unavailable on Mac OSX.
+
#### Selecting Entities
-Textadept allows you to select many different entities from the caret. `Alt+S`
-(`Ctrl+S` on Mac OSX) is the key prefix to entity selection. Typing `'`, `"`,
-`(`, `[`, or `{` selects all text between the matching delimiters. Typing `W`,
-`L`, `P`, `B`, or `S` (without holding `Shift`) selects the current word, line,
-paragraph, indented block, or style respectively. Typing `T` selects the text
-between `>` and `<`, useful for selecting within HTML tags. Typing `G` grows the
-current selection by one character to each side, so `Alt+S, "` followed by
-`Alt+S, G` selects an entire `""` sequence instead of just the text in-between
-quotes. Finally, typing `C` followed by any other character selects all text
-between a pair of those characters. `Alt+S, C, "` is identical to `Alt+S, "`.
+Textadept allows you to select many different entities from the caret. For
+example, `Ctrl+"` (`^"` on Mac OSX) selects all characters in a `""` sequence.
+Typing `Ctrl++` (`^+`) as a follow-up selects the double-quotes too. See the
+`Edit -> Select In...` menu for available entities and their key commands.
## Enclosing Text
As a complement to selecting entities, you can enclose text as entities. The
-key prefix is `Alt+C` (`Ctrl+C` on Mac OSX). Typing `'`, `"`, `(`, `[`, or `{`
-encloses the text in the appropriate character pair. Typing `T` (without holding
-`Shift`) creates an opening and closing HTML tag while `Shift+T` creates a
-single HTML tag. Finally, typing `C` followed by any other character encloses
-the text between a pair of those characters. `Alt+C, C, "` is identical to
-`Alt+C, "`.
+`Edit -> Selection -> Enclose In...` menu contains all available entities and
+their key commands.
If no text is selected, the word to the left of the caret is enclosed.
## Word Highlight
All occurrences of a given word are highlighted by putting the caret over the
-word and pressing `Ctrl+Shift+H` (`Ctrl+Apple+T` on Mac OSX). This is useful to
-show occurrences of a variable name in source code.
+word and pressing `Ctrl+Shift+H` (`⌘⇧H` on Mac OSX). This is useful to show
+occurrences of a variable name in source code.
![Word Highlight](images/wordhighlight.png)
@@ -158,9 +158,9 @@ show occurrences of a variable name in source code.
#### Virtual Space
-Virtual space (freehand) mode is enabled and disabled with `Ctrl+T, V, V`
-(`Apple+T, V, V` in Mac OSX). When enabled, caret movement is not restricted by
-line endings.
+Virtual space (freehand) mode is enabled and disabled with `Ctrl+Alt+Shift+V`
+(`^⇧V` in Mac OSX). When enabled, caret movement is not restricted by line
+endings.
#### Overwrite
diff --git a/doc/manual/7_Modules.md b/doc/manual/7_Modules.md
index 72880974..917a0b33 100644
--- a/doc/manual/7_Modules.md
+++ b/doc/manual/7_Modules.md
@@ -37,13 +37,13 @@ is loaded or a buffer's lexer is set to that language.
#### Snippets
Most language-specific modules have a set of
-[snippets](../modules/_m.textadept.snippets.html). Press `Ctrl+Alt+Shift+I`
-(`Ctrl+Apple+Shift+I` on Mac OSX) for a list of available snippets or see the
-module's Lua code. To insert a snippet, type its trigger followed by the `Tab`
-key. Subsequent presses of `Tab` causes the caret to enter tab stops in
-sequential order, `Shift+Tab` goes back to the previous tab stop, and
-`Ctrl+Alt+I` (`Ctrl+Apple+I` on Mac OSX) cancels the current snippet. Snippets
-can be nested (inserted from within another snippet).
+[snippets](../modules/_m.textadept.snippets.html). Press `Ctrl+K` (`⌥⇥` on Mac
+OSX) for a list of available snippets or see the module's Lua code. To insert a
+snippet, type its trigger followed by the `Tab` (`⇥`) key. Subsequent presses of
+`Tab` (`⇥`) causes the caret to enter tab stops in sequential order, `Shift+Tab`
+(`⇧⇥`) goes back to the previous tab stop, and `Ctrl+Shift+K` (`⌥⇧⇥` on Mac OSX)
+cancels the current snippet. Snippets can be nested (inserted from within
+another snippet).
![Snippet](images/snippet.png)
&nbsp;&nbsp;&nbsp;&nbsp;
@@ -53,21 +53,23 @@ can be nested (inserted from within another snippet).
Most language-specific modules have a set of [key
commands](../modules/_m.textadept.keys.html). See the module's Lua code for
-which key commands are available.
+which key commands are available. They are typically stored in the `Ctrl+L`
+(`⌘L` on Mac OSX) key prefix.
##### Run
Most language-specific modules have a command that runs the code in the current
-file. Pressing `Ctrl+R` runs that command.
+file. Pressing `Ctrl+Alt+R` (`^R` on Mac OSX) runs that command.
##### Compile
Most language-specific modules have a command that compiles the code in the
-current file. Pressing `Ctrl+Shift+R` runs that command.
+current file. Pressing `Ctrl+Alt+Shift+R` (`^⇧R` on Mac OSX) runs that command.
##### Block Comments
-Pressing `Ctrl+Q` comments or uncomments the code on the selected lines.
+Pressing `Ctrl+/` (`⌘/` on Mac OSX) comments or uncomments the code on the
+selected lines.
#### Buffer Properties
diff --git a/doc/manual/9_Preferences.md b/doc/manual/9_Preferences.md
index 579874c6..e917a55c 100644
--- a/doc/manual/9_Preferences.md
+++ b/doc/manual/9_Preferences.md
@@ -70,19 +70,30 @@ You can add global snippets to `snippets` such as:
snippets['file'] = '%<buffer.filename>'
snippets['path'] = "%<(buffer.filename or ''):match('^.+[/\\]')>"
-So typing `file` or `path` and then pressing `Tab` will insert the snippet.
+So typing `file` or `path` and then pressing `Tab` (`⇥` on Mac OSX) will insert
+the snippet.
##### Key Commands
-It is not recommended to edit Textadept's `modules/textadept/keys.lua` for
-changing the key bindings since your changes could be overwritten when updating
-Textadept. Instead, modify `keys` from within your `~/.textadept/init.lua` or
-from a file loaded by `~/.textadept/init.lua`. For example maybe you want
+The default set of key commands is located in `modules/textadept/keys.conf`
+(`modules/textadept/keys.osx.conf` on Mac OSX) and is loaded by the
+`_m.textadept.menu` module. It is not recommended to edit Textadept's
+`keys.conf` or `keys.osx.conf` for changing the key bindings since your changes
+could be overwritten when updating Textadept. Instead, make a copy in your
+`~/.textadept/modules/textadept/` folder and modify that.
+
+You can also modify key commands from within your your `~/.textadept/init.lua`
+or from a file loaded by `~/.textadept/init.lua`. For example maybe you want
`Alt+N` to create a new buffer instead of `Ctrl+N`:
keys.an = new_buffer
keys.cn = nil
+If you choose to exclude loading the menu like in the example above, you will
+have to specify your own set of key commands! I happen to do this and keep a
+copy of `~/.textadept/modules/textadept/keys.lua` that is loaded by my
+`~/.textadept/init.lua`.
+
## Locale
Most messages displayed by Textadept are localized. `core/locale.conf` contains
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 = {}
diff --git a/scripts/update_doc b/scripts/update_doc
index ab8dbf67..18b472af 100755
--- a/scripts/update_doc
+++ b/scripts/update_doc
@@ -53,7 +53,7 @@ if luadoc then
f = io.open('tmp', 'w')
f:write(markdown)
f:close()
- f = io.popen('perl ../doc/Markdown.pl tmp')
+ f = io.popen('perl ../doc/MultiMarkdown.pl tmp')
markdown = f:read('*all')
f:close()
os.execute('rm tmp')
@@ -112,10 +112,10 @@ if manual then
</html>
]]
- local sidebar_md = io.popen('../doc/Markdown.pl ../doc/sidebar.md')
+ local sidebar_md = io.popen('../doc/MultiMarkdown.pl ../doc/sidebar.md')
html = html:gsub('%%sidebar%%', sidebar_md:read('*all'))
sidebar_md:close()
- local content_md = io.popen('../doc/Markdown.pl '..mdfile)
+ local content_md = io.popen('../doc/MultiMarkdown.pl '..mdfile)
local md = content_md:read('*all'):gsub('%%', '%%%%')
md = md:gsub('(<h%d>)([^<]+)(</h%d>)',
function(s, text, e)
diff --git a/src/textadept.c b/src/textadept.c
index 661b8ca6..057742a6 100644
--- a/src/textadept.c
+++ b/src/textadept.c
@@ -22,6 +22,9 @@
#elif __OSX__
#include <Carbon/Carbon.h>
#include "igemacintegration/ige-mac-menu.h"
+#define GDK_CONTROL_MASK 1 << 3 // Command key (GDK_MOD1_MASK)
+#define GDK_MOD1_MASK 1 << 7 // Alt/option key (GDK_MOD5_MASK)
+#define GDK_MOD5_MASK 1 << 2 // Control key (GDK_CONTROL_MASK)
#elif __BSD__
#include <sys/types.h>
#include <sys/sysctl.h>
@@ -77,6 +80,7 @@
// Window
GtkWidget *window, *focused_editor, *menubar, *statusbar[2];
+GtkAccelGroup *accel = 0;
char *textadept_home;
void create_ui();
@@ -242,6 +246,7 @@ void create_ui() {
signal(window, "delete-event", w_exit);
signal(window, "focus-in-event", w_focus);
signal(window, "key-press-event", w_keypress);
+ accel = gtk_accel_group_new();
#if __OSX__
AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
@@ -1369,12 +1374,16 @@ GtkWidget *l_create_gtkmenu(lua_State *lua, GCallback callback, int submenu) {
gtk_menu_shell_append(GTK_MENU_SHELL(menu),
l_create_gtkmenu(lua, callback, TRUE));
else
- if (lua_objlen(lua, -1) == 2) {
+ if (lua_objlen(lua, -1) == 2 || lua_objlen(lua, -1) == 4) {
lua_rawgeti(lua, -1, 1);
lua_rawgeti(lua, -2, 2);
label = lua_tostring(lua, -2);
int menu_id = lua_tointeger(lua, -1);
- lua_pop(lua, 2); // label and id
+ lua_rawgeti(lua, -3, 3);
+ lua_rawgeti(lua, -4, 4);
+ int key = !lua_isnil(lua, -2) ? lua_tointeger(lua, -2) : 0;
+ int modifiers = !lua_isnil(lua, -1) ? lua_tointeger(lua, -1) : 0;
+ lua_pop(lua, 4); // label, id, key, and modifiers
if (label) {
if (g_str_has_prefix(label, "gtk-"))
menu_item = gtk_image_menu_item_new_from_stock(label, NULL);
@@ -1382,11 +1391,14 @@ GtkWidget *l_create_gtkmenu(lua_State *lua, GCallback callback, int submenu) {
menu_item = gtk_separator_menu_item_new();
else
menu_item = gtk_menu_item_new_with_mnemonic(label);
+ if (key || modifiers)
+ gtk_widget_add_accelerator(menu_item, "activate", accel, key,
+ modifiers, GTK_ACCEL_VISIBLE);
g_signal_connect(menu_item, "activate", callback,
GINT_TO_POINTER(menu_id));
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
}
- } else warn("gtkmenu: { 'menu label', id_number } expected");
+ } else warn("gtkmenu: { 'label', id_num [, keycode, mods] } expected");
}
lua_pop(lua, 1); // value
}