Compare commits

...

215 Commits
0.37 ... 0.381

Author SHA1 Message Date
Paul Kulchenko
f28d4da053 Fixed having duplicate tabs after SaveAs with existing file name. 2013-09-08 14:38:59 -07:00
Paul Kulchenko
858742bf05 Fixed showing redirected 'print' messages after debugging is terminated. 2013-09-06 21:29:33 -07:00
Paul Kulchenko
d559afd9e2 Updated CFBundleIdentifier in plist files to allow references from OSX programs. 2013-09-06 15:07:43 -07:00
Paul Kulchenko
9acec71c7a Added package GetEditorNotebook method (ref #166). 2013-09-06 15:01:34 -07:00
Paul Kulchenko
8568f61ba4 Added 'molokai' color scheme (ref #200). 2013-09-05 22:23:28 -07:00
Paul Kulchenko
6714f29302 Updated un/comment to toggle selection as a group rather than line by line. 2013-09-04 19:09:28 -07:00
Paul Kulchenko
f0b7cff06a Added file activation for abbreviated file names in error messages. 2013-09-04 15:26:54 -07:00
Paul Kulchenko
25589fc45a Reorganized path separator handling to minimize use of global variables. 2013-09-04 12:00:57 -07:00
Paul Kulchenko
6a7c8e78c0 Added abbreviation of project directories to keep unique parts visible. 2013-09-03 22:35:33 -07:00
Paul Kulchenko
443f936ac6 Added debugger.redirect configuration option. 2013-09-02 21:07:48 -07:00
Paul Kulchenko
12525ad189 Added editor.saveallonrun configuration option. 2013-09-02 10:43:03 -07:00
Paul Kulchenko
69fae9a36c Fixed using default interpreter when no interpreter is selected. 2013-09-02 10:32:47 -07:00
Paul Kulchenko
725a38b182 Improved IDE activation during debugging on Windows (closes #199); thanks to jpoag. 2013-09-01 22:28:04 -07:00
Paul Kulchenko
13c4ca1a2f Fixed stepping through blocks with undefined variables when 'strict' is in effect (upgraded Mobdebug to 0.5401). 2013-09-01 21:17:47 -07:00
Paul Kulchenko
3e68447415 Updated CHANGELOG with recent changes. 2013-08-29 19:19:42 -07:00
Paul Kulchenko
0419e6812b Added package GetOutput method (ref #166). 2013-08-27 14:15:36 -07:00
Paul Kulchenko
cd1b9d7cd2 Added package onAppLoad/onAppClose events (ref #166). 2013-08-27 14:14:36 -07:00
Paul Kulchenko
d63dda5e6a Cleaned up code. 2013-08-27 14:12:29 -07:00
Paul Kulchenko
32f4b8694b Updated NewFile to accept a file name. 2013-08-27 11:19:50 -07:00
Paul Kulchenko
2dbb6644cb Fixed loading of files with incorrect UTF-8 encoding and control characters (fixes #198). 2013-08-27 10:11:32 -07:00
Paul Kulchenko
649e3c620a Added package onIdleOnce event (ref #166). 2013-08-26 20:22:16 -07:00
Paul Kulchenko
0e7bb32024 Fixed package sample to take into account new documents. 2013-08-25 19:19:30 -07:00
Paul Kulchenko
96f0f876bf Renamed package onEditorPostSave event to onEditorSave for consistency (ref #166). 2013-08-24 17:02:06 -07:00
Paul Kulchenko
58a494931c Added manifest to the Windows executable and re-signed. 2013-08-23 16:04:08 -07:00
Paul Kulchenko
f04160fad1 Updated 'get hostname' logic to avoid using non-resolvable names (mostly on OSX). 2013-08-22 20:38:02 -07:00
Paul Kulchenko
671c62871a Added Notepad++ color scheme (thanks to Florian/SiENcE; closes #193). 2013-08-21 08:54:03 -07:00
Paul Kulchenko
6a6e7ec770 Fixed crash on OSX after opening 'application' in 'Open File' dialog. 2013-08-20 14:55:09 -07:00
Paul Kulchenko
eff4eb8b05 Disabled markup styling for specs without comment styles. 2013-08-20 12:09:02 -07:00
Paul Kulchenko
2781c0ea00 Removed comment from default spec as it forces undesired markup styling. 2013-08-20 12:08:27 -07:00
Paul Kulchenko
fa507450e4 Added clearing document styles after saving file with a different extension. 2013-08-20 12:04:11 -07:00
Paul Kulchenko
a4f069afc0 Fixed windows resource file to properly reference the manifest. 2013-08-17 22:24:50 -07:00
Paul Kulchenko
f3b84edc24 Fixed missing default api for files with unknown extensions. 2013-08-16 21:59:17 -07:00
Paul Kulchenko
ba1c1a678e Added workaround to avoid crash on OSX after Close All Pages (closes #190).
The issue is with wxwidgets (filed as ticket 15417); the only workaround I
have been able to find is to disable this functionality on OSX (as there
are other alternatives to closing tabs in groups). The issue only happens
when the last tab is closed from the drop down menu linked to editor tabs.
2013-08-15 15:54:43 -07:00
Paul Kulchenko
267deea3df Merge branch 'master' of git://git.code.sf.net/p/estrelaeditor/code into estrela-new 2013-08-15 15:36:18 -07:00
Paul Kulchenko
1089f2619e Added return type for string.* functions to assist in auto-complete (ref #189). 2013-08-14 12:43:55 -07:00
Paul Kulchenko
e8c5e7fd78 Added handling of string literals in type assignments (closes #189). 2013-08-14 12:37:49 -07:00
Christoph Kubisch
ff6deedf79 OpenGL 4.4 and ARB extensions added as well as NV_gpu_shader5 functions 2013-08-14 14:19:50 +02:00
Paul Kulchenko
52c7150e51 Switched to using POSIX compatible regexp with '()' used for captures. 2013-08-13 14:50:21 -07:00
Paul Kulchenko
24555a3b3d Fix spurious replacement after 'search, clear selection, replace' actions. 2013-08-13 14:47:01 -07:00
Paul Kulchenko
cc432b65b0 Added support for captures in regexp replacement (\1-\9). 2013-08-13 14:39:06 -07:00
Paul Kulchenko
8d1cca26a3 Fixed using auto-complete with multiple selections (fixes #188). 2013-08-11 15:04:42 -07:00
Paul Kulchenko
c077c94371 Fixed looping in auto-complete with array references (ref #143). 2013-08-11 15:00:32 -07:00
Paul Kulchenko
1ba300213d Added ability to cancel FindInFiles search by closing search dialog (ref #162). 2013-08-10 21:38:50 -07:00
Paul Kulchenko
3fbf0ef81b Added activating Output window before showing search results (ref #162). 2013-08-10 21:38:11 -07:00
Paul Kulchenko
aced5d1bc3 Changed un/comment to act from the beginning of the line for multi-line selection.
Fixed handling of EOL markers (un/commenting doesn't modify them anymore).
Added processing of rectangular selections.
2013-08-09 14:52:25 -07:00
Paul Kulchenko
bf072c1685 Added support for packages from different platforms to co-exist (ref #166). 2013-08-07 23:23:14 -07:00
Paul Kulchenko
4215054b87 Improved logic to jump to file/line indicated in error messages. 2013-08-06 09:20:15 -07:00
Paul Kulchenko
cd85d6f2e8 Added ability to save complex data in package settings (ref #166). 2013-08-05 19:12:05 -07:00
Paul Kulchenko
6fc448b87c Fixed incorrect change for line count calculation for dynamic words.
Fixed commit d6cda0d677.
2013-08-04 22:20:59 -07:00
Paul Kulchenko
d6cda0d677 Optimized line count calculation for dynamic words when text is deleted. 2013-08-04 22:12:13 -07:00
Paul Kulchenko
5355234b85 Fixed showing auto-complete after comma. 2013-08-04 21:37:26 -07:00
Paul Kulchenko
700dfe1765 Optimized dynamic word processing for large files. 2013-08-04 20:29:41 -07:00
Paul Kulchenko
1c068c221f Merge branch 'master' of git://git.code.sf.net/p/estrelaeditor/code into estrela-changes 2013-08-04 17:51:53 -07:00
Paul Kulchenko
5679d90bcd Added support for multiple inheritance in auto-complete (ref #101). 2013-08-03 15:38:24 -07:00
Paul Kulchenko
9b5f6fa67f Added ability to add/remove API descriptions from plugins (ref #166). 2013-08-02 11:05:00 -07:00
Christoph Kubisch
a8060b63cd updated glewgl api for OpenGL4.4 and removed non-core duplicate functions/enums 2013-08-02 10:23:52 +02:00
Paul Kulchenko
7324afb8e3 Reorganized API processing to allow loading API description from a plugin. 2013-08-01 11:03:23 -07:00
Paul Kulchenko
e209f3f440 Added package GetSettings/SetSettings methods (ref #166). 2013-07-28 22:24:44 -07:00
Paul Kulchenko
08ef16a42d Added methods to save/restore package settings (ref #166). 2013-07-27 22:23:41 -07:00
Paul Kulchenko
4fafcff592 Fixed 'cannot get official hostname' message on low privilege accounts (fixes #183). 2013-07-26 08:15:53 -07:00
Paul Kulchenko
6e0e3d07e3 Updated Estrela reference in README. 2013-07-25 14:49:03 -07:00
Paul Kulchenko
fb9c0ba0a6 Disabled showing tooltip when auto-complete suggestions are shown. 2013-07-25 14:48:27 -07:00
Paul Kulchenko
1b4f707232 Updated build script on Windows to enable debugging (ref #164). 2013-07-24 09:50:49 -07:00
Paul Kulchenko
1749c54f71 Updated build script with a (temporary) fix for wxlua issue (mingw32). 2013-07-24 09:48:51 -07:00
Paul Kulchenko
e4201b745c Fixed displaying variable instances when code has invalid blocks (fixes #182). 2013-07-23 14:50:29 -07:00
Paul Kulchenko
9c810b3520 Fixed tooltip to ignore string parameters (ref #101). 2013-07-23 10:07:29 -07:00
Paul Kulchenko
93d3b69335 Removed auto-complete suggestion when it is already typed (ref #101). 2013-07-22 18:45:44 -07:00
Paul Kulchenko
35617caa0e Updated tooltip to use the same type inference as auto-complete (ref #101). 2013-07-22 18:21:52 -07:00
Paul Kulchenko
e07ed0a817 Fixed tooltip display between empty brackets (ref #101). 2013-07-22 17:49:39 -07:00
Paul Kulchenko
aeb35ebf6f Added ability to add/remove specs from plugins (ref #166). 2013-07-22 16:11:18 -07:00
Paul Kulchenko
c84bd3222b Enabled support for xml/html folding. 2013-07-21 22:22:30 -07:00
Paul Kulchenko
e398a216a8 Added ability to add/remove interpreters from plugins (ref #166). 2013-07-20 23:21:44 -07:00
Paul Kulchenko
4137b9d88d Added wxlua patch for twoface compatibility. 2013-07-20 15:17:09 -07:00
Paul Kulchenko
a630dd95c7 Added setfenv for Lua 5.2 compatibility. 2013-07-19 12:51:53 -07:00
Paul Kulchenko
0b748d6389 Updated static analyzer to report only first instance of 'unknown field'. 2013-07-18 16:28:12 -07:00
Paul Kulchenko
790f9d5b45 Added links to project page and documentation (closes #180). 2013-07-18 15:26:00 -07:00
Paul Kulchenko
43513c9153 Updated filename/source code heuristic in the debugger (Mobdebug 0.5362).
If the "chunkname" has no newline, it's treated as a file name.
This helps with handling cases when the application engine reports
filenames without @ (for example, when they are loaded using
loadstring("chunk", "file") instead of loadstring("chunk", "@file"));
also helps with debugging cocos2dx apps that load Lua files.
2013-07-18 15:20:59 -07:00
Paul Kulchenko
f58f185850 Enabled path remapping for local debugging.
This helps in local debugging when project files are copied to a temporary
location, but need to be debugged from the project folder (for example,
with debugging of cocos2d-x apps in iOS simulator).
2013-07-18 14:10:54 -07:00
Paul Kulchenko
ebbeb107a7 Disabled error reporting after debugging has been terminated. 2013-07-17 16:54:12 -07:00
Paul Kulchenko
e0674f9c9a Limited activation of code fragments to the beginning of debugging session.
This can still be configured using `editor.autoactivate` option.
2013-07-16 16:52:31 -07:00
Paul Kulchenko
89cafbec45 Enabled slower and more thorough static analysis (ref #149; ref #168). 2013-07-15 22:02:30 -07:00
Paul Kulchenko
e0f543c262 Updated CHANGELOG with recent changes. 2013-07-14 20:27:24 -07:00
Paul Kulchenko
b73526586c Fixed indentation after lines with brackets in strings. 2013-07-13 09:14:12 -07:00
Paul Kulchenko
cc177264f6 Fixed indentation after lines with anonymous functions. 2013-07-12 22:49:55 -07:00
Paul Kulchenko
2f98bc30a6 Added German translation (thanks to Riidom; ref #70). 2013-07-11 16:38:32 -07:00
Paul Kulchenko
b9374894c9 Set search in subdirectories as default in Find in Files dialog (ref #162). 2013-07-10 16:32:26 -07:00
Paul Kulchenko
17a995a810 Fixed indicator showing at the end of not terminated long comment. 2013-07-09 22:54:23 -07:00
Paul Kulchenko
35d1bc0f03 Fixed an issue with LUA_DEV including files instead of directories. 2013-07-07 23:35:15 -07:00
Paul Kulchenko
6f044d8b2e Added default value to package config (ref #176). 2013-07-06 15:27:31 -07:00
Paul Kulchenko
735f8492e2 Fixed project switching to close all files when switching to a subdirectory.
Some of the files could have been left open if the name starts with
the name of a subdirectory the project is being switched to.
2013-07-05 16:52:22 -07:00
Paul Kulchenko
4eb57fcbda Fixed saving projects that do not have any open files. 2013-07-04 16:48:12 -07:00
Paul Kulchenko
c882b8d0e0 Added handling of ?51.dll and required DLLs for LuaForWindows interpreter. 2013-07-03 17:40:01 -07:00
Paul Kulchenko
ce8552f044 Added plugin::GetConfig method (ref #166). 2013-07-03 14:25:06 -07:00
ardente
6968364c58 windows: adopt native user home 2013-07-03 16:39:57 +04:00
Paul Kulchenko
9ab72209c2 Added erasing current line in Console (ref #173). 2013-07-01 18:46:31 -07:00
Paul Kulchenko
c872934157 Added search/completion in the local and remote console (closes #173). 2013-06-30 20:41:42 -07:00
Paul Kulchenko
ea2d7c289a Replaced package onEditorActivated event with onEditorFocus* events (ref #166). 2013-06-30 13:09:44 -07:00
Paul Kulchenko
19ab4df922 Updated SaveAll to allow saving (only) files with filenames (ref #172).
This is useful when `SaveAll` is called from a plugin and user interaction
(asking for a file name) is not desired.
2013-06-30 10:06:19 -07:00
Paul Kulchenko
7dda2c00fd Added package onAppFocus* events (ref #166; ref #172). 2013-06-30 09:27:16 -07:00
Paul Kulchenko
3d3ae5ca00 Fixed debugger to accept filenames without '@'; thanks to Tim Mensch (closes #174). 2013-06-28 21:55:27 -07:00
Paul Kulchenko
28c3b79b8b Added Chinese translation (thanks to Chow CheeWen; ref #70). 2013-06-28 21:37:05 -07:00
Paul Kulchenko
a91bba8bd0 Added editor.autoreload to enable reload of updated files (ref #172).
Thanks for Tim Mensch for suggestion and implementation.
2013-06-26 23:27:31 -07:00
Paul Kulchenko
ed874063ea Added creating (missing) folders when saving a file (fixes #171). 2013-06-25 17:10:57 -07:00
Paul Kulchenko
6259918648 Added an example of styling individual keywords. 2013-06-24 21:03:07 -07:00
Paul Kulchenko
0995c5a061 Added fold indication of a current block (ref #168). 2013-06-24 21:01:49 -07:00
Paul Kulchenko
f07e42c4b4 Fixed sorting when the sorted fragment ends with a newline. 2013-06-24 17:15:02 -07:00
Paul Kulchenko
7e62939df6 Moved 'Sort' menu to 'Edit'. 2013-06-24 17:12:26 -07:00
Paul Kulchenko
b57bf55ef0 Added reporting of process id for a conflicting process. 2013-06-23 21:58:40 -07:00
Paul Kulchenko
8ed91f76cc Disabled 'Fold' menu instead of removing when no folding is allowed (ref #169). 2013-06-22 22:14:20 -07:00
Mika Attila
9e6ec10be9 Make code folding optional
Some users might consider code folding a needless distraction.
Several editors offer the option to turn code folding off.

This commit adds the editor.fold option, which is a boolean.
true enables code folding (default)
false disables code folding
2013-06-22 12:02:31 +02:00
Paul Kulchenko
115924d567 Fixed missing markdown styling after text removal. 2013-06-21 15:39:53 -07:00
Paul Kulchenko
cc9f9bb49d Updated documentation for 0.38. 2013-06-21 13:58:16 -07:00
Paul Kulchenko
418aef7065 Fixed clearing masked indicators on updated lines. 2013-06-21 09:06:50 -07:00
Paul Kulchenko
0f2e74a098 Added sorting of file lists on Linux (used in the filetree and file search). 2013-06-20 20:15:16 -07:00
Paul Kulchenko
2bc125e616 Disabled following symlinks during directory scanning to avoid infinite loops. 2013-06-20 20:13:50 -07:00
Paul Kulchenko
6b349bbef0 Set default directory for Find in Files opened from a new file (#ref 162). 2013-06-20 20:06:12 -07:00
Paul Kulchenko
7fbcb0b6c7 Fixed looping in auto-complete when indexes are used (fixes #143). 2013-06-20 14:54:13 -07:00
Paul Kulchenko
adb49b8007 Added removing comments for more robust type assignment analysis. 2013-06-20 14:23:23 -07:00
Paul Kulchenko
fb381eaadb Updated LuaForWindows interpreter to set basedir to match current directory. 2013-06-20 14:21:45 -07:00
Paul Kulchenko
8ad9e83b92 Added support for changing the Corona simulator skin (closes #151). 2013-06-19 21:52:40 -07:00
Paul Kulchenko
b8d331b8a9 Updated configuration example for variable indicators. 2013-06-19 21:50:51 -07:00
Paul Kulchenko
76f6fdade6 Updated Gideros auto-complete API to add global objects. 2013-06-19 10:30:51 -07:00
Paul Kulchenko
2fd08a751a Fixed possible duplicate paths in the filetree. 2013-06-18 23:10:43 -07:00
Paul Kulchenko
d5d6247286 Added LuaForWindows interpreter (thanks to Tom Burgel). 2013-06-18 17:52:26 -07:00
Paul Kulchenko
1af5b5e10c Added resetting breakpoints when needed for source code debugging. 2013-06-18 16:52:52 -07:00
Paul Kulchenko
4eda473d9f Added package onEditorCharAdded/onEditorKeyDown events (ref #166). 2013-06-18 12:51:51 -07:00
Paul Kulchenko
58c416e148 Updated capitalization for editor menu items. 2013-06-18 09:27:17 -07:00
Paul Kulchenko
5787dae35c Updated CHANGELOG with recent changes. 2013-06-17 21:29:52 -07:00
Paul Kulchenko
ec1a87f219 Fixed an error when closing editor tab that is still being styled. 2013-06-17 15:57:28 -07:00
Paul Kulchenko
e9728b2a4a Updated Gideros API to separate 'functions' from 'methods'. 2013-06-16 19:29:24 -07:00
Paul Kulchenko
a9c7e247fe Removed duplicates from auto-complete suggestions. 2013-06-16 16:24:18 -07:00
Fringale
0b0d95b2bf Updated French translation with latest string changes (mostly for find/replace dialogs). 2013-06-16 18:55:03 +02:00
Paul Kulchenko
32c3723bcc Updated Marmalade Quick auto-complete API to use class inheritance. 2013-06-14 18:40:34 -07:00
Paul Kulchenko
9d11df3ebe Updated Gideros auto-complete API to use class inheritance. 2013-06-14 18:34:01 -07:00
Paul Kulchenko
14b6568eb5 Added inheritance support for auto-complete API. 2013-06-14 18:33:06 -07:00
Paul Kulchenko
4d8e5647a6 Fixed missing numerical keys in serialized tables (upgraded Mobdebug to 0.535). 2013-06-14 10:15:36 -07:00
Paul Kulchenko
6a3aafc6fa Add package onEditor* events (closes #166). 2013-06-13 22:31:57 -07:00
Paul Kulchenko
8ee608c761 Added package onInterpreterLoad/onInterpreterClose events (ref #166). 2013-06-13 22:31:56 -07:00
Paul Kulchenko
120bc5b48b Added package onProjectLoad/onProjectClose events (ref #166). 2013-06-13 22:31:47 -07:00
Paul Kulchenko
f23ca203ca Added package onMenu* events (ref #166). 2013-06-13 22:31:28 -07:00
Paul Kulchenko
a390825676 Added package onRegister/onUnRegister events (ref #166). 2013-06-13 22:31:16 -07:00
Paul Kulchenko
baa76790e5 Fixed (regression) issue with setting breakpoints before debugging is started. 2013-06-12 10:41:07 -07:00
Paul Kulchenko
344835bf28 Added 'Show Location' to the Project/Filetree menu. 2013-06-12 09:53:12 -07:00
Paul Kulchenko
b9ecfd9284 Added hidpi option to enable HiDPI/Retina display support (closes #160). 2013-06-11 15:37:09 -07:00
Paul Kulchenko
9175bdd3ed Ugraded Mobdebug to 0.534 for debugging of source code fragments. 2013-06-10 00:28:09 -07:00
Paul Kulchenko
e07ac2109a Added breakpoint support for unnamed code fragments. 2013-06-09 00:19:15 -07:00
Paul Kulchenko
77588aa757 Added support for debugging (stepping through) unnamed code fragments. 2013-06-08 00:16:12 -07:00
Paul Kulchenko
065a6f933c Added LuaSec to win32 build script. 2013-06-07 23:10:39 -07:00
Paul Kulchenko
dee316094f Added package/plugin processing. 2013-06-08 13:31:32 -07:00
Paul Kulchenko
30bb8c29a6 Updated Gideros API/auto-complete reference. 2013-06-07 10:44:43 -07:00
Paul Kulchenko
4e66f20078 Allowed tab width and indentation to be set independently. 2013-06-06 23:00:44 -07:00
Paul Kulchenko
a4c503027a Fixed styling of markup that can be affected by folded lines. 2013-06-06 10:07:48 -07:00
Paul Kulchenko
3a5ef4b5e4 Updated markup to allow opening files from new buffers ('untitled'). 2013-06-06 10:07:46 -07:00
Paul Kulchenko
666024a77a Refactored Project tree handling. 2013-06-06 10:07:45 -07:00
Paul Kulchenko
501ba761a9 Added support for 'silent' execution of shell commands in markup. 2013-06-06 10:07:43 -07:00
Paul Kulchenko
66cc79a3fe Added Find Next/Previous over selected variable instances (ref #163). 2013-06-05 10:02:28 -07:00
Paul Kulchenko
a5d5fd729a Fixed value selection with multiple active selections. 2013-06-04 14:34:36 -07:00
Paul Kulchenko
6ad74e09a9 Improved error reporting in interpreters on failures to copy the debugger. 2013-06-04 14:03:38 -07:00
Paul Kulchenko
87dd7edf61 Fixed style compatibility with wxwidgets 2.8 (ref #128). 2013-06-04 13:28:28 -07:00
Paul Kulchenko
06356f6940 Added debugger.allowediting option to allow editing while debugging. 2013-06-03 22:01:37 -07:00
Paul Kulchenko
a4d423c685 Fixed error reporting by (internal) file operations. 2013-06-03 20:50:56 -07:00
Paul Kulchenko
32e828088b Fixed styling comments that start with markup symbols. 2013-06-03 20:38:35 -07:00
Paul Kulchenko
dcfc212bf4 Added skiping binary files during file search (ref #162). 2013-06-03 20:34:53 -07:00
Paul Kulchenko
790d1a6516 Added yield to update search results during file search (ref #162). 2013-06-03 20:34:42 -07:00
Paul Kulchenko
bc660522d5 Added showing default extensions in the file search (ref #162). 2013-06-03 20:34:05 -07:00
Paul Kulchenko
3cc29e1301 Added support for multiple file extensions in the file search (ref #162). 2013-06-03 20:33:16 -07:00
Paul Kulchenko
7b87bc3d88 Added saving folder to search files in (ref #162). 2013-05-31 17:37:26 -07:00
Paul Kulchenko
837a242bbd Fixed restoring a session with one of the files deleted on disk (fixes #161). 2013-05-30 20:06:38 -07:00
Paul Kulchenko
c2ddc72829 Added support for styles.fncall for backward compatibility. 2013-05-30 10:42:00 -07:00
Paul Kulchenko
045b9ad932 Added instance counter to 'Select all Instances'. 2013-05-29 21:26:11 -07:00
Paul Kulchenko
f0b007ff75 Updated activation of 'Select all Instances' to Ctrl/Cmd-DblClick (closes #159). 2013-05-29 20:09:33 -07:00
Paul Kulchenko
c2022a2d33 Added transparency to additional selections (ref #159). 2013-05-29 18:10:09 -07:00
Paul Kulchenko
0c1ef8870e Fixed main selection in 'Select all Instances' to avoid cursor jumps (ref #159). 2013-05-29 18:09:00 -07:00
Paul Kulchenko
22716e9d20 Disabled showing tooltip when the app is in the background (fixes #158). 2013-05-29 13:47:15 -07:00
Paul Kulchenko
34f4564ec0 Fixed reporting variable instances for comment/string fragments. 2013-05-28 13:34:59 -07:00
Paul Kulchenko
e26db06ede Added configuration for analizer indicator styles. 2013-05-28 13:29:37 -07:00
Paul Kulchenko
7384afa325 Moved Lua specific logic for variable indicators to the spec file. 2013-05-27 21:39:28 -07:00
Paul Kulchenko
209756349c Suppressed tooltips with empty descriptions. 2013-05-27 20:41:39 -07:00
Paul Kulchenko
294d19806b Fixed instance selection for local a = a type localization. 2013-05-27 17:44:58 -07:00
Paul Kulchenko
2dc5f85dbb Fixed masking of implicit self parameter. 2013-05-27 14:10:30 -07:00
Paul Kulchenko
f2aeebb8f6 Added a style for masking variables. 2013-05-27 11:58:05 -07:00
Paul Kulchenko
63cc789959 Fixed masking of variables that could reference incorrect location. 2013-05-27 11:32:28 -07:00
Paul Kulchenko
bf19bf7e39 Fixed parser reporting (internal) error on invalid code. 2013-05-26 16:27:32 -07:00
Paul Kulchenko
776888838b Fixed an error when quick search fails with multiple fragments. 2013-05-26 16:13:22 -07:00
Paul Kulchenko
29738092e7 Added selecting all instances with a double-click on a variable. 2013-05-26 16:11:53 -07:00
Paul Kulchenko
c8b669bb80 Added styles and config options for analizer indicators. 2013-05-25 22:41:53 -07:00
Paul Kulchenko
398f3dee55 Added autoanalizer option for dynamic static analysis. 2013-05-25 22:15:40 -07:00
Paul Kulchenko
54db8d28f0 Fixed masking by a statement at the end of file. 2013-05-25 22:15:39 -07:00
Paul Kulchenko
6531ff3c66 Fixed 'Rename Instances' to always reset previous selection. 2013-05-25 22:15:37 -07:00
Paul Kulchenko
cd27b14152 Fixed popup menu logic for one character variables. 2013-05-25 22:15:36 -07:00
Paul Kulchenko
3da05c2a7e Fixed showing all instances of a variable. 2013-05-25 22:15:35 -07:00
Paul Kulchenko
df58fadd15 Fixed masking of function parameters and loop variables. 2013-05-25 22:15:33 -07:00
Paul Kulchenko
48b596af01 Added 'Go To Definition' and 'Rename All Instances'. 2013-05-25 22:15:32 -07:00
Paul Kulchenko
dc36a0f6da Added masking for parameters in variable indication. 2013-05-25 22:15:31 -07:00
Paul Kulchenko
a9488870b3 Added initial support for indicating local/global variables. 2013-05-25 22:15:30 -07:00
Paul Kulchenko
924f1ad89a Disabled 'value' tooltip over variables that match known function names (ref #101). 2013-05-25 22:14:16 -07:00
Paul Kulchenko
bcf0b2ee7b Added showing tooltip in any position over a term and showing 'values' (ref #101). 2013-05-24 16:17:28 -07:00
Paul Kulchenko
74572a9765 Added disabling tooltip when context menu is shown. 2013-05-24 16:17:20 -07:00
Paul Kulchenko
b445ab7810 Fixed auto-complete error for '%dddd' strings (fixes #156). 2013-05-22 14:25:34 -07:00
Paul Kulchenko
52e9b1764b Added 'fixing' path returned by wxDirDialog; may be incorrect in 2.9.x. 2013-05-21 14:21:24 -07:00
Paul Kulchenko
bcabcc7ea6 Added constant initialization missing on ArchLinux with wxlua 2.8.12.2 (fixes #155; ref #128). 2013-05-20 18:29:25 -07:00
Paul Kulchenko
e0dcf5448a Removed sorting in the Stack view to keep the order of table elements. 2013-05-20 09:29:43 -07:00
Paul Kulchenko
f6877667bf Updated Stack view navigation to use clicked on instead of active item. 2013-05-20 08:17:05 -07:00
Paul Kulchenko
de491e1876 Fixed an issue with showing filenames that include '"?*:<>' on OSX/Linux. 2013-05-19 14:15:40 -07:00
Paul Kulchenko
103fdb553c Fixed current line marker being shown using 'Run as Scratchpad' with
'runonstart' option.
2013-05-18 22:15:45 -07:00
Paul Kulchenko
575107c2ae Updated build scripts to use luasocket 2.0.3. 2013-05-18 10:56:11 -07:00
Paul Kulchenko
7dc69a8959 Added support for table valuetypes in auto-complete for foo[index]: (ref #101). 2013-05-17 11:50:41 -07:00
Paul Kulchenko
3fce412df1 Added navigation to the line of code in the Stack Window (thanks to George Pimm; closes #134). 2013-05-15 11:40:57 -07:00
Paul Kulchenko
d6e1a2f8dd Fixed looping in auto-complete (fixes #151). 2013-05-14 11:30:03 -07:00
Paul Kulchenko
b21864a974 Added Show Location to the editor tab menu. 2013-05-13 13:59:18 -07:00
Paul Kulchenko
6108865ed2 Improved focus on the debugger when a breakpoint hits on OSX (fixes #141). 2013-05-13 13:56:24 -07:00
Paul Kulchenko
cb2cb9ff3c Fixed incorrect localization that led to an error in 'Save' from tab menu. 2013-05-13 13:52:52 -07:00
Paul Kulchenko
099f9f92fa Updated linux build files to use latest zlib/libpng to fix png load on Gentoo. 2013-05-12 21:20:08 -07:00
Paul Kulchenko
5449ed237a Updated 'Find in Files' to start in the project folder by default. 2013-05-11 14:22:23 -07:00
Paul Kulchenko
fae664ac0d Allowed closing editor tabs while debugger is running. 2013-05-10 14:13:50 -07:00
64 changed files with 7177 additions and 3633 deletions

View File

@@ -1,10 +1,201 @@
# ZeroBrane Studio Changelog
## v0.37 (May 09 2013)
## Current master (Aug 29 2013)
### Special thanks
- To Samuel Dionne-Riel for wxwidgets 2.8 compatibility updates.
- To Mat Hopwood for assistance with Marmalade Quick integration.
- To Chow CheeWen for Chinese translation.
- To [Riidom](https://github.com/Riidom) for German translation.
- To [ardente](https://github.com/ardente) for user home patch for Windows.
- To [Mika Attila](https://github.com/crumblingstatue) for code folding patch.
- To [Tim Mensch](https://github.com/TimMensch) for auto-save, auto-reload, and debugger improvements.
- To [Florian](https://github.com/SiENcE) for Notepad++ color scheme.
### Improvements
- Added package GetOutput method (ref #166).
- Added package onAppLoad/onAppClose events (ref #166).
- Added package onIdleOnce event (ref #166).
- Added manifest to the Windows executable and re-signed.
- Added Notepad++ color scheme (thanks to Florian/SiENcE; closes #193).
- Added clearing document styles after saving file with a different extension.
- Added workaround to avoid crash on OSX after `Close All Pages` (closes #190).
- Added return type for string.* functions to assist in auto-complete (ref #189).
- Added handling of string literals in type assignments (closes #189).
- Added support for captures in regexp replacement (\1-\9).
- Added ability to cancel FindInFiles search by closing search dialog (ref #162).
- Added activating Output window before showing search results (ref #162).
- Added support for packages from different platforms to co-exist (ref #166).
- Added ability to save complex data in package settings (ref #166).
- Added support for multiple inheritance in auto-complete (ref #101).
- Added ability to add/remove API descriptions from plugins (ref #166).
- Added package GetSettings/SetSettings methods (ref #166).
- Added methods to save/restore package settings (ref #166).
- Added ability to add/remove specs from plugins (ref #166).
- Added ability to add/remove interpreters from plugins (ref #166).
- Added wxlua patch for twoface compatibility.
- Added `setfenv` for Lua 5.2 compatibility.
- Added links to project page and documentation (closes #180).
- Added German translation (thanks to Riidom; ref #70).
- Added default value to package config (ref #176).
- Added handling of ?51.dll and required DLLs for LuaForWindows interpreter.
- Added plugin::GetConfig method (ref #166).
- Added erasing current line in Console (ref #173).
- Added search/completion in the local and remote console (closes #173).
- Added package onAppFocus* events (ref #166; ref #172).
- Added Chinese translation (thanks to Chow CheeWen; ref #70).
- Added `editor.autoreload` to enable reload of updated files (ref #172).
- Added creating (missing) folders when saving a file (fixes #171).
- Added an example of styling individual keywords.
- Added fold indication of a current block (ref #168).
- Added reporting of process id for a conflicting process.
- Changed `un/comment` to act from the beginning of the line for multi-line selection.
- Disabled markup styling for specs without comment styles.
- Disabled showing tooltip when auto-complete suggestions are shown.
- Disabled error reporting after debugging has been terminated.
- Disabled 'Fold' menu instead of removing when no folding is allowed (ref #169).
- Enabled support for xml/html folding.
- Enabled path remapping for local debugging.
- Enabled slower and more thorough static analysis (ref #149; ref #168).
- Improved logic to jump to file/line indicated in error messages.
- Limited activation of code fragments to the beginning of debugging session.
- Make code folding optional (thanks to [Mika Attila](https://github.com/crumblingstatue))
- Moved 'Sort' menu to 'Edit'.
- OpenGL 4.4 and ARB extensions added as well as NV_gpu_shader5 functions
- Optimized line count calculation for dynamic words when text is deleted.
- Optimized dynamic word processing for large files.
- Renamed package onEditorPostSave event to onEditorSave for consistency (ref #166).
- Removed comment from default spec as it forces undesired markup styling.
- Removed auto-complete suggestion when it is already typed (ref #101).
- Reorganized API processing to allow loading API description from a plugin.
- Replaced package onEditorActivated event with onEditorFocus* events (ref #166).
- Set search in subdirectories as default in Find in Files dialog (ref #162).
- Switched to using POSIX compatible regexp with '()' used for captures.
- Updated `NewFile` to accept a file name.
- Updated 'get hostname' logic to avoid using non-resolvable names (mostly on OSX).
- Updated tooltip to use the same type inference as auto-complete (ref #101).
- Updated Estrela reference in README.
- Updated build script on Windows to enable debugging (ref #164).
- Updated build script with a (temporary) fix for wxlua issue (mingw32).
- updated glewgl api for OpenGL4.4 and removed non-core duplicate functions/enums
- Updated static analyzer to report only first instance of 'unknown field'.
- Updated filename/source code heuristic in the debugger (Mobdebug 0.5362).
- Updated `SaveAll` to allow saving (only) files with filenames (ref #172).
- windows: adopt native user home (thanks to [ardente](https://github.com/ardente))
### Fixes
- Fixed loading of files with incorrect UTF-8 encoding and control characters (fixes #198).
- Fixed package sample to take into account new documents.
- Fixed crash on OSX after opening 'application' in 'Open File' dialog.
- Fixed windows resource file to properly reference the manifest.
- Fixed missing default api for files with unknown extensions.
- Fix spurious replacement after 'search, clear selection, replace' actions.
- Fixed using auto-complete with multiple selections (fixes #188).
- Fixed looping in auto-complete with array references (ref #143).
- Fixed showing auto-complete after comma.
- Fixed 'cannot get official hostname' message on low privilege accounts (fixes #183).
- Fixed displaying variable instances when code has invalid blocks (fixes #182).
- Fixed tooltip to ignore string parameters (ref #101).
- Fixed tooltip display between empty brackets (ref #101).
- Fixed indentation after lines with brackets in strings.
- Fixed indentation after lines with anonymous functions.
- Fixed indicator showing at the end of not terminated long comment.
- Fixed an issue with LUA_DEV including files instead of directories.
- Fixed project switching to close all files when switching to a subdirectory.
- Fixed saving projects that do not have any open files.
- Fixed debugger to accept filenames without '@'; thanks to Tim Mensch (closes #174).
- Fixed sorting when the sorted fragment ends with a newline.
## v0.38 (Jun 21 2013)
### Highlights
- Added source code debugging (to support LuaJava and other engines).
- Added scope-aware global/local/masked/masking variable highlighting.
- Added 'Go To Definition' and 'Rename All Instances'.
- Added package/plugin API.
- Added Retina display support (can be enabled with `hidpi` option).
- Improved auto-complete API with inheritance and table index support.
### Special thanks
- To George Pimm for line of code navigation in the Stack Window.
- To Fringale for updated French translation.
- To Tom Burgel for LuaForWindows interpreter.
### Improvements
- Added sorting of file lists on Linux (used in the filetree and file search).
- Added LuaForWindows interpreter (thanks to Tom Burgel).
- Added package onEditorCharAdded/onEditorKeyDown events (ref #166).
- Added support for changing the Corona simulator skin (closes #151).
- Added inheritance support for auto-complete API.
- Added package onEditor* events (closes #166).
- Added package onInterpreterLoad/onInterpreterClose events (ref #166).
- Added package onProjectLoad/onProjectClose events (ref #166).
- Added package onMenu* events (ref #166).
- Added package onRegister/onUnRegister events (ref #166).
- Added 'Show Location' to the Project/Filetree menu.
- Added `hidpi` option to enable HiDPI/Retina display support (closes #160).
- Added breakpoint support for unnamed code fragments.
- Added support for debugging (stepping through) unnamed code fragments.
- Added LuaSec to win32 build script.
- Added package/plugin processing.
- Added support for 'silent' execution of shell commands in markup.
- Added `Find Next/Previous` over selected variable instances (ref #163).
- Added `debugger.allowediting` option to allow editing while debugging.
- Added skiping binary files during file search (ref #162).
- Added yield to update search results during file search (ref #162).
- Added showing default extensions in the file search (ref #162).
- Added support for multiple file extensions in the file search (ref #162).
- Added saving folder to search files in (ref #162).
- Added selecting all instances with a double-click on a variable.
- Added `autoanalizer` option for dynamic static analysis.
- Added 'Go To Definition' and 'Rename All Instances'.
- Added initial support for indicating local/global variables.
- Added showing tooltip in any position over a term and showing 'values' (ref #101).
- Added disabling tooltip when context menu is shown.
- Added 'fixing' path returned by wxDirDialog; may be incorrect in 2.9.x.
- Added constant initialization missing on ArchLinux with wxlua 2.8.12.2 (fixes #155; ref #128).
- Added support for table valuetypes in auto-complete for `foo[index]:` (ref #101).
- Added navigation to the line of code in the Stack Window (thanks to George Pimm; closes #134).
- Added `Show Location` to the editor tab menu.
- Added support for absolute filenames in Markdown links.
- Allowed tab width and indentation to be set independently.
- Allowed closing editor tabs while debugger is running.
- Disabled following symlinks during directory scanning to avoid infinite loops.
- Disabled showing tooltip when the app is in the background (fixes #158).
- Disabled 'value' tooltip over variables that match known function names (ref #101).
- Improved error reporting in interpreters on failures to copy the debugger.
- Improved focus on the debugger when a breakpoint hits on OSX (fixes #141).
- Removed sorting in the Stack view to keep the order of table elements.
- Set default directory for Find in Files opened from a new file (#ref 162).
- Updated configuration example for variable indicators.
- Updated Stack view navigation to use clicked on instead of active item.
- Updated Gideros API/auto-complete reference.
- Updated markup to allow opening files from new buffers ('untitled').
- Updated build scripts to use luasocket 2.0.3.
- Updated linux build files to use latest zlib/libpng to fix png load on Gentoo.
- Updated 'Find in Files' to start in the project folder by default.
- Updated French translation with latest string changes (mostly for find/replace dialogs).
- Updated Marmalade Quick auto-complete API to use class inheritance.
- Updated Gideros auto-complete API to use class inheritance.
- Upgraded Mobdebug to 0.534 for debugging of source code fragments.
### Fixes
- Fixed looping in auto-complete when indexes are used (fixes #143).
- Fixed possible duplicate paths in the filetree.
- Fixed missing numerical keys in serialized tables (upgraded Mobdebug to 0.535).
- Fixed styling of markup that can be affected by folded lines.
- Fixed value selection with multiple active selections.
- Fixed style compatibility with wxwidgets 2.8 (ref #128).
- Fixed error reporting by (internal) file operations.
- Fixed styling comments that start with markup symbols.
- Fixed restoring a session with one of the files deleted on disk (fixes #161).
- Fixed reporting variable instances for comment/string fragments.
- Fixed 'Rename Instances' to always reset previous selection.
- Fixed auto-complete error for '%dddd' strings (fixes #156).
- Fixed an issue with showing filenames that include '"?*:<>' on OSX/Linux.
- Fixed current line marker being shown using 'Run as Scratchpad' with 'runonstart' option.
- Fixed looping in auto-complete (fixes #151).
- Fixed incorrect localization that led to an error in 'Save' from tab menu.
## v0.37 (May 09 2013)
### Highlights
- Added Marmalade Quick auto-complete support and API documentation.
@@ -13,6 +204,10 @@
- Added Recent File history navigation.
- Added Preferences menu to simplify access to system/user settings.
### Special thanks
- To Samuel Dionne-Riel for wxwidgets 2.8 compatibility updates.
- To Mat Hopwood for assistance with Marmalade Quick integration.
### Improvements
- Added Preferences menu to simplify access to system/user settings.
- Added Russian translation for Find/Replace dialog and (ref #70).

View File

@@ -20,6 +20,12 @@ MobileLua, GSL-shell, and others). It originated from the [Estrela Editor](http:
- config (cfg/): contains style and basic editor settings;
- tools (tools/): additional tools (e.g. DirectX/Cg shader compiler...).
## Documentation
* A [short and simple overview](http://studio.zerobrane.com/doc-getting-started.html) for those who are new to this development environment.
* A list of [frequently asked questions](http://studio.zerobrane.com/doc-faq.html) about the IDE.
* [Tutorials and demos](http://studio.zerobrane.com/tutorials.html) that cover debugging and live coding for different environments.
## Screenshot
![ZeroBrane Studio debugger screenshot](http://studio.zerobrane.com/images/debugging.png)
@@ -36,7 +42,7 @@ Overriding default configuration:
e.g.: zbstudio -cfg "editor.fontsize=12" somefile.lua
Loading custom configuration:
zbstudio -cfg config/file.lua [<filename>]
zbstudio -cfg path/file.lua [<filename>]
e.g.: zbstudio -cfg cfg/estrela.lua
```
@@ -52,12 +58,13 @@ Loading custom configuration:
## Where is Estrela?
The projects have been merged and zbstudio will lead the future.
Please reassociate files with zbstudio. To keep your history of files and
projects copy the contents of the `EstrelaEditor.ini` in your HOME directory
to `ZeroBraneStudio.ini`. If you have used Estrela for graphics shader
authoring or luxinia, create/modify the `cfg/user.lua` to include the content
of `cfg/estrela.lua` to load all tools and specifications by default again.
The projects have been merged and ZeroBrane Studio will lead the future.
Please reassociate files with ZeroBrane Studio. To keep your history of files
and projects copy the contents of the `EstrelaEditor.ini` in your HOME
directory to `ZeroBraneStudio.ini`. If you have used Estrela for graphics
shader authoring or luxinia, create/modify the `cfg/user.lua` to include the
content of `cfg/estrela.lua` to load all tools and specifications by default
again.
## License

View File

@@ -64,6 +64,11 @@ smoothstep = fn "clip and smooth blend [a,b]. - (vecN)(vecN a, b, x)",
floatBitsToInt = fn "returns the 32-bit integer representation of an IEEE 754 floating-point scalar or vector - (uintN/intN)(floatN)",
intBitsToFloat = fn "returns the float value corresponding to a given bit represention.of a scalar int value or vector of int values. - (floatN)(intN)",
uintBitsToFloat = fn "returns the float value corresponding to a given bit represention.of a scalar int value or vector of int values. - (floatN)(uintN)",
doubleBitsToInt64 = fn "returns the 64-bit integer representation of an IEEE 754 double precision floating-point scalar or vector - (int64N)(doubleN)",
doubleBitsToUint64 = fn "returns the 64-bit integer representation of an IEEE 754 double precision floating-point scalar or vector - (uint64N)(doubleN)",
int64BitsToDouble = fn "returns the double value corresponding to a given bit represention.of a scalar int value or vector of int values. - (doubleN)(uint64N)",
uint64BitsToDouble = fn "returns the double value corresponding to a given bit represention.of a scalar int value or vector of int values. - (doubleN)(uint64N)",
fma = fn "return a*b + c, treated as single operation when using precise - (vecN a, vecN b, vecN c)",
frexp = fn "splits scalars and vectors into normalized fraction [0.5,1.0) and a power of 2. - (vecN)(vecN x, out vecN e)",
ldexp = fn "build floating point number from x and the corresponding integral exponen of 2 in exp. - (vecN)(vecN x, exp)",
@@ -73,12 +78,19 @@ packUnorm4x8 = fn "Converts each comp. of v into 8-bit ints, packs results into
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)",
packInt2x32 = fn "Packs two 32 bit into one 64-bit value. - (int64_t)(ivec2)",
packUint2x32 = fn "Packs two 32 bit into one 64-bit value. - (uint64_t)(uvec2)",
packFloat2x16 = fn "returns an unsigned integer obtained by interpreting the components of a two-component 16-bit floating-point as integers and packing them into 32 bit. - (uint)(f16vec2 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)",
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)",
unpackInt2x32 = fn "Unpacks 64-bit into two 32-bit values. - (ivec2)(int64_t)",
unpackUint2x32 = fn "Unpacks 64-bit into two 32-bit values. - (uvec2)(uint64_t)",
unpackFloat2x16 = fn "returns a two-component vector with 16-bit floating-point components obtained by unpacking a 32-bit unsigned integer into a pair of 16-bit values. - (f16vec2)(uint)",
length = fn "return scalar Euclidean length of a vector. - (type)(vecN)",
distance = fn "return the Euclidean distance between two points. - (vecN)(vecN a, b)",
@@ -170,6 +182,10 @@ textureGather = fn "gather lookup (pixel quad of 4 single channel samples at onc
textureGatherOffset = fn "gather lookup (pixel quad of 4 single channel samples at once) with offset. Component 0: x, 1: y ... is ignored for shadow samplers instead reference value must be passed. Only 2D/Cube. Illegal for MS. - (vec4)(samplerN, vecN coord, [float shadowRefZ], intN offset / intN offset[4] , [int comp])",
texelFetch = fn "integer coordinate lookup for a single texel. No lod parameter for Buffer, MS, Rect. Illegal for Cube - (vec4)(samplerN, intN coord, [int lod/sample])",
texelFetchOffset = fn "integer coordinate lookup for a single texel with offset. No lod parameter for Buffer, MS, Rect. Illegal for Cube, Buffer, MS. - (vec4)(samplerN, intN coord, [int lod/sample], intN offset)",
anyInvocationARB = fn "returns true if and only if <value> is true for at least one active invocation in the group. - (bool)(bool value)",
allInvocationsARB = fn "returns true if and only if <value> is true for all active invocations in the group - (bool)(bool value)",
allInvocationsEqualARB = fn "returns true if <value> is the same for all active invocation in the group. - (bool)(bool value)",
}
local keyw =
@@ -178,6 +194,18 @@ local keyw =
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
float16_t f16vec2 f16vec3 f16vec4
float32_t f32vec2 f32vec3 f32vec4
float64_t f64vec2 f64vec3 f64vec4
int8_t i8vec2 i8vec3 i8vec4
int8_t i8vec2 i8vec3 i8vec4
int16_t i16vec2 i16vec3 i16vec4
int32_t i32vec2 i32vec3 i32vec4
int64_t i64vec2 i64vec3 i64vec4
uint8_t u8vec2 u8vec3 u8vec4
uint16_t u16vec2 u16vec3 u16vec4
uint32_t u32vec2 u32vec3 u32vec4
uint64_t u64vec2 u64vec3 u64vec4
struct typedef void
usampler1D usampler2D usampler3D usampler2DRect usamplerCube isampler1DArray usampler2DARRAY usamplerCubeArray usampler2DMS usampler2DMSArray
isampler1D isampler2D isampler3D isampler2DRect isamplerCube isampler1DArray isampler2DARRAY isamplerCubeArray isampler2DMS isampler2DMSArray
@@ -189,7 +217,7 @@ local keyw =
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
invocations offset align xfb_offset xfb_buffer
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
@@ -205,6 +233,7 @@ local keyw =
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
gl_BaseVertexARB gl_BaseInstanceARB gl_DrawIDARB
coherent volatile restrict readonly writeonly
image1D image2D image3D image2DRect imageCube imageBuffer image1DArray image2DArray imageCubeArray image2DMS image2DMSArray

View File

@@ -324,12 +324,14 @@ return {
description = "Receives zero or more integers. Returns a string with length equal to the number of arguments, in which each character has the internal numerical code equal to its corresponding argument.\n\nNumerical codes are not necessarily portable across platforms.",
args = "(...)",
returns = "(string)",
valuetype = "string",
},
dump = {
type = "function",
description = "Returns a string containing a binary representation of the given function, so that a later load on this string returns a copy of the function (but with new upvalues).",
args = "(function: function)",
returns = "(string)",
valuetype = "string",
},
find = {
type = "function",
@@ -342,6 +344,7 @@ return {
description = "Returns a formatted version of its variable number of arguments following the description given in its first argument (which must be a string).\n\nThe format string follows the same rules as the C function sprintf. The only differences are that the options/modifiers *, h, L, l, n, and p are not supported and that there is an extra option, q. The q option formats a string between double quotes, using escape sequences when necessary to ensure that it can safely be read back by the Lua interpreter.\n\nOptions A and a (when available) (VALUES ADDED IN Lua 5.2), E, e, f, G, and g all expect a number as argument. Options c, d, i, o, u, X, and x also expect a number, but the range of that number may be limited by the underlying C implementation. For options o, u, X, and x, the number cannot be negative. Option q expects a string; option s expects a string without embedded zeros. If the argument to option s is not a string, it is converted to one following the same rules of tostring (BEHAVIOR ADDED IN Lua 5.2).",
args = "(formatstring, ...)",
returns = "(string)",
valuetype = "string",
},
gmatch = {
type = "function",
@@ -354,6 +357,7 @@ return {
description = "Returns a copy of s in which all (or the first n, if given) occurrences of the pattern have been replaced by a replacement string specified by repl, which can be a string, a table, or a function.\n\ngsub also returns, as its second value, the total number of matches that occurred. The name gsub comes from Global SUBstitution.\n\nIf repl is a string, then its value is used for replacement. The character % works as an escape character: any sequence in repl of the form %d, with d between 1 and 9, stands for the value of the d-th captured substring. The sequence %0 stands for the whole match. The sequence %% stands for a single %.\n\nIf repl is a table, then the table is queried for every match, using the first capture as the key.\n\nIf repl is a function, then this function is called every time a match occurs, with all captured substrings passed as arguments, in order.\n\nIn any case, if the pattern specifies no captures, then it behaves as if the whole pattern was inside a capture.\n\nIf the value returned by the table query or by the function call is a string or a number, then it is used as the replacement string; otherwise, if it is false or nil, then there is no replacement (that is, the original match is kept in the string).",
args = "(s: string, pattern: string, repl: string|table|function [, n: number])",
returns = "(string, number)",
valuetype = "string",
},
len = {
type = "function",
@@ -366,36 +370,42 @@ return {
description = "Receives a string and returns a copy of this string with all uppercase letters changed to lowercase.\n\nAll other characters are left unchanged. The definition of what an uppercase letter is depends on the current locale.",
args = "(s: string)",
returns = "(string)",
valuetype = "string",
},
match = {
type = "function",
description = "Looks for the first match of pattern in the string s.\n\nIf it finds one, then match returns the captures from the pattern; otherwise it returns nil.\n\nIf pattern specifies no captures, then the whole match is returned. A third, optional numerical argument init specifies where to start the search; its default value is 1 and can be negative.",
args = "(s: string, pattern: string [, init: number])",
returns = "(string|nil [,...])",
valuetype = "string",
},
rep = {
type = "function",
description = "Returns a string that is the concatenation of n copies of the string s separated by the string sep.\n\nThe default value for sep is the empty string (that is, no separator). ARGUMENT ADDED IN Lua 5.2.",
args = "(s: string, n: number [, sep: string])",
returns = "(string)",
valuetype = "string",
},
reverse = {
type = "function",
description = "Returns a string that is the string s reversed.",
args = "(s: string)",
returns = "(string)",
valuetype = "string",
},
sub = {
type = "function",
description = "Returns the substring of s that starts at i and continues until j; i and j can be negative.\n\nIf j is absent, then it is assumed to be equal to -1 (which is the same as the string length). In particular, the call string.sub(s,1,j) returns a prefix of s with length j, and string.sub(s, -i) returns a suffix of s with length i.\n\nIf, after the translation of negative indices, i is less than 1, it is corrected to 1. If j is greater than the string length, it is corrected to that length. If, after these corrections, i is greater than j, the function returns the empty string.",
args = "(s: string, i: number [, j: number])",
returns = "(string)",
valuetype = "string",
},
upper = {
type = "function",
description = "Receives a string and returns a copy of this string with all lowercase letters changed to uppercase.\n\nAll other characters are left unchanged. The definition of what a lowercase letter is depends on the current locale.",
args = "(s: string)",
returns = "(string)",
valuetype = "string",
},
},
},
@@ -410,6 +420,7 @@ return {
description = "Given a list where all elements are strings or numbers, returns list[i]..sep..list[i+1] ··· sep..list[j].\n\nThe default value for sep is the empty string, the default for i is 1, and the default for j is #list. If i is greater than j, returns the empty string.",
args = "(list: table [, sep: string [, i: number [, j: number]]])",
returns = "(string)",
valuetype = "string",
},
insert = {
type = "function",

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
-- Copyright 2011-12 Paul Kulchenko, ZeroBrane LLC
-- Copyright 2013 Paul Kulchenko, ZeroBrane LLC
return {
ads = {
@@ -324,6 +324,7 @@ return {
description = "The radius of the circle.",
},
},
inherits = "vector",
},
color = {
type = "class",
@@ -786,6 +787,7 @@ return {
description = "The y coordinate (bottom) of the minimal bounding box around the rendered text.",
},
},
inherits = "node",
},
lines = {
type = "class",
@@ -797,6 +799,7 @@ return {
returns = "()",
},
},
inherits = "vector",
},
location = {
type = "class",
@@ -1227,6 +1230,7 @@ return {
returns = "()",
},
},
inherits = "node",
},
contact = {
type = "class",
@@ -1648,6 +1652,7 @@ return {
description = "The natural length of the joint, in display coordinates.",
},
},
inherits = "joint",
},
jointfriction = {
type = "class",
@@ -1661,6 +1666,7 @@ return {
description = "The maximum friction torque, in Newton-metres.\nJointWeld Properties\n========================\n* :c:member:`jointweld.frequency`\n* :c:member:`jointweld.dampingRatio`",
},
},
inherits = "joint",
},
jointgear = {
type = "class",
@@ -1678,6 +1684,7 @@ return {
description = "The gear ratio.",
},
},
inherits = "joint",
},
jointprismatic = {
type = "class",
@@ -1719,6 +1726,7 @@ return {
description = "The upper distance limit for the joint (should be positive). Only effective if limitEnabled is true.",
},
},
inherits = "joint",
},
jointpulley = {
type = "class",
@@ -1736,6 +1744,7 @@ return {
description = "The pulley ratio, used to simulate a block-and-tackle.",
},
},
inherits = "joint",
},
jointrevolute = {
type = "class",
@@ -1777,6 +1786,7 @@ return {
description = "The upper angle for the joint limit (degrees). Only effective if limitEnabled is true.",
},
},
inherits = "joint",
},
jointrope = {
type = "class",
@@ -1786,6 +1796,7 @@ return {
description = "The maximum length of the rope.\nJointWheel Properties\n========================\n* :c:member:`jointwheel.motorEnabled`\n* :c:member:`jointwheel.motorSpeed`\n* :c:member:`jointwheel.maxMotorTorque`\n* :c:member:`jointwheel.springFrequency`\n* :c:member:`jointwheel.springDampingRatio`\n* :c:member:`jointwheel.motorTorque`\n* :c:member:`jointwheel.jointSpeed`\n* :c:member:`jointwheel.jointTranslation`",
},
},
inherits = "joint",
},
jointtouch = {
type = "class",
@@ -1809,6 +1820,7 @@ return {
returns = "()",
},
},
inherits = "joint",
},
jointweld = {
type = "class",
@@ -1822,6 +1834,7 @@ return {
description = "The mass-spring-damper frequency in Hertz. Rotation only. Disable softness with a value of 0.",
},
},
inherits = "joint",
},
jointwheel = {
type = "class",
@@ -1859,6 +1872,7 @@ return {
description = "Suspension frequency, zero indicates no suspension. Default value is 2.",
},
},
inherits = "joint",
},
sprite = {
type = "class",
@@ -1918,6 +1932,7 @@ return {
description = "True only if the sprite should be flipped along its local y axis.",
},
},
inherits = "node",
},
system = {
type = "class",
@@ -2061,6 +2076,7 @@ return {
description = "The size of each tile, in pixels.\nThe value is a Vec2 object: the x property represents the tile\nwidth, and the y property represents the tile height.",
},
},
inherits = "node",
},
tiledmaplayer = {
type = "class",
@@ -2120,6 +2136,7 @@ return {
returns = "()",
},
},
inherits = "node",
},
tiledmapobject = {
type = "class",
@@ -2360,6 +2377,7 @@ return {
description = "The width, in display coordinates, of the shape outline.\nIf 0, no outline is drawn. The default value is 1.",
},
},
inherits = "node",
},
video = {
type = "class",

View File

@@ -13,7 +13,7 @@
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string></string>
<string>org.Lua.LuaInterpreter</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>

View File

@@ -24,9 +24,13 @@ BUILD_FLAGS="-O2 -shared -s -I $INSTALL_DIR/include -L $INSTALL_DIR/lib $FPIC"
WXWIDGETS_BASENAME="wxWidgets"
WXWIDGETS_URL="http://svn.wxwidgets.org/svn/wx/wxWidgets/trunk"
LIBPNG_BASENAME="libpng-1.6.0"
LIBPNG_BASENAME="libpng-1.6.2"
LIBPNG_FILENAME="$LIBPNG_BASENAME.tar.gz"
LIBPNG_URL="http://sourceforge.net/projects/libpng/files/libpng16/1.6.0/libpng-1.6.0.tar.gz/download"
LIBPNG_URL="http://sourceforge.net/projects/libpng/files/libpng16/1.6.2/libpng-1.6.2.tar.gz/download"
ZLIB_BASENAME="zlib-1.2.8"
ZLIB_FILENAME="$ZLIB_BASENAME.tar.gz"
ZLIB_URL="https://github.com/madler/zlib/archive/v1.2.8.tar.gz"
LUA_BASENAME="lua-5.1.5"
LUA_FILENAME="$LUA_BASENAME.tar.gz"
@@ -35,9 +39,9 @@ LUA_URL="http://www.lua.org/ftp/$LUA_FILENAME"
WXLUA_BASENAME="wxlua"
WXLUA_URL="https://wxlua.svn.sourceforge.net/svnroot/wxlua/trunk"
LUASOCKET_BASENAME="luasocket-2.0.2"
LUASOCKET_FILENAME="$LUASOCKET_BASENAME.tar.gz"
LUASOCKET_URL="http://files.luaforge.net/releases/luasocket/luasocket/luasocket-2.0.2/$LUASOCKET_FILENAME"
LUASOCKET_BASENAME="luasocket-2.0.3"
LUASOCKET_FILENAME="$LUASOCKET_BASENAME-rc2.zip"
LUASOCKET_URL="https://github.com/downloads/diegonehab/luasocket/$LUASOCKET_FILENAME"
# exit if the command line is empty
if [ $# -eq 0 ]; then
@@ -103,20 +107,30 @@ mkdir -p "$INSTALL_DIR" || { echo "Error: cannot create directory $INSTALL_DIR";
# build wxWidgets
if [ $BUILD_WXWIDGETS ]; then
# first build get/configure libpng as v1.6 is needed
wget -c "$LIBPNG_URL" -O "$LIBPNG_FILENAME" || { echo "Error: failed to download lbpng"; exit 1; }
wget -c "$LIBPNG_URL" -O "$LIBPNG_FILENAME" || { echo "Error: failed to download libpng"; exit 1; }
tar -xzf "$LIBPNG_FILENAME"
(cd "$LIBPNG_BASENAME"; ./configure --with-libpng-prefix=wxpng_; make $MAKEFLAGS)
wget -c "$ZLIB_URL" -O "$ZLIB_FILENAME" || { echo "Error: failed to download zlib"; exit 1; }
tar -xzf "$ZLIB_FILENAME"
(cd "$ZLIB_BASENAME"; ./configure; make $MAKEFLAGS)
svn co "$WXWIDGETS_URL" "$WXWIDGETS_BASENAME" || { echo "Error: failed to checkout wxWidgets"; exit 1; }
# replace src/png with the libpng folder
rm -rf "$WXWIDGETS_BASENAME/src/png"
mv "$LIBPNG_BASENAME" "$WXWIDGETS_BASENAME/src/png"
# replace src/zlib with the zlib folder
rm -rf "$WXWIDGETS_BASENAME/src/zlib"
mv "$ZLIB_BASENAME" "$WXWIDGETS_BASENAME/src/zlib"
cd "$WXWIDGETS_BASENAME"
./configure --prefix="$INSTALL_DIR" --disable-debug --disable-shared --enable-unicode \
--with-libjpeg=builtin --with-libpng=builtin --with-libtiff=no --with-expat=no \
--with-zlib=builtin --disable-richtext --with-gtk=2 \
CFLAGS="-Os -fPIC" CXXFLAGS="-Os -fPIC"
# update gzio to gzlib as this has changed between zlib 1.2.3 to 1.2.8
sed -i 's/gzio.c/gzlib.c/' Makefile
make $MAKEFLAGS || { echo "Error: failed to build wxWidgets"; exit 1; }
make install
cd ..
@@ -157,8 +171,8 @@ fi
# build LuaSocket
if [ $BUILD_LUASOCKET ]; then
wget -c "$LUASOCKET_URL" -O "$LUASOCKET_FILENAME" || { echo "Error: failed to download LuaSocket"; exit 1; }
tar -xzf "$LUASOCKET_FILENAME"
wget --no-check-certificate -c "$LUASOCKET_URL" -O "$LUASOCKET_FILENAME" || { echo "Error: failed to download LuaSocket"; exit 1; }
unzip "$LUASOCKET_FILENAME"
cd "$LUASOCKET_BASENAME"
mkdir -p "$INSTALL_DIR/lib/lua/5.1/"{mime,socket}
gcc $BUILD_FLAGS -o "$INSTALL_DIR/lib/lua/5.1/mime/core.so" src/mime.c -llua \

View File

@@ -29,9 +29,9 @@ LUA_URL="http://www.lua.org/ftp/$LUA_FILENAME"
WXLUA_BASENAME="wxlua"
WXLUA_URL="https://wxlua.svn.sourceforge.net/svnroot/wxlua/trunk"
LUASOCKET_BASENAME="luasocket-2.0.2"
LUASOCKET_FILENAME="$LUASOCKET_BASENAME.tar.gz"
LUASOCKET_URL="http://files.luaforge.net/releases/luasocket/luasocket/luasocket-2.0.2/$LUASOCKET_FILENAME"
LUASOCKET_BASENAME="luasocket-2.0.3"
LUASOCKET_FILENAME="$LUASOCKET_BASENAME-rc2.zip"
LUASOCKET_URL="https://github.com/downloads/diegonehab/luasocket/$LUASOCKET_FILENAME"
# exit if the command line is empty
if [ $# -eq 0 ]; then
@@ -151,8 +151,8 @@ fi
# build LuaSocket
if [ $BUILD_LUASOCKET ]; then
wget -c "$LUASOCKET_URL" -O "$LUASOCKET_FILENAME" || { echo "Error: failed to download LuaSocket"; exit 1; }
tar -xzf "$LUASOCKET_FILENAME"
wget --no-check-certificate -c "$LUASOCKET_URL" -O "$LUASOCKET_FILENAME" || { echo "Error: failed to download LuaSocket"; exit 1; }
unzip "$LUASOCKET_FILENAME"
cd "$LUASOCKET_BASENAME"
mkdir -p "$INSTALL_DIR/lib/lua/5.1/"{mime,socket}
gcc $BUILD_FLAGS -o "$INSTALL_DIR/lib/lua/5.1/mime/core.dylib" src/mime.c \

View File

@@ -23,9 +23,17 @@ LUA_URL="http://www.lua.org/ftp/$LUA_FILENAME"
WXLUA_BASENAME="wxlua"
WXLUA_URL="https://wxlua.svn.sourceforge.net/svnroot/wxlua/trunk"
LUASOCKET_BASENAME="luasocket-2.0.2"
LUASOCKET_FILENAME="$LUASOCKET_BASENAME.tar.gz"
LUASOCKET_URL="http://files.luaforge.net/releases/luasocket/luasocket/luasocket-2.0.2/$LUASOCKET_FILENAME"
LUASOCKET_BASENAME="luasocket-2.0.3"
LUASOCKET_FILENAME="$LUASOCKET_BASENAME-rc2.zip"
LUASOCKET_URL="https://github.com/downloads/diegonehab/luasocket/$LUASOCKET_FILENAME"
OPENSSL_BASENAME="openssl-1.0.1e"
OPENSSL_FILENAME="$OPENSSL_BASENAME.tar.gz"
OPENSSL_URL="http://www.openssl.org/source/$OPENSSL_FILENAME"
LUASEC_BASENAME="luasec-0.4.1"
LUASEC_FILENAME="$LUASEC_BASENAME.zip"
LUASEC_URL="https://github.com/brunoos/luasec/archive/$LUASEC_FILENAME"
WINAPI_BASENAME="winapi"
WINAPI_URL="https://github.com/stevedonovan/winapi.git"
@@ -36,6 +44,10 @@ if [ $# -eq 0 ]; then
exit 0
fi
WXLUASTRIP="/strip"
WXLUABUILD="MinSizeRel"
WXWIDGETSDEBUG="--disable-debug"
# iterate through the command line arguments
for ARG in "$@"; do
case $ARG in
@@ -51,12 +63,19 @@ for ARG in "$@"; do
luasocket)
BUILD_LUASOCKET=true
;;
luasec)
BUILD_LUASEC=true
;;
winapi)
BUILD_WINAPI=true
;;
zbstudio)
BUILD_ZBSTUDIO=true
;;
debug)
WXLUASTRIP=""
WXWIDGETSDEBUG="--enable-debug"
;;
all)
BUILD_WXWIDGETS=true
BUILD_LUA=true
@@ -110,7 +129,7 @@ if [ $BUILD_WXWIDGETS ]; then
svn co "$WXWIDGETS_URL" "$WXWIDGETS_BASENAME" || { echo "Error: failed to checkout wxWidgets"; exit 1; }
svn revert -R "$WXWIDGETS_BASENAME"
cd "$WXWIDGETS_BASENAME"
./configure --prefix="$INSTALL_DIR" --disable-debug --disable-shared --enable-unicode \
./configure --prefix="$INSTALL_DIR" $WXWIDGETSDEBUG --disable-shared --enable-unicode \
--with-libjpeg=builtin --with-libpng=builtin --with-libtiff=no --with-expat=no \
--with-zlib=builtin --disable-richtext \
CFLAGS="-Os -fno-keep-inline-dllexport" CXXFLAGS="-Os -fno-keep-inline-dllexport"
@@ -140,18 +159,26 @@ if [ $BUILD_WXLUA ]; then
cd "$WXLUA_BASENAME/wxLua"
sed -i 's|:-/\(.\)/|:-\1:/|' "$INSTALL_DIR/bin/wx-config"
sed -i 's/execute_process(COMMAND/& sh/' build/CMakewxAppLib.cmake modules/wxstedit/build/CMakewxAppLib.cmake
# the following patches wxlua source to fix live coding support in wxlua apps
# http://www.mail-archive.com/wxlua-users@lists.sourceforge.net/msg03225.html
sed -i 's/\(m_wxlState = wxLuaState(wxlState.GetLuaState(), wxLUASTATE_GETSTATE|wxLUASTATE_ROOTSTATE);\)/\/\/ removed by ZBS build process \/\/ \1/' modules/wxlua/wxlcallb.cpp
# remove check for Lua 5.2 as it doesn't work with Twoface ABI mapper
sed -i 's/LUA_VERSION_NUM < 502/0/' modules/wxlua/wxlcallb.cpp
# (temporary) fix for compilation issue in wxlua in Windows using mingw (r184)
sed -i 's/defined(__MINGW32__) || defined(__GNUWIN32__)/0/' modules/wxbind/src/wxcore_bind.cpp
cp "$INSTALL_DIR/lib/libwxscintilla-2.9.a" "$INSTALL_DIR/lib/libwx_mswu_scintilla-2.9.a"
echo "set_target_properties(wxLuaModule PROPERTIES LINK_FLAGS -static)" >> modules/luamodule/CMakeLists.txt
cmake -G "MSYS Makefiles" -DBUILD_INSTALL_PREFIX="$INSTALL_DIR" -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SHARED_LIBS=FALSE \
cmake -G "MSYS Makefiles" -DBUILD_INSTALL_PREFIX="$INSTALL_DIR" -DCMAKE_BUILD_TYPE=$WXLUABUILD -DBUILD_SHARED_LIBS=FALSE \
-DwxWidgets_CONFIG_EXECUTABLE="$INSTALL_DIR/bin/wx-config" \
-DwxWidgets_COMPONENTS="stc;html;aui;adv;core;net;base" \
-DwxLuaBind_COMPONENTS="stc;html;aui;adv;core;net;base" -DwxLua_LUA_LIBRARY_USE_BUILTIN=FALSE \
-DwxLua_LUA_INCLUDE_DIR="$INSTALL_DIR/include" -DwxLua_LUA_LIBRARY="$INSTALL_DIR/lib/lua51.dll" .
(cd modules/luamodule; make $MAKEFLAGS) || { echo "Error: failed to build wxLua"; exit 1; }
(cd modules/luamodule; make install/strip)
(cd modules/luamodule; make install$WXLUASTRIP)
[ -f "$INSTALL_DIR/bin/libwx.dll" ] || { echo "Error: libwx.dll isn't found"; exit 1; }
cd ../..
rm -rf "$WXLUA_BASENAME"
@@ -159,8 +186,8 @@ fi
# build LuaSocket
if [ $BUILD_LUASOCKET ]; then
wget -c "$LUASOCKET_URL" -O "$LUASOCKET_FILENAME" || { echo "Error: failed to download LuaSocket"; exit 1; }
tar -xzf "$LUASOCKET_FILENAME"
wget --no-check-certificate -c "$LUASOCKET_URL" -O "$LUASOCKET_FILENAME" || { echo "Error: failed to download LuaSocket"; exit 1; }
unzip "$LUASOCKET_FILENAME"
cd "$LUASOCKET_BASENAME"
mkdir -p "$INSTALL_DIR/lib/lua/5.1/"{mime,socket}
gcc $BUILD_FLAGS -o "$INSTALL_DIR/lib/lua/5.1/mime/core.dll" src/mime.c -llua51 \
@@ -177,6 +204,33 @@ if [ $BUILD_LUASOCKET ]; then
rm -rf "$LUASOCKET_FILENAME" "$LUASOCKET_BASENAME"
fi
# build LuaSec
if [ $BUILD_LUASEC ]; then
# build openSSL
wget --no-check-certificate -c "$OPENSSL_URL" -O "$OPENSSL_FILENAME" || { echo "Error: failed to download OpenSSL"; exit 1; }
tar -xzf "$OPENSSL_FILENAME"
cd "$OPENSSL_BASENAME"
bash Configure mingw
make
make install_sw INSTALLTOP="$INSTALL_DIR"
cd ..
rm -rf "$OPENSSL_FILENAME" "$OPENSSL_BASENAME"
# build LuaSec
wget --no-check-certificate -c "$LUASEC_URL" -O "$LUASEC_FILENAME" || { echo "Error: failed to download LuaSec"; exit 1; }
unzip "$LUASEC_FILENAME"
# the folder in the archive is "luasec-luasec-....", so need to fix
mv "luasec-$LUASEC_BASENAME" $LUASEC_BASENAME
cd "$LUASEC_BASENAME"
gcc $BUILD_FLAGS -o "$INSTALL_DIR/lib/lua/5.1/ssl.dll" \
src/{timeout.c,buffer.c,io.c,context.c,ssl.c,wsocket.c} -lssl -lcrypto -lws2_32 -lgdi32 -llua51 \
|| { echo "Error: failed to build LuaSec"; exit 1; }
cp src/{ssl.lua,https.lua} "$INSTALL_DIR/share/lua/5.1"
[ -f "$INSTALL_DIR/lib/lua/5.1/ssl.dll" ] || { echo "Error: luasec.dll isn't found"; exit 1; }
cd ..
rm -rf "$LUASEC_FILENAME" "$LUASEC_BASENAME"
fi
# build winapi
if [ $BUILD_WINAPI ]; then
git clone "$WINAPI_URL" "$WINAPI_BASENAME"
@@ -201,6 +255,7 @@ mkdir -p "$BIN_DIR" || { echo "Error: cannot create directory $BIN_DIR"; exit 1;
[ $BUILD_LUA ] && cp "$INSTALL_DIR/bin/lua.exe" "$INSTALL_DIR/lib/lua51.dll" "$BIN_DIR"
[ $BUILD_WXLUA ] && cp "$INSTALL_DIR/bin/libwx.dll" "$BIN_DIR/wx.dll"
[ $BUILD_WINAPI ] && cp "$INSTALL_DIR/lib/lua/5.1/winapi.dll" "$BIN_DIR"
[ $BUILD_LUASEC ] && cp "$INSTALL_DIR/lib/lua/5.1/ssl.dll" "$BIN_DIR"
if [ $BUILD_LUASOCKET ]; then
mkdir -p "$BIN_DIR/clibs/"{mime,socket}
cp "$INSTALL_DIR/lib/lua/5.1/mime/core.dll" "$BIN_DIR/clibs/mime"

231
cfg/i18n/cn.lua Normal file
View File

@@ -0,0 +1,231 @@
return {
["%d instance"] = "%d 个体", -- src\editor\findreplace.lua
["&About"] = "关于(&A)", -- src\editor\menu_help.lua
["&Add Watch"] = "添加监视(&A)", -- src\editor\debugger.lua
["&Break"] = "中断", -- src\editor\menu_project.lua
["&Close Page"] = "关闭页面", -- src\editor\menu_file.lua, src\editor\gui.lua
["&Compile"] = "编译", -- src\editor\menu_project.lua
["&Copy"] = "复制", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&Default Layout"] = "布局", -- src\editor\menu_view.lua
["&Delete Watch"] = "删除监视", -- src\editor\debugger.lua
["&Down"] = "往下", -- src\editor\findreplace.lua
["&Edit Watch"] = "编辑监视", -- src\editor\debugger.lua
["&Edit"] = "编辑", -- src\editor\menu_edit.lua
["&File"] = "文件", -- src\editor\menu_file.lua
["&Find All"] = "查找全部", -- src\editor\findreplace.lua
["&Find Next"] = "查找下一个", -- src\editor\findreplace.lua
["&Find"] = "查找", -- src\editor\menu_search.lua
["&Fold/Unfold All"] = "全 折叠/展开", -- src\editor\menu_edit.lua
["&Goto Line"] = "到...行", -- src\editor\menu_search.lua
["&Help"] = "帮助", -- src\editor\menu_help.lua
["&New"] = "新建", -- src\editor\menu_file.lua
["&Open..."] = "打开...", -- src\editor\menu_file.lua
["&Output/Console Window"] = "输出/主控台视窗", -- src\editor\menu_view.lua
["&Paste"] = "粘贴", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&Project"] = "项目", -- src\editor\menu_project.lua, src\editor\inspect.lua
["&Redo"] = "重做", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&Replace All"] = "全替换", -- src\editor\findreplace.lua
["&Replace"] = "替换", -- src\editor\findreplace.lua, src\editor\menu_search.lua
["&Run"] = "执行", -- src\editor\menu_project.lua
["&Save"] = "保存", -- src\editor\menu_file.lua, src\editor\gui.lua
["&Search"] = "搜索", -- src\editor\menu_search.lua
["&Sort"] = "分类", -- src\editor\menu_search.lua
["&Stack Window"] = "叠视窗/堆栈视窗", -- src\editor\menu_view.lua
["&Start Debugger Server"] = "开启除错器伺服机", -- src\editor\menu_project.lua
["&Subdirectories"] = "子文件夹", -- src\editor\findreplace.lua
["&Undo"] = "撤消", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&Up"] = "往上", -- src\editor\findreplace.lua
["&View"] = "视图", -- src\editor\menu_view.lua
["&Watch Window"] = "监视视窗", -- src\editor\menu_view.lua
["About %s"] = "关于 %s", -- src\editor\menu_help.lua
["Add Watch Expression"] = "添加监视表达式", -- src\editor\editor.lua
["Add to Scratchpad"] = "添加至暂存器", -- src\editor\editor.lua
["All files"] = "全部文件", -- src\editor\commands.lua
["Allow external process to start debugging"] = "允许外部进程开启除错", -- src\editor\menu_project.lua
["Analyze the source code"] = "分析源代码", -- src\editor\inspect.lua
["Analyze"] = "分析", -- src\editor\inspect.lua
["Auto Complete Identifiers"] = "自动补全标识符", -- src\editor\menu_edit.lua
["Auto complete while typing"] = "当输入时自动补全", -- src\editor\menu_edit.lua
["Break execution at the next executed line of code"] = "执行下一语句之后中断执行", -- src\editor\menu_project.lua, src\editor\gui.lua
["C&lear Output Window"] = "清除输出视窗", -- src\editor\menu_project.lua
["C&omment/Uncomment"] = "注释/消除注释", -- src\editor\menu_edit.lua
["Can't debug the script in the active editor window."] = "不能在现行编辑视窗对脚本进行除错", -- src\editor\debugger.lua
["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."] = "在当前项目中寻找不到文件 '%s' 以进行激活然后除错, 更新项目或是在编辑器里开启文件后再除错", -- src\editor\debugger.lua
["Can't process auto-recovery record; invalid format: %s."] = "不能处理自动恢复存档: %s", -- src\editor\commands.lua
["Can't run the entry point script ('%s')."] = "不能执行entry point脚本 ('%s')", -- src\editor\debugger.lua
["Can't start debugging session due to internal error '%s'."] = "除错动作失败 '%s'.", -- src\editor\debugger.lua
["Can't start debugging without an opened file or with the current file not being saved ('%s')."] = "不能启动除错,没有文档被开启或当前更改过的文档还没保存('%s')", -- src\editor\debugger.lua
["Cancel"] = "取消", -- src\editor\findreplace.lua
["Choose ..."] = "请选 ...", -- src\editor\menu_project.lua
["Choose a project directory"] = "选择项目文件夹", -- src\editor\findreplace.lua, src\editor\menu_project.lua
["Clear &Dynamic Words"] = "清除动态词汇", -- src\editor\menu_edit.lua
["Clear the output window before compiling or debugging"] = "编译或除错前清除输出视窗", -- src\editor\menu_project.lua
["Close &Other Pages"] = "关闭其他页面", -- src\editor\gui.lua
["Close A&ll Pages"] = "关闭全部页面", -- src\editor\gui.lua
["Close the current editor window"] = "关闭当前编译视窗", -- src\editor\menu_file.lua
["Co&ntinue"] = "继续", -- src\editor\menu_project.lua
["Col: %d"] = "列: %d", -- src\editor\editor.lua
["Comment or uncomment current or selected lines"] = "注释/消除注释 当前或被选的语句", -- src\editor\menu_edit.lua
["Compilation error"] = "编译错误", -- src\editor\debugger.lua, src\editor\commands.lua
["Compilation successful; %.0f%% success rate (%d/%d)."] = "编译成功; 成功率: %.0f%% (%d/%d).", -- src\editor\commands.lua
["Compile the current file"] = "编译当前的文档", -- src\editor\menu_project.lua
["Complete &Identifier"] = "补全标识符", -- src\editor\menu_edit.lua
["Complete the current identifier"] = "补全当前标识符", -- src\editor\menu_edit.lua
["Copy selected text to clipboard"] = "复制被选的text到clipboard", -- src\editor\menu_edit.lua
["Couldn't activate file '%s' for debugging; continuing without it."] = "不能激活 '%s' 以除错; 省略后继续进行", -- src\editor\debugger.lua
["Create an empty document"] = "新建空文档", -- src\editor\menu_file.lua, src\editor\gui.lua
["Cu&t"] = "剪切", -- src\editor\editor.lua, src\editor\menu_edit.lua
["Cut selected text to clipboard"] = "剪切被选的text到clipboard", -- src\editor\menu_edit.lua
["Debugger server started at %s:%d."] = "除错伺服器起始于 %s:%d.", -- src\editor\debugger.lua
["Debugging session completed (%s)."] = "除错会话完成 (%s)", -- src\editor\debugger.lua
["Debugging session started in '%s'."] = "除错会话于 '%s' 起始", -- src\editor\debugger.lua
["Debugging suspended at %s:%s (couldn't activate the file)."] = "除错挂起于 %s:%s (不能激活文档).", -- src\editor\debugger.lua
["Directory"] = "文件夹", -- src\editor\findreplace.lua
["Do you want to reload it?"] = "需要重新导入吗?", -- src\editor\editor.lua
["Do you want to save the changes to '%s'?"] = "需要把更改保存于 '%s'?", -- src\editor\commands.lua
["E&xit"] = "离开", -- src\editor\menu_file.lua
["Enter Lua code and press Enter to run it."] = "输入Lua代码然后按 <Enter> 以执行", -- src\editor\shellbox.lua
["Enter line number"] = "输入行号码", -- src\editor\menu_search.lua
["Error while loading API file: %s"] = "导入API档时出错误: %s", -- src\editor\autocomplete.lua
["Error while loading configuration file: %s"] = "导入configuration档时出错误: %s", -- src\editor\style.lua
["Error while processing API file: %s"] = "处理API档时出错误: %s", -- src\editor\autocomplete.lua
["Error while processing configuration file: %s"] = "处理configuration档时出错误: %s", -- src\editor\style.lua
["Error"] = "错误", -- src\editor\commands.lua
["Evaluate in Console"] = "在主控台中估值", -- src\editor\editor.lua
["Execute the current project/file and keep updating the code to see immediate results"] = "执行当前项目/文档和更新代码以便得到执行结果", -- src\editor\menu_project.lua
["Execute the current project/file"] = "执行当前项目/文档", -- src\editor\menu_project.lua
["Execution error"] = "执行出错误", -- src\editor\debugger.lua
["Exit program"] = "离开程式", -- src\editor\menu_file.lua
["Expr"] = "表达式", -- src\editor\debugger.lua
["Expression"] = "表达式", -- src\editor\debugger.lua
["File '%s' has been modified on disk."] = "磁碟上的文档 '%s' 已被更改", -- src\editor\editor.lua
["File '%s' has more recent timestamp than restored '%s'; please review before saving."] =
"文档 '%s' 的时间戳比 '%s' 更新近; 请检验后再保存", -- src\editor\commands.lua
["File '%s' no longer exists."] = "文档 '%s' 已不存在", -- src\editor\editor.lua, src\editor\menu_file.lua
["File Type"] = "文档类", -- src\editor\findreplace.lua
["File history"] = "文档历史", -- src\editor\menu_file.lua
["Find &In Files"] = "在文档中查找", -- src\editor\menu_search.lua
["Find &Next"] = "查找下一个", -- src\editor\menu_search.lua
["Find &Previous"] = "查找上一个", -- src\editor\menu_search.lua
["Find In Files"] = "在文档中查找", -- src\editor\findreplace.lua
["Find and replace text in files"] = "在文档中查找text然后更换", -- src\editor\menu_search.lua
["Find and replace text"] = "查找text然后更换", -- src\editor\menu_search.lua, src\editor\gui.lua
["Find text in files"] = "在文档中查找text", -- src\editor\menu_search.lua
["Find text"] = "查找text", -- src\editor\menu_search.lua, src\editor\gui.lua
["Find the earlier text occurence"] = "查找之前出现的text", -- src\editor\menu_search.lua
["Find the next text occurrence"] = "查找之後将出现的text", -- src\editor\menu_search.lua
["Find"] = "查找", -- src\editor\findreplace.lua
["Fold or unfold all code folds"] = "折叠/展开所有代码折叠", -- src\editor\menu_edit.lua
["Found auto-recovery record and restored saved session."] = "找到自动恢复存档和恢复已存对话", -- src\editor\commands.lua
["Found"] = "找到", -- src\editor\findreplace.lua
["Full &Screen"] = "全屏", -- src\editor\menu_view.lua
["Go to a selected line"] = "到所选的行", -- src\editor\menu_search.lua
["Goto Line"] = "到...行", -- src\editor\menu_search.lua
["INS"] = "INS", -- src\editor\editor.lua
["In Files"] = "在档案里", -- src\editor\findreplace.lua
["Jump to a function definition..."] = "跳到函数定义", -- src\editor\editor.lua
["Known Files"] = "所知的文档", -- src\editor\commands.lua
["Ln: %d"] = "行: %d", -- src\editor\editor.lua
["Local console"] = "本地主控台", -- src\editor\shellbox.lua, src\editor\gui.lua
["Lua &Interpreter"] = "Lua 解释器", -- src\editor\menu_project.lua
["Mapped remote request for '%s' to '%s'."] = "映射远程请求 '%s' 至 '%s'", -- src\editor\debugger.lua
["Match &case"] = "case匹配", -- src\editor\findreplace.lua
["Match &whole word"] = "全句匹配", -- src\editor\findreplace.lua
["Mixed end-of-line encodings detected."] = "发现混杂的EOL编码", -- src\editor\commands.lua
["OVR"] = "OVR", -- src\editor\editor.lua
["Open an existing document"] = "打开现存文档", -- src\editor\menu_file.lua, src\editor\gui.lua
["Open file"] = "打开文档", -- src\editor\commands.lua
["Options"] = "选项", -- src\editor\findreplace.lua
["Output (running)"] = "输出 (进行中)", -- src\editor\output.lua
["Output"] = "输出", -- src\editor\output.lua, src\editor\settings.lua, src\editor\gui.lua
["Paste text from the clipboard"] = "从clipboard粘贴text", -- src\editor\menu_edit.lua
["Preferences"] = "首选项", -- src\editor\menu_edit.lua
["Prepend '=' to show complex values on multiple lines."] = "在多行展现复杂值请前置 '='", -- src\editor\shellbox.lua
["Press cancel to abort."] = "按 <cancel> 以退出", -- src\editor\commands.lua
["Program '%s' started in '%s' (pid: %d)."] = "程式 '%s' 执行于 '%s' (pid: %d).", -- src\editor\output.lua
["Program can't start because conflicting process is running as '%s'."] = "程序不能启动因为有名为 '%s' 的冲突进程", -- src\editor\output.lua
["Program completed in %.2f seconds (pid: %d)."] = "程序于 %.2f 秒完成 (pid: %d).", -- src\editor\output.lua
["Program starting as '%s'."] = "程式以 '%s' 执行", -- src\editor\output.lua
["Program stopped (pid: %d)."] = "程式停止 (pid: %d).", -- src\editor\debugger.lua
["Program unable to run as '%s'."] = "程式不能以 '%s' 执行", -- src\editor\output.lua
["Project Directory"] = "项目文件夹", -- src\editor\menu_project.lua
["Project"] = "项目", -- src\editor\settings.lua, src\editor\gui.lua
["Project/&FileTree Window"] = "项目/文档树 视窗", -- src\editor\menu_view.lua
["R/O"] = "唯读", -- src\editor\editor.lua
["R/W"] = "读写", -- src\editor\editor.lua
["Re&place In Files"] = "在文档中替换", -- src\editor\menu_search.lua
["Recent Files"] = "最近的文档", -- src\editor\menu_file.lua
["Redo last edit undone"] = "重做最后被取消的编辑", -- src\editor\menu_edit.lua
["Refused a request to start a new debugging session as there is one in progress already."] = "因为有另一个除错在进行,拒绝开启新的除错对话", -- src\editor\debugger.lua
["Regular &expression"] = "正则表达式", -- src\editor\findreplace.lua
["Remote console"] = "远程主控台", -- src\editor\shellbox.lua
["Replace &All"] = "更换全部", -- src\editor\findreplace.lua
["Replace"] = "更换", -- src\editor\findreplace.lua
["Replaced an invalid UTF8 character with %s."] = "以%s更换无效的UTF8字元", -- src\editor\commands.lua
["Replaced"] = "更换", -- src\editor\findreplace.lua
["Replacing"] = "更换中", -- src\editor\findreplace.lua
["Reset to default layout"] = "重置缺省布局", -- src\editor\menu_view.lua
["Resets the dynamic word list for autocompletion"] = "为自动补全重置动态word list", -- src\editor\menu_edit.lua
["Run as Scratchpad"] = "以Scratchpad执行", -- src\editor\menu_project.lua
["S&top Debugging"] = "停止除错", -- src\editor\menu_project.lua
["S&top Process"] = "停止进程", -- src\editor\menu_project.lua
["Save &As..."] = "另存为...", -- src\editor\menu_file.lua, src\editor\gui.lua
["Save A&ll"] = "全部存档", -- src\editor\menu_file.lua
["Save Changes?"] = "存档更新?", -- src\editor\commands.lua
["Save all open documents"] = "保存所有开启的文档", -- src\editor\menu_file.lua, src\editor\gui.lua
["Save file as"] = "文档另存为", -- src\editor\commands.lua
["Save file?"] = "保存文档?", -- src\editor\commands.lua
["Save the current document to a file with a new name"] = "用新档案名称保存当前文档", -- src\editor\menu_file.lua
["Save the current document"] = "保存当前文档", -- src\editor\menu_file.lua, src\editor\gui.lua
["Saved auto-recover at %s."] = "在 %s 存档自动恢复", -- src\editor\commands.lua
["Scope"] = "范围", -- src\editor\findreplace.lua
["Scratchpad error"] = "暂存器错误", -- src\editor\debugger.lua
["Searching for"] = "搜索", -- src\editor\findreplace.lua
["Select &All"] = "选全部", -- src\editor\editor.lua, src\editor\menu_edit.lua
["Select all text in the editor"] = "选编辑器内的所有text", -- src\editor\menu_edit.lua
["Set From Current File"] = "从当前文档设置", -- src\editor\menu_project.lua
["Set project directory from current file"] = "从当前文档设置项目文件夹", -- src\editor\menu_project.lua, src\editor\gui.lua
["Set the interpreter to be used"] = "设置解释器", -- src\editor\menu_project.lua
["Set the project directory to be used"] = "设置项目文件夹", -- src\editor\menu_project.lua
["Settings: System"] = "设置: 系统", -- src\editor\menu_edit.lua
["Settings: User"] = "设置: 用户", -- src\editor\menu_edit.lua
["Show &Tooltip"] = "展现tooltip", -- src\editor\menu_edit.lua
["Show tooltip for current position; place cursor after opening bracket of function"] = "在当前的位置展现tooltip; 把游标放置于函数的开括号之后", -- src\editor\menu_edit.lua
["Sort selected lines"] = "对被选的行进行排列", -- src\editor\menu_search.lua
["Stack"] = "堆栈", -- src\editor\debugger.lua
["Start &Debugging"] = "开始除错", -- src\editor\menu_project.lua
["Start debugging"] = "开始除错", -- src\editor\menu_project.lua, src\editor\gui.lua
["Step &Into"] = "除错运行 进入子程序/函数", -- src\editor\menu_project.lua
["Step &Over"] = "除错运行 掠过子程序/函数", -- src\editor\menu_project.lua
["Step O&ut"] = "除错运行 离开子程序/函数", -- src\editor\menu_project.lua
["Step into"] = "除错运行 进入子程序/函数", -- src\editor\menu_project.lua, src\editor\gui.lua
["Step out of the current function"] = "除错运行 离开当前的函数", -- src\editor\menu_project.lua, src\editor\gui.lua
["Step over"] = "除错运行 掠过子程序/函数", -- src\editor\menu_project.lua, src\editor\gui.lua
["Stop the currently running process"] = "终止目前进行着的进程", -- src\editor\menu_project.lua, src\editor\gui.lua
["Switch to or from full screen mode"] = "切换全屏模式", -- src\editor\menu_view.lua
["Text not found."] = "寻找不到text", -- src\editor\findreplace.lua
["The API file must be located in a subdirectory of the API directory."] = "API file必须存放在API文件夹中的子文件夹", -- src\editor\autocomplete.lua
["Toggle Break&point"] = "切换中断点", -- src\editor\menu_project.lua
["Toggle breakpoint"] = "切换中断点", -- src\editor\menu_project.lua, src\editor\gui.lua
["Tr&ace"] = "追踪", -- src\editor\menu_project.lua
["Trace execution showing each executed line"] = "执行追踪展示每一执行过的语句", -- src\editor\menu_project.lua
["Unable to load file '%s'."] = "导出文件失败 '%s'.", -- src\editor\commands.lua
["Unable to save file '%s': %s"] = "保存文件失败 '%s': %s", -- src\editor\commands.lua
["Unable to stop program (pid: %d), code %d."] = "停止程序失败 (pid: %d), 代码 %d.", -- src\editor\debugger.lua
["Undo last edit"] = "清除前编辑动作", -- src\editor\menu_edit.lua
["Use '%s' to see full description."] = "用 '%s' 来看全解析", -- src\editor\editor.lua
["Use '%s' to show line endings and '%s' to convert them."] = "用 '%s' 来显示语句的终结和 '%s' 来进行转换", -- src\editor\commands.lua
["Use 'clear' to clear the shell output and the history."] = "用 'clear' 来清除shell的输出和历史", -- src\editor\shellbox.lua
["Use Shift-Enter for multiline code."] = "用 <Shift-Enter> 来处理多行代码", -- src\editor\shellbox.lua
["Value"] = "数值", -- src\editor\debugger.lua
["View the output/console window"] = "查看输出/主控台视窗", -- src\editor\menu_view.lua
["View the project/filetree window"] = "查看项目/文件树视窗", -- src\editor\menu_view.lua
["View the stack window"] = "查看堆栈视窗", -- src\editor\menu_view.lua, src\editor\gui.lua
["View the watch window"] = "查看监视视窗", -- src\editor\menu_view.lua, src\editor\gui.lua
["Watch"] = "监视", -- src\editor\debugger.lua
["Welcome to the interactive Lua interpreter."] = "欢迎来到互动 Lua interpreter.", -- src\editor\shellbox.lua
["Wrap ar&ound"] = "卷绕", -- src\editor\findreplace.lua
["You must save the program first."] = "必须先保存程序", -- src\editor\commands.lua
["on line %d"] = "在 %d 行", -- src\editor\debugger.lua, src\editor\commands.lua
["traced %d instruction"] = "追踪 %d 指令", -- src\editor\debugger.lua
}

236
cfg/i18n/de.lua Normal file
View File

@@ -0,0 +1,236 @@
return {
[0] = function(c) return c == 1 and 1 or 2 end, -- plural
["%d instance"] = {"%d Instanz", "%d Instanzen"}, -- src\editor\findreplace.lua
["%s event failed: %s"] = "Ereignis fehlgeschlagen : %s", -- src\editor\package.lua
["&About"] = "&Über", -- src\editor\menu_help.lua
["&Add Watch"] = "&Beobachtungspunkt hinzufügen", -- src\editor\debugger.lua
["&Break"] = "&Unterbrechung", -- src\editor\menu_project.lua
["&Close Page"] = "S&eite schließen", -- src\editor\menu_file.lua, src\editor\gui.lua
["&Compile"] = "&Compiler", -- src\editor\menu_project.lua
["&Copy"] = "&Kopieren", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&Default Layout"] = "Standard-&Layout", -- src\editor\menu_view.lua
["&Delete Watch"] = "&Beobachtungspunkt entfernen", -- src\editor\debugger.lua
["&Down"] = "&Runter", -- src\editor\findreplace.lua
["&Edit Watch"] = "&Beobachtungspunkt bearbeiten", -- src\editor\debugger.lua
["&Edit"] = "&Bearbeiten", -- src\editor\menu_edit.lua
["&File"] = "&Datei", -- src\editor\menu_file.lua
["&Find All"] = "&Alle finden", -- src\editor\findreplace.lua
["&Find Next"] = "&Nächsten finden", -- src\editor\findreplace.lua
["&Find"] = "&Finden", -- src\editor\menu_search.lua
["&Fold/Unfold All"] = "A&lles ein-/ausklappen", -- src\editor\menu_edit.lua
["&Goto Line"] = "&Gehe zu Zeile", -- src\editor\menu_search.lua
["&Help"] = "&Hilfe", -- src\editor\menu_help.lua
["&New"] = "&Neu", -- src\editor\menu_file.lua
["&Open..."] = "&Öffnen...", -- src\editor\menu_file.lua
["&Output/Console Window"] = "&Ausgabefenster/Konsole", -- src\editor\menu_view.lua
["&Paste"] = "&Einfügen", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&Project"] = "&Projekt", -- src\editor\menu_project.lua, src\editor\inspect.lua
["&Redo"] = "&Wiederholen", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&Replace All"] = "&Alles ersetzen", -- src\editor\findreplace.lua
["&Replace"] = "&Ersetzen", -- src\editor\findreplace.lua, src\editor\menu_search.lua
["&Run"] = "&Starten", -- src\editor\menu_project.lua
["&Save"] = "&Speichern", -- src\editor\menu_file.lua, src\editor\gui.lua
["&Search"] = "&Suchen", -- src\editor\menu_search.lua
["&Sort"] = "&Sortieren", -- src\editor\menu_search.lua
["&Stack Window"] = "&Stapel/Stack", -- src\editor\menu_view.lua
["&Start Debugger Server"] = "De&bugserver starten", -- src\editor\menu_project.lua
["&Subdirectories"] = "&Unterverzeichnisse", -- src\editor\findreplace.lua
["&Undo"] = "&Rückgängig", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&Up"] = "&Hoch", -- src\editor\findreplace.lua
["&View"] = "&Ansicht", -- src\editor\menu_view.lua
["&Watch Window"] = "&Beobachtungspunkte", -- src\editor\menu_view.lua
[".&bak on Replace"] = ".&bak bei Ersetzen", -- src\editor\findreplace.lua
["About %s"] = "Über %s", -- src\editor\menu_help.lua
["Add Watch Expression"] = "Beobachtungspunkt hinzufügen", -- src\editor\editor.lua
["Add To Scratchpad"] = "Zu Entwurf hinzufügen", -- src\editor\editor.lua
["All files"] = "Alle Dateien", -- src\editor\commands.lua
["Allow external process to start debugging"] = "Externem Prozeß erlauben, den Debugger zu starten", -- src\editor\menu_project.lua
["Analyze the source code"] = "Quellcode analysieren", -- src\editor\inspect.lua
["Analyze"] = "&Analyseroutine", -- src\editor\inspect.lua
["Auto Complete Identifiers"] = "Auto-Vervollständigen von Bezeichnern", -- src\editor\menu_edit.lua
["Auto complete while typing"] = "Auto-Vervollständigen beim Tippen", -- src\editor\menu_edit.lua
["Break execution at the next executed line of code"] = "Programmausführung bei der nächsten ausgeführten Zeile stoppen", -- src\editor\menu_project.lua, src\editor\gui.lua
["C&lear Output Window"] = "Ausgabefenster &löschen", -- src\editor\menu_project.lua
["C&omment/Uncomment"] = "(Aus-)/&Kommentieren", -- src\editor\menu_edit.lua
["Can't debug the script in the active editor window."] = "Script kann im aktiven Editorfenster nicht gedebuggt werden.", -- src\editor\debugger.lua
["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."] = "Kann Datei '%s' zwecks Debugging im aktuellen Projekt nicht finden. Bitte Projekt aktualisieren oder Datei in den Editor laden.", -- src\editor\debugger.lua
["Can't process auto-recovery record; invalid format: %s."] = "Auto-Wiederherstellen nicht möglich; ungültiges Format: %s.", -- src\editor\commands.lua
["Can't run the entry point script ('%s')."] = "Kann Script für Einsprungspunkt ('%s') nicht ausführen.", -- src\editor\debugger.lua
["Can't start debugging session due to internal error '%s'."] = "Debugging kann nicht gestartet werden wegen internem Fehler '%s'.", -- src\editor\debugger.lua
["Can't start debugging without an opened file or with the current file not being saved ('%s')."] = "Debugging kann nicht gestartet werden ohne geöffnete Datei oder wenn die aktuelle Datei nicht gespeichert ist ('%s').", -- src\editor\debugger.lua
["Cancel"] = "Abbrechen", -- src\editor\findreplace.lua
["Choose ..."] = "Wählen...", -- src\editor\menu_project.lua
["Choose a project directory"] = "Projektverzeichnis auswählen", -- src\editor\findreplace.lua, src\editor\menu_project.lua
["Clear &Dynamic Words"] = "&Dynamic Words löschen", -- src\editor\menu_edit.lua
["Clear the output window before compiling or debugging"] = "Vor Kompilieren oder Debuggen das Ausgabefenster löschen", -- src\editor\menu_project.lua
["Close &Other Pages"] = "A&ndere Seiten schließen", -- src\editor\gui.lua
["Close A&ll Pages"] = "&Alle Seiten schließen", -- src\editor\gui.lua
["Close the current editor window"] = "Aktuelles Editorfenster schließen", -- src\editor\menu_file.lua
["Co&ntinue"] = "&Fortsetzen", -- src\editor\menu_project.lua
["Col: %d"] = "Spalte: %d", -- src\editor\editor.lua
["Comment or uncomment current or selected lines"] = "Ausgewählte bzw. aktive Zeile (un-)kommentieren", -- src\editor\menu_edit.lua
["Compilation error"] = "Fehler beim Kompilieren", -- src\editor\debugger.lua, src\editor\commands.lua
["Compilation successful; %.0f%% success rate (%d/%d)."] = "Kompilieren erfolgreich; Erfolgsquote von %.0f%% (%d/%d).", -- src\editor\commands.lua
["Compile the current file"] = "Aktuelle Datei kompilieren", -- src\editor\menu_project.lua
["Complete &Identifier"] = "&Bezeichner vervollständigen", -- src\editor\menu_edit.lua
["Complete the current identifier"] = " Aktuellen Bezeichner vervollständigen", -- src\editor\menu_edit.lua
["Copy selected text to clipboard"] = "Text in Zwischenablage kopieren", -- src\editor\menu_edit.lua
["Couldn't activate file '%s' for debugging; continuing without it."] = "Konnte Datei '%s' zwecks nicht Debugging aktivieren; fahre ohne die Datei fort.", -- src\editor\debugger.lua
["Create an empty document"] = "Leeres Dokument anlegen", -- src\editor\menu_file.lua, src\editor\gui.lua
["Cu&t"] = "A&usschneiden", -- src\editor\editor.lua, src\editor\menu_edit.lua
["Cut selected text to clipboard"] = "Schneide ausgewählten Text in die Zwischenablage hinein", -- src\editor\menu_edit.lua
["Debugger server started at %s:%d."] = "Debugserver gestartet an %s:%d.", -- src\editor\debugger.lua
["Debugging session completed (%s)."] = "Debugging Session beendet (%s).", -- src\editor\debugger.lua
["Debugging session started in '%s'."] = "Debugging Session gestartet '%s'.", -- src\editor\debugger.lua
["Debugging suspended at %s:%s (couldn't activate the file)."] = "Debugging angehalten bei %s:%s (konnte Datei nicht aktivieren).", -- src\editor\debugger.lua
["Directory"] = "Verzeichnis", -- src\editor\findreplace.lua
["Do you want to reload it?"] = "Neu laden?", -- src\editor\editor.lua
["Do you want to save the changes to '%s'?"] = "Änderungen an '%s' speichern?", -- src\editor\commands.lua
["E&xit"] = "&Beenden", -- src\editor\menu_file.lua
["Enter Lua code and press Enter to run it."] = "Lua-Code eingeben und Enter drücken zum Ausführen.", -- src\editor\shellbox.lua
["Enter line number"] = "Zeilennummer eingeben", -- src\editor\menu_search.lua
["Error while loading API file: %s"] = "Fehler beim Laden von API-Datei: %s", -- src\editor\autocomplete.lua
["Error while loading configuration file: %s"] = "Fehler beim Laden von Konfigurationsdatei: %s", -- src\editor\style.lua
["Error while processing API file: %s"] = "Fehler beim Lesen von API-Datei: %s", -- src\editor\autocomplete.lua
["Error while processing configuration file: %s"] = "Fehler beim Lesen von Konfiguratonsdatei: %s", -- src\editor\style.lua
["Error"] = "Fehler", -- src\editor\commands.lua
["Evaluate In Console"] = "In Konsole auswerten", -- src\editor\editor.lua
["Execute the current project/file and keep updating the code to see immediate results"] = "Aktuelles Projekt/ aktuelle Datei ausführen und Quellcode ändern, um Ergebnisse in Echtzeit zu sehen", -- src\editor\menu_project.lua
["Execute the current project/file"] = "Aktuelles Projekt/ aktuelle Datei ausführen", -- src\editor\menu_project.lua
["Execution error"] = "Fehler bei Ausführung", -- src\editor\debugger.lua
["Exit program"] = "Programm beenden", -- src\editor\menu_file.lua
["Expr"] = "Ausdr.", -- src\editor\debugger.lua
["Expression"] = "Ausdruck", -- src\editor\debugger.lua
["File '%s' has been modified on disk."] = "Datei '%s' wurde auf der Festplatte geändert.", -- src\editor\editor.lua
["File '%s' has more recent timestamp than restored '%s'; please review before saving."] = "Datei '%s' hat neueren Zeitstempel als wiederhergestellte Datei '%s'; bitte vor dem Speichern kontrollieren.", -- src\editor\commands.lua
["File '%s' no longer exists."] = "Datei '%s' existiert nicht mehr.", -- src\editor\editor.lua, src\editor\menu_file.lua
["File Type"] = "Dateityp", -- src\editor\findreplace.lua
["File history"] = "Dateiverlauf", -- src\editor\menu_file.lua
["Find &In Files"] = "Finde &in Dateien", -- src\editor\menu_search.lua
["Find &Next"] = "Finde &Nächste", -- src\editor\menu_search.lua
["Find &Previous"] = "Finde &Vorherige", -- src\editor\menu_search.lua
["Find In Files"] = "Finde in Dateien", -- src\editor\findreplace.lua
["Find and replace text in files"] = "Finde und ersetze Text in Dateien", -- src\editor\menu_search.lua
["Find and replace text"] = "Finde und ersetze Text", -- src\editor\menu_search.lua, src\editor\gui.lua
["Find text in files"] = "Finde Text in Dateien", -- src\editor\menu_search.lua
["Find text"] = "Finde Text", -- src\editor\menu_search.lua, src\editor\gui.lua
["Find the earlier text occurence"] = "Finde vorheriges Auftreten des Textes", -- src\editor\menu_search.lua
["Find the next text occurrence"] = "Finde nächstes Auftreten des Textes", -- src\editor\menu_search.lua
["Find"] = "Finden", -- src\editor\findreplace.lua
["Fold or unfold all code folds"] = "Alle Stellen im Code ein-/ausklappen ", -- src\editor\menu_edit.lua
["Found auto-recovery record and restored saved session."] = "Autowiederherstellen-Aufzeichnung gefunden und vorherige Sitzung wiederhergestellt.", -- src\editor\commands.lua
["Found"] = "Gefunden", -- src\editor\findreplace.lua
["Full &Screen"] = "&Vollbild", -- src\editor\menu_view.lua
["Go To Definition"] = "Gehe zu Definition", -- src\editor\editor.lua
["Go to a selected line"] = "Gehe zu ausgewählter Zeile", -- src\editor\menu_search.lua
["Goto Line"] = "Gehe zu Zeile", -- src\editor\menu_search.lua
["INS"] = "INS", -- src\editor\editor.lua
["In Files"] = "In Dateien", -- src\editor\findreplace.lua
["Jump to a function definition..."] = "Springe zu Funktions-Definition...", -- src\editor\editor.lua
["Known Files"] = "Bekannte Dateien", -- src\editor\commands.lua
["Ln: %d"] = "Zeile: %d", -- src\editor\editor.lua
["Local console"] = "Lokale Konsole", -- src\editor\shellbox.lua, src\editor\gui.lua
["Lua &Interpreter"] = "&Lua Interpreter", -- src\editor\menu_project.lua
["Mapped remote request for '%s' to '%s'."] = "Mapped remote request for '%s' to '%s'.", -- src\editor\debugger.lua
["Match &case"] = "&Groß-/Kleinschreibung", -- src\editor\findreplace.lua
["Match &whole word"] = "Ganzes &Wort", -- src\editor\findreplace.lua
["Mixed end-of-line encodings detected."] = "Gemischte End-of-Line Kodierung entdeckt.", -- src\editor\commands.lua
["OVR"] = "OVR", -- src\editor\editor.lua
["Open an existing document"] = "Öffne existierendes Dokument", -- src\editor\menu_file.lua, src\editor\gui.lua
["Open file"] = "Öffne Datei", -- src\editor\commands.lua
["Options"] = "Optionen", -- src\editor\findreplace.lua
["Output (running)"] = "Ausgabe (ausgeführt)", -- src\editor\output.lua
["Output"] = "Ausgabe", -- src\editor\output.lua, src\editor\settings.lua, src\editor\gui.lua
["Paste text from the clipboard"] = "Text aus Zwischenablage einfügen", -- src\editor\menu_edit.lua
["Preferences"] = "Einstellungen", -- src\editor\menu_edit.lua
["Prepend '=' to show complex values on multiple lines."] = "'=' voranstellen, um komplexe Ausdrücke auf mehrere Zeilen zu verteilen.", -- src\editor\shellbox.lua
["Press cancel to abort."] = "Abbrechen Drücken zum Beenden.", -- src\editor\commands.lua
["Program '%s' started in '%s' (pid: %d)."] = "Programm '%s' gestartet in '%s' (pid : %d).", -- src\editor\output.lua
["Program can't start because conflicting process is running as '%s'."] = "Programm kann nicht starten, da blockierender Prozeß als '%s' läuft.", -- src\editor\output.lua
["Program completed in %.2f seconds (pid: %d)."] = "Programm beendet nach %.2f Sekunden (pid : %d).", -- src\editor\output.lua
["Program starting as '%s'."] = "Programm gestartet als '%s'.", -- src\editor\output.lua
["Program stopped (pid: %d)."] = "Programm gestoppt (pid: %d).", -- src\editor\debugger.lua
["Program unable to run as '%s'."] = "Programm kann nicht als '%s' laufen.", -- src\editor\output.lua
["Project Directory"] = "&Projektverzeichnis", -- src\editor\menu_project.lua
["Project"] = "Projekt", -- src\editor\settings.lua, src\editor\gui.lua
["Project/&FileTree Window"] = "&Projekt/Datei Fenster", -- src\editor\menu_view.lua
["R/O"] = "R/O", -- src\editor\editor.lua
["R/W"] = "R/W", -- src\editor\editor.lua
["Re&place In Files"] = "Ersetze in &Dateien", -- src\editor\menu_search.lua
["Recent Files"] = "Letzte Dateien", -- src\editor\menu_file.lua
["Redo last edit undone"] = "Stelle letzte rückgängig gemachte Bearbeitung wieder her", -- src\editor\menu_edit.lua
["Refused a request to start a new debugging session as there is one in progress already."] = "Starten einer neuen Debuggingsession abgelehnt, da bereits eine läuft.", -- src\editor\debugger.lua
["Regular &expression"] = "&Regulärer Ausdruck", -- src\editor\findreplace.lua
["Remote console"] = "Fensteuerungs-Konsole", -- src\editor\shellbox.lua
["Rename All Instances"] = "Umbenennen aller Instanzen", -- src\editor\editor.lua
["Replace &All"] = "&Alles ersetzen", -- src\editor\findreplace.lua
["Replace"] = "Ersetzen", -- src\editor\findreplace.lua
["Replaced an invalid UTF8 character with %s."] = "Unbekanntes UTF8-Symbol ersetzt mit %s.", -- src\editor\commands.lua
["Replaced"] = "Ersetzt:", -- src\editor\findreplace.lua
["Replacing"] = "Am Ersetzen", -- src\editor\findreplace.lua
["Reset to default layout"] = "Standard-Layout wiederherstellen", -- src\editor\menu_view.lua
["Resets the dynamic word list for autocompletion"] = "Zurücksetzen der Liste der dynamischen Wörter für Autovervollständigung", -- src\editor\menu_edit.lua
["Run as Scratchpad"] = "Als &Entwurf starten", -- src\editor\menu_project.lua
["S&top Debugging"] = "Debugging a&nhalten", -- src\editor\menu_project.lua
["S&top Process"] = "Prozeß &anhalten", -- src\editor\menu_project.lua
["Save &As..."] = "S&peichern als...", -- src\editor\menu_file.lua, src\editor\gui.lua
["Save A&ll"] = "&Alle Speichern", -- src\editor\menu_file.lua
["Save Changes?"] = "Änderungen speichern?", -- src\editor\commands.lua
["Save all open documents"] = "Alle offenen Dokumente speichern", -- src\editor\menu_file.lua, src\editor\gui.lua
["Save file as"] = "Datei speichern als", -- src\editor\commands.lua
["Save file?"] = "Datei speichern?", -- src\editor\commands.lua
["Save the current document to a file with a new name"] = "Aktuelles Dokument unter neuem Namen speichern", -- src\editor\menu_file.lua
["Save the current document"] = "Aktuelles Dokument speichern", -- src\editor\menu_file.lua, src\editor\gui.lua
["Saved auto-recover at %s."] = "Autowiederherstellen gespeichert unter %s.", -- src\editor\commands.lua
["Scope"] = "Richtung", -- src\editor\findreplace.lua
["Scratchpad error"] = "Fehler im Entwurf", -- src\editor\debugger.lua
["Searching for"] = "Suchen nach", -- src\editor\findreplace.lua
["Select &All"] = "&Alles Auswählen", -- src\editor\editor.lua, src\editor\menu_edit.lua
["Select all text in the editor"] = "Kompletten Text im Editor auswählen", -- src\editor\menu_edit.lua
["Set From Current File"] = "Anhand der aktuellen Datei festlegen", -- src\editor\menu_project.lua
["Set project directory from current file"] = "Lege Projektverzeichnis anhand der aktuellen Datei fest", -- src\editor\menu_project.lua, src\editor\gui.lua
["Set the interpreter to be used"] = "Wähle zu benutzenden Interpreter aus", -- src\editor\menu_project.lua
["Set the project directory to be used"] = "Lege zu benutzendes Projektverzeichnis fest", -- src\editor\menu_project.lua
["Settings: System"] = "Einstellungen: System", -- src\editor\menu_edit.lua
["Settings: User"] = "Einstellungen: Nutzer", -- src\editor\menu_edit.lua
["Show &Tooltip"] = "&Tooltip zeigen", -- src\editor\menu_edit.lua
["Show Location"] = "Ordner öffnen", -- src\editor\gui.lua, src\editor\filetree.lua
["Show tooltip for current position; place cursor after opening bracket of function"] = "Zeige Tooltip für aktuelle Position; setze Cursor hinter die öffnende Klammer der Funktion", -- src\editor\menu_edit.lua
["Sort selected lines"] = "Ausgewählte Zeilen sortieren", -- src\editor\menu_search.lua
["Stack"] = "Stack", -- src\editor\debugger.lua
["Start &Debugging"] = "&Debugging starten", -- src\editor\menu_project.lua
["Start debugging"] = "Debugging starten", -- src\editor\menu_project.lua, src\editor\gui.lua
["Step &Into"] = "Schritt h&inein", -- src\editor\menu_project.lua
["Step &Over"] = "&Überspringen", -- src\editor\menu_project.lua
["Step O&ut"] = "Schritt &raus", -- src\editor\menu_project.lua
["Step into"] = "Schritt hinein", -- src\editor\menu_project.lua, src\editor\gui.lua
["Step out of the current function"] = "Schritt aus der aktuellen Funktion heraus", -- src\editor\menu_project.lua, src\editor\gui.lua
["Step over"] = "Überspringen", -- src\editor\menu_project.lua, src\editor\gui.lua
["Stop the currently running process"] = "Aktuell laufenden Prozeß stoppen", -- src\editor\menu_project.lua, src\editor\gui.lua
["Switch to or from full screen mode"] = "Vollbild an/aus", -- src\editor\menu_view.lua
["Text not found."] = "Text nicht gefunden.", -- src\editor\findreplace.lua
["The API file must be located in a subdirectory of the API directory."] = "Die API-Datei muß sich in einem Unterverzeichnis des API-Vereichnisses befinden.", -- src\editor\autocomplete.lua
["Toggle Break&point"] = "&Haltepunkt an/aus", -- src\editor\menu_project.lua
["Toggle breakpoint"] = "Haltepunkt an/aus", -- src\editor\menu_project.lua, src\editor\gui.lua
["Tr&ace"] = "Ablauf &verfolgen", -- src\editor\menu_project.lua
["Trace execution showing each executed line"] = "Ablaufverfolgung zeigt jede ausgeführte Zeile an", -- src\editor\menu_project.lua
["Unable to load file '%s'."] = "Scheitern beim Laden von Datei '%s'.", -- src\editor\commands.lua
["Unable to save file '%s': %s"] = "Scheitern beim Speichern von Datei '%s' : %s", -- src\editor\commands.lua
["Unable to stop program (pid: %d), code %d."] = "Scheitern beim Stoppen des Prozesses (pid : %d), code %d.", -- src\editor\debugger.lua
["Undo last edit"] = "Letzte Änderung rückgängig machen", -- src\editor\menu_edit.lua
["Use '%s' to see full description."] = "'%s' für eine komplette Beschreibung.", -- src\editor\editor.lua
["Use '%s' to show line endings and '%s' to convert them."] = "'%s' um Zeilenende-Codes zu sehen, und '%s' um sie zu konvertieren.", -- src\editor\commands.lua
["Use 'clear' to clear the shell output and the history."] = "'clear' um Ausgabefenster und Verlauf zu löschen.", -- src\editor\shellbox.lua
["Use Shift-Enter for multiline code."] = "<Umsch-Eingabetaste> für Code in mehreren Zeilen.", -- src\editor\shellbox.lua
["Value"] = "Wert", -- src\editor\debugger.lua
["View the output/console window"] = "Ausgabe-/Konsolenfenster ansehen", -- src\editor\menu_view.lua
["View the project/filetree window"] = "Projekt-/Dateifenster ansehen", -- src\editor\menu_view.lua
["View the stack window"] = "Stapel/Stack-Fenster ansehen", -- src\editor\menu_view.lua, src\editor\gui.lua
["View the watch window"] = "Fenster für Beobachtungspunkte ansehen", -- src\editor\menu_view.lua, src\editor\gui.lua
["Watch"] = "Beobachtungspunkte", -- src\editor\debugger.lua
["Welcome to the interactive Lua interpreter."] = "Willkommen zum interaktiven Lua-Interpretr!", -- src\editor\shellbox.lua
["Wrap ar&ound"] = "Am Anfang fortsetzen", -- src\editor\findreplace.lua
["You must save the program first."] = "Erst das Programm speichern.", -- src\editor\commands.lua
["on line %d"] = "in Zeile %d", -- src\editor\debugger.lua, src\editor\commands.lua, src\editor\editor.lua
["traced %d instruction"] = {"%d Anweisung verfolgt", "%d Anweisungen verfolgt"} -- src\editor\debugger.lua
}

View File

@@ -36,7 +36,7 @@ return {
["&Watch Window"] = "Ventana de observaciones", -- src\editor\menu_view.lua
["About %s"] = "Acerca de %s", -- src\editor\menu_help.lua
["Add Watch Expression"] = "Añadir expresión de observación", -- src\editor\editor.lua
["Add to Scratchpad"] = "Añadir al borrador", -- src\editor\editor.lua
["Add To Scratchpad"] = "Añadir al borrador", -- src\editor\editor.lua
["All files"] = "Todos los archivos", -- src\editor\commands.lua
["Allow external process to start debugging"] = "Permitir proceso externo para iniciar depuración", -- src\editor\menu_project.lua
["Analyze the source code"] = "Analizar el código fuente", -- src\editor\inspect.lua
@@ -86,7 +86,7 @@ return {
["Error while processing API file: %s"] = "Error mientras se procesaba el archivo de API: %s", -- src\editor\autocomplete.lua
["Error while processing configuration file: %s"] = nil, -- src\editor\style.lua
["Error"] = "Error", -- src\editor\commands.lua
["Evaluate in Console"] = "Evaluar en consola", -- src\editor\editor.lua
["Evaluate In Console"] = "Evaluar en consola", -- src\editor\editor.lua
["Execute the current project/file and keep updating the code to see immediate results"] = "Ejecutar el proyecto/archivo actual y manteniendo actualizado el código para ver resultados en tiempo real", -- src\editor\menu_project.lua
["Execute the current project/file"] = "Ejecutar el proyecto/archivo actual", -- src\editor\menu_project.lua
["Execution error"] = "Error de ejecución", -- src\editor\debugger.lua

View File

@@ -1,5 +1,7 @@
return {
[0] = function(c) return c == 1 and 1 or 2 end, -- plural
["%d instance"] = {"%d occurrence", "%d occurrences"}, -- src\editor\findreplace.lua
["%s event failed: %s"] = "L'événement %s a échoué : %s", -- src\editor\package.lua
["&About"] = "À &propos", -- src\editor\menu_help.lua
["&Add Watch"] = "&Ajouter une expression", -- src\editor\debugger.lua
["&Break"] = "&Interrompre", -- src\editor\menu_project.lua
@@ -8,12 +10,15 @@ return {
["&Copy"] = "Co&pier", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&Default Layout"] = "Affichage par &défaut", -- src\editor\menu_view.lua
["&Delete Watch"] = "&Supprimer une expression", -- src\editor\debugger.lua
["&Down"] = "Vers le &bas", -- src\editor\findreplace.lua
["&Edit Watch"] = "&Modifier une expression", -- src\editor\debugger.lua
["&Edit"] = "É&dition", -- src\editor\menu_edit.lua
["&File"] = "&Fichier", -- src\editor\menu_file.lua
["&Find"] = "&Rechercher...", -- src\editor\menu_search.lua
["&Find All"] = "&Rechercher tout", -- src\editor\findreplace.lua
["&Find Next"] = "&Rechercher", -- src\editor\findreplace.lua
["&Find"] = "&Rechercher", -- src\editor\menu_search.lua
["&Fold/Unfold All"] = "Re&plier/Déplier tout", -- src\editor\menu_edit.lua
["&Goto Line"] = "&Aller à la ligne...", -- src\editor\menu_search.lua
["&Goto Line"] = "&Aller à la ligne", -- src\editor\menu_search.lua
["&Help"] = "Aid&e", -- src\editor\menu_help.lua
["&New"] = "&Nouveau", -- src\editor\menu_file.lua
["&Open..."] = "&Ouvrir...", -- src\editor\menu_file.lua
@@ -21,19 +26,23 @@ return {
["&Paste"] = "Co&ller", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&Project"] = "&Projet", -- src\editor\menu_project.lua, src\editor\inspect.lua
["&Redo"] = "&Rétablir", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&Replace"] = "Re&mplacer...", -- src\editor\menu_search.lua
["&Replace All"] = "Remplacer &tout", -- src\editor\findreplace.lua
["&Replace"] = "Re&mplacer", -- src\editor\findreplace.lua, src\editor\menu_search.lua
["&Run"] = "&Exécuter", -- src\editor\menu_project.lua
["&Save"] = "&Enregistrer", -- src\editor\menu_file.lua, src\editor\gui.lua
["&Search"] = "&Recherche", -- src\editor\menu_search.lua
["&Sort"] = "&Trier", -- src\editor\menu_search.lua
["&Stack Window"] = "&Pile d'exécution", -- src\editor\menu_view.lua
["&Start Debugger Server"] = "Lancer le &serveur de débogage", -- src\editor\menu_project.lua
["&Subdirectories"] = "&Sous-répertoires", -- src\editor\findreplace.lua
["&Undo"] = "&Annuler", -- src\editor\editor.lua, src\editor\menu_edit.lua
["&Up"] = "Vers le &haut", -- src\editor\findreplace.lua
["&View"] = "&Affichage", -- src\editor\menu_view.lua
["&Watch Window"] = "&Expressions espionnes", -- src\editor\menu_view.lua
[".&bak on Replace"] = ".&bak avant remplacement", -- src\editor\findreplace.lua
["About %s"] = "À propos de %s", -- src\editor\menu_help.lua
["Add Watch Expression"] = "Ajouter une expression", -- src\editor\editor.lua
["Add to Scratchpad"] = "Ajouter au brouillon", -- src\editor\editor.lua
["Add To Scratchpad"] = "Ajouter au brouillon", -- src\editor\editor.lua
["All files"] = "Tous les fichiers", -- src\editor\commands.lua
["Allow external process to start debugging"] = "Autoriser les processus externes à lancer le débogage", -- src\editor\menu_project.lua
["Analyze the source code"] = "Analyser le code source", -- src\editor\inspect.lua
@@ -49,8 +58,9 @@ return {
["Can't run the entry point script ('%s')."] = "Impossible d'exécuter le point d'entrée du script ('%s').", -- src\editor\debugger.lua
["Can't start debugging session due to internal error '%s'."] = "Impossible de lancer la session de débogage : erreur interne '%s'.", -- src\editor\debugger.lua
["Can't start debugging without an opened file or with the current file not being saved ('%s')."] = "Impossible de lancer le débogage si aucun fichier n'est ouvert ou si le fichier courant n'a pas été enregistré ('%s').", -- src\editor\debugger.lua
["Cancel"] = "Annuler", -- src\editor\findreplace.lua
["Choose ..."] = "Choisir...", -- src\editor\menu_project.lua
["Choose a project directory"] = "Choisissez un répertoire de projet", -- src\editor\menu_project.lua
["Choose a project directory"] = "Choisissez un répertoire de projet", -- src\editor\findreplace.lua, src\editor\menu_project.lua
["Clear &Dynamic Words"] = "Effacer les mots &dynamiques", -- src\editor\menu_edit.lua
["Clear the output window before compiling or debugging"] = "Effacer la fenêtre de sortie avant compilation ou débogage", -- src\editor\menu_project.lua
["Close &Other Pages"] = "Fermer les &autres pages", -- src\editor\gui.lua
@@ -73,6 +83,7 @@ return {
["Debugging session completed (%s)."] = "Session de débogage terminée (%s).", -- src\editor\debugger.lua
["Debugging session started in '%s'."] = "Session de débogage démarrée dans '%s'.", -- src\editor\debugger.lua
["Debugging suspended at %s:%s (couldn't activate the file)."] = "Débogage interrompu à %s:%s (impossible d'activer le fichier).", -- src\editor\debugger.lua
["Directory"] = "Répertoire ", -- src\editor\findreplace.lua
["Do you want to reload it?"] = "Voulez-vous le recharger ?", -- src\editor\editor.lua
["Do you want to save the changes to '%s'?"] = "Voulez-vous enregistrer les modifications dans '%s' ?", -- src\editor\commands.lua
["E&xit"] = "&Quitter", -- src\editor\menu_file.lua
@@ -83,7 +94,7 @@ return {
["Error while processing API file: %s"] = "Erreur lors de la lecture du fichier d'API : %s", -- src\editor\autocomplete.lua
["Error while processing configuration file: %s"] = "Erreur lors de la lecture du fichier de configuration : %s", -- src\editor\style.lua
["Error"] = "Erreur", -- src\editor\commands.lua
["Evaluate in Console"] = "Évaluer dans la console", -- src\editor\editor.lua
["Evaluate In Console"] = "Évaluer dans la console", -- src\editor\editor.lua
["Execute the current project/file and keep updating the code to see immediate results"] = "Exécuter le projet/fichier courant en mettant le code à jour afin de voir les résultats en temps réel", -- src\editor\menu_project.lua
["Execute the current project/file"] = "Exécuter le projet/fichier courant", -- src\editor\menu_project.lua
["Execution error"] = "Erreur d'exécution", -- src\editor\debugger.lua
@@ -92,36 +103,46 @@ return {
["Expression"] = "Expression", -- src\editor\debugger.lua
["File '%s' has been modified on disk."] = "Le fichier '%s' a été modifié sur le disque.", -- src\editor\editor.lua
["File '%s' has more recent timestamp than restored '%s'; please review before saving."] = "Le fichier '%s' a un horodatage plus récent que celui restauré '%s' ; veuillez vérifier avant d'enregistrer.", -- src\editor\commands.lua
["File '%s' no longer exists."] = "Le fichier '%s' n'existe plus.", -- src\editor\editor.lua
["File '%s' no longer exists."] = "Le fichier '%s' n'existe plus.", -- src\editor\editor.lua, src\editor\menu_file.lua
["File Type"] = "Type de fichier ", -- src\editor\findreplace.lua
["File history"] = "Historique de fichier", -- src\editor\menu_file.lua
["Find &In Files"] = "Rec&hercher dans les fichiers...", -- src\editor\menu_search.lua
["Find &In Files"] = "Rec&hercher dans les fichiers", -- src\editor\menu_search.lua
["Find &Next"] = "Rechercher l'occurrence &suivante", -- src\editor\menu_search.lua
["Find &Previous"] = "Rechercher l'occurrence &précédente", -- src\editor\menu_search.lua
["Find In Files"] = "Rechercher dans les fichiers", -- src\editor\findreplace.lua
["Find and replace text in files"] = "Rechercher et remplacer le texte dans les fichiers", -- src\editor\menu_search.lua
["Find and replace text"] = "Rechercher et remplacer le texte", -- src\editor\menu_search.lua, src\editor\gui.lua
["Find text in files"] = "Rechercher le texte dans les fichiers", -- src\editor\menu_search.lua
["Find text"] = "Rechercher le texte", -- src\editor\menu_search.lua, src\editor\gui.lua
["Find the earlier text occurence"] = "Recherche l'occurrence précédente du texte", -- src\editor\menu_search.lua
["Find the next text occurrence"] = "Recherche l'occurrence suivante du texte", -- src\editor\menu_search.lua
["Find"] = "Rechercher ", -- src\editor\findreplace.lua
["Fold or unfold all code folds"] = "Replier ou déplier tous les blocs de code", -- src\editor\menu_edit.lua
["Found auto-recovery record and restored saved session."] = "Une récupération automatique a été trouvé et la session a été restaurée.", -- src\editor\commands.lua
["Found"] = "Occurrences trouvées :", -- src\editor\findreplace.lua
["Full &Screen"] = "&Plein écran", -- src\editor\menu_view.lua
["Go To Definition"] = "Aller à la définition", -- src\editor\editor.lua
["Go to a selected line"] = "Aller à la ligne sélectionnée", -- src\editor\menu_search.lua
["Goto Line"] = "Aller à la ligne", -- src\editor\menu_search.lua
["INS"] = "INS", -- src\editor\editor.lua
["In Files"] = "Dans les fichiers", -- src\editor\findreplace.lua
["Jump to a function definition..."] = "Aller à la définition de fonction...", -- src\editor\editor.lua
["Known Files"] = "Fichiers connus", -- src\editor\commands.lua
["Ln: %d"] = "Lig : %d", -- src\editor\editor.lua
["Local console"] = "Console locale", -- src\editor\shellbox.lua, src\editor\gui.lua
["Lua &Interpreter"] = "Interpréteur L&ua", -- src\editor\menu_project.lua
["Mapped remote request for '%s' to '%s'."] = "La requête distante pour '%s' a été associée à '%s'.", -- src\editor\debugger.lua
["Match &case"] = "Respecter la &casse", -- src\editor\findreplace.lua
["Match &whole word"] = "&Mot entier uniquement", -- src\editor\findreplace.lua
["Mixed end-of-line encodings detected."] = "Plusieurs codages de fin de ligne détectés.", -- src\editor\commands.lua
["OVR"] = "OVR", -- src\editor\editor.lua
["Open an existing document"] = "Ouvrir un document existant", -- src\editor\menu_file.lua, src\editor\gui.lua
["Open file"] = "Ouvrir un fichier", -- src\editor\commands.lua
["Options"] = "Options", -- src\editor\findreplace.lua
["Output (running)"] = "Sortie (en cours d'exécution)", -- src\editor\output.lua
["Output"] = "Sortie", -- src\editor\output.lua, src\editor\settings.lua, src\editor\gui.lua
["Paste text from the clipboard"] = "Coller le texte depuis le presse-papiers", -- src\editor\menu_edit.lua
["Preferences"] = "Préférences", -- src\editor\menu_edit.lua
["Prepend '=' to show complex values on multiple lines."] = "Préfixez par '=' pour afficher les valeurs complexes sur plusieurs lignes.", -- src\editor\shellbox.lua
["Press cancel to abort."] = "Cliquez sur Annuler pour annuler.", -- src\editor\commands.lua
["Program '%s' started in '%s' (pid: %d)."] = "Programme '%s' démarré dans '%s' (pid : %d).", -- src\editor\output.lua
@@ -135,12 +156,18 @@ return {
["Project/&FileTree Window"] = "&Explorateur de projet", -- src\editor\menu_view.lua
["R/O"] = "R/O", -- src\editor\editor.lua
["R/W"] = "R/W", -- src\editor\editor.lua
["Re&place In Files"] = "Remp&lacer dans les fichiers...", -- src\editor\menu_search.lua
["Re&place In Files"] = "Remp&lacer dans les fichiers", -- src\editor\menu_search.lua
["Recent Files"] = "Fichiers récents", -- src\editor\menu_file.lua
["Redo last edit undone"] = "Rétablir la dernière modification", -- src\editor\menu_edit.lua
["Refused a request to start a new debugging session as there is one in progress already."] = "Une requête de lancement de débogage a été refusée car une session de débogage est déjà en cours.", -- src\editor\debugger.lua
["Regular &expression"] = "&Expression régulière", -- src\editor\findreplace.lua
["Remote console"] = "Console à distance", -- src\editor\shellbox.lua
["Rename All Instances"] = "Renommer toutes les occurrences", -- src\editor\editor.lua
["Replace &All"] = "Remplacer &tout", -- src\editor\findreplace.lua
["Replace"] = "Remplacer par ", -- src\editor\findreplace.lua
["Replaced an invalid UTF8 character with %s."] = "Un caractère UTF8 invalide a été remplacé par %s.", -- src\editor\commands.lua
["Replaced"] = "Occurrences remplacées :", -- src\editor\findreplace.lua
["Replacing"] = "Remplacement de", -- src\editor\findreplace.lua
["Reset to default layout"] = "Restaurer l'affichage par défaut", -- src\editor\menu_view.lua
["Resets the dynamic word list for autocompletion"] = "Réinitialiser la liste des mots dynamiques pour l'auto-complétion", -- src\editor\menu_edit.lua
["Run as Scratchpad"] = "Exécuter comme brouillon", -- src\editor\menu_project.lua
@@ -155,14 +182,19 @@ return {
["Save the current document to a file with a new name"] = "Enregistrer le document courant sous un nouveau nom", -- src\editor\menu_file.lua
["Save the current document"] = "Enregistrer le document courant", -- src\editor\menu_file.lua, src\editor\gui.lua
["Saved auto-recover at %s."] = "Récup. auto enregistrée à %s.", -- src\editor\commands.lua
["Scope"] = "Direction", -- src\editor\findreplace.lua
["Scratchpad error"] = "Erreur dans le brouillon", -- src\editor\debugger.lua
["Searching for"] = "Recherche de", -- src\editor\findreplace.lua
["Select &All"] = "Sélectionner &tout", -- src\editor\editor.lua, src\editor\menu_edit.lua
["Select all text in the editor"] = "Sélectionner tout le texte dans l'éditeur", -- src\editor\menu_edit.lua
["Set From Current File"] = "Définir depuis le fichier courant", -- src\editor\menu_project.lua
["Set project directory from current file"] = "Définir le répertoire de projet depuis le fichier courant", -- src\editor\menu_project.lua, src\editor\gui.lua
["Set the interpreter to be used"] = "Définir l'interpréteur à utiliser", -- src\editor\menu_project.lua
["Set the project directory to be used"] = "Définir le répertoire de projet à utiliser", -- src\editor\menu_project.lua
["Settings: System"] = "Paramètres : Système", -- src\editor\menu_edit.lua
["Settings: User"] = "Paramètres : Utilisateur", -- src\editor\menu_edit.lua
["Show &Tooltip"] = "Afficher l'info-&bulle", -- src\editor\menu_edit.lua
["Show Location"] = "Afficher l'emplacement", -- src\editor\gui.lua, src\editor\filetree.lua
["Show tooltip for current position; place cursor after opening bracket of function"] = "Afficher l'info-bulle pour la position actuelle ; placez le curseur après la parenthèse ouvrante de la fonction", -- src\editor\menu_edit.lua
["Sort selected lines"] = "Trier les lignes sélectionnées", -- src\editor\menu_search.lua
["Stack"] = "Pile d'exécution", -- src\editor\debugger.lua
@@ -176,6 +208,7 @@ return {
["Step over"] = "Enjamber l'instruction suivante", -- src\editor\menu_project.lua, src\editor\gui.lua
["Stop the currently running process"] = "Arrêter le processus en cours d'exécution", -- src\editor\menu_project.lua, src\editor\gui.lua
["Switch to or from full screen mode"] = "Activer ou désactiver le mode plein écran", -- src\editor\menu_view.lua
["Text not found."] = "Texte non trouvé.", -- src\editor\findreplace.lua
["The API file must be located in a subdirectory of the API directory."] = "Le fichier d'API doit être placé dans un sous-répertoire du répertoire d'API.", -- src\editor\autocomplete.lua
["Toggle Break&point"] = "Créer/Supprimer un &point d'arrêt", -- src\editor\menu_project.lua
["Toggle breakpoint"] = "Créer ou supprimer un point d'arrêt", -- src\editor\menu_project.lua, src\editor\gui.lua
@@ -196,7 +229,8 @@ return {
["View the watch window"] = "Afficher la fenêtre d'expressions espionnes", -- src\editor\menu_view.lua, src\editor\gui.lua
["Watch"] = "Expressions espionnes", -- src\editor\debugger.lua
["Welcome to the interactive Lua interpreter."] = "Bienvenue dans l´interpréteur interactif Lua.", -- src\editor\shellbox.lua
["Wrap ar&ound"] = "B&oucler", -- src\editor\findreplace.lua
["You must save the program first."] = "Vous devez d'abord enregistrer le programme.", -- src\editor\commands.lua
["on line %d"] = "à la ligne %d", -- src\editor\debugger.lua, src\editor\commands.lua
["on line %d"] = "à la ligne %d", -- src\editor\debugger.lua, src\editor\commands.lua, src\editor\editor.lua
["traced %d instruction"] = {"%d instruction tracée", "%d instructions tracées"} -- src\editor\debugger.lua
}

View File

@@ -33,7 +33,7 @@ return {
["&Watch Window"] = "Finestra Espressioni di Controllo", -- src\editor\menu_view.lua
["About %s"] = "Informazioni su %s", -- src\editor\menu_help.lua
["Add Watch Expression"] = "Aggiungi Espressione di Controllo", -- src\editor\editor.lua
["Add to Scratchpad"] = "Aggiungi a Scratchpad ", -- src\editor\editor.lua
["Add To Scratchpad"] = "Aggiungi a Scratchpad ", -- src\editor\editor.lua
["All files"] = "Tutti i files", -- src\editor\commands.lua
["Allow external process to start debugging"] = "Permetti a processi esterni di avviare il debug", -- src\editor\menu_project.lua
["Analyze the source code"] = "Analizza il codice", -- src\editor\inspect.lua
@@ -83,7 +83,7 @@ return {
["Error while processing API file: %s"] = "Errore durante l'elaborazione del file API: %s", -- src\editor\autocomplete.lua
["Error while processing configuration file: %s"] = "Errore durante l'elaborazione del file di configurazione: %s", -- src\editor\style.lua
["Error"] = "Errore", -- src\editor\commands.lua
["Evaluate in Console"] = "Elabora in console", -- src\editor\editor.lua
["Evaluate In Console"] = "Elabora in console", -- src\editor\editor.lua
["Execute the current project/file and keep updating the code to see immediate results"] = "Esegue il progetto/file corrente e permette di modificare il codice per vedere i risultati in tempo reale", -- src\editor\menu_project.lua
["Execute the current project/file"] = "Esegue il progetto/file corrente", -- src\editor\menu_project.lua
["Execution error"] = "Errore di esecuzione", -- src\editor\debugger.lua

View File

@@ -41,7 +41,7 @@ return {
[".&bak on Replace"] = ".&bak после замены", -- src\editor\findreplace.lua
["About %s"] = "О %s", -- src\editor\menu_help.lua
["Add Watch Expression"] = "Добавить выражение", -- src\editor\editor.lua
["Add to Scratchpad"] = "Добавить в черновик", -- src\editor\editor.lua
["Add To Scratchpad"] = "Добавить в черновик", -- src\editor\editor.lua
["All files"] = "Все файлы", -- src\editor\commands.lua
["Allow external process to start debugging"] = "Разрешить внешнему процессу начать отладку", -- src\editor\menu_project.lua
["Analyze the source code"] = "Проанализировать исходный код", -- src\editor\inspect.lua
@@ -93,7 +93,7 @@ return {
["Error while processing API file: %s"] = "Ошибка обработки файла определений API: %s", -- src\editor\autocomplete.lua
["Error while processing configuration file: %s"] = "Ошибка обработки файла конфигурации: %s", -- src\editor\style.lua
["Error"] = "Ошибка", -- src\editor\commands.lua
["Evaluate in Console"] = "Выполнить в консоли", -- src\editor\editor.lua
["Evaluate In Console"] = "Выполнить в консоли", -- src\editor\editor.lua
["Execute the current project/file and keep updating the code to see immediate results"] = "Запустить текущий проект/файл и продолжать вносить изменения в код с немедленным выводом результатов", -- src\editor\menu_project.lua
["Execute the current project/file"] = "Запустить текущий проект/файл", -- src\editor\menu_project.lua
["Execution error"] = "Ошибка выполнения", -- src\editor\debugger.lua

View File

@@ -1,5 +1,5 @@
--[[
1. Pick a color scheme by clicking on a link:
1. Pick a color scheme by clicking on its name:
- [Tomorrow](macro:shell(ApplyStyleConfig('cfg/tomorrow.lua','Tomorrow')))
- [TomorrowContrast](macro:shell(ApplyStyleConfig('cfg/tomorrow.lua','TomorrowContrast')))
- [TomorrowNight](macro:shell(ApplyStyleConfig('cfg/tomorrow.lua','TomorrowNight')))
@@ -8,8 +8,10 @@
- [TomorrowNightEighties](macro:shell(ApplyStyleConfig('cfg/tomorrow.lua','TomorrowNightEighties')))
- [Zenburn](macro:shell(ApplyStyleConfig('cfg/tomorrow.lua','Zenburn')))
- [Monokai](macro:shell(ApplyStyleConfig('cfg/tomorrow.lua','Monokai')))
- [Molokai](macro:shell(ApplyStyleConfig('cfg/tomorrow.lua','Molokai')))
- [SolarizedDark](macro:shell(ApplyStyleConfig('cfg/tomorrow.lua','SolarizedDark')))
- [SolarizedLight](macro:shell(ApplyStyleConfig('cfg/tomorrow.lua','SolarizedLight')))
- [Notepad++](macro:shell(ApplyStyleConfig('cfg/tomorrow.lua','NotepadPlusPlus')))
- [ZeroBrane Studio](macro:shell(ide.config.styles = StylesGetDefault(); ReApplySpecAndStyles()))

View File

@@ -135,6 +135,20 @@ local colors = {
Blue = H'F92672',
Purple = H'A6E22E',
},
Molokai = { -- based on https://github.com/tomasr/molokai/blob/master/colors/molokai.vim
Background = H'1B1D1E',
CurrentLine = H'293739',
Selection = H'49483E',
Foreground = H'F8F8F2',
Comment = H'7E8E91',
Red = H'AE81FF',
Orange = H'AE81FF',
Yellow = H'F8F8F2',
Green = H'E6DB74',
Aqua = H'66D9EF',
Blue = H'F92672',
Purple = H'A6E22E',
},
SolarizedDark = {
Background = H'042029',
CurrentLine = H'0A2933',
@@ -163,6 +177,20 @@ local colors = {
Blue = H'859900',
Purple = H'268BD2',
},
NotepadPlusPlus = { -- contributed by Florian (https://github.com/SiENcE)
Background = H'FFFFFF',
CurrentLine = H'E9E2FF',
Selection = H'ADADA1',
Foreground = H'000000',
Comment = H'008000',
Red = H'FF6900',
Orange = H'00FF00',
Yellow = H'FF4E00',
Green = H'808080',
Aqua = H'260099',
Blue = H'2123FF',
Purple = H'FFFFFF',
},
}
-- add more of the specified color (keeping all in 0-255 range)
@@ -221,19 +249,26 @@ return {
sel = {bg = C.Selection},
caret = {fg = C.Foreground},
caretlinebg = {bg = C.CurrentLine},
fold = {fg = C.Comment, bg = C.Background},
fold = {fg = C.Comment, bg = C.Background, sel = mixer(C.Comment, 1, 96)},
whitespace = {fg = C.Comment, bg = C.Background},
fncall = {fg = C.Purple, st = wxstc.wxSTC_INDIC_PLAIN},
--[[ other possible values are:
wxSTC_INDIC_PLAIN Single-line underline
wxSTC_INDIC_SQUIGGLE Squiggly underline
wxSTC_INDIC_TT Line of small T-shapes
wxSTC_INDIC_DIAGONAL Diagonal hatching
wxSTC_INDIC_STRIKE Strike-out
wxSTC_INDIC_BOX Box
wxSTC_INDIC_ROUNDBOX Rounded Box
--]]
indicator = {
fncall = {fg = C.Purple, st = wxstc.wxSTC_INDIC_ROUNDBOX},
--[[ other possible values are:
wxSTC_INDIC_PLAIN Single-line underline
wxSTC_INDIC_SQUIGGLE Squiggly underline
wxSTC_INDIC_TT Line of small T-shapes
wxSTC_INDIC_DIAGONAL Diagonal hatching
wxSTC_INDIC_STRIKE Strike-out
wxSTC_INDIC_BOX Box
wxSTC_INDIC_ROUNDBOX Rounded Box
--]]
-- these indicators have all different default styles
varlocal = {fg = C.Foreground},
varglobal = {fg = C.Foreground},
varmasked = {fg = C.Foreground},
varmasking = {fg = C.Foreground},
},
-- markup
['['] = {hs = mixer(C.Comment, 3, 64)},

View File

@@ -95,13 +95,13 @@ styles.marker.prompt = {ch = wxstc.wxSTC_MARK_CHARACTER+('>'):byte(), {0, 0, 0},
stylesoutshell = styles
-- to disable indicators (underlining) on function calls
editor.showfncall = false
styles.indicator.fncall = nil
-- to change the color of the indicator used for function calls
styles.fncall.fg = {240,0,0}
styles.indicator.fncall.fg = {240,0,0}
-- to change the type of the indicator used for function calls
styles.fncall.st = wxstc.wxSTC_INDIC_PLAIN
styles.indicator.fncall.st = wxstc.wxSTC_INDIC_PLAIN
--[[ other possible values are:
wxSTC_INDIC_PLAIN Single-line underline
wxSTC_INDIC_SQUIGGLE Squiggly underline
@@ -135,3 +135,8 @@ editor.foldcompact = true
-- to disable zoom with mouse wheel as it may be too sensitive on OSX
editor.nomousezoom = true
-- to specify a skin for Corona simulator (OSX only);
-- you can also change it between runs from Local Console by executing
-- `ide.config.corona = {skin = 'iPad'}`
corona = { skin = "iPad" }

View File

@@ -57,3 +57,17 @@ ide.app.postinit = function()
end
end
--]]
--[[ An example of how individual keywords can be styled
local G = ... -- this now points to the global environment in the script
local luaspec = G.ide.specs['lua']
local num = #luaspec.keywords
-- take a new slot in the list of keywords (starting from 1)
luaspec.keywords[num+1] = 'return'
-- remove 'return' from the list of "regular" keywords
luaspec.keywords[1] = luaspec.keywords[1]:gsub(' return', '')
-- assign new style to the added slot (starting from 0)
styles["keywords"..num] = {fg = {240, 0, 0}, b = true}
--]]

View File

@@ -1,4 +1,4 @@
-- Copyright 2011-12 Paul Kulchenko, ZeroBrane LLC
-- Copyright 2011-13 Paul Kulchenko, ZeroBrane LLC
local corona
local win = ide.osname == "Windows"
@@ -52,13 +52,21 @@ return {
local mdbl = MergeFullPath(GetPathWithSep(ide.editorFilename), "lualibs/mobdebug/mobdebug.lua")
if not wx.wxFileExists(mdbc)
or GetFileModTime(mdbc):GetTicks() < GetFileModTime(mdbl):GetTicks() then
FileCopy(mdbl, mdbc)
DisplayOutput(("Copied ZeroBrane Studio debugger ('mobdebug.lua') to '%s' folder.\n"):format(mdbc))
local copied = FileCopy(mdbl, mdbc)
local message = copied
and ("Copied debugger ('mobdebug.lua') to '%s'."):format(mdbc)
or ("Failed to copy debugger ('mobdebug.lua') to '%s': %s")
:format(mdbc, wx.wxSysErrorMsg())
DisplayOutputLn(message)
if not copied then return end
end
end
local debugopt = mac and "-debug 1 -project " or "-debug "
local cmd = ('"%s" %s"%s"'):format(corona, rundebug and debugopt or "", file)
local skin = ide.config.corona and ide.config.corona.skin
and (" -skin "..ide.config.corona.skin) or ""
local cmd = ('"%s" %s"%s"%s')
:format(corona, rundebug and debugopt or "", file, skin)
-- CommandLineRun(cmd,wdir,tooutput,nohide,stringcallback,uid,endcallback)
return CommandLineRun(cmd,self:fworkdir(wfilename),true,false,nil,nil,
function() ide.debugger.pid = nil end)

63
interpreters/lfw.lua Normal file
View File

@@ -0,0 +1,63 @@
if ide.osname ~= "Windows" or not os.getenv("LUA_DEV") then return end
local exe
local function exePath()
local defaultPath = ide.config.path.lfw or os.getenv("LUA_DEV")
return MergeFullPath(defaultPath, 'lua.exe')
end
return {
name = "LuaForWindows",
description = "Lua For Windows interpreter with debugger",
api = {"baselib"},
frun = function(self,wfilename,rundebug)
exe = exe or exePath()
local filepath = wfilename:GetFullPath()
local script
if rundebug then
DebuggerAttachDefault({basedir = self:fworkdir(wfilename),
runstart = ide.config.debugger.runonstart == true})
script = rundebug
else
-- if running on Windows and can't open the file, this may mean that
-- the file path includes unicode characters that need special handling
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 = '"'..exe..'" -e "'..code..'"'
-- add "LUA_DEV\clibs" to PATH to allow required DLLs to load
local _, path = wx.wxGetEnv("PATH")
local clibs = MergeFullPath(GetPathWithSep(exe), 'clibs')
if path and not path:find(clibs, 1, true) then
wx.wxSetEnv("PATH", path..';'..clibs)
end
-- CommandLineRun(cmd,wdir,tooutput,nohide,stringcallback,uid,endcallback)
local pid = CommandLineRun(cmd,self:fworkdir(wfilename),true,false,nil,nil,
function() ide.debugger.pid = nil end)
-- restore PATH
wx.wxSetEnv("PATH", path)
return pid
end,
fprojdir = function(self,wfilename)
return wfilename:GetPath(wx.wxPATH_GET_VOLUME)
end,
fworkdir = function (self,wfilename)
return wfilename:GetPath(wx.wxPATH_GET_VOLUME)
end,
hasdebugger = true,
fattachdebug = function(self) DebuggerAttachDefault() end,
scratchextloop = false,
unhideanywindow = true,
}

View File

@@ -1,4 +1,4 @@
-- Copyright 2011-12 Paul Kulchenko, ZeroBrane LLC
-- Copyright 2011-13 Paul Kulchenko, ZeroBrane LLC
local quick
local win = ide.osname == "Windows"
@@ -85,8 +85,13 @@ return {
local mdbl = MergeFullPath(GetPathWithSep(ide.editorFilename), "lualibs/mobdebug/mobdebug.lua")
if not wx.wxFileExists(mdbc)
or GetFileModTime(mdbc):GetTicks() < GetFileModTime(mdbl):GetTicks() then
FileCopy(mdbl, mdbc)
DisplayOutputLn("Copied ZeroBrane Studio debugger ('mobdebug.lua') to the project folder.")
local copied = FileCopy(mdbl, mdbc)
local message = copied
and ("Copied debugger ('mobdebug.lua') to '%s'."):format(mdbc)
or ("Failed to copy debugger ('mobdebug.lua') to '%s': %s")
:format(mdbc, wx.wxSysErrorMsg())
DisplayOutputLn(message)
if not copied then return end
end
end

View File

@@ -1,3 +1,5 @@
-- Copyright 2011-13 Paul Kulchenko, ZeroBrane LLC
local moai
local win = ide.osname == "Windows"

188
lualibs/lua_lexer_loose.lua Normal file
View File

@@ -0,0 +1,188 @@
--[[
lua_lexer_loose.lua.
Loose lexing of Lua code. See README.
WARNING: This code is preliminary and may have errors
in its current form.
(c) 2013 David Manura. MIT License.
--]]
local M = {}
-- based on LuaBalanced
local function match_string(s, pos)
pos = pos or 1
local posa = pos
local c = s:sub(pos,pos)
if c == '"' or c == "'" then
pos = pos + 1
while 1 do
pos = s:find("[" .. c .. "\\]", pos)
if not pos then return s:sub(posa), #s + 1 end -- not terminated string
if s:sub(pos,pos) == c then
local part = s:sub(posa, pos)
return part, pos + 1
else
pos = pos + 2
end
end
else
local sc = s:match("^%[(=*)%[", pos)
if sc then
local _; _, pos = s:find("%]" .. sc .. "%]", pos)
if not pos then return s:sub(posa), #s + 1 end -- not terminated string
local part = s:sub(posa, pos)
return part, pos + 1
else
return nil, pos
end
end
end
-- based on LuaBalanced
local function match_comment(s, pos)
pos = pos or 1
if s:sub(pos, pos+1) ~= '--' then
return nil, pos
end
pos = pos + 2
if s:sub(pos,pos) == '[' then
local partt, post = match_string(s, pos)
if partt then
return '--' .. partt, post
end
end
local part; part, pos = s:match('^([^\n]*\n?)()', pos)
return '--' .. part, pos
end
-- note: matches invalid numbers too
local function match_numberlike(s, pos)
local tok = s:match('^0[xX][0-9A-Fa-f]*', pos)
if tok then return tok end
local tok = s:match('^[0-9%.]+', pos)
if tok then
local tok2 = s:match('^[eE][+-]?[0-9]*', pos + #tok)
if tok2 then tok = tok .. tok2 end
return tok
end
return nil
end
local function newset(s)
local t = {}
for c in s:gmatch'.' do t[c] = true end
return t
end
local function qws(s)
local t = {}
for k in s:gmatch'%S+' do t[k] = true end
return t
end
local sym = newset("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_")
local dig = newset('0123456789')
local op = newset('=~<>.+-*/%^#=<>;:,.{}[]()')
op['=='] = true
op['<='] = true
op['>='] = true
op['~='] = true
op['..'] = true
local is_keyword = qws[[
and break do else elseif end false for function if
in local nil not or repeat return
then true until while]]
function M.lex(code, f, pos)
local pos = pos or 1
local tok = code:match('^#![^\n]*\n', pos) -- shebang
if tok then f('Shebang', tok, 1) pos = pos + #tok end
while pos <= #code do
local p2, n2, n1 = code:match('^%s*()((%S)%S?)', pos)
if not p2 then assert(code:sub(pos):match('^%s*$')); break end
pos = p2
if sym[n1] then
local tok = code:match('^([_A-Za-z][_A-Za-z0-9]*)', pos)
assert(tok)
if is_keyword[tok] then
f('Keyword', tok, pos)
else
f('Id', tok, pos)
end
pos = pos + #tok
elseif n2 == '--' then
local tok, pos2 = match_comment(code, pos)
assert(tok)
f('Comment', tok, pos)
pos = pos2
elseif n1 == '\'' or n1 == '\"' or n2 == '[[' or n2 == '[=' then
local tok = match_string(code, pos)
if tok then
f('String', tok, pos)
pos = pos + #tok
else
f('Unknown', code:sub(pos), pos) -- unterminated string
pos = #code + 1
end
elseif dig[n1] then
local tok = match_numberlike(code, pos)
assert(tok)
f('Number', tok, pos)
pos = pos + #tok
elseif op[n2] then
if n2 == '..' and code:match('^%.', pos+2) then
tok = '...'
else
tok = n2
end
f('Keyword', tok, pos)
pos = pos + #tok
elseif op[n1] then
local tok = n1
f('Keyword', tok, pos)
pos = pos + #tok
else
f('Unknown', n1, pos)
pos = pos + 1
end
end
end
local Stream = {}
Stream.__index = Stream
function Stream:next(val)
if self._next then
local _next = self._next
self._next = nil
return _next
else
self._next = nil
return self.f()
end
end
function Stream:peek()
if self._next then
return self._next
else
local _next = self.f()
self._next = _next
return _next
end
end
function M.lexc(code, f, pos)
local yield = coroutine.yield
local func = coroutine.wrap(f or function()
M.lex(code, function(tag, name, pos)
yield {tag=tag, name, lineinfo=pos}
end, pos)
yield {tag='Eof'}
end)
return setmetatable({f=func}, Stream)
end
return M

View File

@@ -0,0 +1,303 @@
--[[
lua_parser_loose.lua.
Loose parsing of Lua code. See README.
(c) 2013 David Manura. MIT License.
--]]
local PARSE = {}
local LEX = require 'lua_lexer_loose'
local function warn(message, position)
io.stderr:write('WARNING: ', tostring(position), ': ', message, '\n')
end
--[[
Loose parser.
lx - lexer stream of Lua tokens.
f(event...) - callback function to send events to.
Events generated:
'Var', name, lineinfo - variable declaration that immediately comes into scope.
'VarSelf', name, lineinfo - same as 'Var' but for implicit 'self' parameter
in method definitions. lineinfo is zero-width space after '('
'VarNext', name, lineinfo - variable definition that comes into scope
upon next statement.
'VarInside', name, lineinfo - variable definition that comes into scope
inside following block. Used for control variables in 'for' statements.
'Id', name, lineinfo - reference to variable.
'String', name - string or table field.
'Scope', opt - beginning of scope block.
'EndScope', nil, lineinfo - end of scope block.
'FunctionCall', name, lineinfo - function call (in addition to other events).
--]]
function PARSE.parse_scope(lx, f, level)
local cprev = {tag='Eof'}
-- stack of scopes.
local scopes = {{}}
for l = 2, (level or 1) do scopes[l] = {} end
local function scope_begin(opt, lineinfo)
scopes[#scopes+1] = {}
f('Scope', opt, lineinfo)
end
local function scope_end(opt, lineinfo)
if #scopes <= 1 then
warn("'end' without opening block", lineinfo)
else
table.remove(scopes)
end
f('EndScope', opt, lineinfo)
end
local function parse_function_list(has_self)
local c = lx:next(); assert(c[1] == '(')
f('Statement', c[1], c.lineinfo) -- generate Statement for function definition
scope_begin(c[1], c.lineinfo)
if has_self then
local lineinfo = c.lineinfo+1 -- zero size
f('VarSelf', 'self', lineinfo)
end
while lx:peek().tag == 'Id' do
local c = lx:next()
f('Var', c[1], c.lineinfo)
if lx:peek()[1] == ',' then lx:next() end
end
if lx:peek()[1] == ')' then lx:next() end
end
while 1 do
local c = lx:next()
-- Detect end of previous statement
if c.tag == 'Eof' -- trigger 'Statement' at the end of file
or c.tag == 'Keyword' and (
c[1] == 'break' or c[1] == 'goto' or c[1] == 'do' or c[1] == 'while' or
c[1] == 'repeat' or c[1] == 'if' or c[1] == 'for' or c[1] == 'function' and lx:peek().tag == 'Id' or
c[1] == 'local' or c[1] == ';' or c[1] == 'until' or c[1] == 'return' or c[1] == 'end') or
c.tag == 'Id' and
(cprev.tag == 'Id' or
cprev.tag == 'Keyword' and
(cprev[1] == ']' or cprev[1] == ')' or cprev[1] == '}' or
cprev[1] == '...' or cprev[1] == 'end' or
cprev[1] == 'true' or cprev[1] == 'false' or
cprev[1] == 'nil') or
cprev.tag == 'Number' or cprev.tag == 'String')
then
if scopes[#scopes].inside_until then scope_end(nil, c.lineinfo) end
f('Statement', c[1], c.lineinfo)
end
if c.tag == 'Eof' then break end
-- Process token(s)
if c.tag == 'Keyword' then
if c[1] == 'local' and lx:peek().tag == 'Keyword' and lx:peek()[1] == 'function' then
-- local function
local c = lx:next(); assert(c[1] == 'function')
if lx:peek().tag == 'Id' then
c = lx:next()
f('Var', c[1], c.lineinfo)
if lx:peek()[1] == '(' then parse_function_list() end
end
elseif c[1] == 'function' then
if lx:peek()[1] == '(' then -- inline function
parse_function_list()
elseif lx:peek().tag == 'Id' then -- function definition statement
c = lx:next(); assert(c.tag == 'Id')
f('Id', c[1], c.lineinfo)
local has_self
while lx:peek()[1] ~= '(' and lx:peek().tag ~= 'Eof' do
c = lx:next()
if c.tag == 'Id' then
f('String', c[1], c.lineinfo)
elseif c.tag == 'Keyword' and c[1] == ':' then
has_self = true
end
end
if lx:peek()[1] == '(' then parse_function_list(has_self) end
end
elseif c[1] == 'local' and lx:peek().tag == 'Id' then
c = lx:next()
f('VarNext', c[1], c.lineinfo)
while lx:peek().tag == 'Keyword' and lx:peek()[1] == ',' do
c = lx:next(); if lx:peek().tag ~= 'Id' then break end
c = lx:next()
f('VarNext', c[1], c.lineinfo)
end
elseif c[1] == 'for' and lx:peek().tag == 'Id' then
c = lx:next()
f('VarInside', c[1], c.lineinfo)
while lx:peek().tag == 'Keyword' and lx:peek()[1] == ',' do
c = lx:next(); if lx:peek().tag ~= 'Id' then break end
c = lx:next()
f('VarInside', c[1], c.lineinfo)
end
elseif c[1] == 'do' then
scope_begin('do', c.lineinfo)
-- note: do/while/for statement scopes all begin at 'do'.
elseif c[1] == 'repeat' or c[1] == 'then' then
scope_begin(c[1], c.lineinfo)
elseif c[1] == 'end' or c[1] == 'elseif' then
scope_end(c[1], c.lineinfo)
elseif c[1] == 'else' then
scope_end(nil, c.lineinfo)
scope_begin(c[1], c.lineinfo)
elseif c[1] == 'until' then
scopes[#scopes].inside_until = true
elseif c[1] == '{' then
scopes[#scopes].inside_table = (scopes[#scopes].inside_table or 0) + 1
elseif c[1] == '}' then
local newval = (scopes[#scopes].inside_table or 0) - 1
newval = newval >= 1 and newval or nil
scopes[#scopes].inside_table = newval
end
elseif c.tag == 'Id' then
local cnext = lx:peek()
if cnext.tag == 'Keyword' and (cnext[1] == '(' or cnext[1] == '{')
or cnext.tag == 'String' then
f('FunctionCall', c[1], c.lineinfo)
end
if scopes[#scopes].inside_table and cnext.tag == 'Keyword' and cnext[1] == '=' then
-- table field
f('String', c[1], c.lineinfo)
elseif cprev.tag == 'Keyword' and (cprev[1] == ':' or cprev[1] == '.') then
f('String', c[1], c.lineinfo)
else
f('Id', c[1], c.lineinfo)
end
end
if c.tag ~= 'Comment' then cprev = c end
end
end
--[[
This is similar to parse_scope but determines if variables are local or global.
lx - lexer stream of Lua tokens.
f(event...) - callback function to send events to.
Events generated:
'Id', name, lineinfo, 'local'|'global'
(plus all events in parse_scope)
--]]
function PARSE.parse_scope_resolve(lx, f, vars)
local NEXT = {} -- unique key
local INSIDE = {} -- unique key
local function newscope(vars, opt, lineinfo)
local newvars = opt=='do' and vars[INSIDE] or {}
if newvars == vars[INSIDE] then vars[INSIDE] = false end
newvars[INSIDE]=false
newvars[NEXT]=false
local level = (vars[0] or 0) + 1
newvars[0] = level -- keep the current level
newvars[-1] = lineinfo -- keep the start of the scope
newvars[level] = newvars -- reference the current vars table
return setmetatable(newvars, {__index=vars})
end
vars = vars or newscope({[0] = 0}, nil, 1)
vars[NEXT] = false -- vars that come into scope upon next statement
vars[INSIDE] = false -- vars that come into scope upon entering block
PARSE.parse_scope(lx, function(op, name, lineinfo)
-- in some (rare) cases VarNext can follow Statement event (which copies
-- vars[NEXT]). This may cause vars[0] to be `nil`, so default to 1.
local var = op:find("^Var") and
{fpos = lineinfo, at = (vars[0] or 1) + (op == 'VarInside' and 1 or 0),
masked = vars[name], self = (op == 'VarSelf') or nil } or nil
if op == 'Var' or op == 'VarSelf' then
vars[name] = var
elseif op == 'VarNext' then
vars[NEXT] = vars[NEXT] or {}
vars[NEXT][name] = var
elseif op == 'VarInside' then
vars[INSIDE] = vars[INSIDE] or {}
vars[INSIDE][name] = var
elseif op == 'Scope' then
vars = newscope(vars, name, lineinfo)
elseif op == 'EndScope' then
local mt = getmetatable(vars)
if mt == nil then
warn("'end' without opening block.", lineinfo)
else
vars = mt.__index
end
elseif op == 'Id' then
-- Just make callback
elseif op == 'String' or op == 'FunctionCall' then
-- Just make callback
elseif op == 'Statement' then -- beginning of statement
-- Apply vars that come into scope upon beginning of statement.
if vars[NEXT] then
for k,v in pairs(vars[NEXT]) do
vars[k] = v; vars[NEXT][k] = nil
end
end
else
assert(false)
end
f(op, name, lineinfo, vars)
end, vars[0])
end
function PARSE.extract_vars(code, f)
local lx = LEX.lexc(code)
local char0 = 1 -- next char offset to write
local function gen(char1, nextchar0)
char0 = nextchar0
end
PARSE.parse_scope_resolve(lx, function(op, name, lineinfo, other)
if op == 'Id' then
f('Id', name, other, lineinfo)
elseif op == 'Var' or op == 'VarNext' or op == 'VarInside' then
gen(lineinfo, lineinfo+#name)
f('Var', name, "local", lineinfo)
end -- ignore 'VarSelf' and others
end)
gen(#code+1, nil)
end
--[[
Converts 5.2 code to 5.1 style code with explicit _ENV variables.
Example: "function f(_ENV, x) print(x, y)" -->
"function _ENV.f(_ENV, x) _ENV.print(x, _ENV.y) end"
code - string of Lua code. Assumed to be valid Lua (FIX: 5.1 or 5.2?)
f(s) - call back function to send chunks of Lua code output to. Example: io.stdout.
--]]
function PARSE.replace_env(code, f)
if not f then return PARSE.accumulate(PARSE.replace_env, code) end
PARSE.extract_vars(code, function(op, name, other)
if op == 'Id' then
f(other == 'global' and '_ENV.' .. name or name)
elseif op == 'Var' or op == 'Other' then
f(name)
end
end)
end
-- helper function. Can be passed as argument `f` to functions
-- like `replace_env` above to accumulate fragments into a single string.
function PARSE.accumulator()
local ts = {}
local mt = {}
mt.__index = mt
function mt:__call(s) ts[#ts+1] = s end
function mt:result() return table.concat(ts) end
return setmetatable({}, mt)
end
-- helper function
function PARSE.accumulate(g, code)
local accum = PARSE.accumulator()
g(code, accum)
return accum:result()
end
return PARSE

View File

@@ -1,12 +1,12 @@
--
-- MobDebug 0.526
-- MobDebug 0.5401
-- Copyright 2011-13 Paul Kulchenko
-- Based on RemDebug 1.0 Copyright Kepler Project 2005
--
local mobdebug = {
_NAME = "mobdebug",
_VERSION = 0.526,
_VERSION = 0.5401,
_COPYRIGHT = "Paul Kulchenko",
_DESCRIPTION = "Mobile Remote Debugger for the Lua programming language",
port = os and os.getenv and os.getenv("MOBDEBUG_PORT") or 8172,
@@ -26,6 +26,8 @@ local require = require
local setmetatable = setmetatable
local string = string
local tonumber = tonumber
local unpack = table.unpack or unpack
local rawget = rawget
-- if strict.lua is used, then need to avoid referencing some global
-- variables, as they can be undefined;
@@ -103,7 +105,7 @@ end
local function q(s) return s:gsub('([%(%)%.%%%+%-%*%?%[%^%$%]])','%%%1') end
local serpent = (function() ---- include Serpent module for serialization
local n, v = "serpent", 0.23 -- (C) 2012-13 Paul Kulchenko; MIT License
local n, v = "serpent", 0.24 -- (C) 2012-13 Paul Kulchenko; MIT License
local c, d = "Paul Kulchenko", "Lua serializer and pretty printer"
local snum = {[tostring(1/0)]='1/0 --[[math.huge]]',[tostring(-1/0)]='-1/0 --[[-math.huge]]',[tostring(0/0)]='0/0'}
local badtype = {thread = true, userdata = true, cdata = true}
@@ -151,7 +153,7 @@ local function s(t, opts)
if seen[t] then -- already seen this element
table.insert(sref, spath..space..'='..space..seen[t])
return tag..'nil'..comment('ref', level) end
if mt and (mt.__serialize or mt.__tostring) then -- knows how to serialize itself
if type(mt) == 'table' and (mt.__serialize or mt.__tostring) then -- knows how to serialize itself
seen[t] = insref or spath
if mt.__serialize then t = mt.__serialize(t) else t = tostring(t) end
ttype = type(t) end -- new value falls through to be serialized
@@ -161,7 +163,7 @@ local function s(t, opts)
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
for key in pairs(t) do if not o[key] or key > maxn then table.insert(o, key) end end
if opts.sortkeys then alphanumsort(o, t, opts.sortkeys) end
for n, key in ipairs(o) do
local value, ktype, plainindex = t[key], type(key), n <= maxn and not sparse
@@ -277,9 +279,9 @@ local function remove_breakpoint(file, line)
if breakpoints[line] then breakpoints[line][file] = nil end
end
-- this file name is already converted to lower case on windows.
local function has_breakpoint(file, line)
return breakpoints[line] and breakpoints[line][file]
return breakpoints[line]
and breakpoints[line][iscasepreserving and string.lower(file) or file]
end
local function restore_vars(vars)
@@ -302,7 +304,9 @@ local function restore_vars(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
if string.sub(name, 1, 1) ~= '(' then
debug.setlocal(3, i, rawget(vars, name))
end
written_vars[name] = true
end
i = i - 1
@@ -314,7 +318,9 @@ local function restore_vars(vars)
local name = debug.getupvalue(func, i)
if not name then break end
if not written_vars[name] then
if string.sub(name, 1, 1) ~= '(' then debug.setupvalue(func, i, vars[name]) end
if string.sub(name, 1, 1) ~= '(' then
debug.setupvalue(func, i, rawget(vars, name))
end
written_vars[name] = true
end
i = i + 1
@@ -338,6 +344,13 @@ local function capture_vars(level)
if string.sub(name, 1, 1) ~= '(' then vars[name] = value end
i = i + 1
end
-- returned 'vars' table plays a dual role: (1) it captures local values
-- and upvalues to be restored later (in case they are modified in "eval"),
-- and (2) it provides an environment for evaluated chunks.
-- getfenv(func) is needed to provide proper environment for functions,
-- including access to globals, but this causes vars[name] to fail in
-- restore_vars on local variables or upvalues with `nil` values when
-- 'strict' is in effect. To avoid this `rawget` is used in restore_vars.
setmetatable(vars, { __index = getfenv(func), __newindex = getfenv(func) })
return vars
end
@@ -446,23 +459,27 @@ local function debug_hook(event, line)
local file = lastfile
if (lastsource ~= caller.source) then
file, lastsource = caller.source, caller.source
-- the easiest/fastest way would be to check for file names starting
-- with '@', but users can supply names that may not use '@',
-- technically, users can supply names that may not use '@',
-- for example when they call loadstring('...', 'filename.lua').
-- so we handle all sources as filenames
file = file:gsub("^@", ""):gsub("\\", "/")
-- need this conversion to be applied to relative and absolute
-- file names as you may write "require 'Foo'" to
-- load "foo.lua" (on a case insensitive file system) and breakpoints
-- set on foo.lua will not work if not converted to the same case.
if iscasepreserving then file = string.lower(file) end
if file:find("%./") == 1 then file = file:sub(3)
else file = file:gsub('^'..q(basedir), '') end
-- fix filenames for loaded strings that may contain scripts with newlines;
-- some filesystems may allow "\n" in filenames, which is not supported here.
if file:find("\n") then
file = file:gsub("\n", ' '):sub(1, 32) -- limit to 32 chars
-- Unfortunately, there is no reliable/quick way to figure out
-- what is the filename and what is the source code.
-- The following will work if the supplied filename uses Unix path.
if file:find("^@") then
file = file:gsub("^@", ""):gsub("\\", "/")
-- need this conversion to be applied to relative and absolute
-- file names as you may write "require 'Foo'" to
-- load "foo.lua" (on a case insensitive file system) and breakpoints
-- set on foo.lua will not work if not converted to the same case.
if iscasepreserving then file = string.lower(file) end
if file:find("%./") == 1 then file = file:sub(3)
else file = file:gsub('^'..q(basedir), '') end
-- some file systems allow newlines in file names; remove these.
file = file:gsub("\n", ' ')
else
-- this is either a file name coming from loadstring("chunk", "file"),
-- or the actual source code that needs to be serialized (as it may
-- include newlines); assume it's a file name if it's all on one line.
file = file:find("[\r\n]") and serpent.line(file) or file
end
-- set to true if we got here; this only needs to be done once per
@@ -513,7 +530,7 @@ local function debug_hook(event, line)
-- 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
if abort == nil and res == "exit" then os.exit(1); return 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
@@ -643,7 +660,8 @@ local function debugger_loop(sev, svars, sfile, sline)
server:send("200 OK 0\n")
coroutine.yield("load")
else
local chunk = server:receive(size)
-- receiving 0 bytes blocks (at least in luasocket 2.0.2), so skip reading
local chunk = size == 0 and "" or server:receive(size)
if chunk then -- LOAD a new script for debugging
local func, res = loadstring(chunk, "@"..name)
if func then
@@ -808,13 +826,18 @@ local function isrunning()
return coro_debugger and coroutine.status(coro_debugger) == 'suspended'
end
local lasthost, lastport
-- Starts a debug session by connecting to a controller
local function start(controller_host, controller_port)
-- only one debugging session can be run (as there is only one debug hook)
if isrunning() then return end
controller_host = controller_host or "localhost"
controller_port = controller_port or mobdebug.port
lasthost = controller_host or lasthost
lastport = controller_port or lastport
controller_host = lasthost or "localhost"
controller_port = lastport or mobdebug.port
server = (socket.connect4 or socket.connect)(controller_host, controller_port)
if server then
@@ -849,6 +872,7 @@ local function start(controller_host, controller_port)
end
coro_debugger = coroutine.create(debugger_loop)
debug.sethook(debug_hook, "lcr")
seen_hook = nil -- reset in case the last start() call was refused
step_into = true -- start with step command
return true
else
@@ -860,8 +884,11 @@ local function controller(controller_host, controller_port, scratchpad)
-- only one debugging session can be run (as there is only one debug hook)
if isrunning() then return end
controller_host = controller_host or "localhost"
controller_port = controller_port or mobdebug.port
lasthost = controller_host or lasthost
lastport = controller_port or lastport
controller_host = lasthost or "localhost"
controller_port = lastport or mobdebug.port
local exitonerror = not scratchpad
server = (socket.connect4 or socket.connect)(controller_host, controller_port)
@@ -1009,8 +1036,11 @@ local function handle(params, client, options)
elseif command == "setb" then
_, _, _, file, line = string.find(params, "^([a-z]+)%s+(.-)%s+(%d+)%s*$")
if file and line then
file = string.gsub(file, "\\", "/") -- convert slash
file = removebasedir(file, basedir)
-- if this is a file name, and not a file source
if not file:find('^".*"$') then
file = string.gsub(file, "\\", "/") -- convert slash
file = removebasedir(file, basedir)
end
client:send("SETB " .. file .. " " .. line .. "\n")
if client:receive() == "200 OK" then
set_breakpoint(file, line)
@@ -1044,8 +1074,11 @@ local function handle(params, client, options)
elseif command == "delb" then
_, _, _, file, line = string.find(params, "^([a-z]+)%s+(.-)%s+(%d+)%s*$")
if file and line then
file = string.gsub(file, "\\", "/") -- convert slash
file = removebasedir(file, basedir)
-- if this is a file name, and not a file source
if not file:find('^".*"$') then
file = string.gsub(file, "\\", "/") -- convert slash
file = removebasedir(file, basedir)
end
client:send("DELB " .. file .. " " .. line .. "\n")
if client:receive() == "200 OK" then
remove_breakpoint(file, line)
@@ -1123,7 +1156,7 @@ local function handle(params, client, options)
local file = string.gsub(exp, "\\", "/") -- convert slash
file = removebasedir(file, basedir)
client:send("LOAD " .. #lines .. " " .. file .. "\n")
client:send(lines)
if #lines > 0 then client:send(lines) end
end
while true do
local params, err = client:receive()
@@ -1150,7 +1183,7 @@ local function handle(params, client, options)
print("Error in processing results: " .. err)
return nil, nil, "Error in processing results: " .. err
end
print((table.unpack or unpack)(res))
print(unpack(res))
return res[1], res
end
elseif status == "201" then
@@ -1372,6 +1405,10 @@ local function done()
debug.sethook()
server:close()
coro_debugger = nil -- to make sure isrunning() returns `false`
seen_hook = nil -- to make sure that the next start() call works
abort = nil -- to make sure that callback calls use proper "abort" value
end
-- make public functions available

118
packages/sample.lua Normal file
View File

@@ -0,0 +1,118 @@
local G = ...
local id = G.ID("sample.samplemenu")
local P = {
name = "Sample plugin",
description = "Sample plugin to demonstrate various event types.",
author = "Paul Kulchenko",
}
-- Events that are marked with "return false" can return `false` to
-- abort further processing.
-- For `onEditorPreSave` event it means that file saving will be aborted.
-- For `onEditorKeyDown` event it means that the key will be "eaten".
-- For `onEditorCharAdded` event it means that no further processing is done
-- (but the character is still added to the editor).
local events = {
onRegister = function(self) end,
onUnRegister = function(self) end,
onEditorLoad = function(self, editor) end,
onEditorClose = function(self, editor) end,
onEditorNew = function(self, editor) end,
onEditorPreSave = function(self, editor, filepath) end, -- return false
onEditorSave = function(self, editor) end,
onEditorFocusLost = function(self, editor) end,
onEditorFocusSet = function(self, editor) end,
onEditorKeyDown = function(self, editor, event) end, -- return false
onEditorCharAdded = function(self, editor, event) end, -- return false
onMenuEditor = function(self, menu, editor, event) end,
onMenuEditorTab = function(self, menu, notebook, event) end,
onMenuFiletree = function(self, menu, tree, event) end,
onProjectLoad = function(self, project) end,
onProjectClose = function(self, project) end,
onInterpreterLoad = function(self, interpreter) end,
onInterpreterClose = function(self, interpreter) end,
onIdleOnce = function(self, event) end,
onAppFocusLost = function(self, app) end,
onAppFocusSet = function(self, app) end,
onAppLoad = function(self, app) end,
onAppClose = function(self, app) end,
}
--[[ Uncomment this to see event names printed in the Output window
for k in pairs(events) do
if k:find("^on") then
P[k] = k:find("^onEditor")
and function(self, ed)
-- document can be empty for newly added documents
local doc = ide:GetDocument(ed)
DisplayOutputLn(self:GetFileName(), k, doc and doc:GetFilePath() or "new document") end
or function(self, ...)
DisplayOutputLn(self:GetFileName(), k, ...) end
end
end
P.onMenuEditor = function(self, menu, editor, event)
local point = editor:ScreenToClient(event:GetPosition())
pos = editor:PositionFromPointClose(point.x, point.y)
menu:Append(id, ">> Sample item; pos "..pos)
menu:Enable(id, true)
editor:Connect(id, wx.wxEVT_COMMAND_MENU_SELECTED,
function() DisplayOutputLn("Selected "..pos) end)
DisplayOutputLn(self:GetFileName(), "onMenuEditor")
end
P.onMenuEditorTab = function(self, menu, notebook, event)
local index = event:GetSelection()
menu:Append(id, ">> Sample item; tab "..index)
menu:Enable(id, true)
notebook:Connect(id, wx.wxEVT_COMMAND_MENU_SELECTED,
function() DisplayOutputLn("Selected "..index) end)
DisplayOutputLn(self:GetFileName(), "onMenuEditorTab")
end
P.onMenuFiletree = function(self, menu, tree, event)
local item_id = event:GetItem()
local name = tree:GetItemFullName(item_id)
menu:Append(id, ">> Sample item; name "..name)
menu:Enable(id, true)
tree:Connect(id, wx.wxEVT_COMMAND_MENU_SELECTED,
function() DisplayOutputLn("Selected "..name) end)
DisplayOutputLn(self:GetFileName(), "onMenuFiletree")
end
P.onInterpreterLoad = function(self, interpreter)
DisplayOutputLn(self:GetFileName(), "onInterpreterLoad", interpreter:GetFileName())
end
P.onInterpreterClose = function(self, interpreter)
DisplayOutputLn(self:GetFileName(), "onInterpreterClose", interpreter:GetFileName())
end
P.onEditorPreSave = function(self, editor, filepath)
if filepath:find("%.txt$") then
DisplayOutputLn(self:GetFileName(), "onEditorPreSave", "Aborted saving a .txt file")
return false
else
DisplayOutputLn(self:GetFileName(), "onEditorPreSave", filepath)
end
end
P.onEditorCharAdded = function(self, editor, event)
DisplayOutputLn(self:GetFileName(), "onEditorCharAdded", event:GetKey())
end
P.onEditorKeyDown = function(self, editor, event)
DisplayOutputLn(self:GetFileName(), "onEditorKeyDown", event:GetKeyCode())
end
--]]
return P

View File

@@ -43,6 +43,18 @@ return {
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
float16_t f16vec2 f16vec3 f16vec4
float32_t f32vec2 f32vec3 f32vec4
float64_t f64vec2 f64vec3 f64vec4
int8_t i8vec2 i8vec3 i8vec4
int8_t i8vec2 i8vec3 i8vec4
int16_t i16vec2 i16vec3 i16vec4
int32_t i32vec2 i32vec3 i32vec4
int64_t i64vec2 i64vec3 i64vec4
uint8_t u8vec2 u8vec3 u8vec4
uint16_t u16vec2 u16vec3 u16vec4
uint32_t u32vec2 u32vec3 u32vec4
uint64_t u64vec2 u64vec3 u64vec4
struct typedef void
usampler1D usampler2D usampler3D usampler2DRect usamplerCube isampler1DArray usampler2DARRAY usamplerCubeArray usampler2DMS usampler2DMSArray
isampler1D isampler2D isampler3D isampler2DRect isamplerCube isampler1DArray isampler2DARRAY isamplerCubeArray isampler2DMS isampler2DMSArray
@@ -51,10 +63,10 @@ return {
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
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
invocations offset align xfb_offset xfb_buffer
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
@@ -70,6 +82,7 @@ return {
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
gl_BaseVertexARB gl_BaseInstanceARB gl_DrawIDARB
coherent volatile restrict readonly writeonly
image1D image2D image3D image2DRect imageCube imageBuffer image1DArray image2DArray imageCubeArray image2DMS image2DMSArray
@@ -88,6 +101,10 @@ return {
packUnorm2x16 packUnorm4x8 packSnorm4x8
unpackUnorm2x16 unpackUnorm4x8 unpackSnorm4x8
packDouble2x32 unpackDouble2x32 packHalf2x16 unpackHalf2x16
packInt2x32 packUint2x32 unpackInt2x32 unpackUint2x32
packFloat2x16 unpackFloat2x16 doubleBitsToInt64
doubleBitsToUint64 int64BitsToDouble uint64BitsToDouble
length distance dot cross normalize ftransform faceforward
reflect refract
matrixCompMult outerProduct transpose determinant inverse
@@ -140,6 +157,8 @@ return {
atomicCounterIncrement atomicCounterDecrement atomicCounter
atomicMin atomicMax atomicAdd atomicAnd atomicOr atomicXor atomicExchange atomicCompSwap
anyInvocationARB allInvocationsARB allInvocationsEqualARB
x y z w
xxxx xxxy xxxz xxxw xxyx xxyy xxyz xxyw xxzx xxzy

View File

@@ -49,16 +49,44 @@ return {
return match and 1 or 0, match and term and 1 or 0
end,
isincindent = function(str)
local term = str:match("^%s*(%w+)[^%w]*")
local term = str:match("^%s*(%w+)%W*")
term = term and incindent[term] and 1 or 0
str = str:gsub("'.-'",""):gsub('".-"','')
local _, opened = str:gsub("([%{%(])", "%1")
local _, closed = str:gsub("([%}%)])", "%1")
local func = (isfndef(str) or str:match("[^%w]+function%s*%(")) and 1 or 0
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
local anon = str:match("%W+function%s*%(.+%Wend%W")
local ended = (term + func > 0) and (str:match("%W+end%s*$") or anon) and 1 or 0
return opened - closed + func + term - ended
end,
markvars = function(code, pos, vars)
local PARSE = require 'lua_parser_loose'
local LEX = require 'lua_lexer_loose'
local lx = LEX.lexc(code, nil, pos)
return coroutine.wrap(function()
local varnext = {}
PARSE.parse_scope_resolve(lx, function(op, name, lineinfo, vars)
if not(op == 'Id' or op == 'Statement' or op == 'Var'
or op == 'VarNext' or op == 'VarInside' or op == 'VarSelf'
or op == 'FunctionCall' or op == 'Scope' or op == 'EndScope') then
return end -- "normal" return; not interested in other events
-- level needs to be adjusted for VarInside as it comes into scope
-- only after next block statement
local at = vars[0] and (vars[0] + (op == 'VarInside' and 1 or 0))
if op == 'Statement' then
for _, token in pairs(varnext) do coroutine.yield(unpack(token)) end
varnext = {}
elseif op == 'VarNext' or op == 'VarInside' then
table.insert(varnext, {'Var', name, lineinfo, vars, at})
end
coroutine.yield(op, name, lineinfo, vars, at)
end, vars)
end)
end,
typeassigns = function(editor)
local line = editor:GetCurrentLine()
@@ -115,13 +143,21 @@ return {
var = var and var:gsub("local","")
var = var and var:gsub("%s","")
typ = typ and typ:gsub("%b[]","")
typ = typ and typ:gsub("%b()","")
typ = typ and typ:gsub("%b{}","")
typ = typ and typ
:gsub("%b()","")
:gsub("%b{}","")
:gsub("%b[]",".0")
-- remove comments; they may be in strings, but that's okay here
:gsub("%-%-.*","")
if (typ and (typ:match(",") or typ:match("%sor%s") or typ:match("%sand%s"))) then
typ = nil
end
typ = typ and typ:gsub("%s","")
typ = typ and typ:gsub(".+", function(s)
return (s:find("^'[^']*'$")
or s:find('^"[^"]*"$')
or s:find('^%[=*%[.*%]=*%]$')) and 'string' or s
end)
if (var and typ) then
class,func = typ:match(varname.."[%.:]"..varname)
if (assigns[typ]) then

View File

@@ -100,17 +100,21 @@ config = {
calltipdelay = nil, -- delay to show calltip (in ms)
autoactivate = false, -- auto-activate/open files during debugging
smartindent = false, -- use smart indentation if spec allows
fold = true, -- enable code folding
foldcompact = true, -- use compact fold that includes empty lines
checkeol = true, -- check for eol encoding on loaded files and use it
-- also report mixed eol encodings
defaulteol = nil, -- default line-endings for new files; valid values are
-- wxstc.wxSTC_EOL_CRLF, wxstc.wxSTC_EOL_LF and nil (OS default)
nomousezoom = nil, -- disable zooming using mouse wheel
autoreload = nil, -- trigger auto-reload when file is updated
saveallonrun = nil, -- save all modified files before Run/Debug
},
default = {
name = 'untitled',
fullname = 'untitled.lua',
interpreter = 'luadeb',
},
debugger = {
@@ -119,6 +123,7 @@ config = {
port = nil, -- port number to use
runonstart = nil, -- if debugger should run immediately after starting
-- default values are different for different interpreters
redirect = nil, -- "d", "c", or "r" values for default, copy, or redirect
}
outputshell = { -- output and shell settings
@@ -141,6 +146,7 @@ config = {
interpreter = "luadeb", -- the default "project" lua interpreter
autocomplete = true, -- whether autocomplete is on by default
autoanalizer = true, -- whether auto syntax analizer is on by default
acandtip = {
shorttip = false, -- tooltips are compact during typing
@@ -168,6 +174,7 @@ config = {
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
hidpi = false, -- HiDPI/Retina display support
}
-- application engine

View File

@@ -36,54 +36,70 @@ local apis = {
lua = newAPI(),
}
function GetApi(apitype)
return apis[apitype] or apis["none"]
end
function GetApi(apitype) return apis[apitype] or apis.none end
----------
-- API loading
local function addAPI(apifile,only,subapis,known) -- relative to API directory
local ftype, fname = apifile:match("api[/\\]([^/\\]+)[/\\](.*)%.")
if not ftype or not fname then
DisplayOutputLn(TR("The API file must be located in a subdirectory of the API directory."))
return
end
if ((only and ftype ~= only) or (known and not known[ftype])) then
return
end
if (subapis and not subapis[fname]) then return end
local fn,err = loadfile(apifile)
if err then
DisplayOutputLn(TR("Error while loading API file: %s"):format(err))
return
end
local env = apis[ftype] or newAPI()
apis[ftype] = env
env = env.ac.childs
local suc,res = pcall(function()return fn(env) end)
if (not suc) then
DisplayOutputLn(TR("Error while processing API file: %s"):format(res))
elseif (res) then
local function gennames(tab,prefix)
for i,v in pairs(tab) do
v.classname = (prefix and (prefix..".") or "")..i
if(v.childs) then
gennames(v.childs,v.classname)
end
end
end
gennames(res)
for i,v in pairs(res) do
env[i] = v
local function gennames(tab, prefix)
for i,v in pairs(tab) do
v.classname = (prefix and (prefix..".") or "")..i
if (v.childs) then
gennames(v.childs,v.classname)
end
end
end
local function loadallAPIs (only,subapis,known)
local function addAPI(ftype, fname) -- relative to API directory
local env = apis[ftype] or newAPI()
local res
local api = ide.apis[ftype][fname]
if type(api) == 'table' then
res = api
else
local fn, err = loadfile(api)
if err then
DisplayOutputLn(TR("Error while loading API file: %s"):format(err))
return
end
local suc
suc, res = pcall(function() return fn(env.ac.childs) end)
if (not suc) then
DisplayOutputLn(TR("Error while processing API file: %s"):format(res))
return
end
-- cache the result
ide.apis[ftype][fname] = res
end
apis[ftype] = env
gennames(res)
for i,v in pairs(res) do env.ac.childs[i] = v end
end
local function loadallAPIs(only, subapis, known)
for ftype, v in pairs(only and {[only] = ide.apis[only]} or ide.apis) do
if (not known or known[ftype]) then
for fname in pairs(v) do
if (not subapis or subapis[fname]) then addAPI(ftype, fname) end
end
end
end
end
local function scanAPIs()
for _, file in ipairs(FileSysGetRecursive("api", true, "*.lua")) do
if not file:match(string_Pathsep.."$") then addAPI(file,only,subapis,known) end
if not IsDirectory(file) then
local ftype, fname = file:match("api[/\\]([^/\\]+)[/\\](.*)%.")
if not ftype or not fname then
DisplayOutputLn(TR("The API file must be located in a subdirectory of the API directory."))
return
end
ide.apis[ftype] = ide.apis[ftype] or {}
ide.apis[ftype][fname] = file
end
end
end
@@ -115,7 +131,7 @@ local function fillTips(api,apibasename,apiname)
if not tab.childs then return end
for key,info in pairs(tab.childs) do
traverse(info,key)
if info.type == "function" or info.type == "method" then
if info.type == "function" or info.type == "method" or info.type == "value" then
local libstr = libname ~= "" and libname.."." or ""
-- fix description
@@ -125,15 +141,17 @@ local function fillTips(api,apibasename,apiname)
:gsub("\t","")
:gsub("("..widthmask..")[ \t]([^%)])","%1\n %2")
info.description = info.description
info.description = (info.description or "")
:gsub("\n\n","<br>"):gsub("\n"," "):gsub("<br>","\n")
:gsub("[ \t]+"," ")
:gsub("("..widthmask..") ","%1\n")
-- build info
local inf = frontname.."\n"..info.description
local inf = (info.type == "value" and "" or frontname.."\n")
..info.description
local sentence = info.description:match("^(.-)%. ?\n")
local infshort = frontname.."\n"..(sentence and sentence.."..." or info.description)
local infshort = (info.type == "value" and "" or frontname.."\n")
..(sentence and sentence.."..." or info.description)
local infshortbatch = (info.returns and info.args) and frontname or infshort
-- add to infoclass
@@ -193,6 +211,7 @@ local function resolveAssign(editor,tx)
local assigns = editor.assignscache and editor.assignscache.assigns
local function getclass(tab,a)
local key,rest = a:match("([%w_]+)[%.:](.*)")
key = tonumber(key) or key -- make this work for childs[0]
if (key and rest and tab.childs and tab.childs[key]) then
return getclass(tab.childs[key],rest)
end
@@ -216,15 +235,18 @@ local function resolveAssign(editor,tx)
-- this can happen if it's a reference to a value with a known type
classname = classname or assigns[c..w]
if (s ~= "" and old ~= classname) then
-- continue checking unless this can lead to recursive substitution
change = not classname:find("^"..w) and not classname:find("^"..c..w)
c = classname..s
change = true
else
c = c..w..s
end
end
-- abort if the same value is returned; no need to continue.
-- this can happen after typing "smth = smth:new(); smth:"
if tx == c then break end
-- abort if the same or recursive value is returned; no need to continue.
-- this can happen after typing "smth = smth:new(); smth:" or
-- "line = line:gsub(...); line:" as the current algorithm attempts to
-- replace "line" with the value that also includes "line"
if change and c:find("^"..(tx:gsub("[.:]","[.:]"))) then break end
tx = c
end
else
@@ -235,22 +257,33 @@ local function resolveAssign(editor,tx)
return getclass(ac,c)
end
function GetTipInfo(editor, content, short)
local caller = content:match("([%w_]+)%(%s*$")
local class = caller and content:match("([%w_]+)[%.:]"..caller.."%(%s*$") or ""
function GetTipInfo(editor, content, short, fullmatch)
if not content then return end
UpdateAssignCache(editor)
-- try to resolve the class
content = content:gsub("%b[]",".0")
local tab, rest = resolveAssign(editor, content)
local caller = content:match("([%w_]+)%(?%s*$")
local class = (tab and tab.classname
or caller and content:match("([%w_]+)[%.:]"..caller.."%(?%s*$") or "")
local tip = editor.api.tip
local classtab = short and tip.shortfinfoclass or tip.finfoclass
local funcstab = short and tip.shortfinfo or tip.finfo
UpdateAssignCache(editor)
if (editor.assignscache and not (class and classtab[class])) then
local assigns = editor.assignscache.assigns
class = assigns and assigns[class] or class
end
return caller and (class and classtab[class]) and classtab[class][caller] or funcstab[caller]
local res = (caller and (class and classtab[class]) and classtab[class][caller]
or (not fullmatch and funcstab[caller] or nil))
-- some values may not have descriptions (for example, true/false);
-- don't return empty strings as they are displayed as empty tooltips.
return res and #res > 0 and res or nil
end
local function reloadAPI(only,subapis)
@@ -282,6 +315,7 @@ do
-- by defaul load every known api except lua
known.lua = false
scanAPIs()
loadallAPIs(nil,nil,known)
generateAPIInfo()
end
@@ -342,11 +376,8 @@ function DynamicWordsReset ()
end
local function getEditorLines(editor,line,numlines)
local tx = ""
for i=0,numlines do
tx = tx..editor:GetLine(line + i)
end
return tx
return editor:GetTextRange(
editor:PositionFromLine(line),editor:PositionFromLine(line+numlines+1))
end
function DynamicWordsAdd(ev,editor,content,line,numlines)
@@ -397,7 +428,8 @@ local function getAutoCompApiList(childs,fragment,method)
for i,v in pairs(childs) do
-- if a:b typed, then value (type == "value") not allowed
-- if a.b typed, then method (type == "method") not allowed
if (method and v.type ~= "value") or (not method and v.type ~= "method") then
if ((method and v.type ~= "value") or (not method and v.type ~= "method"))
and v.type then
wlist = wlist..i.." "
end
end
@@ -429,7 +461,8 @@ local function getAutoCompApiList(childs,fragment,method)
for key,v in pairs(childs) do
-- if a:b typed, then value (type == "value") not allowed
-- if a.b typed, then method (type == "method") not allowed
if (method and v.type ~= "value") or (not method and v.type ~= "method") then
if ((method and v.type ~= "value") or (not method and v.type ~= "method"))
and v.type then
local used = {}
--
local kl = key:lower()
@@ -470,8 +503,9 @@ function CreateAutoCompList(editor,key)
local api = editor.api
local tip = api.tip
local ac = api.ac
local sep = editor.spec.sep
local method = key:match(":[^:%.]*$") ~= nil
local method = key:match(":[^"..sep.."]*$") ~= nil
-- ignore keywords
if tip.keys[key] then return end
@@ -484,7 +518,7 @@ function CreateAutoCompList(editor,key)
if not (progress) then return end
if (tab == ac) then
local _, krest = rest:match("([%w_]+)[:%.]([%w_]+)%s*$")
local _, krest = rest:match("([%w_]+)["..sep.."]([%w_]+)%s*$")
if (krest) then
if (#krest < 3) then return end
tab = tip.finfo
@@ -526,6 +560,27 @@ function CreateAutoCompList(editor,key)
-- list from api
local apilist = getAutoCompApiList(tab.childs or tab,rest,method)
local function addInheritance(tab, apilist, seen)
if not tab.inherits then return end
for base in tab.inherits:gmatch("[%w_"..sep.."]+") do
local tab = ac
-- map "a.b.c" to class hierarchy (a.b.c)
for class in base:gmatch("[%w_]+") do tab = tab.childs[class] end
if tab and not seen[tab] then
seen[tab] = true
for _,v in pairs(getAutoCompApiList(tab.childs,rest,method)) do
table.insert(apilist, v)
end
addInheritance(tab, apilist, seen)
end
end
end
-- handle (multiple) inheritance; add matches from the parent class/lib
addInheritance(tab, apilist, {[tab] = true})
local compstr = ""
if apilist then
if (#rest > 0) then
@@ -566,6 +621,14 @@ function CreateAutoCompList(editor,key)
else
table.sort(apilist)
end
local prev = apilist[#apilist]
for i = #apilist-1,1,-1 do
if prev == apilist[i] then
table.remove(apilist, i+1)
else prev = apilist[i] end
end
compstr = table.concat(apilist," ")
end

View File

@@ -11,11 +11,15 @@ local CURRENT_LINE_MARKER = StylesGetMarker("currentline")
local CURRENT_LINE_MARKER_VALUE = 2^CURRENT_LINE_MARKER
local BREAKPOINT_MARKER = StylesGetMarker("breakpoint")
function NewFile(event)
function NewFile(filename)
filename = filename or ide.config.default.fullname
local editor = CreateEditor()
SetupKeywords(editor, "lua")
local doc = AddEditor(editor, ide.config.default.fullname)
if doc then SetEditorSelection(doc.index) end
SetupKeywords(editor, GetFileExt(filename))
local doc = AddEditor(editor, filename)
if doc then
PackageEventHandle("onEditorNew", editor)
SetEditorSelection(doc.index)
end
return editor
end
@@ -70,9 +74,10 @@ function LoadFile(filePath, editor, file_must_exist, skipselection)
editor:SetText(file_text or "")
-- check the editor as it can be empty if the file has malformed UTF8;
-- skip binary files as they may have any sequences; can't show them anyway.
-- skip binary files with unknown extensions as they may have any sequences;
-- can't show them anyway.
if file_text and #file_text > 0 and #(editor:GetText()) == 0
and not isBinary(file_text) then
and (editor.spec ~= ide.specs.none or not isBinary(file_text)) then
local replacement, invalid = "\022"
file_text, invalid = fixUTF8(file_text, replacement)
if #invalid > 0 then
@@ -127,6 +132,9 @@ function LoadFile(filePath, editor, file_must_exist, skipselection)
openDocuments[id].filePath = filePath
openDocuments[id].fileName = wx.wxFileName(filePath):GetFullName()
openDocuments[id].modTime = GetFileModTime(filePath)
PackageEventHandle("onEditorLoad", editor)
SetDocumentModified(id, false)
-- activate the editor; this is needed for those cases when the editor is
@@ -173,6 +181,11 @@ function SaveFile(editor, filePath)
if not filePath then
return SaveFileAs(editor)
else
-- this event can be aborted
if PackageEventHandle("onEditorPreSave", editor, filePath) == false then
return false
end
if (ide.config.savebak) then FileRename(filePath, filePath..".bak") end
local st = editor:GetText()
@@ -180,6 +193,11 @@ function SaveFile(editor, filePath)
st = GetConfigIOFilter("output")(filePath,st)
end
local file = wx.wxFileName(filePath)
if not file:FileExists() then
file:Mkdir(tonumber(755,8), wx.wxPATH_MKDIR_FULL)
end
local ok, err = FileWrite(filePath, st)
if ok then
editor:SetSavePoint()
@@ -189,6 +207,9 @@ function SaveFile(editor, filePath)
openDocuments[id].modTime = GetFileModTime(filePath)
SetDocumentModified(id, false)
SetAutoRecoveryMark()
PackageEventHandle("onEditorSave", editor)
return true
else
wx.wxMessageBox(TR("Unable to save file '%s': %s"):format(filePath, err),
@@ -203,11 +224,9 @@ end
function SaveFileAs(editor)
local id = editor:GetId()
local saved = false
local filePath = openDocuments[id].filePath
if (not filePath) then
filePath = FileTreeGetDir()
filePath = (filePath or "")..ide.config.default.name
end
local filePath = (openDocuments[id].filePath
or ((FileTreeGetDir() or "")
..(openDocuments[id].fileName or ide.config.default.name)))
local fn = wx.wxFileName(filePath)
fn:Normalize() -- want absolute path for dialog
@@ -231,15 +250,30 @@ function SaveFileAs(editor)
if SaveFile(editor, filePath) then
SetEditorSelection() -- update title of the editor
FileTreeRefresh() -- refresh the tree to reflect the new file
FileTreeMarkSelected(filePath)
if ext ~= GetFileExt(filePath) then
-- new extension, so setup new keywords and re-apply indicators
editor:ClearDocumentStyle() -- remove styles from the document
SetupKeywords(editor, GetFileExt(filePath))
IndicateFunctions(editor)
IndicateAll(editor)
MarkupStyle(editor)
end
saved = true
-- check if there is another tab with the same name and close it
local fileName = wx.wxFileName(filePath)
for _, document in pairs(ide.openDocuments) do
if document.filePath and fileName:SameAs(wx.wxFileName(document.filePath)) then
-- save the current selection as it may change after closing
local current = notebook:GetSelection()
ClosePage(document.index)
-- restore the selection if it changed
if current ~= notebook:GetSelection() then
notebook:SetSelection(current)
end
break
end
end
end
end
@@ -247,12 +281,13 @@ function SaveFileAs(editor)
return saved
end
function SaveAll()
function SaveAll(quiet)
for id, document in pairs(openDocuments) do
local editor = document.editor
local filePath = document.filePath
if document.isModified or not document.filePath then
if (document.isModified or not document.filePath) -- need to save
and (document.filePath or not quiet) then -- have path or can ask user
SaveFile(editor, filePath) -- will call SaveFileAs if necessary
end
end
@@ -317,14 +352,13 @@ function ClosePage(selection)
and debugger.scratchpad.editors[editor] then
DebuggerScratchpadOff()
end
-- check if the debugger is running and is using the current window
-- check if the debugger is running and is using the current window;
-- 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.server and
(debugger.running or editor:MarkerNext(0, CURRENT_LINE_MARKER_VALUE) >= 0) then
(editor:MarkerNext(0, CURRENT_LINE_MARKER_VALUE) >= 0) then
debugger.terminate()
end
PackageEventHandle("onEditorClose", editor)
removePage(ide.openDocuments[id].index)
-- disable full screen if the last tab is closed
@@ -611,7 +645,7 @@ function SetOpenTabs(params)
if doc.content then
notebook:SetPageText(opendoc.index, doc.tabname)
editor:SetText(doc.content)
if doc.filename and doc.modified < opendoc.modTime:GetTicks() then
if doc.filename and opendoc.modTime and doc.modified < opendoc.modTime:GetTicks() then
DisplayOutputLn(TR("File '%s' has more recent timestamp than restored '%s'; please review before saving.")
:format(doc.filename, doc.tabname))
end
@@ -686,11 +720,14 @@ function StoreRestoreProjectTabs(curdir, 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
-- check if the filename is in the same folder
if dpath:find(lowcurdir, 1, true) == 1
and dpath:find("^[\\/]", #lowcurdir+1) 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
if not dpath:find(lownewdir, 1, true)
or not dpath:find("^[\\/]", #lownewdir+1) then
table.insert(closdocs, document)
end
elseif document.id == current then restore = true end
@@ -754,6 +791,8 @@ local function closeWindow(event)
ShowFullScreen(false)
PackageEventHandle("onAppClose")
SettingsSaveAll()
ide.settings:Flush()
@@ -782,6 +821,15 @@ frame:Connect(wx.wxEVT_CLOSE_WINDOW, closeWindow)
frame:Connect(wx.wxEVT_TIMER, saveAutoRecovery)
ide.editorApp:Connect(wx.wxEVT_ACTIVATE_APP,
function(event)
if not ide.exitingProgram then
local event = event:GetActive() and "onAppFocusSet" or "onAppFocusLost"
PackageEventHandle(event, ide.editorApp)
end
event:Skip()
end)
if ide.config.autorecoverinactivity then
ide.session.timer = wx.wxTimer(frame)
-- check at least 5s to be never more than 5s off

View File

@@ -1,5 +1,5 @@
-- Integration with MobDebug
-- Copyright 2011-12 Paul Kulchenko, ZeroBrane LLC
-- Copyright 2011-13 Paul Kulchenko, ZeroBrane LLC
-- Original authors: Lomtik Software (J. Winwood & John Labenski)
-- Luxinia Dev (Eike Decker & Christoph Kubisch)
@@ -17,11 +17,8 @@ debugger.watchCtrl = nil -- the watch ctrl that shows watch information
debugger.stackCtrl = nil -- the stack ctrl that shows stack information
debugger.toggleview = { stackpanel = false, watchpanel = false }
debugger.hostname = ide.config.debugger.hostname or (function()
local addr = wx.wxIPV4address() -- check what address is resolvable
for _, host in ipairs({wx.wxGetHostName(), wx.wxGetFullHostName()}) do
if host and #host > 0 and addr:Hostname(host) then return host end
end
return "localhost" -- last resort; no known good hostname
local hostname = socket.dns.gethostname()
return hostname and socket.dns.toip(hostname) and hostname or "localhost"
end)()
local notebook = ide.frame.notebook
@@ -70,6 +67,7 @@ end
local simpleType = {['nil'] = true, ['string'] = true, ['number'] = true, ['boolean'] = true}
local stackItemValue = {}
local callData = {}
local function checkIfExpandable(value, item)
local expandable = type(value) == 'table' and next(value) ~= nil
and not stackItemValue[value] -- only expand first time
@@ -98,23 +96,38 @@ local function updateStackSync()
local params = {comment = false, nocode = true}
local root = stackCtrl:AddRoot("Stack")
stackItemValue = {} -- reset cache of items in the stack
callData = {} -- reset call cache
for _,frame in ipairs(stack) do
-- "main chunk at line 24"
-- "foo() at line 13 (defined at foobar.lua:11)"
-- call = { source.name, source.source, source.linedefined,
-- source.currentline, source.what, source.namewhat, source.short_src }
local call = frame[1]
-- format the function name to a readable user string
local func = call[5] == "main" and "main chunk"
or call[5] == "C" and (call[1] or "C function")
or call[5] == "tail" and "tail call"
or (call[1] or "anonymous function")
-- format the function treeitem text string, including the function name
local text = func ..
(call[4] == -1 and '' or " at line "..call[4]) ..
(call[5] ~= "main" and call[5] ~= "Lua" and ''
or (call[3] > 0 and " (defined at "..call[2]..":"..call[3]..")"
or " (defined in "..call[2]..")"))
-- create the new tree item for this level of the call stack
local callitem = stackCtrl:AppendItem(root, text, 0)
-- registed call data to added item
callData[callitem:GetValue()] = { call[2], call[4] }
-- add the local variables to the call stack item
for name,val in pairs(frame[2]) do
-- format the variable name, value as a single line and,
-- if not a simple type, the string value.
-- comment can be not necessarily a string for tables with metatables
-- that provide its own __tostring method
local value, comment = val[1], tostring(val[2])
@@ -126,6 +139,8 @@ local function updateStackSync()
stackCtrl:SetItemHasChildren(item, true)
end
end
-- add the upvalues for this call stack level to the tree item
for name,val in pairs(frame[3]) do
local value, comment = val[1], tostring(val[2])
local text = ("%s = %s%s"):
@@ -136,6 +151,7 @@ local function updateStackSync()
stackCtrl:SetItemHasChildren(item, true)
end
end
stackCtrl:SortChildren(callitem)
stackCtrl:Expand(callitem)
end
@@ -204,18 +220,37 @@ end
local function activateDocument(file, line, activatehow)
if not file then return end
if not wx.wxIsAbsolutePath(file) and debugger.basedir then
-- file can be a filename or serialized file content; deserialize first.
-- check if the filename starts with '"' and is deserializable
-- to avoid showing filenames that may look like valid lua code
-- (for example: 'mobdebug.lua').
local content
if not wx.wxFileName(file):FileExists() and file:find('^"') then
local ok, res = LoadSafe("return "..file)
if ok then content = res end
end
-- in some cases filename can be returned quoted if the chunk is loaded with
-- loadstring(chunk, "filename") instead of loadstring(chunk, "@filename")
if content then
-- if the returned content can be matched with a file, it's a file name
local fname = GetFullPathIfExists(debugger.basedir, content) or content
if wx.wxFileName(fname):FileExists() then file, content = fname, nil end
elseif 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
-- 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
for _, document in pairs(ide.openDocuments) do
local editor = document.editor
-- either the file name matches, or the content;
-- when checking for the content remove all newlines as they may be
-- reported differently from the original by the Lua engine.
if document.filePath and fileName:SameAs(wx.wxFileName(document.filePath))
or content and content:gsub("[\n\r]","") == editor:GetText():gsub("[\n\r]","") then
ClearAllCurrentLineMarkers()
if line then
if line == 0 then -- special case; find the first executable line
@@ -249,17 +284,38 @@ local function activateDocument(file, line, activatehow)
notebook:SetSelection(selection)
SetEditorSelection(selection)
if content then
-- it's possible that the current editor tab already has
-- breakpoints that have been set based on its filepath;
-- if the content has been matched, then existing breakpoints
-- need to be removed and new ones set, based on the content.
if not debugger.editormap[editor] and document.filePath then
local filePath = document.filePath
local line = editor:MarkerNext(0, BREAKPOINT_MARKER_VALUE)
while filePath and line ~= -1 do
debugger.handle("delb " .. filePath .. " " .. (line+1))
debugger.handle("setb " .. file .. " " .. (line+1))
line = editor:MarkerNext(line + 1, BREAKPOINT_MARKER_VALUE)
end
end
-- keep track of those editors that have been activated based on
-- content rather than file names as their breakpoints have to be
-- specified in a different way
debugger.editormap[editor] = file
end
activated = editor
break
end
end
if not (activated or indebugger or debugger.loop or activatehow == activate.CHECKONLY)
and ide.config.editor.autoactivate then
and (ide.config.editor.autoactivate or content and activatehow == activate.NOREPORT) then
-- found file, but can't activate yet (because this part may be executed
-- in a different coroutine), so schedule pending activation.
if wx.wxFileName(file):FileExists() then
debugger.activate = {file, line}
if content or wx.wxFileName(file):FileExists() then
debugger.activate = {file, line, content}
return true -- report successful activation, even though it's pending
end
@@ -286,7 +342,7 @@ local function reSetBreakpoints()
local editor = document.editor
local filePath = document.filePath
local line = editor:MarkerNext(0, BREAKPOINT_MARKER_VALUE)
while line ~= -1 do
while filePath and line ~= -1 do
debugger.handle("setb " .. filePath .. " " .. (line+1))
line = editor:MarkerNext(line + 1, BREAKPOINT_MARKER_VALUE)
end
@@ -372,7 +428,11 @@ debugger.listen = function()
end
copas.setErrorHandler(function(error)
DisplayOutputLn(TR("Can't start debugging session due to internal error '%s'."):format(error))
-- ignore errors that happen because debugging session is
-- terminated during handshake (server == nil in this case).
if debugger.server then
DisplayOutputLn(TR("Can't start debugging session due to internal error '%s'."):format(error))
end
debugger.terminate()
end)
@@ -381,7 +441,11 @@ debugger.listen = function()
-- debugger.options may not be set, but runonstart is still configured.
if not options.runstart then options.runstart = ide.config.debugger.runonstart end
if not debugger.scratchpad then SetAllEditorsReadOnly(true) end
-- support allowediting as set in the interpreter or config
if not options.allowediting then options.allowediting = ide.config.debugger.allowediting end
if not debugger.scratchpad and not options.allowediting then
SetAllEditorsReadOnly(true) end
debugger.server = copas.wrap(skt)
debugger.socket = skt
@@ -389,6 +453,7 @@ debugger.listen = function()
debugger.scratchable = false
debugger.stats = {line = 0}
debugger.missing = {}
debugger.editormap = {}
local wxfilepath = GetEditorFileAndCurInfo()
local startfile = options.startfile or options.startwith
@@ -411,11 +476,10 @@ debugger.listen = function()
reSetBreakpoints()
if options.redirect then
debugger.handle("output stdout " .. options.redirect, nil,
local redirect = ide.config.debugger.redirect or options.redirect
if redirect then
debugger.handle("output stdout " .. redirect, nil,
{ handler = function(m)
if not debugger.server then return end
-- if it's an error returned, then handle the error
if m and m:find("stack traceback:", 1, true) then
-- this is an error message sent remotely
@@ -445,7 +509,8 @@ debugger.listen = function()
.." "..TR("Compilation error")
..":\n"..err)
return debugger.terminate()
elseif options.runstart and stoppedAtBreakpoint(file, line) then
elseif options.runstart and not debugger.scratchpad
and stoppedAtBreakpoint(file, line) then
activateDocument(file, line)
options.runstart = false
end
@@ -480,8 +545,11 @@ debugger.listen = function()
end
-- if not found and the files doesn't exist, it may be
-- a remote call; try to map it to the project folder
if not activated and not wx.wxFileName(file):FileExists() then
-- a remote call; try to map it to the project folder.
-- also check for absolute path as it may need to be remapped
-- when autoactivation is disabled.
if not activated and (not wx.wxFileName(file):FileExists()
or wx.wxIsAbsolutePath(file)) then
-- file is /foo/bar/my.lua; basedir is d:\local\path\
-- check for d:\local\path\my.lua, d:\local\path\bar\my.lua, ...
-- wxwidgets on Windows handles \\ and / as separators, but on OSX
@@ -653,8 +721,18 @@ 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
local file, line, content = (table.unpack or unpack)(debugger.activate)
if content then
local editor = NewFile()
editor:SetText(content)
if not ide.config.debugger.allowediting
and not (debugger.options or {}).allowediting then
editor:SetReadOnly(true)
end
activateDocument(file, line)
elseif LoadFile(file) then
activateDocument(file, line)
end
debugger.activate = nil
end
end
@@ -760,12 +838,28 @@ function debuggerCreateStackWindow()
end
num = num + 1
end
stackCtrl:SortChildren(item_id)
return true
end)
local notebook = wxaui.wxAuiNotebook(frame, wx.wxID_ANY,
-- register navigation callback
stackCtrl:Connect(wx.wxEVT_LEFT_DCLICK, function (event)
local item_id = stackCtrl:HitTest(event:GetPosition())
if not item_id or not item_id:IsOk() then event:Skip() return end
local coords = callData[item_id:GetValue()]
if not coords then event:Skip() return end
local file, line = coords[1], coords[2]
if file:match("@") then file = string.sub(file, 2) end
file = GetFullPathIfExists(debugger.basedir, file)
if file then
local editor = LoadFile(file,nil,true)
editor:SetFocus()
if line then editor:GotoPos(editor:PositionFromLine(line-1)) end
end
end)
local notebook = wxaui.wxAuiNotebook(ide.frame, wx.wxID_ANY,
wx.wxDefaultPosition, wx.wxDefaultSize,
wxaui.wxAUI_NB_DEFAULT_STYLE + wxaui.wxAUI_NB_TAB_EXTERNAL_MOVE
- wxaui.wxAUI_NB_CLOSE_ON_ACTIVE_TAB + wx.wxNO_BORDER)
@@ -781,7 +875,7 @@ function debuggerCreateStackWindow()
end
local function debuggerCreateWatchWindow()
local watchCtrl = wx.wxListCtrl(frame, wx.wxID_ANY,
local watchCtrl = wx.wxListCtrl(ide.frame, wx.wxID_ANY,
wx.wxDefaultPosition, wx.wxDefaultSize,
wx.wxLC_REPORT + wx.wxLC_EDIT_LABELS)
@@ -871,7 +965,7 @@ local function debuggerCreateWatchWindow()
event:Skip()
end)
local notebook = wxaui.wxAuiNotebook(frame, wx.wxID_ANY,
local notebook = wxaui.wxAuiNotebook(ide.frame, wx.wxID_ANY,
wx.wxDefaultPosition, wx.wxDefaultSize,
wxaui.wxAUI_NB_DEFAULT_STYLE + wxaui.wxAUI_NB_TAB_EXTERNAL_MOVE
- wxaui.wxAUI_NB_CLOSE_ON_ACTIVE_TAB + wx.wxNO_BORDER)
@@ -957,7 +1051,8 @@ function DebuggerToggleBreakpoint(editor, line)
markers = markers - CURRENT_LINE_MARKER_VALUE
end
local id = editor:GetId()
local filePath = DebuggerMakeFileName(editor, ide.openDocuments[id].filePath)
local filePath = debugger.editormap and debugger.editormap[editor]
or DebuggerMakeFileName(editor, ide.openDocuments[id].filePath)
if markers >= BREAKPOINT_MARKER_VALUE then
editor:MarkerDelete(line, BREAKPOINT_MARKER)
if debugger.server then

View File

@@ -1,3 +1,4 @@
-- Copyright 2011-13 Paul Kulchenko, ZeroBrane LLC
-- authors: Lomtik Software (J. Winwood & John Labenski)
-- Luxinia Dev (Eike Decker & Christoph Kubisch)
---------------------------------------------------------
@@ -10,6 +11,7 @@ local statusBar = ide.frame.statusBar
local notebook = ide.frame.notebook
local funclist = ide.frame.toolBar.funclist
local edcfg = ide.config.editor
local styles = ide.config.styles
local projcombobox = ide.frame.projpanel.projcombobox
-- ----------------------------------------------------------------------------
@@ -107,11 +109,12 @@ local function isFileAlteredOnDisk(editor)
GetIDEString("editormessage"),
wx.wxOK + wx.wxCENTRE, ide.frame)
elseif not editor:GetReadOnly() and modTime:IsValid() and oldModTime:IsEarlierThan(modTime) then
local ret = wx.wxMessageBox(
TR("File '%s' has been modified on disk."):format(fileName)
.."\n"..TR("Do you want to reload it?"),
GetIDEString("editormessage"),
wx.wxYES_NO + wx.wxCENTRE, ide.frame)
local ret = (edcfg.autoreload and (not EditorIsModified(editor)) and wx.wxYES)
or wx.wxMessageBox(
TR("File '%s' has been modified on disk."):format(fileName)
.."\n"..TR("Do you want to reload it?"),
GetIDEString("editormessage"),
wx.wxYES_NO + wx.wxCENTRE, ide.frame)
if ret ~= wx.wxYES or LoadFile(filePath, editor, true) then
openDocuments[id].modTime = GetFileModTime(filePath)
@@ -148,6 +151,7 @@ function SetEditorSelection(selection)
editor:SetFocus()
editor:SetSTCFocus(true)
local id = editor:GetId()
FileTreeMarkSelected(openDocuments[id] and openDocuments[id].filePath or '')
AddToFileHistory(openDocuments[id] and openDocuments[id].filePath)
@@ -214,36 +218,32 @@ function EditorAutoComplete(editor)
lt = lt:gsub("%s*(["..editor.spec.sep.."])%s*", "%1")
-- strip closed brace scopes
lt = lt:gsub("%b()","")
lt = lt:gsub("%b[]","")
lt = lt:gsub("%b{}","")
lt = lt:gsub("%b[]",".0")
-- match from starting brace
lt = lt:match("[^%[%(%{%s]*$")
lt = lt:match("[^%[%(%{%s,]*$")
-- know now which string is to be completed
local userList = CreateAutoCompList(editor,lt)
-- don't show the list if the only option is what's already typed
if userList and #userList > 0 and userList ~= lt then
-- don't show the list if it only suggests what's already typed
if userList and #userList > 0 and not lt:find(userList.."$") then
editor:UserListShow(1, userList)
elseif editor:AutoCompActive() then
editor:AutoCompCancel()
end
end
local ident = "([a-zA-Z_][a-zA-Z_0-9%.%:]*)"
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
-- 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.
@@ -251,8 +251,22 @@ local function getValAtPosition(editor, pos)
:gsub("%b[]", function(s) return ("."):rep(#s) end)
:find(ident.."$")
local right, funccall = linetx:sub(localpos+1,#linetx):match("^([a-zA-Z_0-9]*)%s*(['\"{%(]?)")
local var = selected
-- GetSelectedText() returns concatenated text when multiple instances
-- are selected, so get the selected text based on start/end
and editor:GetTextRange(editor:GetSelectionStart(), editor:GetSelectionEnd())
or (start and linetx:sub(start,localpos):gsub(":",".")..right or nil)
-- since this function can be called in different contexts, we need
-- to detect function call of different types:
-- 1. foo.b^ar(... -- the cursor (pos) is on the function name
-- 2. foo.bar(..^. -- the cursor (pos) is on the parameter list
-- "var" has value for #1 and the following fragment checks for #2
-- check if the style is the right one; this is to ignore
-- comments, strings, numbers (to avoid '1 = 1'), keywords, and such
local goodpos = true
if start and not selected then
local style = bit.band(editor:GetStyleAt(linestart+start),31)
if editor.spec.iscomment[style]
@@ -260,25 +274,37 @@ local function getValAtPosition(editor, pos)
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
goodpos = false
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)
local linetxtopos = linetx:sub(1,localpos)
funccall = (#funccall > 0) and goodpos and var
or (linetxtopos..")"):match(ident .. "%s*%b()$")
or (linetxtopos.."}"):match(ident .. "%s*%b{}$")
or (linetxtopos.."'"):match(ident .. "%s*'[^']*'$")
or (linetxtopos..'"'):match(ident .. '%s*"[^"]*"$')
or nil
return var, linetxtopos
-- don't do anything for strings or comments or numbers
if not goodpos then return nil, funccall end
return var, funccall
end
function EditorCallTip(editor, pos, x, y)
-- don't show anything if the calltip is active; this may happen after
-- typing function name, while the mouse is over a different function.
if editor:CallTipActive() then return end
-- don't show anything if the calltip/auto-complete is active;
-- this may happen after typing function name, while the mouse is over
-- a different function or when auto-complete is on for a parameter.
if editor:CallTipActive() or editor:AutoCompActive() then return end
local var, linetxtopos = getValAtPosition(editor, pos)
local tip = linetxtopos and GetTipInfo(editor,linetxtopos.."(",false)
-- don't activate if the window itself is not active (in the background)
if not ide.frame:IsActive() then return end
local var, funccall = getValAtPosition(editor, pos)
-- if this is a value type rather than a function/method call, then use
-- full match to avoid calltip about coroutine.status for "status" vars
local tip = GetTipInfo(editor, funccall or var, false, not funccall)
if ide.debugger and ide.debugger.server then
if var then
local limit = 128
@@ -315,6 +341,234 @@ function EditorIsModified(editor)
return modified
end
-- Indicator handling for functions and local/global variables
local function indicateFunctions28(editor, lines, linee)
if not (edcfg.showfncall and editor.spec and editor.spec.isfncall)
or not (styles.indicator and styles.indicator.fncall) then return end
local es = editor:GetEndStyled()
local lines = lines or 0
local linee = linee or editor:GetLineCount()-1
if (lines < 0) then return end
local isfncall = editor.spec.isfncall
local isinvalid = {}
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
for line=lines,linee do
local tx = editor:GetLine(line)
local ls = editor:PositionFromLine(line)
local from = 1
local off = -1
editor:StartStyling(ls,INDICS_MASK)
editor:SetStyling(#tx,0)
while from do
tx = from==1 and tx or string.sub(tx,from)
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(#w,isinvalid[s] and 0 or (INDIC0_MASK + 1))
off = off + t
end
from = t and (t+1)
end
end
editor:StartStyling(es,31)
end
local delayed = {}
local tokenlists = {}
-- indicator.MASKED is handled separately, so don't include in MAX
local indicator = {FNCALL = 0, LOCAL = 1, GLOBAL = 2, MASKING = 3, MASKED = 4, MAX = 3}
function IndicateIfNeeded()
local editor = GetEditor()
-- do the current one first
if delayed[editor] then return IndicateAll(editor) end
for editor in pairs(delayed) do return IndicateAll(editor) end
end
-- find all instances of a symbol at pos
-- return table with [0] as the definition position (if local)
local function indicateFindInstances(editor, name, pos)
local tokens = tokenlists[editor] or {}
local instances = {{[-1] = 1}}
local this
for _, token in ipairs(tokens) do
local op = token[1]
if op == 'EndScope' then -- EndScope has "new" level, so need +1
if this and token.fpos > pos and this == token.at+1 then break end
if #instances > 1 and instances[#instances][-1] == token.at+1 then
table.remove(instances) end
elseif token.name == name then
if op == 'Id' then
table.insert(instances[#instances], token.fpos)
elseif op:find("^Var") then
if this and this == token.at then break end
-- if new Var is defined at the same level, replace the current frame;
-- if not, add a new one; skip implicit definition of "self" variable.
instances[#instances + (token.at > instances[#instances][-1] and 1 or 0)]
= {[0] = (not token.self and token.fpos or nil), [-1] = token.at}
end
if token.fpos <= pos and pos <= token.fpos+#name then this = instances[#instances][-1] end
end
end
instances[#instances][-1] = nil -- remove the current level
-- only return the list if "this" instance has been found;
-- this is to avoid reporting (improper) instances when checking for
-- comments, strings, table fields, etc.
return this and instances[#instances] or {}
end
function IndicateAll(editor, lines, linee)
local d = delayed[editor]
delayed[editor] = nil -- assume this can be finished for now
-- this function can be called for an editor tab that is already closed
-- when there are still some pending events for it, so handle it.
if not pcall(function() return editor:GetId() end) then return end
if not (editor.spec and editor.spec.markvars) then return end
local indic = styles.indicator or {}
local pos, vars = d and d[1] or 1, d and d[2] or nil
local start = lines and editor:PositionFromLine(lines)+1 or nil
if d and start and pos >= start then
-- ignore delayed processing as the change is earlier in the text
pos, vars = 1, nil
end
tokenlists[editor] = tokenlists[editor] or {}
local tokens = tokenlists[editor]
if start then -- if the range is specified
local curindic = editor:GetIndicatorCurrent()
editor:SetIndicatorCurrent(indicator.MASKED)
for n = #tokens, 1, -1 do
local token = tokens[n]
-- find the last token before the range
if token[1] == 'EndScope' and token.name and token.fpos+#token.name < start then
pos, vars = token.fpos+#token.name, token.context
break
end
-- unmask all variables from the rest of the list
if token[1] == 'Masked' then
editor:IndicatorClearRange(token.fpos-1, #token.name)
end
-- trim the list as it will be re-generated
table.remove(tokens, n)
end
-- Clear masked indicators from the current position to the end as these
-- will be re-calculated and re-applied based on masking variables.
-- This step is needed as some positions could have shifted after updates.
editor:IndicatorClearRange(pos-1, editor:GetLength()-pos+1)
editor:SetIndicatorCurrent(curindic)
-- need to cleanup vars as they may include variables from later
-- fragments (because the cut-point was arbitrary). Also need
-- to clean variables in other scopes, hence getmetatable use.
local vars = vars
while vars do
for name, var in pairs(vars) do
-- remove all variables that are created later than the current pos
while type(var) == 'table' and var.fpos and (var.fpos > pos) do
var = var.masked -- restored a masked var
vars[name] = var
end
end
vars = getmetatable(vars) and getmetatable(vars).__index
end
else
if pos == 1 then -- if not continuing, then trim the list
tokens = {}
tokenlists[editor] = tokens
end
end
local cleared = {}
for indic = 0, indicator.MAX do cleared[indic] = pos end
local function IndicateOne(indic, pos, length)
editor:SetIndicatorCurrent(indic)
editor:IndicatorClearRange(cleared[indic]-1, pos-cleared[indic])
editor:IndicatorFillRange(pos-1, length)
cleared[indic] = pos+length
end
local s = TimeGet()
local canwork = start and 0.010 or 0.100 -- use shorter interval when typing
local f = editor.spec.markvars(editor:GetText(), pos, vars)
while true do
local op, name, lineinfo, vars, at = f()
if not op then break end
local var = vars and vars[name]
local token = {op, name=name, fpos=lineinfo, at=at, context=vars,
self = (op == 'VarSelf') or nil }
if op == 'FunctionCall' then
if indic.fncall and edcfg.showfncall then
IndicateOne(indicator.FNCALL, lineinfo, #name)
end
elseif op ~= 'VarNext' and op ~= 'VarInside' and op ~= 'Statement' then
table.insert(tokens, token)
end
-- indicate local/global variables
if op == 'Id'
and (var and indic.varlocal or not var and indic.varglobal) then
IndicateOne(var and indicator.LOCAL or indicator.GLOBAL, lineinfo, #name)
end
-- indicate masked values at the same level
if op == 'Var' and var and (var.masked and at == var.masked.at) then
local fpos = var.masked.fpos
-- indicate masked if it's not implicit self
if indic.varmasked and not var.masked.self then
editor:SetIndicatorCurrent(indicator.MASKED)
editor:IndicatorFillRange(fpos-1, #name)
table.insert(tokens, {"Masked", name=name, fpos=fpos})
end
if indic.varmasking then IndicateOne(indicator.MASKING, lineinfo, #name) end
end
if op == 'EndScope' and name and TimeGet()-s > canwork then
delayed[editor] = {lineinfo+#name, vars}
break
end
end
-- clear indicators till the end of processed fragment
local pos = delayed[editor] and delayed[editor][1] or editor:GetLength()+1
-- don't clear "masked" indicators as those can be set out of order (so
-- last updated fragment is not always the last in terms of its position);
-- these indicators should be up-to-date to the end of the code fragment.
for indic = 0, indicator.MAX do IndicateOne(indic, pos, 0) end
return delayed[editor] ~= nil -- request more events if still need to work
end
if ide.wxver < "2.9.5" or not ide.config.autoanalizer then
IndicateAll = indicateFunctions28 end
-- ----------------------------------------------------------------------------
-- Create an editor
function CreateEditor()
@@ -327,14 +581,14 @@ function CreateEditor()
editor.matchon = false
editor.assignscache = false
editor:SetBufferedDraw(true)
editor:SetBufferedDraw(not ide.config.hidpi and true or false)
editor:StyleClearAll()
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)
editor:SetTabWidth(ide.config.editor.tabwidth or 2)
editor:SetIndent(ide.config.editor.tabwidth or 2)
editor:SetUseTabs(ide.config.editor.usetabs and true or false)
editor:SetIndentationGuides(true)
editor:SetViewWhiteSpace(ide.config.editor.whitespace and true or false)
@@ -364,10 +618,12 @@ function CreateEditor()
editor:MarkerDefine(StylesGetMarker("currentline"))
editor:MarkerDefine(StylesGetMarker("breakpoint"))
editor:SetMarginWidth(2, 16) -- fold margin
editor:SetMarginType(2, wxstc.wxSTC_MARGIN_SYMBOL)
editor:SetMarginMask(2, wxstc.wxSTC_MASK_FOLDERS)
editor:SetMarginSensitive(2, true)
if ide.config.editor.fold then
editor:SetMarginWidth(2, 16) -- fold margin
editor:SetMarginType(2, wxstc.wxSTC_MARGIN_SYMBOL)
editor:SetMarginMask(2, wxstc.wxSTC_MASK_FOLDERS)
editor:SetMarginSensitive(2, true)
end
editor:SetFoldFlags(wxstc.wxSTC_FOLDFLAG_LINEBEFORE_CONTRACTED +
wxstc.wxSTC_FOLDFLAG_LINEAFTER_CONTRACTED)
@@ -468,8 +724,7 @@ function CreateEditor()
if ide.config.acandtip.nodynwords then return end
-- only required to track changes
if (bit.band(evtype,wxstc.wxSTC_MOD_BEFOREDELETE) ~= 0) then
local numlines = 0
event:GetText():gsub("(\r?\n)",function() numlines = numlines + 1 end)
local _, numlines = event:GetText():gsub("\r?\n","%1")
DynamicWordsRem("pre",editor,nil,editor:LineFromPosition(event:GetPosition()), numlines)
end
if (bit.band(evtype,wxstc.wxSTC_MOD_BEFOREINSERT) ~= 0) then
@@ -480,6 +735,7 @@ function CreateEditor()
editor:Connect(wxstc.wxEVT_STC_CHARADDED,
function (event)
-- auto-indent
local LF = string.byte("\n")
local ch = event:GetKey()
local eol = editor:GetEOLMode()
local pos = editor:GetCurrentPos()
@@ -489,7 +745,9 @@ function CreateEditor()
local localpos = pos-linestart
local linetxtopos = linetx:sub(1,localpos)
if (ch == char_LF) then
if PackageEventHandle("onEditorCharAdded", editor, event) == false then
-- this event has already been handled
elseif (ch == LF) then
if (line > 0) then
local indent = editor:GetLineIndentation(line - 1)
local linedone = editor:GetLine(line - 1)
@@ -502,8 +760,8 @@ function CreateEditor()
indent = editor:GetLineIndentation(line)
end
local tw = editor:GetTabWidth()
local ut = editor:GetUseTabs()
local tw = ut and editor:GetTabWidth() or editor:GetIndent()
if ide.config.editor.smartindent
and editor.spec.isdecindent and editor.spec.isincindent then
@@ -577,18 +835,54 @@ function CreateEditor()
event:Skip()
end)
editor:Connect(wx.wxEVT_SET_FOCUS,
function (event)
PackageEventHandle("onEditorFocusSet", editor)
event:Skip()
end)
editor:Connect(wx.wxEVT_KILL_FOCUS,
function (event)
if editor:AutoCompActive() then editor:AutoCompCancel() end
PackageEventHandle("onEditorFocusLost", editor)
event:Skip()
end)
editor:Connect(wxstc.wxEVT_STC_USERLISTSELECTION,
function (event)
local pos = editor:GetCurrentPos()
local start_pos = editor:WordStartPosition(pos, true)
editor:SetSelection(start_pos, pos)
editor:ReplaceSelection(event:GetText())
if ide.wxver >= "2.9.5" and editor:GetSelections() > 1 then
local text = event:GetText()
-- capture all positions as the selection may change
local positions = {}
for s = 0, editor:GetSelections()-1 do
table.insert(positions, editor:GetSelectionNCaret(s))
end
-- process all selections from last to first
table.sort(positions)
local mainpos = editor:GetSelectionNCaret(editor:GetMainSelection())
editor:BeginUndoAction()
for s = #positions, 1, -1 do
local pos = positions[s]
local start_pos = editor:WordStartPosition(pos, true)
editor:SetSelection(start_pos, pos)
editor:ReplaceSelection(text)
-- if this is the main position, save new cursor position to restore
if pos == mainpos then mainpos = editor:GetCurrentPos()
elseif pos < mainpos then
-- adjust main position as earlier changes may affect it
mainpos = mainpos + #text - (pos - start_pos)
end
end
editor:EndUndoAction()
editor:GotoPos(mainpos)
else
local pos = editor:GetCurrentPos()
local start_pos = editor:WordStartPosition(pos, true)
editor:SetSelection(start_pos, pos)
editor:ReplaceSelection(event:GetText())
end
end)
editor:Connect(wxstc.wxEVT_STC_SAVEPOINTREACHED,
@@ -622,11 +916,15 @@ function CreateEditor()
for _,iv in ipairs(editor.ev) do
local line = editor:LineFromPosition(iv[1])
if not minupdated or line < minupdated then minupdated = line end
IndicateFunctions(editor,line,line+iv[2])
local ok, res = pcall(IndicateAll, editor,line,line+iv[2])
if not ok then DisplayOutputLn("Internal error: ",res,line,line+iv[2]) end
end
local firstline = editor:DocLineFromVisible(editor:GetFirstVisibleLine())
local firstvisible = editor:DocLineFromVisible(editor:GetFirstVisibleLine())
local lastline = math.min(editor:GetLineCount(),
editor:DocLineFromVisible(editor:GetFirstVisibleLine() + editor:LinesOnScreen()))
firstvisible + editor:LinesOnScreen())
-- lastline - editor:LinesOnScreen() can get negative; fix it
local firstline = math.min(math.max(0, lastline - editor:LinesOnScreen()),
firstvisible)
MarkupStyle(editor,minupdated or firstline,lastline)
editor.ev = {}
end)
@@ -667,7 +965,9 @@ function CreateEditor()
local keycode = event:GetKeyCode()
local mod = event:GetModifiers()
local first, last = 0, notebook:GetPageCount()-1
if keycode == wx.WXK_ESCAPE and frame:IsFullScreen() then
if PackageEventHandle("onEditorKeyDown", editor, event) == false then
-- this event has already been handled
elseif keycode == wx.WXK_ESCAPE and ide.frame:IsFullScreen() then
ShowFullScreen(false)
-- Ctrl-Home and Ctrl-End don't work on OSX with 2.9.5+; fix it
elseif ide.osname == 'Macintosh' and ide.wxver >= "2.9.5"
@@ -726,9 +1026,56 @@ function CreateEditor()
end
end)
local value
local function selectAllInstances(instances, name, curpos)
local this
local idx = 0
for i, pos in pairs(instances) do
pos = pos - 1 -- positions are 0-based in Scintilla
if idx == 0 then
-- clear selections first as there seems to be a bug (Scintilla 3.2.3)
-- that doesn't reset selection after right mouse click.
editor:ClearSelections()
editor:SetSelection(pos, pos+#name)
else
editor:AddSelection(pos+#name, pos)
end
-- check if this is the current selection
if curpos >= pos and curpos <= pos+#name then this = idx end
idx = idx + 1
end
if this then editor:SetMainSelection(this) end
end
editor:Connect(wxstc.wxEVT_STC_DOUBLECLICK,
function(event)
-- only activate selection of instances on Ctrl/Cmd-DoubleClick
if event:GetModifiers() == wx.wxMOD_CONTROL then
local pos = event:GetPosition()
local value = pos ~= wxstc.wxSTC_INVALID_POSITION and getValAtPosition(editor, pos) or nil
local instances = value and indicateFindInstances(editor, value, pos+1)
if instances and (instances[0] or #instances > 0) then
selectAllInstances(instances, value, pos)
return
end
end
event:Skip()
end)
local pos, value, instances
editor:Connect(wx.wxEVT_CONTEXT_MENU,
function (event)
local point = editor:ScreenToClient(event:GetPosition())
pos = editor:PositionFromPointClose(point.x, point.y)
value = pos ~= wxstc.wxSTC_INVALID_POSITION and getValAtPosition(editor, pos) or nil
instances = value and indicateFindInstances(editor, value, pos+1)
local occurrences = (not instances or #instances == 0) and ""
or (" (%d)"):format(#instances+(instances[0] and 1 or 0))
local line = instances and instances[0] and editor:LineFromPosition(instances[0]-1)+1
local def = line and " ("..TR("on line %d"):format(line)..")" or ""
local menu = wx.wxMenu()
menu:Append(ID_UNDO, TR("&Undo"))
menu:Append(ID_REDO, TR("&Redo"))
@@ -738,13 +1085,15 @@ function CreateEditor()
menu:Append(ID_PASTE, TR("&Paste"))
menu:Append(ID_SELECTALL, TR("Select &All"))
menu:AppendSeparator()
menu:Append(ID_GOTODEFINITION, TR("Go To Definition")..def)
menu:Append(ID_RENAMEALLINSTANCES, TR("Rename All Instances")..occurrences)
menu:AppendSeparator()
menu:Append(ID_QUICKADDWATCH, TR("Add Watch Expression"))
menu:Append(ID_QUICKEVAL, TR("Evaluate in Console"))
menu:Append(ID_ADDTOSCRATCHPAD, TR("Add to Scratchpad"))
menu:Append(ID_QUICKEVAL, TR("Evaluate In Console"))
menu:Append(ID_ADDTOSCRATCHPAD, TR("Add To Scratchpad"))
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_GOTODEFINITION, instances and instances[0])
menu:Enable(ID_RENAMEALLINSTANCES, instances and (instances[0] or #instances > 0))
menu:Enable(ID_QUICKADDWATCH, value ~= nil)
menu:Enable(ID_QUICKEVAL, value ~= nil)
@@ -752,9 +1101,32 @@ function CreateEditor()
menu:Enable(ID_ADDTOSCRATCHPAD, debugger.scratchpad
and debugger.scratchpad.editors and not debugger.scratchpad.editors[editor])
-- cancel calltip as it interferes with popup menu
-- disable calltips that could open over the menu
local dwelltime = editor:GetMouseDwellTime()
editor:SetMouseDwellTime(0) -- disable dwelling
-- cancel calltip if it's already shown as it interferes with popup menu
if editor:CallTipActive() then editor:CallTipCancel() end
PackageEventHandle("onMenuEditor", menu, editor, event)
editor:PopupMenu(menu)
editor:SetMouseDwellTime(dwelltime) -- restore dwelling
end)
editor:Connect(ID_GOTODEFINITION, wx.wxEVT_COMMAND_MENU_SELECTED,
function(event)
if value and instances[0] then
editor:GotoPos(instances[0]-1)
editor:SetAnchor(instances[0]-1+#value)
end
end)
editor:Connect(ID_RENAMEALLINSTANCES, wx.wxEVT_COMMAND_MENU_SELECTED,
function(event)
if value and pos then
selectAllInstances(instances, value, pos)
end
end)
editor:Connect(ID_QUICKADDWATCH, wx.wxEVT_COMMAND_MENU_SELECTED,
@@ -774,10 +1146,10 @@ end
function AddEditor(editor, name)
if notebook:AddPage(editor, name, true) then
local id = editor:GetId()
local document = {}
local document = setmetatable({}, ide.proto.Document)
document.editor = editor
document.index = notebook:GetPageIndex(editor)
document.fileName = nil
document.fileName = name
document.filePath = nil
document.modTime = nil
document.isModified = false
@@ -811,51 +1183,6 @@ function GetSpec(ext,forcespec)
return spec
end
function IndicateFunctions(editor, lines, linee)
if (not (edcfg.showfncall and editor.spec and editor.spec.isfncall)) then return end
local es = editor:GetEndStyled()
local lines = lines or 0
local linee = linee or editor:GetLineCount()-1
if (lines < 0) then return end
local isfncall = editor.spec.isfncall
local isinvalid = {}
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
for line=lines,linee do
local tx = editor:GetLine(line)
local ls = editor:PositionFromLine(line)
local from = 1
local off = -1
editor:StartStyling(ls,INDICS_MASK)
editor:SetStyling(#tx,0)
while from do
tx = from==1 and tx or string.sub(tx,from)
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(#w,isinvalid[s] and 0 or (INDIC0_MASK + 1))
off = off + t
end
from = t and (t+1)
end
end
editor:StartStyling(es,31)
end
function SetupKeywords(editor, ext, forcespec, styles, font, fontitalic)
local lexerstyleconvert = nil
local spec = forcespec or GetSpec(ext)
@@ -901,9 +1228,12 @@ function SetupKeywords(editor, ext, forcespec, styles, font, fontitalic)
-- need to set folding property after lexer is set, otherwise
-- the folds are not shown (wxwidgets 2.9.5)
editor:SetProperty("fold", "1")
editor:SetProperty("fold.compact", ide.config.editor.foldcompact and "1" or "0")
editor:SetProperty("fold.comment", "1")
if ide.config.editor.fold then
editor:SetProperty("fold", "1")
editor:SetProperty("fold.html", "1")
editor:SetProperty("fold.compact", ide.config.editor.foldcompact and "1" or "0")
editor:SetProperty("fold.comment", "1")
end
-- quickfix to prevent weird looks, otherwise need to update styling mechanism for cpp
-- cpp "greyed out" styles are styleid + 64

View File

@@ -6,27 +6,15 @@ local ide = ide
--
ide.filetree = {
dirdriveText = "",
dirdriveTextArray = {},
projdirText = "",
projdirTextArray = {},
showroot = true,
dirdata = {
root_id = nil,
rootdir = "",
},
projdata = {
root_id = nil,
rootdir = "",
},
projdir = "",
projdirlist = {},
projdirmap = {},
projdirpartmap = {},
}
local filetree = ide.filetree
local iscaseinsensitive = wx.wxFileName("A"):SameAs(wx.wxFileName("a"))
local pathsep = GetPathSeparator()
-- generic tree
-- ------------
@@ -57,7 +45,7 @@ local function treeAddDir(tree,parent_id,rootdir)
local curr
for _, file in ipairs(FileSysGetRecursive(rootdir)) do
local name, dir = file:match("("..stringset_File.."+)("..string_Pathsep.."?)$")
local name, dir = file:match("([^"..pathsep.."]+)("..pathsep.."?)$")
local known = GetSpec(GetFileExt(name))
local icon = #dir>0 and IMG_DIRECTORY or known and IMG_FILE_KNOWN or IMG_FILE_OTHER
local item = items[name .. icon]
@@ -97,66 +85,56 @@ local function treeAddDir(tree,parent_id,rootdir)
tree:GetChildrenCount(parent_id, false) > 0)
end
local function treeGetItemFullName(tree,treedata,item_id)
local str = tree:GetItemText(item_id)
local cur = str
while (#cur > 0) do
item_id = tree:GetItemParent(item_id)
if not item_id:IsOk() then break end
cur = tree:GetItemText(item_id)
if cur and string.len(cur) > 0 then str = cur..string_Pathsep..str end
end
-- as root may already include path separator, 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)
local function treeSetRoot(tree,rootdir)
tree:DeleteAllItems()
if (not wx.wxDirExists(rootdir)) then
treedata.root_id = nil
return
end
if (not wx.wxDirExists(rootdir)) then return end
local root_id = tree:AddRoot(rootdir, IMG_DIRECTORY)
treedata.root_id = root_id
treedata.rootdir = rootdir
-- make sure that the item can expand
tree:SetItemHasChildren(root_id, true)
tree:SetItemHasChildren(root_id, true) -- make sure that the item can expand
tree:Expand(root_id) -- this will also populate the tree
end
local function treeSetConnectorsAndIcons(tree,treedata)
local function treeSetConnectorsAndIcons(tree)
tree:SetImageList(filetree.imglist)
function tree:GetItemFullName(item_id)
local tree = self
local str = tree:GetItemText(item_id)
local cur = str
while (#cur > 0) do
item_id = tree:GetItemParent(item_id)
if not item_id:IsOk() then break end
cur = tree:GetItemText(item_id)
if cur and string.len(cur) > 0 then str = cur..pathsep..str end
end
-- as root may already include path separator, normalize the path
local fullPath = wx.wxFileName(str)
fullPath:Normalize()
return fullPath:GetFullPath()
end
local function refreshAncestors(node)
while node:IsOk() do
local dir = treeGetItemFullName(tree,treedata,node)
local dir = tree:GetItemFullName(node)
treeAddDir(tree,node,dir)
node = tree:GetItemParent(node)
end
end
-- connect to some events from the wxTreeCtrl
tree:Connect( wx.wxEVT_COMMAND_TREE_ITEM_EXPANDING,
function( event )
local item_id = event:GetItem()
local dir = treeGetItemFullName(tree,treedata,item_id)
local dir = tree:GetItemFullName(item_id)
if wx.wxDirExists(dir) then treeAddDir(tree,item_id,dir) -- refresh folder
else refreshAncestors(tree:GetItemParent(item_id)) end -- stale content
return true
end)
tree:Connect( wx.wxEVT_COMMAND_TREE_ITEM_COLLAPSED,
function() return true end)
tree:Connect( wx.wxEVT_COMMAND_TREE_ITEM_ACTIVATED,
function( event )
local item_id = event:GetItem()
local name = treeGetItemFullName(tree,treedata,item_id)
local name = tree:GetItemFullName(item_id)
-- refresh the folder
if (tree:GetItemImage(item_id) == IMG_DIRECTORY) then
if wx.wxDirExists(name) then treeAddDir(tree,item_id,name)
@@ -166,7 +144,21 @@ local function treeSetConnectorsAndIcons(tree,treedata)
else refreshAncestors(tree:GetItemParent(item_id)) end -- stale content
end
end)
-- toggle a folder on
-- handle context menu
tree:Connect( wx.wxEVT_COMMAND_TREE_ITEM_MENU,
function( event )
local item_id = event:GetItem()
tree:SelectItem(item_id)
local menu = wx.wxMenu()
menu:Append(ID_SHOWLOCATION, TR("Show Location"))
tree:Connect(ID_SHOWLOCATION, wx.wxEVT_COMMAND_MENU_SELECTED,
function() ShowLocation(tree:GetItemFullName(item_id)) end)
PackageEventHandle("onMenuFiletree", menu, tree, event)
tree:PopupMenu(menu)
end)
-- toggle a folder on a single click
tree:Connect( wx.wxEVT_LEFT_DOWN,
function( event )
local item_id = tree:HitTest(event:GetPosition())
@@ -187,18 +179,16 @@ end
-- (treectrl)
local projpanel = ide.frame.projpanel
local projcombobox = wx.wxComboBox(projpanel, ID "filetree.proj.drivecb",
filetree.projdirText,
filetree.projdir,
wx.wxDefaultPosition, wx.wxDefaultSize,
filetree.projdirTextArray, wx.wxTE_PROCESS_ENTER)
filetree.projdirlist, wx.wxTE_PROCESS_ENTER)
local projbutton = wx.wxButton(projpanel, ID_PROJECTDIRCHOOSE,
"...",wx.wxDefaultPosition, wx.wxSize(26,20))
"...", wx.wxDefaultPosition, wx.wxSize(26,20))
local projtree = wx.wxTreeCtrl(projpanel, wx.wxID_ANY,
wx.wxDefaultPosition, wx.wxDefaultSize,
filetree.showroot
and (wx.wxTR_LINES_AT_ROOT + wx.wxTR_HAS_BUTTONS + wx.wxTR_SINGLE)
or (wx.wxTR_HAS_BUTTONS + wx.wxTR_SINGLE + wx.wxTR_HIDE_ROOT))
wx.wxTR_HAS_BUTTONS + wx.wxTR_SINGLE + wx.wxTR_LINES_AT_ROOT)
-- use the same font in the combobox as is used in the filetree
projtree:SetFont(ide.font.fNormal)
@@ -221,51 +211,80 @@ local inupdate = false
local function projcomboboxUpdate(event)
if inupdate then return end
local cur = projcombobox:GetValue()
local fn = wx.wxFileName(cur)
local fn = wx.wxFileName(filetree.projdirmap[cur] or cur)
fn:Normalize()
-- on Windows, wxwidgets (2.9.5+) generates two COMMAND_COMBOBOX_SELECTED
-- events when the selection is done with ENTER, which causes recursive
-- call of updateProjectDir. To prevent this the second call is ignored.
inupdate = true
filetree:updateProjectDir(fn:GetFullPath(), event:GetEventType() == wx.wxEVT_COMMAND_COMBOBOX_SELECTED)
filetree:updateProjectDir(fn:GetFullPath())
inupdate = false
end
projpanel:Connect(ID "filetree.proj.drivecb", wx.wxEVT_COMMAND_COMBOBOX_SELECTED, projcomboboxUpdate)
projpanel:Connect(ID "filetree.proj.drivecb", wx.wxEVT_COMMAND_TEXT_ENTER, projcomboboxUpdate)
treeSetConnectorsAndIcons(projtree,filetree.projdata)
treeSetConnectorsAndIcons(projtree)
-- proj functions
-- ---------------
function filetree:updateProjectDir(newdir, cboxsel)
local function q(s) return s:gsub('([%(%)%.%%%+%-%*%?%[%^%$%]])','%%%1') end
local function abbreviateProjList(projdirlist)
filetree.projdirmap = {}
local sep = "\t"
local dirs = table.concat(projdirlist, sep)..sep
local projlist = {}
for _, v in ipairs(projdirlist) do
-- using FileName because the path doesn't have trailing slash
local parts = wx.wxFileName(v..pathsep):GetDirs()
local name = table.remove(parts, #parts) or v
while #parts > 0
and select(2, dirs:gsub("%f[^".. pathsep .."]"..q(name)..sep, "")) > 1 do
name = table.remove(parts, #parts) .. pathsep .. name
end
local abbrev = ("%s (%s)"):format(name, v)
filetree.projdirmap[abbrev] = v
table.insert(projlist, abbrev)
end
return projlist
end
function filetree:updateProjectDir(newdir)
if (not newdir) or not wx.wxDirExists(newdir) then return end
local dirname = wx.wxFileName.DirName(newdir)
if filetree.projdirText and #filetree.projdirText > 0
and dirname:SameAs(wx.wxFileName.DirName(filetree.projdirText)) then return end
if filetree.projdir and #filetree.projdir > 0
and dirname:SameAs(wx.wxFileName.DirName(filetree.projdir)) then return end
-- strip the last path separator if any
local newdir = dirname:GetPath(wx.wxPATH_GET_VOLUME)
if ide.config.projectautoopen and filetree.projdirText then
StoreRestoreProjectTabs(filetree.projdirText, newdir)
if filetree.projdir and #filetree.projdir > 0 then
PackageEventHandle("onProjectClose", filetree.projdir) end
if ide.config.projectautoopen and filetree.projdir then
StoreRestoreProjectTabs(filetree.projdir, newdir)
end
filetree.projdirText = newdir
filetree.projdir = newdir
filetree.projdirpartmap = {}
PrependStringToArray(filetree.projdirTextArray,newdir,ide.config.projecthistorylength)
PackageEventHandle("onProjectLoad", filetree.projdir)
PrependStringToArray(
filetree.projdirlist,
newdir,
ide.config.projecthistorylength,
function(s1, s2) return dirname:SameAs(wx.wxFileName.DirName(s2)) end)
projcombobox:Clear()
projcombobox:Append(filetree.projdirTextArray)
if (not cboxsel) then
projcombobox:SetValue(newdir)
else
projcombobox:Select(0)
end
projcombobox:Append(abbreviateProjList(filetree.projdirlist))
projcombobox:Select(0)
ProjectUpdateProjectDir(newdir,true)
treeSetRoot(projtree,filetree.projdata,newdir)
treeSetRoot(projtree,newdir)
-- sync with the current editor window and activate selected file
local editor = GetEditor()
@@ -282,19 +301,19 @@ projpanel.projcombobox = projcombobox
projpanel.projtree = projtree
function FileTreeGetDir()
return projpanel:IsShown() and filetree.projdata.rootdir
and wx.wxFileName.DirName(filetree.projdata.rootdir):GetFullPath()
return filetree.projdir and #filetree.projdir > 0
and wx.wxFileName.DirName(filetree.projdir):GetFullPath()
end
function FileTreeSetProjects(tab)
filetree.projdirTextArray = tab
filetree.projdirlist = tab
if (tab and tab[1]) then
filetree:updateProjectDir(tab[1])
end
end
function FileTreeGetProjects()
return filetree.projdirTextArray
return filetree.projdirlist
end
local function findItem(tree, match)
@@ -309,14 +328,14 @@ local function findItem(tree, match)
end
if not s or s ~= 1 then return end
for token in string.gmatch(string.sub(match,e+1), "[^%"..string_Pathsep.."]+") do
for token in string.gmatch(string.sub(match,e+1), "[^%"..pathsep.."]+") do
local data = tree:GetItemData(node)
local cache = data and data:GetData()
if cache and cache[iscaseinsensitive and token:lower() or token] then
node = cache[iscaseinsensitive and token:lower() or token]
else
-- token is missing; may need to re-scan the folder; maybe new file
local dir = treeGetItemFullName(tree,filetree.projdata,node)
local dir = tree:GetItemFullName(node)
treeAddDir(tree,node,dir)
local item, cookie = tree:GetFirstChild(node)
@@ -337,7 +356,7 @@ end
local curr_file
function FileTreeMarkSelected(file)
if not file or not filetree.projdirText or #filetree.projdirText == 0 then return end
if not file or not filetree.projdir or #filetree.projdir == 0 then return end
local item_id = findItem(projtree, file)
@@ -363,6 +382,20 @@ function FileTreeMarkSelected(file)
end
end
function FileTreeRefresh()
treeSetRoot(projtree,filetree.projdata,filetree.projdirText)
function FileTreeFindByPartialName(name)
-- check if it's already cached
if filetree.projdirpartmap[name] then return filetree.projdirpartmap[name] end
-- this function may get a partial name that starts with ... and has
-- an abbreviated path (as generated by stack traces);
-- remove starting "..." if any and escape
local pattern = q(name:gsub("^%.%.%.","")).."$"
for _, file in ipairs(FileSysGetRecursive(filetree.projdir, true)) do
if file:find(pattern) then
filetree.projdirpartmap[name] = file
return file
end
end
return
end

View File

@@ -13,14 +13,14 @@ ide.findReplace = {
fWrap = true, -- search wraps around
fDown = true, -- search downwards in doc
fSubDirs = false, -- search in subdirectories
fSubDirs = true, -- search in subdirectories
fMakeBak = true, -- make bak files for replace in files
findTextArray = {}, -- array of last entered find text
findText = "", -- string to find
replaceTextArray = {}, -- array of last entered replace text
replaceText = "", -- string to replace find string with
filemaskText = "*.*",
filemaskText = nil,
filemaskTextArray= {},
filedirText = "",
filedirTextArray = {},
@@ -46,8 +46,8 @@ end
-------------------- Find replace dialog
local function setSearchFlags(editor)
local flags = 0
if findReplace.fWholeWord then flags = wxstc.wxSTC_FIND_WHOLEWORD end
local flags = wxstc.wxSTC_FIND_POSIX
if findReplace.fWholeWord then flags = flags + wxstc.wxSTC_FIND_WHOLEWORD end
if findReplace.fMatchCase then flags = flags + wxstc.wxSTC_FIND_MATCHCASE end
if findReplace.fRegularExpr then flags = flags + wxstc.wxSTC_FIND_REGEXP end
editor:SetSearchFlags(flags)
@@ -107,6 +107,8 @@ local function shake(window, shakes, duration, vigour)
duration = duration or 0.5
vigour = vigour or 0.05
if not window then return end
local delay = math.floor(duration/shakes/2)
local position = window:GetPosition() -- get current position
local deltax = window:GetSize():GetWidth()*vigour
@@ -183,7 +185,6 @@ function findReplace:ReplaceString(fReplaceAll, inFileRegister)
local replaced = false
if findReplace:HasText() then
local replaceLen = string.len(findReplace.replaceText)
local editor = findReplace:GetEditor()
local endTarget = inFileRegister and setTargetAll(editor) or
setTarget(editor, findReplace.fDown, fReplaceAll, findReplace.fWrap)
@@ -198,8 +199,11 @@ function findReplace:ReplaceString(fReplaceAll, inFileRegister)
if (inFileRegister) then inFileRegister(posFind) end
local length = editor:GetLength()
editor:ReplaceTarget(findReplace.replaceText)
editor:SetTargetStart(posFind + replaceLen)
local replaced = findReplace.fRegularExpr
and editor:ReplaceTargetRE(findReplace.replaceText)
or editor:ReplaceTarget(findReplace.replaceText)
editor:SetTargetStart(posFind + replaced)
-- adjust the endTarget as the position could have changed;
-- can't simply subtract findText length as it could be a regexp
endTarget = endTarget + (editor:GetLength() - length)
@@ -214,10 +218,21 @@ function findReplace:ReplaceString(fReplaceAll, inFileRegister)
ide.frame:SetStatusText(("%s %s."):format(
TR("Replaced"), TR("%d instance", occurrences):format(occurrences)))
else
if findReplace.foundString then
-- check if there is anything selected as well as the user can
-- move the cursor after successful search
if findReplace.foundString
and editor:GetSelectionStart() ~= editor:GetSelectionEnd() then
local start = editor:GetSelectionStart()
editor:ReplaceSelection(findReplace.replaceText)
editor:SetSelection(start, start + replaceLen)
-- convert selection to target as we need TargetRE support
editor:TargetFromSelection()
local length = editor:GetLength()
local replaced = findReplace.fRegularExpr
and editor:ReplaceTargetRE(findReplace.replaceText)
or editor:ReplaceTarget(findReplace.replaceText)
editor:SetSelection(start, start + replaced)
findReplace.foundString = false
replaced = true
@@ -239,26 +254,45 @@ local function onFileRegister(pos)
end
local function ProcInFiles(startdir,mask,subdirs,replace)
local files = FileSysGetRecursive(startdir,subdirs,mask)
local files = FileSysGetRecursive(startdir,subdirs,"*")
local start = TimeGet()
-- mask could be a list, so generate a table with matching patterns
-- accept "*.lua; .txt;.wlua" combinations
local masks = {}
for m in mask:gmatch("[^%s;]+") do
table.insert(masks, m:gsub("%.", "%%."):gsub("%*", ".*").."$")
end
for _,file in ipairs(files) do
-- ignore .bak files when replacing and asked to store .bak files
-- and skip folders as these are included in the list as well
if not (replace and findReplace.fMakeBak and file:find('.bak$'))
and not file:match(string_Pathsep.."$") then
findReplace.curfilename = file
and not IsDirectory(file) then
local match = false
for _, mask in ipairs(masks) do match = match or file:find(mask) end
if match then
findReplace.curfilename = file
local filetext = FileRead(file)
if filetext then
findReplace.oveditor:SetText(filetext)
local filetext = FileRead(file)
if filetext and not isBinary(filetext:sub(1, 2048)) then
findReplace.oveditor:SetText(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())
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
-- give time to the UI to refresh
if TimeGet() - start > 0.25 then wx.wxYield() end
if not findReplace.dialog:IsShown() then
DisplayOutputLn(TR("Cancelled by the user."))
break
end
else
findReplace:FindStringAll(onFileRegister)
end
end
end
@@ -266,14 +300,14 @@ local function ProcInFiles(startdir,mask,subdirs,replace)
end
function findReplace:RunInFiles(replace)
if (not findReplace:HasText()) then
return
end
if not findReplace:HasText() then return end
findReplace.oveditor = wxstc.wxStyledTextCtrl(findReplace.dialog, wx.wxID_ANY,
wx.wxDefaultPosition, wx.wxSize(1,1), wx.wxBORDER_STATIC)
findReplace.occurrences = 0
ActivateOutput()
local startdir = findReplace.filedirText
DisplayOutputLn(("%s '%s'."):format(
(replace and TR("Replacing") or TR("Searching for")),
@@ -288,6 +322,18 @@ function findReplace:RunInFiles(replace)
findReplace.oveditor = nil
end
local function getExts()
local knownexts = {}
for i,spec in pairs(ide.specs) do
if (spec.exts) then
for n,ext in ipairs(spec.exts) do
table.insert(knownexts, "*."..ext)
end
end
end
return #knownexts > 0 and table.concat(knownexts, "; ") or nil
end
function findReplace:createDialog(replace,infiles)
local ID_FIND_NEXT = 1
local ID_REPLACE = 2
@@ -339,18 +385,21 @@ function findReplace:createDialog(replace,infiles)
local infilesDirStat,infilesDirCombo,infilesDirButton
if (infiles) then
infilesMaskStat = wx.wxStaticText(findDialog, wx.wxID_ANY, TR("File Type")..": ")
infilesMaskCombo = wx.wxComboBox(findDialog, wx.wxID_ANY, findReplace.filemaskText,
infilesMaskCombo = wx.wxComboBox(findDialog, wx.wxID_ANY,
findReplace.filemaskText or getExts() or "*.*",
wx.wxDefaultPosition, wx.wxDefaultSize, findReplace.filemaskTextArray)
local fname = GetEditorFileAndCurInfo(true)
if (fname) then
findReplace.filedirText = fname:GetPath(wx.wxPATH_GET_VOLUME)
if #(findReplace.filedirText) == 0 then
findReplace.filedirText = ide.config.path.projectdir
or fname and fname:GetPath(wx.wxPATH_GET_VOLUME)
or ""
end
infilesDirStat = wx.wxStaticText(findDialog, wx.wxID_ANY, TR("Directory")..": ")
infilesDirCombo = wx.wxComboBox(findDialog, wx.wxID_ANY, findReplace.filedirText,
wx.wxDefaultPosition, wx.wxDefaultSize, findReplace.filedirTextArray)
infilesDirButton = wx.wxButton(findDialog, ID_SETDIR, "...",wx.wxDefaultPosition, wx.wxSize(26,20))
infilesDirButton = wx.wxButton(findDialog, ID_SETDIR, "...", wx.wxDefaultPosition, wx.wxSize(26,20))
end
local replaceStatText, replaceTextCombo
@@ -537,7 +586,7 @@ function findReplace:createDialog(replace,infiles)
local res = filePicker:ShowModal(true)
if res == wx.wxID_OK then
infilesDirCombo:SetValue(filePicker:GetPath())
infilesDirCombo:SetValue(FixDir(filePicker:GetPath()))
end
end)
end

View File

@@ -5,7 +5,7 @@ local ide = ide
-- Pick some reasonable fixed width fonts to use for the editor
local function setFont(style, config)
return wx.wxFont(config.fontsize or size or 10, wx.wxFONTFAMILY_MODERN, style,
return wx.wxFont(config.fontsize or 10, wx.wxFONTFAMILY_MODERN, style,
wx.wxFONTWEIGHT_NORMAL, false, config.fontname or "",
config.fontencoding or wx.wxFONTENCODING_DEFAULT)
end
@@ -33,7 +33,7 @@ end
-- Create the wxFrame
-- ----------------------------------------------------------------------------
local function createFrame()
frame = wx.wxFrame(wx.NULL, wx.wxID_ANY, GetIDEString("editor"),
local frame = wx.wxFrame(wx.NULL, wx.wxID_ANY, GetIDEString("editor"),
wx.wxDefaultPosition, wx.wxSize(1000, 700))
-- wrap into protected call as DragAcceptFiles fails on MacOS with
-- wxwidgets 2.8.12 even though it should work according to change notes
@@ -172,15 +172,25 @@ local function createNotebook(frame)
menu:AppendSeparator()
menu:Append(ID_SAVE, TR("&Save"))
menu:Append(ID_SAVEAS, TR("Save &As..."))
menu:AppendSeparator()
menu:Append(ID_SHOWLOCATION, TR("Show Location"))
PackageEventHandle("onMenuEditorTab", menu, notebook, event)
notebook:PopupMenu(menu)
end)
local function IfAtLeastOneTab(event) event:Enable(notebook:GetPageCount() > 0) end
local function IfAtLeastOneTab(event)
event:Enable(notebook:GetPageCount() > 0)
if ide.osname == 'Macintosh' and (event:GetId() == ID_CLOSEALL
or event:GetId() == ID_CLOSE and notebook:GetPageCount() <= 1)
then event:Enable(false) end
end
local function IfModified(event) event:Enable(EditorIsModified(GetEditor(selection))) end
notebook:Connect(ID_SAVE, wx.wxEVT_COMMAND_MENU_SELECTED, function ()
local editor = GetEditor(selection)
SaveFile(editor, openDocuments[editor:GetId()].filePath)
SaveFile(editor, ide.openDocuments[editor:GetId()].filePath)
end)
notebook:Connect(ID_SAVE, wx.wxEVT_UPDATE_UI, IfModified)
notebook:Connect(ID_SAVEAS, wx.wxEVT_COMMAND_MENU_SELECTED, function()
@@ -201,6 +211,10 @@ local function createNotebook(frame)
notebook:Connect(ID_CLOSEOTHER, wx.wxEVT_UPDATE_UI, function (event)
event:Enable(notebook:GetPageCount() > 1)
end)
notebook:Connect(ID_SHOWLOCATION, wx.wxEVT_COMMAND_MENU_SELECTED, function()
ShowLocation(ide:GetDocument(GetEditor(selection)):GetFilePath())
end)
notebook:Connect(ID_SHOWLOCATION, wx.wxEVT_UPDATE_UI, IfAtLeastOneTab)
frame.notebook = notebook
return notebook

View File

@@ -15,6 +15,7 @@ ID_OPEN = wx.wxID_OPEN
ID_CLOSE = NewID()
ID_CLOSEALL = NewID()
ID_CLOSEOTHER = NewID()
ID_SHOWLOCATION = NewID()
ID_SAVE = wx.wxID_SAVE
ID_SAVEAS = wx.wxID_SAVEAS
ID_SAVEALL = NewID()
@@ -77,11 +78,19 @@ ID_PROJECTDIRFROMFILE = NewID()
ID_PROJECTDIRCHOOSE = NewID()
-- Help menu
ID_ABOUT = wx.wxID_ABOUT
ID_HELPPROJECT = NewID()
ID_HELPDOCUMENTATION = NewID()
ID_HELPGETTINGSTARTED = NewID()
ID_HELPTUTORIALS = NewID()
ID_HELPFAQ = NewID()
ID_HELPCOMMUNITY = NewID()
-- Watch window menu items
ID_ADDWATCH = NewID()
ID_EDITWATCH = NewID()
ID_DELETEWATCH = NewID()
-- Editor popup menu items
ID_GOTODEFINITION = NewID()
ID_RENAMEALLINSTANCES = NewID()
ID_QUICKADDWATCH = NewID()
ID_QUICKEVAL = NewID()
ID_ADDTOSCRATCHPAD = NewID()

View File

@@ -2,7 +2,7 @@
-- (C) 2012 Paul Kulchenko
local M, LA, LI, T = {}
local FAST = true
local FAST = false
local function init()
if LA then return end
@@ -44,7 +44,7 @@ function M.show_warnings(top_ast)
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 = {}, {}
local isseen, globseen, fieldseen = {}, {}, {}
LA.walk(top_ast, function(ast)
local line = ast.lineinfo and ast.lineinfo.first[1] or 0
local path = ast.lineinfo and ast.lineinfo.first[4] or '?'
@@ -105,7 +105,14 @@ function M.show_warnings(top_ast)
-- added check for FAST as ast.seevalue relies on value evaluation,
-- which is very slow even on simple and short scripts
if not FAST and ast.isfield and not(known(ast.seevalue.value) and ast.seevalue.value ~= nil) then
warn("unknown field " .. name, ast.lineinfo.first[1], path)
if not fieldseen[name] then
fieldseen[name] = true
local parent = ast.parent
and (" in '"..index(ast.parent):gsub("%."..name.."$","").."'")
or ""
warn("first use of unknown field '" .. name .."'"..parent,
ast.lineinfo.first[1], path)
end
elseif ast.tag == 'Id' and not ast.localdefinition and not ast.definedglobal then
if not globseen[name] then
globseen[name] = true
@@ -136,7 +143,7 @@ function M.show_warnings(top_ast)
local note = vast.parent
and (vast.parent.tag == 'Call' or vast.parent.tag == 'Invoke')
and vast.parent.note
if note and not isseen[vast.parent] then
if note and not isseen[vast.parent] and type(name) == "string" then
isseen[vast.parent] = true
warn("function '" .. name .. "': " .. note, line, path)
end

View File

@@ -61,11 +61,15 @@ function MarkupHotspotClick(pos, editor)
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)%)$]])
or FileTreeGetDir()
local _,_,http = string.find(text, [[^(https?:%S+)$]])
local _,_,command = string.find(text, [[^macro:(%w+)$]])
if shell then
ShellExecuteCode(shell)
local _,_,command,code = string.find(text, [[^macro:(%w+)%((.*%S)%)$]])
if not command then _,_,command = string.find(text, [[^macro:(%w+)$]]) end
if command == 'shell' then
ShellExecuteCode(code)
elseif command == 'inline' then
ShellExecuteInline(code)
elseif command == 'run' then -- run the current file
ProjectRun()
elseif command == 'debug' then -- debug the current file
@@ -129,12 +133,16 @@ function MarkupStyle(editor, lines, linee)
local lines = lines or 0
if (lines < 0) then return end
-- if the current spec doesn't have any comments, nothing to style
if not next(editor.spec.iscomment) then return end
-- always style to the end as there may be comments that need re-styling
-- technically, this should be GetLineCount()-1, but we want to style
-- beyond the last line to make sure it is styled correctly
local linec = editor:GetLineCount()
local linee = linee or linec
local linecomment = editor.spec.linecomment
local iscomment = {}
for i,v in pairs(editor.spec.iscomment) do
iscomment[i] = v
@@ -163,7 +171,8 @@ function MarkupStyle(editor, lines, linee)
local s = bit.band(editor:GetStyleAt(p), 31)
-- 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
-- also ignore matches for line comments (as defined in the spec)
if iscomment[s] and p > 0 and mark ~= linecomment then
local smark = #mark
local emark = #mark -- assumes end mark is the same length as start mark
if mark == MD_MARK_HEAD then
@@ -196,5 +205,7 @@ function MarkupStyle(editor, lines, linee)
-- invisible styles hide some of the content that would be wrapped.
local wrapmode = editor:GetWrapMode()
if wrapmode ~= wxstc.wxSTC_WRAP_NONE then editor:SetWrapMode(wrapmode) end
-- if some of the lines have folded, this can make not styled lines visible
MarkupStyle(editor, linee+1) -- style to the end in this case
end
end

View File

@@ -25,6 +25,7 @@ local editMenu = wx.wxMenu{
{ },
{ ID_FOLD, TR("&Fold/Unfold All")..KSC(ID_FOLD), TR("Fold or unfold all code folds") },
{ ID_CLEARDYNAMICWORDS, TR("Clear &Dynamic Words")..KSC(ID_CLEARDYNAMICWORDS), TR("Resets the dynamic word list for autocompletion") },
{ ID_SORT, TR("&Sort")..KSC(ID_SORT), TR("Sort selected lines") },
{ },
}
@@ -53,10 +54,10 @@ function OnUpdateUIEditMenu(event)
local editor = getControlWithFocus()
if editor == nil then event:Enable(false); return end
local alwaysOn = { [ID_SELECTALL] = true, [ID_FOLD] = true,
local alwaysOn = { [ID_SELECTALL] = true, [ID_FOLD] = ide.config.editor.fold,
-- allow Cut and Copy commands as these work on a line if no selection
[ID_COPY] = true, [ID_CUT] = true,
[ID_COMMENT] = true, [ID_AUTOCOMPLETE] = true}
[ID_COMMENT] = true, [ID_AUTOCOMPLETE] = true, [ID_SORT] = true}
local menu_id = event:GetId()
local enable =
menu_id == ID_PASTE and editor:CanPaste() or
@@ -155,24 +156,82 @@ frame:Connect(ID_AUTOCOMPLETEENABLE, wx.wxEVT_COMMAND_MENU_SELECTED,
frame:Connect(ID_COMMENT, wx.wxEVT_COMMAND_MENU_SELECTED,
function (event)
local editor = GetEditor()
local buf = {}
if editor:GetSelectionStart() == editor:GetSelectionEnd() then
local lineNumber = editor:GetCurrentLine()
editor:SetSelection(editor:PositionFromLine(lineNumber), editor:GetLineEndPosition(lineNumber))
end
-- capture the current position in line to restore later
local curline = editor:GetCurrentLine()
local curlen = #editor:GetLine(curline)
local curpos = editor:GetCurrentPos()-editor:PositionFromLine(curline)
-- for multi-line selection, always start the first line at the beginning
local ssel, esel = editor:GetSelectionStart(), editor:GetSelectionEnd()
local sline = editor:LineFromPosition(ssel)
local eline = editor:LineFromPosition(esel)
local sel = ssel ~= esel
local rect = editor:SelectionIsRectangle()
local lc = editor.spec.linecomment
for line in string.gmatch(editor:GetSelectedText()..'\n', "(.-)\r?\n") do
if string.sub(line,1,#lc) == lc then
line = string.sub(line,#lc+1)
elseif #line > 0 then
line = lc..line
local qlc = lc:gsub(".", "%%%1")
-- figure out how to toggle comments; if there is at least one non-empty
-- line that doesn't start with a comment, need to comment
local comment = false
for line = sline, eline do
local pos = sel and (sline == eline or rect)
and ssel-editor:PositionFromLine(sline)+1 or 1
local text = editor:GetLine(line)
local _, cpos = text:find("^%s*"..qlc, pos)
if not cpos and text:find("%S")
-- ignore last line when the end of selection is at the first position
and (line == sline or line < eline or esel-editor:PositionFromLine(line) > 0) then
comment = true
break
end
table.insert(buf, line)
end
editor:ReplaceSelection(table.concat(buf,"\n"))
editor:BeginUndoAction()
-- go last to first as selection positions we captured may be affected
-- by text changes
for line = eline, sline, -1 do
local pos = sel and (sline == eline or rect)
and ssel-editor:PositionFromLine(sline)+1 or 1
local text = editor:GetLine(line)
local _, cpos = text:find("^%s*"..qlc, pos)
if not comment and cpos then
editor:DeleteRange(cpos-#lc+editor:PositionFromLine(line), #lc)
elseif comment and text:find("%S")
and (line == sline or line < eline or esel-editor:PositionFromLine(line) > 0) then
editor:InsertText(pos+editor:PositionFromLine(line)-1, lc)
end
end
editor:EndUndoAction()
-- fix position if it was after where the selection started
if editor:PositionFromLine(curline)+curpos > ssel then
-- position the cursor exactly where its position was, which
-- could have shifted depending on whether the text was added or removed.
editor:GotoPos(editor:PositionFromLine(curline)
+ math.max(0, curpos+#editor:GetLine(curline)-curlen))
end
end)
frame:Connect(ID_COMMENT, wx.wxEVT_UPDATE_UI, OnUpdateUIEditMenu)
frame:Connect(ID_SORT, wx.wxEVT_COMMAND_MENU_SELECTED,
function (event)
local editor = GetEditor()
local buf = {}
for line in string.gmatch(editor:GetSelectedText()..'\n', "(.-)\r?\n") do
table.insert(buf, line)
end
if #buf > 0 then
local newline
if #(buf[#buf]) == 0 then newline = table.remove(buf) end
table.sort(buf)
-- add new line at the end if it was there
if newline then table.insert(buf, newline) end
editor:ReplaceSelection(table.concat(buf,"\n"))
end
end)
frame:Connect(ID_SORT, wx.wxEVT_UPDATE_UI, OnUpdateUIEditMenu)
frame:Connect(ID_FOLD, wx.wxEVT_COMMAND_MENU_SELECTED,
function (event)
FoldSome()

View File

@@ -154,7 +154,7 @@ do -- recent file history
end
end
frame:Connect(ID_NEW, wx.wxEVT_COMMAND_MENU_SELECTED, NewFile)
frame:Connect(ID_NEW, wx.wxEVT_COMMAND_MENU_SELECTED, function() return NewFile() end)
frame:Connect(ID_OPEN, wx.wxEVT_COMMAND_MENU_SELECTED, OpenFile)
frame:Connect(ID_SAVE, wx.wxEVT_COMMAND_MENU_SELECTED,
function ()

View File

@@ -8,8 +8,24 @@ local frame = ide.frame
local menuBar = frame.menuBar
local mobdebug = require "mobdebug"
local url = "http://download.zerobrane.com/zerobranestudio-"
local urls = {
[ID_HELPPROJECT] = "main",
[ID_HELPDOCUMENTATION] = "documentation",
[ID_HELPGETTINGSTARTED] = "gettingstarted",
[ID_HELPTUTORIALS] = "tutorials",
[ID_HELPFAQ] = "faq",
[ID_HELPCOMMUNITY] = "community",
}
local helpMenu = wx.wxMenu{
{ ID_ABOUT, TR("&About")..KSC(ID_ABOUT), TR("About %s"):format(GetIDEString("editor")) },
{ ID_HELPPROJECT, TR("&Project Page")..KSC(ID_HELPPROJECT) },
{ ID_HELPDOCUMENTATION, TR("&Documentation")..KSC(ID_HELPDOCUMENTATION) },
{ ID_HELPGETTINGSTARTED, TR("&Getting Started Guide")..KSC(ID_HELPGETTINGSTARTED) },
{ ID_HELPTUTORIALS, TR("&Tutorials")..KSC(ID_HELPTUTORIALS) },
{ ID_HELPFAQ, TR("&Frequently Asked Questions")..KSC(ID_HELPFAQ) },
{ ID_HELPCOMMUNITY, TR("&Community")..KSC(ID_HELPCOMMUNITY) },
}
-- do not translate Help menu on Mac as it won't merge with "standard" menus
menuBar:Append(helpMenu, ide.osname == 'Macintosh' and "&Help" or TR("&Help"))
@@ -94,3 +110,7 @@ local function DisplayAbout(event)
end
frame:Connect(ID_ABOUT, wx.wxEVT_COMMAND_MENU_SELECTED, DisplayAbout)
for item, page in pairs(urls) do
frame:Connect(item, wx.wxEVT_COMMAND_MENU_SELECTED,
function() wx.wxLaunchDefaultBrowser(url..page, 0) end)
end

View File

@@ -11,30 +11,6 @@ local uimgr = frame.uimgr
------------------------
-- Interpreters and Menu
local targetMenu
local interpreters = {}
local lastinterpreter
do
local interpreternames = {}
local lkinterpreters = {}
for i,v in pairs(ide.interpreters) do
interpreters[ID ("debug.interpreter."..i)] = v
v.fname = i
lastinterpreter = i
table.insert(interpreternames,v.name)
lkinterpreters[v.name] = i
end
assert(lastinterpreter,"no interpreters defined")
table.sort(interpreternames)
local targetargs = {}
for _,v in ipairs(interpreternames) do
local id = ID("debug.interpreter."..lkinterpreters[v])
local inter = interpreters[id]
table.insert(targetargs,{id,inter.name,inter.description,wx.wxITEM_CHECK})
end
targetMenu = wx.wxMenu(targetargs)
end
local debugTab = {
{ ID_RUN, TR("&Run")..KSC(ID_RUN), TR("Execute the current project/file") },
@@ -59,6 +35,7 @@ local targetDirMenu = wx.wxMenu{
{ID_PROJECTDIRCHOOSE, TR("Choose ...")..KSC(ID_PROJECTDIRCHOOSE), TR("Choose a project directory")},
{ID_PROJECTDIRFROMFILE, TR("Set From Current File")..KSC(ID_PROJECTDIRFROMFILE), TR("Set project directory from current file")},
}
local targetMenu = wx.wxMenu({})
local debugMenu = wx.wxMenu(debugTab)
local debugMenuRun = {
start=TR("Start &Debugging")..KSC(ID_STARTDEBUG), continue=TR("Co&ntinue")..KSC(ID_STARTDEBUG)}
@@ -68,20 +45,81 @@ debugMenu:Append(ID_PROJECTDIR, TR("Project Directory"), targetDirMenu, TR("Set
debugMenu:Append(ID_INTERPRETER, TR("Lua &Interpreter"), targetMenu, TR("Set the interpreter to be used"))
menuBar:Append(debugMenu, TR("&Project"))
local interpreters
local function selectInterpreter(id)
for id in pairs(interpreters) do
menuBar:Check(id, false)
menuBar:Enable(id, true)
end
menuBar:Check(id, true)
menuBar:Enable(id, false)
if ide.interpreter and ide.interpreter ~= interpreters[id] then
PackageEventHandle("onInterpreterClose", ide.interpreter) end
ide.interpreter = interpreters[id]
PackageEventHandle("onInterpreterLoad", ide.interpreter)
DebuggerShutdown()
ide.frame.statusBar:SetStatusText(ide.interpreter.name or "", 5)
ReloadLuaAPI()
end
function ProjectSetInterpreter(name)
local id = IDget("debug.interpreter."..name)
if (not interpreters[id]) then return end
selectInterpreter(id)
end
local function evSelectInterpreter(event)
selectInterpreter(event:GetId())
end
function UpdateInterpreters()
assert(ide.interpreters, "no interpreters defined")
-- delete all existing items (if any)
local items = targetMenu:GetMenuItemCount()
for i = items, 1, -1 do
targetMenu:Delete(targetMenu:FindItemByPosition(i-1))
end
local names = {}
for file in pairs(ide.interpreters) do table.insert(names, file) end
table.sort(names)
interpreters = {}
for i, file in ipairs(names) do
local inter = ide.interpreters[file]
local id = ID("debug.interpreter."..file)
inter.fname = file
interpreters[id] = inter
targetMenu:Append(
wx.wxMenuItem(targetMenu, id, inter.name, inter.description, wx.wxITEM_CHECK))
frame:Connect(id, wx.wxEVT_COMMAND_MENU_SELECTED, evSelectInterpreter)
end
local id = (
-- interpreter is set and is (still) on the list of known interpreters
IDget("debug.interpreter."
..(ide.interpreter and ide.interpreters[ide.interpreter.fname]
and ide.interpreter.fname or ide.config.interpreter)) or
-- otherwise use default interpreter
ID("debug.interpreter."..ide.config.default.interpreter)
)
selectInterpreter(id)
end
UpdateInterpreters()
-----------------------------
-- Project directory handling
function ProjectUpdateProjectDir(projdir,skiptree)
local dir = wx.wxFileName.DirName(projdir)
-- wxwidgets 2.9.x may report the last folder twice (depending on how the
-- user selects the folder), which makes the selected folder incorrect.
-- check if the last segment is repeated and drop it.
if not wx.wxDirExists(projdir) then
local dirs = dir:GetDirs()
if #dirs > 1 and dirs[-1] == dirs[-2] then dir:RemoveLastDir() end
if not wx.wxDirExists(dir:GetFullPath()) then return end
end
local dir = wx.wxFileName.DirName(FixDir(projdir))
if not wx.wxDirExists(dir:GetFullPath()) then return end
projdir = dir:GetPath(wx.wxPATH_GET_VOLUME) -- no trailing slash
@@ -126,47 +164,8 @@ local function projFromFile(event)
end
frame:Connect(ID_PROJECTDIRFROMFILE, wx.wxEVT_COMMAND_MENU_SELECTED, projFromFile)
------------------------------------
-- Interpreter Selection and Running
local function selectInterpreter(id)
for id in pairs(interpreters) do
menuBar:Check(id, false)
menuBar:Enable(id, true)
end
menuBar:Check(id, true)
menuBar:Enable(id, false)
ide.interpreter = interpreters[id]
DebuggerShutdown()
ide.frame.statusBar:SetStatusText(ide.interpreter.name or "", 5)
ReloadLuaAPI()
end
function ProjectSetInterpreter(name)
local id = IDget("debug.interpreter."..name)
if (not interpreters[id]) then return end
selectInterpreter(id)
end
local function evSelectInterpreter(event)
selectInterpreter(event:GetId())
end
for id in pairs(interpreters) do
frame:Connect(id,wx.wxEVT_COMMAND_MENU_SELECTED,evSelectInterpreter)
end
do
local defaultid = (
IDget("debug.interpreter."..ide.config.interpreter) or
ID("debug.interpreter."..lastinterpreter)
)
ide.interpreter = interpreters[defaultid]
menuBar:Check(defaultid, true)
end
----------------------
-- Interpreter Running
local function getNameToRun(skipcheck)
local editor = GetEditor()
@@ -184,6 +183,7 @@ local function getNameToRun(skipcheck)
local id = editor:GetId()
if not openDocuments[id].filePath then SetDocumentModified(id, true) end
if not SaveIfModified(editor) then return end
if ide.config.editor.saveallonrun then SaveAll(true) end
return wx.wxFileName(openDocuments[id].filePath)
end
@@ -313,9 +313,9 @@ frame:Connect(ID_STARTDEBUG, wx.wxEVT_UPDATE_UI,
function (event)
local editor = GetEditor()
event:Enable((ide.interpreter) and (ide.interpreter.hasdebugger) and
((debugger.server == nil and debugger.pid == nil) or
((debugger.server == nil and debugger.pid == nil and editor ~= nil) or
(debugger.server ~= nil and not debugger.running)) and
(editor ~= nil) and (not debugger.scratchpad or debugger.scratchpad.paused))
(not debugger.scratchpad or debugger.scratchpad.paused))
local label = (debugger.server ~= nil)
and debugMenuRun.continue or debugMenuRun.start
if debugMenu:GetLabel(ID_STARTDEBUG) ~= label then
@@ -327,8 +327,7 @@ frame:Connect(ID_STOPDEBUG, wx.wxEVT_COMMAND_MENU_SELECTED,
function () DebuggerShutdown() end)
frame:Connect(ID_STOPDEBUG, wx.wxEVT_UPDATE_UI,
function (event)
local editor = GetEditor()
event:Enable((debugger.server ~= nil or debugger.pid ~= nil) and (editor ~= nil))
event:Enable(debugger.server ~= nil or debugger.pid ~= nil)
local label = (debugger.server == nil and debugger.pid ~= nil)
and debugMenuStop.process or debugMenuStop.debugging
if debugMenu:GetLabel(ID_STOPDEBUG) ~= label then
@@ -392,8 +391,7 @@ frame:Connect(ID_BREAK, wx.wxEVT_COMMAND_MENU_SELECTED,
end)
frame:Connect(ID_BREAK, wx.wxEVT_UPDATE_UI,
function (event)
local editor = GetEditor()
event:Enable((debugger.server ~= nil) and (editor ~= nil)
event:Enable(debugger.server ~= nil
and (debugger.running
or (debugger.scratchpad and not debugger.scratchpad.paused)))
end)
@@ -402,5 +400,7 @@ frame:Connect(wx.wxEVT_IDLE,
function(event)
if (debugger.update) then debugger.update() end
if (debugger.scratchpad) then DebuggerRefreshScratchpad() end
if IndicateIfNeeded() then event:RequestMore(true) end
PackageEventHandleOnce("onIdleOnce", event)
event:Skip() -- let other EVT_IDLE handlers to work on the event
end)

View File

@@ -19,8 +19,7 @@ local findMenu = wx.wxMenu{
{ ID_REPLACEINFILES, TR("Re&place In Files")..KSC(ID_REPLACEINFILES), TR("Find and replace text in files") },
{ },
{ ID_GOTOLINE, TR("&Goto Line")..KSC(ID_GOTOLINE), TR("Go to a selected line") },
{ },
{ ID_SORT, TR("&Sort")..KSC(ID_SORT), TR("Sort selected lines") }}
}
menuBar:Append(findMenu, TR("&Search"))
function OnUpdateUISearchMenu(event) event:Enable(GetEditor() ~= nil) end
@@ -47,12 +46,34 @@ frame:Connect(ID_REPLACEINFILES, wx.wxEVT_COMMAND_MENU_SELECTED,
end)
frame:Connect(ID_FINDNEXT, wx.wxEVT_COMMAND_MENU_SELECTED,
function (event) findReplace:GetSelectedString() findReplace:FindString() end)
function (event)
local editor = GetEditor()
if editor and ide.wxver >= "2.9.5" and editor:GetSelections() > 1 then
local selection = editor:GetMainSelection() + 1
if selection >= editor:GetSelections() then selection = 0 end
editor:SetMainSelection(selection)
editor:EnsureCaretVisible()
else
findReplace:GetSelectedString()
findReplace:FindString()
end
end)
frame:Connect(ID_FINDNEXT, wx.wxEVT_UPDATE_UI,
function (event) event:Enable(findReplace:GetSelectedString() or findReplace:HasText()) end)
frame:Connect(ID_FINDPREV, wx.wxEVT_COMMAND_MENU_SELECTED,
function (event) findReplace:GetSelectedString() findReplace:FindString(true) end)
function (event)
local editor = GetEditor()
if editor and ide.wxver >= "2.9.5" and editor:GetSelections() > 1 then
local selection = editor:GetMainSelection() - 1
if selection < 0 then selection = editor:GetSelections() - 1 end
editor:SetMainSelection(selection)
editor:EnsureCaretVisible()
else
findReplace:GetSelectedString()
findReplace:FindString(true)
end
end)
frame:Connect(ID_FINDPREV, wx.wxEVT_UPDATE_UI,
function (event) event:Enable(findReplace:GetSelectedString() or findReplace:HasText()) end)
@@ -73,17 +94,3 @@ frame:Connect(ID_GOTOLINE, wx.wxEVT_COMMAND_MENU_SELECTED,
end
end)
frame:Connect(ID_GOTOLINE, wx.wxEVT_UPDATE_UI, OnUpdateUISearchMenu)
frame:Connect(ID_SORT, wx.wxEVT_COMMAND_MENU_SELECTED,
function (event)
local editor = GetEditor()
local buf = {}
for line in string.gmatch(editor:GetSelectedText()..'\n', "(.-)\r?\n") do
table.insert(buf, line)
end
if #buf > 0 then
table.sort(buf)
editor:ReplaceSelection(table.concat(buf,"\n"))
end
end)
frame:Connect(ID_SORT, wx.wxEVT_UPDATE_UI, OnUpdateUISearchMenu)

View File

@@ -16,9 +16,10 @@ local PROMPT_MARKER_VALUE = 2^PROMPT_MARKER
errorlog:Show(true)
errorlog:SetFont(ide.font.oNormal)
errorlog:StyleSetFont(wxstc.wxSTC_STYLE_DEFAULT, ide.font.oNormal)
errorlog:SetBufferedDraw(not ide.config.hidpi and true or false)
errorlog:StyleClearAll()
errorlog:SetMarginWidth(1, 16) -- marker margin
errorlog:SetMarginType(1, wxstc.wxSTC_MARGIN_SYMBOL);
errorlog:SetMarginType(1, wxstc.wxSTC_MARGIN_SYMBOL)
errorlog:MarkerDefine(StylesGetMarker("message"))
errorlog:MarkerDefine(StylesGetMarker("prompt"))
errorlog:SetReadOnly(true)
@@ -67,18 +68,18 @@ function DetachChildProcess()
end
function CommandLineRunning(uid)
for pid,custom in pairs(customprocs) do
if (custom.uid == uid and custom.proc and custom.proc.Exists(tonumber(tostring(pid)))) then
return true
for pid, custom in pairs(customprocs) do
if (custom.uid == uid and custom.proc and custom.proc.Exists(tonumber(pid))) then
return pid, custom.proc
end
end
return false
return
end
function CommandLineToShell(uid,state)
for pid,custom in pairs(customprocs) do
if ((pid == uid or custom.uid == uid) and custom.proc and custom.proc.Exists(tonumber(tostring(pid))) )then
if (pid == uid or custom.uid == uid) and custom.proc and custom.proc.Exists(tonumber(pid)) then
if (streamins[pid]) then streamins[pid].toshell = state end
if (streamerrs[pid]) then streamerrs[pid].toshell = state end
return true
@@ -304,33 +305,41 @@ local jumptopatterns = {
}
errorlog:Connect(wxstc.wxEVT_STC_DOUBLECLICK,
function()
function(event)
local line = errorlog:GetCurrentLine()
local linetx = errorlog:GetLine(line)
-- try to detect a filename + line
-- in linetx
local fname
local jumpline
local jumplinepos
-- try to detect a filename and line in linetx
local fname, jumpline, jumplinepos
for _,pattern in ipairs(jumptopatterns) do
fname,jumpline,jumplinepos = linetx:match(pattern)
if (fname and jumpline) then
break
end
if (fname and jumpline) then break end
end
if (fname and jumpline) then
LoadFile(fname,nil,true)
local editor = GetEditor()
local name = GetFullPathIfExists(FileTreeGetDir(), fname)
or FileTreeFindByPartialName(fname)
-- fname may include name of executable, as in "path/to/lua: file.lua";
-- strip it and try to find match again if needed
local fixedname = fname:match(": (.+)")
if not name and fixedname then
name = GetFullPathIfExists(FileTreeGetDir(), fixedname)
or FileTreeFindByPartialName(fixedname)
end
local editor = LoadFile(name or fname,nil,true)
if (editor) then
jumpline = tonumber(jumpline)
jumplinepos = tonumber(jumplinepos)
--editor:ScrollToLine(jumpline)
editor:GotoPos(editor:PositionFromLine(math.max(0,jumpline-1)) + (jumplinepos and (math.max(0,jumplinepos-1)) or 0))
editor:GotoPos(editor:PositionFromLine(math.max(0,jumpline-1))
+ (jumplinepos and (math.max(0,jumplinepos-1)) or 0))
editor:SetFocus()
-- doubleclick can set selection, so reset it
errorlog:SetSelection(event:GetPosition(), event:GetPosition())
event:Skip()
end
end
end)

90
src/editor/package.lua Normal file
View File

@@ -0,0 +1,90 @@
-- Copyright 2013 Paul Kulchenko, ZeroBrane LLC
local ide = ide
function PackageEventHandle(event, ...)
local success
for _, package in pairs(ide.packages) do
if type(package[event]) == 'function' then
local ok, res = pcall(package[event], package, ...)
if ok then
if res == false then success = false end
else
DisplayOutputLn(TR("%s event failed: %s"):format(event, res))
end
end
end
return success
end
function PackageEventHandleOnce(event, ...)
local success = PackageEventHandle(event, ...)
-- remove all handlers as they need to be called only once
-- this allows them to be re-installed if needed
for _, package in pairs(ide.packages) do
if type(package[event]) == 'function' then
package[event] = nil
end
end
return success
end
local function PackageEventHandleOne(file, event, ...)
local package = ide.packages[file]
if package and type(package[event]) == 'function' then
local ok, res = pcall(package[event], package, ...)
if ok then
if res == false then return false end
else
DisplayOutputLn(TR("%s event failed: %s"):format(event, res))
end
end
end
function PackageUnRegister(file, ...)
PackageEventHandleOne(file, "onUnRegister", ...)
-- remove from the list of installed packages
ide.packages[file] = nil
end
function PackageRegister(file, ...)
if not ide.packages[file] then
local packages = {}
local package = MergeFullPath(
GetPathWithSep(ide.editorFilename), "packages/"..file..".lua")
LoadLuaFileExt(packages, package, ide.proto.Plugin)
packages[file].fname = file
ide.packages[file] = packages[file]
end
return PackageEventHandleOne(file, "onRegister", ...)
end
function ide:GetEditor(index) return GetEditor(index) end
function ide:GetMenuBar() return self.frame.menuBar end
function ide:GetMainFrame() return self.frame end
function ide:GetDocument(ed) return self.openDocuments[ed:GetId()] end
function ide:GetInterpreter() return self.interpreter end
function ide:GetConfig() return self.config end
function ide:GetOutput() return self.frame.bottomnotebook.errorlog end
function ide:GetEditorNotebook() return self.frame.notebook end
function ide:AddInterpreter(name, interpreter)
self.interpreters[name] = setmetatable(interpreter, ide.proto.Interpreter)
UpdateInterpreters()
end
function ide:RemoveInterpreter(name)
self.interpreters[name] = nil
UpdateInterpreters()
end
function ide:AddSpec(name, spec)
self.specs[name] = spec
UpdateSpecs()
end
function ide:RemoveSpec(name) self.specs[name] = nil end
function ide:AddAPI(type, name, api)
self.apis[type] = self.apis[type] or {}
self.apis[type][name] = api
end
function ide:RemoveAPI(type, name) self.apis[type][name] = nil end

21
src/editor/proto.lua Normal file
View File

@@ -0,0 +1,21 @@
-- Copyright 2013 Paul Kulchenko, ZeroBrane LLC
ide.proto.Document = {__index = {
GetFileName = function(self) return self.fileName end,
GetFilePath = function(self) return self.filePath end,
GetModTime = function(self) return self.modTime end,
IsModified = function(self) return self.isModified end,
}}
ide.proto.Plugin = {__index = {
GetName = function(self) return self.name end,
GetFileName = function(self) return self.fname end,
GetConfig = function(self) return ide.config[self.fname] or {} end,
GetSettings = function(self) return SettingsRestorePackage(self.fname) end,
SetSettings = function(self, settings) SettingsSavePackage(self.fname, settings) end,
}}
ide.proto.Interpreter = {__index = {
GetName = function(self) return self.name end,
GetFileName = function(self) return self.fname end,
}}

View File

@@ -212,7 +212,7 @@ function SettingsSaveProjectSession(projdirs)
settings:Write(tostring(i), dir)
local opendocs, params = ProjectConfig(dir)
if opendocs and #opendocs > 0 then
if opendocs then
SettingsSaveFileSession(opendocs, params, listname .. "/" .. tostring(i))
end
end
@@ -220,6 +220,38 @@ function SettingsSaveProjectSession(projdirs)
settings:SetPath(path)
end
function SettingsRestorePackage(package)
local packagename = "/package/"..package
local path = settings:GetPath()
settings:SetPath(packagename)
local outtab = {}
local ismore, key, index = settings:GetFirstEntry("", 0)
while (ismore) do
local couldread, value = settings:Read(key, "")
if couldread then
local ok, res = LoadSafe("return "..value)
if ok then outtab[key] = res
else outtab[key] = nil end
end
ismore, key, index = settings:GetNextEntry(index)
end
settings:SetPath(path)
return outtab
end
function SettingsSavePackage(package, values)
local packagename = "/package/"..package
local path = settings:GetPath()
local mdb = require('mobdebug')
settings:DeleteGroup(packagename)
settings:SetPath(packagename)
for k,v in pairs(values or {}) do
settings:Write(k, mdb.line(v, {comment = false, nocode = true}))
end
settings:SetPath(path)
end
-----------------------------------
local function saveNotebook(nb)
@@ -253,8 +285,8 @@ local function saveNotebook(nb)
return t
end
sortedX = sortedPages(pagesX)
sortedY = sortedPages(pagesY)
local sortedX = sortedPages(pagesX)
local sortedY = sortedPages(pagesY)
-- for now only support "1D" splits and prefer
-- dimension which has more, anything else

View File

@@ -17,8 +17,8 @@ local MESSAGE_MARKER = StylesGetMarker("message")
out:SetFont(ide.font.oNormal)
out:StyleSetFont(wxstc.wxSTC_STYLE_DEFAULT, ide.font.oNormal)
out:SetBufferedDraw(not ide.config.hidpi and true or false)
out:StyleClearAll()
out:SetBufferedDraw(true)
out:SetTabWidth(ide.config.editor.tabwidth or 2)
out:SetIndent(ide.config.editor.tabwidth or 2)
@@ -75,10 +75,11 @@ end
local function getInput(line)
local nextMarker = line
local count = out:GetLineCount()
repeat
repeat -- check until we find at least some marker
nextMarker = nextMarker+1
until out:MarkerGet(nextMarker) > 0 -- check until we find at least some marker
until out:MarkerGet(nextMarker) > 0 or nextMarker > count-1
return chomp(out:GetTextRange(out:PositionFromLine(line),
out:PositionFromLine(nextMarker)))
end
@@ -97,7 +98,6 @@ local function getNextHistoryLine(forward, promptText)
else
currentHistory = out:MarkerPrevious(currentHistory-1, PROMPT_MARKER_VALUE)
if currentHistory == -1 then
currentHistory = -1
return ""
end
end
@@ -110,6 +110,26 @@ local function getNextHistoryLine(forward, promptText)
return getInput(currentHistory)
end
local function getNextHistoryMatch(promptText)
local count = out:GetLineCount()
if currentHistory == nil then currentHistory = count end
local current = currentHistory
while true do
currentHistory = out:MarkerPrevious(currentHistory-1, PROMPT_MARKER_VALUE)
if currentHistory == -1 then -- restart search from the last item
currentHistory = count
elseif currentHistory ~= getPromptLine() then -- skip current prompt
local input = getInput(currentHistory)
if input:find(promptText, 1, true) == 1 then return input end
end
-- couldn't find anything and made a loop; get out
if currentHistory == current then return end
end
assert(false, "getNextHistoryMatch coudn't find a proper match")
end
local function shellPrint(marker, ...)
local cnt = select('#',...)
if cnt == 0 then return end -- return if nothing to print
@@ -264,6 +284,7 @@ local function executeShellCode(tx)
local addedret, forceexpression = true, tx:match("^%s*=%s*")
tx = tx:gsub("^%s*=%s*","")
local fn
fn, err = loadstring("return "..tx)
if not forceexpression and err and
(err:find("'?<eof>'? expected near '") or
@@ -331,6 +352,7 @@ function ShellExecuteFile(wfilename)
ShellExecuteCode(cmd)
end
ShellExecuteInline = executeShellCode
function ShellExecuteCode(code)
local index = bottomnotebook:GetPageIndex(bottomnotebook.shellbox)
if ide.config.activateoutput and bottomnotebook:GetSelection() ~= index then
@@ -378,6 +400,28 @@ out:Connect(wx.wxEVT_KEY_DOWN,
local promptText = getPromptText()
setPromptText(getNextHistoryLine(true, promptText))
return
elseif key == wx.WXK_TAB then
-- if we are above the prompt line, then don't move
local promptline = getPromptLine()
if out:GetCurrentLine() < promptline then return end
local promptText = getPromptText()
-- save the position in the prompt text to restore
local pos = out:GetCurrentPos()
local text = promptText:sub(1, positionInLine(promptline))
if #text == 0 then return end
-- find the next match and set the prompt text
local match = getNextHistoryMatch(text)
if match then
setPromptText(match)
-- restore the position to make it easier to find the next match
out:GotoPos(pos)
end
return
elseif key == wx.WXK_ESCAPE then
setPromptText("")
return
elseif key == wx.WXK_LEFT or key == wx.WXK_NUMPAD_LEFT then
if not caretOnPromptLine(true) then return end
elseif key == wx.WXK_BACK then

View File

@@ -1,3 +1,4 @@
-- Copyright 2011-13 Paul Kulchenko, ZeroBrane LLC
-- authors: Luxinia Dev (Eike Decker & Christoph Kubisch)
---------------------------------------------------------
----------
@@ -7,12 +8,13 @@
-- ---------------------------
-- fg foreground - {r,g,b} 0-255
-- bg background - {r,g,b} 0-255
-- sel color of the selected block - {r,g,b} 0-255 (only applies to folds)
-- u underline - boolean
-- b bold - boolean
-- i italic - boolean
-- fill fill to end - boolean
-- fn font Face Name - string ("Lucida Console")
-- fx font size - number (11)
-- fs font size - number (11)
-- hs turn hotspot on - true or {r,g,b} 0-255
-- v visibility for symbols of the current style - boolean
@@ -50,11 +52,12 @@ function StylesGetDefault()
sel = {bg = {192, 192, 192}},
caret = {fg = {0, 0, 0}},
caretlinebg = {bg = {240, 240, 230}},
fold = {fg = {90, 90, 80}, bg = {250, 250, 250}},
fold = {fg = {90, 90, 80}, bg = {250, 250, 250}, sel = {90+96, 90, 80}},
whitespace = nil,
fncall = {fg = {128, 128, 255},
st = ide.wxver >= "2.9.5" and wxstc.wxSTC_INDIC_ROUNDBOX or wxstc.wxSTC_INDIC_TT},
-- deprecated; allowed for backward compatibility in case someone does
-- fncall.fg = {...}
fncall = {},
-- markup
['|'] = {fg = {127, 0, 127}},
@@ -69,7 +72,16 @@ function StylesGetDefault()
output = {},
prompt = {},
error = {},
}
},
-- indicators
indicator = {
fncall = {},
varlocal = {},
varglobal = {},
varmasking = {},
varmasked = {},
},
}
end
@@ -83,13 +95,10 @@ local markers = {
}
function StylesGetMarker(marker) return unpack(markers[marker] or {}) end
local function applymarker(editor,marker,clrfg,clrbg)
if (clrfg) then
editor:MarkerSetForeground(marker,clrfg)
end
if (clrbg) then
editor:MarkerSetBackground(marker,clrbg)
end
local function applymarker(editor,marker,clrfg,clrbg,clrsel)
if (clrfg) then editor:MarkerSetForeground(marker,clrfg) end
if (clrbg) then editor:MarkerSetBackground(marker,clrbg) end
if (ide.wxver >= "2.9.5" and clrsel) then editor:MarkerSetBackgroundSelected(marker,clrsel) end
end
local specialmapping = {
sel = function(editor,style)
@@ -103,6 +112,8 @@ local specialmapping = {
else
editor:SetSelBackground(0,wx.wxWHITE)
end
-- set alpha for additional selecton: 0 - transparent, 255 - opaque
if ide.wxver >= "2.9.5" then editor:SetAdditionalSelAlpha(127) end
end,
caret = function(editor,style)
@@ -139,21 +150,25 @@ local specialmapping = {
fold = function(editor,style)
local clrfg = style.fg and wx.wxColour(unpack(style.fg))
local clrbg = style.bg and wx.wxColour(unpack(style.bg))
local clrsel = style.sel and wx.wxColour(unpack(style.sel))
if (clrfg or clrbg) then
-- if selected background is set then enable support for it
if ide.wxver >= "2.9.5" and clrsel then editor:MarkerEnableHighlight(true) end
if (clrfg or clrbg or clrsel) then
-- foreground and background are defined as opposite to what I'd expect
-- for fold markers in Scintilla's terminilogy:
-- background is the color of fold lines/boxes and foreground is the color
-- of everything around fold lines or inside fold boxes.
-- in the following code fg and bg are simply reversed
local clrfg, clrbg = clrbg, clrfg
applymarker(editor,wxstc.wxSTC_MARKNUM_FOLDEROPEN, clrfg, clrbg)
applymarker(editor,wxstc.wxSTC_MARKNUM_FOLDER, clrfg, clrbg)
applymarker(editor,wxstc.wxSTC_MARKNUM_FOLDERSUB, clrfg, clrbg)
applymarker(editor,wxstc.wxSTC_MARKNUM_FOLDERTAIL, clrfg, clrbg)
applymarker(editor,wxstc.wxSTC_MARKNUM_FOLDEREND, clrfg, clrbg)
applymarker(editor,wxstc.wxSTC_MARKNUM_FOLDEROPENMID, clrfg, clrbg)
applymarker(editor,wxstc.wxSTC_MARKNUM_FOLDERMIDTAIL, clrfg, clrbg)
applymarker(editor,wxstc.wxSTC_MARKNUM_FOLDEROPEN, clrfg, clrbg, clrsel)
applymarker(editor,wxstc.wxSTC_MARKNUM_FOLDER, clrfg, clrbg, clrsel)
applymarker(editor,wxstc.wxSTC_MARKNUM_FOLDERSUB, clrfg, clrbg, clrsel)
applymarker(editor,wxstc.wxSTC_MARKNUM_FOLDERTAIL, clrfg, clrbg, clrsel)
applymarker(editor,wxstc.wxSTC_MARKNUM_FOLDEREND, clrfg, clrbg, clrsel)
applymarker(editor,wxstc.wxSTC_MARKNUM_FOLDEROPENMID, clrfg, clrbg, clrsel)
applymarker(editor,wxstc.wxSTC_MARKNUM_FOLDERMIDTAIL, clrfg, clrbg, clrsel)
end
if clrbg then
-- the earlier calls only color the actual markers, but not the
@@ -248,8 +263,24 @@ function StylesApplyToEditor(styles,editor,font,fontitalic,lexerconvert)
end
do
editor:IndicatorSetStyle(0,styles.fncall and styles.fncall.st or wxstc.wxSTC_INDIC_BOX)
editor:IndicatorSetForeground(0,wx.wxColour(unpack(styles.fncall and styles.fncall.fg or {128,128,128})))
local defaultfg = styles.text and styles.text.fg or {127,127,127}
local indic = styles.indicator or {}
-- use styles.fncall if not empty and if indic.fncall is empty
-- for backward compatibility
if type(styles.fncall) == 'table' and next(styles.fncall)
and not (type(indic.fncall) == 'table' and next(indic.fncall)) then indic.fncall = styles.fncall end
editor:IndicatorSetStyle(0, indic.fncall and indic.fncall.st or ide.wxver >= "2.9.5" and wxstc.wxSTC_INDIC_ROUNDBOX or wxstc.wxSTC_INDIC_TT)
editor:IndicatorSetForeground(0, wx.wxColour(unpack(indic.fncall and indic.fncall.fg or {128, 128, 255})))
editor:IndicatorSetStyle(1, indic.varlocal and indic.varlocal.st or wxstc.wxSTC_INDIC_DOTS or wxstc.wxSTC_INDIC_TT)
editor:IndicatorSetForeground(1, wx.wxColour(unpack(indic.varlocal and indic.varlocal.fg or defaultfg)))
editor:IndicatorSetStyle(2, indic.varglobal and indic.varglobal.st or wxstc.wxSTC_INDIC_PLAIN)
editor:IndicatorSetForeground(2, wx.wxColour(unpack(indic.varglobal and indic.varglobal.fg or defaultfg)))
editor:IndicatorSetStyle(3, indic.varmasking and indic.varmasking.st or wxstc.wxSTC_INDIC_DASH or wxstc.wxSTC_INDIC_DIAGONAL)
editor:IndicatorSetForeground(3, wx.wxColour(unpack(indic.varmasking and indic.varmasking.fg or defaultfg)))
editor:IndicatorSetStyle(4, indic.varmasked and indic.varmasked.st or wxstc.wxSTC_INDIC_STRIKE)
editor:IndicatorSetForeground(4, wx.wxColour(unpack(indic.varmasked and indic.varmasked.fg or defaultfg)))
end
end

View File

@@ -45,10 +45,13 @@ ide = {
verbose = false,
hostname = nil,
port = nil,
runonstart = nil,
redirect = nil,
},
default = {
name = 'untitled',
fullname = 'untitled.lua',
interpreter = 'luadeb',
},
outputshell = {},
filetree = {},
@@ -60,9 +63,9 @@ ide = {
styles = nil,
stylesoutshell = nil,
interpreter = "_undefined_",
autocomplete = true,
autoanalizer = true,
acandtip = {
shorttip = false,
ignorecase = false,
@@ -78,19 +81,22 @@ ide = {
savebak = false,
singleinstance = false,
singleinstanceport = 0xe493,
-- HiDPI/Retina display support;
-- `false` by default because of issues with indicators with alpha setting
hidpi = false,
},
specs = {
none = {
linecomment = ">",
sep = "\1",
}
},
tools = {
},
iofilters = {
},
interpreters = {
},
tools = {},
iofilters = {},
interpreters = {},
packages = {},
apis = {},
proto = {}, -- prototypes for various classes
app = nil, -- application engine
interpreter = nil, -- current Lua interpreter
@@ -138,10 +144,32 @@ if not wx.wxMOD_CONTROL then wx.wxMOD_CONTROL = 0x02 end
if not wx.wxMOD_RAW_CONTROL then
wx.wxMOD_RAW_CONTROL = ide.osname == 'Macintosh' and 0x10 or wx.wxMOD_CONTROL
end
-- ArchLinux running 2.8.12.2 doesn't have wx.wxMOD_SHIFT defined
if not wx.wxMOD_SHIFT then wx.wxMOD_SHIFT = 0x04 end
-- wxDIR_NO_FOLLOW is missing in wxlua 2.8.12 as well
if not wx.wxDIR_NO_FOLLOW then wx.wxDIR_NO_FOLLOW = 0x10 end
dofile "src/editor/ids.lua"
dofile "src/editor/style.lua"
dofile "src/editor/keymap.lua"
if not setfenv then -- Lua 5.2
-- based on http://lua-users.org/lists/lua-l/2010-06/msg00314.html
-- this assumes f is a function
local function findenv(f)
local level = 1
repeat
local name, value = debug.getupvalue(f, level)
if name == '_ENV' then return level, value end
level = level + 1
until name == nil
return nil end
getfenv = function (f) return(select(2, findenv(f)) or _G) end
setfenv = function (f, t)
local level = findenv(f)
if level then debug.setupvalue(f, level, t) end
return f end
end
for _, file in ipairs({"ids", "style", "keymap", "proto"}) do
dofile("src/editor/"..file..".lua")
end
ide.config.styles = StylesGetDefault()
ide.config.stylesoutshell = StylesGetDefault()
@@ -149,12 +177,12 @@ ide.config.stylesoutshell = StylesGetDefault()
local function setLuaPaths(mainpath, osname)
-- use LUA_DEV to setup paths for Lua for Windows modules if installed
local luadev = osname == "Windows" and os.getenv('LUA_DEV')
local luadev_path = (luadev
local luadev_path = (luadev and wx.wxDirExists(luadev)
and ('LUA_DEV/?.lua;LUA_DEV/?/init.lua;LUA_DEV/lua/?.lua;LUA_DEV/lua/?/init.lua')
:gsub('LUA_DEV', (luadev:gsub('[\\/]$','')))
or "")
local luadev_cpath = (luadev
and ('LUA_DEV/?.dll;LUA_DEV/clibs/?.dll')
local luadev_cpath = (luadev and wx.wxDirExists(luadev)
and ('LUA_DEV/?.dll;LUA_DEV/?51.dll;LUA_DEV/clibs/?.dll;LUA_DEV/clibs/?51.dll')
:gsub('LUA_DEV', (luadev:gsub('[\\/]$','')))
or "")
@@ -221,45 +249,33 @@ end
ide.app = dofile(ide.config.path.app.."/app.lua")
local app = assert(ide.app)
local function addToTab(tab,file)
local cfgfn,err = loadfile(file)
if not cfgfn then
print(("Error while loading configuration file: '%s'."):format(err))
else
local name = file:match("([a-zA-Z_0-9]+)%.lua$")
local success, result = pcall(function()return cfgfn(assert(_G or _ENV))end)
if not success then
print(("Error while processing configuration file: '%s'."):format(result))
elseif name then
if (tab[name]) then
local out = tab[name]
for i,v in pairs(result) do
out[i] = v
end
else
tab[name] = result
end
local function loadToTab(filter, folder, tab, recursive, proto)
filter = filter and type(filter) ~= 'function' and app.loadfilters[filter] or nil
for _, file in ipairs(FileSysGetRecursive(folder, recursive, "*.lua")) do
if not filter or filter(file) then
LoadLuaFileExt(tab, file, proto)
end
end
end
-- load interpreters
local function loadInterpreters(filter)
for _, file in ipairs(FileSysGetRecursive("interpreters", true, "*.lua")) do
if (filter or app.loadfilters.interpreters)(file) then
addToTab(ide.interpreters,file)
end
end
loadToTab(filter or "interpreters", "interpreters", ide.interpreters, false,
ide.proto.Interpreter)
end
-- load specs
local function loadSpecs(filter)
for _, file in ipairs(FileSysGetRecursive("spec", true, "*.lua")) do
if (filter or app.loadfilters.specs)(file) then
addToTab(ide.specs,file)
end
end
-- load tools
local function loadTools(filter)
loadToTab(filter or "tools", "tools", ide.tools, false)
end
-- load packages
local function loadPackages(filter)
loadToTab(filter, "packages", ide.packages, false, ide.proto.Plugin)
-- assign file names to each package
for fname, package in pairs(ide.packages) do package.fname = fname end
end
function UpdateSpecs()
for _, spec in pairs(ide.specs) do
spec.sep = spec.sep or "\1" -- default separator doesn't match anything
spec.iscomment = {}
@@ -285,13 +301,10 @@ local function loadSpecs(filter)
end
end
-- load tools
local function loadTools(filter)
for _, file in ipairs(FileSysGetRecursive("tools", false, "*.lua")) do
if (filter or app.loadfilters.tools)(file) then
addToTab(ide.tools,file)
end
end
-- load specs
local function loadSpecs(filter)
loadToTab(filter or "specs", "spec", ide.specs, true)
UpdateSpecs()
end
-- temporarily replace print() to capture reported error messages to show
@@ -370,7 +383,7 @@ loadSpecs()
loadTools()
do
local home = os.getenv("HOME")
local home = os.getenv("HOME") or (iswindows and (os.getenv('HOMEDRIVE')..os.getenv('HOMEPATH')))
ide.configs = {
system = MergeFullPath("cfg", "user.lua"),
user = home and MergeFullPath(home, ".zbstudio/user.lua"),
@@ -384,18 +397,20 @@ do
for _, v in ipairs(configs) do addConfig(v, true) end
configs = nil
local sep = string_Pathsep
local sep = GetPathSeparator()
if ide.config.language then
addToTab(ide.config.messages, "cfg"..sep.."i18n"..sep..ide.config.language..".lua")
LoadLuaFileExt(ide.config.messages, "cfg"..sep.."i18n"..sep..ide.config.language..".lua")
end
end
loadPackages()
---------------
-- Load App
for _, file in ipairs({
"markup", "settings", "singleinstance", "iofilters",
"gui", "filetree", "output", "debugger",
"gui", "filetree", "output", "debugger", "package",
"editor", "findreplace", "commands", "autocomplete", "shellbox",
"menu_file", "menu_edit", "menu_search",
"menu_view", "menu_project", "menu_tools", "menu_help",
@@ -405,6 +420,9 @@ end
dofile "src/version.lua"
-- register all the plugins
PackageEventHandle("onRegister")
-- load rest of settings
SettingsRestoreEditorSettings()
SettingsRestoreFramePosition(ide.frame, "MainFrame")
@@ -443,6 +461,8 @@ end
resumePrint()
PackageEventHandle("onAppLoad")
ide.frame:Show(true)
wx.wxGetApp():MainLoop()

View File

@@ -28,14 +28,14 @@ function HasBit(value, num)
return true
end
-- ASCII values for common chars
char_CR = string.byte("\r")
char_LF = string.byte("\n")
char_Tab = string.byte("\t")
char_Sp = string.byte(" ")
function GetPathSeparator()
return string.char(wx.wxFileName.GetPathSeparator())
end
string_Pathsep = string.char(wx.wxFileName.GetPathSeparator())
stringset_File = '[^"%?%*:\\/<>|]'
do
local sep = GetPathSeparator()
function IsDirectory(dir) return dir:find(sep.."$") end
end
function StripCommentsC(tx)
local out = ""
@@ -109,21 +109,19 @@ function FileLines(f)
end
end
function PrependStringToArray(t, s, maxstrings)
function PrependStringToArray(t, s, maxstrings, issame)
if string.len(s) == 0 then return end
for i, v in ipairs(t) do
if v == s then
for i = #t, 1, -1 do
local v = t[i]
if v == s or issame and issame(s, v) then
table.remove(t, i) -- remove old copy
break
-- don't break here in case there are multiple copies to remove
end
end
table.insert(t, 1, s)
if #t > (maxstrings or 15) then table.remove(t, #t) end -- keep reasonable length
end
-- ----------------------------------------------------------------------------
-- Get file modification time, returns a wxDateTime (check IsValid) or nil if
-- the file doesn't exist
function GetFileModTime(filePath)
if filePath and #filePath > 0 then
local fn = wx.wxFileName(filePath)
@@ -174,7 +172,7 @@ function FileSysGetRecursive(path, recursive, spec, skip)
local dir = wx.wxDir(path)
if not dir:IsOpened() then return end
local found, file = dir:GetFirst("*", wx.wxDIR_DIRS)
local found, file = dir:GetFirst("*", wx.wxDIR_DIRS + wx.wxDIR_NO_FOLLOW)
while found do
if not skip or not file:find(skip) then
local fname = wx.wxFileName(path, file):GetFullPath()
@@ -194,6 +192,17 @@ function FileSysGetRecursive(path, recursive, spec, skip)
end
getDir(path, spec)
-- explicitly sort files on Linux; directories first
if ide.osname == 'Unix' then
table.sort(content, function(a,b)
local ad, bd = a:sub(-1) == sep, b:sub(-1) == sep
-- both are folders or both are files
if ad and bd or not ad and not bd then return a < b
-- only one is folder; return true if it's the first one
else return ad end
end)
end
return content
end
@@ -218,7 +227,7 @@ function MergeFullPath(p, f)
or nil)
end
function FileWrite(file,content)
function FileWrite(file, content)
local log = wx.wxLogNull() -- disable error reporting; will report as needed
local file = wx.wxFile(file, wx.wxFile.write)
if not file:IsOpened() then return nil, wx.wxSysErrorMsg() end
@@ -229,9 +238,12 @@ function FileWrite(file,content)
end
function FileRead(file)
-- on OSX "Open" dialog allows to open applications, which are folders
if wx.wxDirExists(file) then return nil, "Can't read directory as file." end
local log = wx.wxLogNull() -- disable error reporting; will report as needed
local file = wx.wxFile(file, wx.wxFile.read)
if not file:IsOpened() then return end
if not file:IsOpened() then return nil, wx.wxSysErrorMsg() end
local _, content = file:Read(file:Length())
file:Close()
@@ -282,7 +294,29 @@ end
function RequestAttention()
local frame = ide.frame
if not frame:IsActive() then frame:RequestUserAttention() end
if not frame:IsActive() then
frame:RequestUserAttention()
if ide.osname == "Macintosh" then
local cmd = [[osascript -e 'tell application "%s" to activate']]
wx.wxExecute(cmd:format(ide.editorApp:GetAppName()), wx.wxEXEC_ASYNC)
elseif ide.osname == "Windows" then
local winapi = require 'winapi'
if winapi then
local pid = winapi.get_current_pid()
local wins = winapi.find_all_windows(function(w)
return w:get_process():get_pid() == pid
and w:get_class_name() == 'wxWindowNR'
end)
if wins and #wins > 0 then
-- found the window, now need to activate it:
-- send Alt key to the current window and then
-- bring our window to foreground (doesn't work without Alt pressed)
winapi.send_to_window(307)
wins[1]:set_foreground()
end
end
end
end
end
local messages, lang, counter
@@ -294,3 +328,73 @@ function TR(msg, count)
return count and counter and message and type(message) == 'table'
and message[counter(count)] or message or msg
end
-- wxwidgets 2.9.x may report the last folder twice (depending on how the
-- user selects the folder), which makes the selected folder incorrect.
-- check if the last segment is repeated and drop it.
function FixDir(path)
if wx.wxDirExists(path) then return path end
local dir = wx.wxFileName.DirName(path)
local dirs = dir:GetDirs()
if #dirs > 1 and dirs[#dirs] == dirs[#dirs-1] then dir:RemoveLastDir() end
return dir:GetFullPath()
end
function ShowLocation(fname)
local osxcmd = [[osascript -e 'tell application "Finder" to reveal POSIX file "%s"']]
.. [[ -e 'tell application "Finder" to activate']]
local wincmd = [[explorer /select,"%s"]]
local lnxcmd = [[xdg-open "%s"]] -- takes path, not a filename
local cmd =
ide.osname == "Windows" and wincmd:format(fname) or
ide.osname == "Macintosh" and osxcmd:format(fname) or
ide.osname == "Unix" and lnxcmd:format(wx.wxFileName(fname):GetPath())
if cmd then wx.wxExecute(cmd, wx.wxEXEC_ASYNC) end
end
function LoadLuaFileExt(tab, file, proto)
local cfgfn,err = loadfile(file)
if not cfgfn then
print(("Error while loading file: '%s'."):format(err))
else
local name = file:match("([a-zA-Z_0-9%-]+)%.lua$")
if not name then return end
-- check if os/arch matches to allow packages for different systems
local os, arch = name:match("-(%w+)-?(%w*)")
if os and os:lower() ~= ide.osname:lower()
or arch and #arch > 0 and arch:lower() ~= ide.osarch:lower()
then return end
if os then name = name:gsub("-.*","") end
local success, result = pcall(function()return cfgfn(assert(_G or _ENV))end)
if not success then
print(("Error while processing file: '%s'."):format(result))
else
if (tab[name]) then
local out = tab[name]
for i,v in pairs(result) do
out[i] = v
end
else
tab[name] = proto and result and setmetatable(result, proto) or result
end
end
end
end
function LoadSafe(data)
local f, res = loadstring(data)
if not f then return f, res end
local count = 0
debug.sethook(function ()
count = count + 1
if count >= 3 then error("cannot call functions") end
end, "c")
local ok, res = pcall(f)
count = 0
debug.sethook()
return ok, res
end

69
t/2-autocomplete.lua Normal file
View File

@@ -0,0 +1,69 @@
local editor = NewFile()
ok(editor, "Open New file.")
ok(editor.assignscache ~= nil, "Auto-complete cache is assigned.")
editor:AddText([[
local line = '123'
line = line:gsub('1','4')
line:]])
ok(limit(10000, function() CreateAutoCompList(editor, "line:") end),
"Auto-complete doesn't loop for 'line:' after 'line:gsub'.")
ok(limit(10000, function() CreateAutoCompList(editor, "line.") end),
"Auto-complete doesn't loop for 'line.' after 'line:gsub'.")
editor:SetText('') -- use Set/Add to position cursor after added text
editor:AddText([[
smth = smth:new()
smth:]])
ok(limit(10000, function() CreateAutoCompList(editor, "smth:") end),
"Auto-complete doesn't loop for 'smth:'.")
ok(pcall(CreateAutoCompList, editor, "%1000"),
"Auto-complete doesn't trigger 'invalid capture index' on '%...'.")
editor:SetText('')
editor:AddText([[
result = result.list[1] --> "does the test" test
result.1
]])
ok(limit(10000, function() CreateAutoCompList(editor, "result.1") end),
"Auto-complete doesn't loop for table index reference 1/2.")
editor:SetText('')
editor:AddText([[
self.popUpObjs = self.undoBuffer[0].sub
self.undoBuffer = self.undoBuffer[0]
self.popUpObjs[popUpNo].]])
ok(limit(10000, function() EditorAutoComplete(editor) end),
"Auto-complete doesn't loop for table index reference 2/2.")
local interpreter = ide:GetInterpreter():GetFileName()
ProjectSetInterpreter("gideros")
local ac = CreateAutoCompList(editor, "Bitmap.n")
local _, c = ac:gsub("new", "new")
ok(c == 1,
("Auto-complete doesn't offer duplicates with the same name ('%s').")
:format(ac))
ProjectSetInterpreter(interpreter)
editor:SetText('')
editor:AddText('print(1,io.')
local value
local ULS = editor.UserListShow
editor.UserListShow = function(editor, pos, list) value = list end
EditorAutoComplete(editor)
editor.UserListShow = ULS
ok(value and value:find("close"), "Auto-complete is shown after comma.")
-- cleanup
ide:GetDocument(editor).isModified = false
ClosePage()

18
t/3-tooltip.lua Normal file
View File

@@ -0,0 +1,18 @@
local editor = NewFile()
editor:SetText('print("select")')
-- this is to set proper styles, which are needed for EditorCallTip
editor:Colourise(0, -1)
local value
local CTS = editor.CallTipShow
editor.CallTipShow = function(editor, pos, tip) value = tip end
EditorCallTip(editor, 10)
editor.CallTipShow = CTS
ok(value:find("print") and not value:find("select"),
"Tooltip ignores values in strings.")
-- cleanup
ide:GetDocument(editor).isModified = false
ClosePage()

54
t/4-comment.lua Normal file
View File

@@ -0,0 +1,54 @@
local editor = NewFile()
local line = "246"
local comment = "%-%-"
editor:AddText(([[
1
%s
3]]):format(line))
local findReplace = ide.findReplace
findReplace.findText = line
findReplace:FindString()
ide.frame:ProcessEvent(wx.wxCommandEvent(
wx.wxEVT_COMMAND_MENU_SELECTED, ID_COMMENT))
local text = editor:GetText()
ok(text:find(comment..line) and not text:find(comment.."3"),
"One-line selection is commented.")
findReplace.findText = "--"..line
findReplace:FindString()
editor:SetCurrentPos(editor:GetLength())
ide.frame:ProcessEvent(wx.wxCommandEvent(
wx.wxEVT_COMMAND_MENU_SELECTED, ID_COMMENT))
text = editor:GetText()
ok(text:find(comment.." "..comment..line) and text:find(comment.."3"),
"Commented and uncommented lines are commented.")
findReplace:FindString()
editor:SetCurrentPos(editor:GetLength())
ide.frame:ProcessEvent(wx.wxCommandEvent(
wx.wxEVT_COMMAND_MENU_SELECTED, ID_COMMENT))
text = editor:GetText()
ok(not text:find(comment.." "..comment..line) and not text:find(comment.."3"),
"Multi-line commented text is uncommented.")
editor:SetAnchor(0)
editor:SetCurrentPos(editor:PositionFromLine(2))
ide.frame:ProcessEvent(wx.wxCommandEvent(
wx.wxEVT_COMMAND_MENU_SELECTED, ID_COMMENT))
text = editor:GetText()
ok(text:find(comment.." "..comment..line) and text:find(comment.."1") and not text:find(comment.."3"),
"Selection that ends at the beginning of the line doesn't comment line.")
-- cleanup
ide:GetDocument(editor).isModified = false
ClosePage()

View File

@@ -16,6 +16,14 @@ ide.app.postinit = function()
setfenv(testwell, env)
testwell()
-- add a test function to detect loops
function limit (limit, func)
debug.sethook(function() error("exceeded") end, "", limit)
local ok, res = pcall(func)
debug.sethook()
return ok, res
end
-- find all test files and load them
local files = FileSysGetRecursive("t", true, "*.lua")
for k, v in ipairs(files) do

Binary file not shown.

View File

@@ -11,6 +11,8 @@ cfg/i18n/*.lua
interpreters/*.lua
lualibs/copas/copas.lua
lualibs/coxpcall/coxpcall.lua
lualibs/lua_lexer_loose.lua
lualibs/lua_parser_loose.lua
lualibs/luainspect/ast.lua
lualibs/luainspect/compat_env.lua
lualibs/luainspect/dump.lua
@@ -49,10 +51,12 @@ lualibs/socket/url.lua
lualibs/ssl.lua
lualibs/ssl/https.lua
lualibs/testwell.lua
packages/sample.lua
spec/*.lua
src/defs.lua
src/editor/autocomplete.lua
src/editor/commands.lua
src/editor/proto.lua
src/editor/debugger.lua
src/editor/editor.lua
src/editor/filetree.lua
@@ -71,6 +75,7 @@ src/editor/menu_search.lua
src/editor/menu_tools.lua
src/editor/menu_view.lua
src/editor/output.lua
src/editor/package.lua
src/editor/settings.lua
src/editor/shellbox.lua
src/editor/singleinstance.lua

View File

@@ -13,7 +13,7 @@
<key>CFBundleIconFile</key>
<string>zbstudio.icns</string>
<key>CFBundleIdentifier</key>
<string></string>
<string>com.ZeroBrane.ZeroBraneStudio</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>

View File

@@ -6,6 +6,7 @@ editor.tabwidth = 2
editor.usewrap = true
editor.calltipdelay = 500
editor.smartindent = true
editor.fold = true
local G = ... -- this now points to the global environment
if G.ide.osname == 'Macintosh' then

View File

@@ -1,2 +1,2 @@
icon ICON "zbstudio.ico"
1 RT_MANIFEST zbstudio.manifest
1 24 zbstudio.manifest