Compare commits
218 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a7797f9d9a | ||
|
|
78e1f176a5 | ||
|
|
a592893b4d | ||
|
|
1a1f25c135 | ||
|
|
00692634a8 | ||
|
|
1037389ce0 | ||
|
|
cc645ebb69 | ||
|
|
544ada09e2 | ||
|
|
85d14ca6fd | ||
|
|
1d33dd6482 | ||
|
|
faa0e0e16d | ||
|
|
bb60b9421c | ||
|
|
ab44438859 | ||
|
|
a463b5fd28 | ||
|
|
d021bfa986 | ||
|
|
beeee9e32f | ||
|
|
dd682791e1 | ||
|
|
dddcd96755 | ||
|
|
cb56311090 | ||
|
|
952f8325c0 | ||
|
|
0526fd4069 | ||
|
|
c0e369b175 | ||
|
|
8e1d823eea | ||
|
|
b73ef167bc | ||
|
|
7c889880d8 | ||
|
|
0387e32072 | ||
|
|
e0c18c189a | ||
|
|
489aaa3e8e | ||
|
|
fd92861998 | ||
|
|
bba9790a2a | ||
|
|
d68985c4a9 | ||
|
|
4463cbd327 | ||
|
|
0d619b1326 | ||
|
|
8c2a4792f6 | ||
|
|
0f71d4b9a0 | ||
|
|
30863a3dcc | ||
|
|
f74f56b917 | ||
|
|
a236d299de | ||
|
|
be54763f7e | ||
|
|
663b7cab8b | ||
|
|
c68d45d697 | ||
|
|
8b7407c3f2 | ||
|
|
1b29f2e05f | ||
|
|
8d4ce56619 | ||
|
|
67da97f32f | ||
|
|
46aa3575cf | ||
|
|
acc635b9b5 | ||
|
|
99e64f51cd | ||
|
|
9002286bcf | ||
|
|
72b5690689 | ||
|
|
e488ed095c | ||
|
|
9c54fb6507 | ||
|
|
065422fa2d | ||
|
|
0c2d6b6d48 | ||
|
|
89cc631a58 | ||
|
|
83e725ef97 | ||
|
|
76ec0de7ab | ||
|
|
38a176d84f | ||
|
|
3bb22f4c48 | ||
|
|
7b60461787 | ||
|
|
843024ec1d | ||
|
|
b4e1dda0d9 | ||
|
|
394c93e9e6 | ||
|
|
ded66391ac | ||
|
|
d81de133a9 | ||
|
|
0f6316619f | ||
|
|
ab8a38fd79 | ||
|
|
c91d287025 | ||
|
|
9fa8c7a972 | ||
|
|
ce90e7898f | ||
|
|
4cafb3c201 | ||
|
|
60bc64283d | ||
|
|
83dc1c5065 | ||
|
|
124f70d342 | ||
|
|
1400bf6b3d | ||
|
|
8f26e2df17 | ||
|
|
49b9b66394 | ||
|
|
ee9fe71657 | ||
|
|
ba0efe224a | ||
|
|
96516c9454 | ||
|
|
e6b8533cf9 | ||
|
|
185ebb5bbf | ||
|
|
f8b447425e | ||
|
|
7330ac21ad | ||
|
|
e6bd7af1d7 | ||
|
|
979b318647 | ||
|
|
16a5934c52 | ||
|
|
2d22060e2c | ||
|
|
82071e6ce1 | ||
|
|
6a23d09821 | ||
|
|
c4b9d3e31c | ||
|
|
9b50cb3525 | ||
|
|
49e56f8f3c | ||
|
|
a84f362c1f | ||
|
|
cfe5b37041 | ||
|
|
e9351c7fde | ||
|
|
305f48ef6f | ||
|
|
5ccafe93a8 | ||
|
|
0f14a54843 | ||
|
|
ac4a2598a3 | ||
|
|
66fdef6088 | ||
|
|
4685fed4bb | ||
|
|
c4a3036794 | ||
|
|
fa5c31a7ec | ||
|
|
985b2c288b | ||
|
|
722378debb | ||
|
|
4c37b51ae1 | ||
|
|
3e5f0ebf4d | ||
|
|
fa522ae36b | ||
|
|
6b85e36fd6 | ||
|
|
fc420943b2 | ||
|
|
989603655a | ||
|
|
543c0d7fad | ||
|
|
cfd0d98270 | ||
|
|
e802e38dc2 | ||
|
|
ac566de0ba | ||
|
|
8419287316 | ||
|
|
27d1d159f6 | ||
|
|
491d37038a | ||
|
|
67eee4f9ef | ||
|
|
552a7373ca | ||
|
|
376a25dfdd | ||
|
|
7945a09811 | ||
|
|
327f650121 | ||
|
|
9bceb449e8 | ||
|
|
4278c25c60 | ||
|
|
7f47506eae | ||
|
|
b0b137eaf1 | ||
|
|
d1d29ced43 | ||
|
|
2795d4d9ce | ||
|
|
02845f2e87 | ||
|
|
ec46531c55 | ||
|
|
9895f06f97 | ||
|
|
a67feb86aa | ||
|
|
6b990b652c | ||
|
|
7a2326cc9e | ||
|
|
e129f486d9 | ||
|
|
c09d9fc143 | ||
|
|
52ef014941 | ||
|
|
e79fedf764 | ||
|
|
b7544577df | ||
|
|
53110b3b2f | ||
|
|
d6ee3d1278 | ||
|
|
c0109a26d1 | ||
|
|
2a706f5bf3 | ||
|
|
1f266e04ab | ||
|
|
f45d6f84a3 | ||
|
|
76b8b7b07b | ||
|
|
d45f893943 | ||
|
|
53e725cf03 | ||
|
|
8a66df19fa | ||
|
|
13be57ae39 | ||
|
|
684150714f | ||
|
|
01e23f448e | ||
|
|
036ec3534a | ||
|
|
af57806c69 | ||
|
|
a4773563e9 | ||
|
|
195c463a60 | ||
|
|
8cbf20ae42 | ||
|
|
a11bd6f0d3 | ||
|
|
1fc12a8a76 | ||
|
|
9a1e681569 | ||
|
|
43083742e6 | ||
|
|
9a5b481189 | ||
|
|
565f8e74fb | ||
|
|
b1b87e9013 | ||
|
|
539eddbf9d | ||
|
|
0abcff015e | ||
|
|
7bb74b5fb4 | ||
|
|
b9bc6454b4 | ||
|
|
5734455818 | ||
|
|
e6e0870a11 | ||
|
|
2c45207436 | ||
|
|
bf09d3748c | ||
|
|
452f99826e | ||
|
|
bbfc1c3624 | ||
|
|
429bb24cb4 | ||
|
|
2a8e7fe423 | ||
|
|
cf1a657b80 | ||
|
|
cf6b328a52 | ||
|
|
b0f98f30dc | ||
|
|
5c0bf93d9c | ||
|
|
7b2241085d | ||
|
|
c9cfd42d34 | ||
|
|
c25c56069d | ||
|
|
a68e8f7bd3 | ||
|
|
fc6de036e0 | ||
|
|
08d42a2501 | ||
|
|
da32878984 | ||
|
|
3fd5d88656 | ||
|
|
7d9ad5100c | ||
|
|
6bff634446 | ||
|
|
b0de487bf0 | ||
|
|
560d56835a | ||
|
|
3c6a06f537 | ||
|
|
b1f3bf0bd9 | ||
|
|
6ea3a4708d | ||
|
|
4de0eb1dc0 | ||
|
|
c2f6ed6338 | ||
|
|
fad7ff0cc3 | ||
|
|
9afa35f9b2 | ||
|
|
3a5b46f65e | ||
|
|
26d0908c89 | ||
|
|
770db579d9 | ||
|
|
8e09ed1658 | ||
|
|
25ac96d39a | ||
|
|
22fda661ec | ||
|
|
529a0e8c9e | ||
|
|
7cc061e18d | ||
|
|
5f2226bac2 | ||
|
|
37795c2480 | ||
|
|
5e934dfd69 | ||
|
|
f970ba38a0 | ||
|
|
8af6c1b5b6 | ||
|
|
0777a5fbd8 | ||
|
|
942681e246 | ||
|
|
46da5b6697 | ||
|
|
80f83d781e |
329
CHANGELOG.md
Normal file
329
CHANGELOG.md
Normal file
@@ -0,0 +1,329 @@
|
||||
# ZeroBrane Studio Changelog
|
||||
|
||||
## v0.33 (Oct 22 2012)
|
||||
|
||||
### Highlights
|
||||
- Added **Linux support**.
|
||||
- Added **Moai auto-complete**.
|
||||
- Added **Gideros debugging, auto-complete, and live coding**.
|
||||
- Added **syntax aware indentation**.
|
||||
- Added **re/storing open files and interpreter** when switching project folders.
|
||||
|
||||
### Improvements
|
||||
- Added configuration option to specify hostname when the default one is not reachable (fixes #68).
|
||||
- Added search for Moai and Love2d executables in default locations on OSX and Windows.
|
||||
- Added handling of command line parameters on OSX and Linux; updated documentation.
|
||||
- Added auto-recovery to save/restore editor content (fixes #23).
|
||||
- Added syntax aware indentation.
|
||||
- Added re/storing open files and interpreter when switching project folders.
|
||||
- Added auto-activation of files requested during debugging.
|
||||
- Added editor.autoactivate parameter (false by default) to enable activation.
|
||||
- Added zbstudio.sh script to run on OSX/Linux; updated permissions (closes #15).
|
||||
- Added variable ratio for sliders in scratchpad.
|
||||
- Added Linux/OSX/Windows CMake-based launcher build (thanks to toiffel).
|
||||
- Added configuration parameter for the number of characters typed before displaying auto-complete suggestions for dynamic words.
|
||||
- Added proper closing of the application after Shutdown/Logoff events (fixes #57).
|
||||
- Added Moai auto-complete (closes #52).
|
||||
- Added hiding auto-complete suggestions on losing focus in the editor.
|
||||
- Added proper reporting of errors in the stack window.
|
||||
- Added wxlua.deb file and install script that pull and build all required dependencies on Linux (covers most of #15).
|
||||
- Added osx executables and build files.
|
||||
- Added disabling full screen mode when the last editor tab is closed.
|
||||
- Added proper reporting of errors in config files.
|
||||
- Added toggling folders in project pane by single click (fixes #41).
|
||||
- Added examples for configuring tabs and moai entry points.
|
||||
- Added reporting compilation success rate (fixes #39)
|
||||
- Added shortcuts for adding and removing watches.
|
||||
- Added highlighting rows with updated values in the Watch window.
|
||||
- Added 'Add Watch Expression' and 'Evaluate in Console' context menu items in the editor.
|
||||
- Added handling of canceling editing in adding a watch.
|
||||
- Added Gideros auto-complete and live coding support (closes #62).
|
||||
- Added Gideros integration on OSX; added search for gideros in default locations on Windows and OSX.
|
||||
- Added Gideros integration and debugging support.
|
||||
- Added debugging-related buttons to the toolbar.
|
||||
- Improved reporting of compilation and run-time errors when running as scratchpad.
|
||||
- Made debugger strict.lua and LuaJIT friendly (upgraded to MobDebug v0.502).
|
||||
- Updated configuration example to avoid using ide.spec that is not available (fixes #67).
|
||||
- Updated CMake build script to handle wildcards in the MANIFEST.
|
||||
- Updated configuring toolbar size to improve Linux compatibility.
|
||||
- Updated MobDebug to v0.497 to fix issues and improve performance.
|
||||
- Updated a warning message about single instance communication.
|
||||
- Updated cpath processing to allow Linux version to run side-by-side with Windows and Mac.
|
||||
- Updated licensing information.
|
||||
- Enabled scratchpad support in the debugger when interpreter is capable of providing it.
|
||||
- Disabled auto-complete in comments and strings.
|
||||
- Disabled toggling breakpoints while debugger is running (as they wouldn't be changed anyway).
|
||||
- Disabled 'not activated file for debugging' message when auto-activation is disabled.
|
||||
- Disabled tooltip when scratchpad is on (fixes #51).
|
||||
- Disabled showing calltip when the editor is not in focus.
|
||||
- Disabled showing calltip over markup in comments.
|
||||
- Disabled 'Run as Scratchpad' in the menu for those intepreters that don't support scratchpad.
|
||||
- Updated configuration examples to add editor settings and fix user.lua path.
|
||||
- Moved all Estrela features into a separate bundle that can be loaded using cfg/estrela.lua config.
|
||||
- Removed multiple file types offered in Save As dialog.
|
||||
|
||||
### Incompatibilities
|
||||
- Changed searching for user config in '$HOME/.zbstudio' from '$HOME/.zbs'.
|
||||
- Temporarily removed the ability to modify spec-related configuration parameters from configuration files.
|
||||
|
||||
### Fixes
|
||||
- Fixed opening a non-existing file from the Recent Files list.
|
||||
- Fixed Find/Replace dialog checkboxes that didn't react to clicks on OSX (fixes #63).
|
||||
- Fixed an auto-complete issue with mixed case dynamic words (fixes #60).
|
||||
- Fixed 'Trying to solve a NULL hostname' warning message.
|
||||
- Fixed a typo that prevented a corner case in autocomplete from working.
|
||||
- Fixed inconsistent error messages about various config files.
|
||||
- Fixed an issue with auto-complete when dot or colon is used (fixes #56).
|
||||
- Fixed an issue with debugging scripts started using absolute file path.
|
||||
- Fixed setting working directory for interpreters to the file path when the project directory is not set.
|
||||
- Fixed an issue with Backspace not closing auto-complete suggestions.
|
||||
- Fixed enabling items in the Edit menu (fixes #56).
|
||||
- Fixed function list in the toolbar on Mac (helps #14).
|
||||
- Fixed deleting of comment blocks with hidden markup (fixes #40).
|
||||
- Fixed an issue with function list when all editor tabs are closed.
|
||||
- Fixed multiple calltips shown on Linux (helps #15).
|
||||
- Fixed an issue with mouse cursor in scratchpad not properly updated on Linux (fixes #49; helps #15).
|
||||
- Fixed an issue with static analyzer that failes on function names like a.b.c (fixes #50).
|
||||
- Fixed disabling Paste menu on Linux when needed (fixes #46; helps #15).
|
||||
- Fixed an issue with context menu on Linux (fixes #47; helps #15).
|
||||
- Fixed debugger failure when debugging is initiated externally and there is an unsaved file in one of editor tabs.
|
||||
- Fixed stopping the debugger when an editor tab where debugging happens is closed.
|
||||
- Fixed enabling of several menu items with no editor tab (fixes #42).
|
||||
- Fixed an issue with loading stock icons on Linux.
|
||||
- Fixed Cut/Copy menu items to reflect proper status in the editor.
|
||||
- Fixed typo in the static analyzer output.
|
||||
- Resolved conflict between lua executable names on Windows and Mac.
|
||||
|
||||
## v0.32 (Sep 03 2012)
|
||||
|
||||
### Highlights
|
||||
- Added **Unicode support** for file encoding and file paths on Windows (fixes #30).
|
||||
- Added **Moai integration and debugging** (including debugging of Moai threads and callbacks).
|
||||
- Added refresh of Stack and Watch windows after executing a statement in remote shell.
|
||||
- Added **display of complex values** on multiple lines in shell with '='.
|
||||
- Added calltip on mouseover for functions during editing and for variables/expressions during debugging.
|
||||
- Added configuration options to set paths to lua and love2d executables.
|
||||
- Added support for **coroutine debugging** with stepping through coroutine.resume/.yield calls.
|
||||
- Updated wx.dll to wxlua 2.8.12.2 and wxwidgets 2.8.12.
|
||||
- Signed zbstudio app and executable to avoid issues with files not being saved without admin privileges and to remove warning about 'unknown publisher' on windows (fixes #25).
|
||||
|
||||
### Improvements
|
||||
- Added calltip on mouseover for functions during editing and for variables/expressions during debugging.
|
||||
- Added an IO filter to fix an issue with 0d0d0a line endings on Windows.
|
||||
- Added support for debugging moai callbacks (upgraded to mobdebug v0.489).
|
||||
- Added refresh of Stack and Watch windows to show updated values after executing a statement in remote shell.
|
||||
- Added display of complex values on multiple lines in shell with '='.
|
||||
- Added rockspec to the list of extensions for lua (fixes #37).
|
||||
- Added a check to avoid evaluating keywords in tooltip.
|
||||
- Added current interpreter to the status bar; adding closing debugger when the interpreter is changed.
|
||||
- Added aborting scratchpad processing when an interpreter can't start or report a fatal error.
|
||||
- Added support for unicode path files on Windows (fixes #30).
|
||||
- Added an option to set path to lua executable.
|
||||
- Added error handler to trap and display debugger errors.
|
||||
- Added search in PATH for love2d executable.
|
||||
- Added a workaround for GetExecutablePath() reporting 'wx.dll' instead of a proper exe name with wxlua 2.8.12.2 on Windows.
|
||||
- Added reporting of function name of the form a.b and a:b in static analysis (fixes #27).
|
||||
- Added ability for user to keep their settings file in their home directory.
|
||||
- Added per user settings file. Users can now move their settings file to ~/.zbs/user.lua.
|
||||
- Added ignoring Cmd-key combinations on Mac as this should be handled by wxwidgets, but is not (fixes #19).
|
||||
- Added support for coroutine debugging with stepping through coroutine.resume/.yield calls.
|
||||
- Changed reporting of program execution time from CPU time to user time.
|
||||
- Changed the call to unhide windows to the async version (ShowWindowAsync) to avoid blocking the IDE when the application doesn't respond.
|
||||
- Upgraded to wxlua 2.8.12.2 (wxwidgets 2.8.12; unicode version); added lua51.dll proxy (fixes #10 and #7).
|
||||
- Updated love2d interpreter to use the project folder to check for main.lua.
|
||||
- Updated test module to use stringified values for comparison.
|
||||
- Updated status bar style to make it consistent across platforms.
|
||||
- Removed .bak files from being replaced in when backup copies are saved.
|
||||
- Removed explicit path conversions and comparisons.
|
||||
- Refactored LUA_PATH/CPATH processing to set it for all interpreters.
|
||||
- Signed zbstudio app and executable to avoid issues with files not being saved without admin privileges and to remove warning about 'unknown publisher' on windows (fixes #25).
|
||||
|
||||
### Incompatibilities
|
||||
- Reassigned hotkeys in the Project menu to minimize conflicts on Mac (reassigned Shift-F12 and F11).
|
||||
|
||||
### Fixes
|
||||
- Fixed an issue with double click on analylsis results being out-of-sync when the editor switched to another file (fixes #38)
|
||||
- Fixed an issue with debugger not activating files with relative path information.
|
||||
- Fixed 'break' command to work after coming from debugger calls (like on()).
|
||||
- Fixed an issue with highlighting selected item in the project tree.
|
||||
- Fixed evaluation of foo:bar in tooltip (now evaluates as foo.bar).
|
||||
- Fixed debugger termination after internal errors.
|
||||
- Fixed activating current file in the project tree on Mac (closes #29).
|
||||
- Fixed running scripts with single quotes in path names.
|
||||
- Fixed an issue with Run/Debug commands when IDE path includes exclamation mark ('!').
|
||||
- Fixed an issue with the app not starting on those systems that don't have HOME environment variable; fixes #28.
|
||||
- Fixed an issue with showing/hiding GUI windows that was occasionally causing a runtime error when the window disappears before it is manipulated.
|
||||
- Fixed returning proper name for unsaved files in reporting compilation and static analysis results; moved default names to ide.config (fixes #26).
|
||||
- Fixed pasting text into the Find dialog and project path box on Mac (fixes #22).
|
||||
- Fixed handling of dashes in paths (upgraded to mobdebug 0.479).
|
||||
- Reorganized handling of automcomplete event (to use AddPendingEvent instead of PostEvent) to avoid runtime application error.
|
||||
|
||||
## v0.31 (Jul 14 2012)
|
||||
|
||||
### Highlights
|
||||
- Added **scratchpad support for love2d**.
|
||||
- Added tooltip to display variable/expression values during debugging.
|
||||
- Added **MacOS support**.
|
||||
|
||||
### Improvements
|
||||
- Added handling of balanced brackets in markup links.
|
||||
- Added unit test module.
|
||||
- Added reporting the number of traced lines during debugging.
|
||||
- Added setting of PATH and CPATH to find proper libs on windows and mac os platforms.
|
||||
- Added scratchpad support for love2d.
|
||||
- Added reset of 'modified' status to keep tab names and their config settings correct upon exit.
|
||||
- Added window title update and filetree refresh after SaveAs command.
|
||||
- Added tooltip to display variable/expression values during debugging.
|
||||
- Made 'View Stack Window' and 'View Watch Window' refresh window content if it's already shown.
|
||||
- Removed setting the editor font in the config as the default font is different on different platforms.
|
||||
- Removed extension from the template to match folders to make it more portable.
|
||||
- Reorganized handling of font configuration and added font config for filetree (with a different size default on MacOS).
|
||||
- Updated matching logic for function definitions to allow for a.b.c() definitions (fixes #17).
|
||||
|
||||
### Fixes
|
||||
- Fixed markup styling and file tree drawing on MacOS.
|
||||
- Fixed detecting executable name in commands with spaces.
|
||||
- Fixed incorrect folders reported in the file tree when no project directory is set and a file is open.
|
||||
- Fixed incorrect filename reported in compile errors when the file is not saved.
|
||||
- Fixed refresh of filetree on MacOS to get it displayed correctly when the app is started.
|
||||
- Fixed an error thrown when a window with debugging is closed before the application being debugged is terminated.
|
||||
- Fixed incorrect storing of settings for editor tabs with the same text (filename). This was causing only one tab displayed for multiple StyledText controls with interesting effects.
|
||||
- Fixed an issue with launching a process when its output is not redirected to the IDE (fixes #16).
|
||||
- Fixed console to evaluate 'function a() ... end' without errors.
|
||||
- Fixed a compilation error caused by shebang in scripts.
|
||||
- Fixed an issue with love2d path with spaces.
|
||||
- Corrected resetting of project directory when it's already set and doesn't need to be changed.
|
||||
- Added checks around ShowFullScreen() calls to avoid failures on those systems that don't provide it (linux/GTK).
|
||||
- Added check for debugger calls to avoid errors when debugger is not loaded.
|
||||
- Updated matching of links to make them less greedy (to avoid capturing link terminators).
|
||||
- Upgraded deprecated constants and logic for compatibility with wxwidgets 2.9.x.
|
||||
- Reset project directory if the current one doesn't exist.
|
||||
- Removed styling of function calls and capturing definitions in strings and comments (fixed #18).
|
||||
- Removed setting focus to the Output window when output is processed as it interfered with Run as Scratchpad.
|
||||
|
||||
## v0.30 (Jun 27 2012)
|
||||
|
||||
### Highlights
|
||||
- Added **love2d support**.
|
||||
- Added auto complete for love2d API.
|
||||
- Added support for debugging processes running under LuaJIT.
|
||||
- Added display of **hierarchical data in Stack window**.
|
||||
- Added **pretty printing in Watch and Console** (local and remote) windows and handling of multiple results in Console.
|
||||
- Added **Stack window to display stack information** and local/upvalue values for each stack frame.
|
||||
- Added ability to **interact with scripts** by allowing text to be entered in the 'Output' window.
|
||||
|
||||
### Improvements
|
||||
- Added love2d support.
|
||||
- Added auto complete for love2d API.
|
||||
- Added support for debugging processes running under LuaJIT.
|
||||
- Added display of hierarchical data in Stack window.
|
||||
- Added execution time and updated messages in the Output window to be more consistent.
|
||||
- Added displaying 'nil' values in local console when no result is returned by an expression.
|
||||
- Added a check to refuse starting a new debugging session if there is one in progress already.
|
||||
- Added handling of tail calls in the Stack window.
|
||||
- Added pretty printing in Watch and Console (local and remote) windows and handling of multiple results in Console.
|
||||
- Added Stack window to display stack information and local/upvalue values for each stack frame.
|
||||
- Added ability to set font encoding in the config.
|
||||
- Added restoring cursor position when a modified file is reloaded in the editor.
|
||||
- Added ability to interact with scripts by allowing text to be entered in the 'Output' window.
|
||||
- Improved logic in love2d integration to distinguish Debug and Run commands (closes #13).
|
||||
- Improved reporting in static analysis for functions and global variables.
|
||||
- Updated menus to avoid conflicts with MacOS shortcuts.
|
||||
- Updated logic creating menubar to make it work correctly on MacOS with special Help/About items.
|
||||
- Updated path handling to better detect how the app is started and to avoid loading dlls on non-windows platforms.
|
||||
- Updated logic for detecting hostname (used in the debugger) to make sure it is resolvable.
|
||||
- Changed order of lualibs/ and bin/ directories in package.path and package.cpath to load included modules first.
|
||||
- Removed extensions from launch commands and updated display logic in the Output window.
|
||||
|
||||
### Fixes
|
||||
- Fixed aborting running/debugged programs on MacOS by adding MAKE_GROUP_LEADER option to wxExecute.
|
||||
- Fixed an issue in the logic for setting breakpoints, which ignored breakpoints in luxinia2 debug sessions.
|
||||
- Fixed logic in the local/remote console that returned incorrect error message on executing code like '%s':format(1).
|
||||
- Fixed IDs for Project menu items to allow them to be removed from the menu if needed.
|
||||
- Fixed an issue with remote application not terminating when IDE is closed while debugging is in progress.
|
||||
- Fixed refreshing a modified file when the editor is set to read-only mode.
|
||||
- Fixed saving/restoring configuration of 'Output'/'Console' tabs when IDE is closed while debugging is in progress.
|
||||
- Fixed removing variable name in Watch window after escaping editing.
|
||||
- Fixed #9 as it had incorrect logic in one of UTF filters.
|
||||
- Fixed edit menu shortcuts to work in the 'Output' window (when allowed).
|
||||
- Fixed reporting of processes that failed to start after 'Run' or 'Debug' commands.
|
||||
- Fixed executable path matching to work on systems that don't have file extensions.
|
||||
- Fixed #3 'unused parameter...' check not to fail on anonymous functions that are part of an expression.
|
||||
- Moved processing of `user.lua` to a later phase after tools and specs are already loaded to allow modification of IDE configuration from `user.lua`. Closes #5.
|
||||
- Added checks to prevent text modification in 'Output' and 'Console' windows. Fixes #8.
|
||||
- Disabled 'Run as Scratchpad' if there is no debugger registered capable of running it.
|
||||
- Disabled Stack and Watch updates when scratchpad is active as they interfere with application execution.
|
||||
|
||||
## v0.29 (May 31 2012)
|
||||
|
||||
### Highlights
|
||||
- Added **scratchpad** (running live) functionality.
|
||||
- Added **code analyzer** based on lua-inspect.
|
||||
- Updated **comment styling** to follow markdown syntax.
|
||||
|
||||
### Improvements
|
||||
- Added scratchpad (running live) functionality.
|
||||
- Added code analyzer based on lua-inspect.
|
||||
- Added Ctrl(-Shift)-TAB navigation between tabs in the editor.
|
||||
- Added navigation between editor tabs using Ctrl-PgUp and Ctrl-PgDn.
|
||||
- Added reporting of assignment to global variables in the code analyzer.
|
||||
- Added ability to turn external processes that connect to debugger into a scratchpad.
|
||||
- Added exit from full screen mode using ESC key.
|
||||
- Added reporting of compilation errors during debugging sessions.
|
||||
- Added handling of more errors in the shell to allow calculations like '(1+2)' to be executed correctly.
|
||||
- Added moving focus back to the notebook after unhiding/activating a wx window.
|
||||
- Added missing mime/code.dll and reorganized socket module files (socket.*) to load correctly with require.
|
||||
- Added stopping the debugger when a debugged program exits.
|
||||
- Added to static analysis reporting of unused parameters in functions.
|
||||
- Disabled warning in static analysis about unused 'self' in methods.
|
||||
- Removed 'error during pre-compilation' message from compile errors.
|
||||
- Updated comment styling to follow markdown syntax.
|
||||
|
||||
### Fixes
|
||||
- Fixed handling of scripts with comments in the remote shell.
|
||||
- Fixed an issue with Analyze process when the analyzed script has compilation errors.
|
||||
- Fixed an issue with scratchpad being on after Save dialog is canceled.
|
||||
- Fixed about screen.
|
||||
|
||||
## v0.28 (Mar 21 2012)
|
||||
|
||||
### Highlights
|
||||
- Added full screen mode.
|
||||
|
||||
### Improvements
|
||||
- Added option to activate output/console when Run/Debug/Compile commands are executed.
|
||||
- Added full screen mode.
|
||||
- Added killing a running process on IDE exit.
|
||||
- Added killing a running process with Shift-F12.
|
||||
- Disabled buffering of the output for scripts run from IDE.
|
||||
|
||||
### Fixes
|
||||
- Fixed 'Trace' command to continue working when a debugged file is not activated.
|
||||
- Fixed an issue with saving a file when no project directory is set.
|
||||
- Fixed missing semicolon in lualibs path; added path for debugger to search under lualibs.
|
||||
- Fixed an issue with a missing path separator, which prevented debugging from executing step commands in some cases.
|
||||
- Fixed missing slash on SaveAs by enforcing trailing slash for the project path.
|
||||
|
||||
## v0.27 (Feb 14 2012)
|
||||
|
||||
### Highlights
|
||||
- Added markup formatting in the comments.
|
||||
|
||||
### Improvements
|
||||
- Added markup formatting in the comments.
|
||||
- Added Debug and Run methods to simulate menu commands.
|
||||
- Added setting a project folder on initial start.
|
||||
- Added style processing for font name, font size, visibility and hotspot attributes.
|
||||
- Added setting the current project directory for the shell to allow 'require' commands to work with local modules.
|
||||
- Updated markup processing with run and debug commands, http link processing, and opening local files in a new window.
|
||||
- Enforced visibility for shell prompt.
|
||||
|
||||
### Fixes
|
||||
- Fixed activation of a correct tab when one of the editor tabs is closed.
|
||||
- Fixed an issue with file activation from a debugger.
|
||||
- Fixed the issue of ClosePage method being called with two different parameters.
|
||||
- Fixed the issue of the project dir being returned with two trailing slashes.
|
||||
- Fixed an issue with activating the currenly edited file in the file tree.
|
||||
- Wrapped DragAcceptFiles into a protected call to make it not fail on MacOS (compiled with wxwidgets 2.8.12).
|
||||
|
||||
## v0.26 (Jan 18 2012)
|
||||
6
LICENSE
6
LICENSE
@@ -49,7 +49,7 @@ 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.
|
||||
|
||||
--[[ wxLua License License ]]----------------------------------------------
|
||||
--[[ wxLua License ]]------------------------------------------------------
|
||||
|
||||
http://wxlua.sourceforge.net/
|
||||
|
||||
@@ -61,7 +61,7 @@ Original wxLua Lua sample IDE:
|
||||
luascript at thersgb.net
|
||||
|
||||
wxLua is based on
|
||||
wxWindows Library Licence, Version 3
|
||||
wxWindows Library License, Version 3
|
||||
|
||||
Copyright (c) 1998 Julian Smart, Robert Roebling et al
|
||||
|
||||
@@ -178,7 +178,7 @@ output file generation.
|
||||
|
||||
MobDebug sources are released under the MIT License
|
||||
|
||||
Copyright (c) 2011 Paul Kulchenko (paul@kulchenko.com)
|
||||
Copyright (c) 2011-2012 Paul Kulchenko (paul@kulchenko.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
78
README.md
78
README.md
@@ -1,70 +1,56 @@
|
||||
# Project Description
|
||||
|
||||
A simple and extensible Lua IDE and debugger. It supports multiple file
|
||||
formats, "api" for autocompletion and tooltips, and custom command-line
|
||||
tools. Its main focus is extensibility for target applications using Lua.
|
||||
[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, MobileLua,
|
||||
and others).
|
||||
|
||||
## Features
|
||||
|
||||
* Written in Lua, so easily customizable
|
||||
* Automatically loads several 'plugin' like classes
|
||||
- applications: overall control of applications settings
|
||||
- specs (spec/): file syntax, lexer, keywords
|
||||
- apis (api/): for code-completion and tool-tips
|
||||
- interpreters (interpreters/): how a project is run
|
||||
- config (cfg/): contains style and basic editor settings
|
||||
- tools (tools/): additional tools, e.g. cg compiler, dx fxc compiler
|
||||
* Auto-completion for functions, keywords...
|
||||
* Function tips
|
||||
* Function list in file (quick jump to)
|
||||
* Function call highlighting
|
||||
* Bracket matching/highlighting
|
||||
* Project file browser
|
||||
* Experimental type/class guessing for auto-completion
|
||||
* Support for different editor styles
|
||||
* Console to directly test code snippets with local and remote execution
|
||||
* Integrated debugger (with support for local and remote debugging)
|
||||
* Written in Lua, so easily customizable.
|
||||
* Small, portable, and cross-platform (Windows, Mac OSX, and Linux).
|
||||
* 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)).
|
||||
* Support for plugin-like components:
|
||||
- applications: overall control of applications settings;
|
||||
- specs (spec/): file syntax, lexer, keywords;
|
||||
- apis (api/): for code-completion and tool-tips;
|
||||
- interpreters (interpreters/): how a project is run;
|
||||
- config (cfg/): contains style and basic editor settings;
|
||||
- tools (tools/): additional tools.
|
||||
|
||||
## Frontends
|
||||
## Screenshot
|
||||
|
||||
There is currently two front-ends using the same editor engine. The original
|
||||
one is `Estrela`, which has a focus on 3d graphics related usage of Lua,
|
||||
especially in combination with the luxinia engine or luxinia2 framework.
|
||||
The second front-end is `ZeroBrane Studio` (zbstudio) which has a focus
|
||||
on using Lua in education, mobile development, and robotics.
|
||||
|
||||
Both are part of the standard distribution.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
$ git clone git://github.com/pkulchenko/ZeroBraneStudio.git zbstudio
|
||||
or
|
||||
$ git clone git://estrelaeditor.git.sourceforge.net/gitroot/estrelaeditor/estrelaeditor estrelaeditor
|
||||
```
|
||||

|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
Open File(s):
|
||||
<exe> <filename> [<filename>...]
|
||||
Open file(s):
|
||||
<zbstudio> <filename> [<filename>...]
|
||||
any non-option will be treated as filename
|
||||
|
||||
Overriding Config:
|
||||
<exe> [...] -cfg "<luacode overriding config>" [...]
|
||||
e.g.: zbstudio.exe -cfg "singleinstance=false;" somefile.lua
|
||||
Overriding default configuration:
|
||||
<zbstudio> -cfg "<luacode overriding config>" [<filename>]
|
||||
e.g.: zbstudio -cfg "editor.fontsize=12" somefile.lua
|
||||
|
||||
Loading custom configuration:
|
||||
<zbstudio> -cfg "config/file.lua" [<filename>]
|
||||
e.g.: zbstudio -cfg cfg/estrela.lua
|
||||
```
|
||||
|
||||
## Author
|
||||
|
||||
### Estrela Editor
|
||||
|
||||
**Luxinia Dev:** Christoph Kubisch (crazybutcher@luxinia.de)
|
||||
|
||||
### ZeroBrane Studio and MobDebug
|
||||
|
||||
**ZeroBrane LLC:** Paul Kulchenko (paul@kulchenko.com)
|
||||
|
||||
### Estrela Editor
|
||||
|
||||
**Luxinia Dev:** Christoph Kubisch (crazybutcher@luxinia.de)
|
||||
|
||||
## License
|
||||
|
||||
See LICENSE file.
|
||||
|
||||
@@ -71,13 +71,14 @@ ldexp = fn "build floating point number from x and the corresponding integral ex
|
||||
packUnorm2x16 = fn "Converts each comp. of v into 16-bit ints, packs results into the returned 32-bit uint. - (uint)(vec2 v)",
|
||||
packUnorm4x8 = fn "Converts each comp. of v into 8-bit ints, packs results into the returned 32-bit uint. - (uint)(vec4 v)",
|
||||
packSnorm4x8 = fn "Converts each comp. of v into 8-bit ints, packs results into the returned 32-bit uint. - (uint)(vec4 v)",
|
||||
packDouble2x32 = fn "Packs components of v into a 64-bit value and returns a double-prec value. - (double)(uvec2 v)",
|
||||
packHalf2x16 = fn "Converts each comp. of v into 16-bit half float, packs results into the returned 32-bit uint. - (uint)(vec2 v)",
|
||||
|
||||
unpackUnorm2x16 = fn "Unpacks 32-bit p into two 16-bit uints and converts them to normalized float. - (vec2)(uint p)",
|
||||
unpackUnorm4x8 = fn "Unpacks 32-bit p into four 8-bit uints and converts them to normalized float. - (vec4)(uint p)",
|
||||
unpackSnorm4x8 = fn "Unpacks 32-bit p into four 8-bit uints and converts them to normalized float. - (vec4)(uint p)",
|
||||
|
||||
packDouble2x32 = fn "Packs components of v into a 64-bit value and returns a double-prec value. - (double)(uvec2 v)",
|
||||
unpackDouble2x32 = fn "Returns a 2 component vector representation of v. - (uvec2)(double v)",
|
||||
unpackHalf2x16 = fn "Interprets p as two 16-bit half floats and returns them as vector. - (vec2)(uint p)",
|
||||
|
||||
length = fn "return scalar Euclidean length of a vector. - (type)(vecN)",
|
||||
distance = fn "return the Euclidean distance between two points. - (vecN)(vecN a, b)",
|
||||
@@ -135,6 +136,11 @@ EndPrimitive = fn "Completes current output primitive and starts a new one. - ()
|
||||
barrier = fn "Synchronizes across shader invocations. - ()()",
|
||||
|
||||
memoryBarrier = fn "control ordering of memory transactions issued by shader thread. - ()()",
|
||||
memoryBarrierAtomicCounter = fn "control ordering of memory transactions issued by shader thread. - ()()",
|
||||
memoryBarrierShared = fn "control ordering of memory transactions issued by shader thread. - ()()",
|
||||
memoryBarrierBuffer = fn "control ordering of memory transactions issued by shader thread. - ()()",
|
||||
memoryBarrierImage = fn "control ordering of memory transactions issued by shader thread. - ()()",
|
||||
groupMemoryBarrier = fn "control ordering of memory transactions issued by shader thread. - ()()",
|
||||
imageAtomicAdd = fn "performs atomic operation on individual texels returns new value. - (uint)(imageN, intN coord, [int sample], uint data)",
|
||||
imageAtomicMin = fn "performs atomic operation on individual texels returns new value. - (uint)(imageN, intN coord, [int sample], uint data)",
|
||||
imageAtomicMax = fn "performs atomic operation on individual texels returns new value. - (uint)(imageN, intN coord, [int sample], uint data)",
|
||||
@@ -167,41 +173,51 @@ texelFetchOffset = fn "integer coordinate lookup for a single texel with offset.
|
||||
}
|
||||
|
||||
local keyw =
|
||||
[[int uint half float bool double
|
||||
vec2 vec3 vec4 dvec2 dvec3 dvec4
|
||||
ivec2 ivec3 ivec4 uvec2 uvec3 uvec4 bvec2 bvec3 bvec4
|
||||
mat2 mat3 mat4 mat2x2 mat3x3 mat4x4 mat2x3 mat3x2 mat4x2 mat2x4 mat4x3 mat3x4
|
||||
dmat2 dmat3 dmat4 dmat2x2 dmat3x3 dmat4x4 dmat2x3 dmat3x2 dmat4x2 dmat2x4 dmat4x3 dmat3x4
|
||||
struct typedef void
|
||||
usampler1D usampler2D usampler3D usampler2DRect usamplerCube isampler1DArray usampler2DARRAY usamplerCubeArray usampler2DMS usampler2DMSArray
|
||||
isampler1D isampler2D isampler3D isampler2DRect isamplerCube isampler1DArray isampler2DARRAY isamplerCubeArray isampler2DMS isampler2DMSArray
|
||||
sampler1D sampler2D sampler3D sampler2DRect samplerCube sampler1DArray sampler2DArray samplerCubeArray sampler2DMS sampler2DMSArray
|
||||
sampler1DShadow sampler2DShadow sampler2DRectShadow sampler1DArrayShadow sampler2DArrayShadow samplerCubeArrayShadow
|
||||
usamplerBuffer isamplerBuffer samplerBuffer
|
||||
in out inout uniform const centroid sample attribute varying patch
|
||||
return switch case for do while if else break continue
|
||||
layout location vertices line_strip triangle_strip max_vertices stream
|
||||
triangles quads equal_spacing isolines fractional_even_spacing
|
||||
fractional_odd_spacing cw ccw point_mode lines_adjacency triangles_adjacency
|
||||
invocations
|
||||
origin_upper_left pixel_center_integer
|
||||
smooth flat noperspective highp mediump lowp shared packed std140 row_major column_major
|
||||
gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor gl_Color gl_SecondaryColor
|
||||
subroutine gl_Position
|
||||
gl_VertexID gl_InstanceID gl_Normal gl_Vertex gl_MultiTexCoord0 gl_MultiTexCoord1
|
||||
gl_MultiTexCoord2 gl_MultiTexCoord3 gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6
|
||||
gl_MultiTexCoord7 gl_FogCoord gl_PointSize gl_ClipDistance
|
||||
gl_TexCoord gl_FogFragCoord gl_ClipVertex gl_in
|
||||
gl_PatchVerticesIn
|
||||
gl_PrimitiveID gl_InvocationID gl_TessLevelOuter gl_TessLevelInner gl_TessCoord
|
||||
gl_InvocationID gl_PrimitiveIDIn gl_Layer gl_ViewportIndex gl_FrontFacing
|
||||
gl_PointCoord gl_SampleID gl_SamplePosition gl_FragColor
|
||||
gl_FragData gl_FragDepth gl_SampleMask
|
||||
[[ int uint half float bool double atomic_uint binding offset
|
||||
vec2 vec3 vec4 dvec2 dvec3 dvec4
|
||||
ivec2 ivec3 ivec4 uvec2 uvec3 uvec4 bvec2 bvec3 bvec4
|
||||
mat2 mat3 mat4 mat2x2 mat3x3 mat4x4 mat2x3 mat3x2 mat4x2 mat2x4 mat4x3 mat3x4
|
||||
dmat2 dmat3 dmat4 dmat2x2 dmat3x3 dmat4x4 dmat2x3 dmat3x2 dmat4x2 dmat2x4 dmat4x3 dmat3x4
|
||||
struct typedef void
|
||||
usampler1D usampler2D usampler3D usampler2DRect usamplerCube isampler1DArray usampler2DARRAY usamplerCubeArray usampler2DMS usampler2DMSArray
|
||||
isampler1D isampler2D isampler3D isampler2DRect isamplerCube isampler1DArray isampler2DARRAY isamplerCubeArray isampler2DMS isampler2DMSArray
|
||||
sampler1D sampler2D sampler3D sampler2DRect samplerCube sampler1DArray sampler2DArray samplerCubeArray sampler2DMS sampler2DMSArray
|
||||
sampler1DShadow sampler2DShadow sampler2DRectShadow sampler1DArrayShadow sampler2DArrayShadow samplerCubeArrayShadow
|
||||
usamplerBuffer isamplerBuffer samplerBuffer samplerRenderbuffer isamplerRenderbuffer usamplerRenderbuffer
|
||||
in out inout uniform const centroid sample attribute varying patch index true false
|
||||
return switch case for do while if else break continue main inline
|
||||
layout location vertices line_strip triangle_strip max_vertices stream
|
||||
triangles quads equal_spacing isolines fractional_even_spacing lines points
|
||||
fractional_odd_spacing cw ccw point_mode lines_adjacency triangles_adjacency
|
||||
invocations
|
||||
origin_upper_left pixel_center_integer depth_greater depth_greater depth_greater depth_unchanged
|
||||
smooth flat noperspective highp mediump lowp shared packed std140 std430 row_major column_major buffer
|
||||
gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor gl_Color gl_SecondaryColor
|
||||
subroutine gl_Position gl_FragCoord
|
||||
gl_VertexID gl_InstanceID gl_Normal gl_Vertex gl_MultiTexCoord0 gl_MultiTexCoord1
|
||||
gl_MultiTexCoord2 gl_MultiTexCoord3 gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6
|
||||
gl_MultiTexCoord7 gl_FogCoord gl_PointSize gl_ClipDistance
|
||||
gl_TexCoord gl_FogFragCoord gl_ClipVertex gl_in
|
||||
gl_PatchVerticesIn
|
||||
gl_PrimitiveID gl_InvocationID gl_TessLevelOuter gl_TessLevelInner gl_TessCoord
|
||||
gl_InvocationID gl_PrimitiveIDIn gl_Layer gl_ViewportIndex gl_FrontFacing
|
||||
gl_PointCoord gl_SampleID gl_SamplePosition gl_FragColor
|
||||
gl_FragData gl_FragDepth gl_SampleMask
|
||||
gl_NumWorkGroups gl_WorkGroupSize gl_WorkGroupID gl_LocalInvocationID gl_GlobalInvocationID gl_LocalInvocationIndex
|
||||
local_size_x local_size_y local_size_z
|
||||
|
||||
coherent volatile restrict readonly writeonly
|
||||
image1D image2D image3D image2DRect imageCube imageBuffer image1DArray image2DArray imageCubeArray image2DMS image2DMSArray
|
||||
uimage1D uimage2D uimage3D uimage2DRect uimageCube uimageBuffer uimage1DArray uimage2DArray uimageCubeArray uimage2DMS uimage2DMSArray
|
||||
iimage1D iimage2D iimage3D iimage2DRect iimageCube iimageBuffer iimage1DArray iimage2DArray iimageCubeArray iimage2DMS iimage2DMSArray
|
||||
size1x8 size1x16 size1x32 size2x32 size4x32 rgba32f rgba16f rg32f rg16f r32f r16f rgba8 rgba16 r11f_g11f_b10f rgb10_a2ui
|
||||
rgb10_a2i rg16 rg8 r16 r8 rgba32i rgba16i rgba8i rg32i rg16i rg8i r32i r16i r8i rgba32ui rgba16ui rgba8ui rg32ui rg16ui rg8ui
|
||||
r32ui r16ui r8ui rgba16_snorm rgba8_snorm rg16_snorm rg8_snorm r16_snorm r8_snorm
|
||||
]]
|
||||
|
||||
-- keywords - shouldn't be left out
|
||||
for w in keyw:gmatch("([a-zA-Z_0-9]+)") do
|
||||
api[w] = {type="keyword"}
|
||||
api[w] = {type="keyword"}
|
||||
end
|
||||
|
||||
return api
|
||||
|
||||
553
api/lua/anttweakbar.lua
Normal file
553
api/lua/anttweakbar.lua
Normal file
@@ -0,0 +1,553 @@
|
||||
--[[// tw tweakbar | AntTweakBar UI
|
||||
enum { TW_VERSION = 114 }
|
||||
|
||||
typedef enum ETwType {
|
||||
TW_TYPE_UNDEF,
|
||||
TW_TYPE_BOOLCPP,
|
||||
TW_TYPE_BOOL8,
|
||||
TW_TYPE_BOOL16,
|
||||
TW_TYPE_BOOL32,
|
||||
TW_TYPE_CHAR,
|
||||
TW_TYPE_INT8,
|
||||
TW_TYPE_UINT8,
|
||||
TW_TYPE_INT16,
|
||||
TW_TYPE_UINT16,
|
||||
TW_TYPE_INT32,
|
||||
TW_TYPE_UINT32,
|
||||
TW_TYPE_FLOAT,
|
||||
TW_TYPE_DOUBLE,
|
||||
TW_TYPE_COLOR32, // 32 bits color. Order is RGBA if API is OpenGL or Direct3D10, and inversed if API is Direct3D9 (can be modified by defining 'colorOrder=...', see doc)
|
||||
TW_TYPE_COLOR3F, // 3 floats color. Order is RGB.
|
||||
TW_TYPE_COLOR4F, // 4 floats color. Order is RGBA.
|
||||
TW_TYPE_CDSTRING, // Null-terminated C Dynamic String (pointer to an array of char dynamically allocated with malloc/realloc/strdup)
|
||||
TW_TYPE__TEMP1, //
|
||||
TW_TYPE_QUAT4F, // 4 floats encoding a quaternion {qx,qy,qz,qs}
|
||||
TW_TYPE_QUAT4D, // 4 doubles encoding a quaternion {qx,qy,qz,qs}
|
||||
TW_TYPE_DIR3F, // direction vector represented by 3 floats
|
||||
TW_TYPE_DIR3D, // direction vector represented by 3 doubles
|
||||
TW_TYPE_CSSTRING_LEN0 = 0x30000000,
|
||||
TW_TYPE_CSSTRING_LEN256 = 0x30000000 + 256,
|
||||
} TwType;
|
||||
|
||||
typedef struct CTwEnumVal {
|
||||
int Value;
|
||||
const char * Label;
|
||||
} TwEnumVal;
|
||||
|
||||
typedef struct CTwStructMember {
|
||||
const char * Name;
|
||||
TwType Type;
|
||||
size_t Offset;
|
||||
const char * DefString;
|
||||
} TwStructMember;
|
||||
|
||||
typedef enum ETwParamValueType {
|
||||
TW_PARAM_INT32,
|
||||
TW_PARAM_FLOAT,
|
||||
TW_PARAM_DOUBLE,
|
||||
TW_PARAM_CSTRING // Null-terminated array of char (ie, c-string)
|
||||
} TwParamValueType;
|
||||
|
||||
typedef enum ETwGraphAPI {
|
||||
TW_OPENGL = 1,
|
||||
TW_DIRECT3D9 = 2,
|
||||
TW_DIRECT3D10 = 3,
|
||||
TW_DIRECT3D11 = 4
|
||||
} TwGraphAPI;
|
||||
|
||||
typedef enum ETwKeyModifier {
|
||||
TW_KMOD_NONE = 0x0000, // same codes as SDL keysym.mod
|
||||
TW_KMOD_SHIFT = 0x0003,
|
||||
TW_KMOD_CTRL = 0x00c0,
|
||||
TW_KMOD_ALT = 0x0100,
|
||||
TW_KMOD_META = 0x0c00
|
||||
} TwKeyModifier;
|
||||
|
||||
typedef enum EKeySpecial {
|
||||
TW_KEY_BACKSPACE = '\b',
|
||||
TW_KEY_TAB = '\t',
|
||||
TW_KEY_CLEAR = 0x0c,
|
||||
TW_KEY_RETURN = '\r',
|
||||
TW_KEY_PAUSE = 0x13,
|
||||
TW_KEY_ESCAPE = 0x1b,
|
||||
TW_KEY_SPACE = ' ',
|
||||
TW_KEY_DELETE = 0x7f,
|
||||
TW_KEY_UP = 273,
|
||||
TW_KEY_DOWN,
|
||||
TW_KEY_RIGHT,
|
||||
TW_KEY_LEFT,
|
||||
TW_KEY_INSERT,
|
||||
TW_KEY_HOME,
|
||||
TW_KEY_END,
|
||||
TW_KEY_PAGE_UP,
|
||||
TW_KEY_PAGE_DOWN,
|
||||
TW_KEY_F1,
|
||||
TW_KEY_F2,
|
||||
TW_KEY_F3,
|
||||
TW_KEY_F4,
|
||||
TW_KEY_F5,
|
||||
TW_KEY_F6,
|
||||
TW_KEY_F7,
|
||||
TW_KEY_F8,
|
||||
TW_KEY_F9,
|
||||
TW_KEY_F10,
|
||||
TW_KEY_F11,
|
||||
TW_KEY_F12,
|
||||
TW_KEY_F13,
|
||||
TW_KEY_F14,
|
||||
TW_KEY_F15,
|
||||
TW_KEY_LAST
|
||||
} TwKeySpecial;
|
||||
|
||||
typedef enum ETwMouseAction {
|
||||
TW_MOUSE_RELEASED,
|
||||
TW_MOUSE_PRESSED
|
||||
} TwMouseAction;
|
||||
|
||||
typedef enum ETwMouseButtonID {
|
||||
TW_MOUSE_LEFT = 1,
|
||||
TW_MOUSE_MIDDLE = 2,
|
||||
TW_MOUSE_RIGHT = 3
|
||||
} TwMouseButtonID;
|
||||
|
||||
typedef void (*TwSetVarCallback) ( const void *value, void *clientData );
|
||||
typedef void (*TwGetVarCallback) ( void *value, void *clientData );
|
||||
typedef void (*TwButtonCallback) ( void *clientData );
|
||||
typedef void (*TwSummaryCallback) ( char *summaryString, size_t summaryMaxLength, const void *value, void *clientData );
|
||||
typedef void (*TwCopyCDStringToClient) ( char **destinationClientStringPtr, const char *sourceString );
|
||||
typedef void (*TwErrorHandler) ( const char *errorMessage );
|
||||
typedef void (*TwGLUTmousebuttonfun) ( int glutButton, int glutState, int mouseX, int mouseY );
|
||||
typedef void (*TwGLUTmousemotionfun) ( int mouseX, int mouseY );
|
||||
typedef void (*TwGLUTkeyboardfun) ( unsigned char glutKey, int mouseX, int mouseY );
|
||||
typedef void (*TwGLUTspecialfun) ( int glutKey, int mouseX, int mouseY );
|
||||
|
||||
typedef struct CTwBar TwBar;
|
||||
|
||||
TwBar* TwNewBar( const char *barName );
|
||||
int TwDeleteBar( TwBar *bar );
|
||||
int TwDeleteAllBars( );
|
||||
int TwSetTopBar( const TwBar *bar );
|
||||
TwBar* TwGetTopBar( );
|
||||
int TwSetBottomBar( const TwBar *bar );
|
||||
TwBar* TwGetBottomBar( );
|
||||
const char* TwGetBarName( TwBar *bar );
|
||||
int TwGetBarCount( );
|
||||
TwBar* TwGetBarByIndex( int barIndex );
|
||||
TwBar* TwGetBarByName( const char *barName );
|
||||
int TwRefreshBar( TwBar *bar );
|
||||
int TwAddVarRW( TwBar *bar, const char *name, TwType type, void *var, const char *def );
|
||||
int TwAddVarRO( TwBar *bar, const char *name, TwType type, const void *var, const char *def );
|
||||
int TwAddVarCB( TwBar *bar, const char *name, TwType type, TwSetVarCallback setCallback, TwGetVarCallback getCallback, void *clientData, const char *def );
|
||||
int TwAddButton( TwBar *bar, const char *name, TwButtonCallback callback, void *clientData, const char *def );
|
||||
int TwAddSeparator( TwBar *bar, const char *name, const char *def );
|
||||
int TwRemoveVar( TwBar *bar, const char *name );
|
||||
int TwRemoveAllVars( TwBar *bar );
|
||||
int TwDefine( const char *def );
|
||||
TwType TwDefineEnum( const char *name, const TwEnumVal *enumValues, unsigned int nbValues );
|
||||
TwType TwDefineEnumFromString( const char *name, const char *enumString );
|
||||
TwType TwDefineStruct( const char *name, const TwStructMember *structMembers, unsigned int nbMembers, size_t structSize, TwSummaryCallback summaryCallback, void *summaryClientData );
|
||||
void TwCopyCDStringToClientFunc( TwCopyCDStringToClient copyCDStringFunc );
|
||||
void TwCopyCDStringToLibrary( char **destinationLibraryStringPtr, const char *sourceClientString );
|
||||
int TwGetParam( TwBar *bar, const char *varName, const char *paramName, TwParamValueType paramValueType, unsigned int outValueMaxCount, void *outValues );
|
||||
int TwSetParam( TwBar *bar, const char *varName, const char *paramName, TwParamValueType paramValueType, unsigned int inValueCount, const void *inValues );
|
||||
int TwInit( TwGraphAPI graphAPI, void *device );
|
||||
int TwTerminate();
|
||||
int TwDraw();
|
||||
int TwWindowSize( int width, int height);
|
||||
int TwSetCurrentWindow( int windowID); // multi-windows support
|
||||
int TwGetCurrentWindow();
|
||||
int TwWindowExists( int windowID);
|
||||
int TwKeyPressed( int key, int modifiers);
|
||||
int TwKeyTest( int key, int modifiers);
|
||||
int TwMouseButton( TwMouseAction action, TwMouseButtonID button);
|
||||
int TwMouseMotion( int mouseX, int mouseY);
|
||||
int TwMouseWheel( int pos);
|
||||
const char* TwGetLastError( );
|
||||
void TwHandleErrors( TwErrorHandler errorHandler);
|
||||
int TwEventSDL( const void *sdlEvent, unsigned char sdlMajorVersion, unsigned char sdlMinorVersion);
|
||||
int TwEventSDL12( const void *sdlEvent);
|
||||
int TwEventSDL13( const void *sdlEvent);
|
||||
int TwEventMouseButtonGLFW( int glfwButton, int glfwAction );
|
||||
int TwEventKeyGLFW( int glfwKey, int glfwAction );
|
||||
int TwEventCharGLFW( int glfwChar, int glfwAction );
|
||||
int TwEventMouseButtonGLUT( int glutButton, int glutState, int mouseX, int mouseY);
|
||||
int TwEventMouseMotionGLUT( int mouseX, int mouseY);
|
||||
int TwEventKeyboardGLUT( unsigned char glutKey, int mouseX, int mouseY );
|
||||
int TwEventSpecialGLUT( int glutKey, int mouseX, int mouseY );
|
||||
int TwGLUTModifiersFunc( int (*glutGetModifiersFunc)(void) );
|
||||
int TwEventSFML( const void *sfmlEvent, unsigned char sfmlMajorVersion, unsigned char sfmlMinorVersion);
|
||||
]]
|
||||
--auto-generated api from ffi headers
|
||||
local api =
|
||||
{
|
||||
["TW_TYPE_UNDEF"] = { type ='value', },
|
||||
["TW_TYPE_BOOLCPP"] = { type ='value', },
|
||||
["TW_TYPE_BOOL8"] = { type ='value', },
|
||||
["TW_TYPE_BOOL16"] = { type ='value', },
|
||||
["TW_TYPE_BOOL32"] = { type ='value', },
|
||||
["TW_TYPE_CHAR"] = { type ='value', },
|
||||
["TW_TYPE_INT8"] = { type ='value', },
|
||||
["TW_TYPE_UINT8"] = { type ='value', },
|
||||
["TW_TYPE_INT16"] = { type ='value', },
|
||||
["TW_TYPE_UINT16"] = { type ='value', },
|
||||
["TW_TYPE_INT32"] = { type ='value', },
|
||||
["TW_TYPE_UINT32"] = { type ='value', },
|
||||
["TW_TYPE_FLOAT"] = { type ='value', },
|
||||
["TW_TYPE_DOUBLE"] = { type ='value', },
|
||||
["TW_TYPE_COLOR32"] = { type ='value', },
|
||||
["TW_TYPE_COLOR3F"] = { type ='value', },
|
||||
["TW_TYPE_COLOR4F"] = { type ='value', },
|
||||
["TW_TYPE_CDSTRING"] = { type ='value', },
|
||||
["TW_TYPE__TEMP1"] = { type ='value', },
|
||||
["TW_TYPE_QUAT4F"] = { type ='value', },
|
||||
["TW_TYPE_QUAT4D"] = { type ='value', },
|
||||
["TW_TYPE_DIR3F"] = { type ='value', },
|
||||
["TW_TYPE_DIR3D"] = { type ='value', },
|
||||
["TW_TYPE_CSSTRING_LEN0"] = { type ='value', },
|
||||
["TW_TYPE_CSSTRING_LEN256"] = { type ='value', },
|
||||
["TW_PARAM_INT32"] = { type ='value', },
|
||||
["TW_PARAM_FLOAT"] = { type ='value', },
|
||||
["TW_PARAM_DOUBLE"] = { type ='value', },
|
||||
["TW_PARAM_CSTRING"] = { type ='value', },
|
||||
["TW_OPENGL"] = { type ='value', },
|
||||
["TW_DIRECT3D9"] = { type ='value', },
|
||||
["TW_DIRECT3D10"] = { type ='value', },
|
||||
["TW_DIRECT3D11"] = { type ='value', },
|
||||
["TW_KMOD_NONE"] = { type ='value', },
|
||||
["TW_KMOD_SHIFT"] = { type ='value', },
|
||||
["TW_KMOD_CTRL"] = { type ='value', },
|
||||
["TW_KMOD_ALT"] = { type ='value', },
|
||||
["TW_KMOD_META"] = { type ='value', },
|
||||
["TW_KEY_BACKSPACE"] = { type ='value', },
|
||||
["TW_KEY_TAB"] = { type ='value', },
|
||||
["TW_KEY_CLEAR"] = { type ='value', },
|
||||
["TW_KEY_RETURN"] = { type ='value', },
|
||||
["TW_KEY_PAUSE"] = { type ='value', },
|
||||
["TW_KEY_ESCAPE"] = { type ='value', },
|
||||
["TW_KEY_SPACE"] = { type ='value', },
|
||||
["TW_KEY_DELETE"] = { type ='value', },
|
||||
["TW_KEY_UP"] = { type ='value', },
|
||||
["TW_KEY_DOWN"] = { type ='value', },
|
||||
["TW_KEY_RIGHT"] = { type ='value', },
|
||||
["TW_KEY_LEFT"] = { type ='value', },
|
||||
["TW_KEY_INSERT"] = { type ='value', },
|
||||
["TW_KEY_HOME"] = { type ='value', },
|
||||
["TW_KEY_END"] = { type ='value', },
|
||||
["TW_KEY_PAGE_UP"] = { type ='value', },
|
||||
["TW_KEY_PAGE_DOWN"] = { type ='value', },
|
||||
["TW_KEY_F1"] = { type ='value', },
|
||||
["TW_KEY_F2"] = { type ='value', },
|
||||
["TW_KEY_F3"] = { type ='value', },
|
||||
["TW_KEY_F4"] = { type ='value', },
|
||||
["TW_KEY_F5"] = { type ='value', },
|
||||
["TW_KEY_F6"] = { type ='value', },
|
||||
["TW_KEY_F7"] = { type ='value', },
|
||||
["TW_KEY_F8"] = { type ='value', },
|
||||
["TW_KEY_F9"] = { type ='value', },
|
||||
["TW_KEY_F10"] = { type ='value', },
|
||||
["TW_KEY_F11"] = { type ='value', },
|
||||
["TW_KEY_F12"] = { type ='value', },
|
||||
["TW_KEY_F13"] = { type ='value', },
|
||||
["TW_KEY_F14"] = { type ='value', },
|
||||
["TW_KEY_F15"] = { type ='value', },
|
||||
["TW_KEY_LAST"] = { type ='value', },
|
||||
["TW_MOUSE_RELEASED"] = { type ='value', },
|
||||
["TW_MOUSE_PRESSED"] = { type ='value', },
|
||||
["TW_MOUSE_LEFT"] = { type ='value', },
|
||||
["TW_MOUSE_MIDDLE"] = { type ='value', },
|
||||
["TW_MOUSE_RIGHT"] = { type ='value', },
|
||||
["TwNewBar"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(TwBar*)",
|
||||
valuetype = nil,
|
||||
args = "(const char *barName)", },
|
||||
["TwDeleteBar"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(TwBar *bar)", },
|
||||
["TwDeleteAllBars"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "()", },
|
||||
["TwSetTopBar"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(const TwBar *bar)", },
|
||||
["TwGetTopBar"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(TwBar*)",
|
||||
valuetype = nil,
|
||||
args = "()", },
|
||||
["TwSetBottomBar"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(const TwBar *bar)", },
|
||||
["TwGetBottomBar"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(TwBar*)",
|
||||
valuetype = nil,
|
||||
args = "()", },
|
||||
["TwGetBarName"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(const char*)",
|
||||
valuetype = "string",
|
||||
args = "(TwBar *bar)", },
|
||||
["TwGetBarCount"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "()", },
|
||||
["TwGetBarByIndex"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(TwBar*)",
|
||||
valuetype = nil,
|
||||
args = "(int barIndex)", },
|
||||
["TwGetBarByName"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(TwBar*)",
|
||||
valuetype = nil,
|
||||
args = "(const char *barName)", },
|
||||
["TwRefreshBar"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(TwBar *bar)", },
|
||||
["TwAddVarRW"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(TwBar *bar, const char *name, TwType type, void *var, const char *def)", },
|
||||
["TwAddVarRO"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(TwBar *bar, const char *name, TwType type, const void *var, const char *def)", },
|
||||
["TwAddVarCB"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(TwBar *bar, const char *name, TwType type, TwSetVarCallback setCallback, TwGetVarCallback getCallback, void *clientData, const char *def)", },
|
||||
["TwAddButton"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(TwBar *bar, const char *name, TwButtonCallback callback, void *clientData, const char *def)", },
|
||||
["TwAddSeparator"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(TwBar *bar, const char *name, const char *def)", },
|
||||
["TwRemoveVar"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(TwBar *bar, const char *name)", },
|
||||
["TwRemoveAllVars"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(TwBar *bar)", },
|
||||
["TwDefine"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(const char *def)", },
|
||||
["TwDefineEnum"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(TwType)",
|
||||
valuetype = nil,
|
||||
args = "(const char *name, const TwEnumVal *enumValues, unsigned int nbValues)", },
|
||||
["TwDefineEnumFromString"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(TwType)",
|
||||
valuetype = nil,
|
||||
args = "(const char *name, const char *enumString)", },
|
||||
["TwDefineStruct"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(TwType)",
|
||||
valuetype = nil,
|
||||
args = "(const char *name, const TwStructMember *structMembers, unsigned int nbMembers, size_t structSize, TwSummaryCallback summaryCallback, void *summaryClientData)", },
|
||||
["TwCopyCDStringToClientFunc"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(void)",
|
||||
valuetype = nil,
|
||||
args = "(TwCopyCDStringToClient copyCDStringFunc)", },
|
||||
["TwCopyCDStringToLibrary"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(void)",
|
||||
valuetype = nil,
|
||||
args = "(char **destinationLibraryStringPtr, const char *sourceClientString)", },
|
||||
["TwGetParam"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(TwBar *bar, const char *varName, const char *paramName, TwParamValueType paramValueType, unsigned int outValueMaxCount, void *outValues)", },
|
||||
["TwSetParam"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(TwBar *bar, const char *varName, const char *paramName, TwParamValueType paramValueType, unsigned int inValueCount, const void *inValues)", },
|
||||
["TwInit"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(TwGraphAPI graphAPI, void *device)", },
|
||||
["TwTerminate"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "()", },
|
||||
["TwDraw"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "()", },
|
||||
["TwWindowSize"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(int width, int height)", },
|
||||
["TwSetCurrentWindow"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(int windowID)", },
|
||||
["TwGetCurrentWindow"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "()", },
|
||||
["TwWindowExists"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(int windowID)", },
|
||||
["TwKeyPressed"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(int key, int modifiers)", },
|
||||
["TwKeyTest"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(int key, int modifiers)", },
|
||||
["TwMouseButton"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(TwMouseAction action, TwMouseButtonID button)", },
|
||||
["TwMouseMotion"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(int mouseX, int mouseY)", },
|
||||
["TwMouseWheel"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(int pos)", },
|
||||
["TwGetLastError"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(const char*)",
|
||||
valuetype = "string",
|
||||
args = "()", },
|
||||
["TwHandleErrors"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(void)",
|
||||
valuetype = nil,
|
||||
args = "(TwErrorHandler errorHandler)", },
|
||||
["TwEventSDL"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(const void *sdlEvent, unsigned char sdlMajorVersion, unsigned char sdlMinorVersion)", },
|
||||
["TwEventSDL12"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(const void *sdlEvent)", },
|
||||
["TwEventSDL13"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(const void *sdlEvent)", },
|
||||
["TwEventMouseButtonGLFW"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(int glfwButton, int glfwAction)", },
|
||||
["TwEventKeyGLFW"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(int glfwKey, int glfwAction)", },
|
||||
["TwEventCharGLFW"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(int glfwChar, int glfwAction)", },
|
||||
["TwEventMouseButtonGLUT"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(int glutButton, int glutState, int mouseX, int mouseY)", },
|
||||
["TwEventMouseMotionGLUT"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(int mouseX, int mouseY)", },
|
||||
["TwEventKeyboardGLUT"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(unsigned char glutKey, int mouseX, int mouseY)", },
|
||||
["TwEventSpecialGLUT"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(int glutKey, int mouseX, int mouseY)", },
|
||||
["glutGetModifiersFunc"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(void))", },
|
||||
["TwEventSFML"] = { type ='function',
|
||||
description = "",
|
||||
returns = "(int)",
|
||||
valuetype = nil,
|
||||
args = "(const void *sfmlEvent, unsigned char sfmlMajorVersion, unsigned char sfmlMinorVersion)", },
|
||||
["TwEnumVal"] = { type ='class',
|
||||
description = "",
|
||||
childs = {
|
||||
["Value"] = { type ='value', description = "int ", valuetype = nil, },
|
||||
["Label"] = { type ='value', description = "const char * ", valuetype = "string", },
|
||||
}
|
||||
},
|
||||
["TwStructMember"] = { type ='class',
|
||||
description = "",
|
||||
childs = {
|
||||
["Name"] = { type ='value', description = "const char * ", valuetype = "string", },
|
||||
["Type"] = { type ='value', description = "TwType ", valuetype = nil, },
|
||||
["Offset"] = { type ='value', description = "size_t ", valuetype = nil, },
|
||||
["DefString"] = { type ='value', description = "const char * ", valuetype = "string", },
|
||||
}
|
||||
},
|
||||
}
|
||||
return {
|
||||
tw = {
|
||||
type = 'lib',
|
||||
description = "AntTweakBar UI",
|
||||
childs = api,
|
||||
},
|
||||
tweakbar = {
|
||||
type = 'lib',
|
||||
description = "AntTweakBar UI",
|
||||
childs = api,
|
||||
},
|
||||
}
|
||||
|
||||
2577
api/lua/gideros.lua
Normal file
2577
api/lua/gideros.lua
Normal file
File diff suppressed because it is too large
Load Diff
26160
api/lua/glewgl.lua
26160
api/lua/glewgl.lua
File diff suppressed because it is too large
Load Diff
6828
api/lua/moai.lua
Normal file
6828
api/lua/moai.lua
Normal file
File diff suppressed because it is too large
Load Diff
BIN
bin/clcc.exe
BIN
bin/clcc.exe
Binary file not shown.
0
bin/clibs/mime/core.dll
Normal file → Executable file
0
bin/clibs/mime/core.dll
Normal file → Executable file
BIN
bin/clibs/mime/core.dylib
Normal file
BIN
bin/clibs/mime/core.dylib
Normal file
Binary file not shown.
0
bin/clibs/socket/core.dll
Normal file → Executable file
0
bin/clibs/socket/core.dll
Normal file → Executable file
BIN
bin/clibs/socket/core.dylib
Normal file
BIN
bin/clibs/socket/core.dylib
Normal 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.
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.
Binary file not shown.
BIN
bin/libjpeg.8.dylib
Normal file
BIN
bin/libjpeg.8.dylib
Normal file
Binary file not shown.
BIN
bin/libwx.dylib
Normal file
BIN
bin/libwx.dylib
Normal file
Binary file not shown.
BIN
bin/libwxlua-wx28d-2.8.12.dylib
Normal file
BIN
bin/libwxlua-wx28d-2.8.12.dylib
Normal file
Binary file not shown.
BIN
bin/libwxlua_bind-wx28d-2.8.12.dylib
Normal file
BIN
bin/libwxlua_bind-wx28d-2.8.12.dylib
Normal file
Binary file not shown.
BIN
bin/libwxlua_debug-wx28d-2.8.12.dylib
Normal file
BIN
bin/libwxlua_debug-wx28d-2.8.12.dylib
Normal file
Binary file not shown.
BIN
bin/libwxlua_lua51-wx28d-2.8.12.dylib
Normal file
BIN
bin/libwxlua_lua51-wx28d-2.8.12.dylib
Normal file
Binary file not shown.
BIN
bin/libwxlua_socket-wx28d-2.8.12.dylib
Normal file
BIN
bin/libwxlua_socket-wx28d-2.8.12.dylib
Normal file
Binary file not shown.
BIN
bin/libwxstedit-wx28d-1.6.0.dylib
Normal file
BIN
bin/libwxstedit-wx28d-1.6.0.dylib
Normal file
Binary file not shown.
38
bin/lua.app/Contents/Info.plist
Normal file
38
bin/lua.app/Contents/Info.plist
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>lua</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Lua</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string></string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string></string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleLongVersionString</key>
|
||||
<string></string>
|
||||
<key>CFBundleName</key>
|
||||
<string>Lua</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string></string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string></string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
<key>LSRequiresCarbon</key>
|
||||
<true/>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
bin/lua.app/Contents/MacOS/lua
Executable file
BIN
bin/lua.app/Contents/MacOS/lua
Executable file
Binary file not shown.
0
bin/lua.exe
Normal file → Executable file
0
bin/lua.exe
Normal file → Executable file
0
bin/lua5.1.dll
Normal file → Executable file
0
bin/lua5.1.dll
Normal file → Executable file
BIN
bin/lua51.dll
Normal file
BIN
bin/lua51.dll
Normal file
Binary file not shown.
BIN
bin/winapi.dll
BIN
bin/winapi.dll
Binary file not shown.
BIN
bin/wx.dll
Normal file → Executable file
BIN
bin/wx.dll
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.
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.
142
build/CMakeLists.txt
Normal file
142
build/CMakeLists.txt
Normal file
@@ -0,0 +1,142 @@
|
||||
# setup the minimum allowed CMake version
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
# set the default build type (this needs to be done *before* project command)
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE)
|
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "RelWithDebInfo" "MinSizeRel")
|
||||
endif()
|
||||
|
||||
# restrict configuration types to the selected build type
|
||||
set(CMAKE_CONFIGURATION_TYPES ${CMAKE_BUILD_TYPE} CACHE INTERNAL "" FORCE)
|
||||
|
||||
# set the project name
|
||||
project("zbstudio")
|
||||
|
||||
# set the top-level project directory relative to CMakeLists.txt location
|
||||
set(TOPDIR ..)
|
||||
|
||||
# checks if the Lua module is available
|
||||
function(check_lua_module MODULE)
|
||||
if(NOT ${MODULE}_FOUND)
|
||||
# find Lua executable at first
|
||||
find_program(LUA_EXECUTABLE "lua")
|
||||
if(NOT LUA_EXECUTABLE)
|
||||
message(FATAL_ERROR "Lua executable is not found")
|
||||
endif()
|
||||
|
||||
# run a short script with "require" statement to determine if the Lua module is available
|
||||
execute_process(COMMAND "${LUA_EXECUTABLE}" -e "require(\"${MODULE}\")"
|
||||
RESULT_VARIABLE EXIT_CODE OUTPUT_QUIET ERROR_QUIET)
|
||||
if(EXIT_CODE EQUAL 0)
|
||||
set(${MODULE}_FOUND TRUE CACHE INTERNAL "")
|
||||
message(STATUS "Found Lua module: ${MODULE}")
|
||||
elseif(ARGV1)
|
||||
message(FATAL_ERROR "Lua module \"${MODULE}\" is not found")
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# adds an user option to select between system-wide and bundled Lua module
|
||||
function(add_system_lua_module_option MODULE)
|
||||
string(TOUPPER ${MODULE} UPPERCASE_MODULE)
|
||||
if(NOT DEFINED USE_SYSTEM_${UPPERCASE_MODULE})
|
||||
option(USE_SYSTEM_${UPPERCASE_MODULE}
|
||||
"Use a system-wide \"${MODULE}\" Lua module instead of the bundled one." ${${MODULE}_FOUND})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# installs all files listed in the manifest
|
||||
function(install_from_manifest TYPE MANIFEST DESTDIR EXCLUDE_REGEX)
|
||||
file(STRINGS ${MANIFEST} PATTERN_LIST)
|
||||
foreach(PATTERN ${PATTERN_LIST})
|
||||
string(STRIP ${PATTERN} PATTERN)
|
||||
if(NOT PATTERN MATCHES ${EXCLUDE_REGEX})
|
||||
file(GLOB FILELIST RELATIVE "${CMAKE_SOURCE_DIR}/${TOPDIR}" "${CMAKE_SOURCE_DIR}/${TOPDIR}/${PATTERN}")
|
||||
foreach(FILENAME ${FILELIST})
|
||||
get_filename_component(FILEPATH ${FILENAME} PATH)
|
||||
install(${TYPE} ${TOPDIR}/${FILENAME} DESTINATION ${DESTDIR}/${FILEPATH})
|
||||
endforeach()
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
if(WIN32)
|
||||
# add the executable file to our project
|
||||
add_executable(zbstudio WIN32 ${TOPDIR}/build/win32_starter.c ${TOPDIR}/zbstudio/res/zbstudio.rc)
|
||||
|
||||
# link to the static multi-threaded CRT under MSVC
|
||||
if(MSVC)
|
||||
string(TOUPPER ${CMAKE_BUILD_TYPE} BUILD_TYPE)
|
||||
foreach(FLAGS_VAR CMAKE_C_FLAGS CMAKE_CXX_FLAGS CMAKE_C_FLAGS_${BUILD_TYPE} CMAKE_CXX_FLAGS_${BUILD_TYPE})
|
||||
string(REGEX REPLACE "/MD" "/MT" ${FLAGS_VAR} ${${FLAGS_VAR}})
|
||||
string(REGEX REPLACE "/MDd" "/MTd" ${FLAGS_VAR} ${${FLAGS_VAR}})
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# setup the data directory
|
||||
set(DATADIR .)
|
||||
|
||||
# install IDE executable
|
||||
install(TARGETS zbstudio DESTINATION ${DATADIR})
|
||||
|
||||
# install files from manifest
|
||||
install_from_manifest(FILES ${TOPDIR}/zbstudio/MANIFEST ${DATADIR} "^$")
|
||||
install_from_manifest(FILES ${TOPDIR}/zbstudio/MANIFEST-bin-win32 ${DATADIR} "^zbstudio.exe$")
|
||||
elseif(APPLE)
|
||||
# setup the data directory
|
||||
set(ROOTDIR ZeroBraneStudio.app/Contents)
|
||||
set(DATADIR ${ROOTDIR}/ZeroBraneStudio)
|
||||
|
||||
# install IDE shell script
|
||||
install(PROGRAMS ${TOPDIR}/zbstudio/ZeroBraneStudio.app/Contents/MacOS/ZeroBraneStudio DESTINATION ${ROOTDIR}/MacOS)
|
||||
|
||||
# install icon pack and .plist file
|
||||
install(DIRECTORY ${TOPDIR}/zbstudio/ZeroBraneStudio.app/Contents/Resources DESTINATION ${ROOTDIR})
|
||||
install(FILES ${TOPDIR}/zbstudio/ZeroBraneStudio.app/Contents/Info.plist DESTINATION ${ROOTDIR})
|
||||
|
||||
# install files from manifest
|
||||
install_from_manifest(FILES ${TOPDIR}/zbstudio/MANIFEST ${DATADIR} "^$")
|
||||
install_from_manifest(PROGRAMS ${TOPDIR}/zbstudio/MANIFEST-bin-macos ${DATADIR} "^$")
|
||||
else()
|
||||
# check the available Lua modules
|
||||
check_lua_module(wx TRUE)
|
||||
check_lua_module(socket TRUE)
|
||||
check_lua_module(copas ${USE_SYSTEM_COPAS})
|
||||
check_lua_module(luainspect ${USE_SYSTEM_LUAINSPECT})
|
||||
#check_lua_module(mobdebug ${USE_SYSTEM_MOBDEBUG})
|
||||
|
||||
# add user options to select between system-wide and bundled Lua modules
|
||||
add_system_lua_module_option(copas)
|
||||
add_system_lua_module_option(luainspect)
|
||||
#add_system_lua_module_option(mobdebug)
|
||||
|
||||
# setup the data directory
|
||||
set(DATADIR share/zbstudio)
|
||||
|
||||
# install IDE shell script
|
||||
set(IDE_DATADIR "${CMAKE_INSTALL_PREFIX}/${DATADIR}")
|
||||
configure_file(${TOPDIR}/zbstudio/zbstudio.in "${CMAKE_BINARY_DIR}/zbstudio")
|
||||
install(PROGRAMS "${CMAKE_BINARY_DIR}/zbstudio" DESTINATION bin)
|
||||
|
||||
# install bundled Lua modules
|
||||
if(NOT USE_SYSTEM_COPAS)
|
||||
install(DIRECTORY ${TOPDIR}/lualibs/copas ${TOPDIR}/lualibs/coxpcall DESTINATION ${DATADIR}/lualibs)
|
||||
endif()
|
||||
if(NOT USE_SYSTEM_LUAINSPECT)
|
||||
install(DIRECTORY ${TOPDIR}/lualibs/luainspect ${TOPDIR}/lualibs/metalua DESTINATION ${DATADIR}/lualibs)
|
||||
endif()
|
||||
if(NOT USE_SYSTEM_MOBDEBUG)
|
||||
install(DIRECTORY ${TOPDIR}/lualibs/mobdebug DESTINATION ${DATADIR}/lualibs)
|
||||
endif()
|
||||
|
||||
# install .desktop file and hicolor icon theme
|
||||
install(DIRECTORY ${TOPDIR}/zbstudio/res/icons/ DESTINATION share/icons/hicolor)
|
||||
install(FILES ${TOPDIR}/zbstudio/res/zbstudio.desktop DESTINATION share/applications)
|
||||
|
||||
# install miscellaneous documentation files
|
||||
install(FILES ${TOPDIR}/CHANGELOG.md ${TOPDIR}/LICENSE ${TOPDIR}/README.md DESTINATION share/doc/zbstudio)
|
||||
|
||||
# install files from manifest
|
||||
install_from_manifest(FILES ${TOPDIR}/zbstudio/MANIFEST ${DATADIR} "^(CHANGELOG.md|LICENSE|README.md)$|^lualibs/")
|
||||
endif()
|
||||
BIN
build/ZeroBraneStudio.dmg.bz2
Normal file
BIN
build/ZeroBraneStudio.dmg.bz2
Normal file
Binary file not shown.
42
build/build-dmg.sh
Executable file
42
build/build-dmg.sh
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/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}.
|
||||
4
build/install-deb.sh
Executable file
4
build/install-deb.sh
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
sudo apt-get install gdebi
|
||||
sudo gdebi wxlua*.deb
|
||||
@@ -4,7 +4,7 @@
|
||||
// (providing a single exe file in our main directory without
|
||||
// polluting it with all these dlls located in the /bin folder)
|
||||
|
||||
#ifdef __MINGW__ /* not sure if this is the *official* define */
|
||||
#ifdef __MINGW32__
|
||||
#define _WIN32_WINNT 0x0502
|
||||
#endif
|
||||
|
||||
BIN
build/wxlua28_2.8.12.2-1_i386.deb
Normal file
BIN
build/wxlua28_2.8.12.2-1_i386.deb
Normal file
Binary file not shown.
@@ -1,9 +1,15 @@
|
||||
local G = ... -- point to the global environment in the script
|
||||
-- update app configuration to load all tools, specs, and interpreters
|
||||
G.ide.app.loadfilters.tools = function() return true end
|
||||
G.ide.app.loadfilters.specs = function() return true end
|
||||
G.ide.app.loadfilters.interpreters = function() return true end
|
||||
|
||||
local luxpath = os.getenv("LUXINIA")
|
||||
path.luxinia = luxpath and luxpath.."/" or "../luxinia/engine/"
|
||||
local luxpath2 = os.getenv("LUXINIA2")
|
||||
path.luxinia2 = luxpath2 and luxpath2.."/" or "../luxinia2/runtime/bin_Windows_x86/"
|
||||
|
||||
interpreter = "estrelashell"
|
||||
interpreter = "luadeb"
|
||||
|
||||
editor.fontname = "Courier New"
|
||||
editor.caretline = true
|
||||
@@ -1,27 +1,53 @@
|
||||
--[[-- Rename this file to `user.lua` to get loaded
|
||||
--[[-- Copy required content from this file to `user.lua`
|
||||
|
||||
Configuration files are loaded in the following order
|
||||
|
||||
1. <application>\config.lua
|
||||
2. cfg\user.lua
|
||||
3. -cfg commandline strings
|
||||
3. ~\.zbstudio\user.lua
|
||||
4. -cfg commandline strings
|
||||
|
||||
--]]--
|
||||
|
||||
-- an example of how loaded configuration can be modified from this file
|
||||
|
||||
local G = ... -- this now points to the global environment in the script
|
||||
local luaspec = G.ide.specs['lua']
|
||||
luaspec.exts[2] = "luaz"
|
||||
luaspec.keywords[1] = luaspec.keywords[1] .. ' foo'
|
||||
-- change font size to 12
|
||||
editor.fontsize = 12 -- this is mapped to ide.config.editor.fontsize
|
||||
editor.fontname = "Courier New"
|
||||
filehistorylength = 20 -- this is mapped to ide.config.filehistorylength
|
||||
|
||||
-- these changes are going to be mapped to ide.config.editor...
|
||||
-- change encoding to Cyrillic
|
||||
editor.fontencoding = G.wx.wxFONTENCODING_ISO8859_5
|
||||
-- or WinCyrillic
|
||||
editor.fontencoding = G.wx.wxFONTENCODING_CP1251
|
||||
outputshell.fontencoding = G.wx.wxFONTENCODING_CP1251
|
||||
|
||||
-- specify full path to love2d executable; this is only needed
|
||||
-- specify full path to love2d *executable*; this is only needed
|
||||
-- if the game folder and the executable are NOT in the same folder.
|
||||
path.love2d = 'd:/lua/love/love' -- set the path of love executable
|
||||
path.love2d = 'd:/lua/love/love'
|
||||
|
||||
--]]--
|
||||
-- specify full path to moai *executable* if it's not in one of PATH folders
|
||||
path.moai = 'd:/lua/moai/moai'
|
||||
|
||||
-- specify full path to gideros *executable* if it's not in one of PATH folders
|
||||
path.gideros = 'd:/Program Files/Gideros/GiderosPlayer.exe'
|
||||
|
||||
-- specify full path to lua interpreter if you need to use your own version
|
||||
path.lua = 'd:/lua/lua'
|
||||
|
||||
-- fix an issue with 0d0d0a line endings in MOAI examples,
|
||||
-- which may negatively affect breakpoints during debugging
|
||||
editor.iofilter = "0d0d0aFix"
|
||||
|
||||
-- to have 4 spaces when TAB is used in the editor
|
||||
editor.tabwidth = 4
|
||||
|
||||
-- to have TABs stored in the file (to allow mixing tabs and spaces)
|
||||
editor.usetabs = true
|
||||
|
||||
-- to disable wrapping of long lines in the editor
|
||||
editor.usewrap = false
|
||||
|
||||
-- to turn dynamic words on and to start suggestions after 4 characters
|
||||
acandtip.nodynwords = false
|
||||
acandtip.startat = 4
|
||||
|
||||
-- to automatically open files requested during debugging
|
||||
editor.autoactivate = true
|
||||
|
||||
-- specify a list of MOAI entrypoints
|
||||
moai = { entrypoints = { "main.lua", "source/main.lua" } }
|
||||
|
||||
BIN
estrela.exe
BIN
estrela.exe
Binary file not shown.
@@ -1,29 +0,0 @@
|
||||
local ide = ide
|
||||
local app = {
|
||||
|
||||
loadfilters = {
|
||||
tools = function(file) return true end,
|
||||
specs = function(file) return true end,
|
||||
interpreters = function(file) return true end,
|
||||
},
|
||||
|
||||
postinit = function ()
|
||||
dofile("estrela/menu_help.lua")
|
||||
|
||||
local icon = wx.wxIcon()
|
||||
icon:LoadFile("estrela/res/estrela.ico",wx.wxBITMAP_TYPE_ICO)
|
||||
ide.frame:SetIcon(icon)
|
||||
end,
|
||||
|
||||
stringtable = {
|
||||
editor = "Estrela Editor",
|
||||
about = "About Estrela Editor",
|
||||
editormessage = "Estrela Editor Message",
|
||||
statuswelcome = "Welcome to Estrela Editor",
|
||||
settingsapp = "EstrelaEditor",
|
||||
settingsvendor = "LuxiniaDev",
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
return app
|
||||
@@ -1,54 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<CodeBlocks_project_file>
|
||||
<FileVersion major="1" minor="6" />
|
||||
<Project>
|
||||
<Option title="starter" />
|
||||
<Option pch_mode="2" />
|
||||
<Option compiler="gcc" />
|
||||
<Build>
|
||||
<Target title="Debug">
|
||||
<Option output="..\..\estrela" prefix_auto="1" extension_auto="1" />
|
||||
<Option working_dir="..\..\" />
|
||||
<Option object_output="obj\Debug\" />
|
||||
<Option type="1" />
|
||||
<Option compiler="gcc" />
|
||||
<Option use_console_runner="0" />
|
||||
<Compiler>
|
||||
<Add option="-g" />
|
||||
</Compiler>
|
||||
</Target>
|
||||
<Target title="Release">
|
||||
<Option output="..\..\estrela" prefix_auto="1" extension_auto="1" />
|
||||
<Option working_dir="..\..\" />
|
||||
<Option object_output="obj\Release\" />
|
||||
<Option type="0" />
|
||||
<Option compiler="gcc" />
|
||||
<Compiler>
|
||||
<Add option="-O2" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-s" />
|
||||
</Linker>
|
||||
</Target>
|
||||
</Build>
|
||||
<Compiler>
|
||||
<Add option="-Wall" />
|
||||
<Add option="-D__MINGW__" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add library="kernel32" />
|
||||
</Linker>
|
||||
<Unit filename="..\res\estrela.ico" />
|
||||
<Unit filename="..\res\estrela.rc">
|
||||
<Option compilerVar="WINDRES" />
|
||||
</Unit>
|
||||
<Unit filename="..\win32_starter.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Extensions>
|
||||
<code_completion />
|
||||
<envvars />
|
||||
<debugger />
|
||||
</Extensions>
|
||||
</Project>
|
||||
</CodeBlocks_project_file>
|
||||
@@ -1,212 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Name="estrela_editor"
|
||||
ProjectGUID="{065C5DC6-EAE4-4A57-9069-39810D816C41}"
|
||||
RootNamespace="luxinia_glfw"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="131072"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies=""
|
||||
OutputFile="../../estrela.exe"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories=""
|
||||
IgnoreDefaultLibraryNames="libc"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(TargetPath).pdb"
|
||||
SubSystem="2"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;"
|
||||
RuntimeLibrary="0"
|
||||
EnableEnhancedInstructionSet="0"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies=""
|
||||
OutputFile="../../estrela.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories=""
|
||||
GenerateManifest="true"
|
||||
IgnoreAllDefaultLibraries="false"
|
||||
IgnoreDefaultLibraryNames=""
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(TargetPath).pdb"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="0"
|
||||
EnableCOMDATFolding="0"
|
||||
RandomizedBaseAddress="0"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Sources"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\win32_starter.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Ressourcendateien"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\res\estrela.rc"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -1,113 +0,0 @@
|
||||
-- authors: Lomtik Software (J. Winwood & John Labenski)
|
||||
-- Luxinia Dev (Eike Decker & Christoph Kubisch)
|
||||
---------------------------------------------------------
|
||||
local ide = ide
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Create the Help menu and attach the callback functions
|
||||
|
||||
local frame = ide.frame
|
||||
local menuBar = frame.menuBar
|
||||
|
||||
local helpMenu = wx.wxMenu{
|
||||
{ ID_ABOUT, "&About\tF1", "About Estrela Editor" },
|
||||
}
|
||||
menuBar:Append(helpMenu, "&Help")
|
||||
|
||||
local function DisplayAbout(event)
|
||||
local page = [[
|
||||
<html>
|
||||
<body bgcolor = "#ffffff" text='#ffffff'>
|
||||
<table border='0' width="100%">
|
||||
<tr><td><img src = "estrela/res/estrela.png"></center></td><td>
|
||||
<table cellspacing = 4 cellpadding = 4 width = "400">
|
||||
<tr>
|
||||
<td bgcolor = "#010156">
|
||||
<center>
|
||||
<font size = +2 color = "#FFFFFF"><br><b>]]..
|
||||
wxlua.wxLUA_VERSION_STRING..[[</b></font>
|
||||
<font size = +1 color = "#FFFFFF">built with</font>
|
||||
<font size = +2 color = "#FFFFFF"><b>]]..
|
||||
wx.wxVERSION_STRING..[[</b></font>
|
||||
</center>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td bgcolor = "#4747A1">
|
||||
<b>Estrela Editor</b><br>
|
||||
<b><font color='#ffffff'>Copyright © 2008-2011 Luxinia DevTeam</font></b>
|
||||
<p>
|
||||
<font size=-1>
|
||||
<table cellpadding = 0 cellspacing = 0 width = "100%">
|
||||
<tr>
|
||||
<td width = "65%">
|
||||
Christoph Kubisch<br>
|
||||
Eike Decker<p>
|
||||
</td>
|
||||
<td valign = top>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<font size = 1>
|
||||
Licensed under The MIT License.
|
||||
</font>
|
||||
</font>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td bgcolor = "#4747A1">
|
||||
<b>based on wxLua editor sample</b><br>
|
||||
<b>Copyright © 2002-2005 Lomtick Software</b>
|
||||
<p>
|
||||
<font size=-1>
|
||||
<table cellpadding = 0 cellspacing = 0 width = "100%">
|
||||
<tr>
|
||||
<td width = "65%">
|
||||
J. Winwood (luascript@thersgb.net)<br>
|
||||
John Labenski<p>
|
||||
</td>
|
||||
<td valign = top>
|
||||
<img src = "estrela/res/wxlualogo2.png">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<font size = 1>
|
||||
wxLua binding licensed under wxWindows Library License, Version 3.
|
||||
</font>
|
||||
</font>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td></tr></table>
|
||||
</body>
|
||||
</html>
|
||||
]]
|
||||
|
||||
local dlg = wx.wxDialog(frame, wx.wxID_ANY, "About Estrela Editor")
|
||||
|
||||
local html = wx.wxLuaHtmlWindow(dlg, wx.wxID_ANY,
|
||||
wx.wxDefaultPosition, wx.wxSize(500, 270),
|
||||
wx.wxHW_SCROLLBAR_NEVER)
|
||||
local line = wx.wxStaticLine(dlg, wx.wxID_ANY)
|
||||
local button = wx.wxButton(dlg, wx.wxID_OK, "OK")
|
||||
|
||||
button:SetDefault()
|
||||
|
||||
html:SetBorders(0)
|
||||
html:SetPage(page)
|
||||
html:SetSize(html:GetInternalRepresentation():GetWidth(),
|
||||
html:GetInternalRepresentation():GetHeight())
|
||||
|
||||
local topsizer = wx.wxBoxSizer(wx.wxVERTICAL)
|
||||
topsizer:Add(html, 1, wx.wxALL, 10)
|
||||
topsizer:Add(line, 0, wx.wxEXPAND + wx.wxLEFT + wx.wxRIGHT, 10)
|
||||
topsizer:Add(button, 0, wx.wxALL + wx.wxALIGN_RIGHT, 10)
|
||||
|
||||
dlg:SetAutoLayout(true)
|
||||
dlg:SetSizer(topsizer)
|
||||
topsizer:Fit(dlg)
|
||||
|
||||
dlg:ShowModal()
|
||||
dlg:Destroy()
|
||||
end
|
||||
|
||||
frame:Connect(ID_ABOUT, wx.wxEVT_COMMAND_MENU_SELECTED, DisplayAbout)
|
||||
@@ -1,20 +0,0 @@
|
||||
Estrela Editor
|
||||
-----------------
|
||||
Estrela Editor is a wxLua based IDE. It supports multiple
|
||||
fileformats, "api" for autocompletion and tooltips, and custom
|
||||
commandline tools. Focus is extensibility for target applications
|
||||
using Lua. Its main purpose is as IDE for the 3D engine "Luxinia".
|
||||
|
||||
|
||||
|
||||
Commandline:
|
||||
------------
|
||||
|
||||
Open File(s):
|
||||
<exe> <filename> [<filename>...]
|
||||
any non-option will be treated as filename
|
||||
|
||||
Overriding Config:
|
||||
<exe> [...] -cfg "<luacode overriding config>" [...]
|
||||
e.g.: estrela.exe -cfg "singleinstance=false;" somefile.lua
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 290 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 47 KiB |
@@ -1 +0,0 @@
|
||||
icon ICON "../res/estrela.ico"
|
||||
@@ -1,706 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
id="svg2178"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.46+devel"
|
||||
width="146"
|
||||
height="146"
|
||||
version="1.0"
|
||||
sodipodi:docname="idelogo.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
inkscape:export-filename="D:\dev\c\tools\wxide\res\estrela.png"
|
||||
inkscape:export-xdpi="36.990002"
|
||||
inkscape:export-ydpi="36.990002">
|
||||
<metadata
|
||||
id="metadata2183">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs2181">
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 73 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="146 : 73 : 1"
|
||||
inkscape:persp3d-origin="73 : 48.666667 : 1"
|
||||
id="perspective86" />
|
||||
<linearGradient
|
||||
id="linearGradient4596">
|
||||
<stop
|
||||
style="stop-color:#5151ac;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4598" />
|
||||
<stop
|
||||
style="stop-color:#000055;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop4600" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4588">
|
||||
<stop
|
||||
style="stop-color:#62769d;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4590" />
|
||||
<stop
|
||||
style="stop-color:#ff0000;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop4592" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient5185">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5187" />
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop5189" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient2237">
|
||||
<stop
|
||||
style="stop-color:#0d0d3f;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop2239" />
|
||||
<stop
|
||||
id="stop3702"
|
||||
offset="0.33628318"
|
||||
style="stop-color:#12127a;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#3e3e80;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop2241" />
|
||||
</linearGradient>
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
x="-0.13963953"
|
||||
width="1.279279"
|
||||
y="-0.14821953"
|
||||
height="1.2964391"
|
||||
id="filter3840">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="6.5521521"
|
||||
id="feGaussianBlur3842" />
|
||||
</filter>
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter6278">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="2.214876"
|
||||
id="feGaussianBlur6280" />
|
||||
</filter>
|
||||
<mask
|
||||
maskUnits="userSpaceOnUse"
|
||||
id="mask6290">
|
||||
<rect
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline"
|
||||
id="rect6292"
|
||||
width="128"
|
||||
height="128"
|
||||
x="0"
|
||||
y="-8.5265128e-014"
|
||||
ry="13.206349"
|
||||
inkscape:export-filename="c:\temp\logotest"
|
||||
inkscape:export-xdpi="300"
|
||||
inkscape:export-ydpi="300" />
|
||||
</mask>
|
||||
<mask
|
||||
maskUnits="userSpaceOnUse"
|
||||
id="mask6295">
|
||||
<rect
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline"
|
||||
id="rect6297"
|
||||
width="128"
|
||||
height="128"
|
||||
x="0"
|
||||
y="-8.5265128e-014"
|
||||
ry="13.206349"
|
||||
inkscape:export-filename="c:\temp\logotest"
|
||||
inkscape:export-xdpi="300"
|
||||
inkscape:export-ydpi="300" />
|
||||
</mask>
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter6316">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="0.6425"
|
||||
id="feGaussianBlur6318" />
|
||||
</filter>
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
x="-0.096865753"
|
||||
width="1.1937315"
|
||||
y="-0.13864499"
|
||||
height="1.27729"
|
||||
id="filter6400">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="5.3595156"
|
||||
id="feGaussianBlur6402" />
|
||||
</filter>
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
x="-0.091426807"
|
||||
width="1.1828536"
|
||||
y="-0.21857401"
|
||||
height="1.437148"
|
||||
id="filter6510">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="4.3854492"
|
||||
id="feGaussianBlur6512" />
|
||||
</filter>
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
x="-0.065166176"
|
||||
width="1.1303324"
|
||||
y="-0.14160248"
|
||||
height="1.283205"
|
||||
id="filter6588">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="3.0129427"
|
||||
id="feGaussianBlur6590" />
|
||||
</filter>
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
x="-0.10324995"
|
||||
width="1.2064999"
|
||||
y="-0.19036609"
|
||||
height="1.3807322"
|
||||
id="filter6628">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="5.1083162"
|
||||
id="feGaussianBlur6630" />
|
||||
</filter>
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
x="-0.66312472"
|
||||
width="2.3262494"
|
||||
y="-0.13057123"
|
||||
height="1.2611425"
|
||||
id="filter6690">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="2.059841"
|
||||
id="feGaussianBlur6692" />
|
||||
</filter>
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
x="-0.75290101"
|
||||
width="2.505802"
|
||||
y="-0.11094242"
|
||||
height="1.2218848"
|
||||
id="filter6776">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="2.1015794"
|
||||
id="feGaussianBlur6778" />
|
||||
</filter>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4596"
|
||||
id="linearGradient4602"
|
||||
x1="63.296463"
|
||||
y1="141"
|
||||
x2="63.296463"
|
||||
y2="-5.0469656"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(13.788582,2.1213203)" />
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter3377"
|
||||
x="-0.1015625"
|
||||
width="1.203125"
|
||||
y="-0.087053571"
|
||||
height="1.1741071">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="2.7929688"
|
||||
id="feGaussianBlur3379" />
|
||||
</filter>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4596"
|
||||
id="linearGradient3381"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.89166667,0,0,0.89166667,19.638582,9.162987)"
|
||||
x1="63.296463"
|
||||
y1="141"
|
||||
x2="63.296463"
|
||||
y2="-5.0469656" />
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter3419"
|
||||
x="-0.10422356"
|
||||
width="1.2084471"
|
||||
y="-0.093260085"
|
||||
height="1.1865202">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="4.0324593"
|
||||
id="feGaussianBlur3421" />
|
||||
</filter>
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter3425"
|
||||
x="-0.12187501"
|
||||
width="1.24375"
|
||||
y="-0.10446428"
|
||||
height="1.2089286">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="2.9431967"
|
||||
id="feGaussianBlur3427" />
|
||||
</filter>
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter3451"
|
||||
x="-0.1187245"
|
||||
width="1.237449"
|
||||
y="-0.12130321"
|
||||
height="1.2426064">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="7.6549135"
|
||||
id="feGaussianBlur3453" />
|
||||
</filter>
|
||||
<filter
|
||||
height="1.3165256"
|
||||
y="-0.15826278"
|
||||
width="1.3097967"
|
||||
x="-0.15489837"
|
||||
id="filter3467"
|
||||
inkscape:collect="always">
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur3469"
|
||||
stdDeviation="9.98727"
|
||||
inkscape:collect="always" />
|
||||
</filter>
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter3483"
|
||||
x="-0.27362286"
|
||||
width="1.5472457"
|
||||
y="-0.27956598"
|
||||
height="1.559132">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="17.642184"
|
||||
id="feGaussianBlur3485" />
|
||||
</filter>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4596"
|
||||
id="linearGradient3497"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.9558335,0,0,0.9558335,16.173573,4.9921428)"
|
||||
x1="63.296463"
|
||||
y1="141"
|
||||
x2="63.296463"
|
||||
y2="-5.0469656" />
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter3499"
|
||||
x="-0.059528317"
|
||||
width="1.1190566"
|
||||
y="-0.10133829"
|
||||
height="1.2026766">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="1.667066"
|
||||
id="feGaussianBlur3501" />
|
||||
</filter>
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter3509"
|
||||
x="-0.0309375"
|
||||
width="1.061875"
|
||||
y="-2.0109374"
|
||||
height="5.0218749">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="1.3472814"
|
||||
id="feGaussianBlur3511" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
inkscape:window-height="719"
|
||||
inkscape:window-width="1024"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0"
|
||||
guidetolerance="10.0"
|
||||
gridtolerance="10.0"
|
||||
objecttolerance="10.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#ffffff"
|
||||
id="base"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="74.122861"
|
||||
inkscape:cy="61.737644"
|
||||
inkscape:window-x="-4"
|
||||
inkscape:window-y="-4"
|
||||
inkscape:current-layer="layer2"
|
||||
showborder="true"
|
||||
inkscape:showpageshadow="false"
|
||||
showgrid="false" />
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
style="opacity:0.34615383;display:none"
|
||||
transform="translate(6,5)">
|
||||
<image
|
||||
xlink:href="c:\temp\luxlogo.png"
|
||||
sodipodi:absref="c:\temp\luxlogo.png"
|
||||
width="128"
|
||||
height="128"
|
||||
id="image2185"
|
||||
x="0"
|
||||
y="0" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
style="display:inline"
|
||||
transform="translate(6,5)">
|
||||
<rect
|
||||
y="4.7046537"
|
||||
x="14.288583"
|
||||
height="124.83334"
|
||||
width="107"
|
||||
id="rect3423"
|
||||
style="opacity:1;fill:url(#linearGradient3381);fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter3425)"
|
||||
transform="matrix(1.0719628,0,0,1.0719628,-4.8782561,-4.8302384)"
|
||||
inkscape:export-filename="D:\dev\c\tools\wxide\res\estrela.png"
|
||||
inkscape:export-xdpi="181.25587"
|
||||
inkscape:export-ydpi="181.25587" />
|
||||
<rect
|
||||
style="opacity:1;fill:url(#linearGradient3497);fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
id="rect4586"
|
||||
width="114.70002"
|
||||
height="133.8167"
|
||||
x="10.438573"
|
||||
y="0.21297537"
|
||||
inkscape:export-filename="D:\dev\c\tools\wxide\res\estrela.png"
|
||||
inkscape:export-xdpi="181.25587"
|
||||
inkscape:export-ydpi="181.25587" />
|
||||
<g
|
||||
id="g3227"
|
||||
transform="matrix(0.36255137,0,0,0.36255137,43.548278,21.953343)"
|
||||
inkscape:export-filename="D:\dev\c\tools\wxide\res\estrela.png"
|
||||
inkscape:export-xdpi="181.25587"
|
||||
inkscape:export-ydpi="181.25587">
|
||||
<g
|
||||
id="g2599"
|
||||
transform="matrix(0.73621364,0,0,0.73621364,15.540372,-36.334537)">
|
||||
<path
|
||||
sodipodi:nodetypes="csscssc"
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="M 19.37247,3.0246539 C -16.608082,20.649318 -41.404147,57.657551 -41.404147,100.40056 c 0,59.80351 48.5400427,108.34356 108.343566,108.34356 40.892381,0 76.510811,-22.69984 94.952061,-56.1714 -15.59146,8.96867 -33.63299,14.11858 -52.89924,14.11858 C 50.276054,166.69131 2.5877015,119.06356 2.5877015,60.347369 c 0,-21.110232 6.1656802,-40.772917 16.7847685,-57.3227151 z"
|
||||
id="path2193"
|
||||
inkscape:export-filename="c:\temp\logotest"
|
||||
inkscape:export-xdpi="300"
|
||||
inkscape:export-ydpi="300" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-rule:evenodd;stroke:none"
|
||||
d="m 46.59366,22.910342 11.81888,0 9.19246,-10.505671 5.252837,14.445294 11.818878,1.969814 -11.818878,9.192463 0.656603,13.132087 -11.81888,-9.849067 -11.818877,3.939627 4.59623,-11.818877 -7.879253,-10.50567 z"
|
||||
id="path2205"
|
||||
inkscape:export-filename="c:\temp\logotest"
|
||||
inkscape:export-xdpi="300"
|
||||
inkscape:export-ydpi="300" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-rule:evenodd;stroke:none"
|
||||
d="m 113.62886,82.661339 13.7887,-14.445296 -5.25284,-19.69813 18.38488,8.535854 15.10187,-10.505668 -1.9698,19.698131 15.1019,12.475482 -19.04153,4.596232 -7.87924,15.758505 -8.53582,-16.41511 -19.69812,0 z"
|
||||
id="path2207"
|
||||
inkscape:export-filename="c:\temp\logotest"
|
||||
inkscape:export-xdpi="300"
|
||||
inkscape:export-ydpi="300" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-rule:evenodd;stroke:none;display:inline"
|
||||
d="m 84.710796,92.101734 3.261705,-2.372978 0.427566,-4.744945 4.349957,2.931871 3.6572,-1.829365 -1.416054,4.909864 2.817849,3.492287 -5.239188,-0.345107 -2.470713,3.460214 -1.104536,-4.184532 -4.283786,-1.317309 z"
|
||||
id="path2209"
|
||||
inkscape:export-filename="c:\temp\logotest"
|
||||
inkscape:export-xdpi="300"
|
||||
inkscape:export-ydpi="300" />
|
||||
</g>
|
||||
</g>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:29.89867401px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:100%;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Palatino Linotype;-inkscape-font-specification:Palatino Linotype"
|
||||
x="66.859642"
|
||||
y="95.922615"
|
||||
id="text2585"
|
||||
sodipodi:linespacing="100%"
|
||||
inkscape:export-filename="D:\dev\c\tools\wxide\res\estrela.png"
|
||||
inkscape:export-xdpi="181.25587"
|
||||
inkscape:export-ydpi="181.25587"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan2587"
|
||||
x="66.859642"
|
||||
y="95.922615">Estrela</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="66.859642"
|
||||
y="125.82129"
|
||||
id="tspan2589">Editor</tspan></text>
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;"
|
||||
id="rect3383"
|
||||
width="104.51637"
|
||||
height="1.6079443"
|
||||
x="15.530396"
|
||||
y="99.936134"
|
||||
inkscape:export-filename="D:\dev\c\tools\wxide\res\estrela.png"
|
||||
inkscape:export-xdpi="181.25587"
|
||||
inkscape:export-ydpi="181.25587" />
|
||||
<g
|
||||
transform="matrix(0.36255137,0,0,0.36255137,43.548278,21.953343)"
|
||||
id="g3439"
|
||||
style="filter:url(#filter3451)"
|
||||
inkscape:export-filename="D:\dev\c\tools\wxide\res\estrela.png"
|
||||
inkscape:export-xdpi="181.25587"
|
||||
inkscape:export-ydpi="181.25587">
|
||||
<g
|
||||
transform="matrix(0.73621364,0,0,0.73621364,15.540372,-36.334537)"
|
||||
id="g3441">
|
||||
<path
|
||||
inkscape:export-ydpi="300"
|
||||
inkscape:export-xdpi="300"
|
||||
inkscape:export-filename="c:\temp\logotest"
|
||||
id="path3443"
|
||||
d="M 19.37247,3.0246539 C -16.608082,20.649318 -41.404147,57.657551 -41.404147,100.40056 c 0,59.80351 48.5400427,108.34356 108.343566,108.34356 40.892381,0 76.510811,-22.69984 94.952061,-56.1714 -15.59146,8.96867 -33.63299,14.11858 -52.89924,14.11858 C 50.276054,166.69131 2.5877015,119.06356 2.5877015,60.347369 c 0,-21.110232 6.1656802,-40.772917 16.7847685,-57.3227151 z"
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
sodipodi:nodetypes="csscssc" />
|
||||
<path
|
||||
inkscape:export-ydpi="300"
|
||||
inkscape:export-xdpi="300"
|
||||
inkscape:export-filename="c:\temp\logotest"
|
||||
id="path3445"
|
||||
d="m 46.59366,22.910342 11.81888,0 9.19246,-10.505671 5.252837,14.445294 11.818878,1.969814 -11.818878,9.192463 0.656603,13.132087 -11.81888,-9.849067 -11.818877,3.939627 4.59623,-11.818877 -7.879253,-10.50567 z"
|
||||
style="fill:#ffffff;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
inkscape:export-ydpi="300"
|
||||
inkscape:export-xdpi="300"
|
||||
inkscape:export-filename="c:\temp\logotest"
|
||||
id="path3447"
|
||||
d="m 113.62886,82.661339 13.7887,-14.445296 -5.25284,-19.69813 18.38488,8.535854 15.10187,-10.505668 -1.9698,19.698131 15.1019,12.475482 -19.04153,4.596232 -7.87924,15.758505 -8.53582,-16.41511 -19.69812,0 z"
|
||||
style="fill:#ffffff;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
inkscape:export-ydpi="300"
|
||||
inkscape:export-xdpi="300"
|
||||
inkscape:export-filename="c:\temp\logotest"
|
||||
id="path3449"
|
||||
d="m 84.710796,92.101734 3.261705,-2.372978 0.427566,-4.744945 4.349957,2.931871 3.6572,-1.829365 -1.416054,4.909864 2.817849,3.492287 -5.239188,-0.345107 -2.470713,3.460214 -1.104536,-4.184532 -4.283786,-1.317309 z"
|
||||
style="fill:#ffffff;fill-rule:evenodd;stroke:none;display:inline" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
style="filter:url(#filter3467)"
|
||||
id="g3455"
|
||||
transform="matrix(0.36255137,0,0,0.36255137,43.548278,21.953343)"
|
||||
inkscape:export-filename="D:\dev\c\tools\wxide\res\estrela.png"
|
||||
inkscape:export-xdpi="181.25587"
|
||||
inkscape:export-ydpi="181.25587">
|
||||
<g
|
||||
id="g3457"
|
||||
transform="matrix(0.73621364,0,0,0.73621364,15.540372,-36.334537)">
|
||||
<path
|
||||
sodipodi:nodetypes="csscssc"
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="M 19.37247,3.0246539 C -16.608082,20.649318 -41.404147,57.657551 -41.404147,100.40056 c 0,59.80351 48.5400427,108.34356 108.343566,108.34356 40.892381,0 76.510811,-22.69984 94.952061,-56.1714 -15.59146,8.96867 -33.63299,14.11858 -52.89924,14.11858 C 50.276054,166.69131 2.5877015,119.06356 2.5877015,60.347369 c 0,-21.110232 6.1656802,-40.772917 16.7847685,-57.3227151 z"
|
||||
id="path3459"
|
||||
inkscape:export-filename="c:\temp\logotest"
|
||||
inkscape:export-xdpi="300"
|
||||
inkscape:export-ydpi="300" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-rule:evenodd;stroke:none"
|
||||
d="m 46.59366,22.910342 11.81888,0 9.19246,-10.505671 5.252837,14.445294 11.818878,1.969814 -11.818878,9.192463 0.656603,13.132087 -11.81888,-9.849067 -11.818877,3.939627 4.59623,-11.818877 -7.879253,-10.50567 z"
|
||||
id="path3461"
|
||||
inkscape:export-filename="c:\temp\logotest"
|
||||
inkscape:export-xdpi="300"
|
||||
inkscape:export-ydpi="300" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-rule:evenodd;stroke:none"
|
||||
d="m 113.62886,82.661339 13.7887,-14.445296 -5.25284,-19.69813 18.38488,8.535854 15.10187,-10.505668 -1.9698,19.698131 15.1019,12.475482 -19.04153,4.596232 -7.87924,15.758505 -8.53582,-16.41511 -19.69812,0 z"
|
||||
id="path3463"
|
||||
inkscape:export-filename="c:\temp\logotest"
|
||||
inkscape:export-xdpi="300"
|
||||
inkscape:export-ydpi="300" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-rule:evenodd;stroke:none;display:inline"
|
||||
d="m 84.710796,92.101734 3.261705,-2.372978 0.427566,-4.744945 4.349957,2.931871 3.6572,-1.829365 -1.416054,4.909864 2.817849,3.492287 -5.239188,-0.345107 -2.470713,3.460214 -1.104536,-4.184532 -4.283786,-1.317309 z"
|
||||
id="path3465"
|
||||
inkscape:export-filename="c:\temp\logotest"
|
||||
inkscape:export-xdpi="300"
|
||||
inkscape:export-ydpi="300" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.36255137,0,0,0.36255137,43.548278,21.953343)"
|
||||
id="g3471"
|
||||
style="filter:url(#filter3483)"
|
||||
inkscape:export-filename="D:\dev\c\tools\wxide\res\estrela.png"
|
||||
inkscape:export-xdpi="181.25587"
|
||||
inkscape:export-ydpi="181.25587">
|
||||
<g
|
||||
transform="matrix(0.73621364,0,0,0.73621364,15.540372,-36.334537)"
|
||||
id="g3473">
|
||||
<path
|
||||
inkscape:export-ydpi="300"
|
||||
inkscape:export-xdpi="300"
|
||||
inkscape:export-filename="c:\temp\logotest"
|
||||
id="path3475"
|
||||
d="M 19.37247,3.0246539 C -16.608082,20.649318 -41.404147,57.657551 -41.404147,100.40056 c 0,59.80351 48.5400427,108.34356 108.343566,108.34356 40.892381,0 76.510811,-22.69984 94.952061,-56.1714 -15.59146,8.96867 -33.63299,14.11858 -52.89924,14.11858 C 50.276054,166.69131 2.5877015,119.06356 2.5877015,60.347369 c 0,-21.110232 6.1656802,-40.772917 16.7847685,-57.3227151 z"
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
sodipodi:nodetypes="csscssc" />
|
||||
<path
|
||||
inkscape:export-ydpi="300"
|
||||
inkscape:export-xdpi="300"
|
||||
inkscape:export-filename="c:\temp\logotest"
|
||||
id="path3477"
|
||||
d="m 46.59366,22.910342 11.81888,0 9.19246,-10.505671 5.252837,14.445294 11.818878,1.969814 -11.818878,9.192463 0.656603,13.132087 -11.81888,-9.849067 -11.818877,3.939627 4.59623,-11.818877 -7.879253,-10.50567 z"
|
||||
style="fill:#ffffff;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
inkscape:export-ydpi="300"
|
||||
inkscape:export-xdpi="300"
|
||||
inkscape:export-filename="c:\temp\logotest"
|
||||
id="path3479"
|
||||
d="m 113.62886,82.661339 13.7887,-14.445296 -5.25284,-19.69813 18.38488,8.535854 15.10187,-10.505668 -1.9698,19.698131 15.1019,12.475482 -19.04153,4.596232 -7.87924,15.758505 -8.53582,-16.41511 -19.69812,0 z"
|
||||
style="fill:#ffffff;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
inkscape:export-ydpi="300"
|
||||
inkscape:export-xdpi="300"
|
||||
inkscape:export-filename="c:\temp\logotest"
|
||||
id="path3481"
|
||||
d="m 84.710796,92.101734 3.261705,-2.372978 0.427566,-4.744945 4.349957,2.931871 3.6572,-1.829365 -1.416054,4.909864 2.817849,3.492287 -5.239188,-0.345107 -2.470713,3.460214 -1.104536,-4.184532 -4.283786,-1.317309 z"
|
||||
style="fill:#ffffff;fill-rule:evenodd;stroke:none;display:inline" />
|
||||
</g>
|
||||
</g>
|
||||
<text
|
||||
sodipodi:linespacing="100%"
|
||||
id="text3487"
|
||||
y="93.989136"
|
||||
x="66.922005"
|
||||
style="font-size:27.89152144999999900px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:100%;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Palatino Linotype;-inkscape-font-specification:Palatino Linotype;filter:url(#filter3499);opacity:1"
|
||||
xml:space="preserve"
|
||||
transform="matrix(1.0719628,0,0,1.0719628,-4.8782561,-4.8302384)"
|
||||
inkscape:export-filename="D:\dev\c\tools\wxide\res\estrela.png"
|
||||
inkscape:export-xdpi="181.25587"
|
||||
inkscape:export-ydpi="181.25587"><tspan
|
||||
y="93.989136"
|
||||
x="66.922005"
|
||||
id="tspan3489"
|
||||
sodipodi:role="line">Estrela</tspan><tspan
|
||||
id="tspan3491"
|
||||
y="121.88066"
|
||||
x="66.922005"
|
||||
sodipodi:role="line">Editor</tspan></text>
|
||||
<rect
|
||||
y="99.936134"
|
||||
x="15.530396"
|
||||
height="1.6079443"
|
||||
width="104.51637"
|
||||
id="rect3507"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;filter:url(#filter3509)"
|
||||
inkscape:export-xdpi="181.25587"
|
||||
inkscape:export-ydpi="181.25587"
|
||||
inkscape:export-filename="D:\dev\c\tools\wxide\res\estrela.png" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer4"
|
||||
inkscape:label="uninstall"
|
||||
style="opacity:0.87179488;display:none">
|
||||
<path
|
||||
style="opacity:0.90909095;fill:#ff0000;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6628)"
|
||||
d="M 14,129.5 C 14.336023,78.681123 10.223888,102.29852 28,126 C 30.459675,129.27957 31.666667,118.66667 33.5,115 C 34.280157,113.43969 60.370804,77.40912 51.5,105.5 C 50.690734,108.06268 52.166667,110.83333 52.5,113.5 C 53.627928,122.52343 58.069819,95.430181 64.5,89 C 77.260993,76.239007 72.034223,53.027263 77.5,84 C 81.920823,109.05133 73.638657,88.715336 86.5,85.5 C 115.4259,78.268526 69.170508,123.74712 95.5,104 C 128.78796,79.03403 116,64.235283 116,113.5 C 116,117.62311 118,105.5 119,101.5 C 121.13437,92.962501 126.33333,117.5 130,125.5 C 130.87839,127.41648 131.33333,121.5 132,119.5 C 133.424,115.228 131.66667,128.5 131.5,133"
|
||||
id="path6594"
|
||||
transform="matrix(1,0,0,1.6987359,0,-92.931881)" />
|
||||
<path
|
||||
style="opacity:0.81404952;fill:#ff0000;fill-rule:nonzero;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6400)"
|
||||
d="M 9.5,127 C 9.3333333,127 9.1666667,127 9,127 C 5.1450826,127 5,115.26288 5,113 C 5,108.88399 4.5,104.31286 4.5,100 C 4.5,90.729345 9.3911698,86.181384 14,78.5 C 16.525846,74.290257 21.294069,70.176551 23.5,66.5 C 24.010025,65.649958 19.12736,72.1816 18,75 C 16.175585,79.561038 16.938863,85.255452 18,89.5 C 19.417577,95.17031 20.550245,97.050245 24.5,101 C 27.204082,103.70408 28.564013,105.87197 30.5,102 C 32.717007,97.565986 32.821681,88.213274 34,83.5 C 36.21779,74.628838 33.5,60.648945 33.5,51.5 C 33.5,51.084452 43.746631,33.513476 40.5,46.5 C 37.526688,58.393246 42.328731,65.743097 48.5,75 C 57.52302,88.53453 51.657407,61.728395 65.5,52.5 C 75.452786,45.864809 69.5,56.563364 69.5,63.5 C 69.5,97.806907 73.726993,52.544988 80,63 C 104.74932,104.24887 98.5,68.637999 98.5,48 C 98.5,43.548461 105.9654,52.637713 112,63.5 C 131.67898,98.922169 101.60755,95.392446 125.5,71.5 C 131.39727,65.602731 126.5,88.160003 126.5,96.5 C 126.5,103.50198 126.00977,110.56839 127,117.5 C 127.95497,124.1848 139.22574,81.791102 137,108.5 C 136.48054,114.73353 136,120.29333 136,126.5 C 136,131.40801 136.45529,134 131,134 C 124.83333,134 118.66667,134 112.5,134 C 106.66667,134 100.83333,134 95,134 C 87.666667,134 80.333333,134 73,134 C 59.815481,134 46.676285,134.5 33.5,134.5 C 29,134.5 24.5,134.5 20,134.5 C 17.560468,134.5 15.299427,130.79943 14.5,130 C 12.881524,128.38152 11.876707,127.47534 9.5,127 z "
|
||||
id="path6360" />
|
||||
<path
|
||||
style="opacity:0.7892562;fill:#ffff00;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6510)"
|
||||
d="M 18,133 C 17.666667,128.16667 17.333333,123.33333 17,118.5 C 16.12131,105.759 12.392768,108.83915 20.5,121 C 26.928487,130.64273 27.121348,121.87865 34.5,114.5 C 40.14466,108.85534 28.809035,133.69097 46.5,116 C 69.437036,93.062964 57.251105,73.257733 62,106.5 C 62.141421,107.48995 62,108.5 62,109.5 C 62,116.18839 65.961948,99.019026 77,93.5 C 84.016889,89.991555 79.782388,94.911939 82,106 C 84.489642,118.44821 104.6601,90.259847 107.5,86 C 108.99663,83.755053 110.63899,106.80503 109.5,112.5 C 107.85301,120.73495 118.5,80.922943 118.5,109 C 118.5,136.59389 130.5,113.97346 130.5,123.5 C 130.5,126.59415 130.47115,131.64424 130,134"
|
||||
id="path6404" />
|
||||
<path
|
||||
style="opacity:0.47107436;fill:#ffff00;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6588)"
|
||||
d="M 23,129.5 C 23,132.18128 23.707157,117.52684 20.5,105.5 C 18.755021,98.956331 22.5,82.949866 22.5,98 C 22.5,101.13302 26.815124,126.46219 32,113.5 C 37.373635,100.06591 49.880495,78.048761 46.5,86.5 C 45.909734,87.975665 37.7573,136.7281 47.5,107.5 C 47.857122,106.42863 51.414918,124.58508 58,118 C 68.456644,107.54336 70,50.914151 70,100.5 C 70,131.81187 78.663987,96.334003 94,92.5 C 101.72907,90.567732 88.111037,107.55652 87.5,115.5 C 87.384247,117.00479 87.833333,118.5 88,120 C 89.236992,131.13293 100.98113,100.50944 111,95.5 C 121.54122,90.229389 111.5,106.05757 111.5,112 C 111.5,113.79505 112.83333,115.33333 113.5,117 C 114.6363,119.84076 116.5,111.66667 118,109 C 127.18664,92.668192 120.25003,138.81244 129.5,118 C 129.81325,117.2952 131,128.12728 131,131.5"
|
||||
id="path6514"
|
||||
transform="matrix(1,0,0,1.558102,0,-73.390417)" />
|
||||
<path
|
||||
style="opacity:0.73966944;fill:#ffa500;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6690)"
|
||||
d="M 98.5,75 C 103.15482,68.57691 90.320092,24.848129 101.5,40.5 C 102.88049,42.432688 106.61962,69.035283 102,72.5 C 100.85302,73.360232 99.666667,74.166667 98.5,75 z "
|
||||
id="path6632" />
|
||||
<path
|
||||
style="opacity:0.94214872;fill:#ffba00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6776)"
|
||||
d="M 51,68 C 45.233621,73.766379 50.387595,36.449622 50.5,36 C 53.115126,25.539495 57.714899,13.962753 49.5,34.5 C 44.403872,47.24032 50.084923,57.754768 53.5,68 C 53.763523,68.790569 51.833333,68 51,68 z "
|
||||
id="path6696" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer3"
|
||||
inkscape:label="border"
|
||||
style="display:none">
|
||||
<rect
|
||||
transform="translate(6,5)"
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline;filter:url(#filter6316)"
|
||||
id="rect6282"
|
||||
width="128"
|
||||
height="128"
|
||||
x="0"
|
||||
y="-8.5265128e-014"
|
||||
ry="13.206349"
|
||||
inkscape:export-filename="c:\temp\logotest"
|
||||
inkscape:export-xdpi="300"
|
||||
inkscape:export-ydpi="300" />
|
||||
<rect
|
||||
transform="translate(6,5)"
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:6;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline;filter:url(#filter6278)"
|
||||
id="rect4190"
|
||||
width="128"
|
||||
height="128"
|
||||
x="0"
|
||||
y="-8.5265128e-014"
|
||||
ry="13.206349"
|
||||
inkscape:export-filename="c:\temp\logotest"
|
||||
inkscape:export-xdpi="300"
|
||||
inkscape:export-ydpi="300"
|
||||
mask="url(#mask6290)" />
|
||||
<rect
|
||||
transform="translate(6,5)"
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline"
|
||||
id="rect5203"
|
||||
width="128"
|
||||
height="128"
|
||||
x="0"
|
||||
y="-8.5265128e-014"
|
||||
ry="13.206349"
|
||||
inkscape:export-filename="c:\temp\logotest"
|
||||
inkscape:export-xdpi="300"
|
||||
inkscape:export-ydpi="300"
|
||||
mask="url(#mask6295)" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 31 KiB |
@@ -1,132 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="204.22055"
|
||||
height="96.006279"
|
||||
id="svg3513"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.46+devel"
|
||||
version="1.0"
|
||||
inkscape:export-filename="D:\dev\c\tools\wxide\res\wxlualogo2.png"
|
||||
inkscape:export-xdpi="59.996075"
|
||||
inkscape:export-ydpi="59.996075"
|
||||
sodipodi:docname="wxlogo.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape">
|
||||
<defs
|
||||
id="defs3515">
|
||||
<linearGradient
|
||||
id="linearGradient3538">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3540" />
|
||||
<stop
|
||||
style="stop-color:#e3e3eb;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3542" />
|
||||
</linearGradient>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 526.18109 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||
id="perspective3521" />
|
||||
<inkscape:perspective
|
||||
id="perspective3530"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3538"
|
||||
id="linearGradient3544"
|
||||
x1="88.214287"
|
||||
y1="0.2142856"
|
||||
x2="88.214287"
|
||||
y2="81.130592"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter4057"
|
||||
x="-0.044305418"
|
||||
width="1.0886108"
|
||||
y="-0.10071105"
|
||||
height="1.2014221">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="2.2929748"
|
||||
id="feGaussianBlur4059" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="98.55416"
|
||||
inkscape:cy="58.784487"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1024"
|
||||
inkscape:window-height="719"
|
||||
inkscape:window-x="-4"
|
||||
inkscape:window-y="-4" />
|
||||
<metadata
|
||||
id="metadata3518">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Ebene 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-102.354,-435.00191)">
|
||||
<rect
|
||||
ry="12.142858"
|
||||
y="-1.9285716"
|
||||
x="-5"
|
||||
height="85"
|
||||
width="193.21428"
|
||||
id="rect3546"
|
||||
style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;filter:url(#filter4057)"
|
||||
transform="translate(112.85714,442.43362)" />
|
||||
<rect
|
||||
style="opacity:1;fill:url(#linearGradient3544);fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="rect3536"
|
||||
width="193.21428"
|
||||
height="85"
|
||||
x="-5"
|
||||
y="-1.9285716"
|
||||
transform="translate(112.85714,442.43362)"
|
||||
ry="12.142858" />
|
||||
<image
|
||||
y="442.43362"
|
||||
x="112.85714"
|
||||
id="image3532"
|
||||
height="77"
|
||||
width="180"
|
||||
sodipodi:absref="D:\dev\c\tools\wxide\res\wxlualogo.png"
|
||||
xlink:href="wxlualogo.png" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.9 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 7.7 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 6.4 KiB |
@@ -1,12 +0,0 @@
|
||||
return {
|
||||
name = "Estrela Editor",
|
||||
description = "Estrela Editor as run target (IDE development)",
|
||||
api = {"wxwidgets","baselib"},
|
||||
frun = function(self,wfilename)
|
||||
local cmd = ide.editorFilename and '"'..ide.editorFilename..'" '..(wfilename and wfilename:GetFullPath() or "")..' -cfg "singleinstance=false;"' or nil
|
||||
CommandLineRun(cmd,nil,false,true)
|
||||
end,
|
||||
fprojdir = function(self,wfilename)
|
||||
return wfilename:GetPath(wx.wxPATH_GET_VOLUME)
|
||||
end,
|
||||
}
|
||||
121
interpreters/gideros.lua
Normal file
121
interpreters/gideros.lua
Normal file
@@ -0,0 +1,121 @@
|
||||
local gideros
|
||||
local win = ide.osname == "Windows"
|
||||
local mac = ide.osname == "Macintosh"
|
||||
|
||||
return {
|
||||
name = "Gideros",
|
||||
description = "Gideros mobile platform",
|
||||
api = {"baselib", "gideros"},
|
||||
frun = function(self,wfilename,rundebug)
|
||||
gideros = gideros or ide.config.path.gideros -- check if the path is configured
|
||||
if not gideros then
|
||||
local sep = win and ';' or ':'
|
||||
local default =
|
||||
win and ([[C:\Program Files\Gideros]]..sep..[[D:\Program Files\Gideros]]..sep)
|
||||
or mac and ('/Applications/Gideros Studio/Gideros Player.app/Contents/MacOS'..sep)
|
||||
or ''
|
||||
local path = default
|
||||
..(os.getenv('PATH') or '')..sep
|
||||
..(os.getenv('HOME') and os.getenv('HOME') .. '/bin' or '')
|
||||
local paths = {}
|
||||
for p in path:gmatch("[^"..sep.."]+") do
|
||||
gideros = gideros or GetFullPathIfExists(p, win and 'GiderosPlayer.exe' or 'Gideros Player')
|
||||
table.insert(paths, p)
|
||||
end
|
||||
if not gideros then
|
||||
DisplayOutput("Can't find gideros executable in any of the folders in PATH: "
|
||||
..table.concat(paths, ", ").."\n")
|
||||
return
|
||||
end
|
||||
end
|
||||
if gideros and not wx.wxFileName(gideros):FileExists() then
|
||||
DisplayOutput("Can't find the specified gideros executable '"..gideros.."'.\n")
|
||||
return
|
||||
end
|
||||
|
||||
local giderostools = wx.wxFileName.DirName(wx.wxFileName(gideros)
|
||||
:GetPath(wx.wxPATH_GET_VOLUME)
|
||||
..(win and '/Tools' or '/../../../Gideros Studio.app/Contents/Tools'))
|
||||
giderostools:Normalize()
|
||||
local giderospath = giderostools:GetPath(wx.wxPATH_GET_VOLUME)
|
||||
local gdrbridge = GetFullPathIfExists(giderospath, win and 'gdrbridge.exe' or 'gdrbridge')
|
||||
if not gdrbridge then
|
||||
DisplayOutput("Can't find gideros bridge executable in '"..giderospath.."'.\n")
|
||||
return
|
||||
end
|
||||
|
||||
-- find *.gproj file in the project directory
|
||||
local file
|
||||
for _, proj in ipairs(FileSysGet(self:fworkdir(wfilename).."/*.gproj", wx.wxFILE)) do
|
||||
if file then
|
||||
DisplayOutput("Found multiple .gproj files in the project directory; ignored '"..proj.."'\n")
|
||||
end
|
||||
file = proj
|
||||
end
|
||||
if not file then
|
||||
DisplayOutput("Can't find gideros project file in the project directory.\n")
|
||||
return
|
||||
end
|
||||
|
||||
if rundebug then DebuggerAttachDefault() end
|
||||
|
||||
local cmd = ('"%s"'):format(gideros)
|
||||
-- CommandLineRun(cmd,wdir,tooutput,nohide,stringcallback,uid,endcallback)
|
||||
local pid = CommandLineRun(cmd,self:fworkdir(wfilename),not mac,true,nil,nil,
|
||||
function() ide.debugger.pid = nil end)
|
||||
|
||||
do
|
||||
DisplayOutput("Starting the player and waiting for the bridge to connect at '"..gdrbridge.."'.\n")
|
||||
local cmd = ('"%s" %s'):format(gdrbridge, 'isconnected')
|
||||
local attempts, connected = 12
|
||||
for _ = 1, attempts do
|
||||
local proc = wx.wxProcess()
|
||||
proc:Redirect()
|
||||
proc:Connect(wx.wxEVT_END_PROCESS, function(event) proc = nil end)
|
||||
local bid = wx.wxExecute(cmd, wx.wxEXEC_ASYNC + wx.wxEXEC_MAKE_GROUP_LEADER, proc)
|
||||
if not bid or bid == -1 or bid == 0 then
|
||||
DisplayOutput(("Program unable to run as '%s'\n"):format(cmd))
|
||||
return
|
||||
end
|
||||
|
||||
local streamin = proc:GetInputStream()
|
||||
for _ = 1, 20 do
|
||||
if streamin:CanRead() then
|
||||
connected = tonumber(streamin:Read(4096)) == 1
|
||||
break end
|
||||
wx.wxSafeYield()
|
||||
wx.wxWakeUpIdle()
|
||||
wx.wxMilliSleep(250)
|
||||
end
|
||||
|
||||
if connected then break end
|
||||
if connected == nil and proc then
|
||||
wx.wxProcess.Kill(bid, wx.wxSIGKILL, wx.wxKILL_CHILDREN)
|
||||
wx.wxProcess.Kill(pid, wx.wxSIGKILL, wx.wxKILL_CHILDREN)
|
||||
DisplayOutput("Couldn't connect to the player. Try again or check starting the player and the bridge manually.\n")
|
||||
return
|
||||
end
|
||||
end
|
||||
if not connected then
|
||||
wx.wxProcess.Kill(pid, wx.wxSIGKILL, wx.wxKILL_CHILDREN)
|
||||
DisplayOutput("Couldn't connect after "..attempts.." attempts. Try again or check starting the player manually.\n")
|
||||
return
|
||||
end
|
||||
|
||||
DisplayOutput("Starting project file '"..file.."'.\n")
|
||||
|
||||
cmd = ('"%s" %s "%s"'):format(gdrbridge, 'play', file)
|
||||
wx.wxExecute(cmd, wx.wxEXEC_ASYNC)
|
||||
end
|
||||
return pid
|
||||
end,
|
||||
fprojdir = function(self,wfilename)
|
||||
return wfilename:GetPath(wx.wxPATH_GET_VOLUME)
|
||||
end,
|
||||
fworkdir = function(self,wfilename)
|
||||
return ide.config.path.projectdir or wfilename:GetPath(wx.wxPATH_GET_VOLUME)
|
||||
end,
|
||||
hasdebugger = true,
|
||||
fattachdebug = function(self) DebuggerAttachDefault() end,
|
||||
scratchextloop = true,
|
||||
}
|
||||
@@ -1,14 +1,44 @@
|
||||
local love2d
|
||||
local win = ide.osname == "Windows"
|
||||
local mac = ide.osname == "Macintosh"
|
||||
|
||||
return {
|
||||
name = "Love2d",
|
||||
description = "Love2d game engine",
|
||||
api = {"baselib", "love2d"},
|
||||
frun = function(self,wfilename,rundebug)
|
||||
love2d = love2d or ide.config.path.love2d -- check if the path is configured
|
||||
if not love2d then
|
||||
local sep = win and ';' or ':'
|
||||
local default =
|
||||
win and ([[C:\Program Files\love]]..sep..[[D:\Program Files\love]]..sep)
|
||||
or mac and ('/Applications/love.app/Contents/MacOS'..sep)
|
||||
or ''
|
||||
local path = default
|
||||
..(os.getenv('PATH') or '')..sep
|
||||
..(GetPathWithSep(self:fworkdir(wfilename)))..sep
|
||||
..(os.getenv('HOME') and GetPathWithSep(os.getenv('HOME'))..'bin' or '')
|
||||
local paths = {}
|
||||
for p in path:gmatch("[^"..sep.."]+") do
|
||||
love2d = love2d or GetFullPathIfExists(p, win and 'love.exe' or 'love')
|
||||
table.insert(paths, p)
|
||||
end
|
||||
if not love2d then
|
||||
DisplayOutput("Can't find love2d executable in any of the following folders: "
|
||||
..table.concat(paths, ", ").."\n")
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if not GetFullPathIfExists(self:fworkdir(wfilename), 'main.lua') then
|
||||
DisplayOutput("Can't find 'main.lua' file in the current project folder.\n")
|
||||
return
|
||||
end
|
||||
|
||||
if rundebug then DebuggerAttachDefault() end
|
||||
local love2d = ide.config.path.love2d
|
||||
or wx.wxFileName(self:fprojdir(wfilename)):GetPath(wx.wxPATH_GET_VOLUME)
|
||||
.. '/love'
|
||||
local cmd = string.gsub(love2d, "\\","/") .. ' "' .. self:fprojdir(wfilename) .. '"'
|
||||
.. (rundebug and ' -debug' or '')
|
||||
|
||||
local cmd = ('"%s" "%s"%s'):format(love2d,
|
||||
self:fworkdir(wfilename), rundebug and ' -debug' or '')
|
||||
-- CommandLineRun(cmd,wdir,tooutput,nohide,stringcallback,uid,endcallback)
|
||||
return CommandLineRun(cmd,self:fworkdir(wfilename),true,false,nil,nil,
|
||||
function() ide.debugger.pid = nil end)
|
||||
@@ -16,12 +46,10 @@ return {
|
||||
fprojdir = function(self,wfilename)
|
||||
return wfilename:GetPath(wx.wxPATH_GET_VOLUME)
|
||||
end,
|
||||
fworkdir = function (self,wfilename)
|
||||
return ide.config.path.projectdir
|
||||
or wfilename:GetPath(wx.wxPATH_GET_VOLUME)
|
||||
fworkdir = function(self,wfilename)
|
||||
return ide.config.path.projectdir or wfilename:GetPath(wx.wxPATH_GET_VOLUME)
|
||||
end,
|
||||
hasdebugger = true,
|
||||
fattachdebug = function(self)
|
||||
DebuggerAttachDefault()
|
||||
end,
|
||||
fattachdebug = function(self) DebuggerAttachDefault() end,
|
||||
scratchextloop = true,
|
||||
}
|
||||
|
||||
@@ -1,23 +1,40 @@
|
||||
local exe
|
||||
|
||||
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
|
||||
|
||||
return {
|
||||
name = "Lua with Debugger",
|
||||
name = "Lua",
|
||||
description = "Lua interpreter with debugger",
|
||||
api = {"wxwidgets","baselib"},
|
||||
frun = function(self,wfilename,rundebug)
|
||||
local mainpath = string.gsub(ide.editorFilename:gsub("[^/\\]+$",""),"\\","/")
|
||||
local filepath = string.gsub(wfilename:GetFullPath(), "\\","/")
|
||||
exe = exe or exePath()
|
||||
local filepath = wfilename:GetFullPath()
|
||||
local script
|
||||
if rundebug then
|
||||
DebuggerAttachDefault()
|
||||
script = (
|
||||
"package.path=package.path..';"..mainpath.."lualibs/?/?.lua;"..mainpath.."lualibs/?.lua';"..
|
||||
"package.cpath=package.cpath..';"..mainpath.."bin/clibs/?.dll';"..
|
||||
rundebug
|
||||
)
|
||||
script = rundebug
|
||||
else
|
||||
script = ([[dofile '%s']]):format(filepath)
|
||||
-- if running on Windows and can't open the file, this may mean that
|
||||
-- the file path includes unicode characters that need special handling
|
||||
local fh = io.open(filepath, "r")
|
||||
if fh then fh:close() end
|
||||
if ide.osname == 'Windows' and pcall(require, "winapi")
|
||||
and wfilename:FileExists() and not fh then
|
||||
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 = '"'..mainpath..'bin/lua" -e "'..code..'"'
|
||||
local cmd = '"'..exe..'" -e "'..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)
|
||||
@@ -26,11 +43,9 @@ return {
|
||||
return wfilename:GetPath(wx.wxPATH_GET_VOLUME)
|
||||
end,
|
||||
fworkdir = function (self,wfilename)
|
||||
return ide.config.path.projectdir
|
||||
or wfilename:GetPath(wx.wxPATH_GET_VOLUME)
|
||||
return ide.config.path.projectdir or wfilename:GetPath(wx.wxPATH_GET_VOLUME)
|
||||
end,
|
||||
hasdebugger = true,
|
||||
fattachdebug = function(self)
|
||||
DebuggerAttachDefault()
|
||||
end,
|
||||
fattachdebug = function(self) DebuggerAttachDefault() end,
|
||||
scratchextloop = false,
|
||||
}
|
||||
|
||||
@@ -77,6 +77,7 @@ return {
|
||||
if not rundebug then
|
||||
local client = self:finitclient()
|
||||
ShellSupportRemote(client,self:fuid(wfilename))
|
||||
pid = nil
|
||||
end
|
||||
|
||||
return pid
|
||||
|
||||
88
interpreters/moai.lua
Normal file
88
interpreters/moai.lua
Normal file
@@ -0,0 +1,88 @@
|
||||
local moai
|
||||
local win = ide.osname == "Windows"
|
||||
|
||||
return {
|
||||
name = "Moai",
|
||||
description = "Moai mobile platform",
|
||||
api = {"baselib", "moai"},
|
||||
frun = function(self,wfilename,rundebug)
|
||||
moai = moai or ide.config.path.moai -- check if the path is configured
|
||||
if not moai then
|
||||
local sep = win and ';' or ':'
|
||||
local default =
|
||||
win and ([[C:\Program Files\moai]]..sep..[[D:\Program Files\moai]]..sep)
|
||||
or ''
|
||||
local path = default
|
||||
..(os.getenv('PATH') or '')..sep
|
||||
..(os.getenv('MOAI_BIN') or '')..sep
|
||||
..(os.getenv('HOME') and os.getenv('HOME') .. '/bin' or '')
|
||||
local paths = {}
|
||||
for p in path:gmatch("[^"..sep.."]+") do
|
||||
moai = moai or GetFullPathIfExists(p, win and 'moai.exe' or 'moai')
|
||||
table.insert(paths, p)
|
||||
end
|
||||
if not moai then
|
||||
DisplayOutput("Can't find moai executable in any of the folders in PATH or MOAI_BIN: "
|
||||
..table.concat(paths, ", ").."\n")
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local file
|
||||
local epoints = ide.config.moai and ide.config.moai.entrypoints
|
||||
if epoints then
|
||||
epoints = type(epoints) == 'table' and epoints or {epoints}
|
||||
for _,entry in pairs(epoints) do
|
||||
file = GetFullPathIfExists(self:fworkdir(wfilename), entry)
|
||||
if file then break end
|
||||
end
|
||||
if not file then
|
||||
DisplayOutput("Can't find any of the specified entry points ("
|
||||
..table.concat(epoints, ", ")
|
||||
..") in the current project; continuing with the current file...\n")
|
||||
end
|
||||
end
|
||||
|
||||
if rundebug then
|
||||
-- start running the application right away
|
||||
DebuggerAttachDefault({runstart=true, startwith = file})
|
||||
local code = (
|
||||
[[xpcall(function()
|
||||
io.stdout:setvbuf('no')
|
||||
require("mobdebug").moai() -- enable debugging for coroutines
|
||||
%s
|
||||
end, function(err) print(debug.traceback(err)) end)]]):format(rundebug)
|
||||
local tmpfile = wx.wxFileName()
|
||||
tmpfile:AssignTempFileName(".")
|
||||
file = tmpfile:GetFullPath()
|
||||
local f = io.open(file, "w")
|
||||
if not f then
|
||||
DisplayOutput("Can't open temporary file '"..file.."' for writing\n")
|
||||
return
|
||||
end
|
||||
f:write(code)
|
||||
f:close()
|
||||
end
|
||||
|
||||
file = file or wfilename:GetFullPath()
|
||||
|
||||
-- try to find a config file: (1) MOAI_CONFIG, (2) project directory,
|
||||
-- (3) folder with the current file, (4) folder with moai executable
|
||||
local config = GetFullPathIfExists(os.getenv('MOAI_CONFIG') or self:fworkdir(wfilename), 'config.lua')
|
||||
or GetFullPathIfExists(wfilename:GetPath(wx.wxPATH_GET_VOLUME), 'config.lua')
|
||||
or GetFullPathIfExists(wx.wxFileName(moai):GetPath(wx.wxPATH_GET_VOLUME), 'config.lua')
|
||||
local cmd = config and ('"%s" "%s" "%s"'):format(moai, config, file)
|
||||
or ('"%s" "%s"'):format(moai, file)
|
||||
-- CommandLineRun(cmd,wdir,tooutput,nohide,stringcallback,uid,endcallback)
|
||||
return CommandLineRun(cmd,self:fworkdir(wfilename),true,false,nil,nil,
|
||||
function() ide.debugger.pid = nil if rundebug then wx.wxRemoveFile(file) end end)
|
||||
end,
|
||||
fprojdir = function(self,wfilename)
|
||||
return wfilename:GetPath(wx.wxPATH_GET_VOLUME)
|
||||
end,
|
||||
fworkdir = function(self,wfilename)
|
||||
return ide.config.path.projectdir or wfilename:GetPath(wx.wxPATH_GET_VOLUME)
|
||||
end,
|
||||
hasdebugger = true,
|
||||
fattachdebug = function(self) DebuggerAttachDefault() end,
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
--
|
||||
-- MobDebug 0.467
|
||||
-- MobDebug 0.502
|
||||
-- Copyright 2011-12 Paul Kulchenko
|
||||
-- Based on RemDebug 1.0 Copyright Kepler Project 2005
|
||||
--
|
||||
|
||||
local mobdebug = {
|
||||
_NAME = "mobdebug",
|
||||
_VERSION = 0.467,
|
||||
_VERSION = 0.502,
|
||||
_COPYRIGHT = "Paul Kulchenko",
|
||||
_DESCRIPTION = "Mobile Remote Debugger for the Lua programming language",
|
||||
port = 8171
|
||||
@@ -23,7 +23,25 @@ local require = require
|
||||
local setmetatable = setmetatable
|
||||
local string = string
|
||||
local tonumber = tonumber
|
||||
local mosync = mosync
|
||||
|
||||
-- if strict.lua is used, then need to avoid referencing some global
|
||||
-- variables, as they can be undefined;
|
||||
-- use rawget to to avoid complaints from strict.lua at run-time.
|
||||
-- it's safe to do the initialization here as all these variables
|
||||
-- should get defined values (of any) before the debugging starts.
|
||||
-- there is also global 'wx' variable, which is checked as part of
|
||||
-- the debug loop as 'wx' can be loaded at any time during debugging.
|
||||
local genv = _G or _ENV
|
||||
local jit = rawget(genv, "jit")
|
||||
local mosync = rawget(genv, "mosync")
|
||||
local MOAICoroutine = rawget(genv, "MOAICoroutine")
|
||||
|
||||
-- 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.getenv('WINDIR')
|
||||
or (os.getenv('OS') or ''):match('[Ww]indows')
|
||||
or pcall(require, "winapi")
|
||||
|
||||
-- this is a socket class that implements maConnect interface
|
||||
local function socketMobileLua()
|
||||
@@ -161,6 +179,12 @@ if mosync and mosync.EventMonitor then
|
||||
mosync.EventMonitor.RunEventLoop = function(self) end
|
||||
end
|
||||
|
||||
-- turn jit off based on Mike Pall's comment in this discussion:
|
||||
-- http://www.freelists.org/post/luajit/Debug-hooks-and-JIT,2
|
||||
-- "You need to turn it off at the start if you plan to receive
|
||||
-- reliable hook calls at any later point in time."
|
||||
if jit and jit.off then jit.off() end
|
||||
|
||||
local socket = mosync and socketMobileLua() or (require "socket")
|
||||
|
||||
local debug = require "debug"
|
||||
@@ -180,15 +204,18 @@ local step_over = false
|
||||
local step_level = 0
|
||||
local stack_level = 0
|
||||
local server
|
||||
local rset
|
||||
local basedir = ""
|
||||
local deferror = "execution aborted at default debugee"
|
||||
local debugee = function ()
|
||||
local a = 1
|
||||
for _ = 1, 10 do a = a + 1 end
|
||||
error(deferror)
|
||||
end
|
||||
local function q(s) return s:gsub('([%(%)%.%%%+%-%*%?%[%^%$%]])','%%%1') end
|
||||
|
||||
local serpent = (function() ---- include Serpent module for serialization
|
||||
local n, v = "serpent", 0.15 -- (C) 2012 Paul Kulchenko; MIT License
|
||||
local n, v = "serpent", 0.18 -- (C) 2012 Paul Kulchenko; MIT License
|
||||
local c, d = "Paul Kulchenko", "Serializer and pretty printer of Lua data types"
|
||||
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}
|
||||
@@ -206,14 +233,14 @@ local function s(t, opts)
|
||||
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+)",
|
||||
function(s) if not syms[s] then symn = symn+1; syms[s] = symn end return syms[s] end) end
|
||||
local function gensym(val) return (tostring(val):gsub("[^%w]",""):gsub("(%d%w+)",
|
||||
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
|
||||
or ("%q"):format(s):gsub("\010","n"):gsub("\026","\\026") end
|
||||
local function comment(s,l) return comm and (l or 0) < comm and ' --[['..tostring(s)..']]' or '' end
|
||||
local function globerr(s,l) return globals[s] and globals[s]..comment(s,l) or not fatal
|
||||
and safestr(tostring(s))..comment('err',l) or error("Can't serialize "..tostring(s)) end
|
||||
and safestr(select(2, pcall(tostring, s))) or error("Can't serialize "..tostring(s)) end
|
||||
local function safename(path, name) -- generates foo.bar, foo[3], or foo['b a r']
|
||||
local n = name == nil and '' or name
|
||||
local plain = type(n) == "string" and n:match("^[%l%u_][%w_]*$") and not keyword[n]
|
||||
@@ -225,25 +252,28 @@ local function s(t, opts)
|
||||
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
|
||||
local function val2str(t, name, indent, path, plainindex, level)
|
||||
local function val2str(t, name, indent, insref, path, plainindex, level)
|
||||
local ttype, level = type(t), (level or 0)
|
||||
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 seen[t] then -- if already seen and in sref processing,
|
||||
if insref then return tag..seen[t] end -- then emit right away
|
||||
table.insert(sref, spath..space..'='..space..seen[t])
|
||||
return tag..'nil'..comment('ref', level)
|
||||
elseif badtype[ttype] then return tag..globerr(t, level)
|
||||
elseif badtype[ttype] then
|
||||
seen[t] = spath
|
||||
return tag..globerr(t, level)
|
||||
elseif ttype == 'function' then
|
||||
seen[t] = spath
|
||||
local ok, res = pcall(string.dump, t)
|
||||
local func = ok and ((opts.nocode and "function() end" or
|
||||
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 level >= maxl then return tag..'{}'..comment('max', level) end
|
||||
seen[t] = spath
|
||||
seen[t] = insref or spath -- set path to use as reference
|
||||
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
|
||||
@@ -253,14 +283,15 @@ local function s(t, opts)
|
||||
local value, ktype, plainindex = t[key], type(key), n <= maxn and not sparse
|
||||
if opts.ignore and opts.ignore[value] -- skip ignored values; do nothing
|
||||
or sparse and value == nil then -- skipping nils; do nothing
|
||||
elseif ktype == 'table' or ktype == 'function' then
|
||||
elseif ktype == 'table' or ktype == 'function' or badtype[ktype] then
|
||||
if not seen[key] and not globals[key] then
|
||||
table.insert(sref, 'local '..val2str(key,gensym(key),indent)) end
|
||||
table.insert(sref, seen[t]..'['..(seen[key] or globals[key] or gensym(key))
|
||||
..']'..space..'='..space..(seen[value] or val2str(value,nil,indent)))
|
||||
table.insert(sref, 'placeholder')
|
||||
sref[#sref] = 'local '..val2str(key,gensym(key),indent,gensym(key)) 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))
|
||||
else
|
||||
if badtype[ktype] then plainindex, key = true, '['..globerr(key, level+1)..']' end
|
||||
table.insert(out,val2str(value,key,indent,spath,plainindex,level+1))
|
||||
table.insert(out,val2str(value,key,indent,insref,seen[t],plainindex,level+1))
|
||||
end
|
||||
end
|
||||
local prefix = string.rep(indent or '', level)
|
||||
@@ -320,36 +351,48 @@ end
|
||||
|
||||
local function set_breakpoint(file, line)
|
||||
if file == '-' and lastfile then file = lastfile end
|
||||
if not breakpoints[file] then
|
||||
breakpoints[file] = {}
|
||||
end
|
||||
if not breakpoints[file] then breakpoints[file] = {} end
|
||||
breakpoints[file][line] = true
|
||||
end
|
||||
|
||||
local function remove_breakpoint(file, line)
|
||||
if file == '-' and lastfile then file = lastfile end
|
||||
if breakpoints[file] then
|
||||
breakpoints[file][line] = nil
|
||||
end
|
||||
if breakpoints[file] then breakpoints[file][line] = 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]
|
||||
end
|
||||
|
||||
local function restore_vars(vars)
|
||||
if type(vars) ~= 'table' then return end
|
||||
local func = debug.getinfo(3, "f").func
|
||||
|
||||
-- locals need to be processed in the reverse order, starting from
|
||||
-- the inner block out, to make sure that the localized variables
|
||||
-- are correctly updated with only the closest variable with
|
||||
-- the same name being changed
|
||||
-- first loop find how many local variables there is, while
|
||||
-- the second loop processes them from i to 1
|
||||
local i = 1
|
||||
local written_vars = {}
|
||||
while true do
|
||||
local name = debug.getlocal(3, i)
|
||||
if not name then break end
|
||||
if string.sub(name, 1, 1) ~= '(' then debug.setlocal(3, i, vars[name]) end
|
||||
written_vars[name] = true
|
||||
i = i + 1
|
||||
end
|
||||
i = i - 1
|
||||
local written_vars = {}
|
||||
while i > 0 do
|
||||
local name = debug.getlocal(3, i)
|
||||
if not written_vars[name] then
|
||||
if string.sub(name, 1, 1) ~= '(' then debug.setlocal(3, i, vars[name]) end
|
||||
written_vars[name] = true
|
||||
end
|
||||
i = i - 1
|
||||
end
|
||||
|
||||
i = 1
|
||||
local func = debug.getinfo(3, "f").func
|
||||
while true do
|
||||
local name = debug.getupvalue(func, i)
|
||||
if not name then break end
|
||||
@@ -417,7 +460,7 @@ end
|
||||
local function debug_hook(event, line)
|
||||
if abort and is_safe(stack_level) then error(abort) end
|
||||
|
||||
-- LuaJIT needs special treatment. Because debug_hook is set for
|
||||
-- (1) LuaJIT needs special treatment. Because debug_hook is set for
|
||||
-- *all* coroutines, and not just the one being debugged as in regular Lua
|
||||
-- (http://lua-users.org/lists/lua-l/2011-06/msg00513.html),
|
||||
-- need to avoid debugging mobdebug's own code as LuaJIT doesn't
|
||||
@@ -427,7 +470,10 @@ local function debug_hook(event, line)
|
||||
-- 'tail return' events are not generated by LuaJIT).
|
||||
-- the next line checks if the debugger is run under LuaJIT and if
|
||||
-- one of debugger methods is present in the stack, it simply returns.
|
||||
if jit and in_debugger() then return end
|
||||
-- (2) also check if this debug hook has not been visited for any reason.
|
||||
-- this check is needed to avoid stepping in too early
|
||||
-- (for example, when coroutine.resume() is executed inside start()).
|
||||
if (jit or not seen_hook) and in_debugger() then return end
|
||||
|
||||
if event == "call" then
|
||||
stack_level = stack_level + 1
|
||||
@@ -442,13 +488,18 @@ local function debug_hook(event, line)
|
||||
skipcount = 0
|
||||
end
|
||||
|
||||
-- this is needed to check if the stack got shorter.
|
||||
-- this may happen when "pcall(load, '')" is called
|
||||
-- this is needed to check if the stack got shorter or longer.
|
||||
-- unfortunately counting call/return calls is not reliable.
|
||||
-- the discrepancy may happen when "pcall(load, '')" call is made
|
||||
-- or when "error()" is called in a function.
|
||||
-- in either case there are more "call" than "return" events reported.
|
||||
-- this validation is done for every "line" event, but should be
|
||||
-- "cheap" as it only checks for the stack to get shorter
|
||||
stack_level = stack_depth(stack_level)
|
||||
-- this validation is done for every "line" event, but should be "cheap"
|
||||
-- as it checks for the stack to get shorter (or longer by one call).
|
||||
-- start from one level higher just in case we need to grow the stack.
|
||||
-- this may happen after coroutine.resume call to a function that doesn't
|
||||
-- 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
|
||||
@@ -457,56 +508,69 @@ local function debug_hook(event, line)
|
||||
lastsource = caller.source
|
||||
file = lastsource
|
||||
if string.find(file, "@") == 1 then file = string.sub(file, 2) end
|
||||
-- remove references to the current folder (./ or .\)
|
||||
if string.find(file, "%.[/\\]") == 1 then file = string.sub(file, 3) end
|
||||
if iswindows then file = string.lower(file) end
|
||||
file = string.gsub(file, "\\", "/") -- convert slash
|
||||
-- remove references to the current folder (./)
|
||||
if string.find(file, "%./") == 1 then file = string.sub(file, 3)
|
||||
else file = string.gsub(file, '^'..q(basedir), '') end
|
||||
-- fix filenames for loaded strings that may contain scripts with newlines
|
||||
if string.find(file, "\n") then
|
||||
file = string.sub(string.gsub(file, "\n", ' '), 1, 32) -- limit to 32 chars
|
||||
end
|
||||
file = string.gsub(file, "\\", "/") -- convert slash
|
||||
|
||||
-- set to true if we got here; this only needs to be done once per
|
||||
-- session, so do it here to at least avoid setting it for every line.
|
||||
seen_hook = true
|
||||
lastfile = file
|
||||
end
|
||||
|
||||
local vars
|
||||
local vars, status, res
|
||||
if (watchescnt > 0) then
|
||||
vars = capture_vars()
|
||||
for index, value in pairs(watches) do
|
||||
setfenv(value, vars)
|
||||
local status, res = pcall(value)
|
||||
if status and res then
|
||||
coroutine.resume(coro_debugger, events.WATCH, vars, file, line, index)
|
||||
local ok, fired = pcall(value)
|
||||
if ok and fired then
|
||||
status, res = coroutine.resume(coro_debugger, events.WATCH, vars, file, line, index)
|
||||
break -- any one watch is enough; don't check multiple times
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if step_into
|
||||
or (step_over and stack_level <= step_level)
|
||||
or has_breakpoint(file, line)
|
||||
or (socket.select({server}, {}, 0))[server] then
|
||||
-- need to get into the "regular" debug handler, but only if there was
|
||||
-- no watch that was fired. If there was a watch, handle its result.
|
||||
local getin = (status == nil) and
|
||||
(step_into
|
||||
or (step_over and stack_level <= step_level)
|
||||
or has_breakpoint(file, line)
|
||||
or (socket.select(rset, nil, 0))[server])
|
||||
|
||||
if getin then
|
||||
vars = vars or capture_vars()
|
||||
seen_hook = true
|
||||
step_into = false
|
||||
step_over = false
|
||||
local status, res = coroutine.resume(coro_debugger, events.BREAK, vars, file, line)
|
||||
|
||||
-- handle 'stack' command that provides stack() information to the debugger
|
||||
if status and res == 'stack' then
|
||||
while status and res == 'stack' do
|
||||
-- resume with the stack trace and variables
|
||||
status, res = coroutine.resume(coro_debugger, events.STACK, stack(3), file, line)
|
||||
end
|
||||
end
|
||||
|
||||
-- need to recheck once more as resume after 'stack' command may
|
||||
-- return something else (for example, 'exit'), which needs to be handled
|
||||
if status and res and res ~= 'stack' then
|
||||
if abort == nil and res == "exit" then os.exit(1) end
|
||||
abort = res
|
||||
-- only abort if safe; if not, there is another (earlier) check inside
|
||||
-- debug_hook, which will abort execution at the first safe opportunity
|
||||
if is_safe(stack_level) then error(abort) end
|
||||
end -- abort execution if requested
|
||||
status, res = coroutine.resume(coro_debugger, events.BREAK, vars, file, line)
|
||||
end
|
||||
|
||||
-- handle 'stack' command that provides stack() information to the debugger
|
||||
if status and res == 'stack' then
|
||||
while status and res == 'stack' do
|
||||
-- resume with the stack trace and variables
|
||||
if vars then restore_vars(vars) end -- restore vars so they are reflected in stack values
|
||||
status, res = coroutine.resume(coro_debugger, events.STACK, stack(3), file, line)
|
||||
end
|
||||
end
|
||||
|
||||
-- need to recheck once more as resume after 'stack' command may
|
||||
-- return something else (for example, 'exit'), which needs to be handled
|
||||
if status and res and res ~= 'stack' then
|
||||
if abort == nil and res == "exit" then os.exit(1) end
|
||||
abort = res
|
||||
-- only abort if safe; if not, there is another (earlier) check inside
|
||||
-- debug_hook, which will abort execution at the first safe opportunity
|
||||
if is_safe(stack_level) then error(abort) end
|
||||
end
|
||||
|
||||
if vars then restore_vars(vars) end
|
||||
end
|
||||
end
|
||||
@@ -526,7 +590,7 @@ end
|
||||
|
||||
local function debugger_loop(sfile, sline)
|
||||
local command
|
||||
local app
|
||||
local app, osname
|
||||
local eval_env = {}
|
||||
local function emptyWatch () return false end
|
||||
local loaded = {}
|
||||
@@ -534,6 +598,7 @@ local function debugger_loop(sfile, sline)
|
||||
|
||||
while true do
|
||||
local line, err
|
||||
local wx = rawget(genv, "wx") -- use rawread to make strict.lua happy
|
||||
if wx and server.settimeout then server:settimeout(0.1) end
|
||||
while true do
|
||||
line, err = server:receive()
|
||||
@@ -542,13 +607,19 @@ local function debugger_loop(sfile, sline)
|
||||
app = app or (wx and wx.wxGetApp and wx.wxGetApp())
|
||||
if app then
|
||||
local win = app:GetTopWindow()
|
||||
if win then
|
||||
local inloop = app:IsMainLoopRunning()
|
||||
osname = osname or wx.wxPlatformInfo.Get():GetOperatingSystemFamilyName()
|
||||
if win and not inloop then
|
||||
-- process messages in a regular way
|
||||
-- and exit as soon as the event loop is idle
|
||||
win:Connect(wx.wxEVT_IDLE, function()
|
||||
if osname == 'Unix' then wx.wxTimer(app):Start(10, true) end
|
||||
local exitLoop = function()
|
||||
win:Disconnect(wx.wxID_ANY, wx.wxID_ANY, wx.wxEVT_IDLE)
|
||||
win:Disconnect(wx.wxID_ANY, wx.wxID_ANY, wx.wxEVT_TIMER)
|
||||
app:ExitMainLoop()
|
||||
end)
|
||||
end
|
||||
win:Connect(wx.wxEVT_IDLE, exitLoop)
|
||||
win:Connect(wx.wxEVT_TIMER, exitLoop)
|
||||
app:MainLoop()
|
||||
end
|
||||
end
|
||||
@@ -559,7 +630,7 @@ local function debugger_loop(sfile, sline)
|
||||
if server.settimeout then server:settimeout() end -- back to blocking
|
||||
command = string.sub(line, string.find(line, "^[A-Z]+"))
|
||||
if command == "SETB" then
|
||||
local _, _, _, file, line = string.find(line, "^([A-Z]+)%s+([%w%p%s]+)%s+(%d+)%s*$")
|
||||
local _, _, _, file, line = string.find(line, "^([A-Z]+)%s+(.-)%s+(%d+)%s*$")
|
||||
if file and line then
|
||||
set_breakpoint(file, tonumber(line))
|
||||
server:send("200 OK\n")
|
||||
@@ -567,7 +638,7 @@ local function debugger_loop(sfile, sline)
|
||||
server:send("400 Bad Request\n")
|
||||
end
|
||||
elseif command == "DELB" then
|
||||
local _, _, _, file, line = string.find(line, "^([A-Z]+)%s+([%w%p%s]+)%s+(%d+)%s*$")
|
||||
local _, _, _, file, line = string.find(line, "^([A-Z]+)%s+(.-)%s+(%d+)%s*$")
|
||||
if file and line then
|
||||
remove_breakpoint(file, tonumber(line))
|
||||
server:send("200 OK\n")
|
||||
@@ -594,7 +665,7 @@ local function debugger_loop(sfile, sline)
|
||||
server:send("400 Bad Request\n")
|
||||
end
|
||||
elseif command == "LOAD" then
|
||||
local _, _, size, name = string.find(line, "^[A-Z]+%s+(%d+)%s+([%w%p%s]*[%w%p]+)%s*$")
|
||||
local _, _, size, name = string.find(line, "^[A-Z]+%s+(%d+)%s+(%S.-)%s*$")
|
||||
size = tonumber(size)
|
||||
|
||||
if abort == nil then -- no LOAD/RELOAD allowed inside start()
|
||||
@@ -634,14 +705,15 @@ local function debugger_loop(sfile, sline)
|
||||
elseif command == "SETW" then
|
||||
local _, _, exp = string.find(line, "^[A-Z]+%s+(.+)%s*$")
|
||||
if exp then
|
||||
local func = loadstring("return(" .. exp .. ")")
|
||||
local func, res = loadstring("return(" .. exp .. ")")
|
||||
if func then
|
||||
watchescnt = watchescnt + 1
|
||||
local newidx = #watches + 1
|
||||
watches[newidx] = func
|
||||
server:send("200 OK " .. newidx .. "\n")
|
||||
else
|
||||
server:send("400 Bad Request\n")
|
||||
server:send("401 Error in Expression " .. string.len(res) .. "\n")
|
||||
server:send(res)
|
||||
end
|
||||
else
|
||||
server:send("400 Bad Request\n")
|
||||
@@ -708,6 +780,14 @@ local function debugger_loop(sfile, sline)
|
||||
server:send("401 Error in Execution " .. string.len(file) .. "\n")
|
||||
server:send(file)
|
||||
end
|
||||
elseif command == "BASEDIR" then
|
||||
local _, _, dir = string.find(line, "^[A-Z]+%s+(.+)%s*$")
|
||||
if dir then
|
||||
basedir = dir
|
||||
server:send("200 OK\n")
|
||||
else
|
||||
server:send("400 Bad Request\n")
|
||||
end
|
||||
elseif command == "SUSPEND" then
|
||||
-- do nothing; it already fulfilled its role
|
||||
elseif command == "STACK" then
|
||||
@@ -754,7 +834,13 @@ local function start(controller_host, controller_port)
|
||||
|
||||
server = 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
|
||||
@@ -765,14 +851,15 @@ local function start(controller_host, controller_port)
|
||||
-- start from 16th frame, which is sufficiently large for this check.
|
||||
stack_level = stack_depth(16)
|
||||
|
||||
debug.sethook(debug_hook, "lcr")
|
||||
coro_debugger = coroutine.create(debugger_loop)
|
||||
debug.sethook(debug_hook, "lcr")
|
||||
return coroutine.resume(coro_debugger, file, info.currentline)
|
||||
else
|
||||
print("Could not connect to " .. controller_host .. ":" .. controller_port)
|
||||
end
|
||||
end
|
||||
|
||||
local coro_debugee
|
||||
local function controller(controller_host, controller_port)
|
||||
-- only one debugging session can be run (as there is only one debug hook)
|
||||
if isrunning() then return end
|
||||
@@ -783,6 +870,8 @@ local function controller(controller_host, controller_port)
|
||||
local exitonerror = not skip -- exit if not running a scratchpad
|
||||
server = 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 " .. string.len(msg) .. "\n")
|
||||
@@ -790,14 +879,15 @@ local function controller(controller_host, controller_port)
|
||||
return err
|
||||
end
|
||||
|
||||
seen_hook = true -- allow to accept all commands
|
||||
coro_debugger = coroutine.create(debugger_loop)
|
||||
|
||||
while true do
|
||||
step_into = true
|
||||
abort = false
|
||||
if skip then skipcount = skip end -- to force suspend right away
|
||||
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
|
||||
|
||||
local coro_debugee = coroutine.create(debugee)
|
||||
coro_debugee = coroutine.create(debugee)
|
||||
debug.sethook(coro_debugee, debug_hook, "lcr")
|
||||
local status, err = coroutine.resume(coro_debugee)
|
||||
|
||||
@@ -819,7 +909,6 @@ local function controller(controller_host, controller_port)
|
||||
end
|
||||
end
|
||||
end
|
||||
server:close()
|
||||
else
|
||||
print("Could not connect to " .. controller_host .. ":" .. controller_port)
|
||||
return false
|
||||
@@ -837,7 +926,34 @@ local function loop(controller_host, controller_port)
|
||||
return controller(controller_host, controller_port)
|
||||
end
|
||||
|
||||
local basedir = ""
|
||||
local coroutines = {}
|
||||
setmetatable(coroutines, {__mode = "k"}) -- "weak" keys
|
||||
|
||||
local function on()
|
||||
if not (isrunning() and server) then return end
|
||||
|
||||
local co = coroutine.running()
|
||||
if co then
|
||||
if not coroutines[co] then
|
||||
coroutines[co] = true
|
||||
debug.sethook(co, debug_hook, "lcr")
|
||||
end
|
||||
else
|
||||
debug.sethook(debug_hook, "lcr")
|
||||
end
|
||||
end
|
||||
|
||||
local function off()
|
||||
if not (isrunning() and server) then return end
|
||||
|
||||
local co = coroutine.running()
|
||||
if co then
|
||||
if coroutines[co] then coroutines[co] = false end
|
||||
debug.sethook(co)
|
||||
else
|
||||
debug.sethook()
|
||||
end
|
||||
end
|
||||
|
||||
-- Handles server debugging commands
|
||||
local function handle(params, client)
|
||||
@@ -857,12 +973,12 @@ local function handle(params, client)
|
||||
if status == "200" then
|
||||
-- don't need to do anything
|
||||
elseif status == "202" then
|
||||
_, _, file, line = string.find(breakpoint, "^202 Paused%s+([%w%p%s]+)%s+(%d+)%s*$")
|
||||
_, _, file, line = string.find(breakpoint, "^202 Paused%s+(.-)%s+(%d+)%s*$")
|
||||
if file and line then
|
||||
print("Paused at file " .. file .. " line " .. line)
|
||||
end
|
||||
elseif status == "203" then
|
||||
_, _, file, line, watch_idx = string.find(breakpoint, "^203 Paused%s+([%w%p%s]+)%s+(%d+)%s+(%d+)%s*$")
|
||||
_, _, file, line, watch_idx = string.find(breakpoint, "^203 Paused%s+(.-)%s+(%d+)%s+(%d+)%s*$")
|
||||
if file and line and watch_idx then
|
||||
print("Paused at file " .. file .. " line " .. line .. " (watch expression " .. watch_idx .. ": [" .. watches[watch_idx] .. "])")
|
||||
end
|
||||
@@ -881,10 +997,11 @@ local function handle(params, client)
|
||||
return nil, nil, "Debugger error: unexpected response '" .. breakpoint .. "'"
|
||||
end
|
||||
elseif command == "setb" then
|
||||
_, _, _, file, line = string.find(params, "^([a-z]+)%s+([%w%p%s]+)%s+(%d+)%s*$")
|
||||
_, _, _, file, line = string.find(params, "^([a-z]+)%s+(.-)%s+(%d+)%s*$")
|
||||
if file and line then
|
||||
if iswindows then file = string.lower(file) end
|
||||
file = string.gsub(file, "\\", "/") -- convert slash
|
||||
file = string.gsub(file, basedir, '') -- remove basedir
|
||||
file = string.gsub(file, '^'..q(basedir), '') -- remove basedir
|
||||
if not breakpoints[file] then breakpoints[file] = {} end
|
||||
client:send("SETB " .. file .. " " .. line .. "\n")
|
||||
if client:receive() == "200 OK" then
|
||||
@@ -905,16 +1022,23 @@ local function handle(params, client)
|
||||
watches[watch_idx] = exp
|
||||
print("Inserted watch exp no. " .. watch_idx)
|
||||
else
|
||||
print("Error: Watch expression not inserted")
|
||||
local _, _, size = string.find(answer, "^401 Error in Expression (%d+)$")
|
||||
if size then
|
||||
local err = client:receive(tonumber(size)):gsub(".-:%d+:%s*","")
|
||||
print("Error: watch expression not set: " .. err)
|
||||
else
|
||||
print("Error: watch expression not set")
|
||||
end
|
||||
end
|
||||
else
|
||||
print("Invalid command")
|
||||
end
|
||||
elseif command == "delb" then
|
||||
_, _, _, file, line = string.find(params, "^([a-z]+)%s+([%w%p%s]+)%s+(%d+)%s*$")
|
||||
_, _, _, file, line = string.find(params, "^([a-z]+)%s+(.-)%s+(%d+)%s*$")
|
||||
if file and line then
|
||||
if iswindows then file = string.lower(file) end
|
||||
file = string.gsub(file, "\\", "/") -- convert slash
|
||||
file = string.gsub(file, basedir, '') -- remove basedir
|
||||
file = string.gsub(file, '^'..q(basedir), '') -- remove basedir
|
||||
if not breakpoints[file] then breakpoints[file] = {} end
|
||||
client:send("DELB " .. file .. " " .. line .. "\n")
|
||||
if client:receive() == "200 OK" then
|
||||
@@ -979,12 +1103,19 @@ local function handle(params, client)
|
||||
client:send(lines)
|
||||
else
|
||||
local file = io.open(exp, "r")
|
||||
if not file then print("Cannot open file " .. exp); return end
|
||||
local lines = file:read("*all")
|
||||
if not file and pcall(require, "winapi") then
|
||||
-- if file is not open and winapi is there, try with a short path;
|
||||
-- this may be needed for unicode paths on windows
|
||||
winapi.set_encoding(winapi.CP_UTF8)
|
||||
file = io.open(winapi.short_path(exp), "r")
|
||||
end
|
||||
if not file then error("Cannot open file " .. exp) end
|
||||
-- read the file and remove the shebang line as it causes a compilation error
|
||||
local lines = file:read("*all"):gsub("^#!.-\n", "\n")
|
||||
file:close()
|
||||
|
||||
local file = string.gsub(exp, "\\", "/") -- convert slash
|
||||
file = string.gsub(file, basedir, '') -- remove basedir
|
||||
file = string.gsub(file, '^'..q(basedir), '') -- remove basedir
|
||||
client:send("LOAD " .. string.len(lines) .. " " .. file .. "\n")
|
||||
client:send(lines)
|
||||
end
|
||||
@@ -992,7 +1123,7 @@ local function handle(params, client)
|
||||
if not params then
|
||||
return nil, nil, "Debugger error: missing response after EXEC/LOAD"
|
||||
end
|
||||
local _, _, status, len = string.find(params, "^(%d+)[%w%p%s]+%s+(%d+)%s*$")
|
||||
local _, _, status, len = string.find(params, "^(%d+).-%s+(%d+)%s*$")
|
||||
if status == "200" then
|
||||
len = tonumber(len)
|
||||
if len > 0 then
|
||||
@@ -1015,7 +1146,7 @@ local function handle(params, client)
|
||||
return res[1], res
|
||||
end
|
||||
elseif status == "201" then
|
||||
_, _, file, line = string.find(params, "^201 Started%s+([%w%p%s]+)%s+(%d+)%s*$")
|
||||
_, _, file, line = string.find(params, "^201 Started%s+(.-)%s+(%d+)%s*$")
|
||||
elseif status == "202" or params == "200 OK" then
|
||||
-- do nothing; this only happens when RE/LOAD command gets the response
|
||||
-- that was for the original command that was aborted
|
||||
@@ -1055,13 +1186,18 @@ local function handle(params, client)
|
||||
print("Error in stack information: " .. err)
|
||||
return nil, nil, err
|
||||
end
|
||||
local stack = func()
|
||||
local ok, stack = pcall(func)
|
||||
if not ok then
|
||||
print("Error in stack information: " .. stack)
|
||||
return nil, nil, stack
|
||||
end
|
||||
for _,frame in ipairs(stack) do
|
||||
-- remove basedir from short_src or source
|
||||
local src = string.gsub(frame[1][2], "\\", "/") -- convert slash
|
||||
if string.find(src, "@") == 1 then src = string.sub(src, 2) end
|
||||
if string.find(src, "%./") == 1 then src = string.sub(src, 3) end
|
||||
frame[1][2] = string.gsub(src, basedir, '') -- remove basedir
|
||||
if iswindows then src = string.lower(src) end
|
||||
frame[1][2] = string.gsub(src, '^'..q(basedir), '') -- remove basedir
|
||||
print(serpent.line(frame[1], {comment = false}))
|
||||
end
|
||||
return stack
|
||||
@@ -1076,10 +1212,20 @@ local function handle(params, client)
|
||||
elseif command == "basedir" then
|
||||
local _, _, dir = string.find(params, "^[a-z]+%s+(.+)$")
|
||||
if dir then
|
||||
if iswindows then dir = string.lower(dir) end
|
||||
dir = string.gsub(dir, "\\", "/") -- convert slash
|
||||
if not string.find(dir, "/$") then dir = dir .. "/" end
|
||||
basedir = dir
|
||||
print("New base directory is " .. basedir)
|
||||
|
||||
client:send("BASEDIR "..dir.."\n")
|
||||
local resp = client:receive()
|
||||
local _, _, status = string.find(resp, "^(%d+)%s+%w+%s*$")
|
||||
if status == "200" then
|
||||
print("New base directory is " .. basedir)
|
||||
else
|
||||
print("Unknown error")
|
||||
return nil, nil, "Debugger error: unexpected response after BASEDIR"
|
||||
end
|
||||
else
|
||||
print(basedir)
|
||||
end
|
||||
@@ -1130,7 +1276,7 @@ local function listen(host, port)
|
||||
client:receive()
|
||||
|
||||
local breakpoint = client:receive()
|
||||
local _, _, file, line = string.find(breakpoint, "^202 Paused%s+([%w%p%s]+)%s+(%d+)%s*$")
|
||||
local _, _, file, line = string.find(breakpoint, "^202 Paused%s+(.-)%s+(%d+)%s*$")
|
||||
if file and line then
|
||||
print("Paused at file " .. file )
|
||||
print("Type 'help' for commands")
|
||||
@@ -1149,6 +1295,37 @@ local function listen(host, port)
|
||||
end
|
||||
end
|
||||
|
||||
local cocreate
|
||||
local function coro()
|
||||
if cocreate then return end -- only set once
|
||||
cocreate = cocreate or coroutine.create
|
||||
coroutine.create = function(f, ...)
|
||||
return cocreate(function(...)
|
||||
require("mobdebug").on()
|
||||
return f(...)
|
||||
end, ...)
|
||||
end
|
||||
end
|
||||
|
||||
local moconew
|
||||
local function moai()
|
||||
if moconew then return end -- only set once
|
||||
moconew = moconew or (MOAICoroutine and MOAICoroutine.new)
|
||||
if not moconew then return end
|
||||
MOAICoroutine.new = function(...)
|
||||
local thread = moconew(...)
|
||||
local mt = getmetatable(thread)
|
||||
local patched = mt.run
|
||||
mt.run = function(self, f, ...)
|
||||
return patched(self, function(...)
|
||||
require("mobdebug").on()
|
||||
return f(...)
|
||||
end, ...)
|
||||
end
|
||||
return thread
|
||||
end
|
||||
end
|
||||
|
||||
-- make public functions available
|
||||
mobdebug.listen = listen
|
||||
mobdebug.loop = loop
|
||||
@@ -1156,6 +1333,10 @@ mobdebug.scratchpad = scratchpad
|
||||
mobdebug.handle = handle
|
||||
mobdebug.connect = connect
|
||||
mobdebug.start = start
|
||||
mobdebug.on = on
|
||||
mobdebug.off = off
|
||||
mobdebug.moai = moai
|
||||
mobdebug.coro = coro
|
||||
mobdebug.line = serpent.line
|
||||
mobdebug.dump = serpent.dump
|
||||
|
||||
|
||||
315
lualibs/testwell.lua
Normal file
315
lualibs/testwell.lua
Normal file
@@ -0,0 +1,315 @@
|
||||
--
|
||||
-- Copyright (C) 2012 Paul Kulchenko
|
||||
-- A simple testing library
|
||||
-- Based on lua-TestMore : <http://fperrad.github.com/lua-TestMore/>
|
||||
-- Copyright (c) 2009-2011 Francois Perrad
|
||||
-- This library is licensed under the terms of the MIT/X11 license,
|
||||
-- like Lua itself.
|
||||
--
|
||||
|
||||
local pairs = pairs
|
||||
local tostring = tostring
|
||||
local type = type
|
||||
local _G = _G or _ENV
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
local tb = {
|
||||
curr_test = 0,
|
||||
good_test = 0,
|
||||
skip_test = 0,
|
||||
}
|
||||
|
||||
function tb:print(...)
|
||||
print(...)
|
||||
end
|
||||
|
||||
function tb:note(...)
|
||||
self:print(...)
|
||||
end
|
||||
|
||||
function tb:diag(...)
|
||||
local arg = {...}
|
||||
for k, v in pairs(arg) do
|
||||
arg[k] = tostring(v)
|
||||
end
|
||||
local msg = table.concat(arg)
|
||||
msg = msg:gsub("\n", "\n# ")
|
||||
msg = msg:gsub("\n# \n", "\n#\n")
|
||||
msg = msg:gsub("\n# $", '')
|
||||
self:print("# " .. msg)
|
||||
end
|
||||
|
||||
function tb:ok(test, name, more)
|
||||
self.curr_test = self.curr_test + 1
|
||||
self.good_test = self.good_test + (test and 1 or 0)
|
||||
self.skip_test = self.skip_test + (test == nil and 1 or 0)
|
||||
name = tostring(name or '')
|
||||
local out = ''
|
||||
if not test then
|
||||
out = "not "
|
||||
end
|
||||
out = out .. "ok " .. self.curr_test
|
||||
if name ~= '' then
|
||||
out = out .. " - " .. name
|
||||
end
|
||||
self:print(out)
|
||||
if test == false then
|
||||
self:diag(" Failed test " .. (name and ("'" .. name .. "'") or ''))
|
||||
if debug then
|
||||
local info = debug.getinfo(3)
|
||||
local file = info.short_src
|
||||
local line = info.currentline
|
||||
self:diag(" in " .. file .. " at line " .. line .. ".")
|
||||
end
|
||||
self:diag(more)
|
||||
end
|
||||
end
|
||||
|
||||
function tb:done_testing(reset)
|
||||
local c, g, s = self.curr_test, self.good_test, self.skip_test
|
||||
if reset then
|
||||
self.curr_test = 0
|
||||
self.good_test = 0
|
||||
self.skip_test = 0
|
||||
end
|
||||
return c, g, s
|
||||
end
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
local serpent = (function() ---- include Serpent module for serialization
|
||||
local n, v = "serpent", 0.15 -- (C) 2012 Paul Kulchenko; MIT License
|
||||
local c, d = "Paul Kulchenko", "Serializer and pretty printer of Lua data types"
|
||||
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 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',
|
||||
'return', 'then', 'true', 'until', 'while'}) do keyword[k] = true end
|
||||
for k,v in pairs(G) do globals[v] = k end -- build func to name mapping
|
||||
for _,g in ipairs({'coroutine', 'debug', 'io', 'math', 'string', 'table', 'os'}) do
|
||||
for k,v in pairs(G[g]) do globals[v] = g..'.'..k end end
|
||||
|
||||
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+)",
|
||||
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
|
||||
or ("%q"):format(s):gsub("\010","n"):gsub("\026","\\026") end
|
||||
local function comment(s,l) return comm and (l or 0) < comm and ' --[['..tostring(s)..']]' or '' end
|
||||
local function globerr(s,l) return globals[s] and globals[s]..comment(s,l) or not fatal
|
||||
and safestr(tostring(s))..comment('err',l) or error("Can't serialize "..tostring(s)) end
|
||||
local function safename(path, name) -- generates foo.bar, foo[3], or foo['b a r']
|
||||
local n = name == nil and '' or name
|
||||
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 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
|
||||
local function val2str(t, name, indent, path, plainindex, level)
|
||||
local ttype, level = type(t), (level or 0)
|
||||
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
|
||||
table.insert(sref, spath..space..'='..space..seen[t])
|
||||
return tag..'nil'..comment('ref', level)
|
||||
elseif badtype[ttype] then return tag..globerr(t, level)
|
||||
elseif ttype == 'function' then
|
||||
seen[t] = spath
|
||||
local ok, res = pcall(string.dump, t)
|
||||
local func = ok and ((opts.nocode and "function() end" or
|
||||
"loadstring("..safestr(res)..",'@serialized')")..comment(t, level))
|
||||
return tag..(func or globerr(t, level))
|
||||
elseif ttype == "table" then
|
||||
if level >= maxl then return tag..'{}'..comment('max', level) end
|
||||
seen[t] = 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
|
||||
for n, key in ipairs(o) do
|
||||
local value, ktype, plainindex = t[key], type(key), n <= maxn and not sparse
|
||||
if opts.ignore and opts.ignore[value] -- skip ignored values; do nothing
|
||||
or sparse and value == nil then -- skipping nils; do nothing
|
||||
elseif ktype == 'table' or ktype == 'function' then
|
||||
if not seen[key] and not globals[key] then
|
||||
table.insert(sref, 'local '..val2str(key,gensym(key),indent)) end
|
||||
table.insert(sref, seen[t]..'['..(seen[key] or globals[key] or gensym(key))
|
||||
..']'..space..'='..space..(seen[value] or val2str(value,nil,indent)))
|
||||
else
|
||||
if badtype[ktype] then plainindex, key = true, '['..globerr(key, level+1)..']' end
|
||||
table.insert(out,val2str(value,key,indent,spath,plainindex,level+1))
|
||||
end
|
||||
end
|
||||
local prefix = string.rep(indent or '', level)
|
||||
local head = indent and '{\n'..prefix..indent or '{'
|
||||
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)
|
||||
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"
|
||||
end
|
||||
|
||||
local function merge(a, b) if b then for k,v in pairs(b) do a[k] = v end end; return a; end
|
||||
return { _NAME = n, _COPYRIGHT = c, _DESCRIPTION = d, _VERSION = v, serialize = s,
|
||||
dump = function(a, opts) return s(a, merge({name = '_', compact = true, sparse = true}, opts)) end,
|
||||
line = function(a, opts) return s(a, merge({sortkeys = true, comment = true}, opts)) end,
|
||||
block = function(a, opts) return s(a, merge({indent = ' ', sortkeys = true, comment = true}, opts)) end }
|
||||
end)() ---- end of Serpent module
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
local m = {}
|
||||
|
||||
function m.ok(test, name)
|
||||
tb:ok(test, name)
|
||||
end
|
||||
|
||||
local parms = {comment = false}
|
||||
function m.is(got, expected, name)
|
||||
local tgot, texp = type(got), type(expected)
|
||||
local vgot, vexp = serpent.line(got, parms), serpent.line(expected, parms)
|
||||
local pass = vgot == vexp
|
||||
if got == nil then pass = nil end
|
||||
tb:ok(pass, name, not pass and
|
||||
" got: " .. vgot .. " (" .. tgot .. ")" ..
|
||||
"\n expected: " .. vexp .. " (" .. texp .. ")")
|
||||
end
|
||||
|
||||
function m.isnt(got, expected, name)
|
||||
local tgot, texp = type(got), type(expected)
|
||||
local vgot, vexp = serpent.line(got, parms), serpent.line(expected, parms)
|
||||
local pass = vgot ~= vexp
|
||||
if got == nil then pass = nil end
|
||||
tb:ok(pass, name, not pass and
|
||||
" got: " .. vgot .. " (" .. tgot .. ")" ..
|
||||
"\n expected: anything else")
|
||||
end
|
||||
|
||||
function m.like(got, pattern, name)
|
||||
if type(pattern) ~= 'string' then
|
||||
return tb:ok(false, name, "pattern isn't a string : " .. tostring(pattern))
|
||||
end
|
||||
|
||||
local pass = tostring(got):match(pattern)
|
||||
if got == nil then pass = nil end
|
||||
tb:ok(pass, name, not pass and
|
||||
" '" .. tostring(got) .. "'" ..
|
||||
"\n doesn't match '" .. pattern .. "'")
|
||||
end
|
||||
|
||||
function m.unlike(got, pattern, name)
|
||||
if type(pattern) ~= 'string' then
|
||||
return tb:ok(false, name, "pattern isn't a string : " .. tostring(pattern))
|
||||
end
|
||||
|
||||
local pass = not tostring(got):match(pattern)
|
||||
if got == nil then pass = nil end
|
||||
tb:ok(pass, name, not pass and
|
||||
" '" .. tostring(got) .. "'" ..
|
||||
"\n matches '" .. pattern .. "'")
|
||||
end
|
||||
|
||||
local cmp = {
|
||||
['<'] = function (a, b) return a < b end,
|
||||
['<='] = function (a, b) return a <= b end,
|
||||
['>'] = function (a, b) return a > b end,
|
||||
['>='] = function (a, b) return a >= b end,
|
||||
['=='] = function (a, b) return a == b end,
|
||||
['~='] = function (a, b) return a ~= b end,
|
||||
}
|
||||
|
||||
function m.cmp_ok(this, op, that, name)
|
||||
local f = cmp[op]
|
||||
if not f then
|
||||
return tb:ok(false, name, "unknown operator : " .. tostring(op))
|
||||
end
|
||||
|
||||
local pass = f(this, that)
|
||||
if this == nil then pass = nil end
|
||||
tb:ok(pass, name, not pass and
|
||||
" " .. tostring(this) ..
|
||||
"\n " .. op ..
|
||||
"\n " .. tostring(that))
|
||||
end
|
||||
|
||||
function m.type_ok(val, t, name)
|
||||
if type(t) ~= 'string' then
|
||||
return tb:ok(false, name, "type isn't a string : " .. tostring(t))
|
||||
end
|
||||
|
||||
if type(val) == t then
|
||||
tb:ok(true, name)
|
||||
else
|
||||
tb:ok(false, name,
|
||||
" " .. tostring(val) .. " isn't a '" .. t .."', it's a '" .. type(val) .. "'")
|
||||
end
|
||||
end
|
||||
|
||||
function m.diag(...)
|
||||
tb:diag(...)
|
||||
end
|
||||
|
||||
function m.report()
|
||||
local total, good, skipped = tb:done_testing(true)
|
||||
if total == 0 then return end
|
||||
local failed = total - good - skipped
|
||||
local sum = ("(%d/%d/%d)."):format(good, skipped, total)
|
||||
local num, msg = 0, ""
|
||||
if good > 0 then
|
||||
num, msg = good, msg .. "passed " .. good
|
||||
end
|
||||
if failed > 0 then
|
||||
num, msg = failed, msg .. (#msg > 0 and (skipped > 0 and ", " or " and ") or "")
|
||||
.. "failed " .. failed
|
||||
end
|
||||
if skipped > 0 then
|
||||
num, msg = skipped, msg .. (#msg > 0 and ((good > 0 and failed > 0 and ',' or '') .." and ") or "")
|
||||
.. "skipped " .. skipped
|
||||
end
|
||||
msg = ("Looks like you %s test%s of %d %s"):format(msg, (num > 1 and 's' or ''), total, sum)
|
||||
if skipped == total then msg = "Looks like you skipped all tests " .. sum end
|
||||
if good == total then msg = "All tests passed " .. sum end
|
||||
tb:note(("1..%d # %s"):format(total, msg))
|
||||
end
|
||||
|
||||
function m.ismain()
|
||||
for l = 3, 64 do -- only check up to 64 level; no more needed
|
||||
local info = debug.getinfo(l)
|
||||
if not info then return true end
|
||||
if info.func == require then return false end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-- this is needed to call report() when the test object is destroyed
|
||||
if _VERSION >= "Lua 5.2" then
|
||||
setmetatable(m, {__gc = m.report})
|
||||
else
|
||||
-- keep sentinel alive until 'm' is garbage collected
|
||||
m.sentinel = newproxy(true)
|
||||
getmetatable(m.sentinel).__gc = m.report
|
||||
end
|
||||
|
||||
for k, v in pairs(m) do -- injection
|
||||
_G[k] = v
|
||||
end
|
||||
|
||||
return m
|
||||
@@ -46,7 +46,7 @@ return {
|
||||
},
|
||||
|
||||
keywords = {
|
||||
[[int uint half float bool double
|
||||
[[int uint half float bool double atomic_uint binding offset
|
||||
vec2 vec3 vec4 dvec2 dvec3 dvec4
|
||||
ivec2 ivec3 ivec4 uvec2 uvec3 uvec4 bvec2 bvec3 bvec4
|
||||
mat2 mat3 mat4 mat2x2 mat3x3 mat4x4 mat2x3 mat3x2 mat4x2 mat2x4 mat4x3 mat3x4
|
||||
@@ -63,8 +63,8 @@ return {
|
||||
triangles quads equal_spacing isolines fractional_even_spacing lines points
|
||||
fractional_odd_spacing cw ccw point_mode lines_adjacency triangles_adjacency
|
||||
invocations
|
||||
origin_upper_left pixel_center_integer
|
||||
smooth flat noperspective highp mediump lowp shared packed std140 row_major column_major
|
||||
origin_upper_left pixel_center_integer depth_greater depth_greater depth_greater depth_unchanged
|
||||
smooth flat noperspective highp mediump lowp shared packed std140 std430 row_major column_major buffer
|
||||
gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor gl_Color gl_SecondaryColor
|
||||
subroutine gl_Position gl_FragCoord
|
||||
gl_VertexID gl_InstanceID gl_Normal gl_Vertex gl_MultiTexCoord0 gl_MultiTexCoord1
|
||||
@@ -76,22 +76,26 @@ return {
|
||||
gl_InvocationID gl_PrimitiveIDIn gl_Layer gl_ViewportIndex gl_FrontFacing
|
||||
gl_PointCoord gl_SampleID gl_SamplePosition gl_FragColor
|
||||
gl_FragData gl_FragDepth gl_SampleMask
|
||||
gl_NumWorkGroups gl_WorkGroupSize gl_WorkGroupID gl_LocalInvocationID gl_GlobalInvocationID gl_LocalInvocationIndex
|
||||
local_size_x local_size_y local_size_z
|
||||
|
||||
coherent volatile restrict
|
||||
coherent volatile restrict readonly writeonly
|
||||
image1D image2D image3D image2DRect imageCube imageBuffer image1DArray image2DArray imageCubeArray image2DMS image2DMSArray
|
||||
uimage1D uimage2D uimage3D uimage2DRect uimageCube uimageBuffer uimage1DArray uimage2DArray uimageCubeArray uimage2DMS uimage2DMSArray
|
||||
iimage1D iimage2D iimage3D iimage2DRect iimageCube iimageBuffer iimage1DArray iimage2DArray iimageCubeArray iimage2DMS iimage2DMSArray
|
||||
size1x8 size1x16 size1x32 size2x32 size4x32
|
||||
size1x8 size1x16 size1x32 size2x32 size4x32 rgba32f rgba16f rg32f rg16f r32f r16f rgba8 rgba16 r11f_g11f_b10f rgb10_a2ui
|
||||
rgb10_a2i rg16 rg8 r16 r8 rgba32i rgba16i rgba8i rg32i rg16i rg8i r32i r16i r8i rgba32ui rgba16ui rgba8ui rg32ui rg16ui rg8ui
|
||||
r32ui r16ui r8ui rgba16_snorm rgba8_snorm rg16_snorm rg8_snorm r16_snorm r8_snorm
|
||||
]],
|
||||
|
||||
[[discard
|
||||
radians degrees sin cos tan asin acos atan sinh cosh tanh asinh acosh atanh
|
||||
pow exp log exp2 log2 sqrt inversesqrt abs sign floor trunc round
|
||||
roundEven ceil fract mod modf min max mix step isnan isinf clamp smoothstep
|
||||
floatBitsToInt intBitsToFloat uintBitsToFloat fma frexp ldexp
|
||||
floatBitsToInt floatBitsToUint intBitsToFloat uintBitsToFloat fma frexp ldexp
|
||||
packUnorm2x16 packUnorm4x8 packSnorm4x8
|
||||
unpackUnorm2x16 unpackUnorm4x8 unpackSnorm4x8
|
||||
packDouble2x32 unpackDouble2x32
|
||||
packDouble2x32 unpackDouble2x32 packHalf2x16 unpackHalf2x16
|
||||
length distance dot cross normalize ftransform faceforward
|
||||
reflect refract
|
||||
matrixCompMult outerProduct transpose determinant inverse
|
||||
@@ -138,7 +142,12 @@ return {
|
||||
imageAtomicAdd imageAtomicMin imageAtomicMax
|
||||
imageAtomicIncWrap imageAtomicDecWrap imageAtomicAnd
|
||||
imageAtomicOr imageAtomixXor imageAtomicExchange
|
||||
imageCompSwap memoryBarrier
|
||||
imageCompSwap
|
||||
|
||||
memoryBarrier groupMemoryBarrier memoryBarrierAtomicCounter memoryBarrierShared memoryBarrierBuffer memoryBarrierImage
|
||||
|
||||
atomicCounterIncrement atomicCounterDecrement atomicCounter
|
||||
atomicMin atomicMax atomicAdd atomicAnd atomicOr atomicXor atomicExchange atomicCompSwap
|
||||
|
||||
x y z w
|
||||
xxxx xxxy xxxz xxxw xxyx xxyy xxyz xxyw xxzx xxzy
|
||||
|
||||
73
spec/lua.lua
73
spec/lua.lua
@@ -1,36 +1,63 @@
|
||||
-- authors: Luxinia Dev (Eike Decker & Christoph Kubisch)
|
||||
---------------------------------------------------------
|
||||
|
||||
local funcdef = "([A-Za-z_][A-Za-z0-9_%.%:]*)%s*"
|
||||
local funccall = "([A-Za-z_][A-Za-z0-9_]*)%s*"
|
||||
local decindent = {
|
||||
['else'] = true, ['elseif'] = true, ['end'] = true}
|
||||
local incindent = {
|
||||
['else'] = true, ['elseif'] = true, ['for'] = true, ['do'] = true,
|
||||
['if'] = true, ['repeat'] = true, ['until'] = true, ['while'] = true}
|
||||
local function isfndef(str)
|
||||
local l
|
||||
local s,e,cap,par = string.find(str, "function%s+" .. funcdef .. "(%(.-%))")
|
||||
-- try to match without brackets now, but only at the beginning of the line
|
||||
if (not s) then
|
||||
s,e,cap = string.find(str, "^%s*function%s+" .. funcdef)
|
||||
end
|
||||
-- try to match "foo = function()"
|
||||
if (not s) then
|
||||
s,e,cap,par = string.find(str, funcdef .. "=%s*function%s*(%(.-%))")
|
||||
end
|
||||
if (s) then
|
||||
l = string.find(string.sub(str,1,s-1),"local%s+$")
|
||||
cap = cap .. " " .. (par or "(?)")
|
||||
end
|
||||
return s,e,cap,l
|
||||
end
|
||||
|
||||
return {
|
||||
exts = {"lua"},
|
||||
exts = {"lua", "rockspec"},
|
||||
lexer = wxstc.wxSTC_LEX_LUA,
|
||||
apitype = "lua",
|
||||
linecomment = "--",
|
||||
sep = "%.:",
|
||||
isfncall = function(str)
|
||||
return string.find(str,"([A-Za-z0-9_]+)%s*%(")
|
||||
return string.find(str, funccall .. "%(")
|
||||
end,
|
||||
isfndef = function(str)
|
||||
local l
|
||||
local s,e,cap,par = string.find(str,"function%s+([A-Za-z0-9_]+%s-[%.%:]?%s-[A-Za-z0-9_]*)%s*(%(.-%))")
|
||||
-- try to match without brackets now, but only at the beginning of the line
|
||||
if (not s) then
|
||||
s,e,cap = string.find(str,"^%s*function%s+([A-Za-z0-9_]+%s-[%.%:]?%s-[A-Za-z0-9_]*)%s*")
|
||||
end
|
||||
-- try to match "foo = function()"
|
||||
if (not s) then
|
||||
s,e,cap,cap1,cap2,par = string.find(str,"(([A-Za-z0-9_]+%s-[%.%:]?%s-)([A-Za-z0-9_]*))%s*=%s*function%s*(%(.-%))")
|
||||
-- check if we captured 'local foo =' instead of 'foo.bar ='
|
||||
if cap1 and cap2 and string.len(cap2) > 0 and not string.find(cap1,'[%.%:]') then
|
||||
cap = cap2
|
||||
s = s + string.len(cap1)
|
||||
end
|
||||
end
|
||||
if (s) then
|
||||
l = string.find(string.sub(str,1,s-1),"local%s+$")
|
||||
cap = cap .. " " .. (par or "(?)")
|
||||
end
|
||||
return s,e,cap,l
|
||||
isfndef = isfndef,
|
||||
isdecindent = function(str)
|
||||
-- this handles three different cases:
|
||||
local term = str:match("^%s*(%w+)%s*$")
|
||||
-- (1) 'end', 'elseif', 'else'
|
||||
local match = term and decindent[term]
|
||||
-- (2) 'end)' and 'end}'
|
||||
if not term then term, match = str:match("^%s*(end)%s*([%)%}]+)%s*[,;]?") end
|
||||
-- (3) '},', '};', '),' and ');'
|
||||
if not term then match = str:match("^%s*[%)%}]+%s*[,;]?%s*$") end
|
||||
|
||||
return match and 1 or 0, match and term and 1 or 0
|
||||
end,
|
||||
isincindent = function(str)
|
||||
local term = str:match("^%s*(%w+)[^%w]*")
|
||||
term = term and incindent[term] and 1 or 0
|
||||
local _, opened = str:gsub("([%{%(])", "%1")
|
||||
local _, closed = str:gsub("([%}%)])", "%1")
|
||||
local func = (isfndef(str) or str:match("[^%w]+function%s*%(")) and 1 or 0
|
||||
-- ended should only be used to negate term and func effects
|
||||
local ended = (term + func > 0) and str:match("[^%w]+end%s*$") and 1 or 0
|
||||
|
||||
return opened - closed + func + term - ended
|
||||
end,
|
||||
|
||||
typeassigns = function(editor)
|
||||
|
||||
74
src/defs.lua
74
src/defs.lua
@@ -79,7 +79,7 @@ style = {
|
||||
-- content is optional
|
||||
-- config is loaded into existing config table
|
||||
config = {
|
||||
appname = "estrela", -- by default the launcher name
|
||||
appname = "zbstudio", -- by default the launcher name
|
||||
|
||||
path = {
|
||||
-- path for tools/interpreters
|
||||
@@ -91,31 +91,30 @@ config = {
|
||||
-- some tools/interpreters
|
||||
},
|
||||
editor = {
|
||||
fontname = "Courier New",
|
||||
-- default font
|
||||
fontsize = 10,
|
||||
-- defailt size
|
||||
caretline = true,
|
||||
-- show active line
|
||||
|
||||
-- input/output filtering of strings
|
||||
-- current filters "GermanUtf8Ascii"
|
||||
iofilter = nil,
|
||||
|
||||
-- use indicator to show function calls
|
||||
-- if spec allows
|
||||
showfncall = true,
|
||||
|
||||
fontname = "Courier New", -- default font
|
||||
fontsize = 10, -- default size
|
||||
caretline = true, -- show active line
|
||||
iofilter = nil, -- input/output filtering of strings
|
||||
showfncall = true, -- use indicator to show function calls if spec allows
|
||||
tabwidth = 4,
|
||||
usetabs = true, -- if false then spaces are used
|
||||
usewrap = true, -- if true then the text is wrapped in the editor
|
||||
whitespace = false,
|
||||
autotabs = true, -- if true test for tabs after file load,
|
||||
-- sets "usetabs" to true for this file
|
||||
-- sets "usetabs" to true for this file
|
||||
calltipdelay = nil, -- delay to show calltip (in ms)
|
||||
autoactivate = false, -- auto-activate/open files during debugging
|
||||
smartindent = false, -- use smart indentation if spec allows
|
||||
},
|
||||
|
||||
default = {
|
||||
name = 'untitled',
|
||||
fullname = 'untitled.lua',
|
||||
},
|
||||
|
||||
debugger = {
|
||||
verbose = false,
|
||||
hostname = nil, -- hostname to use when the detected one is incorrect
|
||||
}
|
||||
|
||||
outputshell = {
|
||||
@@ -126,25 +125,28 @@ config = {
|
||||
-- defult size
|
||||
}
|
||||
|
||||
filetree = { -- filetree settings
|
||||
fontname = nil, -- no default font as it is system dependent
|
||||
fontsize = nil, -- no default size as it is system dependent
|
||||
}
|
||||
|
||||
styles = {},
|
||||
-- styles table as above for editor
|
||||
|
||||
stylesoutshell = {},
|
||||
-- styles for output/shell
|
||||
|
||||
interpreter = "EstrelaEditor",
|
||||
interpreter = "luadeb",
|
||||
-- the default "project" lua interpreter
|
||||
|
||||
autocomplete = true,
|
||||
-- whether autocomplete is on by default
|
||||
|
||||
acandtip = {
|
||||
shorttip = false,
|
||||
-- tooltips are compact during typing
|
||||
nodynwords = false,
|
||||
-- no dynamic words (user entered words)
|
||||
ignorecase = false,
|
||||
-- ignores case when performing comparison with autocomplete list
|
||||
shorttip = false, -- tooltips are compact during typing
|
||||
nodynwords = false, -- no dynamic words (user entered words)
|
||||
ignorecase = false, -- ignores case when performing comparison with autocomplete list
|
||||
startat = 2, -- start suggesting dynamic words after 2 characters
|
||||
strategy = 0,
|
||||
-- 0: is string comparison
|
||||
-- 1: substring leading characters (camel case or _ separated)
|
||||
@@ -168,8 +170,10 @@ config = {
|
||||
-- UDP port for single instance communication
|
||||
|
||||
activateoutput = false, -- activate output/console on Run/Debug/Compile
|
||||
unhidewxwindow = false, -- try to unhide a wx window
|
||||
unhidewindow = false, -- to unhide a gui window
|
||||
allowinteractivescript = false, -- allow interaction in the output window
|
||||
projectautoopen = false, -- allow auto open/close files on a project switch
|
||||
autorecoverinactivity = nil, -- period of inactivity (s) for autorecover
|
||||
}
|
||||
|
||||
-- application engine
|
||||
@@ -301,21 +305,21 @@ debuginterface = {
|
||||
breakpoint = function(self,file,line,state) end, -- set breakpoint state
|
||||
|
||||
-- returns result table if successful
|
||||
evaluate = function(self, expressions, fnSetValues) end, -- for watches tables expected
|
||||
|
||||
-- NYI getstack = function(self, fnSetValues ) end, -- get stack information
|
||||
evaluate = function(self, expressions, fnSetValues) end, -- for watches tables
|
||||
stack = function(self) end, -- get stack information
|
||||
}
|
||||
|
||||
-- interpreter definition-- ----------------------------------------------------
|
||||
interpreter = {
|
||||
name = "",
|
||||
description = "",
|
||||
api = {"apifile_without_extension"} -- optional to limit loaded lua apis
|
||||
frun = function(self,wfilename,withdebugger)
|
||||
end,
|
||||
fprojdir = function(self,wfilename)
|
||||
return "projpath_from_filename" -- optional
|
||||
end,
|
||||
fattachdebug = function(self) end, -- optional
|
||||
api = {"apifile_without_extension"} -- (opt) to limit loaded lua apis
|
||||
frun = function(self,wfilename,withdebugger) end,
|
||||
fprojdir = function(self,wfilename) return "projpath_from_filename" end, -- (opt)
|
||||
fattachdebug = function(self) end, -- (opt)
|
||||
hasdebugger = false, -- if debugging is available
|
||||
scratchextloop = nil, -- (opt) indicates scratchpad support
|
||||
-- nil, no support for scratchpad;
|
||||
-- false, scratchpad supported;
|
||||
-- true, scratchpad supported and requires handling for external loop.
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ local statusBar = ide.frame.statusBar
|
||||
|
||||
local function newAPI(api)
|
||||
api = api or {}
|
||||
for i,v in pairs(api) do
|
||||
for i in pairs(api) do
|
||||
api[i] = nil
|
||||
end
|
||||
-- tool tip info and reserved names
|
||||
@@ -36,8 +36,6 @@ local apis = {
|
||||
lua = newAPI(),
|
||||
}
|
||||
|
||||
local config = ide.config.ac
|
||||
|
||||
function GetApi(apitype)
|
||||
return apis[apitype] or apis["none"]
|
||||
end
|
||||
@@ -58,20 +56,16 @@ local function addAPI(apifile,only,subapis,known) -- relative to API directory
|
||||
|
||||
local fn,err = loadfile(apifile)
|
||||
if err then
|
||||
print("API file '"..apifile.."' could not be loaded: "..err.."\n")
|
||||
DisplayOutput("Error while loading API file: "..err.."\n")
|
||||
return
|
||||
end
|
||||
local mt
|
||||
local env = apis[ftype] or newAPI()
|
||||
apis[ftype] = env
|
||||
env = env.ac.childs
|
||||
local suc,res = xpcall(function()return fn(env)end, function(err)
|
||||
DisplayOutput("Error while loading API file: "..apifile..":\n")
|
||||
DisplayOutput(debug.traceback(err))
|
||||
DisplayOutput("\n")
|
||||
end)
|
||||
|
||||
if (suc and res) then
|
||||
local suc,res = pcall(function()return fn(env)end)
|
||||
if (not suc) then
|
||||
DisplayOutput("Error while processing API file: "..res.."\n")
|
||||
elseif (res) then
|
||||
local function gennames(tab,prefix)
|
||||
for i,v in pairs(tab) do
|
||||
v.classname = (prefix and (prefix..".") or "")..i
|
||||
@@ -89,9 +83,8 @@ local function addAPI(apifile,only,subapis,known) -- relative to API directory
|
||||
end
|
||||
|
||||
local function loadallAPIs (only,subapis,known)
|
||||
for i,dir in ipairs(FileSysGet(".\\api\\*.*",wx.wxDIR)) do
|
||||
local files = FileSysGet(dir.."\\*.*",wx.wxFILE)
|
||||
for i,file in ipairs(files) do
|
||||
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
|
||||
@@ -146,7 +139,7 @@ local function fillTips(api,apibasename,apiname)
|
||||
-- build info
|
||||
local inf = frontname.."\n"..info.description
|
||||
local sentence = info.description:match("^([^\n]+)\n.*")
|
||||
local sentence = sentence and sentence:match("([^%.]+)%..*$")
|
||||
sentence = sentence and sentence:match("([^%.]+)%..*$")
|
||||
local infshort = frontname.."\n"..(sentence and sentence.."..." or info.description)
|
||||
local infshortbatch = (info.returns and info.args) and frontname or infshort
|
||||
|
||||
@@ -266,7 +259,7 @@ function ReloadLuaAPI()
|
||||
interpreterapi = interpreterapi and interpreterapi.api
|
||||
if (interpreterapi) then
|
||||
local apinames = {}
|
||||
for i,v in ipairs(interpreterapi) do
|
||||
for _, v in ipairs(interpreterapi) do
|
||||
apinames[v] = true
|
||||
end
|
||||
interpreterapi = apinames
|
||||
@@ -276,7 +269,7 @@ end
|
||||
|
||||
do
|
||||
local known = {}
|
||||
for n,spec in pairs(ide.specs) do
|
||||
for _, spec in pairs(ide.specs) do
|
||||
if (spec.apitype) then
|
||||
known[spec.apitype] = true
|
||||
end
|
||||
@@ -388,7 +381,7 @@ local function getAutoCompApiList(childs,fragment)
|
||||
local wlist = cache[childs]
|
||||
if not wlist then
|
||||
wlist = " "
|
||||
for i,v in pairs(childs) do
|
||||
for i in pairs(childs) do
|
||||
wlist = wlist..i.." "
|
||||
end
|
||||
cache[childs] = wlist
|
||||
@@ -415,8 +408,8 @@ local function getAutoCompApiList(childs,fragment)
|
||||
local t = {}
|
||||
cache[childs] = t
|
||||
|
||||
local sub = strat == 1
|
||||
for key, info in pairs(childs) do
|
||||
local sub = strategy == 1
|
||||
for key in pairs(childs) do
|
||||
local used = {}
|
||||
--
|
||||
local kl = key:lower()
|
||||
@@ -468,7 +461,7 @@ function CreateAutoCompList(editor,key)
|
||||
if not (progress) then return end
|
||||
|
||||
if (tab == ac) then
|
||||
local obj,krest = rest:match("([%w_]+)[:%.]([%w_]+)%s*$")
|
||||
local _, krest = rest:match("([%w_]+)[:%.]([%w_]+)%s*$")
|
||||
if (krest) then
|
||||
if (#krest < 3) then return end
|
||||
tab = tip.finfo
|
||||
@@ -480,13 +473,14 @@ function CreateAutoCompList(editor,key)
|
||||
rest = rest:gsub("[^%w_]","")
|
||||
end
|
||||
|
||||
local last = key:match "([%w_]+)%s*$"
|
||||
local last = key:match("([%w_]+)%s*$")
|
||||
|
||||
-- build dynamic word list
|
||||
-- only if api search couldnt descend
|
||||
-- ie we couldnt find matching sub items
|
||||
local dw = ""
|
||||
if (tab == ac) then
|
||||
if (tab == ac and last and #last >= (ide.config.acandtip.startat or 2)) then
|
||||
last = last:lower()
|
||||
if dynamicwords[last] then
|
||||
local list = dynamicwords[last]
|
||||
table.sort(list,function(a,b)
|
||||
@@ -496,7 +490,7 @@ function CreateAutoCompList(editor,key)
|
||||
end)
|
||||
-- ignore if word == last and sole user
|
||||
for i,v in ipairs(list) do
|
||||
if (v == last and dywordentries[v] == 1) then
|
||||
if (v:lower() == last and dywordentries[v] == 1) then
|
||||
table.remove(list,i)
|
||||
break
|
||||
end
|
||||
@@ -504,7 +498,6 @@ function CreateAutoCompList(editor,key)
|
||||
|
||||
local res = table.concat(list," ")
|
||||
dw = res ~= "" and " "..res or ""
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -526,13 +519,13 @@ function CreateAutoCompList(editor,key)
|
||||
local ma,mb = 0,0
|
||||
g(a,pat,function(...)
|
||||
local l = {...}
|
||||
for i,v in ipairs(l) do
|
||||
for _, v in ipairs(l) do
|
||||
ma = ma + ((v=="") and 0 or 1)
|
||||
end
|
||||
end)
|
||||
g(b,pat,function(...)
|
||||
local l = {...}
|
||||
for i,v in ipairs(l) do
|
||||
for _, v in ipairs(l) do
|
||||
mb = mb + ((v=="") and 0 or 1)
|
||||
end
|
||||
end)
|
||||
|
||||
@@ -8,8 +8,10 @@ local openDocuments = ide.openDocuments
|
||||
local uimgr = frame.uimgr
|
||||
|
||||
function NewFile(event)
|
||||
local editor = CreateEditor("untitled.lua")
|
||||
local editor = CreateEditor()
|
||||
SetupKeywords(editor, "lua")
|
||||
AddEditor(editor, ide.config.default.fullname)
|
||||
return editor
|
||||
end
|
||||
|
||||
-- Find an editor page that hasn't been used at all, eg. an untouched NewFile()
|
||||
@@ -26,45 +28,44 @@ local function findDocumentToReuse()
|
||||
return editor
|
||||
end
|
||||
|
||||
function LoadFile(filePath, editor, file_must_exist)
|
||||
filePath = wx.wxFileName(filePath):GetFullPath()
|
||||
local cmpName = string.lower(string.gsub(filePath, "\\", "/"))
|
||||
|
||||
function LoadFile(filePath, editor, file_must_exist, skipselection)
|
||||
local filePath = wx.wxFileName(filePath)
|
||||
filePath:Normalize() -- make it absolute and remove all .. and . if possible
|
||||
|
||||
-- prevent files from being reopened again
|
||||
if (not editor) then
|
||||
for id, doc in pairs(openDocuments) do
|
||||
local docName = doc.filePath and string.lower(string.gsub(doc.filePath, "\\", "/"))
|
||||
if cmpName == docName then
|
||||
notebook:SetSelection(doc.index)
|
||||
if doc.filePath and filePath:SameAs(wx.wxFileName(doc.filePath)) then
|
||||
if not skipselection then notebook:SetSelection(doc.index) end
|
||||
return doc.editor
|
||||
end
|
||||
end
|
||||
end
|
||||
filePath = filePath:GetFullPath()
|
||||
|
||||
-- if not opened yet, try open now
|
||||
local file_text = ""
|
||||
local handle = io.open(filePath, "rb")
|
||||
if handle then
|
||||
file_text = handle:read("*a")
|
||||
local file_text = FileRead(filePath)
|
||||
if file_text then
|
||||
if GetConfigIOFilter("input") then
|
||||
file_text = GetConfigIOFilter("input")(filePath,file_text)
|
||||
end
|
||||
handle:close()
|
||||
elseif file_must_exist then
|
||||
return nil
|
||||
end
|
||||
|
||||
local current = editor and editor:GetCurrentPos()
|
||||
editor = editor
|
||||
or findDocumentToReuse()
|
||||
or CreateEditor(wx.wxFileName(filePath):GetFullName() or "untitled.lua")
|
||||
editor = editor or findDocumentToReuse() 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)
|
||||
editor:AppendText(file_text or "")
|
||||
editor:Colourise(0, -1)
|
||||
editor:Thaw()
|
||||
|
||||
if current then editor:GotoPos(current) end
|
||||
if (ide.config.editor.autotabs) then
|
||||
local found = string.find(file_text,"\t") ~= nil
|
||||
@@ -73,19 +74,22 @@ function LoadFile(filePath, editor, file_must_exist)
|
||||
|
||||
editor:EmptyUndoBuffer()
|
||||
local id = editor:GetId()
|
||||
if not openDocuments[id] then -- the editor has not been added to notebook
|
||||
AddEditor(editor, wx.wxFileName(filePath):GetFullName()
|
||||
or ide.config.default.fullname)
|
||||
end
|
||||
openDocuments[id].filePath = filePath
|
||||
openDocuments[id].fileName = wx.wxFileName(filePath):GetFullName()
|
||||
openDocuments[id].modTime = GetFileModTime(filePath)
|
||||
SetDocumentModified(id, false)
|
||||
editor:Colourise(0, -1)
|
||||
|
||||
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.
|
||||
SetEditorSelection()
|
||||
if not skipselection then SetEditorSelection() end
|
||||
|
||||
return editor
|
||||
end
|
||||
@@ -108,14 +112,12 @@ local function getExtsString()
|
||||
end
|
||||
|
||||
function OpenFile(event)
|
||||
|
||||
local exts = getExtsString()
|
||||
|
||||
local fileDialog = wx.wxFileDialog(ide.frame, "Open file",
|
||||
"",
|
||||
"",
|
||||
exts,
|
||||
wx.wxOPEN + wx.wxFILE_MUST_EXIST)
|
||||
wx.wxFD_OPEN + wx.wxFD_FILE_MUST_EXIST)
|
||||
if fileDialog:ShowModal() == wx.wxID_OK then
|
||||
if not LoadFile(fileDialog:GetPath(), nil, true) then
|
||||
wx.wxMessageBox("Unable to load file '"..fileDialog:GetPath().."'.",
|
||||
@@ -131,33 +133,27 @@ function SaveFile(editor, filePath)
|
||||
if not filePath then
|
||||
return SaveFileAs(editor)
|
||||
else
|
||||
if (ide.config.savebak) then
|
||||
local backPath = filePath..".bak"
|
||||
os.remove(backPath)
|
||||
os.rename(filePath, backPath)
|
||||
if (ide.config.savebak) then FileRename(filePath, filePath..".bak") end
|
||||
|
||||
local st = editor:GetText()
|
||||
if GetConfigIOFilter("output") then
|
||||
st = GetConfigIOFilter("output")(filePath,st)
|
||||
end
|
||||
|
||||
local handle = io.open(filePath, "wb")
|
||||
if handle then
|
||||
local st = editor:GetText()
|
||||
|
||||
if GetConfigIOFilter("output") then
|
||||
st = GetConfigIOFilter("output")(filePath,st)
|
||||
end
|
||||
handle:write(st)
|
||||
handle:close()
|
||||
--editor:EmptyUndoBuffer()
|
||||
local ok, err = FileWrite(filePath, st)
|
||||
if ok then
|
||||
editor:SetSavePoint()
|
||||
local id = editor:GetId()
|
||||
openDocuments[id].filePath = filePath
|
||||
openDocuments[id].fileName = wx.wxFileName(filePath):GetFullName()
|
||||
openDocuments[id].modTime = GetFileModTime(filePath)
|
||||
SetDocumentModified(id, false)
|
||||
SetAutoRecoveryMark()
|
||||
return true
|
||||
else
|
||||
wx.wxMessageBox("Unable to save file '"..filePath.."'.",
|
||||
wx.wxMessageBox("Unable to save file '"..filePath.."': "..err,
|
||||
"Error",
|
||||
wx.wxOK + wx.wxCENTRE, ide.frame)
|
||||
wx.wxICON_ERROR + wx.wxOK + wx.wxCENTRE, ide.frame)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -170,24 +166,26 @@ function SaveFileAs(editor)
|
||||
local filePath = openDocuments[id].filePath
|
||||
if (not filePath) then
|
||||
filePath = FileTreeGetDir()
|
||||
filePath = (filePath or "").."untitled"
|
||||
filePath = (filePath or "")..ide.config.default.name
|
||||
end
|
||||
|
||||
local fn = wx.wxFileName(filePath)
|
||||
fn:Normalize() -- want absolute path for dialog
|
||||
|
||||
local exts = getExtsString()
|
||||
|
||||
local ext = fn:GetExt()
|
||||
local fileDialog = wx.wxFileDialog(ide.frame, "Save file as",
|
||||
fn:GetPath(wx.wxPATH_GET_VOLUME),
|
||||
fn:GetFullName(),
|
||||
exts,
|
||||
wx.wxSAVE)
|
||||
"*."..(ext and #ext > 0 and ext or "*"),
|
||||
wx.wxFD_SAVE)
|
||||
|
||||
if fileDialog:ShowModal() == wx.wxID_OK then
|
||||
local filePath = fileDialog:GetPath()
|
||||
|
||||
if SaveFile(editor, filePath) then
|
||||
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
|
||||
@@ -204,7 +202,7 @@ function SaveAll()
|
||||
local editor = document.editor
|
||||
local filePath = document.filePath
|
||||
|
||||
if document.isModified then
|
||||
if document.isModified or not document.filePath then
|
||||
SaveFile(editor, filePath) -- will call SaveFileAs if necessary
|
||||
end
|
||||
end
|
||||
@@ -271,11 +269,14 @@ function ClosePage(selection)
|
||||
-- abort the debugger if the current marker is in the window being closed
|
||||
-- also abort the debugger if it is running, as we don't know what
|
||||
-- window will need to be activated when the debugger is paused
|
||||
if debugger and debugger.pid and
|
||||
if debugger and debugger.server and
|
||||
(debugger.running or editor:MarkerNext(0, CURRENT_LINE_MARKER_VALUE) >= 0) then
|
||||
debugger.terminate()
|
||||
end
|
||||
removePage(ide.openDocuments[id].index)
|
||||
|
||||
-- disable full screen if the last tab is closed
|
||||
if not (notebook:GetSelection() >= 0) then ShowFullScreen(false) end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -288,7 +289,8 @@ function SaveModifiedDialog(editor, allow_cancel)
|
||||
local filePath = document.filePath
|
||||
local fileName = document.fileName
|
||||
if document.isModified then
|
||||
local message = "Do you want to save the changes to '"..(fileName or 'untitled').."'?"
|
||||
local message = "Do you want to save the changes to '"
|
||||
..(fileName or ide.config.default.name).."'?"
|
||||
local dlg_styles = wx.wxYES_NO + wx.wxCENTRE + wx.wxICON_QUESTION
|
||||
if allow_cancel then dlg_styles = dlg_styles + wx.wxCANCEL end
|
||||
local dialog = wx.wxMessageDialog(ide.frame, message,
|
||||
@@ -311,8 +313,13 @@ function SaveOnExit(allow_cancel)
|
||||
if (SaveModifiedDialog(document.editor, allow_cancel) == wx.wxID_CANCEL) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
document.isModified = false
|
||||
-- if all documents have been saved or refused to save, then mark those that
|
||||
-- are still modified as not modified (they don't need to be saved)
|
||||
-- to keep their tab names correct
|
||||
for id, document in pairs(openDocuments) do
|
||||
if document.isModified then SetDocumentModified(id, false) end
|
||||
end
|
||||
|
||||
return true
|
||||
@@ -397,23 +404,35 @@ function ClearAllCurrentLineMarkers()
|
||||
end
|
||||
end
|
||||
|
||||
local compileOk, compileTotal = 0, 0
|
||||
function CompileProgram(editor, quiet)
|
||||
local editorText = editor:GetText()
|
||||
-- remove shebang line (#!) as it throws a compilation error as
|
||||
-- loadstring() doesn't allow it even though lua/loadfile accepts it.
|
||||
-- replace with a new line to keep the number of lines the same.
|
||||
local editorText = editor:GetText():gsub("^#!.-\n", "\n")
|
||||
local id = editor:GetId()
|
||||
local filePath = DebuggerMakeFileName(editor, openDocuments[id].filePath)
|
||||
local _, errMsg, line_num = wxlua.CompileLuaScript(editorText, filePath)
|
||||
local func, line_num, errMsg, _ = loadstring(editorText, filePath), -1
|
||||
if not func then
|
||||
_, errMsg, line_num = wxlua.CompileLuaScript(editorText, filePath)
|
||||
end
|
||||
|
||||
if ide.frame.menuBar:IsChecked(ID_CLEAROUTPUT) then ClearOutput() end
|
||||
|
||||
compileTotal = compileTotal + 1
|
||||
if line_num > -1 then
|
||||
DisplayOutput("Compilation error on line "..tostring(line_num)..":\n"..
|
||||
errMsg:gsub("Lua:.-\n", "").."\n")
|
||||
if not quiet then editor:GotoLine(line_num-1) end
|
||||
else
|
||||
if not quiet then DisplayOutput("Compilation successful.\n") end
|
||||
compileOk = compileOk + 1
|
||||
if not quiet then
|
||||
DisplayOutput(("Compilation successful; %.0f%% success rate (%d/%d).\n")
|
||||
:format(compileOk/compileTotal*100, compileOk, compileTotal))
|
||||
end
|
||||
end
|
||||
|
||||
return line_num == -1 -- return true if it compiled ok
|
||||
return line_num == -1, editorText -- return true if it compiled ok
|
||||
end
|
||||
|
||||
------------------
|
||||
@@ -450,28 +469,22 @@ function GetOpenFiles()
|
||||
local wxfname = wx.wxFileName(document.filePath)
|
||||
wxfname:Normalize()
|
||||
|
||||
table.insert(opendocs,{fname=wxfname:GetFullPath(),id=document.index,
|
||||
cursorpos = document.editor:GetCurrentPos()})
|
||||
table.insert(opendocs, {filename=wxfname:GetFullPath(),
|
||||
id=document.index, cursorpos = document.editor:GetCurrentPos()})
|
||||
end
|
||||
end
|
||||
|
||||
-- to keep tab order
|
||||
table.sort(opendocs,function(a,b) return (a.id < b.id) end)
|
||||
|
||||
local openfiles = {}
|
||||
for i,doc in ipairs(opendocs) do
|
||||
table.insert(openfiles,{filename = doc.fname, cursorpos = doc.cursorpos} )
|
||||
end
|
||||
|
||||
local id = GetEditor()
|
||||
id = id and id:GetId()
|
||||
|
||||
return openfiles, id and openDocuments[id].index or 0
|
||||
return opendocs, {index = (id and openDocuments[id].index or 0)}
|
||||
end
|
||||
|
||||
function SetOpenFiles(nametab,index)
|
||||
function SetOpenFiles(nametab,params)
|
||||
for i,doc in ipairs(nametab) do
|
||||
local editor = LoadFile(doc.filename,nil,true)
|
||||
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)
|
||||
@@ -479,7 +492,8 @@ function SetOpenFiles(nametab,index)
|
||||
editor:EnsureCaretVisible()
|
||||
end
|
||||
end
|
||||
notebook:SetSelection(index or 0)
|
||||
notebook:SetSelection(params and params.index or 0)
|
||||
SetEditorSelection()
|
||||
end
|
||||
|
||||
local beforeFullScreenPerspective
|
||||
@@ -496,10 +510,162 @@ function ShowFullScreen(setFullScreen)
|
||||
|
||||
uimgr:GetPane("toolBar"):Show(not setFullScreen)
|
||||
uimgr:Update()
|
||||
frame:ShowFullScreen(setFullScreen)
|
||||
-- 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)
|
||||
end
|
||||
|
||||
function ProjectConfig(dir, config)
|
||||
if config then ide.session.projects[dir] = config
|
||||
else return unpack(ide.session.projects[dir] or {}) end
|
||||
end
|
||||
|
||||
function SetOpenTabs(params)
|
||||
local recovery, nametab = loadstring("return "..params.recovery)
|
||||
if recovery then recovery, nametab = pcall(recovery) end
|
||||
if not recovery then
|
||||
DisplayOutput("Can't process auto-recovery record; invalid format: "..nametab.."\n")
|
||||
return
|
||||
end
|
||||
DisplayOutput("Found auto-recovery record and restored saved session.\n")
|
||||
for _,doc in ipairs(nametab) do
|
||||
local editor = doc.filename and LoadFile(doc.filename,nil,true,true) or NewFile()
|
||||
local opendoc = openDocuments[editor:GetId()]
|
||||
if doc.content then
|
||||
notebook:SetPageText(opendoc.index, doc.tabname)
|
||||
editor:SetText(doc.content)
|
||||
if doc.filename and doc.modified < opendoc.modTime:GetTicks() then
|
||||
DisplayOutput("File '"..doc.filename.."' has more recent timestamp than restored '"..doc.tabname.."'."
|
||||
.." Please review before saving.\n")
|
||||
end
|
||||
end
|
||||
editor:SetCurrentPos(doc.cursorpos or 0)
|
||||
editor:SetSelectionStart(doc.cursorpos or 0)
|
||||
editor:SetSelectionEnd(doc.cursorpos or 0)
|
||||
editor:EnsureCaretVisible()
|
||||
end
|
||||
notebook:SetSelection(params and params.index or 0)
|
||||
SetEditorSelection()
|
||||
end
|
||||
|
||||
local function getOpenTabs()
|
||||
local opendocs = {}
|
||||
for id, document in pairs(ide.openDocuments) do
|
||||
table.insert(opendocs, {
|
||||
filename = document.filePath,
|
||||
tabname = notebook:GetPageText(document.index),
|
||||
modified = document.modTime and document.modTime:GetTicks(), -- get number of seconds
|
||||
content = document.isModified and document.editor:GetText() or nil,
|
||||
id = document.index, cursorpos = document.editor:GetCurrentPos()})
|
||||
end
|
||||
|
||||
-- to keep tab order
|
||||
table.sort(opendocs, function(a,b) return (a.id < b.id) end)
|
||||
|
||||
local id = GetEditor()
|
||||
id = id and id:GetId()
|
||||
return opendocs, {index = (id and openDocuments[id].index or 0)}
|
||||
end
|
||||
|
||||
function SetAutoRecoveryMark()
|
||||
ide.session.lastupdated = os.time()
|
||||
end
|
||||
|
||||
local function saveAutoRecovery(event)
|
||||
if not ide.config.autorecoverinactivity or not ide.session.lastupdated then return end
|
||||
if ide.session.lastupdated < (ide.session.lastsaved or 0)
|
||||
or ide.session.lastupdated + ide.config.autorecoverinactivity > os.time()
|
||||
then return end
|
||||
|
||||
-- find all open modified files and save them
|
||||
local opentabs, params = getOpenTabs()
|
||||
if #opentabs > 0 then
|
||||
params.recovery = require('mobdebug').line(opentabs, {comment = false})
|
||||
SettingsSaveAll()
|
||||
SettingsSaveFileSession({}, params)
|
||||
ide.settings:Flush()
|
||||
end
|
||||
ide.session.lastsaved = os.time()
|
||||
ide.frame.statusBar:SetStatusText("Saved auto-recover at "..os.date("%H:%M:%S")..".", 1)
|
||||
end
|
||||
|
||||
function StoreRestoreProjectTabs(curdir, newdir)
|
||||
local win = ide.osname == 'Windows'
|
||||
local interpreter = ide.interpreter.fname
|
||||
local current, closing, restore = notebook:GetSelection(), 0, false
|
||||
|
||||
if curdir and #curdir > 0 then
|
||||
local lowcurdir = win and string.lower(curdir) or curdir
|
||||
local lownewdir = win and string.lower(newdir) or newdir
|
||||
local projdocs, closdocs = {}, {}
|
||||
for _, document in ipairs(GetOpenFiles()) do
|
||||
local dpath = win and string.lower(document.filename) or document.filename
|
||||
if dpath:find(lowcurdir, 1, true) then
|
||||
table.insert(projdocs, document)
|
||||
closing = closing + (document.id < current and 1 or 0)
|
||||
-- only close if the file is not in new project as it would be reopened
|
||||
if not dpath:find(lownewdir, 1, true) then
|
||||
table.insert(closdocs, document)
|
||||
end
|
||||
elseif document.id == current then restore = true end
|
||||
end
|
||||
|
||||
-- adjust for the number of closing tabs on the left from the current one
|
||||
current = current - closing
|
||||
|
||||
-- save opened files from this project
|
||||
ProjectConfig(curdir, {projdocs,
|
||||
{index = notebook:GetSelection() - current, interpreter = interpreter}})
|
||||
|
||||
-- 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
|
||||
end
|
||||
|
||||
local files, params = ProjectConfig(newdir)
|
||||
if files then restoreFiles(files) end
|
||||
|
||||
if params and params.interpreter and ide.interpreter.fname ~= params.interpreter then
|
||||
ProjectSetInterpreter(params.interpreter) -- set the interpreter
|
||||
end
|
||||
|
||||
local index = params and params.index
|
||||
if notebook:GetPageCount() == 0 then NewFile()
|
||||
elseif restore and current >= 0 then notebook:SetSelection(current)
|
||||
elseif index and index >= 0 and files[index+1] then
|
||||
-- move the editor tab to the front with the file from the config
|
||||
LoadFile(files[index+1].filename, nil, true)
|
||||
SetEditorSelection() -- activate the editor in the active tab
|
||||
end
|
||||
|
||||
-- remove current config as it may change; the current configuration is
|
||||
-- stored with the general config.
|
||||
-- The project configuration will be updated when the project is changed.
|
||||
ProjectConfig(newdir, {})
|
||||
end
|
||||
|
||||
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
|
||||
-- CloseWindow is called several times in this case and exit. Similar
|
||||
-- behavior has been also seen on Linux, so this logic applies everywhere.
|
||||
if ide.exitingProgram then os.exit() end
|
||||
|
||||
ide.exitingProgram = true -- don't handle focus events
|
||||
|
||||
if not SaveOnExit(event:CanVeto()) then
|
||||
@@ -509,15 +675,24 @@ function CloseWindow(event)
|
||||
end
|
||||
|
||||
ShowFullScreen(false)
|
||||
SettingsSaveProjectSession(FileTreeGetProjects())
|
||||
SettingsSaveFileSession(GetOpenFiles())
|
||||
SettingsSaveView()
|
||||
SettingsSaveFramePosition(ide.frame, "MainFrame")
|
||||
SettingsSaveEditorSettings()
|
||||
DebuggerCloseWatchWindow()
|
||||
DebuggerCloseStackWindow()
|
||||
DebuggerShutdown()
|
||||
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
|
||||
end
|
||||
frame:Connect(wx.wxEVT_CLOSE_WINDOW, CloseWindow)
|
||||
|
||||
frame:Connect(wx.wxEVT_TIMER, saveAutoRecovery)
|
||||
|
||||
if ide.config.autorecoverinactivity then
|
||||
ide.session.timer = wx.wxTimer(frame)
|
||||
-- check at least 5s to be never more than 5s off
|
||||
ide.session.timer:Start(math.min(5, ide.config.autorecoverinactivity)*1000)
|
||||
end
|
||||
|
||||
@@ -17,26 +17,43 @@ 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.hostname = (function() -- check what address is resolvable
|
||||
local addr = wx.wxIPV4address()
|
||||
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
|
||||
if addr:Hostname(host) then return host end
|
||||
if host and #host > 0 and addr:Hostname(host) then return host end
|
||||
end
|
||||
return "localhost" -- last resort; no known good hostname
|
||||
end)()
|
||||
|
||||
local notebook = ide.frame.notebook
|
||||
|
||||
local function updateWatchesSync()
|
||||
local function updateWatchesSync(num)
|
||||
local watchCtrl = debugger.watchCtrl
|
||||
if watchCtrl and debugger.server
|
||||
and not debugger.running and not debugger.scratchpad then
|
||||
for idx = 0, watchCtrl:GetItemCount() - 1 do
|
||||
local expression = watchCtrl:GetItemText(idx)
|
||||
local _, values, error = debugger.evaluate(expression)
|
||||
if error then error = error:gsub("%[.-%]:%d+:%s+","")
|
||||
elseif #values == 0 then values = {'nil'} end
|
||||
watchCtrl:SetItem(idx, 1, error and ('error: '..error) or values[1])
|
||||
if not num or idx == num then
|
||||
local expression = watchCtrl:GetItemText(idx)
|
||||
local _, values, error = debugger.evaluate(expression)
|
||||
if error then error = error:gsub("%[.-%]:%d+:%s+","")
|
||||
elseif #values == 0 then values = {'nil'} end
|
||||
|
||||
local newval = error and ('error: '..error) or values[1]
|
||||
-- get the current value from a list item
|
||||
do local litem = wx.wxListItem()
|
||||
litem:SetMask(wx.wxLIST_MASK_TEXT)
|
||||
litem:SetId(idx)
|
||||
litem:SetColumn(1)
|
||||
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())
|
||||
end
|
||||
|
||||
watchCtrl:SetItem(idx, 1, newval)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -57,8 +74,14 @@ local function updateStackSync()
|
||||
local stackCtrl = debugger.stackCtrl
|
||||
if stackCtrl and debugger.server
|
||||
and not debugger.running and not debugger.scratchpad then
|
||||
local stack = debugger.stack()
|
||||
if not stack or #stack == 0 then stackCtrl:DeleteAllItems(); return end
|
||||
local stack, _, err = debugger.stack()
|
||||
if not stack or #stack == 0 then
|
||||
stackCtrl:DeleteAllItems()
|
||||
if err then -- report an error if any
|
||||
stackCtrl:AppendItem(stackCtrl:AddRoot("Stack"), "Error: " .. err, 0)
|
||||
end
|
||||
return
|
||||
end
|
||||
stackCtrl:Freeze()
|
||||
stackCtrl:DeleteAllItems()
|
||||
local params = {comment = false, nocode = true}
|
||||
@@ -109,14 +132,20 @@ local function updateStackSync()
|
||||
end
|
||||
|
||||
local function updateStackAndWatches()
|
||||
-- check if the debugger is running and may be waiting for a response.
|
||||
-- allow that request to finish, otherwise updateWatchesSync() does nothing.
|
||||
if debugger.running then debugger.update() end
|
||||
if debugger.server and not debugger.running then
|
||||
copas.addthread(function() updateStackSync() updateWatchesSync() end)
|
||||
end
|
||||
end
|
||||
|
||||
local function updateWatches()
|
||||
local function updateWatches(num)
|
||||
-- check if the debugger is running and may be waiting for a response.
|
||||
-- allow that request to finish, otherwise updateWatchesSync() does nothing.
|
||||
if debugger.running then debugger.update() end
|
||||
if debugger.server and not debugger.running then
|
||||
copas.addthread(function() updateWatchesSync() end)
|
||||
copas.addthread(function() updateWatchesSync(num) end)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -136,24 +165,20 @@ local function killClient()
|
||||
end
|
||||
end
|
||||
|
||||
local function activateDocument(fileName, line)
|
||||
if not fileName then return end
|
||||
local function activateDocument(file, line)
|
||||
if not file then return end
|
||||
|
||||
if not wx.wxIsAbsolutePath(fileName) then
|
||||
fileName = wx.wxGetCwd().."/"..fileName
|
||||
end
|
||||
|
||||
if wx.__WXMSW__ then
|
||||
fileName = wx.wxUnix2DosFilename(fileName)
|
||||
if not wx.wxIsAbsolutePath(file) and debugger.basedir then
|
||||
file = debugger.basedir .. file
|
||||
end
|
||||
|
||||
local activated
|
||||
local indebugger = file:find('mobdebug%.lua$')
|
||||
local fileName = wx.wxFileName(file)
|
||||
for _, document in pairs(ide.openDocuments) do
|
||||
local editor = document.editor
|
||||
-- for running in cygwin, use same type of separators
|
||||
local filePath = string.gsub(document.filePath, "\\", "/")
|
||||
local fileName = string.gsub(fileName, "\\", "/")
|
||||
if string.upper(filePath) == string.upper(fileName) then
|
||||
-- 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
|
||||
local selection = document.index
|
||||
notebook:SetSelection(selection)
|
||||
SetEditorSelection(selection)
|
||||
@@ -167,7 +192,22 @@ local function activateDocument(fileName, line)
|
||||
end
|
||||
end
|
||||
|
||||
return activated ~= nil, activated
|
||||
if not activated and not indebugger 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.
|
||||
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
|
||||
debugger.missing[file] = true
|
||||
DisplayOutput(("Couldn't activate file '%s' for debugging; continuing without it.\n")
|
||||
:format(file))
|
||||
end
|
||||
end
|
||||
|
||||
return activated ~= nil
|
||||
end
|
||||
|
||||
local function reSetBreakpoints()
|
||||
@@ -191,13 +231,16 @@ local function reSetBreakpoints()
|
||||
end
|
||||
|
||||
debugger.shell = function(expression, isstatement)
|
||||
if debugger.server and not debugger.running then
|
||||
-- check if the debugger is running and may be waiting for a response.
|
||||
-- allow that request to finish, otherwise updateWatchesSync() does nothing.
|
||||
if debugger.running then debugger.update() end
|
||||
if debugger.server and not debugger.running and not debugger.scratchpad then
|
||||
copas.addthread(function ()
|
||||
-- exec command is not expected to return anything.
|
||||
-- eval command returns 0 or more results.
|
||||
-- 'values' has a list of serialized results returned.
|
||||
-- as it is not possible to distinguish between 0 and nil returned,
|
||||
-- 'nil' is always returned in this case.
|
||||
-- as it is not possible to distinguish between 0 results and one
|
||||
-- 'nil' value returned, 'nil' is always returned in this case.
|
||||
-- the first value returned by eval command is not used;
|
||||
-- this may need to be taken into account by other debuggers.
|
||||
local addedret, forceexpression = true, expression:match("^%s*=%s*")
|
||||
@@ -205,6 +248,7 @@ debugger.shell = function(expression, isstatement)
|
||||
local _, values, err = debugger.evaluate(expression)
|
||||
if not forceexpression and err and
|
||||
(err:find("'<eof>' expected near '") or
|
||||
err:find("'%(' expected near") or
|
||||
err:find("unexpected symbol near '")) then
|
||||
_, values, err = debugger.execute(expression)
|
||||
addedret = false
|
||||
@@ -214,12 +258,29 @@ debugger.shell = function(expression, isstatement)
|
||||
if addedret then err = err:gsub('^%[string "return ', '[string "') end
|
||||
DisplayShellErr(err)
|
||||
elseif addedret or #values > 0 then
|
||||
if forceexpression then -- display elements as multi-line
|
||||
local mobdebug = require "mobdebug"
|
||||
for i,v in pairs(values) do -- stringify each of the returned values
|
||||
local func = loadstring('return '..v) -- deserialize the value first
|
||||
if func then -- if it's deserialized correctly
|
||||
values[i] = (forceexpression and i > 1 and '\n' or '') ..
|
||||
mobdebug.line(func(), {nocode = true, comment = 0,
|
||||
-- if '=' is used, then use multi-line serialized output
|
||||
indent = forceexpression and ' ' or nil})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- if empty table is returned, then show nil if this was an expression
|
||||
if #values == 0 and (forceexpression or not isstatement) then
|
||||
values = {'nil'}
|
||||
end
|
||||
DisplayShell((table.unpack or unpack)(values))
|
||||
end
|
||||
|
||||
-- refresh Stack and Watch windows if executed a statement (and no err)
|
||||
if isstatement and not err and not addret and #values == 0 then
|
||||
updateStackSync() updateWatchesSync() end
|
||||
end)
|
||||
end
|
||||
end
|
||||
@@ -235,19 +296,34 @@ debugger.listen = function()
|
||||
return
|
||||
end
|
||||
|
||||
copas.setErrorHandler(function(error)
|
||||
DisplayOutput("Can't start debugging session due to internal error '" .. error .. "'.\n")
|
||||
debugger.terminate()
|
||||
end)
|
||||
|
||||
local options = debugger.options or {}
|
||||
if not debugger.scratchpad then SetAllEditorsReadOnly(true) end
|
||||
local wxfilepath = GetEditorFileAndCurInfo()
|
||||
local startfile = options.startfile or wxfilepath:GetFullPath()
|
||||
local basedir = options.basedir
|
||||
or FileTreeGetDir()
|
||||
or wxfilepath:GetPath(wx.wxPATH_GET_VOLUME + wx.wxPATH_GET_SEPARATOR)
|
||||
-- guarantee that the path has a trailing separator
|
||||
debugger.basedir = wx.wxFileName.DirName(basedir):GetFullPath()
|
||||
|
||||
debugger.server = copas.wrap(skt)
|
||||
debugger.socket = skt
|
||||
debugger.loop = false
|
||||
debugger.scratchable = false
|
||||
debugger.stats = {line = 0}
|
||||
debugger.missing = {}
|
||||
|
||||
local wxfilepath = GetEditorFileAndCurInfo()
|
||||
local startfile = options.startfile or options.startwith
|
||||
or (wxfilepath and wxfilepath:GetFullPath())
|
||||
|
||||
if not startfile then
|
||||
DisplayOutput("Can't start debugging without an opened file or with the current file not being saved ('untitled.lua').\n")
|
||||
return debugger.terminate()
|
||||
end
|
||||
|
||||
local startpath = wx.wxFileName(startfile):GetPath(wx.wxPATH_GET_VOLUME + wx.wxPATH_GET_SEPARATOR)
|
||||
local basedir = options.basedir or FileTreeGetDir() or startpath
|
||||
-- guarantee that the path has a trailing separator
|
||||
debugger.basedir = wx.wxFileName.DirName(basedir):GetFullPath()
|
||||
|
||||
-- load the remote file into the debugger
|
||||
-- set basedir first, before loading to make sure that the path is correct
|
||||
@@ -255,9 +331,15 @@ debugger.listen = function()
|
||||
|
||||
reSetBreakpoints()
|
||||
|
||||
if (options.run) then
|
||||
local file, line = debugger.handle("run")
|
||||
activateDocument(file, line)
|
||||
if (options.startwith) then
|
||||
local file, line, err = debugger.loadfile(options.startwith)
|
||||
if err then
|
||||
DisplayOutput(("Can't run the entry point script (%s). Compilation error:\n%s\n")
|
||||
:format(options.startwith, err))
|
||||
return debugger.terminate()
|
||||
end
|
||||
elseif (options.run) then
|
||||
-- do nothing here
|
||||
elseif (debugger.scratchpad) then
|
||||
debugger.scratchpad.updated = true
|
||||
else
|
||||
@@ -267,35 +349,28 @@ debugger.listen = function()
|
||||
-- with start() method, which can't load new files
|
||||
-- if file and line are set, this indicates option #2
|
||||
if file and line then
|
||||
-- if the file name is absolute, try to load it
|
||||
local activated
|
||||
if wx.wxIsAbsolutePath(file) then
|
||||
activated = activateDocument(file, line)
|
||||
else
|
||||
-- try to find a proper file based on file name
|
||||
-- first check using basedir that was set based on current file path
|
||||
if not activated then
|
||||
activated = activateDocument(debugger.basedir..file, line)
|
||||
end
|
||||
local activated = activateDocument(file, line)
|
||||
|
||||
-- if not found, check using full file path and reset basedir
|
||||
if not activated then
|
||||
local path = wxfilepath:GetPath(wx.wxPATH_GET_VOLUME + wx.wxPATH_GET_SEPARATOR)
|
||||
activated = activateDocument(path..file, line)
|
||||
if activated then
|
||||
debugger.basedir = path
|
||||
debugger.handle("basedir " .. debugger.basedir)
|
||||
-- reset breakpoints again as basedir has changed
|
||||
reSetBreakpoints()
|
||||
end
|
||||
-- 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)
|
||||
if activated then
|
||||
debugger.basedir = startpath
|
||||
debugger.handle("basedir " .. debugger.basedir)
|
||||
-- reset breakpoints again as basedir has changed
|
||||
reSetBreakpoints()
|
||||
end
|
||||
end
|
||||
|
||||
if not activated then
|
||||
DisplayOutput(("Can't find file '%s' to activate for debugging; open the file in the editor before debugging.\n")
|
||||
DisplayOutput(("Can't find file '%s' in the current project to activate for debugging. Update the project or open the file in the editor before debugging.\n")
|
||||
:format(file))
|
||||
return debugger.terminate()
|
||||
end
|
||||
|
||||
-- debugger may still be available for scratchpad,
|
||||
-- if the interpreter signals scratchpad support, so enable it.
|
||||
debugger.scratchable = ide.interpreter.scratchextloop ~= nil
|
||||
elseif err then
|
||||
DisplayOutput(("Can't debug the script in the active editor window. Compilation error:\n%s\n")
|
||||
:format(err))
|
||||
@@ -315,6 +390,16 @@ debugger.listen = function()
|
||||
|
||||
DisplayOutput(("Debugging session started in '%s'.\n")
|
||||
:format(debugger.basedir))
|
||||
|
||||
if (options.runstart) then
|
||||
ClearAllCurrentLineMarkers()
|
||||
debugger.run()
|
||||
end
|
||||
|
||||
if (options.run) then
|
||||
local file, line = debugger.handle("run")
|
||||
activateDocument(file, line)
|
||||
end
|
||||
end)
|
||||
debugger.listening = true
|
||||
end
|
||||
@@ -349,10 +434,8 @@ debugger.exec = function(command)
|
||||
DebuggerStop()
|
||||
return
|
||||
else
|
||||
if debugger.basedir and not wx.wxIsAbsolutePath(file) then
|
||||
file = debugger.basedir .. file
|
||||
end
|
||||
if activateDocument(file, line) then
|
||||
debugger.stats.line = debugger.stats.line + 1
|
||||
if debugger.loop then
|
||||
updateStackSync()
|
||||
updateWatchesSync()
|
||||
@@ -361,7 +444,15 @@ debugger.exec = function(command)
|
||||
return
|
||||
end
|
||||
else
|
||||
out = "out" -- redo now trying to get out of this file
|
||||
-- redo now; if the call is from the debugger, then repeat
|
||||
-- the same command, except when it was "run" (switch to 'step');
|
||||
-- this is needed to "break" execution that happens in on() call.
|
||||
-- in all other cases get out of this file.
|
||||
-- don't get out of "mobdebug", because it may happen with
|
||||
-- start() or on() call, which will get us out of the current
|
||||
-- file, which is not what we want.
|
||||
out = (file:find('mobdebug%.lua$')
|
||||
and (command == 'run' and 'step' or command) or "out")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -381,7 +472,15 @@ end
|
||||
debugger.loadstring = function(file, string)
|
||||
return debugger.handle("loadstring '" .. file .. "' " .. string)
|
||||
end
|
||||
debugger.update = function() copas.step(0) end
|
||||
debugger.update = function()
|
||||
copas.step(0)
|
||||
-- if there are any pending activations
|
||||
if debugger.activate then
|
||||
local file, line = (table.unpack or unpack)(debugger.activate)
|
||||
if LoadFile(file) then activateDocument(file, line) end
|
||||
debugger.activate = nil
|
||||
end
|
||||
end
|
||||
debugger.terminate = function()
|
||||
if debugger.server then
|
||||
if debugger.pid then -- if there is PID, try local kill
|
||||
@@ -427,6 +526,17 @@ end
|
||||
debugger.breakpoint = function(file, line, state)
|
||||
debugger.handleAsync((state and "setb " or "delb ") .. file .. " " .. line)
|
||||
end
|
||||
debugger.quickeval = function(var, callback)
|
||||
if debugger.server and not debugger.running and not debugger.scratchpad then
|
||||
copas.addthread(function ()
|
||||
local _, values, err = debugger.evaluate(var)
|
||||
local val = err
|
||||
and err:gsub("%[.-%]:%d+:%s*","error: ")
|
||||
or (var .. " = " .. (#values > 0 and values[1] or 'nil'))
|
||||
if callback then callback(val) end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
----------------------------------------------
|
||||
-- public api
|
||||
@@ -450,7 +560,13 @@ function DebuggerStop()
|
||||
ShellSupportRemote(nil)
|
||||
ClearAllCurrentLineMarkers()
|
||||
DebuggerScratchpadOff()
|
||||
DisplayOutput("Debugging session completed.\n")
|
||||
DisplayOutput(("Debugging session completed (traced %d instruction%s).\n")
|
||||
:format(debugger.stats.line, debugger.stats.line == 1 and '' or 's'))
|
||||
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
|
||||
|
||||
@@ -474,17 +590,18 @@ end
|
||||
-- of it and if done inside a function, icons do not work as expected
|
||||
local imglist = wx.wxImageList(16,16)
|
||||
do
|
||||
local getBitmap = (ide.app.createbitmap or wx.wxArtProvider.GetBitmap)
|
||||
local size = wx.wxSize(16,16)
|
||||
-- 0 = stack call
|
||||
imglist:Add((ide.app.createbitmap or wx.wxArtProvider.GetBitmap)(wx.wxART_GO_FORWARD, wx.wxART_OTHER, size))
|
||||
imglist:Add(getBitmap(wx.wxART_GO_FORWARD, wx.wxART_OTHER, size))
|
||||
-- 1 = local variables
|
||||
imglist:Add((ide.app.createbitmap or wx.wxArtProvider.GetBitmap)(wx.wxART_LIST_VIEW, wx.wxART_OTHER, size))
|
||||
imglist:Add(getBitmap(wx.wxART_LIST_VIEW, wx.wxART_OTHER, size))
|
||||
-- 2 = upvalues
|
||||
imglist:Add((ide.app.createbitmap or wx.wxArtProvider.GetBitmap)(wx.wxART_REPORT_VIEW, wx.wxART_OTHER, size))
|
||||
imglist:Add(getBitmap(wx.wxART_REPORT_VIEW, wx.wxART_OTHER, size))
|
||||
end
|
||||
|
||||
function DebuggerCreateStackWindow()
|
||||
if (debugger.stackWindow) then return end
|
||||
if (debugger.stackWindow) then return updateStackAndWatches() end
|
||||
local width = 360
|
||||
local stackWindow = wx.wxFrame(ide.frame, wx.wxID_ANY,
|
||||
"Stack Window",
|
||||
@@ -524,7 +641,7 @@ function DebuggerCreateStackWindow()
|
||||
local strval = mobdebug.line(value, {comment = false, nocode = true})
|
||||
local text = type(name) == "number"
|
||||
and (num == name and strval or ("[%s] = %s"):format(name, strval))
|
||||
or ("%s = %s"):format(name, strval)
|
||||
or ("%s = %s"):format(tostring(name), strval)
|
||||
local item = stackCtrl:AppendItem(item_id, text, image)
|
||||
if checkIfExpandable(value, item) then
|
||||
stackCtrl:SetItemHasChildren(item, true)
|
||||
@@ -542,7 +659,7 @@ function DebuggerCreateStackWindow()
|
||||
end
|
||||
|
||||
function DebuggerCreateWatchWindow()
|
||||
if (debugger.watchWindow) then return end
|
||||
if (debugger.watchWindow) then return updateWatches() end
|
||||
local width = 360
|
||||
local watchWindow = wx.wxFrame(ide.frame, wx.wxID_ANY,
|
||||
"Watch Window",
|
||||
@@ -552,9 +669,9 @@ function DebuggerCreateWatchWindow()
|
||||
debugger.watchWindow = watchWindow
|
||||
|
||||
local watchMenu = wx.wxMenu{
|
||||
{ ID_ADDWATCH, "&Add Watch" },
|
||||
{ ID_ADDWATCH, "&Add Watch\tIns" },
|
||||
{ ID_EDITWATCH, "&Edit Watch\tF2" },
|
||||
{ ID_REMOVEWATCH, "&Remove Watch" },
|
||||
{ ID_REMOVEWATCH, "&Remove Watch\tDel" },
|
||||
{ ID_EVALUATEWATCH, "Evaluate &Watches" }}
|
||||
|
||||
local watchMenuBar = wx.wxMenuBar()
|
||||
@@ -593,6 +710,8 @@ function DebuggerCreateWatchWindow()
|
||||
return -1
|
||||
end
|
||||
|
||||
local defaultExpr = ""
|
||||
|
||||
watchWindow:Connect(wx.wxEVT_CLOSE_WINDOW,
|
||||
function (event)
|
||||
DebuggerCloseWatchWindow()
|
||||
@@ -604,7 +723,7 @@ function DebuggerCreateWatchWindow()
|
||||
watchWindow:Connect(ID_ADDWATCH, wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function ()
|
||||
local row = watchCtrl:InsertItem(watchCtrl:GetItemCount(), "Expr")
|
||||
watchCtrl:SetItem(row, 0, "Expr")
|
||||
watchCtrl:SetItem(row, 0, defaultExpr)
|
||||
watchCtrl:SetItem(row, 1, "Value")
|
||||
watchCtrl:EditLabel(row)
|
||||
end)
|
||||
@@ -642,22 +761,42 @@ function DebuggerCreateWatchWindow()
|
||||
|
||||
watchCtrl:Connect(wx.wxEVT_COMMAND_LIST_END_LABEL_EDIT,
|
||||
function (event)
|
||||
if #(event:GetText()) > 0 then
|
||||
watchCtrl:SetItem(event:GetIndex(), 0, event:GetText())
|
||||
updateWatches()
|
||||
local row = event:GetIndex()
|
||||
if event:IsEditCancelled() then
|
||||
if watchCtrl:GetItemText(row) == defaultExpr then
|
||||
watchCtrl:DeleteItem(row)
|
||||
end
|
||||
else
|
||||
watchCtrl:SetItem(row, 0, event:GetText())
|
||||
updateWatches(row)
|
||||
end
|
||||
event:Skip()
|
||||
end)
|
||||
end
|
||||
|
||||
function DebuggerMakeFileName(editor, filePath)
|
||||
if not filePath then
|
||||
filePath = "file"..tostring(editor)
|
||||
function DebuggerAddWatch(watch)
|
||||
if (not debugger.watchWindow) then DebuggerCreateWatchWindow() end
|
||||
|
||||
local watchCtrl = debugger.watchCtrl
|
||||
-- check if this expression is already on the list
|
||||
for idx = 0, watchCtrl:GetItemCount() - 1 do
|
||||
if watchCtrl:GetItemText(idx) == watch then return end
|
||||
end
|
||||
return filePath
|
||||
|
||||
local row = watchCtrl:InsertItem(watchCtrl:GetItemCount(), "Expr")
|
||||
watchCtrl:SetItem(row, 0, watch)
|
||||
watchCtrl:SetItem(row, 1, "Value")
|
||||
|
||||
updateWatches(row)
|
||||
end
|
||||
|
||||
function DebuggerMakeFileName(editor, filePath)
|
||||
return filePath or ide.config.default.fullname
|
||||
end
|
||||
|
||||
function DebuggerToggleBreakpoint(editor, line)
|
||||
-- ignore requests to toggle when the debugger is running
|
||||
if debugger.server and debugger.running then return end
|
||||
local markers = editor:MarkerGet(line)
|
||||
if markers >= CURRENT_LINE_MARKER_VALUE then
|
||||
markers = markers - CURRENT_LINE_MARKER_VALUE
|
||||
@@ -679,51 +818,68 @@ end
|
||||
|
||||
-- scratchpad functions
|
||||
|
||||
local function q(s) return s:gsub('([%(%)%.%%%+%-%*%?%[%^%$%]])','%%%1') end
|
||||
function DebuggerRefreshScratchpad()
|
||||
if debugger.scratchpad and debugger.scratchpad.updated then
|
||||
|
||||
local scratchpadEditor = debugger.scratchpad.editor
|
||||
local compiled, code = CompileProgram(scratchpadEditor, true)
|
||||
if not compiled then return end
|
||||
|
||||
if debugger.scratchpad.running then
|
||||
-- break the current execution first
|
||||
-- don't try too frequently to avoid overwhelming the debugger
|
||||
local now = os.clock()
|
||||
local now = TimeGet()
|
||||
if now - debugger.scratchpad.running > 0.250 then
|
||||
debugger.breaknow()
|
||||
debugger.scratchpad.running = now
|
||||
end
|
||||
else
|
||||
local clear = ide.frame.menuBar:IsChecked(ID_CLEAROUTPUT)
|
||||
local scratchpadEditor = debugger.scratchpad.editor
|
||||
local code = scratchpadEditor:GetText()
|
||||
local filePath = DebuggerMakeFileName(scratchpadEditor,
|
||||
ide.openDocuments[scratchpadEditor:GetId()].filePath)
|
||||
|
||||
-- this is a special error message that is generated at the very end
|
||||
-- of each script to avoid exiting the (debugee) scratchpad process.
|
||||
-- these errors are handled and not reported to the user
|
||||
local errormsg = 'execution suspended at ' .. os.clock()
|
||||
local errormsg = 'execution suspended at ' .. TimeGet()
|
||||
local stopper = "\ndo error('" .. errormsg .. "') end"
|
||||
-- store if interpreter requires a special handling for external loop
|
||||
local extloop = ide.interpreter.scratchextloop
|
||||
|
||||
local function reloadScratchpadCode()
|
||||
debugger.scratchpad.running = os.clock()
|
||||
debugger.scratchpad.running = TimeGet()
|
||||
debugger.scratchpad.updated = false
|
||||
|
||||
local _, _, err = debugger.loadstring(filePath, code .. stopper)
|
||||
local prefix = "Compilation error"
|
||||
debugger.scratchpad.runs = (debugger.scratchpad.runs or 0) + 1
|
||||
|
||||
if clear then ClearOutput() end
|
||||
|
||||
-- the code can be running in two ways under scratchpad:
|
||||
-- 1. controlled by the application, requires stopper (most apps)
|
||||
-- 2. controlled by some external loop (for example, love2d).
|
||||
-- in the first case we need to reload the app after each change
|
||||
-- in the second case, we need to load the app once and then
|
||||
-- "execute" new code to reflect the changes (with some limitations).
|
||||
local _, _, err
|
||||
if extloop then -- if the execution is controlled by an external loop
|
||||
if debugger.scratchpad.runs == 1
|
||||
then _, _, err = debugger.loadstring(filePath, code)
|
||||
else _, _, err = debugger.execute(code) end
|
||||
else _, _, err = debugger.loadstring(filePath, code .. stopper) end
|
||||
|
||||
-- when execute() is used, it's not possible to distinguish between
|
||||
-- compilation and run-time error, so just report as "Scratchpad error"
|
||||
local prefix = extloop and "Scratchpad error" or "Compilation error"
|
||||
|
||||
if not err then
|
||||
_, _, err = debugger.handle("run")
|
||||
prefix = "Execution error"
|
||||
end
|
||||
if err and not err:find(errormsg) then
|
||||
local line = err:match('.*%[string "[%w:/%\\_%-%.]+"%]:(%d+)%s*:')
|
||||
-- check if the line number in the error matches the line we added
|
||||
-- to stop the script; if so, compile it the usual way and report.
|
||||
-- the usual way is not used all the time because it is slow
|
||||
if prefix == "Compilation error" and
|
||||
tonumber(line) == scratchpadEditor:GetLineCount()+1 then
|
||||
_, err, line = wxlua.CompileLuaScript(code, filePath)
|
||||
err = err:gsub("Lua:.-\n", "") -- remove "syntax error" part
|
||||
local fragment, line = err:match('.-%[string "([^\010\013]+)"%]:(%d+)%s*:')
|
||||
-- make the code shorter to better see the error message
|
||||
if prefix == "Scratchpad error" and fragment and #fragment > 30 then
|
||||
err = err:gsub(q(fragment), function(s) return s:sub(1,30)..'...' end)
|
||||
end
|
||||
DisplayOutput(prefix .. (line and " on line " .. line or "") .. ":\n"
|
||||
.. err:gsub('stack traceback:.+', ''):gsub('\n+$', '') .. "\n")
|
||||
@@ -756,6 +912,8 @@ function DebuggerScratchpadOn(editor)
|
||||
|
||||
local scratchpadEditor = editor
|
||||
scratchpadEditor:StyleSetUnderline(numberStyle, true)
|
||||
debugger.scratchpad.margin = scratchpadEditor:GetMarginWidth(0) +
|
||||
scratchpadEditor:GetMarginWidth(1) + scratchpadEditor:GetMarginWidth(2)
|
||||
|
||||
scratchpadEditor:Connect(wxstc.wxEVT_STC_MODIFIED, function(event)
|
||||
local evtype = event:GetModificationType()
|
||||
@@ -800,8 +958,8 @@ function DebuggerScratchpadOn(editor)
|
||||
end
|
||||
scratchpad.start = nstart + 1
|
||||
scratchpad.length = nend - nstart - 1
|
||||
scratchpad.origin = tonumber(scratchpadEditor:GetTextRange(nstart+1,nend))
|
||||
if scratchpad.origin then
|
||||
scratchpad.origin = scratchpadEditor:GetTextRange(nstart+1,nend)
|
||||
if tonumber(scratchpad.origin) then
|
||||
scratchpad.point = point
|
||||
scratchpadEditor:CaptureMouse()
|
||||
end
|
||||
@@ -823,31 +981,52 @@ function DebuggerScratchpadOn(editor)
|
||||
|
||||
-- record the fact that we are over a number or dragging slider
|
||||
scratchpad.over = scratchpad and
|
||||
(ipoint or (bit.band(scratchpadEditor:GetStyleAt(pos),31) == numberStyle))
|
||||
(ipoint ~= nil or (bit.band(scratchpadEditor:GetStyleAt(pos),31) == numberStyle))
|
||||
|
||||
if ipoint then
|
||||
-- calculate difference in point position
|
||||
local dx = point.x - ipoint.x
|
||||
local dy = - (point.y - ipoint.y) -- invert dy as y increases down
|
||||
|
||||
-- re-calculate the value
|
||||
local startpos = scratchpad.start
|
||||
local endpos = scratchpad.start+scratchpad.length
|
||||
local num = tonumber(scratchpad.origin) + dx/10
|
||||
|
||||
-- calculate difference in point position
|
||||
local dx = point.x - ipoint.x
|
||||
|
||||
-- calculate the number of decimal digits after the decimal point
|
||||
local origin = scratchpad.origin
|
||||
local decdigits = #(origin:match('%.(%d+)') or '')
|
||||
|
||||
-- calculate new value
|
||||
local value = tonumber(origin) + dx * 10^-decdigits
|
||||
|
||||
-- convert new value back to string to check the number of decimal points
|
||||
-- this is needed because the rate of change is determined by the
|
||||
-- current value. For example, for number 1, the next value is 2,
|
||||
-- but for number 1.1, the next is 1.2 and for 1.01 it is 1.02.
|
||||
-- But if 1.01 becomes 1.00, the both zeros after the decimal point
|
||||
-- need to be preserved to keep the increment ratio the same when
|
||||
-- the user wants to release the slider and start again.
|
||||
origin = tostring(value)
|
||||
local newdigits = #(origin:match('%.(%d+)') or '')
|
||||
if decdigits ~= newdigits then
|
||||
origin = origin .. (origin:find('%.') and '' or '.') .. ("0"):rep(decdigits-newdigits)
|
||||
end
|
||||
|
||||
-- update length
|
||||
scratchpad.length = string.len(num)
|
||||
scratchpad.length = #origin
|
||||
|
||||
-- update the value in the document
|
||||
scratchpadEditor:SetTargetStart(startpos)
|
||||
scratchpadEditor:SetTargetEnd(endpos)
|
||||
scratchpadEditor:ReplaceTarget("" .. num)
|
||||
scratchpadEditor:ReplaceTarget(origin)
|
||||
else event:Skip() end
|
||||
end)
|
||||
|
||||
scratchpadEditor:Connect(wx.wxEVT_SET_CURSOR, function(event)
|
||||
if (debugger.scratchpad and debugger.scratchpad.over) then
|
||||
event:SetCursor(wx.wxCursor(wx.wxCURSOR_SIZEWE))
|
||||
elseif debugger.scratchpad and ide.osname == 'Unix' then
|
||||
-- restore the cursor manually on Linux since event:Skip() doesn't reset it
|
||||
local ibeam = event:GetX() > debugger.scratchpad.margin
|
||||
event:SetCursor(wx.wxCursor(ibeam and wx.wxCURSOR_IBEAM or wx.wxCURSOR_RIGHT_ARROW))
|
||||
else event:Skip() end
|
||||
end)
|
||||
|
||||
@@ -865,6 +1044,8 @@ function DebuggerScratchpadOff()
|
||||
scratchpadEditor:Disconnect(wx.wxID_ANY, wx.wxID_ANY, wx.wxEVT_LEFT_UP)
|
||||
scratchpadEditor:Disconnect(wx.wxID_ANY, wx.wxID_ANY, wx.wxEVT_SET_CURSOR)
|
||||
|
||||
wx.wxSetCursor(wx.wxNullCursor) -- restore cursor
|
||||
|
||||
debugger.scratchpad = nil
|
||||
debugger.terminate()
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ local projcombobox = ide.frame.projpanel.projcombobox
|
||||
local statusTextTable = { "OVR?", "R/O?", "Cursor Pos" }
|
||||
|
||||
-- set funclist font to be the same as the combobox in the project dropdown
|
||||
funclist:SetFont(projcombobox:GetFont())
|
||||
funclist:SetFont(ide.font.fNormal)
|
||||
|
||||
local function updateStatusText(editor)
|
||||
local texts = { "", "", "" }
|
||||
@@ -27,9 +27,10 @@ local function updateStatusText(editor)
|
||||
local line = editor:LineFromPosition(pos)
|
||||
local col = 1 + pos - editor:PositionFromLine(line)
|
||||
|
||||
texts = { iff(editor:GetOvertype(), "OVR", "INS"),
|
||||
texts = {
|
||||
iff(editor:GetOvertype(), "OVR", "INS"),
|
||||
iff(editor:GetReadOnly(), "R/O", "R/W"),
|
||||
"Ln "..tostring(line + 1).." Col "..tostring(col) }
|
||||
"Ln: "..tostring(line + 1).." Col: "..tostring(col) }
|
||||
end
|
||||
|
||||
if ide.frame then
|
||||
@@ -139,8 +140,6 @@ function SetEditorSelection(selection)
|
||||
statusBar:SetStatusText("",1)
|
||||
ide.frame:SetTitle(getFileTitle(editor))
|
||||
|
||||
FileTreeMarkSelected('')
|
||||
|
||||
if editor then
|
||||
if funclist:IsEmpty() then funclist:Append('Jump to a function definition...', 0) end
|
||||
funclist:SetSelection(0)
|
||||
@@ -151,7 +150,11 @@ function SetEditorSelection(selection)
|
||||
if openDocuments[id] and openDocuments[id].filePath then
|
||||
FileTreeMarkSelected(openDocuments[id].filePath)
|
||||
end
|
||||
else
|
||||
FileTreeMarkSelected('')
|
||||
end
|
||||
|
||||
SetAutoRecoveryMark()
|
||||
end
|
||||
|
||||
function GetEditorFileAndCurInfo(nochecksave)
|
||||
@@ -162,9 +165,7 @@ function GetEditorFileAndCurInfo(nochecksave)
|
||||
|
||||
local id = editor:GetId()
|
||||
local filepath = openDocuments[id].filePath
|
||||
if (nochecksave and not filepath) then
|
||||
return
|
||||
end
|
||||
if not filepath then return end
|
||||
|
||||
local fn = wx.wxFileName(filepath)
|
||||
fn:Normalize()
|
||||
@@ -181,7 +182,8 @@ end
|
||||
|
||||
-- Set if the document is modified and update the notebook page text
|
||||
function SetDocumentModified(id, modified)
|
||||
local pageText = openDocuments[id].fileName or "untitled.lua"
|
||||
if not openDocuments[id] then return end
|
||||
local pageText = openDocuments[id].fileName or ide.config.default.fullname
|
||||
|
||||
if modified then
|
||||
pageText = "* "..pageText
|
||||
@@ -191,11 +193,108 @@ function SetDocumentModified(id, modified)
|
||||
notebook:SetPageText(openDocuments[id].index, pageText)
|
||||
end
|
||||
|
||||
function EditorAutoComplete(editor)
|
||||
if not (editor and editor.spec) then return end
|
||||
|
||||
local pos = editor:GetCurrentPos()
|
||||
-- don't do auto-complete in comments or strings.
|
||||
-- the current position and the previous one have default style (0),
|
||||
-- so we need to check two positions back.
|
||||
local style = pos >= 2 and bit.band(editor:GetStyleAt(pos-2),31) or 0
|
||||
if editor.spec.iscomment[style] or editor.spec.isstring[style] then return end
|
||||
|
||||
-- retrieve the current line and get a string to the current cursor position in the line
|
||||
local line = editor:GetCurrentLine()
|
||||
local linetx = editor:GetLine(line)
|
||||
local linestart = editor:PositionFromLine(line)
|
||||
local localpos = pos-linestart
|
||||
|
||||
local lt = linetx:sub(1,localpos)
|
||||
lt = lt:gsub("%s*("..editor.spec.sep..")%s*",function(a) return a end)
|
||||
lt = lt:gsub("%s*%b[]%s*","")
|
||||
lt = lt:gsub("%s*%b()%s*","")
|
||||
lt = lt:gsub("%s*%b{}%s*","")
|
||||
lt = lt:match("[^%[%(%s]*$")
|
||||
lt = lt:gsub("%s","")
|
||||
|
||||
-- know now which string is to be completed
|
||||
local userList = CreateAutoCompList(editor,lt)
|
||||
if userList and string.len(userList) > 0 then
|
||||
editor:UserListShow(1, userList)
|
||||
elseif editor:AutoCompActive() then
|
||||
editor:AutoCompCancel()
|
||||
end
|
||||
end
|
||||
|
||||
local function getValAtPosition(editor, pos)
|
||||
local line = editor:LineFromPosition(pos)
|
||||
local linetx = editor:GetLine(line)
|
||||
local linestart = editor:PositionFromLine(line)
|
||||
local localpos = pos-linestart
|
||||
|
||||
local ident = "([a-zA-Z_][a-zA-Z_0-9%.%:]*)"
|
||||
local linetxtopos = linetx:sub(1,localpos)
|
||||
linetxtopos = linetxtopos..")"
|
||||
linetxtopos = linetxtopos:match(ident .. "%b()$")
|
||||
|
||||
local selected = editor:GetSelectionStart() ~= editor:GetSelectionEnd()
|
||||
and pos >= editor:GetSelectionStart() and pos <= editor:GetSelectionEnd()
|
||||
|
||||
-- check if we have a selected text or an identifier
|
||||
-- for an identifier, check fragments on the left and on the right.
|
||||
-- this is to match 'io' in 'i^o.print' and 'io.print' in 'io.pr^int'.
|
||||
-- remove square brackets to make tbl[index].x show proper values.
|
||||
local start = linetx:sub(1,localpos)
|
||||
:gsub("%b[]", function(s) return ("."):rep(#s) end)
|
||||
:find(ident.."$")
|
||||
|
||||
-- check if the style is the right one; this is to ignore
|
||||
-- comments, strings, numbers (to avoid '1 = 1'), keywords, and such
|
||||
if start and not selected then
|
||||
local style = bit.band(editor:GetStyleAt(linestart+start),31)
|
||||
if editor.spec.iscomment[style]
|
||||
or (MarkupIsAny and MarkupIsAny(style)) -- markup in comments
|
||||
or editor.spec.isstring[style]
|
||||
or style == wxstc.wxSTC_LUA_NUMBER
|
||||
or style == wxstc.wxSTC_LUA_WORD then
|
||||
-- don't do anything for strings or comments or numbers
|
||||
return nil, linetxtopos
|
||||
end
|
||||
end
|
||||
|
||||
local right = linetx:sub(localpos+1,#linetx):match("^[a-zA-Z_0-9]*")
|
||||
local var = selected and editor:GetSelectedText()
|
||||
or (start and linetx:sub(start,localpos):gsub(":",".")..right or nil)
|
||||
|
||||
return var, linetxtopos
|
||||
end
|
||||
|
||||
function EditorCallTip(editor, pos, x, y)
|
||||
local var, linetxtopos = getValAtPosition(editor, pos)
|
||||
local tip = linetxtopos and GetTipInfo(editor,linetxtopos.."(",false)
|
||||
if ide.debugger and ide.debugger.server then
|
||||
if var then
|
||||
local limit = 128
|
||||
ide.debugger.quickeval(var, function(val)
|
||||
if #val > limit then val = val:sub(1, limit-3).."..." end
|
||||
-- check if the mouse position is specified and the mouse has moved,
|
||||
-- then don't show the tooltip as it's already too late for it.
|
||||
if x and y then
|
||||
local mpos = wx.wxGetMousePosition()
|
||||
if mpos.x ~= x or mpos.y ~= y then return end
|
||||
end
|
||||
editor:CallTipShow(pos, val) end)
|
||||
end
|
||||
elseif tip then
|
||||
editor:CallTipShow(pos, tip)
|
||||
end
|
||||
end
|
||||
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- Create an editor and add it to the notebook
|
||||
function CreateEditor(name)
|
||||
-- Create an editor
|
||||
function CreateEditor()
|
||||
local editor = wxstc.wxStyledTextCtrl(notebook, editorID,
|
||||
wx.wxDefaultPosition, wx.wxDefaultSize,
|
||||
wx.wxDefaultPosition, wx.wxSize(0, 0),
|
||||
wx.wxBORDER_STATIC)
|
||||
|
||||
editorID = editorID + 1 -- increment so they're always unique
|
||||
@@ -206,8 +305,8 @@ function CreateEditor(name)
|
||||
editor:SetBufferedDraw(true)
|
||||
editor:StyleClearAll()
|
||||
|
||||
editor:SetFont(ide.font)
|
||||
editor:StyleSetFont(wxstc.wxSTC_STYLE_DEFAULT, ide.font)
|
||||
editor:SetFont(ide.font.eNormal)
|
||||
editor:StyleSetFont(wxstc.wxSTC_STYLE_DEFAULT, ide.font.eNormal)
|
||||
|
||||
editor:SetTabWidth(ide.config.editor.tabwidth or 4)
|
||||
editor:SetIndent(ide.config.editor.tabwidth or 4)
|
||||
@@ -224,8 +323,6 @@ function CreateEditor(name)
|
||||
editor:SetCaretLineVisible(ide.config.editor.caretline and 1 or 0)
|
||||
|
||||
editor:SetVisiblePolicy(wxstc.wxSTC_VISIBLE_SLOP, 3)
|
||||
--editor:SetXCaretPolicy(wxstc.wxSTC_CARET_SLOP, 10)
|
||||
--editor:SetYCaretPolicy(wxstc.wxSTC_CARET_SLOP, 3)
|
||||
|
||||
editor:SetMarginWidth(0, editor:TextWidth(32, "99999_")) -- line # margin
|
||||
|
||||
@@ -258,6 +355,10 @@ function CreateEditor(name)
|
||||
editor:MarkerDefine(wxstc.wxSTC_MARKNUM_FOLDERMIDTAIL, wxstc.wxSTC_MARK_TCORNER, wx.wxWHITE, grey)
|
||||
grey:delete()
|
||||
|
||||
if ide.config.editor.calltipdelay and ide.config.editor.calltipdelay > 0 then
|
||||
editor:SetMouseDwellTime(ide.config.editor.calltipdelay)
|
||||
end
|
||||
|
||||
editor:AutoCompSetIgnoreCase(ide.config.acandtip.ignorecase)
|
||||
if (ide.config.acandtip.strategy > 0) then
|
||||
editor:AutoCompSetAutoHide(0)
|
||||
@@ -285,6 +386,8 @@ function CreateEditor(name)
|
||||
|
||||
editor:Connect(wxstc.wxEVT_STC_MODIFIED,
|
||||
function (event)
|
||||
SetAutoRecoveryMark()
|
||||
|
||||
if (editor.assignscache and editor:GetCurrentLine() ~= editor.assignscache.line) then
|
||||
editor.assignscache = false
|
||||
end
|
||||
@@ -320,40 +423,97 @@ function CreateEditor(name)
|
||||
local linetx = editor:GetLine(line)
|
||||
local linestart = editor:PositionFromLine(line)
|
||||
local localpos = pos-linestart
|
||||
|
||||
local linetxtopos = linetx:sub(1,localpos)
|
||||
|
||||
if (ch == char_CR and eol==2) or (ch == char_LF and eol==0) then
|
||||
if (line > 0) then
|
||||
local indent = editor:GetLineIndentation(line - 1)
|
||||
if indent > 0 then
|
||||
editor:SetLineIndentation(line, indent)
|
||||
local tw = editor:GetTabWidth()
|
||||
local ut = editor:GetUseTabs()
|
||||
local indent = ut and (indent / tw) or indent
|
||||
editor:GotoPos(pos+indent)
|
||||
end
|
||||
end
|
||||
elseif ch == ("("):byte() then
|
||||
local linedone = editor:GetLine(line - 1)
|
||||
|
||||
-- if the indentation is 0 and the current line is not empty
|
||||
-- then take indentation from the current line (instead of the
|
||||
-- previous one). This may happen when CR is hit at the beginning
|
||||
-- of a line (rather than at the end).
|
||||
if indent == 0 and not linetx:match("^[\010\013]*$") then
|
||||
indent = editor:GetLineIndentation(line)
|
||||
end
|
||||
|
||||
local tw = editor:GetTabWidth()
|
||||
local ut = editor:GetUseTabs()
|
||||
|
||||
if ide.config.editor.smartindent
|
||||
and editor.spec.isdecindent and editor.spec.isincindent then
|
||||
local closed, blockend = editor.spec.isdecindent(linedone)
|
||||
local opened = editor.spec.isincindent(linedone)
|
||||
|
||||
-- if the current block is already indented, skip reverse indenting
|
||||
if (line > 1) and (closed > 0 or blockend > 0)
|
||||
and editor:GetLineIndentation(line-2) > indent then
|
||||
-- adjust opened first; this is needed when use ENTER after })
|
||||
if blockend == 0 then opened = opened + closed end
|
||||
closed, blockend = 0, 0
|
||||
end
|
||||
editor:SetLineIndentation(line-1, indent - tw * closed)
|
||||
indent = indent + tw * (opened - blockend)
|
||||
if indent < 0 then indent = 0 end
|
||||
end
|
||||
editor:SetLineIndentation(line, indent)
|
||||
|
||||
indent = ut and (indent / tw) or indent
|
||||
editor:GotoPos(editor:GetCurrentPos()+indent)
|
||||
end
|
||||
|
||||
elseif ch == ("("):byte() then
|
||||
local tip = GetTipInfo(editor,linetxtopos,ide.config.acandtip.shorttip)
|
||||
if tip then
|
||||
editor:CallTipShow(pos,tip)
|
||||
end
|
||||
|
||||
elseif ide.config.autocomplete then -- code completion prompt
|
||||
|
||||
local trigger = linetxtopos:match("["..editor.spec.sep.."%w_]+$")
|
||||
|
||||
if (trigger and (#trigger > 1 or trigger:match("[%.:]"))) then
|
||||
-- defined in menu_edit.lua
|
||||
local commandEvent = wx.wxCommandEvent(wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
ID_AUTOCOMPLETE)
|
||||
wx.wxPostEvent(ide.frame, commandEvent)
|
||||
ide.frame:AddPendingEvent(wx.wxCommandEvent(
|
||||
wx.wxEVT_COMMAND_MENU_SELECTED, ID_AUTOCOMPLETE))
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
editor:Connect(wxstc.wxEVT_STC_DWELLSTART,
|
||||
function (event)
|
||||
-- on Linux DWELLSTART event seems to be generated even for those
|
||||
-- editor windows that are not active. What's worse, when generated
|
||||
-- the event seems to report "old" position when retrieved using
|
||||
-- event:GetX and event:GetY, so instead we use wxGetMousePosition.
|
||||
local linux = ide.osname == 'Unix'
|
||||
if linux and editor ~= GetEditor() then return end
|
||||
-- check if this editor has focus; it may not when Stack/Watch window
|
||||
-- is on top, but DWELL events are still triggered in this case.
|
||||
-- Don't want to show calltip as it is still shown when the focus
|
||||
-- is switched to a different application.
|
||||
local focus = editor:FindFocus()
|
||||
if focus and focus:GetId() ~= editor:GetId() then return end
|
||||
local mpos = wx.wxGetMousePosition()
|
||||
local cpos = editor:ScreenToClient(mpos)
|
||||
local position = editor:PositionFromPointClose(
|
||||
linux and cpos.x or event:GetX(), linux and cpos.y or event:GetY())
|
||||
if position ~= wxstc.wxSTC_INVALID_POSITION then
|
||||
EditorCallTip(editor, position, mpos.x, mpos.y)
|
||||
end
|
||||
event:Skip()
|
||||
end)
|
||||
|
||||
editor:Connect(wxstc.wxEVT_STC_DWELLEND,
|
||||
function (event)
|
||||
if editor:CallTipActive() then editor:CallTipCancel() end
|
||||
event:Skip()
|
||||
end)
|
||||
|
||||
editor:Connect(wx.wxEVT_KILL_FOCUS,
|
||||
function (event)
|
||||
if editor:AutoCompActive() then editor:AutoCompCancel() end
|
||||
event:Skip()
|
||||
end)
|
||||
|
||||
editor:Connect(wxstc.wxEVT_STC_USERLISTSELECTION,
|
||||
function (event)
|
||||
local pos = editor:GetCurrentPos()
|
||||
@@ -363,17 +523,17 @@ function CreateEditor(name)
|
||||
end)
|
||||
|
||||
editor:Connect(wxstc.wxEVT_STC_SAVEPOINTREACHED,
|
||||
function (event)
|
||||
function ()
|
||||
SetDocumentModified(editor:GetId(), false)
|
||||
end)
|
||||
|
||||
editor:Connect(wxstc.wxEVT_STC_SAVEPOINTLEFT,
|
||||
function (event)
|
||||
function ()
|
||||
SetDocumentModified(editor:GetId(), true)
|
||||
end)
|
||||
|
||||
editor:Connect(wxstc.wxEVT_STC_UPDATEUI,
|
||||
function (event)
|
||||
function ()
|
||||
updateStatusText(editor)
|
||||
updateBraceMatch(editor)
|
||||
for _,iv in ipairs(editor.ev) do
|
||||
@@ -389,7 +549,7 @@ function CreateEditor(name)
|
||||
function (event)
|
||||
if MarkupHotspotClick then
|
||||
local position = editor:PositionFromPointClose(event:GetX(),event:GetY())
|
||||
if position ~= wx.wxSTC_INVALID_POSITION then
|
||||
if position ~= wxstc.wxSTC_INVALID_POSITION then
|
||||
if MarkupHotspotClick(position, editor) then return end
|
||||
end
|
||||
end
|
||||
@@ -422,11 +582,81 @@ function CreateEditor(name)
|
||||
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
|
||||
-- Delete and Backspace behave the same way for selected text
|
||||
if #(editor:GetSelectedText()) > 0 then
|
||||
editor:SetTargetStart(editor:GetSelectionStart())
|
||||
editor:SetTargetEnd(editor:GetSelectionEnd())
|
||||
else
|
||||
local pos = editor:GetCurrentPos()
|
||||
if keycode == wx.WXK_BACK then
|
||||
pos = pos - 1
|
||||
if pos < 0 then return end
|
||||
end
|
||||
|
||||
-- check if the modification is to one of "invisible" characters.
|
||||
-- if not, proceed with "normal" processing as there are other
|
||||
-- events that may depend on Backspace, for example, re-calculating
|
||||
-- auto-complete suggestions.
|
||||
local style = bit.band(editor:GetStyleAt(pos), 31)
|
||||
if not MarkupIsSpecial or not MarkupIsSpecial(style) then
|
||||
event:Skip()
|
||||
return
|
||||
end
|
||||
|
||||
editor:SetTargetStart(pos)
|
||||
editor:SetTargetEnd(pos+1)
|
||||
end
|
||||
editor:ReplaceTarget("")
|
||||
else
|
||||
if ide.osname == 'Macintosh' and event:CmdDown() then
|
||||
return -- ignore a key press if Command key is also pressed
|
||||
end
|
||||
event:Skip()
|
||||
end
|
||||
end)
|
||||
|
||||
local value
|
||||
editor:Connect(wx.wxEVT_CONTEXT_MENU,
|
||||
function (event)
|
||||
local menu = wx.wxMenu()
|
||||
menu:Append(wx.wxID_UNDO, "&Undo")
|
||||
menu:Append(wx.wxID_REDO, "&Redo")
|
||||
menu:AppendSeparator()
|
||||
menu:Append(wx.wxID_CUT, "Cu&t")
|
||||
menu:Append(wx.wxID_COPY, "&Copy")
|
||||
menu:Append(wx.wxID_PASTE, "&Paste")
|
||||
menu:Append(wx.wxID_SELECTALL, "Select &All")
|
||||
menu:AppendSeparator()
|
||||
menu:Append(ID_QUICKADDWATCH, "Add Watch Expression")
|
||||
menu:Append(ID_QUICKEVAL, "Evaluate in Console")
|
||||
|
||||
local point = editor:ScreenToClient(event:GetPosition())
|
||||
local pos = editor:PositionFromPointClose(point.x, point.y)
|
||||
value = pos ~= wxstc.wxSTC_INVALID_POSITION and getValAtPosition(editor, pos) or nil
|
||||
menu:Enable(ID_QUICKADDWATCH, value ~= nil)
|
||||
menu:Enable(ID_QUICKEVAL, value ~= nil)
|
||||
|
||||
-- cancel calltip as it interferes with popup menu
|
||||
if editor:CallTipActive() then editor:CallTipCancel() end
|
||||
editor:PopupMenu(menu)
|
||||
end)
|
||||
|
||||
editor:Connect(ID_QUICKADDWATCH, wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function(event) DebuggerAddWatch(value) end)
|
||||
|
||||
editor:Connect(ID_QUICKEVAL, wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function(event) ShellExecuteCode(value) end)
|
||||
|
||||
return editor
|
||||
end
|
||||
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- Add an editor to the notebook
|
||||
function AddEditor(editor, name)
|
||||
if notebook:AddPage(editor, name, true) then
|
||||
local id = editor:GetId()
|
||||
local document = {}
|
||||
@@ -437,9 +667,9 @@ function CreateEditor(name)
|
||||
document.modTime = nil
|
||||
document.isModified = false
|
||||
openDocuments[id] = document
|
||||
return document
|
||||
end
|
||||
|
||||
return editor
|
||||
return
|
||||
end
|
||||
|
||||
function GetSpec(ext,forcespec)
|
||||
@@ -448,10 +678,10 @@ function GetSpec(ext,forcespec)
|
||||
-- search proper spec
|
||||
-- allow forcespec for "override"
|
||||
if ext and not spec then
|
||||
for i,curspec in pairs(ide.specs) do
|
||||
for _,curspec in pairs(ide.specs) do
|
||||
local exts = curspec.exts
|
||||
if (exts) then
|
||||
for n,curext in ipairs(exts) do
|
||||
for _,curext in ipairs(exts) do
|
||||
if (curext == ext) then
|
||||
spec = curspec
|
||||
break
|
||||
@@ -475,16 +705,11 @@ function IndicateFunctions(editor, lines, linee)
|
||||
|
||||
if (lines < 0) then return end
|
||||
|
||||
local isfunc = editor.spec.isfncall
|
||||
local iscomment = editor.spec.iscomment
|
||||
local iskeyword0 = editor.spec.iskeyword0
|
||||
local isfncall = editor.spec.isfncall
|
||||
local isinvalid = {}
|
||||
for i,v in pairs(iscomment) do
|
||||
isinvalid[i] = v
|
||||
end
|
||||
for i,v in pairs(iskeyword0) do
|
||||
isinvalid[i] = v
|
||||
end
|
||||
for i,v in pairs(editor.spec.iscomment) do isinvalid[i] = v end
|
||||
for i,v in pairs(editor.spec.iskeyword0) do isinvalid[i] = v end
|
||||
for i,v in pairs(editor.spec.isstring) do isinvalid[i] = v end
|
||||
|
||||
local INDICS_MASK = wxstc.wxSTC_INDICS_MASK
|
||||
local INDIC0_MASK = wxstc.wxSTC_INDIC0_MASK
|
||||
@@ -501,13 +726,13 @@ function IndicateFunctions(editor, lines, linee)
|
||||
while from do
|
||||
tx = from==1 and tx or string.sub(tx,from)
|
||||
|
||||
local f,t,w = isfunc(tx)
|
||||
local f,t,w = isfncall(tx)
|
||||
|
||||
if (f) then
|
||||
local p = ls+f+off
|
||||
local s = bit.band(editor:GetStyleAt(p),31)
|
||||
editor:StartStyling(p,INDICS_MASK)
|
||||
editor:SetStyling(t-f,isinvalid[s] and 0 or (INDIC0_MASK + 1))
|
||||
editor:SetStyling(#w,isinvalid[s] and 0 or (INDIC0_MASK + 1))
|
||||
off = off + t
|
||||
end
|
||||
from = t and (t+1)
|
||||
@@ -534,11 +759,11 @@ function SetupKeywords(editor, ext, forcespec, styles, font, fontitalic)
|
||||
-- Get the items in the global "wx" table for autocompletion
|
||||
if not wxkeywords then
|
||||
local keyword_table = {}
|
||||
for index, value in pairs(wx) do
|
||||
for index in pairs(wx) do
|
||||
table.insert(keyword_table, "wx."..index.." ")
|
||||
end
|
||||
|
||||
for index, value in pairs(wxstc) do
|
||||
for index in pairs(wxstc) do
|
||||
table.insert(keyword_table, "wxstc."..index.." ")
|
||||
end
|
||||
|
||||
@@ -560,21 +785,22 @@ function SetupKeywords(editor, ext, forcespec, styles, font, fontitalic)
|
||||
end
|
||||
|
||||
StylesApplyToEditor(styles or ide.config.styles, editor,
|
||||
font or ide.font,fontitalic or ide.fontItalic,lexerstyleconvert)
|
||||
font or ide.font.eNormal,fontitalic or ide.font.eItalic,lexerstyleconvert)
|
||||
end
|
||||
|
||||
----------------------------------------------------
|
||||
-- function list for current file
|
||||
|
||||
funclist:Connect(wx.wxEVT_SET_FOCUS,
|
||||
-- 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()
|
||||
|
||||
-- parse current file and update list
|
||||
local editor = GetEditor()
|
||||
if (editor and not (editor.spec and editor.spec.isfndef)) then return end
|
||||
|
||||
if (not (editor and 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()
|
||||
@@ -585,12 +811,16 @@ funclist:Connect(wx.wxEVT_SET_FOCUS,
|
||||
funclist:SetSelection(0)
|
||||
|
||||
local lines = 0
|
||||
local linee = editor:GetLineCount()-1
|
||||
local linee = (editor and editor:GetLineCount() or 0)-1
|
||||
for line=lines,linee do
|
||||
local tx = editor:GetLine(line)
|
||||
local s,e,cap,l = editor.spec.isfndef(tx)
|
||||
local s,_,cap,l = editor.spec.isfndef(tx)
|
||||
if (s) then
|
||||
funclist:Append((l and " " or "")..cap,line)
|
||||
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
|
||||
|
||||
|
||||
@@ -30,14 +30,15 @@ local filetree = ide.filetree
|
||||
-- ------------
|
||||
|
||||
do
|
||||
local getBitmap = (ide.app.createbitmap or wx.wxArtProvider.GetBitmap)
|
||||
local size = wx.wxSize(16, 16)
|
||||
filetree.imglist = wx.wxImageList(16,16)
|
||||
-- 0 = directory
|
||||
filetree.imglist:Add(wx.wxArtProvider.GetBitmap(wx.wxART_FOLDER, wx.wxART_OTHER, size))
|
||||
filetree.imglist:Add(getBitmap(wx.wxART_FOLDER, wx.wxART_OTHER, size))
|
||||
-- 1 = file known spec
|
||||
filetree.imglist:Add(wx.wxArtProvider.GetBitmap(wx.wxART_HELP_PAGE, wx.wxART_OTHER, size))
|
||||
filetree.imglist:Add(getBitmap(wx.wxART_HELP_PAGE, wx.wxART_OTHER, size))
|
||||
-- 2 = file rest
|
||||
filetree.imglist:Add(wx.wxArtProvider.GetBitmap(wx.wxART_NORMAL_FILE, wx.wxART_OTHER, size))
|
||||
filetree.imglist:Add(getBitmap(wx.wxART_NORMAL_FILE, wx.wxART_OTHER, size))
|
||||
end
|
||||
|
||||
local function treeAddDir(tree,parent_id,rootdir)
|
||||
@@ -46,15 +47,14 @@ local function treeAddDir(tree,parent_id,rootdir)
|
||||
while true do
|
||||
if not item:IsOk() then break end
|
||||
items[tree:GetItemText(item) .. tree:GetItemImage(item)] = item
|
||||
item, cookie = tree:GetNextChild(item, cookie)
|
||||
item, cookie = tree:GetNextChild(parent_id, cookie)
|
||||
end
|
||||
|
||||
local curr
|
||||
local search = rootdir..string_Pathsep.."*.*"
|
||||
local dirs = FileSysGet(search,wx.wxDIR)
|
||||
local search = rootdir..string_Pathsep.."*"
|
||||
|
||||
-- append directories
|
||||
for _,dir in ipairs(dirs) do
|
||||
for _,dir in ipairs(FileSysGet(search,wx.wxDIR)) do
|
||||
local name = dir:match("%"..string_Pathsep.."("..stringset_File.."+)$")
|
||||
local icon = 0
|
||||
local item = items[name .. icon]
|
||||
@@ -78,8 +78,7 @@ local function treeAddDir(tree,parent_id,rootdir)
|
||||
end
|
||||
|
||||
-- then append files
|
||||
local files = FileSysGet(search,wx.wxFILE)
|
||||
for _,file in ipairs(files) do
|
||||
for _,file in ipairs(FileSysGet(search,wx.wxFILE)) do
|
||||
local name = file:match("%"..string_Pathsep.."("..stringset_File.."+)$")
|
||||
local known = GetSpec(GetFileExt(name))
|
||||
local icon = known and 1 or 2
|
||||
@@ -122,15 +121,17 @@ local function treeGetItemFullName(tree,treedata,item_id)
|
||||
cur = tree:GetItemText(item_id)
|
||||
if cur and string.len(cur) > 0 then str = cur..string_Pathsep..str end
|
||||
end
|
||||
return ((not filetree.showroot) and filetree.projdata.rootdir or "")..str
|
||||
-- as root may already include path separate, normalize the path
|
||||
local fullPath = wx.wxFileName(
|
||||
filetree.showroot and str or filetree.projdata.rootdir .. str)
|
||||
fullPath:Normalize()
|
||||
return fullPath:GetFullPath()
|
||||
end
|
||||
|
||||
local function treeSetRoot(tree,treedata,rootdir)
|
||||
tree:DeleteAllItems()
|
||||
|
||||
if (not wx.wxDirExists(rootdir)) then
|
||||
treedata.root_id = nil
|
||||
tree:AddRoot("Invalid")
|
||||
return
|
||||
end
|
||||
|
||||
@@ -154,9 +155,9 @@ local function treeSetConnectorsAndIcons(tree,treedata)
|
||||
local dir = treeGetItemFullName(tree,treedata,item_id)
|
||||
treeAddDir(tree,item_id,dir)
|
||||
return true
|
||||
end )
|
||||
end)
|
||||
tree:Connect( wx.wxEVT_COMMAND_TREE_ITEM_COLLAPSED,
|
||||
function() return true end )
|
||||
function() return true end)
|
||||
tree:Connect( wx.wxEVT_COMMAND_TREE_ITEM_ACTIVATED,
|
||||
function( event )
|
||||
local item_id = event:GetItem()
|
||||
@@ -172,12 +173,24 @@ local function treeSetConnectorsAndIcons(tree,treedata)
|
||||
else -- open file
|
||||
if wx.wxFileName(name):FileExists() then
|
||||
LoadFile(name,nil,true)
|
||||
FileTreeMarkSelected(name)
|
||||
else -- stale filetree information; rescan
|
||||
treeAddDir(tree,tree:GetItemParent(item_id),name)
|
||||
end
|
||||
end
|
||||
end )
|
||||
end)
|
||||
-- toggle a folder on
|
||||
tree:Connect( wx.wxEVT_LEFT_DOWN,
|
||||
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
|
||||
tree:Toggle(item_id)
|
||||
tree:SelectItem(item_id)
|
||||
else
|
||||
event:Skip()
|
||||
end
|
||||
return true
|
||||
end)
|
||||
end
|
||||
|
||||
-- project
|
||||
@@ -199,7 +212,8 @@ local projtree = wx.wxTreeCtrl(projpanel, ID "filetree.projtree",
|
||||
or (wx.wxTR_HAS_BUTTONS + wx.wxTR_SINGLE + wx.wxTR_HIDE_ROOT))
|
||||
|
||||
-- use the same font in the combobox as is used in the filetree
|
||||
projcombobox:SetFont(projtree:GetFont())
|
||||
projtree:SetFont(ide.font.fNormal)
|
||||
projcombobox:SetFont(ide.font.fNormal)
|
||||
|
||||
local projTopSizer = wx.wxBoxSizer( wx.wxHORIZONTAL );
|
||||
projTopSizer:Add(projcombobox, 1, wx.wxALL + wx.wxALIGN_LEFT + wx.wxGROW, 0)
|
||||
@@ -236,6 +250,11 @@ function filetree:updateProjectDir(newdir, cboxsel)
|
||||
end
|
||||
|
||||
if ((not newdir) or filetree.projdirText == newdir or not wx.wxDirExists(newdir)) then return end
|
||||
|
||||
if ide.config.projectautoopen and filetree.projdirText then
|
||||
StoreRestoreProjectTabs(filetree.projdirText, newdir)
|
||||
end
|
||||
|
||||
filetree.projdirText = newdir
|
||||
|
||||
PrependStringToArray(filetree.projdirTextArray,newdir,ide.config.projecthistorylength)
|
||||
@@ -284,7 +303,7 @@ local function findItem(tree, match)
|
||||
local node = projtree:GetRootItem()
|
||||
local label = tree:GetItemText(node)
|
||||
|
||||
local s, e = string.find(match, label)
|
||||
local s, e = string.find(match, label, 1, true)
|
||||
if not s or s ~= 1 then return end
|
||||
|
||||
for token in string.gmatch(string.sub(match,e+1), "[^%"..string_Pathsep.."]+") do
|
||||
@@ -298,7 +317,7 @@ local function findItem(tree, match)
|
||||
node = item
|
||||
break
|
||||
end
|
||||
item, cookie = tree:GetNextChild(item, cookie)
|
||||
item, cookie = tree:GetNextChild(node, cookie)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -306,18 +325,32 @@ local function findItem(tree, match)
|
||||
return node
|
||||
end
|
||||
|
||||
local curr_id
|
||||
local curr_file
|
||||
function FileTreeMarkSelected(file)
|
||||
if not file then return end
|
||||
if not file or not filetree.projdirText or #filetree.projdirText == 0 then return end
|
||||
|
||||
local item_id = findItem(projtree, file)
|
||||
if curr_id ~= item_id then
|
||||
if curr_id and projtree:IsBold(curr_id) then
|
||||
projtree:SetItemBold(curr_id, false)
|
||||
|
||||
-- if the select item is different from the current one
|
||||
-- or the current one is the same, but not bold (which may happen when
|
||||
-- the project is changed to one that includes the current item)
|
||||
if curr_file ~= file
|
||||
or item_id and not projtree:IsBold(item_id) then
|
||||
if curr_file then
|
||||
local curr_id = findItem(projtree, curr_file)
|
||||
if curr_id and projtree:IsBold(curr_id) then
|
||||
projtree:SetItemBold(curr_id, false)
|
||||
end
|
||||
end
|
||||
if item_id then
|
||||
projtree:EnsureVisible(item_id)
|
||||
projtree:SetItemBold(item_id, true)
|
||||
curr_id = item_id
|
||||
end
|
||||
curr_file = file
|
||||
projtree:Refresh() -- to force refresh on Mac (ide.osname == 'Macintosh')
|
||||
end
|
||||
end
|
||||
|
||||
function FileTreeRefresh()
|
||||
treeSetRoot(projtree,filetree.projdata,filetree.projdirText)
|
||||
end
|
||||
|
||||
@@ -95,6 +95,7 @@ function findReplace:GetSelectedString()
|
||||
findReplace.foundString = true
|
||||
end
|
||||
end
|
||||
return editor and findReplace.foundString
|
||||
end
|
||||
|
||||
function findReplace:FindString(reverse)
|
||||
@@ -112,7 +113,7 @@ function findReplace:FindString(reverse)
|
||||
end
|
||||
if posFind == -1 then
|
||||
findReplace.foundString = false
|
||||
ide.frame:SetStatusText("Find text not found.")
|
||||
ide.frame:SetStatusText("Text not found.")
|
||||
else
|
||||
findReplace.foundString = true
|
||||
local start = editor:GetTargetStart()
|
||||
@@ -209,48 +210,36 @@ local function onFileRegister(pos)
|
||||
findReplace.occurrences = findReplace.occurrences + 1
|
||||
end
|
||||
|
||||
local function storefile(file,content)
|
||||
local handle = io.open(file, "wb")
|
||||
if (handle) then
|
||||
handle:write(content)
|
||||
handle:close()
|
||||
end
|
||||
end
|
||||
|
||||
local function ProcInFiles(startdir,mask,subdirs,replace)
|
||||
if (subdirs) then
|
||||
local dirs = FileSysGet(startdir..string_Pathsep.."*.*",wx.wxDIR)
|
||||
for i,dir in ipairs(dirs) do
|
||||
--DisplayOutput(dir.."\n")
|
||||
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)
|
||||
for i,file in ipairs(files) do
|
||||
findReplace.curfilename = file
|
||||
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
|
||||
findReplace.curfilename = file
|
||||
|
||||
--DisplayOutput(file.."\n")
|
||||
local filetext = FileRead(file)
|
||||
if filetext then
|
||||
findReplace.oveditor:SetText(filetext)
|
||||
|
||||
-- load file
|
||||
local handle = io.open(file, "rb")
|
||||
if handle then
|
||||
local filetext = handle:read("*a")
|
||||
handle:close()
|
||||
findReplace.oveditor:SetText(filetext)
|
||||
|
||||
if (replace and findReplace:ReplaceString(true,onFileRegister)) then
|
||||
-- store changed content, make .bak
|
||||
if (findReplace.fMakeBak) then
|
||||
storefile(file..".bak",filetext)
|
||||
if replace then
|
||||
-- check if anything replaced, store changed content, make .bak
|
||||
if findReplace:ReplaceString(true,onFileRegister)
|
||||
and findReplace.fMakeBak and FileWrite(file..".bak",filetext) then
|
||||
FileWrite(file,findReplace.oveditor:GetText())
|
||||
end
|
||||
else
|
||||
findReplace:FindStringAll(onFileRegister)
|
||||
end
|
||||
storefile(file,findReplace.oveditor:GetText())
|
||||
else
|
||||
findReplace:FindStringAll(onFileRegister)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function findReplace:RunInFiles(replace)
|
||||
@@ -259,17 +248,17 @@ function findReplace:RunInFiles(replace)
|
||||
end
|
||||
|
||||
findReplace.oveditor = wxstc.wxStyledTextCtrl(findReplace.dialog, wx.wxID_ANY,
|
||||
wx.wxDefaultPosition, wx.wxSize(1,1),
|
||||
wx.wxBORDER_STATIC)
|
||||
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")..": '"..findReplace.findText.."'\n")
|
||||
DisplayOutput("FindInFiles: "..(replace and "Replacing" or "Searching for").." '"..findReplace.findText.."'.\n")
|
||||
|
||||
ProcInFiles(startdir, findReplace.filemaskText,findReplace.fSubDirs, replace)
|
||||
ProcInFiles(startdir, findReplace.filemaskText, findReplace.fSubDirs, replace)
|
||||
|
||||
DisplayOutput("> FindInFiles: "..findReplace.occurrences.." occurrence(s) have been found\n\n")
|
||||
DisplayOutput("FindInFiles: "..findReplace.occurrences.." instance(s) have been "..
|
||||
(replace and "replaced" or "found")..".\n")
|
||||
findReplace.oveditor = nil
|
||||
end
|
||||
|
||||
@@ -282,8 +271,8 @@ local function createFindReplaceDialog(replace,infiles)
|
||||
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)
|
||||
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")
|
||||
@@ -305,14 +294,16 @@ local function createFindReplaceDialog(replace,infiles)
|
||||
|
||||
-- Create find/replace text entry sizer
|
||||
local findStatText = wx.wxStaticText( findDialog, wx.wxID_ANY, "Find: ")
|
||||
local findTextCombo = wx.wxComboBox(findDialog, wx.wxID_ANY, findReplace.findText, wx.wxDefaultPosition, wx.wxDefaultSize, findReplace.findTextArray, wx.wxCB_DROPDOWN)
|
||||
local findTextCombo = wx.wxComboBox(findDialog, wx.wxID_ANY, findReplace.findText,
|
||||
wx.wxDefaultPosition, wx.wxDefaultSize, findReplace.findTextArray, wx.wxCB_DROPDOWN)
|
||||
findTextCombo:SetFocus()
|
||||
|
||||
local infilesMaskStat,infilesMaskCombo
|
||||
local infilesDirStat,infilesDirCombo,infilesDirButton
|
||||
if (infiles) then
|
||||
infilesMaskStat = wx.wxStaticText( findDialog, wx.wxID_ANY, "File Type: ")
|
||||
infilesMaskCombo = wx.wxComboBox(findDialog, wx.wxID_ANY, findReplace.filemaskText, wx.wxDefaultPosition, wx.wxSize(250,20), findReplace.filemaskTextArray)
|
||||
infilesMaskCombo = wx.wxComboBox(findDialog, wx.wxID_ANY, findReplace.filemaskText,
|
||||
wx.wxDefaultPosition, wx.wxDefaultSize, findReplace.filemaskTextArray)
|
||||
|
||||
local fname = GetEditorFileAndCurInfo(true)
|
||||
if (fname) then
|
||||
@@ -332,25 +323,30 @@ local function createFindReplaceDialog(replace,infiles)
|
||||
|
||||
local findReplaceSizer = wx.wxFlexGridSizer(2, 3, 0, 0)
|
||||
findReplaceSizer:AddGrowableCol(1)
|
||||
findReplaceSizer:Add(findStatText, 0, wx.wxALL + wx.wxALIGN_LEFT, 0)
|
||||
findReplaceSizer:Add(findTextCombo, 1, wx.wxALL + wx.wxGROW + wx.wxCENTER, 0)
|
||||
findReplaceSizer:Add(16,8, 0, wx.wxALL + wx.wxALIGN_RIGHT + wx.wxADJUST_MINSIZE,0)
|
||||
findReplaceSizer:Add(findStatText, 0, wx.wxALL + wx.wxALIGN_RIGHT + wx.wxALIGN_CENTER_VERTICAL, 0)
|
||||
findReplaceSizer:Add(findTextCombo, 1, wx.wxALL + wx.wxGROW + wx.wxCENTER+ wx.wxALIGN_CENTER_VERTICAL, 0)
|
||||
findReplaceSizer:Add(16, 8, 0, wx.wxALL + wx.wxALIGN_RIGHT + wx.wxADJUST_MINSIZE,0)
|
||||
|
||||
if (infiles) then
|
||||
findReplaceSizer:Add(infilesMaskStat, 0, wx.wxTOP + wx.wxALIGN_CENTER, 5)
|
||||
findReplaceSizer:Add(infilesMaskCombo, 1, wx.wxTOP + wx.wxGROW + wx.wxCENTER, 5)
|
||||
findReplaceSizer:Add(16,8, 0, wx.wxTOP + wx.wxALIGN_RIGHT + wx.wxADJUST_MINSIZE ,5)
|
||||
findReplaceSizer:Add(infilesMaskStat, 0, wx.wxTOP + wx.wxALIGN_RIGHT + wx.wxALIGN_CENTER_VERTICAL, 5)
|
||||
findReplaceSizer:Add(infilesMaskCombo, 1, wx.wxTOP + wx.wxGROW + wx.wxCENTER+ wx.wxALIGN_CENTER_VERTICAL, 5)
|
||||
findReplaceSizer:Add(16, 8, 0, wx.wxTOP, 5)
|
||||
|
||||
findReplaceSizer:Add(infilesDirStat, 0, wx.wxTOP + wx.wxALIGN_CENTER, 5)
|
||||
findReplaceSizer:Add(infilesDirCombo, 1, wx.wxTOP + wx.wxGROW + wx.wxCENTER, 5)
|
||||
findReplaceSizer:Add(infilesDirButton, 0, wx.wxTOP + wx.wxALIGN_RIGHT + wx.wxADJUST_MINSIZE, 5)
|
||||
findReplaceSizer:Add(infilesDirStat, 0, wx.wxTOP + wx.wxALIGN_RIGHT + wx.wxALIGN_CENTER_VERTICAL, 5)
|
||||
findReplaceSizer:Add(infilesDirCombo, 1, wx.wxTOP + wx.wxGROW + wx.wxCENTER+ wx.wxALIGN_CENTER_VERTICAL, 5)
|
||||
findReplaceSizer:Add(infilesDirButton, 0, wx.wxTOP + wx.wxALIGN_RIGHT + wx.wxADJUST_MINSIZE+ wx.wxALIGN_CENTER_VERTICAL, 5)
|
||||
end
|
||||
|
||||
if (replace) then
|
||||
findReplaceSizer:Add(replaceStatText, 0, wx.wxTOP + wx.wxALIGN_CENTER, 5)
|
||||
findReplaceSizer:Add(replaceTextCombo, 1, wx.wxTOP + wx.wxGROW + wx.wxCENTER, 5)
|
||||
findReplaceSizer:Add(replaceStatText, 0, wx.wxTOP + wx.wxALIGN_RIGHT + wx.wxALIGN_CENTER_VERTICAL, 5)
|
||||
findReplaceSizer:Add(replaceTextCombo, 1, wx.wxTOP + wx.wxGROW + wx.wxCENTER+ wx.wxALIGN_CENTER_VERTICAL, 5)
|
||||
end
|
||||
|
||||
-- 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" )
|
||||
|
||||
-- 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")
|
||||
@@ -366,7 +362,7 @@ local function createFindReplaceDialog(replace,infiles)
|
||||
optionSizer:Add(matchCaseCheckBox, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 3)
|
||||
optionSizer:Add(wrapAroundCheckBox, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 3)
|
||||
optionSizer:Add(regexCheckBox, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 3)
|
||||
local optionsSizer = wx.wxStaticBoxSizer(wx.wxVERTICAL, findDialog, "Options" );
|
||||
|
||||
optionsSizer:Add(optionSizer, 0, 0, 5)
|
||||
|
||||
-- Create scope radiobox
|
||||
@@ -376,6 +372,9 @@ 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")
|
||||
|
||||
subDirCheckBox = wx.wxCheckBox(findDialog, wx.wxID_ANY, "&Subdirectories")
|
||||
makeBakCheckBox = wx.wxCheckBox(findDialog, wx.wxID_ANY, ".&bak on Replace")
|
||||
subDirCheckBox:SetValue(findReplace.fSubDirs)
|
||||
@@ -385,13 +384,12 @@ local function createFindReplaceDialog(replace,infiles)
|
||||
optionSizer:Add(subDirCheckBox, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 3)
|
||||
optionSizer:Add(makeBakCheckBox, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 3)
|
||||
|
||||
scopeSizer = wx.wxStaticBoxSizer(wx.wxVERTICAL, findDialog, "In Files" );
|
||||
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:SetSelection(iff(findReplace.fDown, 1, 0))
|
||||
|
||||
scopeSizer = wx.wxBoxSizer(wx.wxVERTICAL, findDialog );
|
||||
scopeSizer = wx.wxBoxSizer(wx.wxVERTICAL, findDialog)
|
||||
scopeSizer:Add(scopeRadioBox, 0, 0, 0)
|
||||
end
|
||||
|
||||
@@ -440,7 +438,7 @@ local function createFindReplaceDialog(replace,infiles)
|
||||
end
|
||||
|
||||
findDialog:Connect(ID_FIND_NEXT, wx.wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
function(event)
|
||||
function()
|
||||
TransferDataFromWindow()
|
||||
if (findReplace.infiles) then
|
||||
findReplace:RunInFiles()
|
||||
@@ -479,8 +477,8 @@ local function createFindReplaceDialog(replace,infiles)
|
||||
|
||||
if infilesDirButton then
|
||||
findDialog:Connect(ID_SETDIR, wx.wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
function(event)
|
||||
local filePicker = wx.wxDirDialog(findDialog, "Chose a project directory",
|
||||
function()
|
||||
local filePicker = wx.wxDirDialog(findDialog, "Choose a project directory",
|
||||
findReplace.filedirText~="" and findReplace.filedirText or wx.wxGetCwd(),wx.wxFLP_USE_TEXTCTRL)
|
||||
|
||||
local res = filePicker:ShowModal(true)
|
||||
|
||||
@@ -10,41 +10,23 @@ BREAKPOINT_MARKER_VALUE = 2 -- = 2^BREAKPOINT_MARKER
|
||||
CURRENT_LINE_MARKER = 2
|
||||
CURRENT_LINE_MARKER_VALUE = 4 -- = 2^CURRENT_LINE_MARKER
|
||||
|
||||
-- Globals
|
||||
local font = nil -- fonts to use for the editor
|
||||
local fontItalic = nil
|
||||
local ofont = nil -- fonts to use for the outputshell
|
||||
local ofontItalic = nil
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- Pick some reasonable fixed width fonts to use for the editor
|
||||
if wx.__WXMSW__ then
|
||||
font = wx.wxFont(ide.config.editor.fontsize or 10, wx.wxFONTFAMILY_MODERN, wx.wxFONTSTYLE_NORMAL,
|
||||
wx.wxFONTWEIGHT_NORMAL, false, ide.config.editor.fontname or "Courier New", ide.config.editor.fontencoding or wx.wxFONTENCODING_DEFAULT)
|
||||
fontItalic = wx.wxFont(ide.config.editor.fontsize or 10, wx.wxFONTFAMILY_MODERN, wx.wxFONTSTYLE_ITALIC,
|
||||
wx.wxFONTWEIGHT_NORMAL, false, ide.config.editor.fontname or "Courier New", ide.config.editor.fontencoding or wx.wxFONTENCODING_DEFAULT)
|
||||
else
|
||||
font = wx.wxFont(ide.config.editor.fontsize or 10, wx.wxFONTFAMILY_MODERN, wx.wxFONTSTYLE_NORMAL,
|
||||
wx.wxFONTWEIGHT_NORMAL, false, ide.config.editor.fontname or "", ide.config.editor.fontencoding or wx.wxFONTENCODING_DEFAULT)
|
||||
fontItalic = wx.wxFont(ide.config.editor.fontsize or 10, wx.wxFONTFAMILY_MODERN, wx.wxFONTSTYLE_ITALIC,
|
||||
wx.wxFONTWEIGHT_NORMAL, false, ide.config.editor.fontname or "", ide.config.editor.fontencoding or wx.wxFONTENCODING_DEFAULT)
|
||||
local function setFont(style, config, name, size)
|
||||
return wx.wxFont(config.fontsize or size or 10, wx.wxFONTFAMILY_MODERN, style,
|
||||
wx.wxFONTWEIGHT_NORMAL, false, config.fontname or name,
|
||||
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 "")
|
||||
|
||||
if wx.__WXMSW__ then
|
||||
ofont = wx.wxFont(ide.config.outputshell.fontsize or 10, wx.wxFONTFAMILY_MODERN, wx.wxFONTSTYLE_NORMAL,
|
||||
wx.wxFONTWEIGHT_NORMAL, false, ide.config.outputshell.fontname or "Courier New", ide.config.outputshell.fontencoding or wx.wxFONTENCODING_DEFAULT)
|
||||
ofontItalic = wx.wxFont(ide.config.outputshell.fontsize or 10, wx.wxFONTFAMILY_MODERN, wx.wxFONTSTYLE_ITALIC,
|
||||
wx.wxFONTWEIGHT_NORMAL, false, ide.config.outputshell.fontname or "Courier New", ide.config.outputshell.fontencoding or wx.wxFONTENCODING_DEFAULT)
|
||||
else
|
||||
ofont = wx.wxFont(ide.config.outputshell.fontsize or 10, wx.wxFONTFAMILY_MODERN, wx.wxFONTSTYLE_NORMAL,
|
||||
wx.wxFONTWEIGHT_NORMAL, false, ide.config.outputshell.fontname or "", ide.config.outputshell.fontencoding or wx.wxFONTENCODING_DEFAULT)
|
||||
ofontItalic = wx.wxFont(ide.config.outputshell.fontsize or 10, wx.wxFONTFAMILY_MODERN, wx.wxFONTSTYLE_ITALIC,
|
||||
wx.wxFONTWEIGHT_NORMAL, false, ide.config.outputshell.fontname or "", ide.config.outputshell.fontencoding or wx.wxFONTENCODING_DEFAULT)
|
||||
end
|
||||
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 = font
|
||||
ide.fontItalic = fontItalic
|
||||
ide.ofont = ofont
|
||||
ide.ofontItalic = ofontItalic
|
||||
-- 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
|
||||
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- Create the wxFrame
|
||||
@@ -65,44 +47,65 @@ local function createFrame()
|
||||
end)
|
||||
|
||||
local menuBar = wx.wxMenuBar()
|
||||
frame.menuBar = menuBar
|
||||
|
||||
local statusBar = frame:CreateStatusBar( 5 )
|
||||
frame.statusBar = statusBar
|
||||
local status_txt_width = statusBar:GetTextExtent("OVRW")
|
||||
statusBar:SetStatusWidths({-1, status_txt_width*6, status_txt_width, status_txt_width, status_txt_width*5})
|
||||
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:SetStatusWidths(
|
||||
{-1, section_width*6, section_width, section_width, section_width*4, section_width*4})
|
||||
statusBar:SetStatusText(GetIDEString("statuswelcome"))
|
||||
|
||||
local mgr = wxaui.wxAuiManager()
|
||||
frame.uimgr = mgr
|
||||
mgr:SetManagedWindow(frame)
|
||||
|
||||
frame.menuBar = menuBar
|
||||
frame.statusBar = statusBar
|
||||
frame.uimgr = mgr
|
||||
|
||||
return frame
|
||||
end
|
||||
|
||||
local function createToolBar(frame)
|
||||
local toolBar = wx.wxToolBar(frame, wx.wxID_ANY,
|
||||
wx.wxDefaultPosition, wx.wxDefaultSize, wx.wxTB_FLAT + wx.wxTB_NODIVIDER)
|
||||
local funclist = wx.wxChoice.new(toolBar,ID "toolBar.funclist",wx.wxDefaultPosition, wx.wxSize.new(240,16))
|
||||
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.
|
||||
wx.wxDefaultPosition, wx.wxSize.new(240,ide.osname == "Unix" and 24 or 16))
|
||||
|
||||
-- note: Ususally the bmp size isn't necessary, but the HELP icon is not the right size in MSW
|
||||
local toolBmpSize = toolBar:GetToolBitmapSize()
|
||||
toolBar:AddTool(ID_NEW, "New", wx.wxArtProvider.GetBitmap(wx.wxART_NORMAL_FILE, wx.wxART_TOOLBAR, toolBmpSize), "Create an empty document")
|
||||
toolBar:AddTool(ID_OPEN, "Open", wx.wxArtProvider.GetBitmap(wx.wxART_FILE_OPEN, wx.wxART_TOOLBAR, toolBmpSize), "Open an existing document")
|
||||
toolBar:AddTool(ID_SAVE, "Save", wx.wxArtProvider.GetBitmap(wx.wxART_FILE_SAVE, wx.wxART_TOOLBAR, toolBmpSize), "Save the current document")
|
||||
toolBar:AddTool(ID_SAVEALL, "Save All", wx.wxArtProvider.GetBitmap(wx.wxART_NEW_DIR, wx.wxART_TOOLBAR, toolBmpSize), "Save all documents")
|
||||
-- usually the bmp size isn't necessary, but the HELP icon is not the right size in MSW
|
||||
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), "Create an empty document")
|
||||
toolBar:AddTool(ID_OPEN, "Open", getBitmap(wx.wxART_FILE_OPEN, wx.wxART_TOOLBAR, toolBmpSize), "Open an existing document")
|
||||
toolBar:AddTool(ID_SAVE, "Save", getBitmap(wx.wxART_FILE_SAVE, wx.wxART_TOOLBAR, toolBmpSize), "Save the current document")
|
||||
toolBar:AddTool(ID_SAVEALL, "Save All", getBitmap(wx.wxART_NEW_DIR, wx.wxART_TOOLBAR, toolBmpSize), "Save all documents")
|
||||
toolBar:AddSeparator()
|
||||
toolBar:AddTool(ID_CUT, "Cut", wx.wxArtProvider.GetBitmap(wx.wxART_CUT, wx.wxART_TOOLBAR, toolBmpSize), "Cut the selection")
|
||||
toolBar:AddTool(ID_COPY, "Copy", wx.wxArtProvider.GetBitmap(wx.wxART_COPY, wx.wxART_TOOLBAR, toolBmpSize), "Copy the selection")
|
||||
toolBar:AddTool(ID_PASTE, "Paste", wx.wxArtProvider.GetBitmap(wx.wxART_PASTE, wx.wxART_TOOLBAR, toolBmpSize), "Paste text from the clipboard")
|
||||
toolBar:AddTool(ID_CUT, "Cut", getBitmap(wx.wxART_CUT, wx.wxART_TOOLBAR, toolBmpSize), "Cut the selection")
|
||||
toolBar:AddTool(ID_COPY, "Copy", getBitmap(wx.wxART_COPY, wx.wxART_TOOLBAR, toolBmpSize), "Copy the selection")
|
||||
toolBar:AddTool(ID_PASTE, "Paste", getBitmap(wx.wxART_PASTE, wx.wxART_TOOLBAR, toolBmpSize), "Paste text from the clipboard")
|
||||
toolBar:AddSeparator()
|
||||
toolBar:AddTool(ID_UNDO, "Undo", wx.wxArtProvider.GetBitmap(wx.wxART_UNDO, wx.wxART_TOOLBAR, toolBmpSize), "Undo last edit")
|
||||
toolBar:AddTool(ID_REDO, "Redo", wx.wxArtProvider.GetBitmap(wx.wxART_REDO, wx.wxART_TOOLBAR, toolBmpSize), "Redo last undo")
|
||||
toolBar:AddTool(ID_UNDO, "Undo", getBitmap(wx.wxART_UNDO, wx.wxART_TOOLBAR, toolBmpSize), "Undo last edit")
|
||||
toolBar:AddTool(ID_REDO, "Redo", getBitmap(wx.wxART_REDO, wx.wxART_TOOLBAR, toolBmpSize), "Redo last undo")
|
||||
toolBar:AddSeparator()
|
||||
toolBar:AddTool(ID_FIND, "Find", wx.wxArtProvider.GetBitmap(wx.wxART_FIND, wx.wxART_TOOLBAR, toolBmpSize), "Find text")
|
||||
toolBar:AddTool(ID_REPLACE, "Replace", wx.wxArtProvider.GetBitmap(wx.wxART_FIND_AND_REPLACE, wx.wxART_TOOLBAR, toolBmpSize), "Find and replace text")
|
||||
toolBar:AddTool(ID_FIND, "Find", getBitmap(wx.wxART_FIND, wx.wxART_TOOLBAR, toolBmpSize), "Find text")
|
||||
toolBar:AddTool(ID_REPLACE, "Replace", getBitmap(wx.wxART_FIND_AND_REPLACE, wx.wxART_TOOLBAR, toolBmpSize), "Find and replace text")
|
||||
if ide.app.createbitmap then -- custom handler should handle all bitmaps
|
||||
toolBar:AddSeparator()
|
||||
toolBar:AddTool(ID_START_DEBUG, "Start Debugging", getBitmap("wxART_DEBUG_START", wx.wxART_TOOLBAR, toolBmpSize), "Start debugging")
|
||||
toolBar:AddTool(ID_STOP_DEBUG, "Stop Debugging", getBitmap("wxART_DEBUG_STOP", wx.wxART_TOOLBAR, toolBmpSize), "Stop debugging")
|
||||
toolBar:AddTool(ID_BREAK, "Break", getBitmap("wxART_DEBUG_BREAK", wx.wxART_TOOLBAR, toolBmpSize), "Break running process")
|
||||
toolBar:AddTool(ID_STEP, "Step into", getBitmap("wxART_DEBUG_STEP_INTO", wx.wxART_TOOLBAR, toolBmpSize), "Step into")
|
||||
toolBar:AddTool(ID_STEP_OVER, "Step over", getBitmap("wxART_DEBUG_STEP_OVER", wx.wxART_TOOLBAR, toolBmpSize), "Step over")
|
||||
toolBar:AddTool(ID_STEP_OUT, "Step out", getBitmap("wxART_DEBUG_STEP_OUT", wx.wxART_TOOLBAR, toolBmpSize), "Step out")
|
||||
toolBar:AddSeparator()
|
||||
toolBar:AddTool(ID_TOGGLEBREAKPOINT, "Toggle breakpoint", getBitmap("wxART_DEBUG_BREAKPOINT_TOGGLE", wx.wxART_TOOLBAR, toolBmpSize), "Toggle breakpoint")
|
||||
toolBar:AddTool(ID_VIEWCALLSTACK, "Stack window", getBitmap("wxART_DEBUG_CALLSTACK", wx.wxART_TOOLBAR, toolBmpSize), "View stack window")
|
||||
toolBar:AddTool(ID_VIEWWATCHWINDOW, "Watch window", getBitmap("wxART_DEBUG_WATCH", wx.wxART_TOOLBAR, toolBmpSize), "View watch window")
|
||||
end
|
||||
toolBar:AddSeparator()
|
||||
toolBar:AddTool(ID "debug.projectdir.fromfile", "Update", wx.wxArtProvider.GetBitmap(wx.wxART_GO_DIR_UP , wx.wxART_TOOLBAR, toolBmpSize), "Sets projectdir from file")
|
||||
toolBar:AddTool(ID "debug.projectdir.fromfile", "Update", getBitmap(wx.wxART_GO_DIR_UP , wx.wxART_TOOLBAR, toolBmpSize), "Set project directory from current file")
|
||||
toolBar:AddSeparator()
|
||||
toolBar:AddControl(funclist)
|
||||
toolBar:Realize()
|
||||
|
||||
@@ -53,6 +53,7 @@ ID_BREAK = NewID()
|
||||
ID_TRACE = NewID()
|
||||
ID_VIEWCALLSTACK = NewID()
|
||||
ID_VIEWWATCHWINDOW = NewID()
|
||||
ID_FULLSCREEN = NewID()
|
||||
ID_CLEAROUTPUT = NewID()
|
||||
ID_PROJECTDIR = NewID()
|
||||
ID_INTERPRETER = NewID()
|
||||
@@ -64,6 +65,9 @@ ID_ADDWATCH = NewID()
|
||||
ID_EDITWATCH = NewID()
|
||||
ID_REMOVEWATCH = NewID()
|
||||
ID_EVALUATEWATCH = NewID()
|
||||
-- Editor popup menu items
|
||||
ID_QUICKADDWATCH = NewID()
|
||||
ID_QUICKEVAL = NewID()
|
||||
|
||||
local ids = {}
|
||||
function ID (name)
|
||||
|
||||
@@ -42,6 +42,8 @@ function M.show_warnings(top_ast)
|
||||
warnings[#warnings+1] = (path or "?") .. "(" .. (linenum or 0) .. "): " .. msg
|
||||
end
|
||||
local function known(o) return not T.istype[o] end
|
||||
local function index(f) -- build abc.def.xyz name recursively
|
||||
return (f[1].tag == 'Id' and f[1][1] or index(f[1])) .. '.' .. f[2][1] end
|
||||
local isseen, globseen = {}, {}
|
||||
LA.walk(top_ast, function(ast)
|
||||
local line = ast.lineinfo and ast.lineinfo.first[1] or 0
|
||||
@@ -66,11 +68,18 @@ 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'
|
||||
local fname = assignment and type(func[1][1][1]) == 'string' and func[1][1][1]
|
||||
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))
|
||||
-- "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
|
||||
-- "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
|
||||
and (fname and func.tag
|
||||
@@ -151,7 +160,7 @@ local function analyzeProgram(editor)
|
||||
local filePath = DebuggerMakeFileName(editor, openDocuments[id].filePath)
|
||||
|
||||
if frame.menuBar:IsChecked(ID_CLEAROUTPUT) then ClearOutput() end
|
||||
DisplayOutput("Analizing the source code")
|
||||
DisplayOutput("Analyzing the source code")
|
||||
frame:Update()
|
||||
|
||||
local warn, err = M.warnings_from_string(editorText, filePath)
|
||||
|
||||
@@ -46,10 +46,20 @@ ide.iofilters["GermanUtf8Ascii"] = {
|
||||
|
||||
}
|
||||
|
||||
ide.iofilters["0d0d0aFix"] = {
|
||||
-- this function converts 0d0d0a line ending to 0d0a
|
||||
input = function(fpath, content)
|
||||
return content:gsub("\013\013\010","\013\010")
|
||||
end,
|
||||
}
|
||||
|
||||
--üäß
|
||||
|
||||
for i,filter in pairs(ide.iofilters) do
|
||||
assert(filter.output("",filter.input("","äöüÄÖÜß")),"„â€ÂäöüÄÖÜß","UTF8-ANSI conversion failed: "..(i))
|
||||
if filter.input and filter.output then
|
||||
assert(filter.output("",filter.input("","äöüÄÖÜß")),
|
||||
"„â€ÂäöüÄÖÜß","UTF8-ANSI conversion failed: "..(i))
|
||||
end
|
||||
end
|
||||
|
||||
-- which: "input" or "output"
|
||||
|
||||
@@ -5,12 +5,13 @@ local styles = ide.config.styles
|
||||
local comment = styles.comment
|
||||
local MD_MARK_ITAL = '_' -- italic
|
||||
local MD_MARK_BOLD = '**' -- bold
|
||||
local MD_MARK_LINK = '[' -- link
|
||||
local MD_MARK_LINT = ')' -- link terminator
|
||||
local MD_MARK_LINK = '[' -- link description start
|
||||
local MD_MARK_LINZ = ']' -- link description end
|
||||
local MD_MARK_LINA = '(' -- link URL start
|
||||
local MD_MARK_LINT = ')' -- link URL end
|
||||
local MD_MARK_HEAD = '#' -- header
|
||||
local MD_MARK_CODE = '`' -- code
|
||||
local MD_MARK_BOXD = '|' -- highlight
|
||||
local MD_MARK_LSEP = '](' -- link separator (between text and link)
|
||||
local MD_MARK_MARK = ' ' -- separator
|
||||
local MD_LINK_NEWWINDOW = '+' -- indicator to open a new window for links
|
||||
local markup = {
|
||||
@@ -25,6 +26,7 @@ local markup = {
|
||||
|
||||
-- allow other editor features to recognize this special markup
|
||||
function MarkupIsSpecial(style) return style == 31 end
|
||||
function MarkupIsAny(style) return style >= 25 and style <= 31 end
|
||||
|
||||
local function q(s) return s:gsub('(.)','%%%1') end
|
||||
|
||||
@@ -45,11 +47,12 @@ function MarkupHotspotClick(pos, editor)
|
||||
pos = pos + #MD_MARK_LINK - editor:PositionFromLine(line) -- turn into relative position
|
||||
|
||||
-- extract the URL/command on the right side of the separator
|
||||
local _,_,text = string.find(tx, q(MD_MARK_LSEP).."([^%s]+)"..q(MD_MARK_LINT), pos)
|
||||
local _,_,text = string.find(tx, q(MD_MARK_LINZ).."(%b"..MD_MARK_LINA..MD_MARK_LINT..")", pos)
|
||||
if text then
|
||||
text = text:gsub("^"..q(MD_MARK_LINA), ""):gsub(q(MD_MARK_LINT).."$", "")
|
||||
local filepath = ide.openDocuments[editor:GetId()].filePath
|
||||
local _,_,shell = string.find(text, [[^macro:shell%((.*%S)%)$]])
|
||||
local _,_,http = string.find(text, [[^(http:%S+)$]])
|
||||
local _,_,http = string.find(text, [[^(https?:%S+)$]])
|
||||
local _,_,command = string.find(text, [[^macro:(%w+)$]])
|
||||
if shell then
|
||||
ShellExecuteCode(shell)
|
||||
@@ -59,7 +62,7 @@ function MarkupHotspotClick(pos, editor)
|
||||
ProjectDebug()
|
||||
elseif http then -- open the URL in a new browser window
|
||||
wx.wxLaunchDefaultBrowser(http, 0)
|
||||
else
|
||||
elseif filepath then -- only check for saved files
|
||||
-- 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
|
||||
@@ -70,6 +73,7 @@ function MarkupHotspotClick(pos, editor)
|
||||
filename:Normalize() -- remove .., ., and other similar elements
|
||||
if filename:FileExists() 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)
|
||||
end
|
||||
end
|
||||
@@ -96,10 +100,10 @@ local function ismarkup (tx)
|
||||
-- [%w%p] set is needed to avoid continuing this markup to the next line
|
||||
s,e,cap = string.find(tx,"^("..q(MD_MARK_HEAD)..".+[%w%p])")
|
||||
elseif sep == MD_MARK_LINK then
|
||||
-- allow everything except spaces in the second part
|
||||
s,e,cap = string.find(tx,"^("..q(MD_MARK_LINK)..nonspace..".-"..nonspace
|
||||
..q(MD_MARK_LSEP).."[^%s]+"
|
||||
..q(MD_MARK_LINT)..")", st)
|
||||
-- allow everything based on balanced link separators
|
||||
s,e,cap = string.find(tx,
|
||||
"^(%b"..MD_MARK_LINK..MD_MARK_LINZ
|
||||
.."%b"..MD_MARK_LINA..MD_MARK_LINT..")", st)
|
||||
elseif markup[sep] then
|
||||
-- try 2+ characters between separators first
|
||||
-- if not found, try a single character
|
||||
@@ -144,7 +148,9 @@ function MarkupStyle(editor, lines, linee)
|
||||
if (f) then
|
||||
local p = ls+f+off
|
||||
local s = bit.band(editor:GetStyleAt(p), 31)
|
||||
if iscomment[s] then
|
||||
-- only style comments and only those that are not at the beginning
|
||||
-- of the file to avoid styling shebang (#!) lines
|
||||
if iscomment[s] and p > 0 then
|
||||
local smark = #mark
|
||||
local emark = #mark -- assumes end mark is the same length as start mark
|
||||
if mark == MD_MARK_HEAD then
|
||||
@@ -152,7 +158,7 @@ function MarkupStyle(editor, lines, linee)
|
||||
local _,_,full = string.find(w,"^("..q(MD_MARK_HEAD).."+)")
|
||||
smark,emark = #full,0
|
||||
elseif mark == MD_MARK_LINK then
|
||||
local lsep = w:find(q(MD_MARK_LSEP))
|
||||
local lsep = w:find(q(MD_MARK_LINZ)..q(MD_MARK_LINA))
|
||||
if lsep then emark = #w-lsep+#MD_MARK_LINT end
|
||||
end
|
||||
editor:StartStyling(p, 31)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user