Compare commits

...

191 Commits
0.35 ... 0.37

Author SHA1 Message Date
Paul Kulchenko
71b4f47159 Added support for absolute filenames in Markdown links. 2013-05-09 16:22:49 -07:00
Paul Kulchenko
347b53659c Updated CHANGELOG for 0.37. 2013-05-09 13:54:45 -07:00
Paul Kulchenko
16f32e0df5 Updated interpreters and tests after API changes. 2013-05-09 12:41:04 -07:00
Paul Kulchenko
171287fac6 Added Russian translation for Find/Replace dialog (ref #70). 2013-05-08 21:46:10 -07:00
Paul Kulchenko
9d05cd6931 Added Russian translation for the Preferences menu (ref #70). 2013-05-07 21:57:48 -07:00
Paul Kulchenko
a9e847372a Added Preferences menu to simplify access to system/user settings. 2013-05-06 10:05:13 -07:00
Paul Kulchenko
1eba53cc0e Fixed loading a non-existing file. 2013-05-05 22:02:07 -07:00
Paul Kulchenko
c5a0077a01 Fixed filtering out directories when spec is specified. 2013-05-05 22:01:04 -07:00
Paul Kulchenko
2b07dd1db4 Separated settings for function dropdown and project tree fonts (fixes #148). 2013-05-04 16:03:18 -07:00
Paul Kulchenko
28b3380a45 Fixed hiding all panels when switching to Full Screen mode. 2013-05-04 10:40:39 -07:00
Paul Kulchenko
564338656d Updated CHANGELOG with recent changes. 2013-05-04 10:39:57 -07:00
Paul Kulchenko
29b2e4f5ec Fixed activation of non-existing files/folders in the Project tree. 2013-05-04 10:06:35 -07:00
Paul Kulchenko
c7ab3aeb32 Refactored and optimized directory scanning when loading IDE files. 2013-05-02 16:24:25 -07:00
Paul Kulchenko
4b771dafe4 Added 'wlua' to the list of recognized Lua extensions. 2013-05-02 13:13:27 -07:00
Paul Kulchenko
71393bd35a Fixed search results for lines without newline. 2013-05-01 15:10:17 -07:00
Paul Kulchenko
f7e2697e56 Fixed Find/Replace in folders with Unicode names (fixes #147); improved performance. 2013-05-01 15:03:59 -07:00
Paul Kulchenko
608644bd83 Added 'shaking' Find/Replace window when text is not found (closes #146). 2013-05-01 11:20:49 -07:00
Paul Kulchenko
7563e52aba Fixed Un/Comment commands executed for empty lines. 2013-05-01 09:10:08 -07:00
Paul Kulchenko
039dde0ccb Fixed fold/unfold for files starting with block/comment. 2013-04-30 22:26:47 -07:00
Paul Kulchenko
abbde79ab0 Fixed history after activating non-existing file in Recent Files. 2013-04-30 18:09:09 -07:00
Paul Kulchenko
ead958e603 Added disabling Recent Files menu if the list is empty. 2013-04-29 22:00:33 -07:00
Paul Kulchenko
6b7f310cd7 Added TomorrowContrast color scheme (thanks to Sergey Lerg). 2013-04-28 17:49:41 -07:00
Paul Kulchenko
451186ac4e Fixed scrolling to restored cursor position on OSX (when usewrap = false). 2013-04-27 14:58:42 -07:00
Paul Kulchenko
b8b3b7f0af Fixed Find/Replace dialog to take Enter on OSX (fixes #140). 2013-04-26 11:01:45 -07:00
Paul Kulchenko
5ee71feac4 Updated CHANGELOG with recent changes. 2013-04-26 10:58:51 -07:00
Paul Kulchenko
a2e65e2bbd Updated Marmalade interpreter with Quick 1.1 path changes. 2013-04-26 10:48:35 -07:00
Paul Kulchenko
e8ad508021 Updated Watch/Stack panels min size to make them dockable with other panels. 2013-04-26 09:05:20 -07:00
Paul Kulchenko
aa2a4fac2b Added detaching a child process to avoid crash when exiting during debugging. 2013-04-24 22:53:56 -07:00
Paul Kulchenko
d5fda558c1 Fixed loading an empty recent file history. 2013-04-24 21:55:23 -07:00
Paul Kulchenko
171b98717a Fixed 'breaking' after executing OUT command that never reaches the target level. 2013-04-24 21:40:01 -07:00
Paul Kulchenko
da07ef0e2c Added a check to fix assertions in debug build. 2013-04-24 21:36:22 -07:00
Paul Kulchenko
6c9e226d67 Added Recent File history navigation (closes #66). 2013-04-24 14:02:17 -07:00
Paul Kulchenko
d3884358be Fixed stopping at a breakpoint at the initial line when startwith option is specified. 2013-04-24 12:30:58 -07:00
Paul Kulchenko
0ebeee3641 Fixed activation of a file loaded into active tab. 2013-04-23 19:58:10 -07:00
Paul Kulchenko
bd190d5a4e Added Marmalade auto-complete support and API documentation. 2013-04-23 15:49:19 -07:00
Paul Kulchenko
b1f09b9ef0 Fixed an occasional crash on OSX introduced by a duplicate line fix. 2013-04-23 10:34:52 -07:00
Paul Kulchenko
ac556aea34 Updated documentation about default EOL on OSX (ref #102). 2013-04-22 21:37:02 -07:00
Paul Kulchenko
87ab3702fe Fixed incorrect tab activation on OSX after using 'Open File'. 2013-04-22 18:24:08 -07:00
Paul Kulchenko
83556f9ab2 Improved file activation when debugging is started (closes #137). 2013-04-21 22:35:03 -07:00
Paul Kulchenko
43c18552c1 Added processing of runonstart when using remote debugging (closes #138). 2013-04-21 19:04:26 -07:00
Paul Kulchenko
dc54c76435 Updated highlighting in Watch windows to not use editor styles.
This is to avoid color conflicts with dark color schemes.
2013-04-21 18:47:14 -07:00
Paul Kulchenko
9a16cd026f Fixed editor activation when file is loaded into an existing tab. 2013-04-21 18:43:51 -07:00
Paul Kulchenko
e4710a16b0 Refactored Recent Files history to make it faster and simpler. 2013-04-21 17:33:47 -07:00
Paul Kulchenko
ae2e99f6d3 Fixed an error after opening non-existing file from 'Recent Files'. 2013-04-20 15:38:32 -07:00
Paul Kulchenko
c182a19fa5 Added suggesting proper extension after 'Save/Save As' based on current spec. 2013-04-19 15:09:22 -07:00
Paul Kulchenko
2ddeaf4eb8 Updated Russian 'watch' translation for consistency. 2013-04-19 09:24:59 -07:00
Paul Kulchenko
b4fd071efb Fixed blocking on reading app output without processing other events. 2013-04-18 17:24:30 -07:00
Paul Kulchenko
9344280d5b Fixed an issue with duplicate lines shown in the editor.
This can happen when the line is too long for one line and can wrap; if it
also includes hidden markup (Markdown in comments), this markup can change
the length of the line, but it's not adjusted by Scintilla after the
markup is applied. Force adjustment when this situation is detected.
2013-04-18 12:42:43 -07:00
Paul Kulchenko
ad037536cd Updated documentation for user settings (ref #113, #55). 2013-04-17 21:08:32 -07:00
Paul Kulchenko
d8e8af00b6 Added translation setup for Find/Replace dialog (closes #133). 2013-04-17 18:07:45 -07:00
Paul Kulchenko
1e651a97b7 Fixed 'Replace All' to take 'Wrap Around' into account (fixes #132). 2013-04-17 16:45:19 -07:00
Paul Kulchenko
c2e49e169f Added tests. 2013-04-17 12:26:47 -07:00
Paul Kulchenko
6662cb0f5e Fixed off-by-one error in searching consecutive matches. 2013-04-17 12:18:19 -07:00
Paul Kulchenko
c00d85890a Fixed 'Quick Find' not working without current selection (fixes #131). 2013-04-17 12:01:51 -07:00
Paul Kulchenko
c42c9ffb3d Reduced the minimum size of the Output/Console panel. 2013-04-16 17:31:16 -07:00
Paul Kulchenko
b5661976eb Fixed looping in auto-complete on mistyped class (fixes #130). 2013-04-16 10:22:02 -07:00
Paul Kulchenko
c1e66f8fc2 Fixed compatibility with wx2.8 (thanks to Samuel Dionne-Riel; closes #128). 2013-04-15 18:14:12 -07:00
Paul Kulchenko
c2715040fe Added nomousezoom option to disable zoom with mouse wheel in the editor. 2013-04-15 18:12:15 -07:00
Paul Kulchenko
fc17dac2a5 Added selecting text and Cmd-F shortcut in Find dialog on OSX (ref #127). 2013-04-15 18:10:16 -07:00
Paul Kulchenko
0dfd8e3ba1 Fixed replacement logic in Find/Replace that could replace selected fragment (ref #127). 2013-04-15 18:06:59 -07:00
Paul Kulchenko
acbfd6d81d Fixed an error caused by allowing multiple Search/Replace windows (fixes #127). 2013-04-15 10:23:17 -07:00
Paul Kulchenko
0d268a01e1 Updated Monokai color scheme to fix current line color. 2013-04-13 09:46:08 -07:00
Paul Kulchenko
1e9cbb4633 Updated CHANGELOG with recent changes. 2013-04-12 12:25:34 -07:00
Paul Kulchenko
7d3683df98 Updated About screen to be more configurable and flexible. 2013-04-12 12:22:17 -07:00
Paul Kulchenko
3b10bbbcd2 Fixed launch command for Corona debugging on Windows. 2013-04-11 09:23:52 -07:00
Paul Kulchenko
3ea40683c9 Added handling of Ctrl-Home and Ctrl-End on OSX (ref #89). 2013-04-10 21:55:03 -07:00
Paul Kulchenko
e6b789131a Added line copy/cut for Ctrl-C/Ctrl-X with no selection. 2013-04-10 21:53:16 -07:00
Paul Kulchenko
613dec0571 Fixed 'control' check on OSX that changed with wx2.9.2+ (ref #89). 2013-04-10 18:23:10 -07:00
Paul Kulchenko
36b3692e9e Fixed wrong tab activated on OSX after using New file in some cases.
This is caused by two PAGE_CHANGED event for the notebook triggered
when the current tab is not the last one (in wx2.9.5+). This could lead to
a crash if the incorrect tab is closed (ref #89).
2013-04-10 18:18:35 -07:00
Paul Kulchenko
59cde2fc8c Fixed cursor not being visible in some cases after file is loaded (ref #116). 2013-04-10 15:32:31 -07:00
Paul Kulchenko
e8027b3b95 Updated Russian translation (thanks to toiffel). 2013-04-09 22:12:22 -07:00
Paul Kulchenko
579ab4c831 Updated CHANGELOG for 0.36. 2013-04-08 11:39:17 -07:00
Paul Kulchenko
f54322c1f7 Fixed the current editor not being fully activated when closing a tab. 2013-04-08 11:37:46 -07:00
Paul Kulchenko
a5b85c533a Fixed activating files in the project tree on a case insensitive system. 2013-04-08 09:33:16 -07:00
Paul Kulchenko
149340669a Fixed the Stack view being partially hidden when the root item is too wide (ref #110). 2013-04-08 09:16:11 -07:00
Paul Kulchenko
5165bf5b29 Fixed left side of the project panel being hidden when a file is activated (fixes #122). 2013-04-08 09:14:04 -07:00
Paul Kulchenko
fbc04ba199 Updated Linux launch script and MANIFEST. 2013-04-07 23:53:54 -07:00
Paul Kulchenko
e33f2d40dd Removed build files no longer needed. 2013-04-07 23:52:34 -07:00
Paul Kulchenko
bad62f0a16 Updated CHANGELOG with recent changes. 2013-04-06 21:30:20 -07:00
Paul Kulchenko
b393b58cc1 Fixed breakpoint not firing on the first executable line in debugging (helps #121). 2013-04-06 13:57:49 -07:00
Paul Kulchenko
4480825408 Fixed activating of the first line in the script during debugging. 2013-04-06 13:53:24 -07:00
Paul Kulchenko
10fb31f1e5 Disabled showing 'value' in auto-complete after 'a:' (helps #101). 2013-04-06 13:44:14 -07:00
Paul Kulchenko
789a2d8a88 Upgraded Mobdebug (v0.525) for performance improvements (also closes #121).
Other changes in the same version:
  Added handling of case-insensitive filenames on OSX.
  Improved debugging performance.
  Fixed terminating debugging of an empty script.
  Fixed resetting cached source as it may change when basedir changes.
  Replaced socket.select with non-blocking .receive as it is faster.
2013-04-05 08:46:41 -07:00
Paul Kulchenko
b9ebd44c30 Simplified lua interpreter launch/debug command. 2013-04-04 21:48:05 -07:00
Paul Kulchenko
a65edf8fd5 Fixed reporting of initial line during debugging. 2013-04-03 23:23:53 -07:00
crazybutcher
89f33160bc GLSL compilation checker frontend https://github.com/CrazyButcher/glslc 2013-04-03 16:09:20 +02:00
crazybutcher
e96a7657cd disable cpp preprocessor based "greying" out, due to lack of proper styles 2013-04-03 12:02:52 +02:00
Paul Kulchenko
492270a3bf Added universal binaries for luasocket on OSX (closes #120).
This allows debugging of 64bit applications (for example, LuaJIT) on OSX.
2013-04-02 22:29:54 -07:00
Paul Kulchenko
1cd34e3853 Fixed incorrect type guessing from assignments in auto-complete. 2013-04-02 18:31:40 -07:00
Paul Kulchenko
3ad7b389da Updated references to configuration files in documentation. 2013-04-02 10:17:24 -07:00
Leo Bartoloni
bc58913272 Update it.lua
Added new italian translations
2013-04-02 10:03:04 +03:00
Paul Kulchenko
415ba2bd17 Fixed editor tab activation after closing another tab on Linux (ref #89). 2013-04-01 20:15:10 -07:00
Paul Kulchenko
a338f4c436 Fixed 'Show tooltip' shortcut not working on Linux (fixes #118; ref #89). 2013-04-01 20:14:21 -07:00
Paul Kulchenko
24507e22bb Fixed cursor position being incorrectly restored (fixes #116; ref #89). 2013-04-01 16:07:34 -07:00
Paul Kulchenko
8e208b7dd3 Fixed lag on Windows when using brackets and backspace (fixes #117; ref #89). 2013-04-01 09:23:12 -07:00
Paul Kulchenko
d5c585b118 Updated 'method' type in auto-complete to only allow a:b syntax (closes #101). 2013-04-01 09:16:52 -07:00
Paul Kulchenko
56b63b3b4c Merge branch 'master' of git://estrelaeditor.git.sourceforge.net/gitroot/estrelaeditor/estrelaeditor into auto-complete 2013-03-31 19:20:33 -07:00
Paul Kulchenko
8c64d77276 Added update of Stack and Watch windows after 'Debugging suspended' message. 2013-03-31 18:17:40 -07:00
Paul Kulchenko
406056bf52 Updated language files (es, it, ru) with new messages (ref #70). 2013-03-30 20:17:20 -07:00
Fringale
f960d65e08 Updated French translation with latest string changes, fixed a few typos. 2013-03-31 00:01:19 +01:00
Paul Kulchenko
a3fc62a7c0 Added toggling for View menu items. 2013-03-30 13:13:03 -07:00
Paul Kulchenko
5a4e996b37 Updated Stack and Watch window to not refresh when not visible. 2013-03-30 13:12:57 -07:00
Paul Kulchenko
200647f0c5 Fixed a warning about empty project directory in local console. 2013-03-29 16:25:25 -07:00
Paul Kulchenko
99d6395845 Fixed an issue with default layout on the very first start. 2013-03-29 16:18:28 -07:00
Paul Kulchenko
fc0d5083e6 Updated CHANGELOG and README with current features. 2013-03-29 14:44:01 -07:00
Paul Kulchenko
478a87c8d0 Merge branch 'wxwidgets' (closes #89; closes #111).
Conflicts:
	src/editor/filetree.lua
2013-03-29 11:20:27 -07:00
Paul Kulchenko
d3a8b37cf3 Disabled closing Stack and Watch tabs. 2013-03-29 09:09:24 -07:00
Paul Kulchenko
0f99cb20b0 Forced floating of Stack and Watch windows by default (ref #89). 2013-03-28 22:40:41 -07:00
Paul Kulchenko
df54864e43 Made application name an optional parameter; reorganized on-exit workarounds. 2013-03-28 21:37:48 -07:00
Paul Kulchenko
9beae1f9c4 Updated error messages from loading configuration files. 2013-03-28 21:37:48 -07:00
Paul Kulchenko
0761ee2f4a Reduced flicker in the project tree when a file is opened (ref #89). 2013-03-28 21:37:47 -07:00
Paul Kulchenko
314dc5ba9e Added migration of configuration file on Windows (helps #89). 2013-03-28 21:37:46 -07:00
Paul Kulchenko
02a086e083 Revert "Updated editor handlers to improve performance on OSX with wx2.9.5".
The revert is needed as wx2.9.5 doesn't properly refresh status bar with
this change (on OSX, which the original improvement targeted).
2013-03-28 21:37:45 -07:00
Paul Kulchenko
3a616f5e37 Added hiding floating windows and removed excessive manager updates to reduce flicker. 2013-03-28 21:37:44 -07:00
Paul Kulchenko
3f12ce28d8 Optimized project switching and added notebook freezing where possible (ref #89). 2013-03-28 21:37:44 -07:00
Paul Kulchenko
a913c1fa55 Changed auto-recovery mark to be only applied after text changes. 2013-03-28 21:37:43 -07:00
Paul Kulchenko
363803ea9b Fixed an issue with Enter used to select an item in project dropdown (ref #89).
On Windows multiple COMBOBOX_SELECTED events are sent when Enter is used,
which may lead to run-time errors. Disabled processing of multiple copies
of the same event.
2013-03-28 21:37:35 -07:00
Paul Kulchenko
1bbb9f432c Rearranged saving settings to properly save on OSX (helps #89). 2013-03-27 13:02:15 -07:00
Paul Kulchenko
4854afeb32 Fixed default perspective to include Stack and Watch windows (ref #103). 2013-03-27 12:56:45 -07:00
Paul Kulchenko
507832ac2b Updated project tree workaround on OSX as it's not needed with wx 2.9.5+ (ref #89). 2013-03-27 12:54:54 -07:00
Paul Kulchenko
146b36d9ce Fixed an issue with the Project tree when project and app directories are the same. 2013-03-27 12:53:45 -07:00
Paul Kulchenko
77276d48ae Added auto-show/hide Stack and Watch windows during debugging (closes #110). 2013-03-26 15:25:02 -07:00
Paul Kulchenko
c3f253ef64 Added ignoring -psn... parameter on OSX when reading file names from command line. 2013-03-26 09:18:26 -07:00
Paul Kulchenko
93e51a6d43 Made stack and watch windows dockable (closes #103). 2013-03-24 15:04:27 -07:00
Paul Kulchenko
a26d72f99d Added exit call to avoid crash on Linux when closing the IDE.
The crash appears to happen in Unlink when debugging is in progress or
after an external process is executed. In some cases it also happens in
wxluaO_deletegcobject after simply closing the app on 64bit Linux.

1 0x0000... in wxEvtHandler::Unlink()
2 0x0000... in wxEvtHandler::~wxEvtHandler()
3 0x0000... in wxProcess::~wxProcess()
4 0x0000... in wxluaO_deletegcobject(lua_State*, int, int)
5 0x0000... in wxlua_wxLuaBindClass__gc(lua_State*)
2013-03-22 15:08:04 -07:00
Paul Kulchenko
cd8b714ea6 Upgraded Mobdebug (0.5222) to add serialization with metamethods and notification on incomplete output (closes #109). 2013-03-22 15:05:27 -07:00
Paul Kulchenko
909e9b3ee9 Updated Linux binaries to use libpng 1.6 with wxwidgets (helps #89).
The builtin library is now using separate symbols to avoid conflicts with
system libpng.
2013-03-22 14:45:22 -07:00
Paul Kulchenko
d10bcda693 Added scripts to install build prerequisites on Linux (helps #89). 2013-03-21 22:52:19 -07:00
Paul Kulchenko
7ddb673624 Updated Windows/OSX build files to only build components needed (helps #89). 2013-03-21 19:15:07 -07:00
Paul Kulchenko
bbd11b90eb Added check for different spellings of the same folder in the project tree. 2013-03-21 17:51:03 -07:00
Paul Kulchenko
4fee737981 Improved performance of tab switching and project tree population. 2013-03-21 17:49:35 -07:00
Paul Kulchenko
14143bf0ce Fixed function list in toolbar on Linux (helps #89). 2013-03-21 17:46:50 -07:00
Paul Kulchenko
0e8a9b078c Updated linux binaries to fix libpng support (helps #89).
Binaries have been updated to use whatever system libpng library is
available (without being linked against a particular version).

This also includes fix for 64bit systems to allow for these binaries to
work with "older" versions of libpng (for example, v1.2).

The binaries include wxwidgets fix for lsb_release messages, so the
workaround for this issue has been removed.
2013-03-20 12:22:28 -07:00
Paul Kulchenko
c2ca459882 Updated Linux binaries to work with different libpng versions (helps #89).
The compiled binary always has version of libpng as 1.2.0 (even though
wxwidgets may come with a different version) and is compiled with libpng
set to use system library. The warnings from libpng about different
versions are suppressed when bitmaps are loaded. This has been tested to
work with libpng 1.2.x and 1.5.x.

This update also adds a workaround for "lsb_release: command not found"
message reported on some Linux systems.
2013-03-18 12:48:16 -07:00
Paul Kulchenko
f80a11a982 Replaced deprecated arch with uname -m in Linux components (ref #89). 2013-03-14 09:50:11 -07:00
Paul Kulchenko
29650cef8c Updated executable status on linux files (ref #89). 2013-03-13 22:23:33 -07:00
Paul Kulchenko
4cf8017d7b Fixed debugger output not being suppressed on Linux and using wlua. 2013-03-13 17:16:38 -07:00
Paul Kulchenko
f807b1f48c Set 'Courier New' as the default font on Linux (ref #89). 2013-03-13 17:02:32 -07:00
Paul Kulchenko
dc7e040087 Added linux binaries with support for x86 and x64 (helps #89). 2013-03-13 16:59:38 -07:00
Paul Kulchenko
4262716043 Removed unused code. 2013-03-13 16:51:30 -07:00
Paul Kulchenko
5f25238ba6 Updated function list dropdown to fit toolbar on Linux (helps #89). 2013-03-13 16:47:08 -07:00
Paul Kulchenko
cf95129fc6 Fixed About screen to fit on Linux (helps #89). 2013-03-13 16:46:38 -07:00
Paul Kulchenko
f8b6654cd6 Fixed a warning when setting empty working directory. 2013-03-13 16:45:00 -07:00
Paul Kulchenko
cf001082e2 Removed reference to a dll no longer used. 2013-03-13 13:58:31 -07:00
Paul Kulchenko
c8e2890f60 Enabled full debugging for Corona on OSX. 2013-03-12 16:01:13 -07:00
Paul Kulchenko
9075736cf1 Set 'Courier New' as the default font on Windows.
It turned out that some Windows systems (like XP), don't use 'Courier New'
as the default, and rather use some proportional font, even when
wxFONTFAMILY_MODERN is used, which should pick a fixed pitch font.
2013-03-12 12:17:14 -07:00
Paul Kulchenko
e1cba702f7 Updated windows executable to show properly scaled icons in the Explorer. 2013-03-12 12:04:40 -07:00
Paul Kulchenko
9ffc4cf9dd Fixed wxwidgets issue with wrong cursor shape over editor (ref #89). 2013-03-11 10:35:17 -07:00
Paul Kulchenko
94647152fc Fixed a static analyzer issue with anonymous functions defined in expressions (fixes #3). 2013-03-10 15:59:45 -07:00
Paul Kulchenko
e4a69a63c0 Added a workaround for a crash on OSX when the app is closed while
debugging is in progress (ref #89).

The crash appears to be in wxEvtHandler::Unlink, but I couldn't find the
cause for it:
0   libwx.dylib	0x014d2bd9 wxEvtHandler::Unlink() + 51
1   libwx.dylib	0x014d4023 wxEvtHandler::~wxEvtHandler() + 37
2   libwx.dylib	0x0146d7fa wxProcess::~wxProcess() + 84
3   libwx.dylib	0x01074af9 wxLua_wxProcess_delete_function(void**) + 23
4   libwx.dylib	0x0113300d wxluaO_deletegcobject(lua_State*, int, int) + 425
5   libwx.dylib	0x0111f6f2 wxlua_wxLuaBindClass__gc(lua_State*) + 101
2013-03-09 18:49:35 -08:00
Paul Kulchenko
05e2b483a8 Added window list button to the notepad with editor tabs. 2013-03-09 18:48:40 -08:00
Paul Kulchenko
f2e8c0c213 Updated status bar to use no border around fields. 2013-03-09 18:46:44 -08:00
Paul Kulchenko
43c6be0859 Added centering of current line during debugging. 2013-03-07 20:01:37 -08:00
Paul Kulchenko
fb5ef928fd Improved handling of upvalues with __tostring method in the Stack window. 2013-03-07 19:59:18 -08:00
Paul Kulchenko
3f9be575fd Updated check for wxwidgets version on OSX (helps #89). 2013-03-07 17:11:06 -08:00
Paul Kulchenko
9985cfc50a Fixed OSX crash when tooltips/auto-complete is used (helps #89). 2013-03-07 17:10:19 -08:00
Paul Kulchenko
be018b39fc Updated build scripts to include wxlua patch to fix live coding (helps #89). 2013-03-07 17:09:40 -08:00
Paul Kulchenko
da15c46429 Fixed OSX issues with 2.9.5: numpad keys, switching tabs, and cursor shape when using scratchpad (helps #89). 2013-03-06 22:17:26 -08:00
Paul Kulchenko
0eb71f44d4 Updated indicator description for wx2.9.5; removed license that doesn't apply (helps #89). 2013-03-03 20:03:29 -08:00
Paul Kulchenko
aa6618f002 Updated translation script to work with wxwidgets 2.9.5+ (helps #89). 2013-03-03 19:46:12 -08:00
Paul Kulchenko
e55e28e852 Fixed multi-line paste into console with wxwidgets 2.9.5 (helps #89). 2013-03-03 19:01:05 -08:00
Paul Kulchenko
0e1c937892 Increased default font size for OSX; set 'Monaco' as default font (helps #89). 2013-03-01 20:46:34 -08:00
Paul Kulchenko
65a112a4e9 Removed checks for Windows in font setup; now uses default font. 2013-03-01 20:46:33 -08:00
Paul Kulchenko
0448ebb0e0 Updated function call indicator to use round box with wxwidgets upgrade (helps #89). 2013-03-01 20:46:32 -08:00
Paul Kulchenko
fec7d21ca4 Updated binaries with a patched version of wxlua (helps #89).
The patch is needed to fix live coding issue with wxlua applications. Also
uses a more recent version of wxwidgets, that fixes menu hint on OSX.
2013-03-01 20:46:26 -08:00
Paul Kulchenko
2d29aa3666 Updated large icons for "native" toolbar on OSX (helps #89). 2013-03-01 20:46:06 -08:00
Paul Kulchenko
23a4f5fa04 Reorganized code to allow references to wxver from default style generation. 2013-02-28 00:01:13 -08:00
Paul Kulchenko
80bcc21562 Fixed rearranging editor tabs with drag and drop (helps #89). 2013-02-28 00:00:04 -08:00
Paul Kulchenko
5dcf0a6622 Updated keywords to be re-applied after SaveAs only when needed. 2013-02-25 21:51:50 -08:00
Paul Kulchenko
99c1be49a6 Updated handling of markdown styles to make it more robust (fixes #59). 2013-02-25 21:45:33 -08:00
Paul Kulchenko
2a46b4ece7 Updated file loading logic for a small performance improvement. 2013-02-24 22:17:43 -08:00
Paul Kulchenko
1d77bbdf5a Added multiple selection and multi-cursor editing (wx2.9.5+). 2013-02-24 22:16:05 -08:00
Paul Kulchenko
943517f07e Updated editor handlers to improve performance on OSX with wx2.9.5 (helps #89). 2013-02-24 21:43:21 -08:00
Paul Kulchenko
93b664de45 Fixed an issue with full screen mode on OSX with wx 2.9.5 (helps #89). 2013-02-24 21:43:21 -08:00
Paul Kulchenko
695fed709e Switched to 'native' menu on OSX and added 24x24 icons required (helps #89).
Removed Cut/Copy/Paste/Undo/Redo icons from the toolbar as these are
rarely used and were taking too much space.
2013-02-24 21:43:05 -08:00
Paul Kulchenko
51735ac89d Updated MANIFEST for OSX dylib changes (helps #89). 2013-02-24 21:28:53 -08:00
Paul Kulchenko
5a49699098 Added a check to only activate the Output window if it's not activated.
This reduces flicker by redrawing the project tree only when needed.
2013-02-24 17:53:03 -08:00
Paul Kulchenko
b2b6e82735 Added a check for project tree refresh to only execute on OSX. 2013-02-24 17:53:02 -08:00
Paul Kulchenko
fd3ed2b7da Added a property to store wxwidgets version. 2013-02-24 17:46:59 -08:00
Paul Kulchenko
4da018b8ce Removed files for handling preferences that are no longer used. 2013-02-24 17:46:31 -08:00
Paul Kulchenko
99ad315832 Added dll proxy to make LfW libraries to work with the IDE. 2013-02-23 14:49:40 -08:00
Paul Kulchenko
4bd20406a2 Removed binary libraries not currently used. 2013-02-23 14:33:28 -08:00
Paul Kulchenko
48b51c549a Updated launcher manifest and resource file; resigned windows executable (helps #89). 2013-02-23 14:31:24 -08:00
toiffel
af0a95ddb8 Added wxWidgets 2.9.5 binaries and build scripts 2013-02-22 14:10:02 +07:00
Paul Kulchenko
5db9b6b9b5 Updated applying fold properties to get folds working with wxwidgets 2.9.5+ (helps #89). 2013-02-18 14:08:37 -08:00
toiffel
e1bee48834 Fixed a segfault when closing the application on OS X and Linux 2013-02-18 14:02:02 -08:00
Paul Kulchenko
704f6fed89 Fixed formatting in the About screen for wxwidgets 2.9.x (helps #89). 2013-02-13 13:53:58 -08:00
Paul Kulchenko
c05962c6a6 Updated README with Marmalade Quick support and Corona tutorial. 2013-02-13 13:50:41 -08:00
crazybutcher
17948e06d8 introduce method handling for autocomplete and api resolving 2013-02-10 20:45:38 +01:00
crazybutcher
51777d47c9 Merge remote-tracking branch 'zbstudio/master' 2013-02-10 12:48:25 +01:00
crazybutcher
1714cf6109 improved type guessing: always keep full assignment string, do multiple runs on resolve, strip closed scopes 2013-02-10 12:48:05 +01:00
134 changed files with 5573 additions and 1534 deletions

View File

@@ -1,5 +1,169 @@
# ZeroBrane Studio Changelog
## v0.37 (May 09 2013)
### Special thanks
- To Samuel Dionne-Riel for wxwidgets 2.8 compatibility updates.
- To Mat Hopwood for assistance with Marmalade Quick integration.
### Highlights
- Added Marmalade Quick auto-complete support and API documentation.
- Added full Marmalade Quick debugging support (requires Quick 1.1+).
- Improved Find/Replace behavior and functionality.
- Added Recent File history navigation.
- Added Preferences menu to simplify access to system/user settings.
### Improvements
- Added Preferences menu to simplify access to system/user settings.
- Added Russian translation for Find/Replace dialog and (ref #70).
- Added Russian translation for the Preferences menu (ref #70).
- Added 'shaking' Find/Replace window when text is not found (closes #146).
- Added 'wlua' to the list of recognized Lua extensions.
- Added disabling Recent Files menu if the list is empty.
- Added TomorrowContrast color scheme (thanks to Sergey Lerg).
- Added detaching a child process to avoid crash when exiting during debugging.
- Added Recent File history navigation (closes #66).
- Added Marmalade auto-complete support and API documentation.
- Added processing of `runonstart` when using remote debugging (closes #138).
- Added suggesting proper extension after 'Save/Save As' based on current spec.
- Added translation setup for Find/Replace dialog (closes #133).
- Added `nomousezoom` option to disable zoom with mouse wheel in the editor.
- Added selecting text and Cmd-F shortcut in Find dialog on OSX (ref #127).
- Improved file activation when debugging is started (closes #137).
- Reduced the minimum size of the Output/Console panel.
- Refactored Recent Files history to make it faster and simpler.
- Refactored and optimized directory scanning when loading IDE files.
- Separated settings for function dropdown and project tree fonts (fixes #148).
- Updated documentation about default EOL on OSX (ref #102).
- Updated highlighting in Watch windows to not use editor styles.
- Updated documentation for user settings (ref #113, #55).
- Updated Monokai color scheme to fix current line color.
### Incompatibilities
- (dev) `FileSysGet` has been replaced with `FileSysGetRecursive` with a different signature.
### Fixes
- Fixed hiding all panels when switching to Full Screen mode.
- Fixed loading a non-existing file.
- Fixed activation of non-existing files/folders in the Project tree.
- Fixed search results for lines without newline.
- Fixed Find/Replace in folders with Unicode names (fixes #147); improved performance.
- Fixed Un/Comment commands executed for empty lines.
- Fixed fold/unfold for files starting with block/comment.
- Fixed history after activating non-existing file in Recent Files.
- Fixed scrolling to restored cursor position on OSX (when `usewrap` = false).
- Fixed Find/Replace dialog to take Enter on OSX (fixes #140).
- Fixed 'breaking' after executing OUT command that never reaches the target level.
- Fixed stopping at a breakpoint at the initial line when `startwith` option is specified.
- Fixed activation of a file loaded into active tab.
- Fixed incorrect tab activation on OSX after using 'Open File'.
- Fixed editor activation when file is loaded into an existing tab.
- Fixed an error after opening non-existing file from 'Recent Files'.
- Fixed blocking on reading app output without processing other events.
- Fixed an issue with duplicate lines shown in the editor.
- Fixed 'Replace All' to take 'Wrap Around' into account (fixes #132).
- Fixed off-by-one error in searching consecutive matches.
- Fixed 'Quick Find' not working without current selection (fixes #131).
- Fixed looping in auto-complete on mistyped class (fixes #130).
- Fixed compatibility with wx2.8 (thanks to Samuel Dionne-Riel; closes #128).
- Fixed replacement logic in Find/Replace that could replace selected fragment (ref #127).
- Fixed an error caused by allowing multiple Search/Replace windows (fixes #127).
## v0.361 (Apr 12 2013)
### Improvements
- Added handling of Ctrl-Home and Ctrl-End on OSX (ref #89).
- Added line copy/cut for Ctrl-C/Ctrl-X with no selection.
- Updated About screen to be more configurable and flexible.
- Updated Russian translation (thanks to toiffel).
### Fixes
- Fixed launch command for Corona debugging on Windows.
- Fixed 'control' check on OSX that changed with wx2.9.2+ (ref #89).
- Fixed wrong tab activated on OSX after using New file in some cases.
- Fixed cursor not being visible in some cases after file is loaded (ref #116).
## v0.36 (Apr 08 2013)
### Highlights
- Added 32bit and 64bit **Linux binaries**.
- Enabled **full debugging for Corona on OSX**.
- Improved **debugger performance**.
- Improved **performance of tab and project switching**.
- Added **multiple selection and multi-cursor editing**.
- Made Stack and Watch windows dockable and toggleable.
### Special thanks
- To toiffel for build improvements and continuous work on wxwidgets 2.9 and Linux support.
- To Marcel van Herk for testing and feedback on Stack and Watch windows behavior.
- To Leo Bartoloni for Italian translation update.
- To Fringale for updated French translation.
- To neomantra for adding cdata processing in the serializer.
### Improvements
- Added handling of case-insensitive filenames on OSX.
- Added cdata processing (thanks to neomantra).
- Added universal binaries for luasocket on OSX to allow debugging of 64bit applications (for example, LuaJIT) on OSX.
- Added update of Stack and Watch windows after 'Debugging suspended' message.
- Added toggling for View menu items.
- Added auto-show/hide Stack and Watch windows during debugging (closes #110).
- Added ignoring `-psn...` parameter on OSX when reading file names from command line.
- Added migration of configuration file on Windows (helps #89).
- Added check for different spellings of the same folder in the project tree.
- Added scripts to install build prerequisites on Linux (helps #89).
- Added linux binaries with support for x86 and x64 (helps #89).
- Added window list button to the notepad with editor tabs.
- Added centering of current line during debugging.
- Added multiple selection and multi-cursor editing (wx2.9.5+).
- Added dll proxy to make LfW libraries to work with the IDE.
- Disabled showing 'value' in auto-complete after 'a:' (helps #101).
- Enabled full debugging for Corona on OSX.
- Improved debugging performance.
- Improved performance of tab switching and project tree population.
- Improved handling of upvalues with __tostring method in the Stack window.
- Increased default font size for OSX; set 'Monaco' as default font (helps #89).
- Made stack and watch windows dockable (closes #103).
- Optimized project switching and added notebook freezing where possible (ref #89).
- Reduced flicker in the project tree when a file is opened (ref #89).
- Removed binary libraries not currently used.
- Set 'Courier New' as the default font on Linux (ref #89).
- Switched to 'native' menu on OSX and added 24x24 icons required (helps #89).
- Updated Italian translation (thanks to Leo Bartoloni)
- Updated 'method' type in auto-complete to only allow a:b syntax (closes #101).
- Updated language files (es, it, ru) with new messages (ref #70).
- Updated French translation with latest string changes, fixed a few typos (thanks to Fringale).
- Updated Stack and Watch window to not refresh when not visible.
- Upgraded Mobdebug (0.5222) to add serialization with metamethods and notification on incomplete output (closes #109).
- Updated error messages from loading configuration files.
- Updated Linux binaries to use libpng 1.6 with wxwidgets (helps #89).
- Updated Windows/OSX build files to only build components needed (helps #89).
- Updated windows executable to show properly scaled icons in the Explorer.
- Updated status bar to use no border around fields.
- Updated large icons for "native" toolbar on OSX (helps #89).
- Updated function call indicator to use round box with wxwidgets upgrade (helps #89).
- Updated handling of markdown styles to make it more robust (fixes #59).
- Updated README with Marmalade Quick support and Corona tutorial.
### Incompatibilities
- Configuration file (.ini) location has changed on Windows. The current file will be copied to the new location.
- The debugger now stops on the next executable line after `.start()` call.
### Fixes
- Fixed activating files in the project tree on a case insensitive system.
- Fixed the Stack view being partially hidden when the root item is too wide (ref #110).
- Fixed left side of the project panel being hidden when a file is activated (fixes #122).
- Fixed breakpoint not firing on the first executable line in debugging (helps #121).
- Fixed terminating debugging of an empty script.
- Fixed reporting of initial line during debugging.
- Fixed editor tab activation after closing another tab on Linux (ref #89).
- Fixed 'Show tooltip' shortcut not working on Linux (fixes #118; ref #89).
- Fixed cursor position being incorrectly restored (fixes #116; ref #89).
- Fixed a warning about empty project directory in local console.
- Fixed an issue with Enter used to select an item in project dropdown (ref #89).
- Fixed an issue with the Project tree when project and app directories are the same.
- Fixed debugger output not being suppressed on Linux and using wlua.
- Fixed a static analyzer issue with anonymous functions defined in expressions (fixes #3).
## v0.35 (Feb 10 2013)
### Highlights

View File

@@ -2,7 +2,7 @@
[ZeroBrane Studio](http://studio.zerobrane.com/) is a lightweight Lua IDE with code completion, syntax
highlighting, remote debugger, code analyzer, live coding, and debugging
support for several Lua engines (LuaJIT, Löve 2D, Moai, Gideros, Corona,
support for several Lua engines (LuaJIT, Löve 2D, Moai, Gideros, Corona, Marmalade Quick,
MobileLua, GSL-shell, and others). It originated from the [Estrela Editor](http://www.luxinia.de/index.php/Estrela/).
## Features
@@ -12,9 +12,8 @@ MobileLua, GSL-shell, and others). It originated from the [Estrela Editor](http:
* Auto-completion for functions, keywords, and custom APIs.
* Interactive console to directly test code snippets with local and remote execution.
* Integrated debugger (with support for local and remote debugging).
* Live coding with Lua ([demo](http://notebook.kulchenko.com/zerobrane/live-coding-in-lua-bret-victor-style)), Löve 2D ([demo](http://notebook.kulchenko.com/zerobrane/live-coding-with-love)), and Gideros ([demo](http://notebook.kulchenko.com/zerobrane/gideros-live-coding-with-zerobrane-studio-ide)).
* Live coding with Lua ([demo](http://notebook.kulchenko.com/zerobrane/live-coding-in-lua-bret-victor-style)), Löve 2D ([demo](http://notebook.kulchenko.com/zerobrane/live-coding-with-love)), Gideros ([demo](http://notebook.kulchenko.com/zerobrane/gideros-live-coding-with-zerobrane-studio-ide)), Moai ([demo](http://notebook.kulchenko.com/zerobrane/live-coding-with-moai-and-zerobrane-studio)), and Corona SDK ([demo](http://notebook.kulchenko.com/zerobrane/debugging-and-live-coding-with-corona-sdk-applications-and-zerobrane-studio)).
* Support for plugin-like components:
- applications: overall control of applications settings;
- specs (spec/): file syntax, lexer, keywords (e.g. glsl);
- apis (api/): for code-completion and tool-tips;
- interpreters (interpreters/): how a project is run;
@@ -53,7 +52,7 @@ Loading custom configuration:
## Where is Estrela?
The projects have been merged again and zbstudio will lead the future.
The projects have been merged and zbstudio will lead the future.
Please reassociate files with zbstudio. To keep your history of files and
projects copy the contents of the `EstrelaEditor.ini` in your HOME directory
to `ZeroBraneStudio.ini`. If you have used Estrela for graphics shader

View File

@@ -739,6 +739,7 @@ return {
description = "When called with a file name, it opens the named file (in text mode), and sets its handle as the default input file. When called with a file handle, it simply sets this file handle as the default input file. When called without parameters, it returns the current default input file.\n\nIn case of errors this function raises the error, instead of returning an error code.",
args = "([file: string|file])",
returns = "([file])",
valuetype = "f",
},
lines = {
type = "function",
@@ -751,18 +752,21 @@ return {
description = "This function opens a file, in the mode specified in the string mode.\n\nIt returns a new file handle, or, in case of errors, nil plus an error message.\n\nThe mode string can be any of the following:\n\n* \"r\": read mode (the default);\n\n* \"w\": write mode;\n\n* \"a\": append mode;\n\n* \"r+\": update mode, all previous data is preserved;\n\n* \"w+\": update mode, all previous data is erased;\n\n* \"a+\": append update mode, previous data is preserved, writing is only allowed at the end of file.\n\nThe mode string can also have a 'b' at the end, which is needed in some systems to open the file in binary mode.",
args = "(filename: string [, mode: string])",
returns = "(file|nil [, string])",
valuetype = "f",
},
output = {
type = "function",
description = "When called with a file name, it opens the named file (in text mode), and sets its handle as the default output file. When called with a file handle, it simply sets this file handle as the default output file. When called without parameters, it returns the current default output file.\n\nIn case of errors this function raises the error, instead of returning an error code.",
args = "([file: string|file])",
returns = "([file])",
valuetype = "f",
},
popen = {
type = "function",
description = "Starts program prog in a separated process and returns a file handle that you can use to read data from this program (if mode is \"r\", the default) or to write data to this program (if mode is \"w\").\n\nThis function is system dependent and is not available on all platforms.",
args = "(prog: string [, mode: string])",
returns = "(file|nil [, string])",
valuetype = "f",
},
read = {
type = "function",
@@ -775,6 +779,7 @@ return {
description = "Returns a handle for a temporary file.\n\nThis file is opened in update mode and it is automatically removed when the program ends.",
args = "()",
returns = "(file)",
valuetype = "f",
},
type = {
type = "function",
@@ -796,43 +801,43 @@ return {
description = "Pseudoclass for operations on file handles.",
childs = {
close = {
type = "function",
type = "method",
description = "Closes file.\n\nNote that files are automatically closed when their handles are garbage collected, but that takes an unpredictable amount of time to happen.\n\nWhen closing a file handle created with io.popen, file:close returns the same values returned by os.execute. RETURN SPECIAL CASE ADDED IN Lua 5.2.",
args = "(file: file)",
returns = "(boolean|nil [, string, number])",
},
flush = {
type = "function",
type = "method",
description = "Saves any written data to file.",
args = "(file: file)",
returns = "(boolean|nil [, string])",
},
lines = {
type = "function",
type = "method",
description = "Returns an iterator function that, each time it is called, reads the file according to the given formats.\n\nWhen no format is given, uses \"*l\" as a default. ARGUMENT ADDED IN Lua 5.2.\n\nUnlike io.lines, this function does not close the file when the loop ends.\n\nIn case of errors this function raises the error, instead of returning an error code.",
args = "(file: file, ...)",
returns = "(function)",
},
read = {
type = "function",
type = "method",
description = "Reads the file file, according to the given formats, which specify what to read.\n\nFor each format, the function returns a string (or a number) with the characters read, or nil if it cannot read data with the specified format. When called without formats, it uses a default format that reads the next line (see below).\n\nThe available formats are\n\n* \"*n\": reads a number; this is the only format that returns a number instead of a string.\n\n* \"*a\": reads the whole file, starting at the current position. On end of file, it returns the empty string.\n\n* \"*l\": reads the next line skipping the end of line, returning nil on end of file. This is the default format.\n\n* \"*L\": reads the next line keeping the end of line (if present), returning nil on end of file. VALUE ADDED IN Lua 5.2.\n\n* number: reads a string with up to this number of bytes, returning nil on end of file. If number is zero, it reads nothing and returns an empty string, or nil on end of file.",
args = "(file: file, ...)",
returns = "(...)",
},
seek = {
type = "function",
type = "method",
description = "Sets and gets the file position, measured from the beginning of the file, to the position given by offset plus a base specified by the string whence.\n\nThe string whence is specified as follows:\n\n* \"set\": base is position 0 (beginning of the file);\n\n* \"cur\": base is current position;\n\n* \"end\": base is end of file.\n\nIn case of success, seek returns the final file position, measured in bytes from the beginning of the file. If seek fails, it returns nil, plus a string describing the error.\n\nThe default value for whence is \"cur\", and for offset is 0. Therefore, the call file:seek() returns the current file position, without changing it; the call file:seek(\"set\") sets the position to the beginning of the file (and returns 0); and the call file:seek(\"end\") sets the position to the end of the file, and returns its size.",
args = "(file: file, [whence: string [, offset: number]])",
returns = "(number|nil [, string])",
},
setvbuf = {
type = "function",
type = "method",
description = "Sets the buffering mode for an output file.\n\nThere are three available modes:\n\n* \"no\": no buffering; the result of any output operation appears immediately.\n\n* \"full\": full buffering; output operation is performed only when the buffer is full or when you explicitly flush the file (see io.flush).\n\n* \"line\": line buffering; output is buffered until a newline is output or there is any input from some special files (such as a terminal device).\n\nFor the last two cases, size specifies the size of the buffer, in bytes. The default is an appropriate size.",
args = "(file: file, mode: string [, size: number])",
returns = "(boolean|nil [, string])",
},
write = {
type = "function",
type = "method",
description = "Writes the value of each of its arguments to file.\n\nThe arguments must be strings or numbers.\n\nIn case of success, this function returns file (RETURN CHANGED IN Lua 5.2, BOOLEAN IN LUA 5.1). Otherwise it returns nil plus a string describing the error.",
args = "(file: file, ...)",
returns = "(file|nil [, string])",

2488
api/lua/marmalade.lua Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

BIN
bin/clibs/mime/core.dll Executable file → Normal file

Binary file not shown.

BIN
bin/clibs/mime/core.dylib Normal file → Executable file

Binary file not shown.

Binary file not shown.

BIN
bin/clibs/socket/core.dll Executable file → Normal file

Binary file not shown.

BIN
bin/clibs/socket/core.dylib Normal file → Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
bin/liblua.dylib Executable file

Binary file not shown.

BIN
bin/libwx.dylib Normal file → Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
bin/linux/x64/libwx.so Normal file

Binary file not shown.

BIN
bin/linux/x64/lua Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
bin/linux/x86/libwx.so Normal file

Binary file not shown.

BIN
bin/linux/x86/lua Executable file

Binary file not shown.

BIN
bin/lua

Binary file not shown.

Binary file not shown.

BIN
bin/lua.exe Executable file → Normal file

Binary file not shown.

BIN
bin/lua5.1.dll Executable file → Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
bin/wx.dll Executable file → Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -1,42 +0,0 @@
#!/bin/bash
set -x
TEMPLATE_DMG=/tmp/ZeroBraneStudio-template.dmg
BUILT_DMG=ZeroBraneStudio.dmg
WKDIR=/tmp/zbs-build
# remove problematic symlink
rm ../zbstudio/ZeroBraneStudio.app/Contents/ZeroBraneStudio
bunzip2 -kf ZeroBraneStudio.dmg.bz2
mv ZeroBraneStudio.dmg $TEMPLATE_DMG
hdiutil attach "${TEMPLATE_DMG}" -noautoopen -quiet -mountpoint "${WKDIR}"
rm -rf "${WKDIR}/ZeroBraneStudio.app"
# copy the app to where it should be
cp -pr "../zbstudio/ZeroBraneStudio.app" "${WKDIR}/ZeroBraneStudio.app"
mkdir "${WKDIR}/ZeroBraneStudio.app/Contents/ZeroBraneStudio"
# only pick the files listed in manifests and 'myprograms' (if exists)
if [[ -d ../myprograms ]]; then MYPROGRAMS=$(cd ..; find myprograms -iname *.lua); fi
(cd ".."; tar cf - $MYPROGRAMS $(< zbstudio/MANIFEST) $(< zbstudio/MANIFEST-bin-macos) | (cd "${WKDIR}/ZeroBraneStudio.app/Contents/ZeroBraneStudio/"; tar xf -))
codesign -s "ZeroBrane LLC" ${WKDIR}/ZeroBraneStudio.app
codesign --signature-size 6400 -s "ZeroBrane LLC" ${WKDIR}/ZeroBraneStudio.app/Contents/ZeroBraneStudio/bin/lua.app
# clean up
sudo rm -rf "${WKDIR}/.Trashes"
sudo rm -rf "${WKDIR}/.fseventsd"
hdiutil detach "${WKDIR}" -quiet -force
hdiutil convert "${TEMPLATE_DMG}" -quiet -format UDZO -imagekey zlib-level=9 -o "${BUILT_DMG}"
rm -f "${TEMPLATE_DMG}"
cd ../zbstudio/ZeroBraneStudio.app/Contents
ln -s ../../.. ZeroBraneStudio
echo Built ${BUILT_DMG}.

22
build/build-linux-prep-deb.sh Executable file
View File

@@ -0,0 +1,22 @@
#!/bin/bash
# this script installs prerequisites to build binary files on Linux with deb
sudo apt-get install git-core
sudo apt-get install g++
sudo apt-get install subversion
sudo apt-get install libgtk2.0-dev
# install cmake as wxwidgets needs 2.8.4+ but "sudo apt-get install cmake"
# only installs 2.8.0 on some systems (like Ubuntu 10.4)
mkdir build-cmake
cd build-cmake
wget http://www.cmake.org/files/v2.8/cmake-2.8.10.2.tar.gz
gunzip cmake-2.8.10.2.tar.gz
tar xvf cmake-2.8.10.2.tar
cd cmake-2.8.10.2
./bootstrap
make
sudo make install
cd ../..
rm -rf build-cmake

View File

@@ -0,0 +1,9 @@
#!/bin/bash
# this script installs prerequisites to build binary files on Linux with rpm
sudo yum install gcc-c++
sudo yum install git
sudo yum install svn
sudo yum install cmake
sudo yum install gtk2-devel

190
build/build-linux.sh Executable file
View File

@@ -0,0 +1,190 @@
#!/bin/bash
if [ "$(uname -m)" = "x86_64" ]; then
FPIC="-fpic"
ARCH="x64"
else
FPIC=""
ARCH="x86"
fi
# ZBS binary directory
BIN_DIR="$(dirname "$PWD")/bin/linux/$ARCH"
# temporary installation directory for dependencies
INSTALL_DIR="$PWD/deps"
# number of parallel jobs used for building
MAKEFLAGS="-j4"
# flags for manual building with gcc
BUILD_FLAGS="-O2 -shared -s -I $INSTALL_DIR/include -L $INSTALL_DIR/lib $FPIC"
# paths configuration
WXWIDGETS_BASENAME="wxWidgets"
WXWIDGETS_URL="http://svn.wxwidgets.org/svn/wx/wxWidgets/trunk"
LIBPNG_BASENAME="libpng-1.6.0"
LIBPNG_FILENAME="$LIBPNG_BASENAME.tar.gz"
LIBPNG_URL="http://sourceforge.net/projects/libpng/files/libpng16/1.6.0/libpng-1.6.0.tar.gz/download"
LUA_BASENAME="lua-5.1.5"
LUA_FILENAME="$LUA_BASENAME.tar.gz"
LUA_URL="http://www.lua.org/ftp/$LUA_FILENAME"
WXLUA_BASENAME="wxlua"
WXLUA_URL="https://wxlua.svn.sourceforge.net/svnroot/wxlua/trunk"
LUASOCKET_BASENAME="luasocket-2.0.2"
LUASOCKET_FILENAME="$LUASOCKET_BASENAME.tar.gz"
LUASOCKET_URL="http://files.luaforge.net/releases/luasocket/luasocket/luasocket-2.0.2/$LUASOCKET_FILENAME"
# exit if the command line is empty
if [ $# -eq 0 ]; then
echo "Usage: $0 LIBRARY..."
exit 0
fi
# iterate through the command line arguments
for ARG in "$@"; do
case $ARG in
wxwidgets)
BUILD_WXWIDGETS=true
;;
lua)
BUILD_LUA=true
;;
wxlua)
BUILD_WXLUA=true
;;
luasocket)
BUILD_LUASOCKET=true
;;
all)
BUILD_WXWIDGETS=true
BUILD_LUA=true
BUILD_WXLUA=true
BUILD_LUASOCKET=true
;;
*)
echo "Error: invalid argument $ARG"
exit 1
;;
esac
done
# check for g++
if [ ! "$(which g++)" ]; then
echo "Error: g++ isn't found. Please install GNU C++ compiler."
exit 1
fi
# check for cmake
if [ ! "$(which cmake)" ]; then
echo "Error: cmake isn't found. Please install CMake and add it to PATH."
exit 1
fi
# check for svn
if [ ! "$(which svn)" ]; then
echo "Error: svn isn't found. Please install console SVN client."
exit 1
fi
# check for wget
if [ ! "$(which wget)" ]; then
echo "Error: wget isn't found. Please install GNU Wget."
exit 1
fi
# create the installation directory
mkdir -p "$INSTALL_DIR" || { echo "Error: cannot create directory $INSTALL_DIR"; exit 1; }
# build wxWidgets
if [ $BUILD_WXWIDGETS ]; then
# first build get/configure libpng as v1.6 is needed
wget -c "$LIBPNG_URL" -O "$LIBPNG_FILENAME" || { echo "Error: failed to download lbpng"; exit 1; }
tar -xzf "$LIBPNG_FILENAME"
(cd "$LIBPNG_BASENAME"; ./configure --with-libpng-prefix=wxpng_; make $MAKEFLAGS)
svn co "$WXWIDGETS_URL" "$WXWIDGETS_BASENAME" || { echo "Error: failed to checkout wxWidgets"; exit 1; }
# replace src/png with the libpng folder
rm -rf "$WXWIDGETS_BASENAME/src/png"
mv "$LIBPNG_BASENAME" "$WXWIDGETS_BASENAME/src/png"
cd "$WXWIDGETS_BASENAME"
./configure --prefix="$INSTALL_DIR" --disable-debug --disable-shared --enable-unicode \
--with-libjpeg=builtin --with-libpng=builtin --with-libtiff=no --with-expat=no \
--with-zlib=builtin --disable-richtext --with-gtk=2 \
CFLAGS="-Os -fPIC" CXXFLAGS="-Os -fPIC"
make $MAKEFLAGS || { echo "Error: failed to build wxWidgets"; exit 1; }
make install
cd ..
rm -rf "$WXWIDGETS_BASENAME" "$LIBPNG_FILENAME"
fi
# build Lua
if [ $BUILD_LUA ]; then
wget -c "$LUA_URL" -O "$LUA_FILENAME" || { echo "Error: failed to download Lua"; exit 1; }
tar -xzf "$LUA_FILENAME"
cd "$LUA_BASENAME"
# use POSIX as it has minimum dependencies (no readline and no ncurses required)
# LUA_USE_DLOPEN is required for loading libraries
(cd src; make all MYCFLAGS="$FPIC -DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-Wl,-E -ldl") || { echo "Error: failed to build Lua"; exit 1; }
make install INSTALL_TOP="$INSTALL_DIR"
cd ..
rm -rf "$LUA_FILENAME" "$LUA_BASENAME"
fi
# build wxLua
if [ $BUILD_WXLUA ]; then
svn co "$WXLUA_URL" "$WXLUA_BASENAME" || { echo "Error: failed to checkout wxLua"; exit 1; }
cd "$WXLUA_BASENAME/wxLua"
# the following patches wxlua source to fix live coding support in wxlua apps
# http://www.mail-archive.com/wxlua-users@lists.sourceforge.net/msg03225.html
sed -i 's/\(m_wxlState = wxLuaState(wxlState.GetLuaState(), wxLUASTATE_GETSTATE|wxLUASTATE_ROOTSTATE);\)/\/\/ removed by ZBS build process \/\/ \1/' modules/wxlua/wxlcallb.cpp
cmake -G "Unix Makefiles" -DBUILD_INSTALL_PREFIX="$INSTALL_DIR" -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SHARED_LIBS=FALSE \
-DwxWidgets_CONFIG_EXECUTABLE="$INSTALL_DIR/bin/wx-config" \
-DwxWidgets_COMPONENTS="stc;html;aui;adv;core;net;base" \
-DwxLuaBind_COMPONENTS="stc;html;aui;adv;core;net;base" -DwxLua_LUA_LIBRARY_USE_BUILTIN=FALSE \
-DwxLua_LUA_INCLUDE_DIR="$INSTALL_DIR/include" -DwxLua_LUA_LIBRARY="$INSTALL_DIR/lib/liblua.a" .
(cd modules/luamodule; make $MAKEFLAGS) || { echo "Error: failed to build wxLua"; exit 1; }
(cd modules/luamodule; make install/strip)
[ -f "$INSTALL_DIR/lib/libwx.so" ] || { echo "Error: libwx.so isn't found"; exit 1; }
cd ../..
rm -rf "$WXLUA_BASENAME"
fi
# build LuaSocket
if [ $BUILD_LUASOCKET ]; then
wget -c "$LUASOCKET_URL" -O "$LUASOCKET_FILENAME" || { echo "Error: failed to download LuaSocket"; exit 1; }
tar -xzf "$LUASOCKET_FILENAME"
cd "$LUASOCKET_BASENAME"
mkdir -p "$INSTALL_DIR/lib/lua/5.1/"{mime,socket}
gcc $BUILD_FLAGS -o "$INSTALL_DIR/lib/lua/5.1/mime/core.so" src/mime.c -llua \
|| { echo "Error: failed to build LuaSocket"; exit 1; }
gcc $BUILD_FLAGS -o "$INSTALL_DIR/lib/lua/5.1/socket/core.so" \
src/{auxiliar.c,buffer.c,except.c,inet.c,io.c,luasocket.c,options.c,select.c,tcp.c,timeout.c,udp.c,usocket.c} -llua \
|| { echo "Error: failed to build LuaSocket"; exit 1; }
mkdir -p "$INSTALL_DIR/share/lua/5.1/socket"
cp src/{ftp.lua,http.lua,smtp.lua,tp.lua,url.lua} "$INSTALL_DIR/share/lua/5.1/socket"
cp src/{ltn12.lua,mime.lua,socket.lua} "$INSTALL_DIR/share/lua/5.1"
[ -f "$INSTALL_DIR/lib/lua/5.1/mime/core.so" ] || { echo "Error: mime/core.so isn't found"; exit 1; }
[ -f "$INSTALL_DIR/lib/lua/5.1/socket/core.so" ] || { echo "Error: socket/core.so isn't found"; exit 1; }
cd ..
rm -rf "$LUASOCKET_FILENAME" "$LUASOCKET_BASENAME"
fi
# now copy the compiled dependencies to ZBS binary directory
mkdir -p "$BIN_DIR" || { echo "Error: cannot create directory $BIN_DIR"; exit 1; }
[ $BUILD_LUA ] && cp "$INSTALL_DIR/bin/lua" "$BIN_DIR"
[ $BUILD_WXLUA ] && cp "$INSTALL_DIR/lib/libwx.so" "$BIN_DIR"
if [ $BUILD_LUASOCKET ]; then
mkdir -p "$BIN_DIR/clibs/"{mime,socket}
cp "$INSTALL_DIR/lib/lua/5.1/mime/core.so" "$BIN_DIR/clibs/mime"
cp "$INSTALL_DIR/lib/lua/5.1/socket/core.so" "$BIN_DIR/clibs/socket"
fi
# show a message about successful completion
echo "*** Build has been successfully completed ***"
exit 0

189
build/build-macosx.sh Executable file
View File

@@ -0,0 +1,189 @@
#!/bin/bash
# ZBS binary directory
BIN_DIR="$(dirname "$PWD")/bin"
# temporary installation directory for dependencies
INSTALL_DIR="$PWD/deps"
# Mac OS X global settings
MACOSX_ARCH="i386"
MACOSX_VERSION="10.6"
MACOSX_SDK_PATH="/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.6.sdk"
# number of parallel jobs used for building
MAKEFLAGS="-j4"
# flags for manual building with gcc; build universal binaries for luasocket
MACOSX_FLAGS="-arch $MACOSX_ARCH -mmacosx-version-min=$MACOSX_VERSION -isysroot $MACOSX_SDK_PATH"
BUILD_FLAGS="-O2 -arch x86_64 -dynamiclib -undefined dynamic_lookup $MACOSX_FLAGS -I $INSTALL_DIR/include -L $INSTALL_DIR/lib"
# paths configuration
WXWIDGETS_BASENAME="wxWidgets"
WXWIDGETS_URL="http://svn.wxwidgets.org/svn/wx/wxWidgets/trunk"
LUA_BASENAME="lua-5.1.5"
LUA_FILENAME="$LUA_BASENAME.tar.gz"
LUA_URL="http://www.lua.org/ftp/$LUA_FILENAME"
WXLUA_BASENAME="wxlua"
WXLUA_URL="https://wxlua.svn.sourceforge.net/svnroot/wxlua/trunk"
LUASOCKET_BASENAME="luasocket-2.0.2"
LUASOCKET_FILENAME="$LUASOCKET_BASENAME.tar.gz"
LUASOCKET_URL="http://files.luaforge.net/releases/luasocket/luasocket/luasocket-2.0.2/$LUASOCKET_FILENAME"
# exit if the command line is empty
if [ $# -eq 0 ]; then
echo "Usage: $0 LIBRARY..."
exit 0
fi
# iterate through the command line arguments
for ARG in "$@"; do
case $ARG in
wxwidgets)
BUILD_WXWIDGETS=true
;;
lua)
BUILD_LUA=true
;;
wxlua)
BUILD_WXLUA=true
;;
luasocket)
BUILD_LUASOCKET=true
;;
all)
BUILD_WXWIDGETS=true
BUILD_LUA=true
BUILD_WXLUA=true
BUILD_LUASOCKET=true
;;
*)
echo "Error: invalid argument $ARG"
exit 1
;;
esac
done
# check for g++
if [ ! "$(which g++)" ]; then
echo "Error: g++ isn't found. Please install GNU C++ compiler."
exit 1
fi
# check for cmake
if [ ! "$(which cmake)" ]; then
echo "Error: cmake isn't found. Please install CMake and add it to PATH."
exit 1
fi
# check for svn
if [ ! "$(which svn)" ]; then
echo "Error: svn isn't found. Please install console SVN client."
exit 1
fi
# check for wget
if [ ! "$(which wget)" ]; then
echo "Error: wget isn't found. Please install GNU Wget."
exit 1
fi
# create the installation directory
mkdir -p "$INSTALL_DIR" || { echo "Error: cannot create directory $INSTALL_DIR"; exit 1; }
# build wxWidgets
if [ $BUILD_WXWIDGETS ]; then
svn co "$WXWIDGETS_URL" "$WXWIDGETS_BASENAME" || { echo "Error: failed to checkout wxWidgets"; exit 1; }
cd "$WXWIDGETS_BASENAME"
./configure --prefix="$INSTALL_DIR" --disable-debug --disable-shared --enable-unicode \
--with-libjpeg=builtin --with-libpng=builtin --with-libtiff=no --with-expat=no \
--with-zlib=builtin --disable-richtext \
--enable-macosx_arch=$MACOSX_ARCH --with-macosx-version-min=$MACOSX_VERSION --with-macosx-sdk="$MACOSX_SDK_PATH" \
--with-osx_cocoa CFLAGS="-Os" CXXFLAGS="-Os"
make $MAKEFLAGS || { echo "Error: failed to build wxWidgets"; exit 1; }
make install
cd ..
rm -rf "$WXWIDGETS_BASENAME"
fi
# build Lua
if [ $BUILD_LUA ]; then
wget -c "$LUA_URL" -O "$LUA_FILENAME" || { echo "Error: failed to download Lua"; exit 1; }
tar -xzf "$LUA_FILENAME"
cd "$LUA_BASENAME"
sed -i "" 's/PLATS=/& macosx_dylib/' Makefile
printf "macosx_dylib:\n" >> src/Makefile
printf "\t\$(MAKE) LUA_A=\"liblua.dylib\" AR=\"\$(CC) -dynamiclib $MACOSX_FLAGS -o\" RANLIB=\"strip -u -r\" \\\\\n" >> src/Makefile
printf "\tMYCFLAGS=\"-DLUA_USE_LINUX $MACOSX_FLAGS\" MYLDFLAGS=\"$MACOSX_FLAGS\" MYLIBS=\"-lreadline\" lua\n" >> src/Makefile
printf "\t\$(MAKE) MYCFLAGS=\"-DLUA_USE_LINUX $MACOSX_FLAGS\" MYLDFLAGS=\"$MACOSX_FLAGS\" luac\n" >> src/Makefile
make macosx_dylib || { echo "Error: failed to build Lua"; exit 1; }
make install INSTALL_TOP="$INSTALL_DIR"
strip -u -r "$INSTALL_DIR/bin/lua"
cp src/liblua.dylib "$INSTALL_DIR/lib"
[ -f "$INSTALL_DIR/lib/liblua.dylib" ] || { echo "Error: liblua.dylib isn't found"; exit 1; }
cd ..
rm -rf "$LUA_FILENAME" "$LUA_BASENAME"
fi
# build wxLua
if [ $BUILD_WXLUA ]; then
svn co "$WXLUA_URL" "$WXLUA_BASENAME" || { echo "Error: failed to checkout wxLua"; exit 1; }
cd "$WXLUA_BASENAME/wxLua"
# the following patches wxlua source to fix live coding support in wxlua apps
# http://www.mail-archive.com/wxlua-users@lists.sourceforge.net/msg03225.html
sed -i "" 's/\(m_wxlState = wxLuaState(wxlState.GetLuaState(), wxLUASTATE_GETSTATE|wxLUASTATE_ROOTSTATE);\)/\/\/ removed by ZBS build process \/\/ \1/' modules/wxlua/wxlcallb.cpp
cmake -G "Unix Makefiles" -DBUILD_INSTALL_PREFIX="$INSTALL_DIR" -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SHARED_LIBS=FALSE \
-DCMAKE_OSX_ARCHITECTURES=$MACOSX_ARCH -DCMAKE_OSX_DEPLOYMENT_TARGET=$MACOSX_VERSION CMAKE_OSX_SYSROOT="$MACOSX_SDK_PATH" \
-DCMAKE_C_COMPILER=/usr/bin/gcc -DCMAKE_CXX_COMPILER=/usr/bin/g++ -DwxWidgets_CONFIG_EXECUTABLE="$INSTALL_DIR/bin/wx-config" \
-DwxWidgets_COMPONENTS="stc;html;aui;adv;core;net;base" \
-DwxLuaBind_COMPONENTS="stc;html;aui;adv;core;net;base" -DwxLua_LUA_LIBRARY_USE_BUILTIN=FALSE \
-DwxLua_LUA_INCLUDE_DIR="$INSTALL_DIR/include" -DwxLua_LUA_LIBRARY="$INSTALL_DIR/lib/liblua.dylib" .
(cd modules/luamodule; make $MAKEFLAGS) || { echo "Error: failed to build wxLua"; exit 1; }
(cd modules/luamodule; make install/strip)
strip -u -r "$INSTALL_DIR/lib/libwx.dylib"
[ -f "$INSTALL_DIR/lib/libwx.dylib" ] || { echo "Error: libwx.dylib isn't found"; exit 1; }
cd ../..
rm -rf "$WXLUA_BASENAME"
fi
# build LuaSocket
if [ $BUILD_LUASOCKET ]; then
wget -c "$LUASOCKET_URL" -O "$LUASOCKET_FILENAME" || { echo "Error: failed to download LuaSocket"; exit 1; }
tar -xzf "$LUASOCKET_FILENAME"
cd "$LUASOCKET_BASENAME"
mkdir -p "$INSTALL_DIR/lib/lua/5.1/"{mime,socket}
gcc $BUILD_FLAGS -o "$INSTALL_DIR/lib/lua/5.1/mime/core.dylib" src/mime.c \
|| { echo "Error: failed to build LuaSocket"; exit 1; }
gcc $BUILD_FLAGS -o "$INSTALL_DIR/lib/lua/5.1/socket/core.dylib" \
src/{auxiliar.c,buffer.c,except.c,inet.c,io.c,luasocket.c,options.c,select.c,tcp.c,timeout.c,udp.c,usocket.c} \
|| { echo "Error: failed to build LuaSocket"; exit 1; }
strip -u -r "$INSTALL_DIR/lib/lua/5.1/mime/core.dylib" "$INSTALL_DIR/lib/lua/5.1/socket/core.dylib"
mkdir -p "$INSTALL_DIR/share/lua/5.1/socket"
cp src/{ftp.lua,http.lua,smtp.lua,tp.lua,url.lua} "$INSTALL_DIR/share/lua/5.1/socket"
cp src/{ltn12.lua,mime.lua,socket.lua} "$INSTALL_DIR/share/lua/5.1"
[ -f "$INSTALL_DIR/lib/lua/5.1/mime/core.dylib" ] || { echo "Error: mime/core.dylib isn't found"; exit 1; }
[ -f "$INSTALL_DIR/lib/lua/5.1/socket/core.dylib" ] || { echo "Error: socket/core.dylib isn't found"; exit 1; }
cd ..
rm -rf "$LUASOCKET_FILENAME" "$LUASOCKET_BASENAME"
fi
# now copy the compiled dependencies to ZBS binary directory
mkdir -p "$BIN_DIR" || { echo "Error: cannot create directory $BIN_DIR"; exit 1; }
if [ $BUILD_LUA ]; then
mkdir -p "$BIN_DIR/lua.app/Contents/MacOS"
cp "$INSTALL_DIR/bin/lua" "$BIN_DIR/lua.app/Contents/MacOS"
cp "$INSTALL_DIR/bin/lua" "$INSTALL_DIR/lib/liblua.dylib" "$BIN_DIR"
fi
[ $BUILD_WXLUA ] && cp "$INSTALL_DIR/lib/libwx.dylib" "$BIN_DIR"
if [ $BUILD_LUASOCKET ]; then
mkdir -p "$BIN_DIR/clibs/"{mime,socket}
cp "$INSTALL_DIR/lib/lua/5.1/mime/core.dylib" "$BIN_DIR/clibs/mime"
cp "$INSTALL_DIR/lib/lua/5.1/socket/core.dylib" "$BIN_DIR/clibs/socket"
fi
# show a message about successful completion
echo "*** Build has been successfully completed ***"
exit 0

216
build/build-win32.sh Normal file
View File

@@ -0,0 +1,216 @@
#!/bin/bash
# ZBS binary directory
BIN_DIR="$(dirname "$PWD")/bin"
# temporary installation directory for dependencies
INSTALL_DIR="$PWD/deps"
# number of parallel jobs used for building
MAKEFLAGS="-j4"
# flags for manual building with gcc
BUILD_FLAGS="-O2 -shared -s -I $INSTALL_DIR/include -L $INSTALL_DIR/lib"
# paths configuration
WXWIDGETS_BASENAME="wxWidgets"
WXWIDGETS_URL="http://svn.wxwidgets.org/svn/wx/wxWidgets/trunk"
LUA_BASENAME="lua-5.1.5"
LUA_FILENAME="$LUA_BASENAME.tar.gz"
LUA_URL="http://www.lua.org/ftp/$LUA_FILENAME"
WXLUA_BASENAME="wxlua"
WXLUA_URL="https://wxlua.svn.sourceforge.net/svnroot/wxlua/trunk"
LUASOCKET_BASENAME="luasocket-2.0.2"
LUASOCKET_FILENAME="$LUASOCKET_BASENAME.tar.gz"
LUASOCKET_URL="http://files.luaforge.net/releases/luasocket/luasocket/luasocket-2.0.2/$LUASOCKET_FILENAME"
WINAPI_BASENAME="winapi"
WINAPI_URL="https://github.com/stevedonovan/winapi.git"
# exit if the command line is empty
if [ $# -eq 0 ]; then
echo "Usage: $0 LIBRARY..."
exit 0
fi
# iterate through the command line arguments
for ARG in "$@"; do
case $ARG in
wxwidgets)
BUILD_WXWIDGETS=true
;;
lua)
BUILD_LUA=true
;;
wxlua)
BUILD_WXLUA=true
;;
luasocket)
BUILD_LUASOCKET=true
;;
winapi)
BUILD_WINAPI=true
;;
zbstudio)
BUILD_ZBSTUDIO=true
;;
all)
BUILD_WXWIDGETS=true
BUILD_LUA=true
BUILD_WXLUA=true
BUILD_LUASOCKET=true
BUILD_WINAPI=true
BUILD_ZBSTUDIO=true
;;
*)
echo "Error: invalid argument $ARG"
exit 1
;;
esac
done
# check for g++
if [ ! "$(which g++)" ]; then
echo "Error: g++ isn't found. Please install MinGW C++ compiler."
exit 1
fi
# check for cmake
if [ ! "$(which cmake)" ]; then
echo "Error: cmake isn't found. Please install CMake and add it to PATH."
exit 1
fi
# check for svn
if [[ ($BUILD_WXWIDGETS || $BUILD_LUA) && ! "$(which svn)" ]]; then
echo "Error: svn isn't found. Please install console SVN client."
exit 1
fi
# check for git
if [[ $BUILD_WINAPI && ! "$(which git)" ]]; then
echo "Error: git isn't found. Please install console GIT client."
exit 1
fi
# check for wget
if [ ! "$(which wget)" ]; then
# NOTE: can't check the return status since mingw-get always returns 0 even in the case of errors :(
mingw-get install msys-wget
fi
# create the installation directory
mkdir -p "$INSTALL_DIR" || { echo "Error: cannot create directory $INSTALL_DIR"; exit 1; }
# build wxWidgets
if [ $BUILD_WXWIDGETS ]; then
svn co "$WXWIDGETS_URL" "$WXWIDGETS_BASENAME" || { echo "Error: failed to checkout wxWidgets"; exit 1; }
svn revert -R "$WXWIDGETS_BASENAME"
cd "$WXWIDGETS_BASENAME"
./configure --prefix="$INSTALL_DIR" --disable-debug --disable-shared --enable-unicode \
--with-libjpeg=builtin --with-libpng=builtin --with-libtiff=no --with-expat=no \
--with-zlib=builtin --disable-richtext \
CFLAGS="-Os -fno-keep-inline-dllexport" CXXFLAGS="-Os -fno-keep-inline-dllexport"
make $MAKEFLAGS || { echo "Error: failed to build wxWidgets"; exit 1; }
make install
cd ..
rm -rf "$WXWIDGETS_BASENAME"
fi
# build Lua
if [ $BUILD_LUA ]; then
wget -c "$LUA_URL" -O "$LUA_FILENAME" || { echo "Error: failed to download Lua"; exit 1; }
tar -xzf "$LUA_FILENAME"
cd "$LUA_BASENAME"
make mingw || { echo "Error: failed to build Lua"; exit 1; }
make install INSTALL_TOP="$INSTALL_DIR"
cp src/lua51.dll "$INSTALL_DIR/lib"
[ -f "$INSTALL_DIR/lib/lua51.dll" ] || { echo "Error: lua51.dll isn't found"; exit 1; }
cd ..
rm -rf "$LUA_FILENAME" "$LUA_BASENAME"
fi
# build wxLua
if [ $BUILD_WXLUA ]; then
svn co "$WXLUA_URL" "$WXLUA_BASENAME" || { echo "Error: failed to checkout wxLua"; exit 1; }
svn revert -R "$WXLUA_BASENAME"
cd "$WXLUA_BASENAME/wxLua"
sed -i 's|:-/\(.\)/|:-\1:/|' "$INSTALL_DIR/bin/wx-config"
sed -i 's/execute_process(COMMAND/& sh/' build/CMakewxAppLib.cmake modules/wxstedit/build/CMakewxAppLib.cmake
# the following patches wxlua source to fix live coding support in wxlua apps
# http://www.mail-archive.com/wxlua-users@lists.sourceforge.net/msg03225.html
sed -i 's/\(m_wxlState = wxLuaState(wxlState.GetLuaState(), wxLUASTATE_GETSTATE|wxLUASTATE_ROOTSTATE);\)/\/\/ removed by ZBS build process \/\/ \1/' modules/wxlua/wxlcallb.cpp
cp "$INSTALL_DIR/lib/libwxscintilla-2.9.a" "$INSTALL_DIR/lib/libwx_mswu_scintilla-2.9.a"
echo "set_target_properties(wxLuaModule PROPERTIES LINK_FLAGS -static)" >> modules/luamodule/CMakeLists.txt
cmake -G "MSYS Makefiles" -DBUILD_INSTALL_PREFIX="$INSTALL_DIR" -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SHARED_LIBS=FALSE \
-DwxWidgets_CONFIG_EXECUTABLE="$INSTALL_DIR/bin/wx-config" \
-DwxWidgets_COMPONENTS="stc;html;aui;adv;core;net;base" \
-DwxLuaBind_COMPONENTS="stc;html;aui;adv;core;net;base" -DwxLua_LUA_LIBRARY_USE_BUILTIN=FALSE \
-DwxLua_LUA_INCLUDE_DIR="$INSTALL_DIR/include" -DwxLua_LUA_LIBRARY="$INSTALL_DIR/lib/lua51.dll" .
(cd modules/luamodule; make $MAKEFLAGS) || { echo "Error: failed to build wxLua"; exit 1; }
(cd modules/luamodule; make install/strip)
[ -f "$INSTALL_DIR/bin/libwx.dll" ] || { echo "Error: libwx.dll isn't found"; exit 1; }
cd ../..
rm -rf "$WXLUA_BASENAME"
fi
# build LuaSocket
if [ $BUILD_LUASOCKET ]; then
wget -c "$LUASOCKET_URL" -O "$LUASOCKET_FILENAME" || { echo "Error: failed to download LuaSocket"; exit 1; }
tar -xzf "$LUASOCKET_FILENAME"
cd "$LUASOCKET_BASENAME"
mkdir -p "$INSTALL_DIR/lib/lua/5.1/"{mime,socket}
gcc $BUILD_FLAGS -o "$INSTALL_DIR/lib/lua/5.1/mime/core.dll" src/mime.c -llua51 \
|| { echo "Error: failed to build LuaSocket"; exit 1; }
gcc $BUILD_FLAGS -o "$INSTALL_DIR/lib/lua/5.1/socket/core.dll" \
src/{auxiliar.c,buffer.c,except.c,inet.c,io.c,luasocket.c,options.c,select.c,tcp.c,timeout.c,udp.c,wsocket.c} -lwsock32 -llua51 \
|| { echo "Error: failed to build LuaSocket"; exit 1; }
mkdir -p "$INSTALL_DIR/share/lua/5.1/socket"
cp src/{ftp.lua,http.lua,smtp.lua,tp.lua,url.lua} "$INSTALL_DIR/share/lua/5.1/socket"
cp src/{ltn12.lua,mime.lua,socket.lua} "$INSTALL_DIR/share/lua/5.1"
[ -f "$INSTALL_DIR/lib/lua/5.1/mime/core.dll" ] || { echo "Error: mime/core.dll isn't found"; exit 1; }
[ -f "$INSTALL_DIR/lib/lua/5.1/socket/core.dll" ] || { echo "Error: socket/core.dll isn't found"; exit 1; }
cd ..
rm -rf "$LUASOCKET_FILENAME" "$LUASOCKET_BASENAME"
fi
# build winapi
if [ $BUILD_WINAPI ]; then
git clone "$WINAPI_URL" "$WINAPI_BASENAME"
cd "$WINAPI_BASENAME"
gcc $BUILD_FLAGS -DPSAPI_VERSION=1 -o "$INSTALL_DIR/lib/lua/5.1/winapi.dll" winapi.c wutils.c -lpsapi -lmpr -llua51 \
|| { echo "Error: failed to build winapi"; exit 1; }
[ -f "$INSTALL_DIR/lib/lua/5.1/winapi.dll" ] || { echo "Error: winapi.dll isn't found"; exit 1; }
cd ..
rm -rf "$WINAPI_BASENAME"
fi
# build ZBS launcher
if [ $BUILD_ZBSTUDIO ]; then
windres ../zbstudio/res/zbstudio.rc zbstudio.rc.o
gcc -O2 -s -mwindows -o ../zbstudio.exe win32_starter.c zbstudio.rc.o
rm zbstudio.rc.o
[ -f ../zbstudio.exe ] || { echo "Error: zbstudio.exe isn't found"; exit 1; }
fi
# now copy the compiled dependencies to ZBS binary directory
mkdir -p "$BIN_DIR" || { echo "Error: cannot create directory $BIN_DIR"; exit 1; }
[ $BUILD_LUA ] && cp "$INSTALL_DIR/bin/lua.exe" "$INSTALL_DIR/lib/lua51.dll" "$BIN_DIR"
[ $BUILD_WXLUA ] && cp "$INSTALL_DIR/bin/libwx.dll" "$BIN_DIR/wx.dll"
[ $BUILD_WINAPI ] && cp "$INSTALL_DIR/lib/lua/5.1/winapi.dll" "$BIN_DIR"
if [ $BUILD_LUASOCKET ]; then
mkdir -p "$BIN_DIR/clibs/"{mime,socket}
cp "$INSTALL_DIR/lib/lua/5.1/mime/core.dll" "$BIN_DIR/clibs/mime"
cp "$INSTALL_DIR/lib/lua/5.1/socket/core.dll" "$BIN_DIR/clibs/socket"
fi
# To build lua5.1.dll proxy:
# (1) get mkforwardlib-gcc.lua from http://lua-users.org/wiki/LuaProxyDllThree
# (2) run it as "lua mkforwardlib-gcc.lua lua51 lua5.1 X86"
# show a message about successful completion
echo "*** Build has been successfully completed ***"
exit 0

View File

@@ -1,10 +0,0 @@
#!/bin/bash
echo "Installing wxlua modules from ZeroBrane Studio repository..."
sudo add-apt-repository ppa:zerobranestudio/zerobranestudio
sudo apt-get update
sudo apt-get install wxlua28
# To remove wxlua and required packages use:
# sudo apt-get purge wxlua28
# sudo apt-get autoremove

View File

@@ -19,10 +19,21 @@ require "wx"
function FileSysGet(dir,spec)
local content = {}
local browse = wx.wxFileSystem()
local cwd = wx.wxGetCwd()
if not wx.wxFileName(dir):DirExists() then return content end
local f = browse:FindFirst(dir,spec)
while #f>0 do
table.insert(content,(f:gsub("^file:",""))) -- drop file: protocol (wx2.9+)
if f:match("^file:") then -- remove file: protocol (wx2.9+)
f = f:gsub(iswindows and "^file:/?" or "^file:","")
:gsub('%%(%x%x)', function(n) return string.char(tonumber(n, 16)) end)
end
-- wx2.9+ return absolute path here instead of expected relative; fix it
if wx.wxIsAbsolutePath(f) then
local relative = wx.wxFileName(f)
relative:MakeRelativeTo(cwd)
f = relative:GetFullPath()
end
table.insert(content, f)
f = browse:FindNext()
end
return content

View File

@@ -164,7 +164,7 @@ int main (int argc, char *argv[])
SetDllDirectory(".\\bin\\");
hinstLib = LoadLibrary("lua5.1.dll");
hinstLib = LoadLibrary("lua51.dll");
if (hinstLib != NULL)
{
luaL_newstate = (voidfunc*) GetProcAddress(hinstLib, "luaL_newstate");
@@ -214,7 +214,7 @@ int main (int argc, char *argv[])
MB_OK|MB_ICONERROR);
} else {
MessageBox(NULL,
TEXT("Could not load all functions that are supposed to be located in the lua5.1.dll\n"
TEXT("Could not load all functions that are supposed to be located in the lua51.dll\n"
"This is not supposed to be happening..."),
TEXT("Failed to start editor"),
MB_OK|MB_ICONERROR);
@@ -224,7 +224,7 @@ int main (int argc, char *argv[])
FreeLibrary(hinstLib);
} else {
MessageBox(NULL,
TEXT("The lua5.1.dll could not be found or loaded, please check the working directory of the application.\n"),
TEXT("The lua51.dll could not be found or loaded, please check the working directory of the application.\n"),
TEXT("Failed to initialize editor"),
MB_OK|MB_ICONERROR);
}

View File

@@ -1,4 +1,5 @@
return {
[0] = function(c) return c == 1 and 1 or 2 end, -- plural
["traced %d instruction"] = {"traced %d instruction", "traced %d instructions"}, -- src\editor\debugger.lua
["%d instance"] = {"%d instance", "%d instances"}, -- src\editor\findreplace.lua
}

View File

@@ -6,10 +6,11 @@ return {
["&About"] = "&Acerca de...", -- src\editor\menu_help.lua
["&Add Watch"] = "Añadir observación", -- src\editor\debugger.lua
["&Break"] = "Ruptura", -- src\editor\menu_project.lua
["&Close Page"] = "Cerrar página", -- src\editor\menu_file.lua
["&Close Page"] = "Cerrar página", -- src\editor\menu_file.lua, src\editor\gui.lua
["&Compile"] = "Compilar", -- src\editor\menu_project.lua
["&Copy"] = "Copiar", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&Default Layout"] = "Diseño por defecto", -- src\editor\menu_view.lua
["&Delete Watch"] = "Eliminar observación", -- src\editor\debugger.lua
["&Edit Watch"] = "Editar observación", -- src\editor\debugger.lua
["&Edit"] = "Editar", -- src\editor\menu_edit.lua
["&File"] = "Archivo", -- src\editor\menu_file.lua
@@ -23,10 +24,9 @@ return {
["&Paste"] = "Pegar", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&Project"] = "Proyecto", -- src\editor\menu_project.lua, src\editor\inspect.lua
["&Redo"] = "Rehacer", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&Remove Watch"] = "Eliminar observación", -- src\editor\debugger.lua
["&Replace"] = "Remplazar", -- src\editor\menu_search.lua
["&Run"] = "Ejecutar", -- src\editor\menu_project.lua
["&Save"] = "Guardar", -- src\editor\menu_file.lua
["&Save"] = "Guardar", -- src\editor\menu_file.lua, src\editor\gui.lua
["&Search"] = "Buscar", -- src\editor\menu_search.lua
["&Sort"] = "Clasificar", -- src\editor\menu_search.lua
["&Stack Window"] = "Ventana de la pila de ejecución", -- src\editor\menu_view.lua
@@ -34,8 +34,7 @@ return {
["&Undo"] = "Deshacer", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&View"] = "Ver", -- src\editor\menu_view.lua
["&Watch Window"] = "Ventana de observaciones", -- src\editor\menu_view.lua
["&Watches"] = "Observaciones", -- src\editor\debugger.lua
["About ZeroBrane Studio"] = "Acerca de ZeroBrane Studio", -- src\editor\menu_help.lua
["About %s"] = "Acerca de %s", -- src\editor\menu_help.lua
["Add Watch Expression"] = "Añadir expresión de observación", -- src\editor\editor.lua
["Add to Scratchpad"] = "Añadir al borrador", -- src\editor\editor.lua
["All files"] = "Todos los archivos", -- src\editor\commands.lua
@@ -53,9 +52,12 @@ return {
["Can't run the entry point script ('%s')."] = "No se pude ejecutar el punto de entrada del script (%s).", -- src\editor\debugger.lua
["Can't start debugging session due to internal error '%s'."] = "No se puede iniciar la sesión de depuración debido a un error interno '%s'.'", -- src\editor\debugger.lua
["Can't start debugging without an opened file or with the current file not being saved ('%s')."] = "No se puede iniciar la depuración sin abrir un archivo o si no ha sido guardado ('%s').", -- src\editor\debugger.lua
["Choose ..."] = nil, -- src\editor\menu_project.lua
["Choose a project directory"] = "Elegir el directorio del proyecto", -- src\editor\menu_project.lua
["Clear &Dynamic Words"] = "Limpiar las palabras dinámicas", -- src\editor\menu_edit.lua
["Clear the output window before compiling or debugging"] = "Limpiar la ventana de salida antes de compilar o depurar", -- src\editor\menu_project.lua
["Close &Other Pages"] = nil, -- src\editor\gui.lua
["Close A&ll Pages"] = nil, -- src\editor\gui.lua
["Close the current editor window"] = "Cerrar la ventana actual del editor", -- src\editor\menu_file.lua
["Co&ntinue"] = "Continuar", -- src\editor\menu_project.lua
["Col: %d"] = "Col: %d", -- src\editor\editor.lua
@@ -65,23 +67,25 @@ return {
["Compile the current file"] = "Compilar el archivo actual", -- src\editor\menu_project.lua
["Complete &Identifier"] = "Completar identificador", -- src\editor\menu_edit.lua
["Complete the current identifier"] = "Completar el actual identificador", -- src\editor\menu_edit.lua
["Copy selected text to clipboard"] = "Copiar el texto seleccionado al portapapeles", -- src\editor\menu_edit.lua, src\editor\gui.lua
["Copy selected text to clipboard"] = "Copiar el texto seleccionado al portapapeles", -- src\editor\menu_edit.lua
["Couldn't activate file '%s' for debugging; continuing without it."] = "No se pudo activar el archivo '%s' para la depuración; continuar sin él.", -- src\editor\debugger.lua
["Create an empty document"] = "Crear un documento en blanco", -- src\editor\menu_file.lua, src\editor\gui.lua
["Cu&t"] = "Cortar", -- src\editor\editor.lua, src\editor\menu_edit.lua
["Cut selected text to clipboard"] = "Cortar el texto selecionado al portapapeles", -- src\editor\menu_edit.lua, src\editor\gui.lua
["Cut selected text to clipboard"] = "Cortar el texto selecionado al portapapeles", -- src\editor\menu_edit.lua
["Debugger server started at %s:%d."] = "Servidor de depuración inciado en %s:%s", -- src\editor\debugger.lua
["Debugging session completed (%s)."] = "Sesión de depuración completada (%s).", -- src\editor\debugger.lua
["Debugging session started in '%s'."] = "Sesión de depuración iniciada en '%s'.", -- src\editor\debugger.lua
["Debugging suspended at %s:%s (couldn't activate the file)."] = nil, -- src\editor\debugger.lua
["Do you want to reload it?"] = "¿Quieres recargarlo?", -- src\editor\editor.lua
["Do you want to save the changes to '%s'?"] = "¿Quieres guardar los cambios en '%s'?", -- src\editor\commands.lua
["E&xit"] = "Salir", -- src\editor\menu_file.lua
["Enter Lua code and press Enter to run it."] = "Introduce código Lua y pulsa <Entrer> para ejecutarlo.", -- src\editor\shellbox.lua
["Enter line number"] = "Introduce número de línea", -- src\editor\menu_search.lua
["Error while loading API file: %s"] = "Error mientras se cargaba el archivo de API: %s", -- src\editor\autocomplete.lua
["Error while loading configuration file: %s"] = nil, -- src\editor\style.lua
["Error while processing API file: %s"] = "Error mientras se procesaba el archivo de API: %s", -- src\editor\autocomplete.lua
["Error while processing configuration file: %s"] = nil, -- src\editor\style.lua
["Error"] = "Error", -- src\editor\commands.lua
["Evaluate &Watches"] = "Evaluar las observaciones", -- src\editor\debugger.lua
["Evaluate in Console"] = "Evaluar en consola", -- src\editor\editor.lua
["Execute the current project/file and keep updating the code to see immediate results"] = "Ejecutar el proyecto/archivo actual y manteniendo actualizado el código para ver resultados en tiempo real", -- src\editor\menu_project.lua
["Execute the current project/file"] = "Ejecutar el proyecto/archivo actual", -- src\editor\menu_project.lua
@@ -113,12 +117,14 @@ return {
["Ln: %d"] = "Ln: %d", -- src\editor\editor.lua
["Local console"] = "Consola local", -- src\editor\shellbox.lua, src\editor\gui.lua
["Lua &Interpreter"] = "Intérprete Lua", -- src\editor\menu_project.lua
["Mapped remote request for '%s' to '%s'."] = nil, -- src\editor\debugger.lua
["Mixed end-of-line encodings detected."] = nil, -- src\editor\commands.lua
["OVR"] = "OVR", -- src\editor\editor.lua
["Open an existing document"] = "Abrir un documento existente", -- src\editor\menu_file.lua, src\editor\gui.lua
["Open file"] = "Abrir archivo", -- src\editor\commands.lua
["Output (running)"] = "Salida (en ejecución)", -- src\editor\output.lua
["Output"] = "Salida", -- src\editor\output.lua, src\editor\settings.lua, src\editor\gui.lua
["Paste text from the clipboard"] = "Pegar texto desde el portapapeles", -- src\editor\menu_edit.lua, src\editor\gui.lua
["Paste text from the clipboard"] = "Pegar texto desde el portapapeles", -- src\editor\menu_edit.lua
["Prepend '=' to show complex values on multiple lines."] = "Antepón '=' para ver valores complejos en líneas múltiples", -- src\editor\shellbox.lua
["Press cancel to abort."] = "Presiona cancelar para abortar.", -- src\editor\commands.lua
["Program '%s' started in '%s' (pid: %d)."] = "Programa '%s' iniciado en '%s' (pid: %d).", -- src\editor\output.lua
@@ -127,21 +133,23 @@ return {
["Program starting as '%s'."] = "Programa iniciado como '%s'.", -- src\editor\output.lua
["Program stopped (pid: %d)."] = "Programa parado (pid: %d).", -- src\editor\debugger.lua
["Program unable to run as '%s'."] = "No se puede ejecutar el programa como '%s'.", -- src\editor\output.lua
["Project Directory"] = nil, -- src\editor\menu_project.lua
["Project"] = "Proyecto", -- src\editor\settings.lua, src\editor\gui.lua
["Project/&FileTree Window"] = "Ventana de proyecto/árbol de archivos", -- src\editor\menu_view.lua
["R/O"] = "R/O", -- src\editor\editor.lua
["R/W"] = "R/W", -- src\editor\editor.lua
["Re&place In Files"] = "Remplazar en archivos", -- src\editor\menu_search.lua
["Recent Files"] = "Archivos recientes", -- src\editor\menu_file.lua
["Redo last edit undone"] = "Rehacer la última edición deshecha", -- src\editor\menu_edit.lua, src\editor\gui.lua
["Redo last edit undone"] = "Rehacer la última edición deshecha", -- src\editor\menu_edit.lua
["Refused a request to start a new debugging session as there is one in progress already."] = "No se pudo lanzar una nueva sesión de depuración porque ya hay una en curso.", -- src\editor\debugger.lua
["Remote console"] = "Consola remota", -- src\editor\shellbox.lua
["Replaced an invalid UTF8 character with %s."] = nil, -- src\editor\commands.lua
["Reset to default layout"] = "Restablecer el diseño por defecto", -- src\editor\menu_view.lua
["Resets the dynamic word list for autocompletion"] = "Restablecer la lista dinámica de palabras para autocompletado", -- src\editor\menu_edit.lua
["Run as Scratchpad"] = "Ejecutar como borrador", -- src\editor\menu_project.lua
["S&top Debugging"] = "Parar depuración", -- src\editor\menu_project.lua
["S&top Process"] = "Parar proceso", -- src\editor\menu_project.lua
["Save &As..."] = "Guardar como...", -- src\editor\menu_file.lua
["Save &As..."] = "Guardar como...", -- src\editor\menu_file.lua, src\editor\gui.lua
["Save A&ll"] = "Guardar todo", -- src\editor\menu_file.lua
["Save Changes?"] = "¿Guardar cambios?", -- src\editor\commands.lua
["Save all open documents"] = "Guardar todos los documentos abiertos", -- src\editor\menu_file.lua, src\editor\gui.lua
@@ -153,12 +161,14 @@ return {
["Scratchpad error"] = "Error en el borrador", -- src\editor\debugger.lua
["Select &All"] = "Seleccionar todo", -- src\editor\editor.lua, src\editor\menu_edit.lua
["Select all text in the editor"] = "Seleccionar todo el texto en el editor", -- src\editor\menu_edit.lua
["Set project directory from current file"] = "Establecer el directorio del proyecto del archivo actual", -- src\editor\gui.lua
["Set From Current File"] = nil, -- src\editor\menu_project.lua
["Set project directory from current file"] = "Establecer el directorio del proyecto del archivo actual", -- src\editor\menu_project.lua, src\editor\gui.lua
["Set the interpreter to be used"] = "Establecer el intérprete a ser usado", -- src\editor\menu_project.lua
["Set the project directory to be used"] = nil, -- src\editor\menu_project.lua
["Show &Tooltip"] = "Ver tooltip", -- src\editor\menu_edit.lua
["Show tooltip for current position; place cursor after opening bracket of function"] = "Ver tooltip para la posición actual; posicionar el cursor después de abrir el paréntisis de los argumentos de la función", -- src\editor\menu_edit.lua
["Sort selected lines"] = "Clasificar las líneas seleccionadas", -- src\editor\menu_search.lua
["Stack Window"] = "Ventana de la pila de ejecución", -- src\editor\debugger.lua
["Stack"] = nil, -- src\editor\debugger.lua
["Start &Debugging"] = "Comenzar depuración", -- src\editor\menu_project.lua
["Start debugging"] = "Comenzar depuración", -- src\editor\menu_project.lua, src\editor\gui.lua
["Step &Into"] = "Paso dentro", -- src\editor\menu_project.lua
@@ -177,7 +187,9 @@ return {
["Unable to load file '%s'."] = "No se pudo cargar el archivo '%s'.", -- src\editor\commands.lua
["Unable to save file '%s': %s"] = "No se pudo guardar el archivo '%s': %s", -- src\editor\commands.lua
["Unable to stop program (pid: %d), code %d."] = "No se puedo parar el programa (pid: %d), código %d.", -- src\editor\debugger.lua
["Undo last edit"] = "Deshacer la última edición", -- src\editor\menu_edit.lua, src\editor\gui.lua
["Undo last edit"] = "Deshacer la última edición", -- src\editor\menu_edit.lua
["Use '%s' to see full description."] = nil, -- src\editor\editor.lua
["Use '%s' to show line endings and '%s' to convert them."] = nil, -- src\editor\commands.lua
["Use 'clear' to clear the shell output and the history."] = "Usa 'clear' para limpiar la consola de salida y el historial.", -- src\editor\shellbox.lua
["Use Shift-Enter for multiline code."] = "Usa <Shift-Enter> para código multilínea.", -- src\editor\shellbox.lua
["Value"] = "Valor", -- src\editor\debugger.lua
@@ -185,7 +197,7 @@ return {
["View the project/filetree window"] = "Ver la ventana de proyecto/árbol de archivos", -- src\editor\menu_view.lua
["View the stack window"] = "Ver la ventana de la pila de ejecución", -- src\editor\menu_view.lua, src\editor\gui.lua
["View the watch window"] = "Ver la ventana de observación", -- src\editor\menu_view.lua, src\editor\gui.lua
["Watch Window"] = "Ventana de observación", -- src\editor\debugger.lua
["Watch"] = nil, -- src\editor\debugger.lua
["Welcome to the interactive Lua interpreter."] = "Bienvenido al intérprete interactico de Lua.", -- src\editor\shellbox.lua
["You must save the program first."] = "Debes guardar el programa primero", -- src\editor\commands.lua
["on line %d"] = "en la línea %d", -- src\editor\debugger.lua, src\editor\commands.lua

View File

@@ -7,6 +7,7 @@ return {
["&Compile"] = "&Compiler", -- src\editor\menu_project.lua
["&Copy"] = "Co&pier", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&Default Layout"] = "Affichage par &défaut", -- src\editor\menu_view.lua
["&Delete Watch"] = "&Supprimer une expression", -- src\editor\debugger.lua
["&Edit Watch"] = "&Modifier une expression", -- src\editor\debugger.lua
["&Edit"] = "É&dition", -- src\editor\menu_edit.lua
["&File"] = "&Fichier", -- src\editor\menu_file.lua
@@ -20,7 +21,6 @@ return {
["&Paste"] = "Co&ller", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&Project"] = "&Projet", -- src\editor\menu_project.lua, src\editor\inspect.lua
["&Redo"] = "&Rétablir", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&Remove Watch"] = "&Supprimer une expression", -- src\editor\debugger.lua
["&Replace"] = "Re&mplacer...", -- src\editor\menu_search.lua
["&Run"] = "&Exécuter", -- src\editor\menu_project.lua
["&Save"] = "&Enregistrer", -- src\editor\menu_file.lua, src\editor\gui.lua
@@ -31,8 +31,7 @@ return {
["&Undo"] = "&Annuler", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&View"] = "&Affichage", -- src\editor\menu_view.lua
["&Watch Window"] = "&Expressions espionnes", -- src\editor\menu_view.lua
["&Watches"] = "&Expressions", -- src\editor\debugger.lua
["About ZeroBrane Studio"] = "À propos de ZeroBrane Studio", -- src\editor\menu_help.lua
["About %s"] = "À propos de %s", -- src\editor\menu_help.lua
["Add Watch Expression"] = "Ajouter une expression", -- src\editor\editor.lua
["Add to Scratchpad"] = "Ajouter au brouillon", -- src\editor\editor.lua
["All files"] = "Tous les fichiers", -- src\editor\commands.lua
@@ -60,16 +59,16 @@ return {
["Co&ntinue"] = "Co&ntinuer", -- src\editor\menu_project.lua
["Col: %d"] = "Col : %d", -- src\editor\editor.lua
["Comment or uncomment current or selected lines"] = "Commenter ou décommenter les lignes courantes ou sélectionnées", -- src\editor\menu_edit.lua
["Compilation error"] = "Erreur de commpilation", -- src\editor\debugger.lua, src\editor\commands.lua
["Compilation error"] = "Erreur de compilation", -- src\editor\debugger.lua, src\editor\commands.lua
["Compilation successful; %.0f%% success rate (%d/%d)."] = "Compilation réussie ; taux de succès : %.0f%% (%d/%d).", -- src\editor\commands.lua
["Compile the current file"] = "Сompiler le fichier courant", -- src\editor\menu_project.lua
["Complete &Identifier"] = "Compléter l'&identifiant", -- src\editor\menu_edit.lua
["Complete the current identifier"] = "Compléter l'identifiant courant", -- src\editor\menu_edit.lua
["Copy selected text to clipboard"] = "Copier le texte sélectionné dans le presse-papiers", -- src\editor\menu_edit.lua, src\editor\gui.lua
["Copy selected text to clipboard"] = "Copier le texte sélectionné dans le presse-papiers", -- src\editor\menu_edit.lua
["Couldn't activate file '%s' for debugging; continuing without it."] = "Impossible d'activer le fichier '%s' pour débogage ; poursuite du processus en ignorant le fichier.", -- src\editor\debugger.lua
["Create an empty document"] = "Créer un document vierge", -- src\editor\menu_file.lua, src\editor\gui.lua
["Cu&t"] = "&Couper", -- src\editor\editor.lua, src\editor\menu_edit.lua
["Cut selected text to clipboard"] = "Couper le texte selectionné et copier dans le presse-papiers", -- src\editor\menu_edit.lua, src\editor\gui.lua
["Cut selected text to clipboard"] = "Couper le texte sélectionné et copier dans le presse-papiers", -- src\editor\menu_edit.lua
["Debugger server started at %s:%d."] = "Serveur de débogage démarré à %s:%d.", -- src\editor\debugger.lua
["Debugging session completed (%s)."] = "Session de débogage terminée (%s).", -- src\editor\debugger.lua
["Debugging session started in '%s'."] = "Session de débogage démarrée dans '%s'.", -- src\editor\debugger.lua
@@ -84,8 +83,7 @@ return {
["Error while processing API file: %s"] = "Erreur lors de la lecture du fichier d'API : %s", -- src\editor\autocomplete.lua
["Error while processing configuration file: %s"] = "Erreur lors de la lecture du fichier de configuration : %s", -- src\editor\style.lua
["Error"] = "Erreur", -- src\editor\commands.lua
["Evaluate &Watches"] = "&Evaluer les expressions", -- src\editor\debugger.lua
["Evaluate in Console"] = "Evaluer dans la console", -- src\editor\editor.lua
["Evaluate in Console"] = "Évaluer dans la console", -- src\editor\editor.lua
["Execute the current project/file and keep updating the code to see immediate results"] = "Exécuter le projet/fichier courant en mettant le code à jour afin de voir les résultats en temps réel", -- src\editor\menu_project.lua
["Execute the current project/file"] = "Exécuter le projet/fichier courant", -- src\editor\menu_project.lua
["Execution error"] = "Erreur d'exécution", -- src\editor\debugger.lua
@@ -97,14 +95,14 @@ return {
["File '%s' no longer exists."] = "Le fichier '%s' n'existe plus.", -- src\editor\editor.lua
["File history"] = "Historique de fichier", -- src\editor\menu_file.lua
["Find &In Files"] = "Rec&hercher dans les fichiers...", -- src\editor\menu_search.lua
["Find &Next"] = "Rechercher l'occurence &suivante", -- src\editor\menu_search.lua
["Find &Previous"] = "Rechercher l'occurence &précédente", -- src\editor\menu_search.lua
["Find &Next"] = "Rechercher l'occurrence &suivante", -- src\editor\menu_search.lua
["Find &Previous"] = "Rechercher l'occurrence &précédente", -- src\editor\menu_search.lua
["Find and replace text in files"] = "Rechercher et remplacer le texte dans les fichiers", -- src\editor\menu_search.lua
["Find and replace text"] = "Rechercher et remplacer le texte", -- src\editor\menu_search.lua, src\editor\gui.lua
["Find text in files"] = "Rechercher le texte dans les fichiers", -- src\editor\menu_search.lua
["Find text"] = "Rechercher le texte", -- src\editor\menu_search.lua, src\editor\gui.lua
["Find the earlier text occurence"] = "Recherche l'occurence précédente du texte", -- src\editor\menu_search.lua
["Find the next text occurrence"] = "Recherche l'occurence suivante du texte", -- src\editor\menu_search.lua
["Find the earlier text occurence"] = "Recherche l'occurrence précédente du texte", -- src\editor\menu_search.lua
["Find the next text occurrence"] = "Recherche l'occurrence suivante du texte", -- src\editor\menu_search.lua
["Fold or unfold all code folds"] = "Replier ou déplier tous les blocs de code", -- src\editor\menu_edit.lua
["Found auto-recovery record and restored saved session."] = "Une récupération automatique a été trouvé et la session a été restaurée.", -- src\editor\commands.lua
["Full &Screen"] = "&Plein écran", -- src\editor\menu_view.lua
@@ -116,12 +114,14 @@ return {
["Ln: %d"] = "Lig : %d", -- src\editor\editor.lua
["Local console"] = "Console locale", -- src\editor\shellbox.lua, src\editor\gui.lua
["Lua &Interpreter"] = "Interpréteur L&ua", -- src\editor\menu_project.lua
["Mapped remote request for '%s' to '%s'."] = "La requête distante pour '%s' a été associée à '%s'.", -- src\editor\debugger.lua
["Mixed end-of-line encodings detected."] = "Plusieurs codages de fin de ligne détectés.", -- src\editor\commands.lua
["OVR"] = "OVR", -- src\editor\editor.lua
["Open an existing document"] = "Ouvrir un document existant", -- src\editor\menu_file.lua, src\editor\gui.lua
["Open file"] = "Ouvrir un fichier", -- src\editor\commands.lua
["Output (running)"] = "Sortie (en cours d'exécution)", -- src\editor\output.lua
["Output"] = "Sortie", -- src\editor\output.lua, src\editor\settings.lua, src\editor\gui.lua
["Paste text from the clipboard"] = "Coller le texte depuis le presse-papiers", -- src\editor\menu_edit.lua, src\editor\gui.lua
["Paste text from the clipboard"] = "Coller le texte depuis le presse-papiers", -- src\editor\menu_edit.lua
["Prepend '=' to show complex values on multiple lines."] = "Préfixez par '=' pour afficher les valeurs complexes sur plusieurs lignes.", -- src\editor\shellbox.lua
["Press cancel to abort."] = "Cliquez sur Annuler pour annuler.", -- src\editor\commands.lua
["Program '%s' started in '%s' (pid: %d)."] = "Programme '%s' démarré dans '%s' (pid : %d).", -- src\editor\output.lua
@@ -137,9 +137,10 @@ return {
["R/W"] = "R/W", -- src\editor\editor.lua
["Re&place In Files"] = "Remp&lacer dans les fichiers...", -- src\editor\menu_search.lua
["Recent Files"] = "Fichiers récents", -- src\editor\menu_file.lua
["Redo last edit undone"] = "Rétablir la dernière modification", -- src\editor\menu_edit.lua, src\editor\gui.lua
["Redo last edit undone"] = "Rétablir la dernière modification", -- src\editor\menu_edit.lua
["Refused a request to start a new debugging session as there is one in progress already."] = "Une requête de lancement de débogage a été refusée car une session de débogage est déjà en cours.", -- src\editor\debugger.lua
["Remote console"] = "Console à distance", -- src\editor\shellbox.lua
["Replaced an invalid UTF8 character with %s."] = "Un caractère UTF8 invalide a été remplacé par %s.", -- src\editor\commands.lua
["Reset to default layout"] = "Restaurer l'affichage par défaut", -- src\editor\menu_view.lua
["Resets the dynamic word list for autocompletion"] = "Réinitialiser la liste des mots dynamiques pour l'auto-complétion", -- src\editor\menu_edit.lua
["Run as Scratchpad"] = "Exécuter comme brouillon", -- src\editor\menu_project.lua
@@ -164,7 +165,7 @@ return {
["Show &Tooltip"] = "Afficher l'info-&bulle", -- src\editor\menu_edit.lua
["Show tooltip for current position; place cursor after opening bracket of function"] = "Afficher l'info-bulle pour la position actuelle ; placez le curseur après la parenthèse ouvrante de la fonction", -- src\editor\menu_edit.lua
["Sort selected lines"] = "Trier les lignes sélectionnées", -- src\editor\menu_search.lua
["Stack Window"] = "Fenêtre de pile d'éxécution", -- src\editor\debugger.lua
["Stack"] = "Pile d'exécution", -- src\editor\debugger.lua
["Start &Debugging"] = "Lancer le &débogage", -- src\editor\menu_project.lua
["Start debugging"] = "Lancer le débogage", -- src\editor\menu_project.lua, src\editor\gui.lua
["Step &Into"] = "Pas à pas détai&llé", -- src\editor\menu_project.lua
@@ -183,16 +184,17 @@ return {
["Unable to load file '%s'."] = "Impossible de charger le le fichier '%s'.", -- src\editor\commands.lua
["Unable to save file '%s': %s"] = "Impossible d'enregistrer le fichier '%s' : %s", -- src\editor\commands.lua
["Unable to stop program (pid: %d), code %d."] = "Impossible d'arrêter le programme (pid : %d), code %d.", -- src\editor\debugger.lua
["Undo last edit"] = "Annuler la dernière modification", -- src\editor\menu_edit.lua, src\editor\gui.lua
["Undo last edit"] = "Annuler la dernière modification", -- src\editor\menu_edit.lua
["Use '%s' to see full description."] = "Utilisez '%s' pour voir la description complète.", -- src\editor\editor.lua
["Use '%s' to show line endings and '%s' to convert them."] = "Utilisez '%s' pour afficher les fins de ligne et '%s' pour les convertir.", -- src\editor\commands.lua
["Use 'clear' to clear the shell output and the history."] = "Utilisez 'clear' pour effacer la sortie console et l´historique.", -- src\editor\shellbox.lua
["Use Shift-Enter for multiline code."] = "Appuyez sur <Shift-Entrée> pour du code multiligne.", -- src\editor\shellbox.lua
["Value"] = "Valeur", -- src\editor\debugger.lua
["View the output/console window"] = "Afficher la fenêtre de sortie/console", -- src\editor\menu_view.lua
["View the project/filetree window"] = "Afficher la fenêtre d'explorateur de projet", -- src\editor\menu_view.lua
["View the stack window"] = "Afficher la fenêtre de pile d'éxécution", -- src\editor\menu_view.lua, src\editor\gui.lua
["View the stack window"] = "Afficher la fenêtre de pile d'exécution", -- src\editor\menu_view.lua, src\editor\gui.lua
["View the watch window"] = "Afficher la fenêtre d'expressions espionnes", -- src\editor\menu_view.lua, src\editor\gui.lua
["Watch Window"] = "Fenêtre d'expressions espionnes", -- src\editor\debugger.lua
["Watch"] = "Expressions espionnes", -- src\editor\debugger.lua
["Welcome to the interactive Lua interpreter."] = "Bienvenue dans l´interpréteur interactif Lua.", -- src\editor\shellbox.lua
["You must save the program first."] = "Vous devez d'abord enregistrer le programme.", -- src\editor\commands.lua
["on line %d"] = "à la ligne %d", -- src\editor\debugger.lua, src\editor\commands.lua

View File

@@ -3,10 +3,11 @@ return {
["&About"] = "Informazioni", -- src\editor\menu_help.lua
["&Add Watch"] = "&Aggiungi Espressione di Controllo", -- src\editor\debugger.lua
["&Break"] = "Interrompi", -- src\editor\menu_project.lua
["&Close Page"] = "&Chiudi pagina", -- src\editor\menu_file.lua
["&Close Page"] = "&Chiudi pagina", -- src\editor\menu_file.lua, src\editor\gui.lua
["&Compile"] = "&Compila", -- src\editor\menu_project.lua
["&Copy"] = "&Copia", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&Default Layout"] = "Visualizzazione di &Default", -- src\editor\menu_view.lua
["&Delete Watch"] = "Elimina Espressione di Controllo", -- src\editor\debugger.lua
["&Edit Watch"] = "Modifica Espressione di Controllo", -- src\editor\debugger.lua
["&Edit"] = "Modifica", -- src\editor\menu_edit.lua
["&File"] = "File", -- src\editor\menu_file.lua
@@ -20,10 +21,9 @@ return {
["&Paste"] = "Incolla", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&Project"] = "&Progetto", -- src\editor\menu_project.lua, src\editor\inspect.lua
["&Redo"] = "&Ripeti", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&Remove Watch"] = "Elimina Espressione di Controllo", -- src\editor\debugger.lua
["&Replace"] = "Sostituisci", -- src\editor\menu_search.lua
["&Run"] = "Lancia", -- src\editor\menu_project.lua
["&Save"] = "&Salva", -- src\editor\menu_file.lua
["&Save"] = "&Salva", -- src\editor\menu_file.lua, src\editor\gui.lua
["&Search"] = "Ricerca", -- src\editor\menu_search.lua
["&Sort"] = "Ordina", -- src\editor\menu_search.lua
["&Stack Window"] = "Stack di chiamate", -- src\editor\menu_view.lua
@@ -31,8 +31,7 @@ return {
["&Undo"] = "Annulla", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&View"] = "Visualizza", -- src\editor\menu_view.lua
["&Watch Window"] = "Finestra Espressioni di Controllo", -- src\editor\menu_view.lua
["&Watches"] = "Espressioni di Controllo", -- src\editor\debugger.lua
["About ZeroBrane Studio"] = "Informazioni su ZeroBrane Studio", -- src\editor\menu_help.lua
["About %s"] = "Informazioni su %s", -- src\editor\menu_help.lua
["Add Watch Expression"] = "Aggiungi Espressione di Controllo", -- src\editor\editor.lua
["Add to Scratchpad"] = "Aggiungi a Scratchpad ", -- src\editor\editor.lua
["All files"] = "Tutti i files", -- src\editor\commands.lua
@@ -50,9 +49,12 @@ return {
["Can't run the entry point script ('%s')."] = "Impossibile eseguire il punto di ingresos dello script (%s).", -- src\editor\debugger.lua
["Can't start debugging session due to internal error '%s'."] = "Impossibile lanciare la sessione di debug: errore interno '%s'.'", -- src\editor\debugger.lua
["Can't start debugging without an opened file or with the current file not being saved ('%s')."] = "Impossibile lanciare il debug senza aver aperto un file o se il file corrente non è stato salvato ('%s').", -- src\editor\debugger.lua
["Choose ..."] = "Scegli...", -- src\editor\menu_project.lua
["Choose a project directory"] = "Scegli la directory di un progetto", -- src\editor\menu_project.lua
["Clear &Dynamic Words"] = "Elimna le &Dynamic Words", -- src\editor\menu_edit.lua
["Clear the output window before compiling or debugging"] = "Pulisci la finestra di output prima di compilare o lanciare debug", -- src\editor\menu_project.lua
["Close &Other Pages"] = "Chidi le Altre Pagine", -- src\editor\gui.lua
["Close A&ll Pages"] = "Chiudi Tutte le Pagine", -- src\editor\gui.lua
["Close the current editor window"] = "Chiude la finestra dell'edit corrente", -- src\editor\menu_file.lua
["Co&ntinue"] = "Co&ntinua", -- src\editor\menu_project.lua
["Col: %d"] = "Col: %d", -- src\editor\editor.lua
@@ -62,23 +64,25 @@ return {
["Compile the current file"] = "Compila il file corrente", -- src\editor\menu_project.lua
["Complete &Identifier"] = "Completa l'&Identificatore", -- src\editor\menu_edit.lua
["Complete the current identifier"] = "Completa l'identificatore corrente", -- src\editor\menu_edit.lua
["Copy selected text to clipboard"] = "Copia il testo selezionato negli appunti", -- src\editor\menu_edit.lua, src\editor\gui.lua
["Copy selected text to clipboard"] = "Copia il testo selezionato negli appunti", -- src\editor\menu_edit.lua
["Couldn't activate file '%s' for debugging; continuing without it."] = "Impossibile attivare il file '%s' per debug; si prosegue senza.", -- src\editor\debugger.lua
["Create an empty document"] = "Crea un documento vuoto", -- src\editor\menu_file.lua, src\editor\gui.lua
["Cu&t"] = "&Taglia", -- src\editor\editor.lua, src\editor\menu_edit.lua
["Cut selected text to clipboard"] = "Taglia il testo selezionato e mette negli appunti", -- src\editor\menu_edit.lua, src\editor\gui.lua
["Cut selected text to clipboard"] = "Taglia il testo selezionato e mette negli appunti", -- src\editor\menu_edit.lua
["Debugger server started at %s:%d."] = "Server Debugger iniziato %s:%s", -- src\editor\debugger.lua
["Debugging session completed (%s)."] = "Sessione di debug completata (%s).", -- src\editor\debugger.lua
["Debugging session started in '%s'."] = "Sessione di debug iniziata da '%s'.", -- src\editor\debugger.lua
["Debugging suspended at %s:%s (couldn't activate the file)."] = "Debug sospeso a %s:%s (impossibile attivare il file).", -- src\editor\debugger.lua
["Do you want to reload it?"] = "Vuoi ricaricarlo?", -- src\editor\editor.lua
["Do you want to save the changes to '%s'?"] = "Vuoi salvare le modifiche a '%s'?", -- src\editor\commands.lua
["E&xit"] = "Uscita", -- src\editor\menu_file.lua
["Enter Lua code and press Enter to run it."] = "Inserisci codice Lua e premi <Enter> per eseguirlo.", -- src\editor\shellbox.lua
["Enter line number"] = "Inserisci il numero di linea", -- src\editor\menu_search.lua
["Error while loading API file: %s"] = "Errore durante il caricamento del file API: %s", -- src\editor\autocomplete.lua
["Error while loading configuration file: %s"] = "Errore nel caricamento del file di configurazione: %s", -- src\editor\style.lua
["Error while processing API file: %s"] = "Errore durante l'elaborazione del file API: %s", -- src\editor\autocomplete.lua
["Error while processing configuration file: %s"] = "Errore durante l'elaborazione del file di configurazione: %s", -- src\editor\style.lua
["Error"] = "Errore", -- src\editor\commands.lua
["Evaluate &Watches"] = "Elabora Espressioni di Controllo", -- src\editor\debugger.lua
["Evaluate in Console"] = "Elabora in console", -- src\editor\editor.lua
["Execute the current project/file and keep updating the code to see immediate results"] = "Esegue il progetto/file corrente e permette di modificare il codice per vedere i risultati in tempo reale", -- src\editor\menu_project.lua
["Execute the current project/file"] = "Esegue il progetto/file corrente", -- src\editor\menu_project.lua
@@ -110,12 +114,14 @@ return {
["Ln: %d"] = "Ln: %d", -- src\editor\editor.lua
["Local console"] = "Console locale", -- src\editor\shellbox.lua, src\editor\gui.lua
["Lua &Interpreter"] = "&Interprete Lua", -- src\editor\menu_project.lua
["Mapped remote request for '%s' to '%s'."] = "Richiesta remota '%s' mappata su '%s'.", -- src\editor\debugger.lua
["Mixed end-of-line encodings detected."] = "Trovata codifica Fine-Riga mista.", -- src\editor\commands.lua
["OVR"] = "OVR", -- src\editor\editor.lua
["Open an existing document"] = "Apri un documento esistente", -- src\editor\menu_file.lua, src\editor\gui.lua
["Open file"] = "Apri un file", -- src\editor\commands.lua
["Output (running)"] = "Output (in corso d'esecuzione)", -- src\editor\output.lua
["Output"] = "Output", -- src\editor\output.lua, src\editor\settings.lua, src\editor\gui.lua
["Paste text from the clipboard"] = "Incolla testo dagli appunti", -- src\editor\menu_edit.lua, src\editor\gui.lua
["Paste text from the clipboard"] = "Incolla testo dagli appunti", -- src\editor\menu_edit.lua
["Prepend '=' to show complex values on multiple lines."] = "Prefissa '=' per visualizzare valori complessi su piu` righe", -- src\editor\shellbox.lua
["Press cancel to abort."] = "Premi cancel per bloccare.", -- src\editor\commands.lua
["Program '%s' started in '%s' (pid: %d)."] = "Programma '%s' partito da '%s' (pid: %d).", -- src\editor\output.lua
@@ -124,21 +130,23 @@ return {
["Program starting as '%s'."] = "Programma partito da '%s'.", -- src\editor\output.lua
["Program stopped (pid: %d)."] = "Programma fermato (pid: %d).", -- src\editor\debugger.lua
["Program unable to run as '%s'."] = "Il programma non puo' partire '%s'.", -- src\editor\output.lua
["Project Directory"] = "Directory del Progetto", -- src\editor\menu_project.lua
["Project"] = "Progetto", -- src\editor\settings.lua, src\editor\gui.lua
["Project/&FileTree Window"] = "Progetto/Explorer", -- src\editor\menu_view.lua
["R/O"] = "R/O", -- src\editor\editor.lua
["R/W"] = "R/W", -- src\editor\editor.lua
["Re&place In Files"] = "Sostituisci nei files", -- src\editor\menu_search.lua
["Recent Files"] = "Files recenti", -- src\editor\menu_file.lua
["Redo last edit undone"] = "Ripeti l'ultima azione annullata", -- src\editor\menu_edit.lua, src\editor\gui.lua
["Redo last edit undone"] = "Ripeti l'ultima azione annullata", -- src\editor\menu_edit.lua
["Refused a request to start a new debugging session as there is one in progress already."] = "Impossibile aprire una nuova sessione di debug in quanto ne esiste una in corso", -- src\editor\debugger.lua
["Remote console"] = "Console remota", -- src\editor\shellbox.lua
["Replaced an invalid UTF8 character with %s."] = "Sostituito un carattere UTF8 invalido con %s.", -- src\editor\commands.lua
["Reset to default layout"] = "Ritorna al default layout", -- src\editor\menu_view.lua
["Resets the dynamic word list for autocompletion"] = "Azzera la lista di dynamic words per l'autocompletamento", -- src\editor\menu_edit.lua
["Run as Scratchpad"] = "Esegui in Scratchpad (Live coding)", -- src\editor\menu_project.lua
["S&top Debugging"] = "Ferma il debugger", -- src\editor\menu_project.lua
["S&top Process"] = "Ferma il processo", -- src\editor\menu_project.lua
["Save &As..."] = "S&alva con nome...", -- src\editor\menu_file.lua
["Save &As..."] = "S&alva con nome...", -- src\editor\menu_file.lua, src\editor\gui.lua
["Save A&ll"] = "Sa&lva tutto", -- src\editor\menu_file.lua
["Save Changes?"] = "Vuoi salvare le modifiche?", -- src\editor\commands.lua
["Save all open documents"] = "Salva tutti i documenti aperti", -- src\editor\menu_file.lua, src\editor\gui.lua
@@ -150,12 +158,14 @@ return {
["Scratchpad error"] = "Errore durente Scratchpad", -- src\editor\debugger.lua
["Select &All"] = "Selezion&a Tutto", -- src\editor\editor.lua, src\editor\menu_edit.lua
["Select all text in the editor"] = "Seleziona tutto il testo nell'editor", -- src\editor\menu_edit.lua
["Set project directory from current file"] = "Definisci la directory del progeetto dal file corrente", -- src\editor\gui.lua
["Set From Current File"] = "Impostato da file corrente", -- src\editor\menu_project.lua
["Set project directory from current file"] = "Definisci la directory del progeetto dal file corrente", -- src\editor\menu_project.lua, src\editor\gui.lua
["Set the interpreter to be used"] = "Definisci l'interprete da utilizzare", -- src\editor\menu_project.lua
["Set the project directory to be used"] = "Imposta la directory di progetto da usare", -- src\editor\menu_project.lua
["Show &Tooltip"] = "Mos&tra i consgli", -- src\editor\menu_edit.lua
["Show tooltip for current position; place cursor after opening bracket of function"] = "Mostra i consigli per la posizione corrente; muovi il cursore dopo la parentesi o la funzione", -- src\editor\menu_edit.lua
["Sort selected lines"] = "Ordina le righe selezionate", -- src\editor\menu_search.lua
["Stack Window"] = "Finestra Stack", -- src\editor\debugger.lua
["Stack"] = "Stack", -- src\editor\debugger.lua
["Start &Debugging"] = "Inizia il &Debug", -- src\editor\menu_project.lua
["Start debugging"] = "Inizia il Debug", -- src\editor\menu_project.lua, src\editor\gui.lua
["Step &Into"] = "Step &Into", -- src\editor\menu_project.lua
@@ -174,7 +184,9 @@ return {
["Unable to load file '%s'."] = "Impossibile aprire il file '%s'.", -- src\editor\commands.lua
["Unable to save file '%s': %s"] = "Impossibile salvare il file '%s': %s", -- src\editor\commands.lua
["Unable to stop program (pid: %d), code %d."] = "Impossibile fermare il programma (pid: %d), code %d.", -- src\editor\debugger.lua
["Undo last edit"] = "Annulla l'ultima azione di edit", -- src\editor\menu_edit.lua, src\editor\gui.lua
["Undo last edit"] = "Annulla l'ultima azione di edit", -- src\editor\menu_edit.lua
["Use '%s' to see full description."] = "Utilizza '%s' per vedere la descrizione completa.", -- src\editor\editor.lua
["Use '%s' to show line endings and '%s' to convert them."] = "Utilizza '%s' per vedere la fine della riga e '%s' per convertirli.", -- src\editor\commands.lua
["Use 'clear' to clear the shell output and the history."] = "Utilizza 'clear' per pulire l`output e lo storico.", -- src\editor\shellbox.lua
["Use Shift-Enter for multiline code."] = "Premi <Shift-Invio> per inserire piu` righe di codice.", -- src\editor\shellbox.lua
["Value"] = "Valore", -- src\editor\debugger.lua
@@ -182,9 +194,9 @@ return {
["View the project/filetree window"] = "Mostra la finestra di progetto/explorer", -- src\editor\menu_view.lua
["View the stack window"] = "Mostra la finestra dello Stack", -- src\editor\menu_view.lua, src\editor\gui.lua
["View the watch window"] = "Mostra la finestra delle Espressioni di Controllo", -- src\editor\menu_view.lua, src\editor\gui.lua
["Watch Window"] = "Finestra Espressioni di Controllo", -- src\editor\debugger.lua
["Watch"] = "Watch", -- src\editor\debugger.lua
["Welcome to the interactive Lua interpreter."] = "Benvenuti nell`interprete interattivo Lua.", -- src\editor\shellbox.lua
["You must save the program first."] = "Devi prima salvare il programma", -- src\editor\commands.lua
["on line %d"] = "alla linea %d", -- src\editor\debugger.lua, src\editor\commands.lua
["traced %d instruction"] = {"tracciata %d istruzione", "%d istruzioni tracciate"} -- src\editor\debugger.lua
}
}

View File

@@ -1,5 +1,6 @@
return {
[0] = function(c) return (c%10 == 1 and c%100 ~= 11) and 1 or (c%10 >= 2 and c%10 <= 4 and (c%100 < 10 or c%100 >= 20) and 2) or 3 end, -- plural
[0] = function(c) c = (c-9)%100 < 9 and 9 or (c-1)%10 return c == 0 and 1 or c < 4 and 2 or 3 end, -- plural
["%d instance"] = {"%d совпадение", "%d совпадения", "%d совпадений"}, -- src\editor\findreplace.lua
["&About"] = "&О программе", -- src\editor\menu_help.lua
["&Add Watch"] = "&Добавить выражение", -- src\editor\debugger.lua
["&Break"] = "Пр&ервать", -- src\editor\menu_project.lua
@@ -7,9 +8,13 @@ return {
["&Compile"] = "&Компилировать", -- src\editor\menu_project.lua
["&Copy"] = "&Копировать", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&Default Layout"] = "Вид по &умолчанию", -- src\editor\menu_view.lua
["&Delete Watch"] = "&Удалить выражение", -- src\editor\debugger.lua
["&Down"] = "Вниз", -- src\editor\findreplace.lua
["&Edit Watch"] = "&Редактировать выражение", -- src\editor\debugger.lua
["&Edit"] = "&Правка", -- src\editor\menu_edit.lua
["&File"] = "&Файл", -- src\editor\menu_file.lua
["&Find All"] = "Найти все", -- src\editor\findreplace.lua
["&Find Next"] = "Найти далее", -- src\editor\findreplace.lua
["&Find"] = "&Найти", -- src\editor\menu_search.lua
["&Fold/Unfold All"] = "Св&ернуть/развернуть все", -- src\editor\menu_edit.lua
["&Goto Line"] = "&Перейти к строке", -- src\editor\menu_search.lua
@@ -20,20 +25,22 @@ return {
["&Paste"] = "В&ставить", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&Project"] = "Пр&оект", -- src\editor\menu_project.lua, src\editor\inspect.lua
["&Redo"] = "Верну&ть", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&Remove Watch"] = "&Удалить выражение", -- src\editor\debugger.lua
["&Replace"] = "За&менить", -- src\editor\menu_search.lua
["&Replace All"] = "Заменить всe", -- src\editor\findreplace.lua
["&Replace"] = "За&менить", -- src\editor\findreplace.lua, src\editor\menu_search.lua
["&Run"] = "За&пустить", -- src\editor\menu_project.lua
["&Save"] = "&Сохранить", -- src\editor\menu_file.lua, src\editor\gui.lua
["&Search"] = "По&иск", -- src\editor\menu_search.lua
["&Sort"] = "&Cортировать", -- src\editor\menu_search.lua
["&Stack Window"] = "Окно &стека", -- src\editor\menu_view.lua
["&Start Debugger Server"] = "Запустить сервер отла&дки", -- src\editor\menu_project.lua
["&Subdirectories"] = "В папках", -- src\editor\findreplace.lua
["&Undo"] = "&Отменить", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&Up"] = "Вверх", -- src\editor\findreplace.lua
["&View"] = "&Вид", -- src\editor\menu_view.lua
["&Watch Window"] = "Окно &наблюдения", -- src\editor\menu_view.lua
["&Watches"] = "&Выражения", -- src\editor\debugger.lua
["About ZeroBrane Studio"] = "О ZeroBrane Studio", -- src\editor\menu_help.lua
["Add Watch Expression"] = "Добавить в окно наблюдения", -- src\editor\editor.lua
["&Watch Window"] = "Окно &выражений", -- src\editor\menu_view.lua
[".&bak on Replace"] = ".&bak после замены", -- src\editor\findreplace.lua
["About %s"] = "О %s", -- src\editor\menu_help.lua
["Add Watch Expression"] = "Добавить выражение", -- src\editor\editor.lua
["Add to Scratchpad"] = "Добавить в черновик", -- src\editor\editor.lua
["All files"] = "Все файлы", -- src\editor\commands.lua
["Allow external process to start debugging"] = "Разрешить внешнему процессу начать отладку", -- src\editor\menu_project.lua
@@ -50,8 +57,9 @@ return {
["Can't run the entry point script ('%s')."] = "Ошибка выполнения стартового скрипта ('%s').", -- src\editor\debugger.lua
["Can't start debugging session due to internal error '%s'."] = "Невозможно начать отладочную сессию из-за внутренней ошибки '%s'.", -- src\editor\debugger.lua
["Can't start debugging without an opened file or with the current file not being saved ('%s')."] = "Невозможно начать отладку без открытого файла или с несохраненным текущим файлом ('%s').", -- src\editor\debugger.lua
["Cancel"] = "Отмена", -- src\editor\findreplace.lua
["Choose ..."] = "Выбрать ...", -- src\editor\menu_project.lua
["Choose a project directory"] = "Выберите каталог проекта", -- src\editor\menu_project.lua
["Choose a project directory"] = "Выберите папку проекта", -- src\editor\findreplace.lua, src\editor\menu_project.lua
["Clear &Dynamic Words"] = "Очистить &динамические слова", -- src\editor\menu_edit.lua
["Clear the output window before compiling or debugging"] = "Очистить окно вывода перед компиляцией или отладкой", -- src\editor\menu_project.lua
["Close &Other Pages"] = "Закрыть &остальные вкладки", -- src\editor\gui.lua
@@ -65,15 +73,16 @@ return {
["Compile the current file"] = "Скомпилировать текущий файл", -- src\editor\menu_project.lua
["Complete &Identifier"] = "Дополнить &идентификатор", -- src\editor\menu_edit.lua
["Complete the current identifier"] = "Дополнить текущий идентификатор", -- src\editor\menu_edit.lua
["Copy selected text to clipboard"] = "Скопировать выделенный текст в буфер обмена", -- src\editor\menu_edit.lua, src\editor\gui.lua
["Copy selected text to clipboard"] = "Скопировать выделенный текст в буфер обмена", -- src\editor\menu_edit.lua
["Couldn't activate file '%s' for debugging; continuing without it."] = "Невозможно открыть файл '%s' для отладки; выполнение будет продолжено без него.", -- src\editor\debugger.lua
["Create an empty document"] = "Создать новый документ", -- src\editor\menu_file.lua, src\editor\gui.lua
["Cu&t"] = "Вы&резать", -- src\editor\editor.lua, src\editor\menu_edit.lua
["Cut selected text to clipboard"] = "Вырезать выделенный текст в буфер обмена", -- src\editor\menu_edit.lua, src\editor\gui.lua
["Cut selected text to clipboard"] = "Вырезать выделенный текст в буфер обмена", -- src\editor\menu_edit.lua
["Debugger server started at %s:%d."] = "Сервер отладки запущен на %s:%d.", -- src\editor\debugger.lua
["Debugging session completed (%s)."] = "Отладочная сессия завершена (%s).", -- src\editor\debugger.lua
["Debugging session started in '%s'."] = "Отладочная сессия запущена в '%s'.", -- src\editor\debugger.lua
["Debugging suspended at %s:%s (couldn't activate the file)."] = "Отладка остановлена на %s:%s (невозможно открыть файл).", -- src\editor\debugger.lua
["Directory"] = "Папка", -- src\editor\findreplace.lua
["Do you want to reload it?"] = "Перезагрузить его?", -- src\editor\editor.lua
["Do you want to save the changes to '%s'?"] = "Сохранить изменения в '%s'?", -- src\editor\commands.lua
["E&xit"] = "Вы&ход", -- src\editor\menu_file.lua
@@ -84,7 +93,6 @@ return {
["Error while processing API file: %s"] = "Ошибка обработки файла определений API: %s", -- src\editor\autocomplete.lua
["Error while processing configuration file: %s"] = "Ошибка обработки файла конфигурации: %s", -- src\editor\style.lua
["Error"] = "Ошибка", -- src\editor\commands.lua
["Evaluate &Watches"] = "&Вычислить выражения", -- src\editor\debugger.lua
["Evaluate in Console"] = "Выполнить в консоли", -- src\editor\editor.lua
["Execute the current project/file and keep updating the code to see immediate results"] = "Запустить текущий проект/файл и продолжать вносить изменения в код с немедленным выводом результатов", -- src\editor\menu_project.lua
["Execute the current project/file"] = "Запустить текущий проект/файл", -- src\editor\menu_project.lua
@@ -94,34 +102,45 @@ return {
["Expression"] = "Выражение", -- src\editor\debugger.lua
["File '%s' has been modified on disk."] = "Файл '%s' был изменен на диске.", -- src\editor\editor.lua
["File '%s' has more recent timestamp than restored '%s'; please review before saving."] = "Файл '%s' имеет более позднее время модификации, чем восстановленный '%s'; пожалуйста просмотрите его перед сохранением.", -- src\editor\commands.lua
["File '%s' no longer exists."] = "Файл '%s' больше не существует.", -- src\editor\editor.lua
["File '%s' no longer exists."] = "Файл '%s' больше не существует.", -- src\editor\editor.lua, src\editor\menu_file.lua
["File Type"] = "Тип файла", -- src\editor\findreplace.lua
["File history"] = "История файлов", -- src\editor\menu_file.lua
["Find &In Files"] = "Н&айти в файлах", -- src\editor\menu_search.lua
["Find &Next"] = "Найти &далее", -- src\editor\menu_search.lua
["Find &Previous"] = "Найти &ранее", -- src\editor\menu_search.lua
["Find In Files"] = "Найти в файлах", -- src\editor\findreplace.lua
["Find and replace text in files"] = "Найти и заменить текст в файлах", -- src\editor\menu_search.lua
["Find and replace text"] = "Найти и заменить текст", -- src\editor\menu_search.lua, src\editor\gui.lua
["Find text in files"] = "Найти текст в файлах", -- src\editor\menu_search.lua
["Find text"] = "Найти текст", -- src\editor\menu_search.lua, src\editor\gui.lua
["Find the earlier text occurence"] = "Найти предыдущее вхождение текста", -- src\editor\menu_search.lua
["Find the next text occurrence"] = "Найти следующее вхождение текста", -- src\editor\menu_search.lua
["Find"] = "Найти", -- src\editor\findreplace.lua
["Fold or unfold all code folds"] = "Свернуть или развернуть все блоки кода", -- src\editor\menu_edit.lua
["Found auto-recovery record and restored saved session."] = "Найдена запись авто-восстановления и восстановлена сохраненная сессия.", -- src\editor\commands.lua
["Found"] = "Найдено", -- src\editor\findreplace.lua
["Full &Screen"] = "Во весь экр&ан", -- src\editor\menu_view.lua
["Go to a selected line"] = "Перейти к заданной строке", -- src\editor\menu_search.lua
["Goto Line"] = "Перейти к строке", -- src\editor\menu_search.lua
["INS"] = "ВСТ", -- src\editor\editor.lua
["In Files"] = "Установки файлов", -- src\editor\findreplace.lua
["Jump to a function definition..."] = "Перейти к определению функции...", -- src\editor\editor.lua
["Known Files"] = "Файлы Lua", -- src\editor\commands.lua
["Ln: %d"] = "Стр: %d", -- src\editor\editor.lua
["Local console"] = "Локальная консоль", -- src\editor\shellbox.lua, src\editor\gui.lua
["Lua &Interpreter"] = "&Интерпретатор Lua", -- src\editor\menu_project.lua
["Mapped remote request for '%s' to '%s'."] = "Удаленный запрос для '%s' отображен на '%s'.", -- src\editor\debugger.lua
["Match &case"] = "Совпадение регистра", -- src\editor\findreplace.lua
["Match &whole word"] = "Совпадение целого слова", -- src\editor\findreplace.lua
["Mixed end-of-line encodings detected."] = "Обнаружены смешанные символы конца строки.", -- src\editor\commands.lua
["OVR"] = "ЗАМ", -- src\editor\editor.lua
["Open an existing document"] = "Открыть существующий документ", -- src\editor\menu_file.lua, src\editor\gui.lua
["Open file"] = "Открыть файл", -- src\editor\commands.lua
["Options"] = "Установки", -- src\editor\findreplace.lua
["Output (running)"] = "Вывод (запущен)", -- src\editor\output.lua
["Output"] = "Вывод", -- src\editor\output.lua, src\editor\settings.lua, src\editor\gui.lua
["Paste text from the clipboard"] = "Вставить текст из буфера обмена", -- src\editor\menu_edit.lua, src\editor\gui.lua
["Paste text from the clipboard"] = "Вставить текст из буфера обмена", -- src\editor\menu_edit.lua
["Preferences"] = "Настройки", -- src\editor\menu_edit.lua
["Prepend '=' to show complex values on multiple lines."] = "Укажите '=' в начале выражения для отображения сложных значений на нескольких строках.", -- src\editor\shellbox.lua
["Press cancel to abort."] = "Нажмите Отмена для завершения.", -- src\editor\commands.lua
["Program '%s' started in '%s' (pid: %d)."] = "Программа '%s' запущена в '%s' (pid: %d).", -- src\editor\output.lua
@@ -130,16 +149,22 @@ return {
["Program starting as '%s'."] = "Программа запускается как '%s'.", -- src\editor\output.lua
["Program stopped (pid: %d)."] = "Программа завершена (pid: %d).", -- src\editor\debugger.lua
["Program unable to run as '%s'."] = "Программа не может быть запущена как '%s'.", -- src\editor\output.lua
["Project Directory"] = "Каталог проекта", -- src\editor\menu_project.lua
["Project Directory"] = "Папка проекта", -- src\editor\menu_project.lua
["Project"] = "Проект", -- src\editor\settings.lua, src\editor\gui.lua
["Project/&FileTree Window"] = "Окно &проекта/списка файлов", -- src\editor\menu_view.lua
["R/O"] = "R/O", -- src\editor\editor.lua
["R/W"] = "R/W", -- src\editor\editor.lua
["Re&place In Files"] = "Замени&ть в файлах", -- src\editor\menu_search.lua
["Recent Files"] = "Недавние файлы", -- src\editor\menu_file.lua
["Redo last edit undone"] = "Вернуть последнее отмененное изменение", -- src\editor\menu_edit.lua, src\editor\gui.lua
["Redo last edit undone"] = "Вернуть последнее отмененное изменение", -- src\editor\menu_edit.lua
["Refused a request to start a new debugging session as there is one in progress already."] = "Отказано в запросе на запуск новой отладочной сессии, поскольку одна сессия уже выполняется.", -- src\editor\debugger.lua
["Regular &expression"] = "Регулярное выражение", -- src\editor\findreplace.lua
["Remote console"] = "Удаленная консоль", -- src\editor\shellbox.lua
["Replace &All"] = "Заменить все", -- src\editor\findreplace.lua
["Replace"] = "Заменить", -- src\editor\findreplace.lua
["Replaced an invalid UTF8 character with %s."] = "Некорректный символ UTF8 заменен на %s.", -- src\editor\commands.lua
["Replaced"] = "Заменено", -- src\editor\findreplace.lua
["Replacing"] = "Замена", -- src\editor\findreplace.lua
["Reset to default layout"] = "Установить расположение окон по умолчанию", -- src\editor\menu_view.lua
["Resets the dynamic word list for autocompletion"] = "Очистить список динамических слов для автодополнения", -- src\editor\menu_edit.lua
["Run as Scratchpad"] = "Запустить как черновик", -- src\editor\menu_project.lua
@@ -154,17 +179,21 @@ return {
["Save the current document to a file with a new name"] = "Сохранить текущий документ в файл под новым именем", -- src\editor\menu_file.lua
["Save the current document"] = "Сохранить текущий документ", -- src\editor\menu_file.lua, src\editor\gui.lua
["Saved auto-recover at %s."] = "Сохранено авто-восст в %s.", -- src\editor\commands.lua
["Scope"] = "Направление", -- src\editor\findreplace.lua
["Scratchpad error"] = "Ошибка в черновике", -- src\editor\debugger.lua
["Searching for"] = "Поиск", -- src\editor\findreplace.lua
["Select &All"] = "Выделить &все", -- src\editor\editor.lua, src\editor\menu_edit.lua
["Select all text in the editor"] = "Выделить весь текст в редакторе", -- src\editor\menu_edit.lua
["Set From Current File"] = "Установить по текущему файлу", -- src\editor\menu_project.lua
["Set project directory from current file"] = "Установить каталог проекта по текущему файлу", -- src\editor\menu_project.lua, src\editor\gui.lua
["Set project directory from current file"] = "Установить папку проекта по текущему файлу", -- src\editor\menu_project.lua, src\editor\gui.lua
["Set the interpreter to be used"] = "Установить используемый интерпретатор", -- src\editor\menu_project.lua
["Set the project directory to be used"] = "Установить используемый каталог проекта", -- src\editor\menu_project.lua
["Set the project directory to be used"] = "Установить используемую папку проекта", -- src\editor\menu_project.lua
["Settings: System"] = "Установки: Системы", -- src\editor\menu_edit.lua
["Settings: User"] = "Установки: Пользователя", -- src\editor\menu_edit.lua
["Show &Tooltip"] = "Показать &подсказку", -- src\editor\menu_edit.lua
["Show tooltip for current position; place cursor after opening bracket of function"] = "Показать подсказку в текущей позиции; переместите курсор в позицию после открывающей скобки функции", -- src\editor\menu_edit.lua
["Sort selected lines"] = "Отсортировать выделенные строки", -- src\editor\menu_search.lua
["Stack Window"] = "Окно стека", -- src\editor\debugger.lua
["Stack"] = "Стек", -- src\editor\debugger.lua
["Start &Debugging"] = "Начать &отладку", -- src\editor\menu_project.lua
["Start debugging"] = "Начать отладку", -- src\editor\menu_project.lua, src\editor\gui.lua
["Step &Into"] = "&Войти", -- src\editor\menu_project.lua
@@ -175,7 +204,8 @@ return {
["Step over"] = "Перейти на следующую строку", -- src\editor\menu_project.lua, src\editor\gui.lua
["Stop the currently running process"] = "Завершить текущий процесс", -- src\editor\menu_project.lua, src\editor\gui.lua
["Switch to or from full screen mode"] = "Переключить полноэкранный режим", -- src\editor\menu_view.lua
["The API file must be located in a subdirectory of the API directory."] = "Файл определений API должен быть расположен в подкаталоге каталога API.", -- src\editor\autocomplete.lua
["Text not found."] = "Текст не найден.", -- src\editor\findreplace.lua
["The API file must be located in a subdirectory of the API directory."] = "Файл определений API должен быть расположен внутри папки API.", -- src\editor\autocomplete.lua
["Toggle Break&point"] = "&Точка останова", -- src\editor\menu_project.lua
["Toggle breakpoint"] = "Переключить точку останова", -- src\editor\menu_project.lua, src\editor\gui.lua
["Tr&ace"] = "Т&рассировка", -- src\editor\menu_project.lua
@@ -183,17 +213,19 @@ return {
["Unable to load file '%s'."] = "Ошибка загрузки файла '%s'.", -- src\editor\commands.lua
["Unable to save file '%s': %s"] = "Ошибка сохранения файла '%s': %s", -- src\editor\commands.lua
["Unable to stop program (pid: %d), code %d."] = "Невозможно завершить программу (pid: %d), код %d.", -- src\editor\debugger.lua
["Undo last edit"] = "Отменить последнее действие", -- src\editor\menu_edit.lua, src\editor\gui.lua
["Undo last edit"] = "Отменить последнее действие", -- src\editor\menu_edit.lua
["Use '%s' to see full description."] = "Используйте '%s' для полного описания.", -- src\editor\editor.lua
["Use '%s' to show line endings and '%s' to convert them."] = "Используйте '%s' для отображения символов конца строки и '%s' для их преобразования.", -- src\editor\commands.lua
["Use 'clear' to clear the shell output and the history."] = "Используйте команду 'clear' для очистки содержимого окна и истории.", -- src\editor\shellbox.lua
["Use Shift-Enter for multiline code."] = "Используйте Shift-Enter для многострочного кода.", -- src\editor\shellbox.lua
["Value"] = "Значение", -- src\editor\debugger.lua
["View the output/console window"] = "Показать окно вывода/консоли", -- src\editor\menu_view.lua
["View the project/filetree window"] = "Показать окно проекта/списка файлов", -- src\editor\menu_view.lua
["View the stack window"] = "Показать окно стека", -- src\editor\menu_view.lua, src\editor\gui.lua
["View the watch window"] = "Показать окно наблюдения", -- src\editor\menu_view.lua, src\editor\gui.lua
["Watch Window"] = "Окно наблюдения", -- src\editor\debugger.lua
["View the watch window"] = "Показать окно выражений", -- src\editor\menu_view.lua, src\editor\gui.lua
["Watch"] = "Выражение", -- src\editor\debugger.lua
["Welcome to the interactive Lua interpreter."] = "Добро пожаловать в интерактивный интерпретатор Lua.", -- src\editor\shellbox.lua
["Wrap ar&ound"] = "Продолжить сначала", -- src\editor\findreplace.lua
["You must save the program first."] = "Вы должны сначала сохранить программу.", -- src\editor\commands.lua
["on line %d"] = "в строке %d", -- src\editor\debugger.lua, src\editor\commands.lua
["traced %d instruction"] = {"выполнена %d инструкция", "выполнено %d инструкции", "выполнено %d инструкций"}, -- src\editor\debugger.lua

View File

@@ -1,6 +1,7 @@
--[[
1. Pick a color scheme by clicking on a link:
- [Tomorrow](macro:shell(ApplyStyleConfig('cfg/tomorrow.lua','Tomorrow')))
- [TomorrowContrast](macro:shell(ApplyStyleConfig('cfg/tomorrow.lua','TomorrowContrast')))
- [TomorrowNight](macro:shell(ApplyStyleConfig('cfg/tomorrow.lua','TomorrowNight')))
- [TomorrowNightBlue](macro:shell(ApplyStyleConfig('cfg/tomorrow.lua','TomorrowNightBlue')))
- [TomorrowNightBright](macro:shell(ApplyStyleConfig('cfg/tomorrow.lua','TomorrowNightBright')))

View File

@@ -37,6 +37,20 @@ local colors = {
Blue = H'4271ae',
Purple = H'8959a8',
},
TomorrowContrast = { -- contributed by Sergey Lerg
Background = H'f7f7f7',
CurrentLine = H'efefef',
Selection = H'd6d6d6',
Foreground = H'202020',
Comment = H'8e908c',
Red = H'4669ff', --numbers
Orange = H'f5871f',
Yellow = H'eab700',
Green = H'108010', --strings
Aqua = H'4060b0', --built in functions
Blue = H'101080', --keywords
Purple = H'a01090',
},
TomorrowNight = {
Background = H'1d1f21',
CurrentLine = H'282a2e',
@@ -109,7 +123,7 @@ local colors = {
},
Monokai = {
Background = H'272822',
CurrentLine = H'49483E',
CurrentLine = H'2D2F29',
Selection = H'49483E',
Foreground = H'F8F8F2',
Comment = H'75715E',
@@ -182,15 +196,15 @@ return {
-- wxstc.wxSTC_LUA_NUMBER
number = {fg = C.Red},
-- wxstc.wxSTC_LUA_WORD, wxstc.wxSTC_LUA_WORD#
-- wxstc.wxSTC_LUA_WORD, wxstc.wxSTC_LUA_WORD2-8
keywords0 = {fg = C.Blue, b = true},
keywords1 = {fg = C.Aqua, b = false},
keywords2 = {fg = C.Aqua, b = true},
keywords3 = {fg = C.Purple, b = true},
keywords4 = {fg = C.Purple, b = true},
keywords5 = {fg = C.Purple, b = true},
keywords6 = {fg = C.Purple, b = true},
keywords7 = {fg = C.Purple, b = true},
keywords3 = {fg = C.Purple, b = false},
keywords4 = {fg = C.Purple, b = false},
keywords5 = {fg = C.Purple, b = false},
keywords6 = {fg = C.Purple, b = false},
keywords7 = {fg = C.Purple, b = false},
-- common (inherit fg/bg from text)
-- wxstc.wxSTC_LUA_IDENTIFIER
@@ -218,7 +232,7 @@ return {
wxSTC_INDIC_DIAGONAL Diagonal hatching
wxSTC_INDIC_STRIKE Strike-out
wxSTC_INDIC_BOX Box
wxSTC_INDIC_ROUNDBOX Rounded Box (not suppored in the current version?)
wxSTC_INDIC_ROUNDBOX Rounded Box
--]]
-- markup
@@ -244,8 +258,4 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---- Zenburn license ----
GNU GPL, http://www.gnu.org/licenses/gpl.html
--]]

View File

@@ -1,11 +1,11 @@
--[[-- Copy required content from this file to `user.lua`
--[[-- This file shows examples of settings you can adjust.
Configuration files are loaded in the following order
Configuration files with preferences are loaded in the following order:
1. cfg/user.lua (system-wide configuration)
2. HOME/.zbstudio/user.lua (per-user configuration)
3. -cfg <lua code fragment|filename> (command line configuration)
1. <application>\config.lua
2. cfg\user.lua
3. ~\.zbstudio\user.lua
4. -cfg commandline strings
See [configuration](http://studio.zerobrane.com/doc-configuration.html) page for information about location of configuration files.
--]]--
@@ -47,7 +47,7 @@ path.lua = 'd:/lua/lua'
path.gslshell = [[D:\Lua\gsl-shell\gsl-shell.exe]]
-- to provide output filter for those engines that support redirecting
-- of "print" output to the IDE (like Corona SDK and Gideros)
-- of "print" output to the IDE (like Corona SDK or Gideros)
debugger.outputfilter = function(m) return #m < 124 and m or m:sub(1,120).."...\n" end
-- to fix an issue with 0d0d0a line endings in MOAI examples,
@@ -109,7 +109,7 @@ styles.fncall.st = wxstc.wxSTC_INDIC_PLAIN
wxSTC_INDIC_DIAGONAL Diagonal hatching
wxSTC_INDIC_STRIKE Strike-out
wxSTC_INDIC_BOX Box
wxSTC_INDIC_ROUNDBOX Rounded Box (not suppored in the current version?)
wxSTC_INDIC_ROUNDBOX Rounded Box
--]]
-- to enable additional spec files (like spec/cpp.lua)
@@ -117,8 +117,8 @@ load.specs(function(file) return file:find('spec[/\\]cpp%.lua$') end)
-- to specify a default EOL encoding to be used for new files:
-- `wxstc.wxSTC_EOL_CRLF` or `wxstc.wxSTC_EOL_LF`;
-- `nil` means OS default: CRLF on Windows and OSX and LF on Linux/Unix.
-- CRLF as a default on OSX is a bug and is likely to change in future versions.
-- `nil` means OS default: CRLF on Windows and LF on Linux/Unix and OSX.
-- (OSX had CRLF as a default until v0.36, which fixed it).
editor.defaulteol = wxstc.wxSTC_EOL_LF
-- to turn off checking for mixed end-of-line encodings in loaded files
@@ -132,3 +132,6 @@ debugger.runonstart = true
-- to set compact fold that doesn't include empty lines after a block
editor.foldcompact = true
-- to disable zoom with mouse wheel as it may be too sensitive on OSX
editor.nomousezoom = true

59
cfg/user-snippet.lua Normal file
View File

@@ -0,0 +1,59 @@
--[[-- Copy snippets from this file to `user.lua` --]]--
--[[ Add a shortcut to generate `~` if your keyboard doesn't have one
local G = ... -- this now points to the global environment in the script
local ide, wx, TR, ID = G.ide, G.wx, G.TR, G.ID
local postinit = ide.app.postinit
ide.app.postinit = function()
if postinit then postinit() end
local menu = ide.frame.menuBar:GetMenu(ide.frame.menuBar:FindMenu(TR("&Edit")))
menu:Append(ID "tilde", "Tilde\tAlt-'")
ide.frame:Connect(ID "tilde", wx.wxEVT_COMMAND_MENU_SELECTED,
function () GetEditor():AddText("~") end)
end
--]]
--[[ Add `Evaluate in Console` option to the Edit menu
local G = ... -- this now points to the global environment in the script
local ide, wx, TR, ID = G.ide, G.wx, G.TR, G.ID
local postinit = ide.app.postinit
ide.app.postinit = function()
if postinit then postinit() end
local menu = ide.frame.menuBar:GetMenu(ide.frame.menuBar:FindMenu(TR("&Edit")))
menu:Append(ID "eval", "Evaluate in Console\tCtrl-E")
ide.frame:Connect(ID "eval", wx.wxEVT_COMMAND_MENU_SELECTED,
function () ShellExecuteCode(GetEditor():GetSelectedText()) end)
ide.frame:Connect(ID "eval", wx.wxEVT_UPDATE_UI,
function (event) event:Enable(GetEditor() and #GetEditor():GetSelectedText() > 0) end)
end
--]]
--[[ Add `Zoom` menu to increase/decrease/reset font in the editor
local G = ... -- this now points to the global environment in the script
local ide, wx, TR, ID = G.ide, G.wx, G.TR, G.ID
local postinit = ide.app.postinit
ide.app.postinit = function()
if postinit then postinit() end
local zoomMenu = wx.wxMenu{
{ID "zoomreset", "Zoom to 100%\tCtrl-0"},
{ID "zoomin", "Zoom In\tCtrl-+"},
{ID "zoomout", "Zoom Out\tCtrl--"},
}
local menu = ide.frame.menuBar:GetMenu(ide.frame.menuBar:FindMenu(TR("&View")))
menu:Append(ID "zoom", "Zoom", zoomMenu)
ide.frame:Connect(ID "zoomreset", wx.wxEVT_COMMAND_MENU_SELECTED,
function () GetEditor():SetZoom(1) end)
ide.frame:Connect(ID "zoomin", wx.wxEVT_COMMAND_MENU_SELECTED,
function () GetEditor():SetZoom(GetEditor():GetZoom()+1) end)
ide.frame:Connect(ID "zoomout", wx.wxEVT_COMMAND_MENU_SELECTED,
function () GetEditor():SetZoom(GetEditor():GetZoom()-1) end)
-- only enable if there is an editor
for _, m in G.ipairs({"zoomreset", "zoomin", "zoomout"}) do
ide.frame:Connect(ID(m), wx.wxEVT_UPDATE_UI,
function (event) event:Enable(GetEditor() ~= nil) end)
end
end
--]]

View File

@@ -65,8 +65,7 @@ local xcode = {
-- Watch window menu items
[G.ID_ADDWATCH] = "Ins",
[G.ID_EDITWATCH] = "F2",
[G.ID_REMOVEWATCH] = "Del",
[G.ID_EVALUATEWATCH] = "",
[G.ID_DELETEWATCH] = "Del",
-- Editor popup menu items
[G.ID_QUICKADDWATCH] = "",
[G.ID_QUICKEVAL] = "",

View File

@@ -40,13 +40,10 @@ return {
return
end
-- can we really do debugging? do if asked and if not on mac OSX where it's not supported
local debug = rundebug and not mac
if rundebug then
-- start running the application right away
DebuggerAttachDefault({startwith = file,
runstart = ide.config.debugger.runonstart ~= false,
redirect = debug and "c", noshell = mac or nil, noeval = mac or nil})
DebuggerAttachDefault({startwith = file, redirect = mac and "r" or "c",
runstart = ide.config.debugger.runonstart ~= false})
-- copy mobdebug.lua to Resources/ folder on Win and to the project folder on OSX
-- as copying it to Resources/ folder seems to break the signature of the app.
@@ -60,7 +57,8 @@ return {
end
end
local cmd = ('"%s" %s"%s"'):format(corona, debug and "-debug " or "", file)
local debugopt = mac and "-debug 1 -project " or "-debug "
local cmd = ('"%s" %s"%s"'):format(corona, rundebug and debugopt or "", file)
-- CommandLineRun(cmd,wdir,tooutput,nohide,stringcallback,uid,endcallback)
return CommandLineRun(cmd,self:fworkdir(wfilename),true,false,nil,nil,
function() ide.debugger.pid = nil end)

View File

@@ -4,15 +4,6 @@ local gideros
local win = ide.osname == "Windows"
local mac = ide.osname == "Macintosh"
local function exePath()
local mainpath = ide.editorFilename:gsub("[^/\\]+$","")
local macExe = mainpath..'bin/lua.app/Contents/MacOS/lua'
return ide.config.path.lua or
(ide.osname == "Windows" and mainpath..[[bin\lua.exe]]
or (ide.osname == "Unix" and [[lua]]) -- using installed lua
or (wx.wxFileExists(macExe) and macExe or mainpath..[[bin/lua]]))
end
local function isValidPid(bid, cmd)
if not bid or bid == -1 or bid == 0 then
DisplayOutputLn(("Program unable to run as '%s'."):format(cmd))
@@ -74,7 +65,7 @@ return {
-- find *.gproj file in the project directory
local file
for _, proj in ipairs(FileSysGet(self:fworkdir(wfilename).."/*.gproj", wx.wxFILE)) do
for _, proj in ipairs(FileSysGetRecursive(self:fworkdir(wfilename), false, "*.gproj")) do
if file then
DisplayOutputLn("Found multiple .gproj files in the project directory; ignored '"..proj.."'.")
end

View File

@@ -5,7 +5,7 @@ local function exePath()
local macExe = mainpath..'bin/lua.app/Contents/MacOS/lua'
return ide.config.path.lua or
(ide.osname == "Windows" and mainpath..[[bin\lua.exe]]
or (ide.osname == "Unix" and [[lua]]) -- using installed lua
or (ide.osname == "Unix" and mainpath..([[bin/linux/%s/lua]]):format(ide.osarch))
or (wx.wxFileExists(macExe) and macExe or mainpath..[[bin/lua]]))
end
@@ -16,10 +16,8 @@ return {
frun = function(self,wfilename,rundebug)
exe = exe or exePath()
local filepath = wfilename:GetFullPath()
local script
if rundebug then
DebuggerAttachDefault({runstart = ide.config.debugger.runonstart == true})
script = rundebug
else
-- if running on Windows and can't open the file, this may mean that
-- the file path includes unicode characters that need special handling
@@ -30,11 +28,11 @@ return {
winapi.set_encoding(winapi.CP_UTF8)
filepath = winapi.short_path(filepath)
end
script = ('dofile [[%s]]'):format(filepath)
end
local code = ([[xpcall(function() io.stdout:setvbuf('no'); %s end,function(err) print(debug.traceback(err)) end)]]):format(script)
local cmd = '"'..exe..'" -e "'..code..'"'
local code = rundebug
and ([[-e "io.stdout:setvbuf('no'); %s"]]):format(rundebug)
or ([[-e "io.stdout:setvbuf('no')" "%s"]]):format(filepath)
local cmd = '"'..exe..'" '..code
-- CommandLineRun(cmd,wdir,tooutput,nohide,stringcallback,uid,endcallback)
return CommandLineRun(cmd,self:fworkdir(wfilename),true,false,nil,nil,
function() ide.debugger.pid = nil end)

View File

@@ -9,7 +9,7 @@ local s3e = os.getenv("S3E_DIR")
return {
name = "Marmalade Quick",
description = "Marmalade Quick mobile framework",
api = {"baselib"},
api = {"baselib", "marmalade"},
frun = function(self,wfilename,rundebug)
quick = quick or ide.config.path.quick or (s3e and GetFullPathIfExists(s3e, exe))
if not quick then
@@ -25,7 +25,7 @@ return {
local candidates, paths = {}, {}
for p in path:gmatch("[^"..sep.."]+") do
table.insert(paths, p)
for _, candidate in ipairs(FileSysGet(p.."/*.*", wx.wxDIR)) do
for _, candidate in ipairs(FileSysGetRecursive(p, false, "*")) do
if GetFullPathIfExists(candidate, exe) then table.insert(candidates, candidate) end
if GetFullPathIfExists(candidate.."/s3e", exe) then table.insert(candidates, candidate.."/s3e") end
end
@@ -52,10 +52,10 @@ return {
-- check for *.mkb file; it can be in the same or in the parent folder
local mproj, mfile = MergeFullPath(projdir, "./")
for _, file in ipairs(FileSysGet(mproj.."*.mkb", wx.wxFILE)) do mfile = file end
for _, file in ipairs(FileSysGetRecursive(mproj, false, "*.mkb")) do mfile = file end
if not mfile then
mproj, mfile = MergeFullPath(projdir, "../")
for _, file in ipairs(FileSysGet(mproj.."*.mkb", wx.wxFILE)) do mfile = file end
for _, file in ipairs(FileSysGetRecursive(mproj, false, "*.mkb")) do mfile = file end
end
if not mfile then
DisplayOutputLn(("Can't find '%s' project file."):format(mproj))
@@ -90,7 +90,8 @@ return {
end
end
local dll = MergeFullPath(s3e, "../quick/target/quick_prebuilt_d.s86")
local dll = GetFullPathIfExists(s3e, "../quick/target/quick_prebuilt_d.s86")
or MergeFullPath(s3e, ("../quick/target/%s/quick_prebuilt_d.s86"):format(mac and 'osx' or 'win'))
local options = table.concat({
([[--dll="%s"]]):format(dll),
(datadir and ([[--data="%s"]]):format(datadir) or ''),

View File

@@ -1,15 +1,16 @@
--
-- MobDebug 0.517
-- Copyright 2011-12 Paul Kulchenko
-- MobDebug 0.526
-- Copyright 2011-13 Paul Kulchenko
-- Based on RemDebug 1.0 Copyright Kepler Project 2005
--
local mobdebug = {
_NAME = "mobdebug",
_VERSION = 0.517,
_VERSION = 0.526,
_COPYRIGHT = "Paul Kulchenko",
_DESCRIPTION = "Mobile Remote Debugger for the Lua programming language",
port = os and os.getenv and os.getenv("MOBDEBUG_PORT") or 8172,
checkcount = 200,
yieldtimeout = 0.02,
}
@@ -58,9 +59,11 @@ end
-- check for OS and convert file names to lower case on windows
-- (its file system is case insensitive, but case preserving), as setting a
-- breakpoint on x:\Foo.lua will not work if the file was loaded as X:\foo.lua.
local iswindows = os and os.getenv and (os.getenv('WINDIR')
or (os.getenv('OS') or ''):match('[Ww]indows'))
or pcall(require, "winapi")
-- OSX and Windows behave the same way (case insensitive, but case preserving)
local iscasepreserving = os and os.getenv and (os.getenv('WINDIR')
or (os.getenv('OS') or ''):match('[Ww]indows')
or os.getenv('DYLD_LIBRARY_PATH'))
or not io.open("/proc")
-- turn jit off based on Mike Pall's comment in this discussion:
-- http://www.freelists.org/post/luajit/Debug-hooks-and-JIT,2
@@ -81,14 +84,13 @@ local lastfile
local watchescnt = 0
local abort -- default value is nil; this is used in start/loop distinction
local seen_hook = false
local skip
local skipcount = 0
local checkcount = 0
local step_into = false
local step_over = false
local step_level = 0
local stack_level = 0
local server
local rset
local buf
local outputs = {}
local iobase = {print = print}
local basedir = ""
@@ -101,10 +103,10 @@ end
local function q(s) return s:gsub('([%(%)%.%%%+%-%*%?%[%^%$%]])','%%%1') end
local serpent = (function() ---- include Serpent module for serialization
local n, v = "serpent", 0.22 -- (C) 2012 Paul Kulchenko; MIT License
local c, d = "Paul Kulchenko", "Serializer and pretty printer of Lua data types"
local n, v = "serpent", 0.23 -- (C) 2012-13 Paul Kulchenko; MIT License
local c, d = "Paul Kulchenko", "Lua serializer and pretty printer"
local snum = {[tostring(1/0)]='1/0 --[[math.huge]]',[tostring(-1/0)]='-1/0 --[[-math.huge]]',[tostring(0/0)]='0/0'}
local badtype = {thread = true, userdata = true}
local badtype = {thread = true, userdata = true, cdata = true}
local keyword, globals, G = {}, {}, (_G or _ENV)
for _,k in ipairs({'and', 'break', 'do', 'else', 'elseif', 'end', 'false',
'for', 'function', 'goto', 'if', 'in', 'local', 'nil', 'not', 'or', 'repeat',
@@ -117,9 +119,10 @@ local function s(t, opts)
local name, indent, fatal = opts.name, opts.indent, opts.fatal
local sparse, custom, huge = opts.sparse, opts.custom, not opts.nohuge
local space, maxl = (opts.compact and '' or ' '), (opts.maxlevel or math.huge)
local comm = opts.comment and (tonumber(opts.comment) or math.huge)
local seen, sref, syms, symn = {}, {}, {}, 0
local function gensym(val) return (tostring(val):gsub("[^%w]",""):gsub("(%d%w+)",
local iname, comm = '_'..(name or ''), opts.comment and (tonumber(opts.comment) or math.huge)
local seen, sref, syms, symn = {}, {'local '..iname..'={}'}, {}, 0
local function gensym(val) return '_'..(tostring(tostring(val)):gsub("[^%w]",""):gsub("(%d%w+)",
-- tostring(val) is needed because __tostring may return a non-string value
function(s) if not syms[s] then symn = symn+1; syms[s] = symn end return syms[s] end)) end
local function safestr(s) return type(s) == "number" and (huge and snum[tostring(s)] or s)
or type(s) ~= "string" and tostring(s) -- escape NEWLINE/010 and EOF/026
@@ -132,41 +135,34 @@ local function s(t, opts)
local plain = type(n) == "string" and n:match("^[%l%u_][%w_]*$") and not keyword[n]
local safe = plain and n or '['..safestr(n)..']'
return (path or '')..(plain and path and '.' or '')..safe, safe end
local alphanumsort = type(opts.sortkeys) == 'function' and opts.sortkeys or function(o, n)
local alphanumsort = type(opts.sortkeys) == 'function' and opts.sortkeys or function(k, o, n) -- k=keys, o=originaltable, n=padding
local maxn, to = tonumber(n) or 12, {number = 'a', string = 'b'}
local function padnum(d) return ("%0"..maxn.."d"):format(d) end
table.sort(o, function(a,b)
return (o[a] and 0 or to[type(a)] or 'z')..(tostring(a):gsub("%d+",padnum))
< (o[b] and 0 or to[type(b)] or 'z')..(tostring(b):gsub("%d+",padnum)) end) end
table.sort(k, function(a,b)
-- sort numeric keys first: k[key] is non-nil for numeric keys
return (k[a] and 0 or to[type(a)] or 'z')..(tostring(a):gsub("%d+",padnum))
< (k[b] and 0 or to[type(b)] or 'z')..(tostring(b):gsub("%d+",padnum)) end) end
local function val2str(t, name, indent, insref, path, plainindex, level)
local ttype, level = type(t), (level or 0)
local ttype, level, mt = type(t), (level or 0), getmetatable(t)
local spath, sname = safename(path, name)
local tag = plainindex and
((type(name) == "number") and '' or name..space..'='..space) or
(name ~= nil and sname..space..'='..space or '')
if seen[t] then -- if already seen and in sref processing,
if insref then return tag..seen[t] end -- then emit right away
if seen[t] then -- already seen this element
table.insert(sref, spath..space..'='..space..seen[t])
return tag..'nil'..comment('ref', level)
elseif badtype[ttype] then
seen[t] = spath
return tag..globerr(t, level)
elseif ttype == 'function' then
return tag..'nil'..comment('ref', level) end
if mt and (mt.__serialize or mt.__tostring) then -- knows how to serialize itself
seen[t] = insref or spath
local ok, res = pcall(string.dump, t)
local func = ok and ((opts.nocode and "function() --[[..skipped..]] end" or
"loadstring("..safestr(res)..",'@serialized')")..comment(t, level))
return tag..(func or globerr(t, level))
elseif ttype == "table" then
if mt.__serialize then t = mt.__serialize(t) else t = tostring(t) end
ttype = type(t) end -- new value falls through to be serialized
if ttype == "table" then
if level >= maxl then return tag..'{}'..comment('max', level) end
seen[t] = insref or spath -- set path to use as reference
if getmetatable(t) and getmetatable(t).__tostring
then return tag..val2str(tostring(t),nil,indent,false,nil,nil,level+1)..comment("meta", level) end
seen[t] = insref or spath
if next(t) == nil then return tag..'{}'..comment(t, level) end -- table empty
local maxn, o, out = #t, {}, {}
for key = 1, maxn do table.insert(o, key) end
for key in pairs(t) do if not o[key] then table.insert(o, key) end end
if opts.sortkeys then alphanumsort(o, opts.sortkeys) end
if opts.sortkeys then alphanumsort(o, t, opts.sortkeys) end
for n, key in ipairs(o) do
local value, ktype, plainindex = t[key], type(key), n <= maxn and not sparse
if opts.valignore and opts.valignore[value] -- skip ignored values; do nothing
@@ -176,7 +172,8 @@ local function s(t, opts)
elseif ktype == 'table' or ktype == 'function' or badtype[ktype] then
if not seen[key] and not globals[key] then
table.insert(sref, 'placeholder')
sref[#sref] = 'local '..val2str(key,gensym(key),indent,gensym(key)) end
local sname = safename(iname, gensym(key)) -- iname is table for local variables
sref[#sref] = val2str(key,sname,indent,sname,iname,true) end
table.insert(sref, 'placeholder')
local path = seen[t]..'['..(seen[key] or globals[key] or gensym(key))..']'
sref[#sref] = path..space..'='..space..(seen[value] or val2str(value,nil,indent,path))
@@ -189,12 +186,22 @@ local function s(t, opts)
local body = table.concat(out, ','..(indent and '\n'..prefix..indent or space))
local tail = indent and "\n"..prefix..'}' or '}'
return (custom and custom(tag,head,body,tail) or tag..head..body..tail)..comment(t, level)
elseif badtype[ttype] then
seen[t] = insref or spath
return tag..globerr(t, level)
elseif ttype == 'function' then
seen[t] = insref or spath
local ok, res = pcall(string.dump, t)
local func = ok and ((opts.nocode and "function() --[[..skipped..]] end" or
"loadstring("..safestr(res)..",'@serialized')")..comment(t, level))
return tag..(func or globerr(t, level))
else return tag..safestr(t) end -- handle all other types
end
local sepr = indent and "\n" or ";"..space
local body = val2str(t, name, indent) -- this call also populates sref
local tail = #sref>0 and table.concat(sref, sepr)..sepr or ''
return not name and body or "do local "..body..sepr..tail.."return "..name..sepr.."end"
local tail = #sref>1 and table.concat(sref, sepr)..sepr or ''
local warn = opts.comment and #sref>1 and space.."--[[incomplete output with shared/self-references skipped]]" or ''
return not name and body..warn or "do local "..body..sepr..tail.."return "..name..sepr.."end"
end
local function merge(a, b) if b then for k,v in pairs(b) do a[k] = v end end; return a; end
@@ -205,7 +212,7 @@ return { _NAME = n, _COPYRIGHT = c, _DESCRIPTION = d, _VERSION = v, serialize =
end)() ---- end of Serpent module
local function removebasedir(path, basedir)
if iswindows then
if iscasepreserving then
-- check if the lowercased path matches the basedir
-- if so, return substring of the original path (to not lowercase it)
return path:lower():find('^'..q(basedir:lower()))
@@ -242,14 +249,13 @@ local function stack(start)
local source = debug.getinfo(i, "Snl")
if not source then break end
-- remove basedir from source
local src = source.source
if src:find("@") == 1 then
src = src:sub(2):gsub("\\", "/")
if src:find("%./") == 1 then src = src:sub(3) end
end
table.insert(stack, {
table.insert(stack, { -- remove basedir from source
{source.name, removebasedir(src, basedir), source.linedefined,
source.currentline, source.what, source.namewhat, source.short_src},
vars(i+1)})
@@ -260,20 +266,20 @@ end
local function set_breakpoint(file, line)
if file == '-' and lastfile then file = lastfile
elseif iswindows then file = string.lower(file) end
if not breakpoints[file] then breakpoints[file] = {} end
breakpoints[file][line] = true
elseif iscasepreserving then file = string.lower(file) end
if not breakpoints[line] then breakpoints[line] = {} end
breakpoints[line][file] = true
end
local function remove_breakpoint(file, line)
if file == '-' and lastfile then file = lastfile
elseif iswindows then file = string.lower(file) end
if breakpoints[file] then breakpoints[file][line] = nil end
elseif iscasepreserving then file = string.lower(file) end
if breakpoints[line] then breakpoints[line][file] = nil end
end
-- this file name is already converted to lower case on windows.
local function has_breakpoint(file, line)
return breakpoints[file] and breakpoints[file][line]
return breakpoints[line] and breakpoints[line][file]
end
local function restore_vars(vars)
@@ -366,6 +372,17 @@ local function in_debugger()
return false
end
local function is_pending(peer)
-- if there is something already in the buffer, skip check
if not buf and checkcount >= mobdebug.checkcount then
peer:settimeout(0) -- non-blocking
buf = peer:receive(1)
peer:settimeout() -- back to blocking
checkcount = 0
end
return buf
end
local function debug_hook(event, line)
-- (1) LuaJIT needs special treatment. Because debug_hook is set for
-- *all* coroutines, and not just the one being debugged as in regular Lua
@@ -397,13 +414,18 @@ local function debug_hook(event, line)
elseif event == "return" or event == "tail return" then
stack_level = stack_level - 1
elseif event == "line" then
-- may need to fall through because of the following:
-- (1) step_into
-- (2) step_over and stack_level <= step_level (need stack_level)
-- (3) breakpoint; check for line first as it's known; then for file
-- (4) socket call (only do every Xth check)
-- (5) at least one watch is registered
if not (
step_into or step_over or breakpoints[line] or watchescnt > 0
or is_pending(server)
) then checkcount = checkcount + 1; return end
-- check if we need to skip some callbacks (to save time)
if skip then
skipcount = skipcount + 1
if skipcount < skip or not is_safe(stack_level) then return end
skipcount = 0
end
checkcount = mobdebug.checkcount -- force check on the next command
-- this is needed to check if the stack got shorter or longer.
-- unfortunately counting call/return calls is not reliable.
@@ -417,6 +439,7 @@ local function debug_hook(event, line)
-- have any other instructions to execute. it triggers three returns:
-- "return, tail return, return", which needs to be accounted for.
stack_level = stack_depth(stack_level+1)
local caller = debug.getinfo(2, "S")
-- grab the filename and fix it if needed
@@ -429,10 +452,10 @@ local function debug_hook(event, line)
-- so we handle all sources as filenames
file = file:gsub("^@", ""):gsub("\\", "/")
-- need this conversion to be applied to relative and absolute
-- file names as you may write "require 'Foo'" on Windows to
-- load "foo.lua" (as it's case insensitive) and breakpoints
-- file names as you may write "require 'Foo'" to
-- load "foo.lua" (on a case insensitive file system) and breakpoints
-- set on foo.lua will not work if not converted to the same case.
if iswindows then file = string.lower(file) end
if iscasepreserving then file = string.lower(file) end
if file:find("%./") == 1 then file = file:sub(3)
else file = file:gsub('^'..q(basedir), '') end
@@ -467,7 +490,7 @@ local function debug_hook(event, line)
(step_into
or (step_over and stack_level <= step_level)
or has_breakpoint(file, line)
or (socket.select(rset, nil, 0))[server])
or is_pending(server))
if getin then
vars = vars or capture_vars()
@@ -556,6 +579,8 @@ local function debugger_loop(sev, svars, sfile, sline)
elseif not line and err == "closed" then
error("Debugger connection unexpectedly closed", 0)
else
-- if there is something in the pending buffer, prepend it to the line
if buf then line = buf .. line; buf = nil end
break
end
end
@@ -614,7 +639,7 @@ local function debugger_loop(sev, svars, sfile, sline)
if not loaded[k] then package.loaded[k] = nil end
end
if size == 0 then -- RELOAD the current script being debugged
if size == 0 and name == '-' then -- RELOAD the current script being debugged
server:send("200 OK 0\n")
coroutine.yield("load")
else
@@ -715,7 +740,9 @@ local function debugger_loop(sev, svars, sfile, sline)
elseif command == "BASEDIR" then
local _, _, dir = string.find(line, "^[A-Z]+%s+(.+)%s*$")
if dir then
basedir = iswindows and string.lower(dir) or dir
basedir = iscasepreserving and string.lower(dir) or dir
-- reset cached source as it may change with basedir
lastsource = nil
server:send("200 OK\n")
else
server:send("400 Bad Request\n")
@@ -791,17 +818,6 @@ local function start(controller_host, controller_port)
server = (socket.connect4 or socket.connect)(controller_host, controller_port)
if server then
rset = {server} -- store hash to avoid recreating it later
-- check if we are called from the debugger as this may happen
-- when another debugger function calls start(); only check one level deep
local this = debug.getinfo(1, "S").source
local info = debug.getinfo(2, "Sl")
if info.source == this then info = debug.getinfo(3, "Sl") end
local file = info.source
if string.find(file, "@") == 1 then file = string.sub(file, 2) end
if string.find(file, "%.[/\\]") == 1 then file = string.sub(file, 3) end
-- correct stack depth which already has some calls on it
-- so it doesn't go into negative when those calls return
-- as this breaks subsequence checks in stack_depth().
@@ -811,30 +827,45 @@ local function start(controller_host, controller_port)
-- provide our own traceback function to report the error remotely
do
local dtraceback = debug.traceback
debug.traceback = function (err) genv.print(dtraceback(err, 3)) end
debug.traceback = function (...)
if select('#', ...) >= 1 then
local err, lvl = ...
if err and type(err) ~= 'thread' then
local trace = dtraceback(err, (lvl or 2)+1)
if genv.print == iobase.print then -- no remote redirect
return trace
else
genv.print(trace) -- report the error remotely
return -- don't report locally to avoid double reporting
end
end
end
-- direct call to debug.traceback: return the original.
-- debug.traceback(nil, level) doesn't work in Lua 5.1
-- (http://lua-users.org/lists/lua-l/2011-06/msg00574.html), so
-- simply remove first frame from the stack trace
return (dtraceback(...):gsub("(stack traceback:\n)[^\n]*\n", "%1"))
end
end
coro_debugger = coroutine.create(debugger_loop)
debug.sethook(debug_hook, "lcr")
local ok, res = coroutine.resume(coro_debugger, events.RESTART, capture_vars(), file, info.currentline)
if not ok and res then error(res, 2) end
step_into = true -- start with step command
return true
else
print("Could not connect to " .. controller_host .. ":" .. controller_port)
end
end
local function controller(controller_host, controller_port)
local function controller(controller_host, controller_port, scratchpad)
-- only one debugging session can be run (as there is only one debug hook)
if isrunning() then return end
controller_host = controller_host or "localhost"
controller_port = controller_port or mobdebug.port
local exitonerror = not skip -- exit if not running a scratchpad
local exitonerror = not scratchpad
server = (socket.connect4 or socket.connect)(controller_host, controller_port)
if server then
rset = {server} -- store hash to avoid recreating it later
local function report(trace, err)
local msg = err .. "\n" .. trace
server:send("401 Error in Execution " .. #msg .. "\n")
@@ -848,7 +879,7 @@ local function controller(controller_host, controller_port)
while true do
step_into = true -- start with step command
abort = false -- reset abort flag from the previous loop
if skip then skipcount = skip end -- force suspend right away
if scratchpad then checkcount = mobdebug.checkcount end -- force suspend right away
coro_debugee = coroutine.create(debugee)
debug.sethook(coro_debugee, debug_hook, "lcr")
@@ -886,14 +917,12 @@ local function controller(controller_host, controller_port)
return true
end
local function scratchpad(controller_host, controller_port, frequency)
skip = frequency or 100
return controller(controller_host, controller_port)
local function scratchpad(controller_host, controller_port)
return controller(controller_host, controller_port, true)
end
local function loop(controller_host, controller_port)
skip = nil -- just in case if loop() is called after scratchpad()
return controller(controller_host, controller_port)
return controller(controller_host, controller_port, false)
end
local function on()
@@ -983,9 +1012,8 @@ local function handle(params, client, options)
file = string.gsub(file, "\\", "/") -- convert slash
file = removebasedir(file, basedir)
client:send("SETB " .. file .. " " .. line .. "\n")
if client:receive() == "200 OK" then
if not breakpoints[file] then breakpoints[file] = {} end
breakpoints[file][line] = true
if client:receive() == "200 OK" then
set_breakpoint(file, line)
else
print("Error: breakpoint not inserted")
end
@@ -1020,7 +1048,7 @@ local function handle(params, client, options)
file = removebasedir(file, basedir)
client:send("DELB " .. file .. " " .. line .. "\n")
if client:receive() == "200 OK" then
if breakpoints[file] then breakpoints[file][line] = nil end
remove_breakpoint(file, line)
else
print("Error: breakpoint not removed")
end
@@ -1028,11 +1056,11 @@ local function handle(params, client, options)
print("Invalid command")
end
elseif command == "delallb" then
for file, breaks in pairs(breakpoints) do
for line, _ in pairs(breaks) do
for line, breaks in pairs(breakpoints) do
for file, _ in pairs(breaks) do
client:send("DELB " .. file .. " " .. line .. "\n")
if client:receive() == "200 OK" then
breakpoints[file][line] = nil
if client:receive() == "200 OK" then
remove_breakpoint(file, line)
else
print("Error: breakpoint at file " .. file .. " line " .. line .. " not removed")
end
@@ -1154,12 +1182,10 @@ local function handle(params, client, options)
print("Invalid command")
end
elseif command == "listb" then
for k, v in pairs(breakpoints) do
local b = k .. ": " -- get filename
for k in pairs(v) do
b = b .. k .. " " -- get line numbers
for l, v in pairs(breakpoints) do
for f in pairs(v) do
print(f .. ": " .. l)
end
print(b)
end
elseif command == "listw" then
for i, v in pairs(watches) do

View File

@@ -27,7 +27,7 @@ local function isfndef(str)
end
return {
exts = {"lua", "rockspec"},
exts = {"lua", "rockspec", "wlua"},
lexer = wxstc.wxSTC_LEX_LUA,
apitype = "lua",
linecomment = "--",
@@ -93,7 +93,6 @@ return {
line = line -1
end
local added
while (line <= endline) do
local ls = editor:PositionFromLine(line)
local s = bit.band(editor:GetStyleAt(ls),31)
@@ -103,35 +102,47 @@ return {
-- check for assignments
local varname = "([%w_%.]+)"
local identifier = "([%w_%.:]+)"
local identifier = "([%w_%.:%s]+)"
-- special hint
local typ,var = tx:match("%s*%-%-=%s*"..varname.."%s+"..identifier)
if (var and typ) then
typ = typ:gsub("%s","")
assigns[var] = typ
added = true
else
-- real assignments
local var,typ,rest = tx:match("%s*"..identifier.."%s*=%s*"..identifier.."(.*)")
local comment = rest and rest:match(".*%-%-=%s*"..varname.."%s*$")
local comma = rest and rest:match(".-%s*([,]*)%s*$")
if (var and comment) then
assigns[var] = comment
added = true
elseif (var and typ and comma=="") then
local var,typ = tx:match("%s*"..identifier.."%s*=%s*([^;]+)")
var = var and var:gsub("local","")
var = var and var:gsub("%s","")
typ = typ and typ:gsub("%b[]","")
typ = typ and typ:gsub("%b()","")
typ = typ and typ:gsub("%b{}","")
if (typ and (typ:match(",") or typ:match("%sor%s") or typ:match("%sand%s"))) then
typ = nil
end
typ = typ and typ:gsub("%s","")
if (var and typ) then
class,func = typ:match(varname.."[%.:]"..varname)
if (func) then
if (assigns[typ]) then
assigns[var] = assigns[typ]
elseif (func) then
-- FIXME remove this, in favor of proper api definitions
local added
local funcnames = {"new","load","create"}
for i,v in ipairs(funcnames) do
if (func:match("^"..v)) then
if (func == v) then
assigns[var] = class
added = true
break
end
end
elseif (assigns[typ]) then
assigns[var] = assigns[typ]
added = true
if (not added) then
-- let's hope autocomplete info can resolve this
assigns[var] = typ
end
else
assigns[var] = typ
end
end
end

View File

@@ -105,6 +105,7 @@ config = {
-- also report mixed eol encodings
defaulteol = nil, -- default line-endings for new files; valid values are
-- wxstc.wxSTC_EOL_CRLF, wxstc.wxSTC_EOL_LF and nil (OS default)
nomousezoom = nil, -- disable zooming using mouse wheel
},
default = {
@@ -193,11 +194,17 @@ app = {
api = {
-- global space words, e.g "table"
["blah"] = {
-- "function", "class", "keyword", "value", "lib"
-- "function", "class", "keyword", "value", "lib", "method"
-- method is for class:func functions
type = "function",
description = "this does something",
-- value and function:
-- value/function/method:
-- for autocomplete type guessing, insert the string
-- that the variable name is replace with
-- e.g. "test = somefunc()" somefunc has valuetype of "math"
-- then typing "test." will be treated as "math." in
-- autcomplete logic
valuetype = "api.ClassName",
-- function:

View File

@@ -44,8 +44,8 @@ end
-- API loading
local function addAPI(apifile,only,subapis,known) -- relative to API directory
local ftype,fname = apifile:match("api[/\\]([^/\\]+)[/\\](.*)%.")
if not ftype then
local ftype, fname = apifile:match("api[/\\]([^/\\]+)[/\\](.*)%.")
if not ftype or not fname then
DisplayOutputLn(TR("The API file must be located in a subdirectory of the API directory."))
return
end
@@ -82,12 +82,8 @@ local function addAPI(apifile,only,subapis,known) -- relative to API directory
end
local function loadallAPIs (only,subapis,known)
for _, dir in ipairs(FileSysGet("api/*", wx.wxDIR)) do
for _, file in ipairs(FileSysGet(dir.."/*.*", wx.wxFILE)) do
if file:match "%.lua$" then
addAPI(file,only,subapis,known)
end
end
for _, file in ipairs(FileSysGetRecursive("api", true, "*.lua")) do
if not file:match(string_Pathsep.."$") then addAPI(file,only,subapis,known) end
end
end
@@ -119,7 +115,7 @@ local function fillTips(api,apibasename,apiname)
if not tab.childs then return end
for key,info in pairs(tab.childs) do
traverse(info,key)
if info.type == "function" then
if info.type == "function" or info.type == "method" then
local libstr = libname ~= "" and libname.."." or ""
-- fix description
@@ -206,23 +202,35 @@ local function resolveAssign(editor,tx)
return tab,a
end
local classname
local c = ""
local c
if (assigns) then
-- find assign
for w,s in tx:gmatch("([%w_]*)([%.:]?)") do
local old = classname
classname = classname or (assigns[c..w])
if (s ~= "" and old ~= classname) then
c = classname..s
else
c = c..w..s
local change = true
while (change) do
local classname = nil
c = ""
change = false
for w,s in tx:gmatch("([%w_]+)([%.:]?)") do
local old = classname
-- check if what we have so far can be matched with a class name
-- this can happen if it's a reference to a value with a known type
classname = classname or assigns[c..w]
if (s ~= "" and old ~= classname) then
c = classname..s
change = true
else
c = c..w..s
end
end
-- abort if the same value is returned; no need to continue.
-- this can happen after typing "smth = smth:new(); smth:"
if tx == c then break end
tx = c
end
else
c = tx
end
-- then work from api
return getclass(ac,c)
end
@@ -367,19 +375,31 @@ end
------------
-- Final Autocomplete
local cache = {}
local cachemain = {}
local cachemethod = {}
local laststrategy
local function getAutoCompApiList(childs,fragment)
local lastmethod
local function getAutoCompApiList(childs,fragment,method)
fragment = fragment:lower()
local strategy = ide.config.acandtip.strategy
if (laststrategy ~= strategy) then cache = {}; laststrategy = strategy end
if (laststrategy ~= strategy) then
cachemain = {}
cachemethod = {}
laststrategy = strategy
end
local cache = method and cachemethod or cachemain
if (strategy == 2) then
local wlist = cache[childs]
if not wlist then
wlist = " "
for i in pairs(childs) do
wlist = wlist..i.." "
for i,v in pairs(childs) do
-- if a:b typed, then value (type == "value") not allowed
-- if a.b typed, then method (type == "method") not allowed
if (method and v.type ~= "value") or (not method and v.type ~= "method") then
wlist = wlist..i.." "
end
end
cache[childs] = wlist
end
@@ -406,29 +426,33 @@ local function getAutoCompApiList(childs,fragment)
cache[childs] = t
local sub = strategy == 1
for key in pairs(childs) do
local used = {}
--
local kl = key:lower()
for i=0,#key do
local k = kl:sub(1,i)
t[k] = t[k] or {}
used[k] = true
table.insert(t[k],key)
end
if (sub) then
-- find camel case / _ separated subwords
-- glfwGetGammaRamp -> g, gg, ggr
-- GL_POINT_SPRIT -> g, gp, gps
local last = ""
for ks in string.gmatch(key,"([A-Z%d]*[a-z%d]*_?)") do
local k = last..(ks:sub(1,1):lower())
last = k
for key,v in pairs(childs) do
-- if a:b typed, then value (type == "value") not allowed
-- if a.b typed, then method (type == "method") not allowed
if (method and v.type ~= "value") or (not method and v.type ~= "method") then
local used = {}
--
local kl = key:lower()
for i=0,#key do
local k = kl:sub(1,i)
t[k] = t[k] or {}
if (not used[k]) then
used[k] = true
table.insert(t[k],key)
used[k] = true
table.insert(t[k],key)
end
if (sub) then
-- find camel case / _ separated subwords
-- glfwGetGammaRamp -> g, gg, ggr
-- GL_POINT_SPRIT -> g, gp, gps
local last = ""
for ks in string.gmatch(key,"([A-Z%d]*[a-z%d]*_?)") do
local k = last..(ks:sub(1,1):lower())
last = k
t[k] = t[k] or {}
if (not used[k]) then
used[k] = true
table.insert(t[k],key)
end
end
end
end
@@ -447,6 +471,8 @@ function CreateAutoCompList(editor,key)
local tip = api.tip
local ac = api.ac
local method = key:match(":[^:%.]*$") ~= nil
-- ignore keywords
if tip.keys[key] then return end
@@ -499,7 +525,7 @@ function CreateAutoCompList(editor,key)
end
-- list from api
local apilist = getAutoCompApiList(tab.childs or tab,rest)
local apilist = getAutoCompApiList(tab.childs or tab,rest,method)
local compstr = ""
if apilist then
if (#rest > 0) then

View File

@@ -14,13 +14,14 @@ local BREAKPOINT_MARKER = StylesGetMarker("breakpoint")
function NewFile(event)
local editor = CreateEditor()
SetupKeywords(editor, "lua")
AddEditor(editor, ide.config.default.fullname)
local doc = AddEditor(editor, ide.config.default.fullname)
if doc then SetEditorSelection(doc.index) end
return editor
end
-- Find an editor page that hasn't been used at all, eg. an untouched NewFile()
local function findDocumentToReuse()
local editor = nil
local function findUnusedEditor()
local editor
for id, document in pairs(openDocuments) do
if (document.editor:GetLength() == 0) and
(not document.isModified) and (not document.filePath) and
@@ -40,7 +41,10 @@ function LoadFile(filePath, editor, file_must_exist, skipselection)
if (not editor) then
for id, doc in pairs(openDocuments) do
if doc.filePath and filePath:SameAs(wx.wxFileName(doc.filePath)) then
if not skipselection then notebook:SetSelection(doc.index) end
if not skipselection and doc.index ~= notebook:GetSelection() then
-- selecting the same tab doesn't trigger PAGE_CHANGE event,
-- but moves the focus to the tab bar, which needs to be avoided.
notebook:SetSelection(doc.index) end
return doc.editor
end
end
@@ -58,20 +62,17 @@ function LoadFile(filePath, editor, file_must_exist, skipselection)
end
local current = editor and editor:GetCurrentPos()
editor = editor or findDocumentToReuse() or CreateEditor()
editor = editor or findUnusedEditor() or CreateEditor()
editor:Freeze()
editor:Clear()
editor:ClearAll()
SetupKeywords(editor, GetFileExt(filePath))
editor:MarkerDeleteAll(BREAKPOINT_MARKER)
editor:MarkerDeleteAll(CURRENT_LINE_MARKER)
editor:AppendText(file_text or "")
editor:MarkerDeleteAll(-1)
editor:SetText(file_text or "")
-- check the editor as it can be empty if the file has malformed UTF8;
-- skip binary files as they may have any sequences; can't show them anyway.
if file_text and #file_text > 0 and not isBinary(file_text)
and #(editor:GetText()) == 0 then
if file_text and #file_text > 0 and #(editor:GetText()) == 0
and not isBinary(file_text) then
local replacement, invalid = "\022"
file_text, invalid = fixUTF8(file_text, replacement)
if #invalid > 0 then
@@ -92,12 +93,12 @@ function LoadFile(filePath, editor, file_must_exist, skipselection)
editor:Thaw()
if current then editor:GotoPos(current) end
if (ide.config.editor.autotabs) then
if (file_text and ide.config.editor.autotabs) then
local found = string.find(file_text,"\t") ~= nil
editor:SetUseTabs(found)
end
if (ide.config.editor.checkeol) then
if (file_text and ide.config.editor.checkeol) then
-- Auto-detect CRLF/LF line-endings
local foundcrlf = string.find(file_text,"\r\n") ~= nil
local foundlf = (string.find(file_text,"[^\r]\n") ~= nil)
@@ -117,7 +118,9 @@ function LoadFile(filePath, editor, file_must_exist, skipselection)
editor:EmptyUndoBuffer()
local id = editor:GetId()
if not openDocuments[id] then -- the editor has not been added to notebook
if openDocuments[id] then -- existing editor; switch to the tab
notebook:SetSelection(openDocuments[id].index)
else -- the editor has not been added to notebook
AddEditor(editor, wx.wxFileName(filePath):GetFullName()
or ide.config.default.fullname)
end
@@ -126,10 +129,6 @@ function LoadFile(filePath, editor, file_must_exist, skipselection)
openDocuments[id].modTime = GetFileModTime(filePath)
SetDocumentModified(id, false)
IndicateFunctions(editor)
SettingsAppendFileToHistory(filePath)
-- activate the editor; this is needed for those cases when the editor is
-- created from some other element, for example, from a project tree.
if not skipselection then SetEditorSelection() end
@@ -149,9 +148,7 @@ local function getExtsString()
knownexts = knownexts:len() > 0 and knownexts:sub(1,-2) or nil
local exts = knownexts and TR("Known Files").." ("..knownexts..")|"..knownexts.."|" or ""
exts = exts..TR("All files").." (*)|*"
return exts
return exts..TR("All files").." (*)|*"
end
function OpenFile(event)
@@ -216,10 +213,17 @@ function SaveFileAs(editor)
fn:Normalize() -- want absolute path for dialog
local ext = fn:GetExt()
if (not ext or #ext == 0) and editor.spec and editor.spec.exts then
ext = editor.spec.exts[1]
-- set the extension on the file if assigned as this is used by OSX/Linux
-- to present the correct default "save as type" choice.
if ext then fn:SetExt(ext) end
end
local fileDialog = wx.wxFileDialog(ide.frame, TR("Save file as"),
fn:GetPath(wx.wxPATH_GET_VOLUME),
fn:GetFullName(),
"*."..(ext and #ext > 0 and ext or "*"),
-- specify the current extension plus all other extensions based on specs
(ext and #ext > 0 and "*."..ext.."|*."..ext.."|" or "")..getExtsString(),
wx.wxFD_SAVE)
if fileDialog:ShowModal() == wx.wxID_OK then
@@ -229,9 +233,12 @@ function SaveFileAs(editor)
SetEditorSelection() -- update title of the editor
FileTreeRefresh() -- refresh the tree to reflect the new file
FileTreeMarkSelected(filePath)
SetupKeywords(editor, GetFileExt(filePath))
IndicateFunctions(editor)
if MarkupStyle then MarkupStyle(editor) end
if ext ~= GetFileExt(filePath) then
-- new extension, so setup new keywords and re-apply indicators
SetupKeywords(editor, GetFileExt(filePath))
IndicateFunctions(editor)
MarkupStyle(editor)
end
saved = true
end
end
@@ -295,7 +302,8 @@ local function removePage(index)
notebook:SetSelection(prevIndex)
end
SetEditorSelection() -- will use notebook GetSelection to update
-- need to set editor selection as it's called *after* PAGE_CHANGED event
SetEditorSelection()
end
function ClosePage(selection)
@@ -384,50 +392,47 @@ function SaveOnExit(allow_cancel)
return true
end
-- circle through "fold all" => "hide base lines" => "unfold all"
function FoldSome()
local editor = GetEditor()
editor:Colourise(0, -1) -- update doc's folding info
local visible, baseFound, expanded, folded
for ln = 2, editor.LineCount - 1 do
local foldall = false -- at least on header unfolded => fold all
local hidebase = false -- at least one base is visible => hide all
for ln = 0, editor.LineCount - 1 do
local foldRaw = editor:GetFoldLevel(ln)
local foldLvl = math.mod(foldRaw, 4096)
local foldHdr = math.mod(math.floor(foldRaw / 8192), 2) == 1
if not baseFound and (foldLvl == wxstc.wxSTC_FOLDLEVELBASE) then
baseFound = true
visible = editor:GetLineVisible(ln)
end
if foldHdr then
if editor:GetFoldExpanded(ln) then
expanded = true
else
folded = true
end
end
if expanded and folded and baseFound then break end
end
local show = not visible or (not baseFound and expanded) or (expanded and folded)
local hide = visible and folded
if show then
editor:ShowLines(1, editor.LineCount-1)
-- at least one header is expanded
foldall = foldall or (foldHdr and editor:GetFoldExpanded(ln))
-- at least one base can be hidden
hidebase = hidebase or (
not foldHdr
and ln > 1 -- first line can't be hidden, so ignore it
and foldLvl == wxstc.wxSTC_FOLDLEVELBASE
and bit.band(foldRaw, wxstc.wxSTC_FOLDLEVELWHITEFLAG) == 0
and editor:GetLineVisible(ln))
end
for ln = 1, editor.LineCount - 1 do
-- shows lines; this doesn't change fold status for folded lines
if not foldall and not hidebase then editor:ShowLines(0, editor.LineCount-1) end
for ln = 0, editor.LineCount-1 do
local foldRaw = editor:GetFoldLevel(ln)
local foldLvl = math.mod(foldRaw, 4096)
local foldHdr = math.mod(math.floor(foldRaw / 8192), 2) == 1
if show then
if foldHdr then
if not editor:GetFoldExpanded(ln) then editor:ToggleFold(ln) end
end
elseif hide and (foldLvl == wxstc.wxSTC_FOLDLEVELBASE) then
if not foldHdr then
editor:HideLines(ln, ln)
end
elseif foldHdr then
if editor:GetFoldExpanded(ln) then
editor:ToggleFold(ln)
end
if foldall then
if foldHdr and editor:GetFoldExpanded(ln) then
editor:ToggleFold(ln) end
elseif hidebase then
if not foldHdr and (foldLvl == wxstc.wxSTC_FOLDLEVELBASE) then
editor:HideLines(ln, ln) end
else -- unfold all
if foldHdr and not editor:GetFoldExpanded(ln) then
editor:ToggleFold(ln) end
end
end
editor:EnsureCaretVisible()
@@ -546,12 +551,7 @@ end
function SetOpenFiles(nametab,params)
for i,doc in ipairs(nametab) do
local editor = LoadFile(doc.filename,nil,true,true) -- skip selection
if editor then
editor:SetCurrentPos(doc.cursorpos or 0)
editor:SetSelectionStart(doc.cursorpos or 0)
editor:SetSelectionEnd(doc.cursorpos or 0)
editor:EnsureCaretVisible()
end
if editor then editor:GotoPosDelayed(doc.cursorpos or 0) end
end
notebook:SetSelection(params and params.index or 0)
SetEditorSelection()
@@ -561,33 +561,35 @@ local beforeFullScreenPerspective
function ShowFullScreen(setFullScreen)
if setFullScreen then
beforeFullScreenPerspective = uimgr:SavePerspective()
uimgr:GetPane("bottomnotebook"):Show(false)
uimgr:GetPane("projpanel"):Show(false)
local panes = frame.uimgr:GetAllPanes()
for index = 0, panes:GetCount()-1 do
local name = panes:Item(index).name
if name ~= "notebook" then frame.uimgr:GetPane(name):Hide() end
end
uimgr:Update()
SetEditorSelection() -- make sure the focus is on the editor
elseif beforeFullScreenPerspective then
uimgr:LoadPerspective(beforeFullScreenPerspective)
uimgr:LoadPerspective(beforeFullScreenPerspective, true)
beforeFullScreenPerspective = nil
end
uimgr:GetPane("toolBar"):Show(not setFullScreen)
uimgr:Update()
-- On OSX, toolbar and status bar are not hidden when switched to
-- full screen: http://trac.wxwidgets.org/ticket/14259; do manually.
-- need to turn off before showing full screen and turn on after,
-- otherwise the window is restored incorrectly and is reduced in size.
if ide.osname == 'Macintosh' and setFullScreen then
frame:GetStatusBar():Hide()
frame:GetToolBar():Hide()
end
-- protect from systems that don't have ShowFullScreen (GTK on linux?)
pcall(function() frame:ShowFullScreen(setFullScreen) end)
end
local function restoreFiles(files)
-- open files, but ignore some functions that are not needed;
-- as we may be opening multiple files, it doesn't make sense to
-- select editor and do some other similar work after each file.
local noop, func = function() end, LoadFile
local genv = {SetEditorSelection = noop, SettingsAppendFileToHistory = noop}
setmetatable(genv, {__index = _G})
local env = getfenv(func)
setfenv(func, genv)
-- provide fake index so that it doesn't activate it as the index may be not
-- quite correct if some of the existing files are already open in the IDE.
SetOpenFiles(files, {index = #files + notebook:GetPageCount()})
setfenv(func, env)
if ide.osname == 'Macintosh' and not setFullScreen then
frame:GetStatusBar():Show()
frame:GetToolBar():Show()
end
end
function ProjectConfig(dir, config)
@@ -614,10 +616,7 @@ function SetOpenTabs(params)
:format(doc.filename, doc.tabname))
end
end
editor:SetCurrentPos(doc.cursorpos or 0)
editor:SetSelectionStart(doc.cursorpos or 0)
editor:SetSelectionEnd(doc.cursorpos or 0)
editor:EnsureCaretVisible()
editor:GotoPosDelayed(doc.cursorpos or 0)
end
notebook:SetSelection(params and params.index or 0)
SetEditorSelection()
@@ -665,11 +664,22 @@ local function saveAutoRecovery(event)
TR("Saved auto-recover at %s."):format(os.date("%H:%M:%S")), 1)
end
local function fastWrap(func, ...)
-- ignore SetEditorSelection that is not needed as `func` may work on
-- multipe files, but editor needs to be selected once.
local SES = SetEditorSelection
SetEditorSelection = function() end
func(...)
SetEditorSelection = SES
end
function StoreRestoreProjectTabs(curdir, newdir)
local win = ide.osname == 'Windows'
local interpreter = ide.interpreter.fname
local current, closing, restore = notebook:GetSelection(), 0, false
if ide.osname ~= 'Macintosh' then notebook:Freeze() end
if curdir and #curdir > 0 then
local lowcurdir = win and string.lower(curdir) or curdir
local lownewdir = win and string.lower(newdir) or newdir
@@ -695,16 +705,22 @@ function StoreRestoreProjectTabs(curdir, newdir)
-- close pages for those files that match the project in the reverse order
-- (as ids shift when pages are closed)
for i = #closdocs, 1, -1 do ClosePage(closdocs[i].id) end
for i = #closdocs, 1, -1 do fastWrap(ClosePage, closdocs[i].id) end
end
local files, params = ProjectConfig(newdir)
if files then restoreFiles(files) end
if files then
-- provide fake index so that it doesn't activate it as the index may be not
-- quite correct if some of the existing files are already open in the IDE.
fastWrap(SetOpenFiles, files, {index = #files + notebook:GetPageCount()})
end
if params and params.interpreter and ide.interpreter.fname ~= params.interpreter then
ProjectSetInterpreter(params.interpreter) -- set the interpreter
end
if ide.osname ~= 'Macintosh' then notebook:Thaw() end
local index = params and params.index
if notebook:GetPageCount() == 0 then NewFile()
elseif restore and current >= 0 then notebook:SetSelection(current)
@@ -720,7 +736,7 @@ function StoreRestoreProjectTabs(curdir, newdir)
ProjectConfig(newdir, {})
end
function CloseWindow(event)
local function closeWindow(event)
-- if the app is already exiting, then help it exit; wxwidgets on Windows
-- is supposed to report Shutdown/logoff events by setting CanVeto() to
-- false, but it doesn't happen. We simply leverage the fact that
@@ -737,20 +753,32 @@ function CloseWindow(event)
end
ShowFullScreen(false)
ide.frame:Hide() -- hide everything while the IDE exits
SettingsSaveAll()
if DebuggerCloseWatchWindow then DebuggerCloseWatchWindow() end
if DebuggerCloseStackWindow then DebuggerCloseStackWindow() end
if DebuggerShutdown then DebuggerShutdown() end
ide.settings:delete() -- always delete the config
if ide.session.timer then ide.session.timer:Stop() end
event:Skip()
-- without explicit exit() the IDE crashes with SIGILL exception when closed
-- on MacOS compiled under 64bit with wxwidgets 2.9.3
if ide.osname == "Macintosh" then os.exit() end
SettingsSaveAll()
ide.settings:Flush()
do -- hide all floating panes first
local panes = frame.uimgr:GetAllPanes()
for index = 0, panes:GetCount()-1 do
local pane = frame.uimgr:GetPane(panes:Item(index).name)
if pane:IsFloating() then pane:Hide() end
end
end
frame.uimgr:Update() -- hide floating panes
frame.uimgr:UnInit()
frame:Hide() -- hide the main frame while the IDE exits
-- first need to detach all processes IDE has launched as the current
-- process is likely to terminate before child processes are terminated,
-- which may lead to a crash when EVT_END_PROCESS event is called.
DetachChildProcess()
DebuggerShutdown()
if ide.session.timer then ide.session.timer:Stop() end
event:Skip()
end
frame:Connect(wx.wxEVT_CLOSE_WINDOW, CloseWindow)
frame:Connect(wx.wxEVT_CLOSE_WINDOW, closeWindow)
frame:Connect(wx.wxEVT_TIMER, saveAutoRecovery)

View File

@@ -13,10 +13,9 @@ debugger.server = nil -- DebuggerServer object when debugging, else nil
debugger.running = false -- true when the debuggee is running
debugger.listening = false -- true when the debugger is listening for a client
debugger.portnumber = ide.config.debugger.port or mobdebug.port -- the port # to use for debugging
debugger.watchWindow = nil -- the watchWindow, nil when not created
debugger.watchCtrl = nil -- the child ctrl in the watchWindow
debugger.stackWindow = nil -- the stackWindow, nil when not created
debugger.stackCtrl = nil -- the child ctrl in the stackWindow
debugger.watchCtrl = nil -- the watch ctrl that shows watch information
debugger.stackCtrl = nil -- the stack ctrl that shows stack information
debugger.toggleview = { stackpanel = false, watchpanel = false }
debugger.hostname = ide.config.debugger.hostname or (function()
local addr = wx.wxIPV4address() -- check what address is resolvable
for _, host in ipairs({wx.wxGetHostName(), wx.wxGetFullHostName()}) do
@@ -32,12 +31,18 @@ local CURRENT_LINE_MARKER_VALUE = 2^CURRENT_LINE_MARKER
local BREAKPOINT_MARKER = StylesGetMarker("breakpoint")
local BREAKPOINT_MARKER_VALUE = 2^BREAKPOINT_MARKER
local activate = {CHECKONLY = 1, NOREPORT = 2}
local function q(s) return s:gsub('([%(%)%.%%%+%-%*%?%[%^%$%]])','%%%1') end
local function updateWatchesSync(num)
local watchCtrl = debugger.watchCtrl
if watchCtrl and debugger.server and not debugger.running
and ide.frame.uimgr:GetPane("watchpanel"):IsShown()
and not debugger.scratchpad and not (debugger.options or {}).noeval then
local bgcl = watchCtrl:GetBackgroundColour()
local hicl = wx.wxColour(math.floor(bgcl:Red()*.9),
math.floor(bgcl:Green()*.9), math.floor(bgcl:Blue()*.9))
for idx = 0, watchCtrl:GetItemCount() - 1 do
if not num or idx == num then
local expression = watchCtrl:GetItemText(idx)
@@ -54,9 +59,7 @@ local function updateWatchesSync(num)
watchCtrl:GetItem(litem)
watchCtrl:SetItemBackgroundColour(idx,
watchCtrl:GetItem(litem) and newval ~= litem:GetText()
and ide.config.styles.caretlinebg
and wx.wxColour(unpack(ide.config.styles.caretlinebg.bg))
or watchCtrl:GetBackgroundColour())
and hicl or bgcl)
end
watchCtrl:SetItem(idx, 1, newval)
@@ -79,8 +82,9 @@ end
local function updateStackSync()
local stackCtrl = debugger.stackCtrl
if stackCtrl and debugger.server
and not debugger.running and not debugger.scratchpad then
if stackCtrl and debugger.server and not debugger.running
and ide.frame.uimgr:GetPane("stackpanel"):IsShown()
and not debugger.scratchpad then
local stack, _, err = debugger.stack()
if not stack or #stack == 0 then
stackCtrl:DeleteAllItems()
@@ -123,7 +127,7 @@ local function updateStackSync()
end
end
for name,val in pairs(frame[3]) do
local value, comment = val[1], val[2]
local value, comment = val[1], tostring(val[2])
local text = ("%s = %s%s"):
format(name, mobdebug.line(value, params),
simpleType[type(value)] and "" or (" --[["..comment.."]]"))
@@ -136,6 +140,7 @@ local function updateStackSync()
stackCtrl:Expand(callitem)
end
stackCtrl:EnsureVisible(stackCtrl:GetFirstChild(root))
stackCtrl:SetScrollPos(wx.wxHORIZONTAL, 0, true)
stackCtrl:Thaw()
end
end
@@ -158,6 +163,28 @@ local function updateWatches(num)
end
end
local function debuggerToggleViews(show)
local mgr = ide.frame.uimgr
local refresh = false
for view, needed in pairs(debugger.toggleview) do
local pane = mgr:GetPane(view)
if show then -- starting debugging and pane is not shown
debugger.toggleview[view] = not pane:IsShown()
if debugger.toggleview[view] and needed then
pane:Show()
refresh = true
end
else -- completing debugging and pane is shown
debugger.toggleview[view] = pane:IsShown() and needed
if debugger.toggleview[view] then
pane:Hide()
refresh = true
end
end
end
if refresh then mgr:Update() end
end
local function killClient()
if (debugger.pid) then
-- using SIGTERM for some reason kills not only the debugee process,
@@ -174,7 +201,7 @@ local function killClient()
end
end
local function activateDocument(file, line, skipauto)
local function activateDocument(file, line, activatehow)
if not file then return end
if not wx.wxIsAbsolutePath(file) and debugger.basedir then
@@ -188,30 +215,56 @@ local function activateDocument(file, line, skipauto)
-- skip those tabs that may have file without names (untitled.lua)
if document.filePath and fileName:SameAs(wx.wxFileName(document.filePath)) then
local editor = document.editor
ClearAllCurrentLineMarkers()
if line then
if line == 0 then -- special case; find the first executable line
line = math.huge
local func = loadstring(editor:GetText())
if func then -- .activelines == {[3] = true, [4] = true, ...}
for l in pairs(debug.getinfo(func, "L").activelines) do
if l < line then line = l end
end
end
if line == math.huge then line = 1 end
end
local line = line - 1 -- editor line operations are zero-based
editor:MarkerAdd(line, CURRENT_LINE_MARKER)
-- found and marked what we are looking for;
-- don't need to activate with CHECKONLY (this assumes line is given)
if activatehow == activate.CHECKONLY then return editor end
local firstline = editor:DocLineFromVisible(editor:GetFirstVisibleLine())
local lastline = math.min(editor:GetLineCount(),
editor:DocLineFromVisible(editor:GetFirstVisibleLine() + editor:LinesOnScreen()))
-- if the line is already on the screen, then don't enforce policy
if line <= firstline or line >= lastline then
editor:EnsureVisibleEnforcePolicy(line)
end
end
local selection = document.index
RequestAttention()
notebook:SetSelection(selection)
SetEditorSelection(selection)
ClearAllCurrentLineMarkers()
if line then
editor:MarkerAdd(line-1, CURRENT_LINE_MARKER)
editor:EnsureVisibleEnforcePolicy(line-1)
end
activated = editor
break
end
end
if not (activated or indebugger or debugger.loop or skipauto)
if not (activated or indebugger or debugger.loop or activatehow == activate.CHECKONLY)
and ide.config.editor.autoactivate then
-- found file, but can't activate yet (because this part may be executed
-- in a different co-routine), so schedule pending activation.
-- in a different coroutine), so schedule pending activation.
if wx.wxFileName(file):FileExists() then
debugger.activate = {file, line}
return true -- report successful activation, even though it's pending
end
if not debugger.missing[file] then -- only report files once per session
-- only report files once per session and if not asked to skip
if not debugger.missing[file] and activatehow ~= activate.NOREPORT then
debugger.missing[file] = true
DisplayOutputLn(TR("Couldn't activate file '%s' for debugging; continuing without it.")
:format(file))
@@ -297,6 +350,16 @@ debugger.shell = function(expression, isstatement)
end
end
local function stoppedAtBreakpoint(file, line)
-- if this document can be activated and the current line has a breakpoint
local editor = activateDocument(file, line, activate.CHECKONLY)
if not editor then return false end
local current = editor:MarkerNext(0, CURRENT_LINE_MARKER_VALUE)
local breakpoint = editor:MarkerNext(current, BREAKPOINT_MARKER_VALUE)
return breakpoint > -1 and breakpoint == current
end
debugger.listen = function()
local server = socket.bind("*", debugger.portnumber)
DisplayOutputLn(TR("Debugger server started at %s:%d.")
@@ -314,6 +377,10 @@ debugger.listen = function()
end)
local options = debugger.options or {}
-- this may be a remote call without using an interpreter and as such
-- debugger.options may not be set, but runonstart is still configured.
if not options.runstart then options.runstart = ide.config.debugger.runonstart end
if not debugger.scratchpad then SetAllEditorsReadOnly(true) end
debugger.server = copas.wrap(skt)
@@ -378,6 +445,9 @@ debugger.listen = function()
.." "..TR("Compilation error")
..":\n"..err)
return debugger.terminate()
elseif options.runstart and stoppedAtBreakpoint(file, line) then
activateDocument(file, line)
options.runstart = false
end
elseif not (options.run or debugger.scratchpad) then
local file, line, err = debugger.loadfile(startfile)
@@ -391,13 +461,16 @@ debugger.listen = function()
..":\n"..err)
return debugger.terminate()
elseif options.runstart then
-- do nothing as no activation is required; the script will be run
if stoppedAtBreakpoint(file or startfile, line or 0) then
activateDocument(file or startfile, line or 0)
options.runstart = false
end
elseif file and line then
local activated = activateDocument(file, line, true)
local activated = activateDocument(file, line, activate.NOREPORT)
-- if not found, check using full file path and reset basedir
if not activated and not wx.wxIsAbsolutePath(file) then
activated = activateDocument(startpath..file, line, true)
activated = activateDocument(startpath..file, line, activate.NOREPORT)
if activated then
debugger.basedir = startpath
debugger.handle("basedir " .. debugger.basedir)
@@ -431,7 +504,7 @@ debugger.listen = function()
end
-- if found a local mapping under basedir
activated = longestpath and activateDocument(longestpath, line, true)
activated = longestpath and activateDocument(longestpath, line, activate.NOREPORT)
if activated then
-- find remote basedir by removing the tail from remote file
debugger.handle("basedir " .. debugger.basedir .. "\t" .. remotedir)
@@ -453,7 +526,7 @@ debugger.listen = function()
debugger.scratchable = ide.interpreter.scratchextloop ~= nil
else
debugger.scratchable = true
activateDocument(startfile, 1)
activateDocument(startfile, 0) -- find the appropriate line
end
end
@@ -461,6 +534,7 @@ debugger.listen = function()
ShellSupportRemote(debugger.shell)
end
debuggerToggleViews(true)
updateStackSync()
updateWatchesSync()
@@ -486,9 +560,7 @@ debugger.handle = function(command, server, options)
local verbose = ide.config.debugger.verbose
local osexit, gprint
osexit, os.exit = os.exit, function () end
if (verbose) then
gprint, _G.print = _G.print, function (...) DisplayOutputLn(...) end
end
gprint, _G.print = _G.print, function (...) if verbose then DisplayOutputLn(...) end end
debugger.running = true
if verbose then DisplayOutputLn("Debugger sent (command):", command) end
@@ -497,7 +569,7 @@ debugger.handle = function(command, server, options)
debugger.running = false
os.exit = osexit
if (verbose) then _G.print = gprint end
_G.print = gprint
return file, line, err
end
@@ -541,6 +613,7 @@ debugger.exec = function(command)
if debugger.breaking then
DisplayOutputLn(TR("Debugging suspended at %s:%s (couldn't activate the file).")
:format(file, line))
updateStackAndWatches()
return
end
-- redo now; if the call is from the debugger, then repeat
@@ -644,57 +717,6 @@ debugger.quickeval = function(var, callback)
end
end
----------------------------------------------
-- public api
function DebuggerAttachDefault(options)
debugger.options = options
if (debugger.listening) then return end
debugger.listen()
end
function DebuggerShutdown()
if debugger.server then debugger.terminate() end
if debugger.pid then killClient() end
-- wait for a little bit as in some rare cases when closing the debugger
-- with a running application under OSX, the process crashes (wxlua2.8.12).
if ide.osname == "Macintosh" then wx.wxMilliSleep(100) end
end
function DebuggerStop()
if (debugger.server) then
debugger.server = nil
debugger.pid = nil
SetAllEditorsReadOnly(false)
ShellSupportRemote(nil)
ClearAllCurrentLineMarkers()
DebuggerScratchpadOff()
local lines = TR("traced %d instruction", debugger.stats.line):format(debugger.stats.line)
DisplayOutputLn(TR("Debugging session completed (%s)."):format(lines))
else
-- it's possible that the application couldn't start, or that the
-- debugger in the application didn't start, which means there is
-- no debugger.server, but scratchpad may still be on. Turn it off.
DebuggerScratchpadOff()
end
end
function DebuggerCloseStackWindow()
if (debugger.stackWindow) then
SettingsSaveFramePosition(debugger.stackWindow, "StackWindow")
debugger.stackCtrl = nil
debugger.stackWindow = nil
end
end
function DebuggerCloseWatchWindow()
if (debugger.watchWindow) then
SettingsSaveFramePosition(debugger.watchWindow, "WatchWindow")
debugger.watchCtrl = nil
debugger.watchWindow = nil
end
end
-- need imglist to be a file local variable as SetImageList takes ownership
-- of it and if done inside a function, icons do not work as expected
local imglist = wx.wxImageList(16,16)
@@ -709,34 +731,15 @@ do
imglist:Add(getBitmap(wx.wxART_REPORT_VIEW, wx.wxART_OTHER, size))
end
function DebuggerCreateStackWindow()
if (debugger.stackWindow) then return updateStackAndWatches() end
local width = 360
local stackWindow = wx.wxFrame(ide.frame, wx.wxID_ANY,
TR("Stack Window"),
wx.wxDefaultPosition, wx.wxSize(width, 200),
wx.wxDEFAULT_FRAME_STYLE + wx.wxFRAME_FLOAT_ON_PARENT)
debugger.stackWindow = stackWindow
local stackCtrl = wx.wxTreeCtrl(stackWindow, wx.wxID_ANY,
wx.wxDefaultPosition, wx.wxDefaultSize,
local width, height = 360, 200
function debuggerCreateStackWindow()
local stackCtrl = wx.wxTreeCtrl(ide.frame, wx.wxID_ANY,
wx.wxDefaultPosition, wx.wxSize(width, height),
wx.wxTR_LINES_AT_ROOT + wx.wxTR_HAS_BUTTONS + wx.wxTR_SINGLE + wx.wxTR_HIDE_ROOT)
debugger.stackCtrl = stackCtrl
stackCtrl:SetImageList(imglist)
stackWindow:CentreOnParent()
SettingsRestoreFramePosition(stackWindow, "StackWindow")
stackWindow:Show(true)
stackWindow:Connect(wx.wxEVT_CLOSE_WINDOW,
function (event)
DebuggerCloseStackWindow()
stackWindow = nil
stackCtrl = nil
event:Skip()
end)
stackCtrl:Connect( wx.wxEVT_COMMAND_TREE_ITEM_EXPANDING,
function (event)
@@ -761,33 +764,24 @@ function DebuggerCreateStackWindow()
stackCtrl:SortChildren(item_id)
return true
end)
stackCtrl:Connect( wx.wxEVT_COMMAND_TREE_ITEM_COLLAPSED,
function() return true end)
updateStackAndWatches()
local notebook = wxaui.wxAuiNotebook(frame, wx.wxID_ANY,
wx.wxDefaultPosition, wx.wxDefaultSize,
wxaui.wxAUI_NB_DEFAULT_STYLE + wxaui.wxAUI_NB_TAB_EXTERNAL_MOVE
- wxaui.wxAUI_NB_CLOSE_ON_ACTIVE_TAB + wx.wxNO_BORDER)
notebook:AddPage(stackCtrl, TR("Stack"), true)
local mgr = ide.frame.uimgr
mgr:AddPane(notebook, wxaui.wxAuiPaneInfo():
Name("stackpanel"):Float():
MinSize(width/2,height/2):
BestSize(width,height):FloatingSize(width,height):
PinButton(true):Hide())
mgr.defaultPerspective = mgr:SavePerspective() -- resave default perspective
end
function DebuggerCreateWatchWindow()
if (debugger.watchWindow) then return updateWatches() end
local width = 360
local watchWindow = wx.wxFrame(ide.frame, wx.wxID_ANY,
TR("Watch Window"),
wx.wxDefaultPosition, wx.wxSize(width, 200),
wx.wxDEFAULT_FRAME_STYLE + wx.wxFRAME_FLOAT_ON_PARENT)
debugger.watchWindow = watchWindow
local watchMenu = wx.wxMenu{
{ ID_ADDWATCH, TR("&Add Watch")..KSC(ID_ADDWATCH) },
{ ID_EDITWATCH, TR("&Edit Watch")..KSC(ID_EDITWATCH) },
{ ID_REMOVEWATCH, TR("&Remove Watch")..KSC(ID_REMOVEWATCH) },
{ ID_EVALUATEWATCH, TR("Evaluate &Watches")..KSC(ID_EVALUATEWATCH) }}
local watchMenuBar = wx.wxMenuBar()
watchMenuBar:Append(watchMenu, TR("&Watches"))
watchWindow:SetMenuBar(watchMenuBar)
local watchCtrl = wx.wxListCtrl(watchWindow, wx.wxID_ANY,
local function debuggerCreateWatchWindow()
local watchCtrl = wx.wxListCtrl(frame, wx.wxID_ANY,
wx.wxDefaultPosition, wx.wxDefaultSize,
wx.wxLC_REPORT + wx.wxLC_EDIT_LABELS)
@@ -803,9 +797,10 @@ function DebuggerCreateWatchWindow()
info:SetWidth(width * 0.56)
watchCtrl:InsertColumn(1, info)
watchWindow:CentreOnParent()
SettingsRestoreFramePosition(watchWindow, "WatchWindow")
watchWindow:Show(true)
local watchMenu = wx.wxMenu{
{ ID_ADDWATCH, TR("&Add Watch")..KSC(ID_ADDWATCH) },
{ ID_EDITWATCH, TR("&Edit Watch")..KSC(ID_EDITWATCH) },
{ ID_DELETEWATCH, TR("&Delete Watch")..KSC(ID_DELETEWATCH) }}
local function findSelectedWatchItem()
local count = watchCtrl:GetSelectedItemCount()
@@ -820,53 +815,47 @@ function DebuggerCreateWatchWindow()
end
local defaultExpr = ""
local function addWatch()
local row = watchCtrl:InsertItem(watchCtrl:GetItemCount(), TR("Expr"))
watchCtrl:SetItem(row, 0, defaultExpr)
watchCtrl:SetItem(row, 1, TR("Value"))
watchCtrl:EditLabel(row)
end
watchWindow:Connect(wx.wxEVT_CLOSE_WINDOW,
local function editWatch()
local row = findSelectedWatchItem()
if row >= 0 then watchCtrl:EditLabel(row) end
end
local function deleteWatch()
local row = findSelectedWatchItem()
if row >= 0 then watchCtrl:DeleteItem(row) end
end
watchCtrl:Connect(wx.wxEVT_CONTEXT_MENU,
function (event)
DebuggerCloseWatchWindow()
watchWindow = nil
watchCtrl = nil
watchCtrl:PopupMenu(watchMenu)
end)
watchCtrl:Connect(wx.wxEVT_KEY_DOWN,
function (event)
local keycode = event:GetKeyCode()
if (keycode == wx.WXK_DELETE) then return deleteWatch()
elseif (keycode == wx.WXK_INSERT) then return addWatch()
elseif (keycode == wx.WXK_F2) then return editWatch()
end
event:Skip()
end)
watchWindow:Connect(ID_ADDWATCH, wx.wxEVT_COMMAND_MENU_SELECTED,
function ()
local row = watchCtrl:InsertItem(watchCtrl:GetItemCount(), TR("Expr"))
watchCtrl:SetItem(row, 0, defaultExpr)
watchCtrl:SetItem(row, 1, TR("Value"))
watchCtrl:EditLabel(row)
end)
watchCtrl:Connect(ID_ADDWATCH, wx.wxEVT_COMMAND_MENU_SELECTED, addWatch)
watchWindow:Connect(ID_EDITWATCH, wx.wxEVT_COMMAND_MENU_SELECTED,
function ()
local row = findSelectedWatchItem()
if row >= 0 then
watchCtrl:EditLabel(row)
end
end)
watchWindow:Connect(ID_EDITWATCH, wx.wxEVT_UPDATE_UI,
function (event)
event:Enable(watchCtrl:GetSelectedItemCount() > 0)
end)
watchCtrl:Connect(ID_EDITWATCH, wx.wxEVT_COMMAND_MENU_SELECTED, editWatch)
watchCtrl:Connect(ID_EDITWATCH, wx.wxEVT_UPDATE_UI,
function (event) event:Enable(watchCtrl:GetSelectedItemCount() > 0) end)
watchWindow:Connect(ID_REMOVEWATCH, wx.wxEVT_COMMAND_MENU_SELECTED,
function ()
local row = findSelectedWatchItem()
if row >= 0 then
watchCtrl:DeleteItem(row)
end
end)
watchWindow:Connect(ID_REMOVEWATCH, wx.wxEVT_UPDATE_UI,
function (event)
event:Enable(watchCtrl:GetSelectedItemCount() > 0)
end)
watchWindow:Connect(ID_EVALUATEWATCH, wx.wxEVT_COMMAND_MENU_SELECTED,
function () updateWatches() end)
watchWindow:Connect(ID_EVALUATEWATCH, wx.wxEVT_UPDATE_UI,
function (event)
event:Enable(watchCtrl:GetItemCount() > 0)
end)
watchCtrl:Connect(ID_DELETEWATCH, wx.wxEVT_COMMAND_MENU_SELECTED, deleteWatch)
watchCtrl:Connect(ID_DELETEWATCH, wx.wxEVT_UPDATE_UI,
function (event) event:Enable(watchCtrl:GetSelectedItemCount() > 0) end)
watchCtrl:Connect(wx.wxEVT_COMMAND_LIST_END_LABEL_EDIT,
function (event)
@@ -881,10 +870,37 @@ function DebuggerCreateWatchWindow()
end
event:Skip()
end)
local notebook = wxaui.wxAuiNotebook(frame, wx.wxID_ANY,
wx.wxDefaultPosition, wx.wxDefaultSize,
wxaui.wxAUI_NB_DEFAULT_STYLE + wxaui.wxAUI_NB_TAB_EXTERNAL_MOVE
- wxaui.wxAUI_NB_CLOSE_ON_ACTIVE_TAB + wx.wxNO_BORDER)
notebook:AddPage(watchCtrl, TR("Watch"), true)
local mgr = ide.frame.uimgr
mgr:AddPane(notebook, wxaui.wxAuiPaneInfo():
Name("watchpanel"):Float():
MinSize(width/2,height/2):
BestSize(width,height):FloatingSize(width,height):
PinButton(true):Hide())
mgr.defaultPerspective = mgr:SavePerspective() -- resave default perspective
end
debuggerCreateStackWindow()
debuggerCreateWatchWindow()
----------------------------------------------
-- public api
DebuggerRefreshPanels = updateStackAndWatches
function DebuggerAddWatch(watch)
if (not debugger.watchWindow) then DebuggerCreateWatchWindow() end
local mgr = ide.frame.uimgr
local pane = mgr:GetPane("watchpanel")
if (not pane:IsShown()) then
pane:Show()
mgr:Update()
end
local watchCtrl = debugger.watchCtrl
-- check if this expression is already on the list
@@ -899,6 +915,36 @@ function DebuggerAddWatch(watch)
updateWatches(row)
end
function DebuggerAttachDefault(options)
debugger.options = options
if (debugger.listening) then return end
debugger.listen()
end
function DebuggerShutdown()
if debugger.server then debugger.terminate() end
if debugger.pid then killClient() end
end
function DebuggerStop()
if (debugger.server) then
debugger.server = nil
debugger.pid = nil
SetAllEditorsReadOnly(false)
ShellSupportRemote(nil)
ClearAllCurrentLineMarkers()
DebuggerScratchpadOff()
debuggerToggleViews(false)
local lines = TR("traced %d instruction", debugger.stats.line):format(debugger.stats.line)
DisplayOutputLn(TR("Debugging session completed (%s)."):format(lines))
else
-- it's possible that the application couldn't start, or that the
-- debugger in the application didn't start, which means there is
-- no debugger.server, but scratchpad may still be on. Turn it off.
DebuggerScratchpadOff()
end
end
function DebuggerMakeFileName(editor, filePath)
return filePath or ide.config.default.fullname
end

View File

@@ -17,8 +17,7 @@ local projcombobox = ide.frame.projpanel.projcombobox
-- Only update if the text has changed.
local statusTextTable = { "OVR?", "R/O?", "Cursor Pos" }
-- set funclist font to be the same as the combobox in the project dropdown
funclist:SetFont(ide.font.fNormal)
funclist:SetFont(ide.font.dNormal)
local function updateStatusText(editor)
local texts = { "", "", "" }
@@ -151,6 +150,7 @@ function SetEditorSelection(selection)
editor:SetSTCFocus(true)
local id = editor:GetId()
FileTreeMarkSelected(openDocuments[id] and openDocuments[id].filePath or '')
AddToFileHistory(openDocuments[id] and openDocuments[id].filePath)
else
FileTreeMarkSelected('')
end
@@ -212,7 +212,12 @@ function EditorAutoComplete(editor)
local lt = linetx:sub(1,localpos)
lt = lt:gsub("%s*(["..editor.spec.sep.."])%s*", "%1")
lt = lt:match("[^%[%(%s]*$")
-- strip closed brace scopes
lt = lt:gsub("%b()","")
lt = lt:gsub("%b[]","")
lt = lt:gsub("%b{}","")
-- match from starting brace
lt = lt:match("[^%[%(%{%s]*$")
-- know now which string is to be completed
local userList = CreateAutoCompList(editor,lt)
@@ -348,7 +353,7 @@ function CreateEditor()
editor:SetCaretLineVisible(ide.config.editor.caretline and 1 or 0)
editor:SetVisiblePolicy(wxstc.wxSTC_VISIBLE_SLOP, 3)
editor:SetVisiblePolicy(wxstc.wxSTC_VISIBLE_STRICT, 3)
editor:SetMarginWidth(0, editor:TextWidth(32, "99999_")) -- line # margin
@@ -367,9 +372,12 @@ function CreateEditor()
editor:SetFoldFlags(wxstc.wxSTC_FOLDFLAG_LINEBEFORE_CONTRACTED +
wxstc.wxSTC_FOLDFLAG_LINEAFTER_CONTRACTED)
editor:SetProperty("fold", "1")
editor:SetProperty("fold.compact", ide.config.editor.foldcompact and "1" or "0")
editor:SetProperty("fold.comment", "1")
-- allow multiple selection and multi-cursor editing if supported
if ide.wxver >= "2.9.5" then
editor:SetMultipleSelection(1)
editor:SetAdditionalCaretsBlink(1)
editor:SetAdditionalSelectionTyping(1)
end
do
local fg, bg = wx.wxWHITE, wx.wxColour(128, 128, 128)
@@ -393,6 +401,34 @@ function CreateEditor()
editor:AutoCompStops([[ \n\t=-+():.,;*/!"'$%&~'#°^@?´`<>][|}{]])
end
-- GotoPos should work by itself, but it doesn't (wx 2.9.5).
-- This is likely because the editor window hasn't been refreshed yet,
-- so its LinesOnScreen method returns 0/-1, which skews the calculations.
-- To avoid this, the caret line is made visible at the first opportunity.
do
local redolater
function editor:GotoPosDelayed(pos)
local badtime = self:LinesOnScreen() <= 0 -- -1 on OSX, 0 on Windows
if pos then
if badtime then
redolater = pos
-- without this GotoPos the content is not scrolled correctly on
-- Windows, but with this it's not scrolled correctly on OSX.
if ide.osname ~= 'Macintosh' then self:GotoPos(pos) end
else
redolater = nil
self:GotoPos(pos)
end
elseif not badtime and redolater then
-- reset the left margin first to make sure that the position
-- is set "from the left" to get the best content displayed.
self:SetXOffset(0)
self:GotoPos(redolater)
redolater = nil
end
end
end
editor.ev = {}
editor:Connect(wxstc.wxEVT_STC_MARGINCLICK,
function (event)
@@ -414,17 +450,17 @@ function CreateEditor()
editor:Connect(wxstc.wxEVT_STC_MODIFIED,
function (event)
SetAutoRecoveryMark()
if (editor.assignscache and editor:GetCurrentLine() ~= editor.assignscache.line) then
editor.assignscache = false
end
local evtype = event:GetModificationType()
if (bit.band(evtype,wxstc.wxSTC_MOD_INSERTTEXT) ~= 0) then
SetAutoRecoveryMark()
table.insert(editor.ev,{event:GetPosition(),event:GetLinesAdded()})
DynamicWordsAdd("post",editor,nil,editor:LineFromPosition(event:GetPosition()),event:GetLinesAdded())
end
if (bit.band(evtype,wxstc.wxSTC_MOD_DELETETEXT) ~= 0) then
SetAutoRecoveryMark()
table.insert(editor.ev,{event:GetPosition(),0})
DynamicWordsAdd("post",editor,nil,editor:LineFromPosition(event:GetPosition()),0)
end
@@ -565,16 +601,33 @@ function CreateEditor()
SetDocumentModified(editor:GetId(), true)
end)
-- "updateStatusText" should be called in UPDATEUI event, but it creates
-- several performance problems on Windows (using wx2.9.5+) when
-- brackets or backspace is used (very slow screen repaint with 0.5s delay).
-- Moving it to PAINTED event creates problems on OSX (using wx2.9.5+),
-- where refresh of R/W and R/O status in the status bar is delayed.
editor:Connect(wxstc.wxEVT_STC_PAINTED,
function ()
if ide.osname == 'Windows' then updateStatusText(editor) end
end)
editor:Connect(wxstc.wxEVT_STC_UPDATEUI,
function ()
updateStatusText(editor)
if ide.osname ~= 'Windows' then updateStatusText(editor) end
editor:GotoPosDelayed()
updateBraceMatch(editor)
local minupdated
for _,iv in ipairs(editor.ev) do
local line = editor:LineFromPosition(iv[1])
if not minupdated or line < minupdated then minupdated = line end
IndicateFunctions(editor,line,line+iv[2])
if MarkupStyle then MarkupStyle(editor,line,line+iv[2]+1) end
end
if MarkupStyleRefresh then MarkupStyleRefresh(editor, editor.ev) end
local firstline = editor:DocLineFromVisible(editor:GetFirstVisibleLine())
local lastline = math.min(editor:GetLineCount(),
editor:DocLineFromVisible(editor:GetFirstVisibleLine() + editor:LinesOnScreen()))
MarkupStyle(editor,minupdated or firstline,lastline)
editor.ev = {}
end)
@@ -589,6 +642,16 @@ function CreateEditor()
event:Skip()
end)
if ide.config.editor.nomousezoom then
-- disable zoom using mouse wheel as it triggers zooming when scrolling
-- on OSX with kinetic scroll and then pressing CMD.
editor:Connect(wx.wxEVT_MOUSEWHEEL,
function (event)
if wx.wxGetKeyState(wx.WXK_CONTROL) then return end
event:Skip()
end)
end
local inhandler = false
editor:Connect(wx.wxEVT_SET_FOCUS,
function (event)
@@ -602,23 +665,30 @@ function CreateEditor()
editor:Connect(wx.wxEVT_KEY_DOWN,
function (event)
local keycode = event:GetKeyCode()
local mod = event:GetModifiers()
local first, last = 0, notebook:GetPageCount()-1
if keycode == wx.WXK_ESCAPE and frame:IsFullScreen() then
ShowFullScreen(false)
elseif event:ControlDown() and
(keycode == wx.WXK_PAGEUP or keycode == wx.WXK_TAB and event:ShiftDown()) then
-- Ctrl-Home and Ctrl-End don't work on OSX with 2.9.5+; fix it
elseif ide.osname == 'Macintosh' and ide.wxver >= "2.9.5"
and (mod == wx.wxMOD_RAW_CONTROL or mod == (wx.wxMOD_RAW_CONTROL + wx.wxMOD_SHIFT))
and (keycode == wx.WXK_HOME or keycode == wx.WXK_END) then
local pos = keycode == wx.WXK_HOME and 0 or editor:GetLength()
if event:ShiftDown() -- mark selection and scroll to caret
then editor:SetCurrentPos(pos) editor:EnsureCaretVisible()
else editor:GotoPos(pos) end
elseif mod == wx.wxMOD_RAW_CONTROL and keycode == wx.WXK_PAGEUP
or mod == (wx.wxMOD_RAW_CONTROL + wx.wxMOD_SHIFT) and keycode == wx.WXK_TAB then
if notebook:GetSelection() == first
then notebook:SetSelection(last)
else notebook:AdvanceSelection(false) end
elseif event:ControlDown() and
(keycode == wx.WXK_PAGEDOWN or keycode == wx.WXK_TAB) then
elseif mod == wx.wxMOD_RAW_CONTROL
and (keycode == wx.WXK_PAGEDOWN or keycode == wx.WXK_TAB) then
if notebook:GetSelection() == last
then notebook:SetSelection(first)
else notebook:AdvanceSelection(true) end
elseif (keycode == wx.WXK_DELETE or keycode == wx.WXK_BACK)
-- ide.osname == 'Macintosh' has wx.wxMOD_NONE not defined
-- for some reason (at least in wxlua 2.8.12.1)
and (event:GetModifiers() == (wx.wxMOD_NONE or 0)) then
and (mod == wx.wxMOD_NONE) then
-- Delete and Backspace behave the same way for selected text
if #(editor:GetSelectedText()) > 0 then
editor:SetTargetStart(editor:GetSelectionStart())
@@ -644,8 +714,12 @@ function CreateEditor()
editor:SetTargetEnd(pos+1)
end
editor:ReplaceTarget("")
elseif ide.osname == "Unix" and ide.wxver >= "2.9.5"
and keycode == ('T'):byte() and mod == wx.wxMOD_CONTROL then
ide.frame:AddPendingEvent(wx.wxCommandEvent(
wx.wxEVT_COMMAND_MENU_SELECTED, ID_SHOWTOOLTIP))
else
if ide.osname == 'Macintosh' and event:CmdDown() then
if ide.osname == 'Macintosh' and mod == wx.wxMOD_META then
return -- ignore a key press if Command key is also pressed
end
event:Skip()
@@ -702,7 +776,7 @@ function AddEditor(editor, name)
local id = editor:GetId()
local document = {}
document.editor = editor
document.index = notebook:GetSelection()
document.index = notebook:GetPageIndex(editor)
document.fileName = nil
document.filePath = nil
document.modTime = nil
@@ -825,6 +899,17 @@ function SetupKeywords(editor, ext, forcespec, styles, font, fontitalic)
editor.spec = ide.specs.none
end
-- need to set folding property after lexer is set, otherwise
-- the folds are not shown (wxwidgets 2.9.5)
editor:SetProperty("fold", "1")
editor:SetProperty("fold.compact", ide.config.editor.foldcompact and "1" or "0")
editor:SetProperty("fold.comment", "1")
-- quickfix to prevent weird looks, otherwise need to update styling mechanism for cpp
-- cpp "greyed out" styles are styleid + 64
editor:SetProperty("lexer.cpp.track.preprocessor", "0")
editor:SetProperty("lexer.cpp.update.preprocessor", "0")
StylesApplyToEditor(styles or ide.config.styles, editor,
font or ide.font.eNormal,fontitalic or ide.font.eItalic,lexerstyleconvert)
end
@@ -832,42 +917,50 @@ end
----------------------------------------------------
-- function list for current file
-- wx.wxEVT_SET_FOCUS is not triggered for wxChoice on Mac (wx 2.8.12),
-- so use wx.wxEVT_LEFT_DOWN instead
funclist:Connect(ide.osname == 'Macintosh' and wx.wxEVT_LEFT_DOWN or wx.wxEVT_SET_FOCUS,
function (event)
event:Skip()
local function refreshFunctionList(event)
event:Skip()
local editor = GetEditor()
if (editor and not (editor.spec and editor.spec.isfndef)) then return end
local editor = GetEditor()
if (editor and not (editor.spec and editor.spec.isfndef)) then return end
-- parse current file and update list
-- first populate with the current label to minimize flicker
-- then populate the list and update the label
local current = funclist:GetCurrentSelection()
local label = funclist:GetString(current)
local default = funclist:GetString(0)
funclist:Clear()
funclist:Append(current ~= wx.wxNOT_FOUND and label or default, 0)
funclist:SetSelection(0)
-- parse current file and update list
-- first populate with the current label to minimize flicker
-- then populate the list and update the label
local current = funclist:GetCurrentSelection()
local label = funclist:GetString(current)
local default = funclist:GetString(0)
funclist:Clear()
funclist:Append(current ~= wx.wxNOT_FOUND and label or default, 0)
funclist:SetSelection(0)
local lines = 0
local linee = (editor and editor:GetLineCount() or 0)-1
for line=lines,linee do
local tx = editor:GetLine(line)
local s,_,cap,l = editor.spec.isfndef(tx)
if (s) then
local ls = editor:PositionFromLine(line)
local style = bit.band(editor:GetStyleAt(ls+s),31)
if not (editor.spec.iscomment[style] or editor.spec.isstring[style]) then
funclist:Append((l and " " or "")..cap,line)
end
local lines = 0
local linee = (editor and editor:GetLineCount() or 0)-1
for line=lines,linee do
local tx = editor:GetLine(line)
local s,_,cap,l = editor.spec.isfndef(tx)
if (s) then
local ls = editor:PositionFromLine(line)
local style = bit.band(editor:GetStyleAt(ls+s),31)
if not (editor.spec.iscomment[style] or editor.spec.isstring[style]) then
funclist:Append((l and " " or "")..cap,line)
end
end
end
funclist:SetString(0, default)
funclist:SetSelection(current ~= wx.wxNOT_FOUND and current or 0)
end)
funclist:SetString(0, default)
funclist:SetSelection(current ~= wx.wxNOT_FOUND and current or 0)
end
-- wx.wxEVT_SET_FOCUS is not triggered for wxChoice on Mac (wx 2.8.12),
-- so use wx.wxEVT_LEFT_DOWN instead; none of the events are triggered for
-- wxChoice on Linux (wx 2.9.5+), so use EVT_ENTER_WINDOW attached to the
-- toolbar itself until something better is available.
if ide.osname == 'Unix' then
ide.frame.toolBar:Connect(wx.wxEVT_ENTER_WINDOW, refreshFunctionList)
else
local event = ide.osname == 'Macintosh' and wx.wxEVT_LEFT_DOWN or wx.wxEVT_SET_FOCUS
funclist:Connect(event, refreshFunctionList)
end
funclist:Connect(wx.wxEVT_COMMAND_CHOICE_SELECTED,
function (event)

View File

@@ -26,9 +26,13 @@ ide.filetree = {
}
local filetree = ide.filetree
local iscaseinsensitive = wx.wxFileName("A"):SameAs(wx.wxFileName("a"))
-- generic tree
-- ------------
local IMG_DIRECTORY, IMG_FILE_KNOWN, IMG_FILE_OTHER = 0, 1, 2
do
local getBitmap = (ide.app.createbitmap or wx.wxArtProvider.GetBitmap)
local size = wx.wxSize(16, 16)
@@ -37,51 +41,25 @@ do
filetree.imglist:Add(getBitmap(wx.wxART_FOLDER, wx.wxART_OTHER, size))
-- 1 = file known spec
filetree.imglist:Add(getBitmap(wx.wxART_HELP_PAGE, wx.wxART_OTHER, size))
-- 2 = file rest
-- 2 = file other
filetree.imglist:Add(getBitmap(wx.wxART_NORMAL_FILE, wx.wxART_OTHER, size))
end
local function treeAddDir(tree,parent_id,rootdir)
local item, cookie = tree:GetFirstChild(parent_id)
local items = {}
while true do
if not item:IsOk() then break end
local item, cookie = tree:GetFirstChild(parent_id)
while item:IsOk() do
items[tree:GetItemText(item) .. tree:GetItemImage(item)] = item
item, cookie = tree:GetNextChild(parent_id, cookie)
end
local cache = {}
local curr
local search = rootdir..string_Pathsep.."*"
-- append directories
for _,dir in ipairs(FileSysGet(search,wx.wxDIR)) do
local name = dir:match("("..stringset_File.."+)$")
local icon = 0
local item = items[name .. icon]
if item then -- existing item
-- keep deleting items until we find item
while true do
local next = curr and tree:GetNextSibling(curr)
or tree:GetFirstChild(parent_id)
if not next:IsOk() or name == tree:GetItemText(next) then
curr = next
break
end
tree:Delete(next)
end
else -- new item
local dir_id = curr and tree:InsertItem(parent_id, curr, name, icon)
or tree:PrependItem(parent_id, name, icon)
tree:SetItemHasChildren(dir_id,FileSysHasContent(dir))
curr = dir_id
end
end
-- then append files
for _,file in ipairs(FileSysGet(search,wx.wxFILE)) do
local name = file:match("("..stringset_File.."+)$")
for _, file in ipairs(FileSysGetRecursive(rootdir)) do
local name, dir = file:match("("..stringset_File.."+)("..string_Pathsep.."?)$")
local known = GetSpec(GetFileExt(name))
local icon = known and 1 or 2
local icon = #dir>0 and IMG_DIRECTORY or known and IMG_FILE_KNOWN or IMG_FILE_OTHER
local item = items[name .. icon]
if item then -- existing item
-- keep deleting items until we find item
@@ -97,7 +75,9 @@ local function treeAddDir(tree,parent_id,rootdir)
else -- new item
curr = curr and tree:InsertItem(parent_id, curr, name, icon)
or tree:PrependItem(parent_id, name, icon)
if #dir>0 then tree:SetItemHasChildren(curr, FileSysHasContent(file)) end
end
if curr:IsOk() then cache[iscaseinsensitive and name:lower() or name] = curr end
end
-- delete any leftovers (something that exists in the tree, but not on disk)
@@ -108,6 +88,11 @@ local function treeAddDir(tree,parent_id,rootdir)
tree:Delete(next)
end
-- cache the mapping from names to tree items
local data = wx.wxLuaTreeItemData()
data:SetData(cache)
tree:SetItemData(parent_id, data)
tree:SetItemHasChildren(parent_id,
tree:GetChildrenCount(parent_id, false) > 0)
end
@@ -118,10 +103,11 @@ local function treeGetItemFullName(tree,treedata,item_id)
while (#cur > 0) do
item_id = tree:GetItemParent(item_id)
if not item_id:IsOk() then break end
cur = tree:GetItemText(item_id)
if cur and string.len(cur) > 0 then str = cur..string_Pathsep..str end
end
-- as root may already include path separate, normalize the path
-- as root may already include path separator, normalize the path
local fullPath = wx.wxFileName(
filetree.showroot and str or filetree.projdata.rootdir .. str)
fullPath:Normalize()
@@ -135,25 +121,34 @@ local function treeSetRoot(tree,treedata,rootdir)
return
end
local root_id = tree:AddRoot(rootdir,0)
local root_id = tree:AddRoot(rootdir, IMG_DIRECTORY)
treedata.root_id = root_id
treedata.rootdir = rootdir
treeAddDir(tree,root_id,rootdir)
filetree.newfiledir = rootdir
tree:Expand(root_id)
-- make sure that the item can expand
tree:SetItemHasChildren(root_id, true)
tree:Expand(root_id) -- this will also populate the tree
end
local function treeSetConnectorsAndIcons(tree,treedata)
tree:SetImageList(filetree.imglist)
local function refreshAncestors(node)
while node:IsOk() do
local dir = treeGetItemFullName(tree,treedata,node)
treeAddDir(tree,node,dir)
node = tree:GetItemParent(node)
end
end
-- connect to some events from the wxTreeCtrl
tree:Connect( wx.wxEVT_COMMAND_TREE_ITEM_EXPANDING,
function( event )
local item_id = event:GetItem()
local dir = treeGetItemFullName(tree,treedata,item_id)
treeAddDir(tree,item_id,dir)
if wx.wxDirExists(dir) then treeAddDir(tree,item_id,dir) -- refresh folder
else refreshAncestors(tree:GetItemParent(item_id)) end -- stale content
return true
end)
tree:Connect( wx.wxEVT_COMMAND_TREE_ITEM_COLLAPSED,
@@ -161,21 +156,14 @@ local function treeSetConnectorsAndIcons(tree,treedata)
tree:Connect( wx.wxEVT_COMMAND_TREE_ITEM_ACTIVATED,
function( event )
local item_id = event:GetItem()
local name = treeGetItemFullName(tree,treedata,item_id)
-- refresh the folder
if (tree:GetItemImage(item_id) == 0) then
if wx.wxFileName(name):DirExists() then
treeAddDir(tree,item_id,name) -- refresh the content
else -- stale filetree information; rescan
treeAddDir(tree,tree:GetItemParent(item_id),name)
end
if (tree:GetItemImage(item_id) == IMG_DIRECTORY) then
if wx.wxDirExists(name) then treeAddDir(tree,item_id,name)
else refreshAncestors(tree:GetItemParent(item_id)) end -- stale content
else -- open file
if wx.wxFileName(name):FileExists() then
LoadFile(name,nil,true)
else -- stale filetree information; rescan
treeAddDir(tree,tree:GetItemParent(item_id),name)
end
if wx.wxFileExists(name) then LoadFile(name,nil,true)
else refreshAncestors(tree:GetItemParent(item_id)) end -- stale content
end
end)
-- toggle a folder on
@@ -183,7 +171,7 @@ local function treeSetConnectorsAndIcons(tree,treedata)
function( event )
local item_id = tree:HitTest(event:GetPosition())
-- only toggle if this is a folder and the click is on the label
if item_id and tree:GetItemImage(item_id) == 0 then
if item_id and tree:GetItemImage(item_id) == IMG_DIRECTORY then
tree:Toggle(item_id)
tree:SelectItem(item_id)
else
@@ -229,12 +217,19 @@ projpanel:SetSizer(projSizer)
-- proj connectors
-- ---------------
local inupdate = false
local function projcomboboxUpdate(event)
if inupdate then return end
local cur = projcombobox:GetValue()
local fn = wx.wxFileName(cur)
fn:Normalize()
-- on Windows, wxwidgets (2.9.5+) generates two COMMAND_COMBOBOX_SELECTED
-- events when the selection is done with ENTER, which causes recursive
-- call of updateProjectDir. To prevent this the second call is ignored.
inupdate = true
filetree:updateProjectDir(fn:GetFullPath(), event:GetEventType() == wx.wxEVT_COMMAND_COMBOBOX_SELECTED)
inupdate = false
end
projpanel:Connect(ID "filetree.proj.drivecb", wx.wxEVT_COMMAND_COMBOBOX_SELECTED, projcomboboxUpdate)
@@ -246,11 +241,13 @@ treeSetConnectorsAndIcons(projtree,filetree.projdata)
-- ---------------
function filetree:updateProjectDir(newdir, cboxsel)
if (newdir and newdir:sub(-3,-2) == string_Pathsep) then
newdir = newdir:sub(0,-2)
end
if (not newdir) or not wx.wxDirExists(newdir) then return end
local dirname = wx.wxFileName.DirName(newdir)
if ((not newdir) or filetree.projdirText == newdir or not wx.wxDirExists(newdir)) then return end
if filetree.projdirText and #filetree.projdirText > 0
and dirname:SameAs(wx.wxFileName.DirName(filetree.projdirText)) then return end
-- strip the last path separator if any
local newdir = dirname:GetPath(wx.wxPATH_GET_VOLUME)
if ide.config.projectautoopen and filetree.projdirText then
StoreRestoreProjectTabs(filetree.projdirText, newdir)
@@ -285,8 +282,8 @@ projpanel.projcombobox = projcombobox
projpanel.projtree = projtree
function FileTreeGetDir()
return projpanel:IsShown() and filetree.newfiledir
and wx.wxFileName.DirName(filetree.newfiledir):GetFullPath()
return projpanel:IsShown() and filetree.projdata.rootdir
and wx.wxFileName.DirName(filetree.projdata.rootdir):GetFullPath()
end
function FileTreeSetProjects(tab)
@@ -304,21 +301,33 @@ local function findItem(tree, match)
local node = projtree:GetRootItem()
local label = tree:GetItemText(node)
local s, e = string.find(match, label, 1, true)
local s, e
if iscaseinsensitive then
s, e = string.find(match:lower(), label:lower(), 1, true)
else
s, e = string.find(match, label, 1, true)
end
if not s or s ~= 1 then return end
for token in string.gmatch(string.sub(match,e+1), "[^%"..string_Pathsep.."]+") do
local dir = treeGetItemFullName(tree,filetree.projdata,node)
treeAddDir(tree,node,dir)
local data = tree:GetItemData(node)
local cache = data and data:GetData()
if cache and cache[iscaseinsensitive and token:lower() or token] then
node = cache[iscaseinsensitive and token:lower() or token]
else
-- token is missing; may need to re-scan the folder; maybe new file
local dir = treeGetItemFullName(tree,filetree.projdata,node)
treeAddDir(tree,node,dir)
local item, cookie = tree:GetFirstChild(node)
while true do
if not item:IsOk() then return end -- not found
if tree:GetItemText(item) == token then
node = item
break
local item, cookie = tree:GetFirstChild(node)
while true do
if not item:IsOk() then return end -- not found
if tree:GetItemText(item) == token then
node = item
break
end
item, cookie = tree:GetNextChild(node, cookie)
end
item, cookie = tree:GetNextChild(node, cookie)
end
end
@@ -345,10 +354,12 @@ function FileTreeMarkSelected(file)
end
if item_id then
projtree:EnsureVisible(item_id)
projtree:SetScrollPos(wx.wxHORIZONTAL, 0, true)
projtree:SetItemBold(item_id, true)
end
curr_file = file
projtree:Refresh() -- to force refresh on Mac (ide.osname == 'Macintosh')
if ide.wxver < "2.9.5" and ide.osname == 'Macintosh' then
projtree:Refresh() end
end
end

View File

@@ -53,19 +53,23 @@ local function setSearchFlags(editor)
editor:SetSearchFlags(flags)
end
local function setTarget(editor, fDown, fInclude)
local function setTarget(editor, fDown, fAll, fWrap)
local selStart = editor:GetSelectionStart()
local selEnd = editor:GetSelectionEnd()
local len = editor:GetLength()
local s, e
if fDown then
e= len
s = iff(fInclude, selStart, selEnd +1)
s = iff(fAll, selStart, selEnd)
e = len
else
s = 0
e = iff(fInclude, selEnd, selStart-1)
e = iff(fAll, selEnd, selStart)
end
if not fDown and not fInclude then s, e = e, s end
-- if going up and not search/replace All, then switch the range to
-- allow the next match to be properly marked
if not fDown and not fAll then s, e = e, s end
-- if wrap around and search all requested, then search the entire document
if fAll and fWrap then s, e = 0, len end
editor:SetTargetStart(s)
editor:SetTargetEnd(e)
return e
@@ -92,17 +96,33 @@ function findReplace:GetSelectedString()
local endSel = editor:GetSelectionEnd()
if (startSel ~= endSel) and (editor:LineFromPosition(startSel) == editor:LineFromPosition(endSel)) then
findReplace.findText = editor:GetSelectedText()
findReplace.foundString = true
return true
end
end
return editor and findReplace.foundString
return false
end
local function shake(window, shakes, duration, vigour)
shakes = shakes or 4
duration = duration or 0.5
vigour = vigour or 0.05
local delay = math.floor(duration/shakes/2)
local position = window:GetPosition() -- get current position
local deltax = window:GetSize():GetWidth()*vigour
for s = 1, shakes do
window:Move(position:GetX()-deltax, position:GetY())
wx.wxMilliSleep(delay)
window:Move(position:GetX()+deltax, position:GetY())
wx.wxMilliSleep(delay)
end
window:Move(position) -- restore position
end
function findReplace:FindString(reverse)
if findReplace:HasText() then
local editor = findReplace:GetEditor()
local fDown = iff(reverse, not findReplace.fDown, findReplace.fDown)
local lenFind = string.len(findReplace.findText)
setSearchFlags(editor)
setTarget(editor, fDown)
local posFind = editor:SearchInTarget(findReplace.findText)
@@ -113,13 +133,15 @@ function findReplace:FindString(reverse)
end
if posFind == -1 then
findReplace.foundString = false
ide.frame:SetStatusText("Text not found.")
ide.frame:SetStatusText(TR("Text not found."))
shake(findReplace.dialog)
else
findReplace.foundString = true
local start = editor:GetTargetStart()
local finish = editor:GetTargetEnd()
EnsureRangeVisible(start, finish)
editor:SetSelection(start, finish)
ide.frame:SetStatusText("")
end
end
end
@@ -157,34 +179,40 @@ end
-- registers every position item was found
-- supposed for "Search/Replace in Files"
function findReplace:ReplaceString(fReplaceAll,inFileRegister)
function findReplace:ReplaceString(fReplaceAll, inFileRegister)
local replaced = false
if findReplace:HasText() then
local replaceLen = string.len(findReplace.replaceText)
local findLen = string.len(findReplace.findText)
local editor = findReplace:GetEditor()
local endTarget = inFileRegister and setTargetAll(editor) or
setTarget(editor, findReplace.fDown, fReplaceAll)
setTarget(editor, findReplace.fDown, fReplaceAll, findReplace.fWrap)
if fReplaceAll then
setSearchFlags(editor)
local occurrences = 0
local posFind = editor:SearchInTarget(findReplace.findText)
if (posFind ~= -1) then
if(not inFileRegister) then editor:BeginUndoAction() end
if (not inFileRegister) then editor:BeginUndoAction() end
while posFind ~= -1 do
if(inFileRegister) then inFileRegister(posFind) end
if (inFileRegister) then inFileRegister(posFind) end
local length = editor:GetLength()
editor:ReplaceTarget(findReplace.replaceText)
editor:SetTargetStart(posFind + replaceLen)
endTarget = endTarget + replaceLen - findLen
-- adjust the endTarget as the position could have changed;
-- can't simply subtract findText length as it could be a regexp
endTarget = endTarget + (editor:GetLength() - length)
editor:SetTargetEnd(endTarget)
posFind = editor:SearchInTarget(findReplace.findText)
occurrences = occurrences + 1
end
if(not inFileRegister) then editor:EndUndoAction() end
if (not inFileRegister) then editor:EndUndoAction() end
replaced = true
end
ide.frame:SetStatusText(("%s %s."):format(
TR("Replaced"), TR("%d instance", occurrences):format(occurrences)))
else
if findReplace.foundString then
local start = editor:GetSelectionStart()
@@ -206,22 +234,17 @@ local function onFileRegister(pos)
local line = editor:LineFromPosition(pos)
local linepos = pos - editor:PositionFromLine(line)
local result = "("..(line+1)..","..(linepos+1).."): "..editor:GetLine(line)
DisplayOutput(findReplace.curfilename..result)
DisplayOutputLn(findReplace.curfilename..result:gsub("\r?\n$",""))
findReplace.occurrences = findReplace.occurrences + 1
end
local function ProcInFiles(startdir,mask,subdirs,replace)
if (subdirs) then
local dirs = FileSysGet(startdir..string_Pathsep.."*",wx.wxDIR)
for _,dir in ipairs(dirs) do
ProcInFiles(dir,mask,true,replace)
end
end
local files = FileSysGet(startdir..string_Pathsep..mask,wx.wxFILE)
local files = FileSysGetRecursive(startdir,subdirs,mask)
for _,file in ipairs(files) do
-- ignore .bak files when replacing and asked to store .bak files
if not (replace and findReplace.fMakeBak and file:find('.bak$')) then
-- and skip folders as these are included in the list as well
if not (replace and findReplace.fMakeBak and file:find('.bak$'))
and not file:match(string_Pathsep.."$") then
findReplace.curfilename = file
local filetext = FileRead(file)
@@ -251,38 +274,51 @@ function findReplace:RunInFiles(replace)
wx.wxDefaultPosition, wx.wxSize(1,1), wx.wxBORDER_STATIC)
findReplace.occurrences = 0
local fname = wx.wxFileName(findReplace.filedirText)
local startdir = findReplace.filedirText
DisplayOutput("FindInFiles: "..(replace and "Replacing" or "Searching for").." '"..findReplace.findText.."'.\n")
DisplayOutputLn(("%s '%s'."):format(
(replace and TR("Replacing") or TR("Searching for")),
findReplace.findText))
ProcInFiles(startdir, findReplace.filemaskText, findReplace.fSubDirs, replace)
DisplayOutput("FindInFiles: "..findReplace.occurrences.." instance(s) have been "..
(replace and "replaced" or "found")..".\n")
DisplayOutputLn(("%s %s."):format(
(replace and TR("Replaced") or TR("Found")),
TR("%d instance", findReplace.occurrences):format(findReplace.occurrences)))
findReplace.oveditor = nil
end
local function createFindReplaceDialog(replace,infiles)
function findReplace:createDialog(replace,infiles)
local ID_FIND_NEXT = 1
local ID_REPLACE = 2
local ID_REPLACE_ALL = 3
local ID_SETDIR = 4
local mac = ide.osname == 'Macintosh'
local findReplace = self
local position = wx.wxDefaultPosition
if findReplace.dialog then
-- grab current position before destroying the dialog
position = findReplace.dialog:GetPosition()
findReplace.dialog:Destroy()
end
local findDialog = wx.wxDialog(ide.frame, wx.wxID_ANY, infiles and TR("Find In Files") or TR("Find"),
position, wx.wxDefaultSize, wx.wxDEFAULT_DIALOG_STYLE)
findReplace.replace = replace
findReplace.infiles = infiles
local findDialog = wx.wxDialog(ide.frame, wx.wxID_ANY, infiles and "Find In Files" or "Find",
wx.wxDefaultPosition, wx.wxDefaultSize, wx.wxDEFAULT_DIALOG_STYLE)
-- Create right hand buttons and sizer
local findButton = wx.wxButton(findDialog, ID_FIND_NEXT, infiles and "&Find All" or "&Find Next")
findButton:SetDefault()
local replaceButton = wx.wxButton(findDialog, ID_REPLACE, infiles and replace and "&Replace All" or "&Replace")
local findButton = wx.wxButton(findDialog, ID_FIND_NEXT, infiles and TR("&Find All") or TR("&Find Next"))
local replaceButton = wx.wxButton(findDialog, ID_REPLACE, infiles and replace and TR("&Replace All") or TR("&Replace"))
local replaceAllButton = nil
if (replace and not infiles) then
replaceAllButton = wx.wxButton(findDialog, ID_REPLACE_ALL, "Replace &All")
replaceAllButton = wx.wxButton(findDialog, ID_REPLACE_ALL, TR("Replace &All"))
end
local cancelButton = wx.wxButton(findDialog, wx.wxID_CANCEL, "Cancel")
local cancelButton = wx.wxButton(findDialog, wx.wxID_CANCEL, TR("Cancel"))
local buttonsSizer = wx.wxBoxSizer(wx.wxVERTICAL)
buttonsSizer:Add(findButton, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 3)
@@ -293,15 +329,16 @@ local function createFindReplaceDialog(replace,infiles)
buttonsSizer:Add(cancelButton, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 3)
-- Create find/replace text entry sizer
local findStatText = wx.wxStaticText( findDialog, wx.wxID_ANY, "Find: ")
local findStatText = wx.wxStaticText(findDialog, wx.wxID_ANY, TR("Find")..": ")
local findTextCombo = wx.wxComboBox(findDialog, wx.wxID_ANY, findReplace.findText,
wx.wxDefaultPosition, wx.wxDefaultSize, findReplace.findTextArray, wx.wxCB_DROPDOWN)
wx.wxDefaultPosition, wx.wxDefaultSize, findReplace.findTextArray,
wx.wxCB_DROPDOWN + (mac and wx.wxTE_PROCESS_ENTER or 0))
findTextCombo:SetFocus()
local infilesMaskStat,infilesMaskCombo
local infilesDirStat,infilesDirCombo,infilesDirButton
if (infiles) then
infilesMaskStat = wx.wxStaticText( findDialog, wx.wxID_ANY, "File Type: ")
infilesMaskStat = wx.wxStaticText(findDialog, wx.wxID_ANY, TR("File Type")..": ")
infilesMaskCombo = wx.wxComboBox(findDialog, wx.wxID_ANY, findReplace.filemaskText,
wx.wxDefaultPosition, wx.wxDefaultSize, findReplace.filemaskTextArray)
@@ -310,15 +347,18 @@ local function createFindReplaceDialog(replace,infiles)
findReplace.filedirText = fname:GetPath(wx.wxPATH_GET_VOLUME)
end
infilesDirStat = wx.wxStaticText( findDialog, wx.wxID_ANY, "Directory: ")
infilesDirCombo = wx.wxComboBox(findDialog, wx.wxID_ANY, findReplace.filedirText, wx.wxDefaultPosition, wx.wxDefaultSize, findReplace.filedirTextArray)
infilesDirStat = wx.wxStaticText(findDialog, wx.wxID_ANY, TR("Directory")..": ")
infilesDirCombo = wx.wxComboBox(findDialog, wx.wxID_ANY, findReplace.filedirText,
wx.wxDefaultPosition, wx.wxDefaultSize, findReplace.filedirTextArray)
infilesDirButton = wx.wxButton(findDialog, ID_SETDIR, "...",wx.wxDefaultPosition, wx.wxSize(26,20))
end
local replaceStatText, replaceTextCombo
if (replace) then
replaceStatText = wx.wxStaticText( findDialog, wx.wxID_ANY, "Replace: ")
replaceTextCombo = wx.wxComboBox(findDialog, wx.wxID_ANY, findReplace.replaceText, wx.wxDefaultPosition, wx.wxDefaultSize, findReplace.replaceTextArray)
replaceStatText = wx.wxStaticText(findDialog, wx.wxID_ANY, TR("Replace")..": ")
replaceTextCombo = wx.wxComboBox(findDialog, wx.wxID_ANY, findReplace.replaceText,
wx.wxDefaultPosition, wx.wxDefaultSize, findReplace.replaceTextArray,
wx.wxCB_DROPDOWN + (mac and wx.wxTE_PROCESS_ENTER or 0))
end
local findReplaceSizer = wx.wxFlexGridSizer(2, 3, 0, 0)
@@ -345,13 +385,13 @@ local function createFindReplaceDialog(replace,infiles)
-- the StaticBox(Sizer) needs to be created before checkboxes, otherwise
-- checkboxes don't get any clicks on OSX (ide.osname == 'Macintosh')
-- as the z-order for event traversal appears to be incorrect.
local optionsSizer = wx.wxStaticBoxSizer(wx.wxVERTICAL, findDialog, "Options" )
local optionsSizer = wx.wxStaticBoxSizer(wx.wxVERTICAL, findDialog, TR("Options"))
-- Create find/replace option checkboxes
local wholeWordCheckBox = wx.wxCheckBox(findDialog, wx.wxID_ANY, "Match &whole word")
local matchCaseCheckBox = wx.wxCheckBox(findDialog, wx.wxID_ANY, "Match &case")
local wrapAroundCheckBox = wx.wxCheckBox(findDialog, wx.wxID_ANY, "Wrap ar&ound")
local regexCheckBox = wx.wxCheckBox(findDialog, wx.wxID_ANY, "Regular &expression")
local wholeWordCheckBox = wx.wxCheckBox(findDialog, wx.wxID_ANY, TR("Match &whole word"))
local matchCaseCheckBox = wx.wxCheckBox(findDialog, wx.wxID_ANY, TR("Match &case"))
local wrapAroundCheckBox = wx.wxCheckBox(findDialog, wx.wxID_ANY, TR("Wrap ar&ound"))
local regexCheckBox = wx.wxCheckBox(findDialog, wx.wxID_ANY, TR("Regular &expression"))
wholeWordCheckBox:SetValue(findReplace.fWholeWord)
matchCaseCheckBox:SetValue(findReplace.fMatchCase)
wrapAroundCheckBox:SetValue(findReplace.fWrap)
@@ -373,10 +413,10 @@ local function createFindReplaceDialog(replace,infiles)
local scopeSizer
if (infiles) then
-- the StaticBox(Sizer) needs to be created before checkboxes
scopeSizer = wx.wxStaticBoxSizer(wx.wxVERTICAL, findDialog, "In Files")
scopeSizer = wx.wxStaticBoxSizer(wx.wxVERTICAL, findDialog, TR("In Files"))
subDirCheckBox = wx.wxCheckBox(findDialog, wx.wxID_ANY, "&Subdirectories")
makeBakCheckBox = wx.wxCheckBox(findDialog, wx.wxID_ANY, ".&bak on Replace")
subDirCheckBox = wx.wxCheckBox(findDialog, wx.wxID_ANY, TR("&Subdirectories"))
makeBakCheckBox = wx.wxCheckBox(findDialog, wx.wxID_ANY, TR(".&bak on Replace"))
subDirCheckBox:SetValue(findReplace.fSubDirs)
makeBakCheckBox:SetValue(findReplace.fMakeBak)
@@ -386,7 +426,8 @@ local function createFindReplaceDialog(replace,infiles)
scopeSizer:Add(optionSizer, 0, 0, 5)
else
scopeRadioBox = wx.wxRadioBox(findDialog, wx.wxID_ANY, "Scope", wx.wxDefaultPosition, wx.wxDefaultSize, {"&Up", "&Down"}, 1, wx.wxRA_SPECIFY_COLS)
scopeRadioBox = wx.wxRadioBox(findDialog, wx.wxID_ANY, TR("Scope"), wx.wxDefaultPosition,
wx.wxDefaultSize, {TR("&Up"), TR("&Down")}, 1, wx.wxRA_SPECIFY_COLS)
scopeRadioBox:SetSelection(iff(findReplace.fDown, 1, 0))
scopeSizer = wx.wxBoxSizer(wx.wxVERTICAL, findDialog)
@@ -406,7 +447,7 @@ local function createFindReplaceDialog(replace,infiles)
mainSizer:Add(leftSizer, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 10)
mainSizer:Add(buttonsSizer, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 10)
mainSizer:SetSizeHints( findDialog )
mainSizer:SetSizeHints(findDialog)
findDialog:SetSizer(mainSizer)
local function TransferDataFromWindow()
@@ -437,12 +478,26 @@ local function createFindReplaceDialog(replace,infiles)
return true
end
-- this is a workaround for Enter issue in wxComboBox on OSX:
-- https://groups.google.com/d/msg/wx-users/EVJr8GqyNUA/CUALp585E78J
if (mac and ide.wxver >= "2.9.5") then
local function simulateEnter()
findDialog:AddPendingEvent(wx.wxCommandEvent(
wx.wxEVT_COMMAND_BUTTON_CLICKED, ID_FIND_NEXT))
end
findTextCombo:Connect(wx.wxEVT_COMMAND_TEXT_ENTER, simulateEnter)
if replace then
replaceTextCombo:Connect(wx.wxEVT_COMMAND_TEXT_ENTER, simulateEnter)
end
end
findDialog:Connect(ID_FIND_NEXT, wx.wxEVT_COMMAND_BUTTON_CLICKED,
function()
TransferDataFromWindow()
if (findReplace.infiles) then
findReplace:RunInFiles()
findReplace.dialog:Destroy()
findReplace.dialog = nil
else
findReplace:FindString()
end
@@ -456,13 +511,12 @@ local function createFindReplaceDialog(replace,infiles)
if (findReplace.infiles) then
findReplace:RunInFiles(true)
findReplace.dialog:Destroy()
findReplace.dialog = nil
else
findReplace:ReplaceString()
end
else
findReplace.dialog:Destroy()
findReplace.dialog = createFindReplaceDialog(true,infiles)
findReplace.dialog:Show(true)
findReplace:createDialog(true,infiles)
end
end)
@@ -478,7 +532,7 @@ local function createFindReplaceDialog(replace,infiles)
if infilesDirButton then
findDialog:Connect(ID_SETDIR, wx.wxEVT_COMMAND_BUTTON_CLICKED,
function()
local filePicker = wx.wxDirDialog(findDialog, "Choose a project directory",
local filePicker = wx.wxDirDialog(findDialog, TR("Choose a project directory"),
findReplace.filedirText~="" and findReplace.filedirText or wx.wxGetCwd(),wx.wxFLP_USE_TEXTCTRL)
local res = filePicker:ShowModal(true)
@@ -486,22 +540,26 @@ local function createFindReplaceDialog(replace,infiles)
infilesDirCombo:SetValue(filePicker:GetPath())
end
end)
end
findDialog:Connect(wx.wxID_ANY, wx.wxEVT_CLOSE_WINDOW,
function (event)
TransferDataFromWindow()
event:Skip()
findDialog:Show(false)
findDialog:Destroy()
end)
-- if on OSX then select the current value of the default dropdown
-- and don't set the default as it doesn't make Enter to work, but
-- prevents associated hotkey (Cmd-F) from working (wx2.9.5).
if ide.osname == 'Macintosh' then
findTextCombo:SetSelection(0, #findTextCombo:GetValue())
else
findButton:SetDefault()
end
-- reset search when re-creating dialog to avoid modifying selected
-- fragment after successful search and updated replacement
findReplace.foundString = false
findReplace.dialog = findDialog
findDialog:Show(true)
return findDialog
end
function findReplace:Show(replace,infiles)
self.dialog = nil
self.dialog = createFindReplaceDialog(replace,infiles)
self.dialog:Show(true)
self:GetSelectedString()
self:createDialog(replace,infiles)
end

View File

@@ -4,22 +4,30 @@
local ide = ide
-- Pick some reasonable fixed width fonts to use for the editor
local function setFont(style, config, name, size)
local function setFont(style, config)
return wx.wxFont(config.fontsize or size or 10, wx.wxFONTFAMILY_MODERN, style,
wx.wxFONTWEIGHT_NORMAL, false, config.fontname or name,
wx.wxFONTWEIGHT_NORMAL, false, config.fontname or "",
config.fontencoding or wx.wxFONTENCODING_DEFAULT)
end
ide.font.eNormal = setFont(wx.wxFONTSTYLE_NORMAL, ide.config.editor, wx.__WXMSW__ and "Courier New" or "")
ide.font.eItalic = setFont(wx.wxFONTSTYLE_ITALIC, ide.config.editor, wx.__WXMSW__ and "Courier New" or "")
ide.font.eNormal = setFont(wx.wxFONTSTYLE_NORMAL, ide.config.editor)
ide.font.eItalic = setFont(wx.wxFONTSTYLE_ITALIC, ide.config.editor)
ide.font.oNormal = setFont(wx.wxFONTSTYLE_NORMAL, ide.config.outputshell, wx.__WXMSW__ and "Courier New" or "")
ide.font.oItalic = setFont(wx.wxFONTSTYLE_ITALIC, ide.config.outputshell, wx.__WXMSW__ and "Courier New" or "")
ide.font.oNormal = setFont(wx.wxFONTSTYLE_NORMAL, ide.config.outputshell)
ide.font.oItalic = setFont(wx.wxFONTSTYLE_ITALIC, ide.config.outputshell)
-- treeCtrl font requires slightly different handling
local gui, config = wx.wxTreeCtrl():GetFont(), ide.config.filetree
if config.fontsize then gui:SetPointSize(config.fontsize) end
if config.fontname then gui:SetFaceName(config.fontname) end
ide.font.fNormal = gui
do local gui, config = wx.wxTreeCtrl():GetFont(), ide.config.filetree
if config.fontsize then gui:SetPointSize(config.fontsize) end
if config.fontname then gui:SetFaceName(config.fontname) end
ide.font.fNormal = gui
end
-- funcList font requires similar handling
do local gui, config = wx.wxTreeCtrl():GetFont(), ide.config.funclist
if config.fontsize then gui:SetPointSize(config.fontsize) end
if config.fontname then gui:SetFaceName(config.fontname) end
ide.font.dNormal = gui
end
-- ----------------------------------------------------------------------------
-- Create the wxFrame
@@ -42,8 +50,8 @@ local function createFrame()
local menuBar = wx.wxMenuBar()
local statusBar = frame:CreateStatusBar(6)
local section_width = statusBar:GetTextExtent("OVRW")
statusBar:SetStatusStyles({wx.wxSB_RAISED, wx.wxSB_RAISED, wx.wxSB_RAISED,
wx.wxSB_RAISED, wx.wxSB_RAISED, wx.wxSB_RAISED})
statusBar:SetStatusStyles({wx.wxSB_FLAT, wx.wxSB_FLAT, wx.wxSB_FLAT,
wx.wxSB_FLAT, wx.wxSB_FLAT, wx.wxSB_FLAT})
statusBar:SetStatusWidths(
{-1, section_width*6, section_width, section_width, section_width*4, section_width*4})
statusBar:SetStatusText(GetIDEString("statuswelcome"))
@@ -64,30 +72,20 @@ local function SCinB(id) -- shortcut in brackets
end
local function createToolBar(frame)
local toolBar = wx.wxToolBar(frame, wx.wxID_ANY,
wx.wxDefaultPosition, wx.wxDefaultSize, wx.wxTB_FLAT + wx.wxTB_NODIVIDER)
local toolBar = frame:CreateToolBar(wx.wxTB_FLAT + wx.wxTB_NODIVIDER, wx.wxID_ANY)
-- wxChoice is a bit too narrow on Linux, so make it a bit larger
local funclist = wx.wxChoice.new(toolBar, ID "toolBar.funclist",
-- Linux requires a bit larger size for the function list in the toolbar.
-- Mac also requires a bit larger size, but setting it to 20 resets
-- back to 16 when the toolbar is refreshed.
-- Windows with wxwidgets 2.9.x also requires a larger size.
wx.wxDefaultPosition, wx.wxSize.new(240,
(ide.osname == "Unix" or ide.osname == "Windows") and 24 or 16))
wx.wxDefaultPosition, wx.wxSize.new(240, ide.osname == 'Unix' and 28 or 24))
-- usually the bmp size isn't necessary, but the HELP icon is not the right size in MSW
-- there are two sets of icons: use 24 on OSX and 16 on others.
local toolBmpSize =
ide.osname == 'Macintosh' and wx.wxSize(24, 24) or wx.wxSize(16, 16)
local getBitmap = (ide.app.createbitmap or wx.wxArtProvider.GetBitmap)
local toolBmpSize = wx.wxSize(16, 16)
toolBar:AddTool(ID_NEW, "New", getBitmap(wx.wxART_NORMAL_FILE, wx.wxART_TOOLBAR, toolBmpSize), TR("Create an empty document")..SCinB(ID_NEW))
toolBar:AddTool(ID_OPEN, "Open", getBitmap(wx.wxART_FILE_OPEN, wx.wxART_TOOLBAR, toolBmpSize), TR("Open an existing document")..SCinB(ID_OPEN))
toolBar:AddTool(ID_SAVE, "Save", getBitmap(wx.wxART_FILE_SAVE, wx.wxART_TOOLBAR, toolBmpSize), TR("Save the current document")..SCinB(ID_SAVE))
toolBar:AddTool(ID_SAVEALL, "Save All", getBitmap(wx.wxART_NEW_DIR, wx.wxART_TOOLBAR, toolBmpSize), TR("Save all open documents")..SCinB(ID_SAVEALL))
toolBar:AddSeparator()
toolBar:AddTool(ID_CUT, "Cut", getBitmap(wx.wxART_CUT, wx.wxART_TOOLBAR, toolBmpSize), TR("Cut selected text to clipboard")..SCinB(ID_CUT))
toolBar:AddTool(ID_COPY, "Copy", getBitmap(wx.wxART_COPY, wx.wxART_TOOLBAR, toolBmpSize), TR("Copy selected text to clipboard")..SCinB(ID_COPY))
toolBar:AddTool(ID_PASTE, "Paste", getBitmap(wx.wxART_PASTE, wx.wxART_TOOLBAR, toolBmpSize), TR("Paste text from the clipboard")..SCinB(ID_PASTE))
toolBar:AddSeparator()
toolBar:AddTool(ID_UNDO, "Undo", getBitmap(wx.wxART_UNDO, wx.wxART_TOOLBAR, toolBmpSize), TR("Undo last edit")..SCinB(ID_UNDO))
toolBar:AddTool(ID_REDO, "Redo", getBitmap(wx.wxART_REDO, wx.wxART_TOOLBAR, toolBmpSize), TR("Redo last edit undone")..SCinB(ID_REDO))
toolBar:AddTool(ID_PROJECTDIRFROMFILE, "Update", getBitmap(wx.wxART_GO_DIR_UP , wx.wxART_TOOLBAR, toolBmpSize), TR("Set project directory from current file")..SCinB(ID_PROJECTDIRFROMFILE))
toolBar:AddSeparator()
toolBar:AddTool(ID_FIND, "Find", getBitmap(wx.wxART_FIND, wx.wxART_TOOLBAR, toolBmpSize), TR("Find text")..SCinB(ID_FIND))
toolBar:AddTool(ID_REPLACE, "Replace", getBitmap(wx.wxART_FIND_AND_REPLACE, wx.wxART_TOOLBAR, toolBmpSize), TR("Find and replace text")..SCinB(ID_REPLACE))
@@ -105,8 +103,6 @@ local function createToolBar(frame)
toolBar:AddTool(ID_VIEWWATCHWINDOW, "Watch window", getBitmap("wxART_DEBUG_WATCH", wx.wxART_TOOLBAR, toolBmpSize), TR("View the watch window")..SCinB(ID_VIEWWATCHWINDOW))
end
toolBar:AddSeparator()
toolBar:AddTool(ID_PROJECTDIRFROMFILE, "Update", getBitmap(wx.wxART_GO_DIR_UP , wx.wxART_TOOLBAR, toolBmpSize), TR("Set project directory from current file")..SCinB(ID_PROJECTDIRFROMFILE))
toolBar:AddSeparator()
toolBar:AddControl(funclist)
toolBar:Realize()
@@ -120,22 +116,29 @@ local function createNotebook(frame)
local notebook = wxaui.wxAuiNotebook(frame, wx.wxID_ANY,
wx.wxDefaultPosition, wx.wxDefaultSize,
wxaui.wxAUI_NB_DEFAULT_STYLE + wxaui.wxAUI_NB_TAB_EXTERNAL_MOVE
+ wx.wxNO_BORDER)
+ wxaui.wxAUI_NB_WINDOWLIST_BUTTON + wx.wxNO_BORDER)
-- the following group of event handlers allows the active editor
-- to get/keep focus after execution of Run and other commands
local current -- the currently active editor, needed by the focus selection
local function onPageChange(event)
current = event:GetSelection() -- update the active editor reference
SetEditorSelection(current)
event:Skip() -- skip to let page change
end
notebook:Connect(wx.wxEVT_SET_FOCUS, -- Notepad tabs shouldn't be selectable,
-- wxEVT_SET_FOCUS could be used, but it only works on Windows with wx2.9.5+
notebook:Connect(wxaui.wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED,
function (event)
SetEditorSelection(current) -- select the currently active editor
local ed = GetEditor(notebook:GetSelection())
local doc = ed and ed:GetId() and ide.openDocuments[ed:GetId()]
-- skip activation when any of the following is true:
-- (1) there is no document yet, the editor tab was just added,
-- so no changes needed as there will be a proper later call;
-- (2) the page change event was triggered after a tab is closed;
-- (3) on OSX from AddPage event when changing from the last tab
-- (this is to work around a duplicate event generated in this case
-- that first activates the added tab and then some other tab (2.9.5)).
local double = (ide.osname == 'Macintosh'
and event:GetOldSelection() == notebook:GetPageCount()
and debug:traceback():find("'AddPage'"))
if doc and event:GetOldSelection() ~= -1 and not double then
SetEditorSelection(notebook:GetSelection()) end
end)
notebook:Connect(wx.wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, onPageChange)
notebook:Connect(wxaui.wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, onPageChange)
notebook:Connect(wxaui.wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE,
function (event)
@@ -143,6 +146,21 @@ local function createNotebook(frame)
event:Veto() -- don't propagate the event as the page is already closed
end)
-- tabs can be dragged around which may change their indexes;
-- when this happens stored indexes need to be updated to reflect the change.
-- there is DRAG_DONE event that I'd prefer to use, but it
-- doesn't fire for some reason using wxwidgets 2.9.5 (tested on Windows).
if ide.wxver >= "2.9.5" then
notebook:Connect(wxaui.wxEVT_COMMAND_AUINOTEBOOK_END_DRAG,
function (event)
for page = 0, notebook:GetPageCount()-1 do
local editor = GetEditor(page)
if editor then ide.openDocuments[editor:GetId()].index = page end
end
event:Skip()
end)
end
local selection
notebook:Connect(wxaui.wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP,
function (event)
@@ -203,10 +221,6 @@ local function createBottomNotebook(frame)
bottomnotebook:AddPage(errorlog, TR("Output"), true)
bottomnotebook:AddPage(shellbox, TR("Local console"), false)
bottomnotebook:Connect(wxaui.wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE,
function (event)
event:Veto() -- don't allow closing pages in this notebook
end)
frame.bottomnotebook = bottomnotebook
bottomnotebook.errorlog = errorlog
@@ -235,35 +249,19 @@ do
local frame = ide.frame
local mgr = frame.uimgr
mgr:AddPane(frame.toolBar, wxaui.wxAuiPaneInfo():
Name("toolBar"):Caption("Main Toolbar"):
MinSize(300,16):
ToolbarPane():Top():CloseButton(false):
LeftDockable(false):RightDockable(false):Hide())
mgr:AddPane(frame.notebook, wxaui.wxAuiPaneInfo():
Name("notebook"):
CenterPane():PaneBorder(false):Hide())
CenterPane():PaneBorder(false))
mgr:AddPane(frame.projpanel, wxaui.wxAuiPaneInfo():
Name("projpanel"):Caption(TR("Project")):
MinSize(200,200):FloatingSize(200,400):
Left():Layer(1):Position(1):
CloseButton(true):MaximizeButton(false):PinButton(true):Hide())
CloseButton(true):MaximizeButton(false):PinButton(true))
mgr:AddPane(frame.bottomnotebook, wxaui.wxAuiPaneInfo():
Name("bottomnotebook"):
MinSize(200,200):FloatingSize(400,250):
MinSize(100,100):BestSize(200,200):FloatingSize(400,200):
Bottom():Layer(1):Position(1):
CloseButton(true):MaximizeButton(false):PinButton(true):Hide())
mgr:GetPane("toolBar"):Show(true)
mgr:GetPane("bottomnotebook"):Show(true)
mgr:GetPane("projpanel"):Show(true)
mgr:GetPane("notebook"):Show(true)
local pp = mgr:SavePerspective()
mgr.defaultPerspective = pp
mgr:Update()
CloseButton(true):MaximizeButton(false):PinButton(true))
mgr.defaultPerspective = mgr:SavePerspective()
end

View File

@@ -5,8 +5,8 @@
-- Generate a unique new wxWindowID
local ID_IDCOUNTER = wx.wxID_HIGHEST + 1
function NewID()
ID_IDCOUNTER = ID_IDCOUNTER + 1
return ID_IDCOUNTER
ID_IDCOUNTER = ID_IDCOUNTER + 1
return ID_IDCOUNTER
end
-- File menu
@@ -19,6 +19,8 @@ ID_SAVE = wx.wxID_SAVE
ID_SAVEAS = wx.wxID_SAVEAS
ID_SAVEALL = NewID()
ID_RECENTFILES = NewID()
ID_RECENTFILESPREV = NewID()
ID_RECENTFILESNEXT = NewID()
ID_EXIT = wx.wxID_EXIT
-- Edit menu
ID_CUT = wx.wxID_CUT
@@ -33,6 +35,11 @@ ID_AUTOCOMPLETEENABLE = NewID()
ID_COMMENT = NewID()
ID_FOLD = NewID()
ID_CLEARDYNAMICWORDS = NewID()
-- don't use wx.wxID_PREFERENCES to avoid merging with OSX app menu, because
-- Apple guidelines describe Preferences as a "normal" item without submenus.
ID_PREFERENCES = NewID()
ID_PREFERENCESSYSTEM = NewID()
ID_PREFERENCESUSER = NewID()
-- Search menu
ID_FIND = wx.wxID_FIND
ID_FINDNEXT = NewID()
@@ -73,8 +80,7 @@ ID_ABOUT = wx.wxID_ABOUT
-- Watch window menu items
ID_ADDWATCH = NewID()
ID_EDITWATCH = NewID()
ID_REMOVEWATCH = NewID()
ID_EVALUATEWATCH = NewID()
ID_DELETEWATCH = NewID()
-- Editor popup menu items
ID_QUICKADDWATCH = NewID()
ID_QUICKEVAL = NewID()

View File

@@ -68,20 +68,25 @@ function M.show_warnings(top_ast)
if name ~= 'self' then
local func = parent.parent and parent.parent.parent
local assignment = not func.tag or func.tag == 'Set' or func.tag == 'Localrec'
-- anonymous functions can also be defined in expressions,
-- for example, 'Op' or 'Return' tags
local expression = not assignment and func.tag
local func1 = func[1][1]
local fname = assignment and func1 and type(func1[1]) == 'string' and func1[1]
or (func1.tag == 'Index' and index(func1))
local fname = assignment and func1 and type(func1[1]) == 'string'
and func1[1] or (func1 and func1.tag == 'Index' and index(func1))
-- "function foo(bar)" => func.tag == 'Set'
-- `Set{{`Id{"foo"}},{`Function{{`Id{"bar"}},{}}}}
-- "local function foo(bar)" => func.tag == 'Localrec'
-- "local _, foo = 1, function(bar)" => func.tag == 'Local'
-- "print(function(bar) end)" => func.tag == nil
-- "a = a or function(bar) end" => func.tag == nil
-- "return(function(bar) end)" => func.tag == 'Return'
-- "function tbl:foo(bar)" => func.tag == 'Set'
-- `Set{{`Index{`Id{"tbl"},`String{"foo"}}},{`Function{{`Id{"self"},`Id{"bar"}},{}}}}
-- "function tbl.abc:foo(bar)" => func.tag == 'Set'
-- `Set{{`Index{`Index{`Id{"tbl"},`String{"abc"}},`String{"foo"}}},{`Function{{`Id{"self"},`Id{"bar"}},{}}}},
warn("unused parameter '" .. name .. "'" ..
(func and assignment
(func and (assignment or expression)
and (fname and func.tag
and (" in function '" .. fname .. "'")
or " in anonymous function")

View File

@@ -32,6 +32,8 @@ ide.config.keymap = {
[ID_SAVEAS] = "Alt-Shift-S",
[ID_SAVEALL] = "",
[ID_RECENTFILES] = "",
[ID_RECENTFILESPREV] = "Ctrl-<",
[ID_RECENTFILESNEXT] = "Ctrl->",
[ID_EXIT] = "Ctrl-Q",
-- Edit menu
[ID_CUT] = "Ctrl-X",
@@ -84,8 +86,7 @@ ide.config.keymap = {
-- Watch window menu items
[ID_ADDWATCH] = "Ins",
[ID_EDITWATCH] = "F2",
[ID_REMOVEWATCH] = "Del",
[ID_EVALUATEWATCH] = "",
[ID_DELETEWATCH] = "Del",
-- Editor popup menu items
[ID_QUICKADDWATCH] = "",
[ID_QUICKEVAL] = "",

View File

@@ -41,7 +41,7 @@ end
local function q(s) return s:gsub('(.)','%%%1') end
local MD_MARK_PTRN = '' -- combination of all markup marks that can start styling
for key,value in pairs(markup) do
for key in pairs(markup) do
if key ~= MD_MARK_MARK then MD_MARK_PTRN = MD_MARK_PTRN .. q(key) end
end
MarkupAddStyles(ide.config.styles)
@@ -76,12 +76,9 @@ function MarkupHotspotClick(pos, editor)
-- check if requested to open in a new window
local newwindow = string.find(text, MD_LINK_NEWWINDOW, 1, true) -- plain search
if newwindow then text = string.gsub(text, "^%" .. MD_LINK_NEWWINDOW, "") end
local name = wx.wxFileName(filepath):GetPath(wx.wxPATH_GET_VOLUME
+ wx.wxPATH_GET_SEPARATOR) .. text
-- load/activate file
local filename = wx.wxFileName(name)
filename:Normalize() -- remove .., ., and other similar elements
if filename:FileExists() and
local filename = GetFullPathIfExists(
wx.wxFileName(filepath):GetPath(wx.wxPATH_GET_VOLUME), text)
if filename and
(newwindow or SaveModifiedDialog(editor, true) ~= wx.wxID_CANCEL) then
if not newwindow and ide.osname == 'Macintosh' then editor:GotoPos(0) end
LoadFile(filename,not newwindow and editor or nil,true)
@@ -135,22 +132,28 @@ function MarkupStyle(editor, lines, linee)
-- always style to the end as there may be comments that need re-styling
-- technically, this should be GetLineCount()-1, but we want to style
-- beyond the last line to make sure it is styled correctly
local linee = linee or editor:GetLineCount()
local linec = editor:GetLineCount()
local linee = linee or linec
local iscomment = {}
for i,v in pairs(editor.spec.iscomment) do
iscomment[i] = v
end
local es = editor:GetEndStyled()
local needfix = false
for line=lines,linee do
local tx = editor:GetLine(line)
local ls = editor:PositionFromLine(line)
editor:StartStyling(ls, 0)
local from = 1
local off = -1
-- doing WrapCount(line) when line == linec (which may be beyond
-- the last line) occasionally crashes the application on OSX.
local wrapped = line < linec and editor:WrapCount(line) or 0
while from do
tx = string.sub(tx,from)
local f,t,w,mark = ismarkup(tx)
@@ -181,33 +184,17 @@ function MarkupStyle(editor, lines, linee)
end
from = t and (t+1)
end
end
end
-- this could work by calling MarkupStyle directly from EVT_UPDATEUI,
-- but the styling didn't work correctly as the style on block comments
-- (which is used to identify where the markup should be applied)
-- was not always correct during UPDATEUI event.
-- to rectify this, we style immediately (by calling MarkupStyle
-- from UPDATEUI), but also store the starting point and re-style during
-- the next UPDATEUI/IDLE event when the block comment style is correct.
local needStyle = {}
local frame
function MarkupStyleRefresh(editor, ev)
if not frame then
frame = ide.frame
frame:Connect(wx.wxEVT_IDLE,
function(event) MarkupStyleRefresh(); event:Skip() end)
end
if not ev or #ev == 0 then -- no new records, refresh deferred ones
for ed,line in pairs(needStyle) do
MarkupStyle(ed, line)
needStyle[ed] = nil
end
else -- store records from the event table to defer refresh
for _,pos in ipairs(ev) do
needStyle[editor] = editor:LineFromPosition(pos[1])
end
-- has this line changed its wrapping because of invisible styling?
if wrapped > 1 and editor:WrapCount(line) < wrapped then needfix = true end
end
editor:StartStyling(es, 31)
-- if any wrapped lines have changed, then reset WrapMode to fix the drawing
if needfix then
-- this fixes an issue with duplicate lines in Scintilla when
-- invisible styles hide some of the content that would be wrapped.
local wrapmode = editor:GetWrapMode()
if wrapmode ~= wxstc.wxSTC_WRAP_NONE then editor:SetWrapMode(wrapmode) end
end
end

View File

@@ -25,7 +25,14 @@ local editMenu = wx.wxMenu{
{ },
{ ID_FOLD, TR("&Fold/Unfold All")..KSC(ID_FOLD), TR("Fold or unfold all code folds") },
{ ID_CLEARDYNAMICWORDS, TR("Clear &Dynamic Words")..KSC(ID_CLEARDYNAMICWORDS), TR("Resets the dynamic word list for autocompletion") },
{ },
}
local preferencesMenu = wx.wxMenu{
{ID_PREFERENCESSYSTEM, TR("Settings: System")..KSC(ID_PREFERENCESSYSTEM)},
{ID_PREFERENCESUSER, TR("Settings: User")..KSC(ID_PREFERENCESUSER)},
}
editMenu:Append(ID_PREFERENCES, TR("Preferences"), preferencesMenu)
menuBar:Append(editMenu, TR("&Edit"))
editMenu:Check(ID_AUTOCOMPLETEENABLE, ide.config.autocomplete)
@@ -47,12 +54,11 @@ function OnUpdateUIEditMenu(event)
if editor == nil then event:Enable(false); return end
local alwaysOn = { [ID_SELECTALL] = true, [ID_FOLD] = true,
-- allow Cut and Copy commands as these work on a line if no selection
[ID_COPY] = true, [ID_CUT] = true,
[ID_COMMENT] = true, [ID_AUTOCOMPLETE] = true}
local menu_id = event:GetId()
local enable =
((menu_id == ID_COPY or menu_id == ID_CUT) and
(editor:GetClassInfo():GetClassName() ~= 'wxStyledTextCtrl'
or editor:GetSelectionStart() ~= editor:GetSelectionEnd())) or
menu_id == ID_PASTE and editor:CanPaste() or
menu_id == ID_UNDO and editor:CanUndo() or
menu_id == ID_REDO and editor:CanRedo() or
@@ -74,8 +80,12 @@ function OnEditMenu(event)
then event:Skip(); return end
local menu_id = event:GetId()
if menu_id == ID_CUT then editor:Cut()
elseif menu_id == ID_COPY then editor:Copy()
if menu_id == ID_CUT then
if editor:GetSelectionStart() == editor:GetSelectionEnd()
then editor:LineCut() else editor:Cut() end
elseif menu_id == ID_COPY then
if editor:GetSelectionStart() == editor:GetSelectionEnd()
then editor:LineCopy() else editor:Copy() end
elseif menu_id == ID_PASTE then editor:Paste()
elseif menu_id == ID_SELECTALL then editor:SelectAll()
elseif menu_id == ID_UNDO then editor:Undo()
@@ -88,6 +98,32 @@ for _, event in pairs({ID_CUT, ID_COPY, ID_PASTE, ID_SELECTALL, ID_UNDO, ID_REDO
frame:Connect(event, wx.wxEVT_UPDATE_UI, OnUpdateUIEditMenu)
end
local function generateConfigMessage(type)
return ([==[--[[--
Use this file to specify %s preferences.
Review [examples](+%s) or check [online documentation](%s) for details.
--]]--
]==])
:format(type, MergeFullPath(ide.editorFilename, "../cfg/user-sample.lua"),
"http://studio.zerobrane.com/documentation.html")
end
frame:Connect(ID_PREFERENCESSYSTEM, wx.wxEVT_COMMAND_MENU_SELECTED,
function ()
local editor = LoadFile(ide.configs.system)
if editor and #editor:GetText() == 0 then
editor:AddText(generateConfigMessage("System")) end
end)
frame:Connect(ID_PREFERENCESUSER, wx.wxEVT_COMMAND_MENU_SELECTED,
function ()
local editor = LoadFile(ide.configs.user)
if editor and #editor:GetText() == 0 then
editor:AddText(generateConfigMessage("User")) end
end)
frame:Connect(ID_PREFERENCESUSER, wx.wxEVT_UPDATE_UI,
function (event) event:Enable(ide.configs.user ~= nil) end)
frame:Connect(ID_CLEARDYNAMICWORDS, wx.wxEVT_COMMAND_MENU_SELECTED,
function () DynamicWordsReset() end)
@@ -126,9 +162,9 @@ frame:Connect(ID_COMMENT, wx.wxEVT_COMMAND_MENU_SELECTED,
end
local lc = editor.spec.linecomment
for line in string.gmatch(editor:GetSelectedText()..'\n', "(.-)\r?\n") do
if string.sub(line,1,2) == lc then
line = string.sub(line,3)
else
if string.sub(line,1,#lc) == lc then
line = string.sub(line,#lc+1)
elseif #line > 0 then
line = lc..line
end
table.insert(buf, line)

View File

@@ -25,26 +25,133 @@ local filehistorymenu = wx.wxMenu({})
local filehistory = wx.wxMenuItem(fileMenu, ID_RECENTFILES,
TR("Recent Files")..KSC(ID_RECENTFILES), TR("File history"), wx.wxITEM_NORMAL, filehistorymenu)
fileMenu:Insert(8,filehistory)
function UpdateFileHistoryUI(list)
-- remove all at first
for i=1,filehistorymenu:GetMenuItemCount() do
filehistorymenu:Delete( ID("file.recentfiles."..i))
end
for i=1,#list do
local file = list[i].filename
local item = wx.wxMenuItem(filehistorymenu, ID("file.recentfiles."..i),file,"")
filehistorymenu:Append(item)
end
end
for i=1,ide.config.filehistorylength do
frame:Connect(ID("file.recentfiles."..i), wx.wxEVT_COMMAND_MENU_SELECTED,
function (event)
local item = filehistorymenu:FindItemByPosition(i-1)
local filename = item:GetLabel()
LoadFile(filename)
do -- recent file history
local iscaseinsensitive = wx.wxFileName("A"):SameAs(wx.wxFileName("a"))
local function isSameAs(f1, f2)
return f1 == f2 or iscaseinsensitive and f1:lower() == f2:lower()
end
local filehistory = {[0] = 1}
-- add file to the file history removing duplicates
local function addFileHistory(filename)
-- a new (empty) tab is opened; don't change the history
if not filename then return end
local fn = wx.wxFileName(filename)
if fn:Normalize() then filename = fn:GetFullPath() end
local index = filehistory[0]
-- special case: selecting the current file (or moving through the history)
if filehistory[index] and isSameAs(filename, filehistory[index].filename) then return end
-- something else is selected
-- (1) flip the history from 1 to the current index
for i = 1, math.floor(index/2) do
filehistory[i], filehistory[index-i+1] = filehistory[index-i+1], filehistory[i]
end
)
-- (2) if the file is in the history, remove it
for i = #filehistory, 1, -1 do
if isSameAs(filename, filehistory[i].filename) then
table.remove(filehistory, i)
end
end
-- (3) add the file to the top and update the index
table.insert(filehistory, 1, {filename=filename})
filehistory[0] = 1
-- (4) remove all entries that are no longer needed
while #filehistory>ide.config.filehistorylength do table.remove(filehistory) end
end
local function remFileHistory(filename)
if not filename then return end
local fn = wx.wxFileName(filename)
if fn:Normalize() then filename = fn:GetFullPath() end
local index = filehistory[0]
-- special case: removing the current file
if filehistory[index] and isSameAs(filename, filehistory[index].filename) then
-- (1) flip the history from 1 to the current index
for i = 1, math.floor(index/2) do
filehistory[i], filehistory[index-i+1] = filehistory[index-i+1], filehistory[i]
end
end
-- (2) if the file is in the history, remove it
for i = #filehistory, 1, -1 do
if isSameAs(filename, filehistory[i].filename) then
table.remove(filehistory, i)
end
end
-- (3) update index
filehistory[0] = 1
end
local updateRecentFiles -- need forward declaration because of recursive refs
local function loadRecent(event)
local id = event:GetId()
local item = filehistorymenu:FindItem(id)
local filename = item:GetLabel()
local index = filehistory[0]
filehistory[0] = (
(index > 1 and id == ID("file.recentfiles."..(index-1)) and index-1) or
(index < #filehistory) and id == ID("file.recentfiles."..(index+1)) and index+1 or
1)
if not LoadFile(filename, nil, true) then
wx.wxMessageBox(
TR("File '%s' no longer exists."):format(filename),
GetIDEString("editormessage"),
wx.wxOK + wx.wxCENTRE, ide.frame)
remFileHistory(filename)
updateRecentFiles(filehistory)
end
end
updateRecentFiles = function (list)
local items = filehistorymenu:GetMenuItemCount()
for i=1, #list do
local file = list[i].filename
local id = ID("file.recentfiles."..i)
local label = file..(
i == list[0]-1 and KSC(ID_RECENTFILESNEXT) or
i == list[0]+1 and KSC(ID_RECENTFILESPREV) or
"")
if i <= items then -- this is an existing item; update the label
filehistorymenu:FindItem(id):SetItemLabel(label)
else -- need to add an item
local item = wx.wxMenuItem(filehistorymenu, id, label, "")
filehistorymenu:Append(item)
frame:Connect(id, wx.wxEVT_COMMAND_MENU_SELECTED, loadRecent)
end
end
for i=items, #list+1, -1 do -- delete the rest if the list got shorter
filehistorymenu:Delete(filehistorymenu:FindItemByPosition(i-1))
end
-- enable if there are any recent files
fileMenu:Enable(ID_RECENTFILES, #list > 0)
end
-- public methods
function GetFileHistory() return filehistory end
function SetFileHistory(fh)
filehistory = fh
filehistory[0] = 1
updateRecentFiles(filehistory)
end
function AddToFileHistory(filename)
addFileHistory(filename)
updateRecentFiles(filehistory)
end
end
frame:Connect(ID_NEW, wx.wxEVT_COMMAND_MENU_SELECTED, NewFile)

View File

@@ -9,23 +9,26 @@ local menuBar = frame.menuBar
local mobdebug = require "mobdebug"
local helpMenu = wx.wxMenu{
{ ID_ABOUT, TR("&About")..KSC(ID_ABOUT), TR("About ZeroBrane Studio") },
{ ID_ABOUT, TR("&About")..KSC(ID_ABOUT), TR("About %s"):format(GetIDEString("editor")) },
}
-- do not translate Help menu on Mac as it won't merge with "standard" menus
menuBar:Append(helpMenu, ide.osname == 'Macintosh' and "&Help" or TR("&Help"))
local function DisplayAbout(event)
local page = [[
local logo = ide.config.path.app.."/"..GetIDEString("logo")
local logoimg = wx.wxFileName(logo):FileExists() and
([[<tr><td><img src="%s"></td></tr>]]):format(logo) or ""
local page = ([[
<html>
<body text="#777777">
<table border="0" width="100%">
<tr><td><img src="zbstudio/res/zerobrane.png"></td></tr>
<table border="0" width="100%%">
%s
<tr><td>
<table cellspacing="3" cellpadding="3" width="100%">
<table cellspacing="3" cellpadding="3" width="100%%">
<tr>
<td>
<b>ZeroBrane Studio (]]..ide.VERSION..[[; MobDebug ]]..mobdebug._VERSION..[[)</b><br>
<b>Copyright &copy; 2011-2012 ZeroBrane LLC</b><br>
<b>ZeroBrane Studio (%s; MobDebug %s)</b><br>
<b>Copyright &copy; 2011-2013 ZeroBrane LLC</b><br>
Paul Kulchenko<br>
Licensed under the MIT License.
</td>
@@ -41,7 +44,7 @@ local function DisplayAbout(event)
</tr>
<tr>
<td>
<b>Based on wxLua editor (]]..wxlua.wxLUA_VERSION_STRING..[[)</b><br>
<b>Based on wxLua editor (%s)</b><br>
<b>Copyright &copy; 2002-2005 Lomtick Software</b><br>
J. Winwood, John Labenski<br>
Licensed under wxWindows Library License, v3.
@@ -49,36 +52,43 @@ local function DisplayAbout(event)
</tr>
<tr>
<td>
<b>Built with ]]..wx.wxVERSION_STRING..[[</b>
<b>Built with %s</b>
</td>
</tr>
</table>
</td></tr></table>
</body>
</html>]]
</html>]])
:format(logoimg, ide.VERSION, mobdebug._VERSION,
wxlua.wxLUA_VERSION_STRING, wx.wxVERSION_STRING)
local dlg = wx.wxDialog(frame, wx.wxID_ANY, TR("About %s"):format(GetIDEString("editor")))
-- this is needed because wxLuaHtmlWindow only seems to take into account
-- the initial size, but not the one set with SetSize using
-- wxlua 2.8.12.2 and wxwidgets 2.9.5+.
local tmp = wx.wxLuaHtmlWindow(dlg, wx.wxID_ANY, wx.wxDefaultPosition, wx.wxSize(450, 260))
tmp:SetPage(page)
local w = tmp:GetInternalRepresentation():GetWidth()
local h = tmp:GetInternalRepresentation():GetHeight()
tmp:Destroy()
local dlg = wx.wxDialog(frame, wx.wxID_ANY, TR("About ZeroBrane Studio"))
local html = wx.wxLuaHtmlWindow(dlg, wx.wxID_ANY,
wx.wxDefaultPosition, wx.wxSize(440, 270),
wx.wxHW_SCROLLBAR_NEVER)
local line = wx.wxStaticLine(dlg, wx.wxID_ANY)
local button = wx.wxButton(dlg, wx.wxID_OK, "OK")
button:SetDefault()
wx.wxDefaultPosition, wx.wxSize(w, h), wx.wxHW_SCROLLBAR_NEVER)
html:SetBorders(0)
html:SetPage(page)
html:SetSize(html:GetInternalRepresentation():GetWidth(),
html:GetInternalRepresentation():GetHeight())
local line = wx.wxStaticLine(dlg, wx.wxID_ANY)
local button = wx.wxButton(dlg, wx.wxID_OK, "OK")
button:SetDefault()
local topsizer = wx.wxBoxSizer(wx.wxVERTICAL)
topsizer:Add(html, 1, wx.wxALL, 10)
topsizer:Add(html, 1, wx.wxEXPAND + wx.wxALL, 10)
topsizer:Add(line, 0, wx.wxEXPAND + wx.wxLEFT + wx.wxRIGHT, 10)
topsizer:Add(button, 0, wx.wxALL + wx.wxALIGN_RIGHT, 10)
topsizer:Fit(dlg)
dlg:SetAutoLayout(true)
dlg:SetSizer(topsizer)
dlg:SetSizerAndFit(topsizer)
dlg:ShowModal()
dlg:Destroy()
end

View File

@@ -139,7 +139,8 @@ local function selectInterpreter(id)
ide.interpreter = interpreters[id]
if DebuggerShutdown then DebuggerShutdown() end
DebuggerShutdown()
ide.frame.statusBar:SetStatusText(ide.interpreter.name or "", 5)
ReloadLuaAPI()
end
@@ -190,8 +191,10 @@ end
function ActivateOutput()
if not ide.config.activateoutput then return end
-- show output/errorlog pane
uimgr:GetPane("bottomnotebook"):Show(true)
uimgr:Update()
if not uimgr:GetPane("bottomnotebook"):IsShown() then
uimgr:GetPane("bottomnotebook"):Show(true)
uimgr:Update()
end
-- activate output/errorlog window
local index = bottomnotebook:GetPageIndex(bottomnotebook.errorlog)
if bottomnotebook:GetSelection() ~= index then

View File

@@ -27,38 +27,34 @@ function OnUpdateUISearchMenu(event) event:Enable(GetEditor() ~= nil) end
frame:Connect(ID_FIND, wx.wxEVT_COMMAND_MENU_SELECTED,
function (event)
findReplace:GetSelectedString()
findReplace:Show(false)
end)
frame:Connect(ID_FIND, wx.wxEVT_UPDATE_UI, OnUpdateUISearchMenu)
frame:Connect(ID_REPLACE, wx.wxEVT_COMMAND_MENU_SELECTED,
function (event)
findReplace:GetSelectedString()
findReplace:Show(true)
end)
frame:Connect(ID_REPLACE, wx.wxEVT_UPDATE_UI, OnUpdateUISearchMenu)
frame:Connect(ID_FINDINFILES, wx.wxEVT_COMMAND_MENU_SELECTED,
function (event)
findReplace:GetSelectedString()
findReplace:Show(false,true)
end)
frame:Connect(ID_REPLACEINFILES, wx.wxEVT_COMMAND_MENU_SELECTED,
function (event)
findReplace:GetSelectedString()
findReplace:Show(true,true)
end)
frame:Connect(ID_FINDNEXT, wx.wxEVT_COMMAND_MENU_SELECTED,
function (event) findReplace:GetSelectedString() findReplace:FindString() end)
frame:Connect(ID_FINDNEXT, wx.wxEVT_UPDATE_UI,
function (event) event:Enable(findReplace:GetSelectedString() and findReplace:HasText()) end)
function (event) event:Enable(findReplace:GetSelectedString() or findReplace:HasText()) end)
frame:Connect(ID_FINDPREV, wx.wxEVT_COMMAND_MENU_SELECTED,
function (event) findReplace:GetSelectedString() findReplace:FindString(true) end)
frame:Connect(ID_FINDPREV, wx.wxEVT_UPDATE_UI,
function (event) event:Enable(findReplace:GetSelectedString() and findReplace:HasText()) end)
function (event) event:Enable(findReplace:GetSelectedString() or findReplace:HasText()) end)
-------------------- Find replace end

View File

@@ -7,42 +7,57 @@ local menuBar = frame.menuBar
local uimgr = frame.uimgr
local viewMenu = wx.wxMenu {
{ ID_VIEWFILETREE, TR("Project/&FileTree Window")..KSC(ID_VIEWFILETREE), TR("View the project/filetree window") },
{ ID_VIEWOUTPUT, TR("&Output/Console Window")..KSC(ID_VIEWOUTPUT), TR("View the output/console window") },
{ ID_VIEWWATCHWINDOW, TR("&Watch Window")..KSC(ID_VIEWWATCHWINDOW), TR("View the watch window") },
{ ID_VIEWCALLSTACK, TR("&Stack Window")..KSC(ID_VIEWCALLSTACK), TR("View the stack window") },
{ ID_VIEWFILETREE, TR("Project/&FileTree Window")..KSC(ID_VIEWFILETREE), TR("View the project/filetree window"), wx.wxITEM_CHECK },
{ ID_VIEWOUTPUT, TR("&Output/Console Window")..KSC(ID_VIEWOUTPUT), TR("View the output/console window"), wx.wxITEM_CHECK },
{ ID_VIEWWATCHWINDOW, TR("&Watch Window")..KSC(ID_VIEWWATCHWINDOW), TR("View the watch window"), wx.wxITEM_CHECK },
{ ID_VIEWCALLSTACK, TR("&Stack Window")..KSC(ID_VIEWCALLSTACK), TR("View the stack window"), wx.wxITEM_CHECK },
{ },
{ ID_VIEWDEFAULTLAYOUT, TR("&Default Layout")..KSC(ID_VIEWDEFAULTLAYOUT), TR("Reset to default layout") },
{ ID_VIEWFULLSCREEN, TR("Full &Screen")..KSC(ID_VIEWFULLSCREEN), TR("Switch to or from full screen mode") },
}
menuBar:Append(viewMenu, TR("&View"))
local panels = {
[ID_VIEWOUTPUT] = "bottomnotebook",
[ID_VIEWFILETREE] = "projpanel",
[ID_VIEWWATCHWINDOW] = "watchpanel",
[ID_VIEWCALLSTACK] = "stackpanel"
}
local function togglePanel(event)
local panel = panels[event:GetId()]
local mgr = ide.frame.uimgr
local shown = not mgr:GetPane(panel):IsShown()
mgr:GetPane(panel):Show(shown)
mgr:Update()
return shown
end
local function checkPanel(event)
local panel = panels[event:GetId()]
local shown = ide.frame.uimgr:GetPane(panel):IsShown()
if ide.frame.menuBar:IsChecked(event:GetId()) ~= shown then
ide.frame.menuBar:Check(event:GetId(), shown)
end
end
frame:Connect(ID_VIEWDEFAULTLAYOUT, wx.wxEVT_COMMAND_MENU_SELECTED,
function (event)
uimgr:LoadPerspective(uimgr.defaultPerspective)
uimgr:Update()
uimgr:LoadPerspective(uimgr.defaultPerspective, true)
end)
frame:Connect(ID_VIEWOUTPUT, wx.wxEVT_COMMAND_MENU_SELECTED,
function ()
uimgr:GetPane("bottomnotebook"):Show(true)
uimgr:Update()
end)
frame:Connect(ID_VIEWFILETREE, wx.wxEVT_COMMAND_MENU_SELECTED,
function ()
uimgr:GetPane("projpanel"):Show(true)
uimgr:Update()
end)
frame:Connect(ID_VIEWFULLSCREEN, wx.wxEVT_COMMAND_MENU_SELECTED, function ()
pcall(function() ShowFullScreen(not frame:IsFullScreen()) end)
end)
frame:Connect(ID_VIEWFULLSCREEN, wx.wxEVT_UPDATE_UI,
function (event) event:Enable(GetEditor() ~= nil) end)
frame:Connect(ID_VIEWOUTPUT, wx.wxEVT_COMMAND_MENU_SELECTED, togglePanel)
frame:Connect(ID_VIEWFILETREE, wx.wxEVT_COMMAND_MENU_SELECTED, togglePanel)
frame:Connect(ID_VIEWWATCHWINDOW, wx.wxEVT_COMMAND_MENU_SELECTED,
function () DebuggerCreateWatchWindow() end)
function (event) if togglePanel(event) then DebuggerRefreshPanels() end end)
frame:Connect(ID_VIEWCALLSTACK, wx.wxEVT_COMMAND_MENU_SELECTED,
function () DebuggerCreateStackWindow() end)
function (event) if togglePanel(event) then DebuggerRefreshPanels() end end)
for id in pairs(panels) do frame:Connect(id, wx.wxEVT_UPDATE_UI, checkPanel) end

View File

@@ -60,9 +60,15 @@ local streamouts = {}
local customprocs = {}
local textout = '' -- this is a buffer for any text sent to external scripts
function DetachChildProcess()
for _, custom in pairs(customprocs) do
if (custom and custom.proc) then custom.proc:Detach() end
end
end
function CommandLineRunning(uid)
for pid,custom in pairs(customprocs) do
if (custom.uid == uid and custom.proc and custom.proc.Exists(tonumber(tostring(pid))) )then
if (custom.uid == uid and custom.proc and custom.proc.Exists(tonumber(tostring(pid)))) then
return true
end
end
@@ -140,9 +146,9 @@ function CommandLineRun(cmd,wdir,tooutput,nohide,stringcallback,uid,endcallback)
local proc = wx.wxProcess(errorlog)
if (tooutput) then proc:Redirect() end -- redirect the output if requested
-- manipulate working directory
-- set working directory if specified
local oldcwd
if (wdir) then
if (wdir and #wdir > 0) then -- directory can be empty; ignore in this case
oldcwd = wx.wxFileName.GetCwd()
oldcwd = wx.wxFileName.SetCwd(wdir) and oldcwd
end
@@ -203,11 +209,17 @@ local function updateInputMarker()
inputBound = #getInputText()
end
local readonce = 4096
local maxread = readonce * 10 -- maximum number of bytes to read before pausing
local function getStreams()
local function readStream(tab)
for _,v in pairs(tab) do
while(v.stream:CanRead()) do
local str = v.stream:Read(4096)
-- periodically stop reading to get a chance to process other events
local processed = 0
while (v.stream:CanRead() and processed <= maxread) do
local str = v.stream:Read(readonce)
processed = processed + #str
local pfn
if (v.callback) then
str,pfn = v.callback(str)

View File

@@ -1,303 +0,0 @@
-- authors: Luxinia Dev (Eike Decker & Christoph Kubisch)
---------------------------------------------------------
local ide = ide
-- the preferences dialog
preferencesDialog = {
category = {};
uifactory = {};
}
local cats = preferencesDialog.category
local function checkstring (v,m)
if type(v)~="string" then
error(m.." ("..type(v)..")")
end
end
function preferencesDialog.addCategory(category)
checkstring(category.title,"Invalid category title")
checkstring(category.category,"No category")
assert(not cats[category.category],"Category already declared")
cats[category.category] = category
cats[#cats+1] = category
category.order = category.order or #cats
category.entry = {}
end
function preferencesDialog.addPage(page)
assert(page.category and cats[page.category],"Invalid category given")
checkstring(page.title,"Invalid title")
local c = cats[page.category]
c.entry[#c.entry+1] = page
page.order = page.order or #c.entry
end
function preferencesDialog.uifactory.space(page,layout,element)
layout.currentx = layout.currentx + element.space
return layout
end
function preferencesDialog.uifactory.group(page,layout,element)
local margin = element.margin or 6
local nl = {
currentx = margin;
currenty = margin+ (element.title and 12 or 8);
maxsizex = 0;
maxsizey = 0;
minwidth = element.minwidth or 0;
minheight = element.minheight or 0;
margin = margin;
layout = layout;
parent = wx.wxStaticBox(layout.parent,wx.wxID_ANY,element.title or "",
wx.wxPoint(layout.currentx,layout.currenty),
wx.wxDefaultSize, element.borderstyle and wx["wxBORDER_"..element.borderstyle:upper()] or 0);
}
return nl
end
function preferencesDialog.uifactory.finishgroup(page,layout,element)
local l = layout.layout
layout.maxsizex = math.max(layout.minwidth,layout.maxsizex + layout.margin)
layout.maxsizey = math.max(layout.minheight,layout.maxsizey + layout.margin)
l.maxsizey = math.max(l.maxsizey,layout.maxsizey+l.currenty)
l.currentx = l.currentx + layout.maxsizex
l.maxsizex = math.max(l.maxsizex,l.currentx)
layout.parent:SetSize(wx.wxSize(layout.maxsizex,layout.maxsizey))
return l
end
local function pos(layout) return layout.currentx,layout.currenty end
local function fitin(el,layout)
local x,y = pos(layout)
local sz = el:GetBestFittingSize()
el:SetSize(sz)
layout.maxsizex = math.max(x+sz:GetWidth(),layout.maxsizex)
layout.maxsizey = math.max(y+sz:GetHeight(),layout.maxsizey)
layout.currentx = x+sz:GetWidth()
return layout
end
function preferencesDialog.uifactory.combobox(page,layout,element,value)
local x,y = pos(layout)
local id = ID("view.preferences.dialog.page."..page.title.."."..element.name)
local cbox = wx.wxComboBox(layout.parent,id,"",wx.wxPoint(x,y-4),wx.wxDefaultSize,
wx.wxArrayString(),wx.wxCB_READONLY)
if value then
for i=1,#value do
cbox:Append(value[i])
end
end
return fitin(cbox,layout)
end
function preferencesDialog.uifactory.dirpicker(page,layout,element,value)
local x,y = pos(layout)
local id = ID("view.preferences.dialog.page."..page.title.."."..element.name)
local picker = wx.wxDirPickerCtrl(layout.parent,id,value or "",element.title or "",wx.wxPoint(x,y-4))
return fitin(picker,layout)
end
function preferencesDialog.uifactory.edit (page,layout,element,value)
local x,y = pos(layout)
local id = ID("view.preferences.dialog.page."..page.title.."."..element.name)
local edit = wx.wxTextCtrl(layout.parent,id,value or (""..x..","..y), wx.wxPoint(x,y-4))
return fitin(edit,layout)
end
function preferencesDialog.uifactory.linebreak(page,layout,element)
layout.currentx = layout.margin or 0
layout.currenty = layout.maxsizey + (element.space or 0)
return layout
end
function preferencesDialog.uifactory.checkbox (page,layout,element, value)
local x,y = pos(layout)
local id = ID("view.preferences.dialog.page."..page.title.."."..element.name)
local cbox = wx.wxCheckBox(layout.parent,id,element.title,wx.wxPoint(x,y))
if value then cbox:SetValue(value) end
return fitin(cbox,layout)
end
function preferencesDialog.uifactory.static(page,layout,element)
local x,y = pos(layout)
local static = wx.wxStaticText(layout.parent,wx.wxID_ANY,element.title,wx.wxPoint(x,y))
return fitin(static,layout)
end
function preferencesDialog.uifactory.space(page,layout,element)
layout.currentx = layout.currentx + element.space
return layout
end
function preferencesDialog.uifactory.group(page,layout,element)
local margin = element.margin or 6
local nl = {
currentx = margin;
currenty = margin+ (element.title and 12 or 8);
maxsizex = 0;
maxsizey = 0;
minwidth = element.minwidth or 0;
minheight = element.minheight or 0;
margin = margin;
layout = layout;
parent = wx.wxStaticBox(layout.parent,wx.wxID_ANY,element.title or "",
wx.wxPoint(layout.currentx,layout.currenty),
wx.wxDefaultSize, element.borderstyle and wx["wxBORDER_"..element.borderstyle:upper()] or 0);
}
return nl
end
function preferencesDialog.uifactory.finishgroup(page,layout,element)
local l = layout.layout
layout.maxsizex = math.max(layout.minwidth,layout.maxsizex + layout.margin)
layout.maxsizey = math.max(layout.minheight,layout.maxsizey + layout.margin)
l.maxsizey = math.max(l.maxsizey,layout.maxsizey+l.currenty)
l.currentx = l.currentx + layout.maxsizex
l.maxsizex = math.max(l.maxsizex,l.currentx)
layout.parent:SetSize(wx.wxSize(layout.maxsizex,layout.maxsizey))
return l
end
function preferencesDialog.uifactory.linebreak(page,layout,element)
layout.currentx = layout.margin or 0
layout.currenty = layout.maxsizey + (element.space or 0)
return layout
end
function preferencesDialog.uifactory.checkbox (page,layout,element, value)
local x,y = layout.currentx,layout.currenty
local id = ID("view.preferences.dialog.page."..page.title.."."..element.name)
local cbox = wx.wxCheckBox(layout.parent,id,element.title,wx.wxPoint(x,y))
local sz = cbox:GetBestFittingSize()
cbox:SetSize(sz)
layout.maxsizex = math.max(x+sz:GetWidth(),layout.maxsizex)
layout.maxsizey = math.max(y+sz:GetHeight(),layout.maxsizey)
layout.currentx = layout.maxsizex
if value then cbox:SetValue(value) end
return layout
end
function preferencesDialog.uifactory.static(page,layout,element)
local x,y = layout.currentx,layout.currenty
local static = wx.wxStaticText(layout.parent,wx.wxID_ANY,element.title,wx.wxPoint(x,y))
local sz = static:GetBestFittingSize()
static:SetSize(sz)
layout.maxsizex = math.max(x+sz:GetWidth(),layout.maxsizex)
layout.maxsizey = math.max(y+sz:GetHeight(),layout.maxsizey)
layout.currentx = layout.maxsizex
return layout
end
local function showpage(panel,page)
--TODO: layout the page, load values, etc
local data = page.onload()
local layout = page.layout
local layoutdata = {
currentx = 0;
currenty = 0;
maxsizex = 0;
maxsizey = 0;
parent = panel;
}
for i,el in ipairs(layout) do
assert(preferencesDialog.uifactory[el.type],"Unknown ui type type")
layoutdata = assert(
preferencesDialog.uifactory[el.type](page,layoutdata,el,data[el.name])
)
end
panel:SetSize(layoutdata.maxsizex,layoutdata.maxsizey)
--print(layoutdata.maxsizex,layoutdata.maxsizey)
end
function preferencesDialog.show(event)
local dialog = wx.wxDialog(ide.frame, ID "view.preferences.dialog","Preferences")
local id_btn_ok = ID "view.preferences.dialog.button.ok"
local id_btn_cancel = ID "view.preferences.dialog.button.cancel"
local id_btn_apply = ID "view.preferences.dialog.button.apply"
local panel_buttons = wx.wxPanel(dialog,ID "view.preferences.dialog.buttonpanel")
local btn_ok = wx.wxButton(panel_buttons,id_btn_ok, "OK")
local btn_cancel = wx.wxButton(panel_buttons,id_btn_cancel, "Cancel")
local btn_apply = wx.wxButton(panel_buttons,id_btn_apply, "Apply")
dialog:Connect(id_btn_cancel, wx.wxEVT_COMMAND_BUTTON_CLICKED,
function (event)
dialog:EndModal(0)
end)
dialog:Connect(id_btn_ok, wx.wxEVT_COMMAND_BUTTON_CLICKED,
function (event)
dialog:EndModal(0)
end)
local panel = wx.wxPanel(dialog,ID "view.preferences.dialog.panel",
wx.wxDefaultPosition, wx.wxSize(600,400))
local projtree = wx.wxTreeCtrl(panel, ID "view.preferences.dialog.panel.tree",
wx.wxDefaultPosition, wx.wxSize(180,400),
wx.wxTR_HAS_BUTTONS + wx.wxTR_SINGLE + wx.wxTR_HIDE_ROOT)
local preferencesPage = wx.wxPanel(panel,ID "view.preferences.dialog.page",
wx.wxDefaultPosition, wx.wxSize(500,400))
local panelsizer = wx.wxBoxSizer(wx.wxHORIZONTAL)
panelsizer:Add(projtree,0,wx.wxALL + wx.wxALIGN_LEFT + wx.wxTOP + wx.wxBOTTOM,0)
panelsizer:AddSpacer(5)
panelsizer:Add(preferencesPage)
panel:SetSizer(panelsizer)
local treecats = {}
local catdata = {}
table.sort(cats,function(a,b) return a.order < b.order end)
local rootit = projtree:AddRoot("")
catdata[rootit:GetValue()] = {category = "root", children = treecats}
for i=1,#cats do
local it = projtree:AppendItem(rootit,cats[i].title)
treecats[i] = it
local c = cats[i]
local children = {}
catdata[it:GetValue()] = {category = c,children = children}
for i=1,#c.entry do
local e = c.entry[i]
local it = projtree:AppendItem(it,e.title)
catdata[it:GetValue()] = {page = e}
children[i] = it
end
projtree:Expand(it)
end
projtree:Expand(rootit)
local preferencesContent
projtree:Connect( wx.wxEVT_COMMAND_TREE_SEL_CHANGED,
function( event )
local item_id = event:GetItem():GetValue()
local data = catdata[item_id]
if data.category then
if data.children[1] then
projtree:SelectItem(data.children[1])
end
else
if preferencesContent then
preferencesPage:RemoveChild(preferencesContent)
end
preferencesContent = wx.wxPanel(preferencesPage,wx.wxID_ANY)
showpage(preferencesContent,data.page)
end
end )
local topsizer = wx.wxBoxSizer(wx.wxVERTICAL)
topsizer:Add(panel,0,wx.wxALL + wx.wxALIGN_CENTER,10)
topsizer:Add(wx.wxStaticLine(dialog, wx.wxID_ANY), 0, wx.wxEXPAND + wx.wxLEFT + wx.wxRIGHT, 10)
topsizer:Add(panel_buttons, 0, wx.wxALL + wx.wxALIGN_RIGHT, 10)
local buttonpanelsizer = wx.wxBoxSizer(wx.wxHORIZONTAL)
buttonpanelsizer:Add(btn_cancel,0,wx.wxALL + wx.wxALIGN_RIGHT,0)
buttonpanelsizer:AddSpacer(5)
buttonpanelsizer:Add(btn_apply,0,wx.wxALL + wx.wxALIGN_RIGHT,0)
buttonpanelsizer:AddSpacer(5)
buttonpanelsizer:Add(btn_ok,0,wx.wxALL + wx.wxALIGN_RIGHT,0)
panel_buttons:SetSizer(buttonpanelsizer)
buttonpanelsizer:Fit(panel_buttons)
dialog:SetAutoLayout(true)
dialog:SetSizer(topsizer)
topsizer:Fit(dialog)
dialog:Center()
dialog:ShowModal()
end

View File

@@ -100,30 +100,16 @@ function SettingsRestoreFileHistory(fntab)
return outtab
end
function SettingsAppendFileToHistory (filename)
function SettingsSaveFileHistory (filehistory)
local listname = "/filehistory"
local oldlist = SettingsRestoreFileHistory(nil,listname)
-- if the file has been in the history before, remove it
for i=#oldlist,1,-1 do
if oldlist[i] == filename then table.remove(oldlist,i) end
end
table.insert(oldlist,1,{filename=filename})
-- remove all entries that are no longer needed
while #oldlist>ide.config.filehistorylength do table.remove(oldlist) end
local path = settings:GetPath()
settings:DeleteGroup(listname)
settings:SetPath(listname)
for i,doc in ipairs(oldlist) do
for i,doc in ipairs(filehistory) do
settings:Write(tostring(i), doc.filename)
end
UpdateFileHistoryUI(oldlist)
settings:SetPath(path)
end
@@ -371,13 +357,20 @@ function SettingsRestoreView()
local layoutcur = uimgr:SavePerspective()
local layout = settingsReadSafe(settings,"uimgrlayout",layoutcur)
if (layout ~= layoutcur) then
uimgr:LoadPerspective(layout)
uimgr:LoadPerspective(layout, false)
-- check if debugging panes are not mentioned and float them
local panes = frame.uimgr:GetAllPanes()
for _, name in pairs({"stackpanel", "watchpanel"}) do
local pane = frame.uimgr:GetPane(name)
if not layout:find(name) then pane:Float() end
end
-- unfortunately need to explicitly (re-)assign the caption,
-- as it's going to be restored from the config regardless of how
-- it is set now (which affects its translation)
uimgr:GetPane("projpanel"):Caption(TR("Project"))
uimgr:Update()
end
uimgr:Update()
local layoutcur = saveNotebook(frame.notebook)
local layout = settingsReadSafe(settings,"nblayout",layoutcur)
@@ -443,6 +436,7 @@ function SettingsSaveAll()
SettingsSaveProjectSession(FileTreeGetProjects())
SettingsSaveFileSession(GetOpenFiles())
SettingsSaveView()
SettingsSaveFileHistory(GetFileHistory())
SettingsSaveFramePosition(ide.frame, "MainFrame")
SettingsSaveEditorSettings()
end

View File

@@ -280,8 +280,8 @@ local function executeShellCode(tx)
-- set the project dir as the current dir to allow "require" calls
-- to work from shell
local projectDir, cwd = FileTreeGetDir()
if projectDir then
local projectDir, cwd = FileTreeGetDir(), nil
if projectDir and #projectDir > 0 then
cwd = wx.wxFileName.GetCwd()
wx.wxFileName.SetCwd(projectDir)
end
@@ -292,7 +292,7 @@ local function executeShellCode(tx)
end))
-- restore the current dir
if projectDir then wx.wxFileName.SetCwd(cwd) end
if cwd then wx.wxFileName.SetCwd(cwd) end
if ok and (addedret or #res > 0) then
if addedret then
@@ -431,10 +431,37 @@ out:Connect(wx.wxEVT_KEY_DOWN,
end)
local function inputEditable(line)
return caretOnPromptLine(fale, line) and
return caretOnPromptLine(false, line) and
not (out:LineFromPosition(out:GetSelectionStart()) < getPromptLine())
end
-- new Scintilla changed the way markers move when the text is updated
-- ticket: http://sourceforge.net/p/scintilla/bugs/939/
-- discussion: https://groups.google.com/forum/?hl=en&fromgroups#!topic/scintilla-interest/4giFiKG4VXo
if ide.wxver >= "2.9.5" then
-- this is a workaround that stores a position of the last prompt marker
-- before insert and restores the same position after (as the marker)
-- could have moved if the text is added at the beginning of the line.
local promptAt
out:Connect(wxstc.wxEVT_STC_MODIFIED,
function (event)
local evtype = event:GetModificationType()
if bit.band(evtype, wxstc.wxSTC_MOD_BEFOREINSERT) ~= 0 then
local promptLine = getPromptLine()
if promptLine and event:GetPosition() == out:PositionFromLine(promptLine)
then promptAt = promptLine end
end
if bit.band(evtype, wxstc.wxSTC_MOD_INSERTTEXT) ~= 0 then
local promptLine = getPromptLine()
if promptLine and promptAt then
out:MarkerDelete(promptLine, PROMPT_MARKER)
out:MarkerAdd(promptAt, PROMPT_MARKER)
promptAt = nil
end
end
end)
end
out:Connect(wxstc.wxEVT_STC_UPDATEUI,
function (event) out:SetReadOnly(not inputEditable()) end)

View File

@@ -69,14 +69,15 @@ else -- something different is running on our port
local failed = false
for index = 2, #arg do
local fileName = arg[index]
if fileName ~= "--" then
if fileName ~= "--"
-- on OSX, the command line includes -psn parameter, so ignore it
and (ide.osname ~= 'Macintosh' or not fileName:find("^-psn")) then
cln:send(protocol.client.requestloading:format(fileName))
local msg,err = cln:receive()
if msg ~= protocol.server.answerok then
failed = true
print(err,msg)
else
end
end
end

View File

@@ -42,7 +42,7 @@ function StylesGetDefault()
bracematch = {fg = {0, 0, 255}, b = true},
bracemiss = {fg = {255, 0, 0 }, b = true},
ctrlchar = nil,
indent = {fg = {192, 192, 192}, bg = {255, 255, 255}},
indent = {fg = {192, 192, 230}, bg = {255, 255, 255}},
calltip = nil,
-- common special (need custom fg & bg)
@@ -53,7 +53,8 @@ function StylesGetDefault()
fold = {fg = {90, 90, 80}, bg = {250, 250, 250}},
whitespace = nil,
fncall = {fg = {175, 175, 255}, st = wxstc.wxSTC_INDIC_TT},
fncall = {fg = {128, 128, 255},
st = ide.wxver >= "2.9.5" and wxstc.wxSTC_INDIC_ROUNDBOX or wxstc.wxSTC_INDIC_TT},
-- markup
['|'] = {fg = {127, 0, 127}},

View File

@@ -3,33 +3,34 @@
-- put bin/ and lualibs/ first to avoid conflicts with included modules
-- that may have other versions present somewhere else in path/cpath.
-- don't need to do this on Linux where we expect all the libraries
-- and binaries to be installed in *regular* places.
local iswindows = os.getenv('WINDIR') or (os.getenv('OS') or ''):match('[Ww]indows')
local islinux = not iswindows and not os.getenv('DYLD_LIBRARY_PATH') and io.open("/proc")
local arch = "x86" -- use 32bit by default
if iswindows or not pcall(require, "wx")
or wx.wxPlatformInfo.Get():GetOperatingSystemFamilyName() == 'Macintosh' then
package.cpath = (iswindows
and 'bin/?.dll;bin/clibs/?.dll;'
or 'bin/clibs/?.dylib;bin/lib?.dylib;')
.. package.cpath
if islinux then
local file = io.popen("uname -m")
if file then
arch = file:read("*a"):find("x86_64") and "x64" or "x86"
file:close()
end
end
package.cpath = (
iswindows and 'bin/?.dll;bin/clibs/?.dll;' or
islinux and ('bin/linux/%s/lib?.so;bin/linux/%s/clibs/?.so;'):format(arch,arch) or
--[[isosx]] 'bin/lib?.dylib;bin/clibs/?.dylib;')
.. package.cpath
package.path = 'lualibs/?.lua;lualibs/?/?.lua;lualibs/?/init.lua;lualibs/?/?/?.lua;lualibs/?/?/init.lua;'
.. package.path
require("wx")
require("bit")
dofile "src/misc/util.lua"
dofile "src/util.lua"
-----------
-- IDE
--
-- Setup important defaults
dofile "src/editor/ids.lua"
dofile "src/editor/style.lua"
ide = {
config = {
path = {
@@ -51,13 +52,14 @@ ide = {
},
outputshell = {},
filetree = {},
funclist = {},
keymap = {},
messages = {},
language = "en",
styles = StylesGetDefault(),
stylesoutshell = StylesGetDefault(),
styles = nil,
stylesoutshell = nil,
interpreter = "_undefined_",
autocomplete = true,
@@ -121,12 +123,30 @@ ide = {
oNormal = nil,
oItalic = nil,
fNormal = nil,
}
dNormal = nil,
},
osname = wx.wxPlatformInfo.Get():GetOperatingSystemFamilyName(),
osarch = arch,
wxver = string.match(wx.wxVERSION_STRING, "[%d%.]+"),
}
-- add wx.wxMOD_RAW_CONTROL as it's missing in wxlua 2.8.12.3;
-- provide default for wx.wxMOD_CONTROL as it's missing in wxlua 2.8 that
-- is available through Linux package managers
if not wx.wxMOD_CONTROL then wx.wxMOD_CONTROL = 0x02 end
if not wx.wxMOD_RAW_CONTROL then
wx.wxMOD_RAW_CONTROL = ide.osname == 'Macintosh' and 0x10 or wx.wxMOD_CONTROL
end
dofile "src/editor/ids.lua"
dofile "src/editor/style.lua"
dofile "src/editor/keymap.lua"
function setLuaPaths(mainpath, osname)
ide.config.styles = StylesGetDefault()
ide.config.stylesoutshell = StylesGetDefault()
local function setLuaPaths(mainpath, osname)
-- use LUA_DEV to setup paths for Lua for Windows modules if installed
local luadev = osname == "Windows" and os.getenv('LUA_DEV')
local luadev_path = (luadev
@@ -152,7 +172,9 @@ function setLuaPaths(mainpath, osname)
local clibs =
osname == "Windows" and mainpath.."bin/?.dll;"..mainpath.."bin/clibs/?.dll" or
osname == "Macintosh" and mainpath.."bin/lib?.dylib;"..mainpath.."bin/clibs/?.dylib" or
osname == "Unix" and mainpath.."bin/?.so;"..mainpath.."bin/clibs/?.so" or nil
osname == "Unix" and mainpath..("bin/linux/%s/lib?.so;"):format(arch)
..mainpath..("bin/linux/%s/clibs/?.so"):format(arch) or
nil
if clibs then wx.wxSetEnv("LUA_CPATH",
package.cpath .. ';' .. clibs .. ';' .. luadev_cpath) end
end
@@ -163,11 +185,10 @@ local filenames = {}
local configs = {}
do
local arg = {...}
local fullPath = arg[1] -- first argument must be the application name
assert(type(fullPath) == "string", "first argument must be application name")
-- application name is expected as the first argument
local fullPath = arg[1] or "zbstudio"
ide.arg = arg
ide.osname = wx.wxPlatformInfo.Get():GetOperatingSystemFamilyName()
-- on Windows use GetExecutablePath, which is Unicode friendly,
-- whereas wxGetCwd() is not (at least in wxlua 2.8.12.2).
@@ -185,12 +206,7 @@ do
for index = 2, #arg do
if (arg[index] == "-cfg" and index+1 <= #arg) then
local str = arg[index+1]
if #str < 4 then
print("Comandline: -cfg arg data not passed as string")
else
table.insert(configs,str)
end
table.insert(configs,arg[index+1])
elseif arg[index-1] ~= "-cfg" then
table.insert(filenames,arg[index])
end
@@ -203,18 +219,17 @@ end
-- process application
ide.app = dofile(ide.config.path.app.."/app.lua")
local app = ide.app
assert(app)
local app = assert(ide.app)
local function addToTab(tab,file)
local cfgfn,err = loadfile(file)
if not cfgfn then
print(("Error while loading configuration file: %s"):format(err))
print(("Error while loading configuration file: '%s'."):format(err))
else
local name = file:match("([a-zA-Z_0-9]+)%.lua$")
local success, result = pcall(function()return cfgfn(assert(_G or _ENV))end)
if not success then
print(("Error while processing configuration file: %s"):format(result))
print(("Error while processing configuration file: '%s'."):format(result))
elseif name then
if (tab[name]) then
local out = tab[name]
@@ -230,8 +245,8 @@ end
-- load interpreters
local function loadInterpreters(filter)
for _, file in ipairs(FileSysGet("interpreters/*.*", wx.wxFILE)) do
if file:match "%.lua$" and (filter or app.loadfilters.interpreters)(file) then
for _, file in ipairs(FileSysGetRecursive("interpreters", true, "*.lua")) do
if (filter or app.loadfilters.interpreters)(file) then
addToTab(ide.interpreters,file)
end
end
@@ -239,8 +254,8 @@ end
-- load specs
local function loadSpecs(filter)
for _, file in ipairs(FileSysGet("spec/*.*", wx.wxFILE)) do
if file:match("%.lua$") and (filter or app.loadfilters.specs)(file) then
for _, file in ipairs(FileSysGetRecursive("spec", true, "*.lua")) do
if (filter or app.loadfilters.specs)(file) then
addToTab(ide.specs,file)
end
end
@@ -272,8 +287,8 @@ end
-- load tools
local function loadTools(filter)
for _, file in ipairs(FileSysGet("tools/*.*", wx.wxFILE)) do
if file:match "%.lua$" and (filter or app.loadfilters.tools)(file) then
for _, file in ipairs(FileSysGetRecursive("tools", false, "*.lua")) do
if (filter or app.loadfilters.tools)(file) then
addToTab(ide.tools,file)
end
end
@@ -287,13 +302,14 @@ local resumePrint do
print = function(...) errors[#errors+1] = {...} end
resumePrint = function()
print = origprint
for _, e in ipairs(errors) do DisplayOutput(unpack(e), "\n") end
for _, e in ipairs(errors) do DisplayOutputLn(unpack(e)) end
end
end
-----------------------
-- load config
local function addConfig(filename,isstring)
if not filename then return end
-- skip those files that don't exist
if not isstring and not wx.wxFileName(filename):FileExists() then return end
-- if it's marked as command, but exists as a file, load it as a file
@@ -305,7 +321,7 @@ local function addConfig(filename,isstring)
else msg, cfgfn, err = "file", loadfile(filename) end
if not cfgfn then
print(("Error while loading configuration %s: %s"):format(msg, err))
print(("Error while loading configuration %s: '%s'."):format(msg, err))
else
ide.config.os = os
ide.config.wxstc = wxstc
@@ -314,7 +330,7 @@ local function addConfig(filename,isstring)
setfenv(cfgfn,ide.config)
local _, err = pcall(function()cfgfn(assert(_G or _ENV))end)
if err then
print(("Error while processing configuration %s: %s"):format(msg, err))
print(("Error while processing configuration %s: '%s'."):format(msg, err))
end
end
end
@@ -328,6 +344,22 @@ end
addConfig(ide.config.path.app.."/config.lua")
ide.editorApp:SetAppName(GetIDEString("settingsapp"))
-- check if the .ini file needs to be migrated on Windows
if ide.osname == 'Windows' and ide.wxver >= "2.9.5" then
-- Windows used to have local ini file kept in wx.wxGetHomeDir (before 2.9),
-- but since 2.9 it's in GetUserConfigDir(), so migrate it.
local ini = ide.editorApp:GetAppName() .. ".ini"
local old = wx.wxFileName(wx.wxGetHomeDir(), ini)
local new = wx.wxFileName(wx.wxStandardPaths.Get():GetUserConfigDir(), ini)
if old:FileExists() and not new:FileExists() then
FileCopy(old:GetFullPath(), new:GetFullPath())
print(("Migrated configuration file from '%s' to '%s'.")
:format(old:GetFullPath(), new:GetFullPath()))
end
end
----------------------
-- process plugins
@@ -338,20 +370,19 @@ loadSpecs()
loadTools()
do
-- process user config
for _, file in ipairs(FileSysGet("cfg/user.lua", wx.wxFILE)) do
addConfig(file)
end
local home = os.getenv("HOME")
if home then
for _, file in ipairs(FileSysGet(home .. "/.zbstudio/user.lua", wx.wxFILE)) do
addConfig(file)
end
end
ide.configs = {
system = MergeFullPath("cfg", "user.lua"),
user = home and MergeFullPath(home, ".zbstudio/user.lua"),
}
-- process configs
addConfig(ide.configs.system)
addConfig(ide.configs.user)
-- process all other configs (if any)
for _, v in ipairs(configs) do
addConfig(v, true)
end
for _, v in ipairs(configs) do addConfig(v, true) end
configs = nil
local sep = string_Pathsep
if ide.config.language then
@@ -359,15 +390,12 @@ do
end
end
-- load this after preinit and processing configs to allow
-- each of the lists to be modified
---------------
-- Load App
for _, file in ipairs({
"markup", "settings", "singleinstance", "iofilters",
"gui", "filetree", "output", "debugger", "preferences",
"gui", "filetree", "output", "debugger",
"editor", "findreplace", "commands", "autocomplete", "shellbox",
"menu_file", "menu_edit", "menu_search",
"menu_view", "menu_project", "menu_tools", "menu_help",
@@ -375,19 +403,17 @@ for _, file in ipairs({
dofile("src/editor/"..file..".lua")
end
dofile "src/preferences/editor.lua"
dofile "src/preferences/project.lua"
dofile "src/version.lua"
-- load rest of settings
SettingsRestoreEditorSettings()
SettingsRestoreFramePosition(ide.frame, "MainFrame")
SettingsRestoreFileHistory(SetFileHistory)
SettingsRestoreFileSession(function(tabs, params)
if params and params.recovery
then return SetOpenTabs(params)
else return SetOpenFiles(tabs, params) end
end)
SettingsRestoreFileHistory(UpdateFileHistoryUI)
SettingsRestoreProjectSession(FileTreeSetProjects)
SettingsRestoreView()
@@ -411,7 +437,7 @@ if app.postinit then app.postinit() end
-- app-specific menus (Help/About), which are not recognized by MacOS
-- as special items unless SetMenuBar is done after menus are populated.
ide.frame:SetMenuBar(ide.frame.menuBar)
if ide.osname == 'Macintosh' then -- force refresh to fix the filetree
if ide.wxver < "2.9.5" and ide.osname == 'Macintosh' then -- force refresh to fix the filetree
pcall(function() ide.frame:ShowFullScreen(true) ide.frame:ShowFullScreen(false) end)
end
@@ -419,3 +445,10 @@ resumePrint()
ide.frame:Show(true)
wx.wxGetApp():MainLoop()
-- There are several reasons for this call:
-- (1) to fix a crash on OSX when closing with debugging in progress.
-- (2) to fix a crash on Linux 32/64bit during GC cleanup in wxlua
-- after an external process has been started from the IDE.
-- (3) to fix exit on Windows when started as "bin\lua src\main.lua".
os.exit()

View File

@@ -1,23 +0,0 @@
-- authors: Luxinia Dev (Eike Decker & Christoph Kubisch)
---------------------------------------------------------
preferencesDialog.addCategory {
category = "editor";
title = "Editor";
}
preferencesDialog.addPage {
title = "Basic preferences";
category = "editor";
layout = {
{type = 'group',title="Sessions"; minheight = 100; minwidth = 100};
{type = "checkbox"; title = "Reopen files";name = 'session_restore'};
{type = 'finishgroup'};
{type = 'space'; space = 4};
};
onload = function ()
return {testbox = true}
end;
onsave = function (values)
end
}

View File

@@ -1,37 +0,0 @@
-- authors: Luxinia Dev (Eike Decker & Christoph Kubisch)
---------------------------------------------------------
preferencesDialog.addCategory {
category = "project";
title = "Project";
}
preferencesDialog.addPage {
title = "Project settings";
category = "project";
layout = {
{type = 'group',title="Visible menus"; minheight = 100; minwidth = 100};
{type = "checkbox"; title = "Tools";name = 'tools'};
{type = 'linebreak'; space = 4};
{type = "checkbox"; title = "Help";name = 'help'};
{type = 'linebreak'; space = 4};
--{type='static'; title = "foo"};
{type = 'finishgroup'};
{type = "space"; space = 4};
{type = 'group',title="Interpreter"; minheight = 100; minwidth = 100};
{type = "static"; title = "Interpreter"};
{type = "space"; space = 4};
{type = "combobox"; name = "interpreterlist"};
{type = 'linebreak'; space = 4};
{type = "static";title = "Working directory"};
{type = "dirpicker"; name = "workingdir", title='Working directory'};
{type = 'linebreak'; space = 4};
{type = "static"; title = "Argument"};
{type = "edit"; name = "argument"};
{type = 'finishgroup'};
};
onload = function () return {
interpreterlist = {"1","2"}
} end;
onsave = function (values) end;
}

View File

@@ -161,25 +161,39 @@ function FileSysHasContent(dir)
return #f>0
end
function FileSysGet(dir,spec)
function FileSysGetRecursive(path, recursive, spec, skip)
spec = spec or "*"
local content = {}
local browse = wx.wxFileSystem()
if not wx.wxFileName(dir):DirExists() then
return content
end
local f = browse:FindFirst(dir,spec)
while #f>0 do
if f:match("^file:") then -- remove file: protocol (wx2.9+)
f = f:gsub(ide.osname == "Windows" and "^file:/?" or "^file:","")
:gsub('%%(%x%x)', function(n) return string.char(tonumber(n, 16)) end)
local sep = string.char(wx.wxFileName.GetPathSeparator())
-- recursion is done in all folders but only those folders that match
-- the spec are returned. This is the pattern that matches the spec.
local specmask = spec:gsub("%.", "%%."):gsub("%*", ".*").."$"
local function getDir(path, spec)
local dir = wx.wxDir(path)
if not dir:IsOpened() then return end
local found, file = dir:GetFirst("*", wx.wxDIR_DIRS)
while found do
if not skip or not file:find(skip) then
local fname = wx.wxFileName(path, file):GetFullPath()
if fname:find(specmask) then table.insert(content, fname..sep) end
if recursive then getDir(fname, spec) end
end
found, file = dir:GetNext()
end
local found, file = dir:GetFirst(spec, wx.wxDIR_FILES)
while found do
if not skip or not file:find(skip) then
local fname = wx.wxFileName(path, file):GetFullPath()
table.insert(content, fname)
end
found, file = dir:GetNext()
end
local file = wx.wxFileName(f)
-- normalize path if possible to correct separators for the local FS
table.insert(content,
file:Normalize(wx.wxPATH_NORM_ALL) and file:GetFullPath() or f)
f = browse:FindNext()
end
if ide.osname == 'Unix' then table.sort(content) end
getDir(path, spec)
return content
end
@@ -190,7 +204,8 @@ function GetFullPathIfExists(p, f)
-- f = 'xyz/main.lua' work correctly. Normalize() returns true if done.
return (file:Normalize(wx.wxPATH_NORM_ALL, p)
and file:FileExists()
and file:GetFullPath())
and file:GetFullPath()
or nil)
end
function MergeFullPath(p, f)
@@ -199,7 +214,8 @@ function MergeFullPath(p, f)
-- Normalize call is needed to make the case of p = '/abc/def' and
-- f = 'xyz/main.lua' work correctly. Normalize() returns true if done.
return (file:Normalize(wx.wxPATH_NORM_ALL, p)
and file:GetFullPath())
and file:GetFullPath()
or nil)
end
function FileWrite(file,content)

63
t/1-findreplace.lua Normal file
View File

@@ -0,0 +1,63 @@
local findReplace = ide.findReplace
local editor = NewFile()
ok(editor, "Open New file.")
local search = "123"
local replace = "4"
editor:AppendText(search..search.."\n"..search..search)
ide.frame:ProcessEvent(wx.wxCommandEvent(wx.wxEVT_COMMAND_MENU_SELECTED, ID_FIND))
ok(findReplace.dialog, "Open Find/Replace dialog.")
findReplace.findText = search
ok(findReplace:HasText(), "Update text to search.")
findReplace:FindString()
ok(editor:GetSelectionStart() ~= editor:GetSelectionEnd(), "Find text with Find Next.")
local selend = editor:GetSelectionEnd()
findReplace:FindString()
is(editor:GetSelectionStart(), selend, "Find Next doesn't skip consecutive matches.")
editor:GotoPos(0) -- reset current selection
local findnext = wx.wxUpdateUIEvent(ID_FINDNEXT)
ide.frame:ProcessEvent(findnext)
ok(findnext:GetEnabled(), "Quick find is enabled without current selection.")
ide.frame:ProcessEvent(wx.wxCommandEvent(wx.wxEVT_COMMAND_MENU_SELECTED, ID_FINDNEXT))
is(editor:GetSelectionEnd(), selend, "Quick Find works based on previous search.")
ide.frame:ProcessEvent(wx.wxCommandEvent(wx.wxEVT_COMMAND_MENU_SELECTED, ID_FINDNEXT))
is(editor:GetSelectionStart(), selend, "Quick Find finds next match.")
-- replace the text once
findReplace.replaceText = replace
findReplace:ReplaceString()
local _, replacements = editor:GetText():gsub(replace, replace)
is(replacements, 1, "Replace replaces once.")
-- replace the current text and to the end of file
editor:GotoPos(3)
findReplace.fWrap = false
findReplace:ReplaceString(true)
local _, replacements = editor:GetText():gsub(replace, replace)
is(replacements, 3, "Replace All without wrapping replaces to the end of file.")
local expected = search..replace.."\n"..replace..replace
is(editor:GetText(), expected, "Replace All with Wrap Around result is as expected.")
-- start after the match to test wrapping
editor:AppendText("\n"..search..search)
editor:GotoPos(3)
findReplace.fWrap = true
findReplace:ReplaceString(true)
ok(not editor:GetText():find(search), "Replace All with Wrap Around replaces everything.")
local expected = replace..replace.."\n"..replace..replace.."\n"..replace..replace
is(editor:GetText(), expected, "Replace All without Wrap Around result is as expected.")
-- cleanup
ide.findReplace.dialog:Hide()
while editor:CanUndo() do editor:Undo() end
ClosePage()

2
t/test.bat Normal file
View File

@@ -0,0 +1,2 @@
@echo off
zbstudio -cfg t/test.lua

42
t/test.lua Normal file
View File

@@ -0,0 +1,42 @@
local G = ... -- this now points to the global environment in the script
local env = {}
G.setmetatable(env, {__index = G})
local ide = G.ide
local postinit = ide.app.postinit
ide.app.postinit = function()
if postinit then postinit() end
-- load test module in the environment for tests
local function testwell(report)
local tw = require "testwell"
if report then tw.report() end
end
setfenv(testwell, env)
testwell()
-- find all test files and load them
local files = FileSysGetRecursive("t", true, "*.lua")
for k, v in ipairs(files) do
if v:find("[/\\]test%.lua$") then files[k] = nil end
end
table.sort(files)
for _,file in ipairs(files) do
local testfn, err = loadfile(file)
if not testfn then
print(("Error loading test file '%s': '%s'."):format(file, err))
else
setfenv(testfn, env)
local ok, err = pcall(testfn)
if not ok then
print(("Error executing test file '%s': '%s'."):format(file, err))
end
end
end
testwell(true)
end
G.setfenv(ide.app.postinit, env)

1
t/test.sh Executable file
View File

@@ -0,0 +1 @@
./zbstudio.sh -cfg t/test.lua

352
tools/glslc.lua Normal file
View File

@@ -0,0 +1,352 @@
-- authors: Luxinia Dev (Eike Decker & Christoph Kubisch)
---------------------------------------------------------
local binpath = os.getenv("GLSLC_BIN_PATH")
return binpath and {
fninit = function(frame,menuBar)
binpath = ide.config.path.glslcbin or os.getenv("GLSLC_BIN_PATH")
local myMenu = wx.wxMenu{
{ ID "glslc.compile.input", "&Custom Args\tCtrl-L", "when set a popup for custom compiler args will be envoked", wx.wxITEM_CHECK },
{ },
{ ID "glslc.compile.vertex", "Compile &Vertex\tCtrl-1", "Compile Vertex program" },
{ ID "glslc.compile.fragment", "Compile &Fragment\tCtrl-2", "Compile Fragment program" },
{ ID "glslc.compile.geometry", "Compile &Geometry\tCtrl-3", "Compile Geometry program" },
{ ID "glslc.compile.tessctrl", "Compile T.Ctrl\tCtrl-4", "Compile T.Ctrl program" },
{ ID "glslc.compile.tesseval", "Compile T.Eval\tCtrl-5", "Compile T.Eval program" },
{ ID "glslc.compile.compute", "Compile Compute\tCtrl-6", "Compile Compute program" },
{ },
{ ID "glslc.format.asm", "Annotate ASM", "indent and add comments to ASM output" },
}
menuBar:Append(myMenu, "&GLSL")
local data = {}
data.customarg = false
data.custom = ""
data.domains = {
[ID "glslc.compile.vertex"] = 1,
[ID "glslc.compile.fragment"] = 2,
[ID "glslc.compile.geometry"] = 3,
[ID "glslc.compile.tessctrl"] = 4,
[ID "glslc.compile.tesseval"] = 5,
[ID "glslc.compile.compute"] = 6,
}
data.domainprofiles = {
"vertex",
"fragment",
"geometry",
"tesscontrol",
"tessevaluation",
"compute",
}
data.domaindefs = {
" -D_VERTEX_ ",
" -D_FRAGMENT_ ",
" -D_GEOMETRY_ ",
" -D_TESS_CONTROL_ ",
" -D_TESS_EVAL_ ",
" -D_COMPUTE_ ",
}
local function beautifyAsm(tx)
local newtx = ""
local indent = 0
local maxindent = 0
local startindent = {
["IF"]=true,["REP"]=true,["ELSE"]=true,["LOOP"]=true,["BB"]=true,
}
local endindent = {
["ENDIF"]=true,["ENDREP"]=true,["ELSE"]=true,["ENDLOOP"]=true,["END"]=true,["RET"]=true,
}
local function checknesting(str,tab)
local res
local chk = str:match("%s*(BB)%d+.*:")
chk = chk or str:match("%s*(%w+)")
res = chk and tab[chk] and chk
return res
end
local argregistry = {}
local argbuffersfixed = false
local registercc = 0
local registermem = 0
local registers = 0
local instructions = 0
local function fixargbuffers()
if (argbuffersfixed) then return end
local argnew = {}
for i,v in pairs(argregistry) do
local buf,bufstart = string.match(i,"buf(%d+)%[(%d+)%]")
if (buf and bufstart) then
bufstart = tonumber(bufstart)/16
argnew["buf"..buf.."["..tostring(bufstart).."]"] = v
else
argnew[i] = v
end
end
argregistry = argnew
argbuffersfixed = true
end
local function checkregistry(w)
local regsuccess = true
local vtype,vname,sem,resource,pnum,pref = string.match(w,"#var ([_%w]+) ([%[%]%._%w]+) : ([^%:]*) : ([^%:]*) : ([^%:]*) : (%d*)")
local funcname,subroutine = string.match(w,"#function %d+ ([_%w]+)%((%d+)%)")
if (pref == "1") then
local descriptor = vtype.." "..vname
-- check if resource is array
local resstart,rescnt = string.match(resource,"c%[(%d+)%], (%d+)")
resstart = tonumber(resstart)
rescnt = tonumber(rescnt)
-- check if resource is buffer/buffer array
local buf,bufstart,bufcnt = string.match(resource,"buffer%[(%d+)%]%[(%d+)%],? ?(%d*)")
buf = tonumber(buf)
bufstart = tonumber(bufstart)
bufcnt = tonumber(bufcnt)
-- check if texture
local texnum = string.match(resource,"texunit (%d+)")
local argnames = {}
if (rescnt) then
for i=0,(rescnt-1) do
table.insert(argnames,"c["..tostring(resstart + i).."]")
end
elseif (texnum) then
table.insert(argnames,"texture["..tostring(texnum).."]")
table.insert(argnames,"texture"..tostring(texnum))
elseif (buf) then
table.insert(argnames,"buf"..tostring(buf).."["..tostring(bufstart).."]")
else
table.insert(argnames,resource)
end
for i,v in ipairs(argnames) do
argregistry[v] = descriptor
end
elseif (funcname and subroutine) then
argregistry["SUBROUTINENUM("..subroutine..")"] = "function "..funcname
elseif string.find(w,"BUFFER4 ") then
fixargbuffers()
elseif string.find(w,"TEMP ") then
--TEMP R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11;
--TEMP RC, HC;
--TEMP lmem[9];
for i in string.gmatch(w,"C") do
registercc = registercc + 1
end
for i in string.gmatch(w,"R%d+") do
registers = registers + 1
end
registermem = tonumber(string.match(w,"lmem%[(%d+)%]"))
elseif (string.find(w,"CBUFFER ") or string.find(w,"ATTRIB ") or string.find(w,"OPTION ") or
string.find(w,"OUTPUT ") or string.find(w,"PARAM ") or string.find(w,"!!NV")) then
else
regsuccess = false
end
return regsuccess
end
local function checkargs(str)
local comment = "#"
local declared = {}
for i in string.gmatch(str,"([%[%]%(%)%w]+)") do
local descr = argregistry[i]
if (descr and not declared[i]) then
comment = comment.." "..i.." = "..descr
declared[i] = true
end
end
return comment ~= "#" and comment
end
local registerlevels = {{}}
local function checkregisters(str,indent)
if (indent < 0) then return end
local cur = registerlevels[indent+1]
for i in string.gmatch(str,"R(%d+)") do
cur[i] = true
end
end
local function clearregisters(indent)
registerlevels[math.max(0,indent)+1] = {}
end
local function outputregisters(indent)
if (indent < 0) then return "" end
local tab = registerlevels[indent+1]
local out = {}
for i,v in pairs(tab) do
table.insert(out,i)
end
table.sort(out)
local cnt = #out
if (cnt < 1) then return "" end
local str = string.rep(" ",indent).."# "..tostring(cnt).." R used: "
for i,v in ipairs(out) do
str = str..tostring(v)..((i==cnt) and "" or ", ")
end
return str.."\n"
end
-- check declarations
local lastline = ""
local addinstr = false
for w in string.gmatch(tx, "[^\n]*\n") do
if (not checkregistry(w)) then
if (not w:match("%s*#")) then
instructions = instructions + 1
end
if (checknesting(w,endindent)) then
newtx = newtx..outputregisters(indent)
if (indent == 0) then clearregisters(indent) end
indent = math.max(0,indent - 1)
end
local firstchar = string.sub(w,1,1)
local indentstr = (firstchar ~= " " and firstchar ~= "\t" and string.rep(" ",indent) or "")
local linestr = indentstr..w
local argcomment = (firstchar ~= "#") and checkargs(w)
checkregisters(w,indent)
newtx = newtx..(argcomment and (indentstr..argcomment.."\n") or "")
newtx = newtx..linestr
if (checknesting(w,startindent)) then
indent = indent + 1
maxindent = math.max(maxindent,indent)
clearregisters(indent)
end
else
newtx = newtx..w
end
lastline = w
end
local registers = tonumber(string.match(lastline, "(%d+) R%-regs")) or registers
registermem = registermem or 0
registercc = registercc or 0
local stats = "# "..instructions.." instructions\n"
stats = stats.."# "..registers.." R-regs\n"
stats = stats.."# "..tostring(registercc).." C-regs, "..tostring(registermem).." L-regs\n"
stats = stats.."# "..tostring(registercc + registermem + registers).." maximum registers\n"
stats = stats.."# "..maxindent.." maximum nesting level\n"
newtx = newtx..stats
return newtx,stats
end
local function beautifyAsmFile(filePath)
local file_text = ""
local statlines = ""
local handle = io.open(filePath, "rb")
if handle then
file_text = handle:read("*a")
file_text,statlines = beautifyAsm(file_text)
handle:close()
end
if (file_text == "") then return end
local handle = io.open(filePath, "wb")
if handle then
handle:write(file_text)
handle:close()
end
return statlines
end
-- Compile Arg
frame:Connect(ID "glslc.compile.input",wx.wxEVT_COMMAND_MENU_SELECTED,
function(event)
data.customarg = event:IsChecked()
end)
-- Compile
local function evCompile(event)
local filename,info = GetEditorFileAndCurInfo()
local editor = GetEditor()
local glsl = true
if (not (filename and binpath)) then
DisplayOutput("Error: GLSL Compile: Insufficient parameters (nofile)\n")
return
end
local domain = data.domains[event:GetId()]
local profile = data.domainprofiles[domain]
-- popup for custom input
data.custom = data.customarg and wx.wxGetTextFromUser("Compiler Args","GLSLC",data.custom) or data.custom
local args = data.customarg and data.custom or ""
args = args:len() > 0 and args or nil
local fullname = filename:GetFullPath()
local outname = fullname..".main^"
outname = args and outname..args:gsub("%s*[%-%/]",";-")..";^" or outname
outname = outname..profile..".glp"
outname = '"'..outname..'"'
local cmdline = "-profile "..profile.." "
cmdline = args and cmdline..args.." " or cmdline
cmdline = cmdline..data.domaindefs[domain].." "
cmdline = cmdline.."-o "..outname.." "
cmdline = cmdline..'"'..fullname..'"'
cmdline = binpath.."/glslc.exe "..cmdline
local function compilecallback(str)
local postfunc
-- check for errors, if none, launch nvperf
-- and indentation
if (string.find(str,"successfully compiled")) then
postfunc = function()
-- beautify asm
if (true) then
local statlines = beautifyAsmFile(outname:sub(2,-2))
DisplayOutput(statlines)
end
end
end
return str,postfunc
end
-- run compiler process
CommandLineRun(cmdline,nil,true,nil,compilecallback)
end
frame:Connect(ID "glslc.compile.vertex",wx.wxEVT_COMMAND_MENU_SELECTED,evCompile)
frame:Connect(ID "glslc.compile.fragment",wx.wxEVT_COMMAND_MENU_SELECTED,evCompile)
frame:Connect(ID "glslc.compile.geometry",wx.wxEVT_COMMAND_MENU_SELECTED,evCompile)
frame:Connect(ID "glslc.compile.tessctrl",wx.wxEVT_COMMAND_MENU_SELECTED,evCompile)
frame:Connect(ID "glslc.compile.tesseval",wx.wxEVT_COMMAND_MENU_SELECTED,evCompile)
frame:Connect(ID "glslc.compile.compute",wx.wxEVT_COMMAND_MENU_SELECTED,evCompile)
-- indent asm
frame:Connect(ID "glslc.format.asm", wx.wxEVT_COMMAND_MENU_SELECTED,
function(event)
local curedit = GetEditor()
local newtx = beautifyAsm( curedit:GetText() )
curedit:SetText(newtx)
end)
end,
}

BIN
zbstudio.exe Executable file → Normal file

Binary file not shown.

View File

@@ -3,7 +3,6 @@
if [[ $(uname) == 'Darwin' ]]; then
open zbstudio/ZeroBraneStudio.app --args "$@"
else
type lua 2>/dev/null >&2 && lua -e "os.exit(pcall(require, 'wx') and 0 or 1)"
if [[ "$?" != "0" ]]; then (cd build; bash install-deb.sh); fi
lua src/main.lua zbstudio "$@"
if [[ "$(uname -m)" == "x86_64" ]]; then ARCH="x64"; else ARCH="x86"; fi
bin/linux/$ARCH/lua src/main.lua zbstudio "$@" &
fi

View File

@@ -71,48 +71,21 @@ src/editor/menu_search.lua
src/editor/menu_tools.lua
src/editor/menu_view.lua
src/editor/output.lua
src/editor/preferences.lua
src/editor/settings.lua
src/editor/shellbox.lua
src/editor/singleinstance.lua
src/editor/style.lua
src/main.lua
src/misc/util.lua
src/preferences/editor.lua
src/preferences/project.lua
src/util.lua
src/version.lua
tools/*.lua
zbstudio/app.lua
zbstudio/config.lua
zbstudio/res/16.ico
zbstudio/res/16/LICENSE
zbstudio/res/16/wxART_COPY.png
zbstudio/res/16/wxART_CUT.png
zbstudio/res/16/wxART_DEBUG_BREAK.png
zbstudio/res/16/wxART_DEBUG_BREAKPOINT_TOGGLE.png
zbstudio/res/16/wxART_DEBUG_CALLSTACK.png
zbstudio/res/16/wxART_DEBUG_START.png
zbstudio/res/16/wxART_DEBUG_STEP_INTO.png
zbstudio/res/16/wxART_DEBUG_STEP_OUT.png
zbstudio/res/16/wxART_DEBUG_STEP_OVER.png
zbstudio/res/16/wxART_DEBUG_STOP.png
zbstudio/res/16/wxART_DEBUG_WATCH.png
zbstudio/res/16/wxART_FILE_OPEN.png
zbstudio/res/16/wxART_FILE_SAVE.png
zbstudio/res/16/wxART_FIND.png
zbstudio/res/16/wxART_FIND_AND_REPLACE.png
zbstudio/res/16/wxART_FOLDER.png
zbstudio/res/16/wxART_GO_DIR_UP.png
zbstudio/res/16/wxART_GO_FORWARD-wxART_OTHER_C.png
zbstudio/res/16/wxART_HELP_PAGE.png
zbstudio/res/16/wxART_LIST_VIEW-wxART_OTHER_C.png
zbstudio/res/16/wxART_NEW_DIR.png
zbstudio/res/16/wxART_NORMAL_FILE-wxART_OTHER_C.png
zbstudio/res/16/wxART_NORMAL_FILE.png
zbstudio/res/16/wxART_PASTE.png
zbstudio/res/16/wxART_REDO.png
zbstudio/res/16/wxART_REPORT_VIEW-wxART_OTHER_C.png
zbstudio/res/16/wxART_UNDO.png
zbstudio/res/16/*.png
zbstudio/res/24/LICENSE
zbstudio/res/24/*.png
zbstudio/res/32.ico
zbstudio/res/estrela.png
zbstudio/res/zerobrane.png

View File

@@ -0,0 +1,3 @@
bin/linux/*
zbstudio/res/*
zbstudio.sh

Some files were not shown because too many files have changed in this diff Show More