Compare commits
191 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
71b4f47159 | ||
|
|
347b53659c | ||
|
|
16f32e0df5 | ||
|
|
171287fac6 | ||
|
|
9d05cd6931 | ||
|
|
a9e847372a | ||
|
|
1eba53cc0e | ||
|
|
c5a0077a01 | ||
|
|
2b07dd1db4 | ||
|
|
28b3380a45 | ||
|
|
564338656d | ||
|
|
29b2e4f5ec | ||
|
|
c7ab3aeb32 | ||
|
|
4b771dafe4 | ||
|
|
71393bd35a | ||
|
|
f7e2697e56 | ||
|
|
608644bd83 | ||
|
|
7563e52aba | ||
|
|
039dde0ccb | ||
|
|
abbde79ab0 | ||
|
|
ead958e603 | ||
|
|
6b7f310cd7 | ||
|
|
451186ac4e | ||
|
|
b8b3b7f0af | ||
|
|
5ee71feac4 | ||
|
|
a2e65e2bbd | ||
|
|
e8ad508021 | ||
|
|
aa2a4fac2b | ||
|
|
d5fda558c1 | ||
|
|
171b98717a | ||
|
|
da07ef0e2c | ||
|
|
6c9e226d67 | ||
|
|
d3884358be | ||
|
|
0ebeee3641 | ||
|
|
bd190d5a4e | ||
|
|
b1f09b9ef0 | ||
|
|
ac556aea34 | ||
|
|
87ab3702fe | ||
|
|
83556f9ab2 | ||
|
|
43c18552c1 | ||
|
|
dc54c76435 | ||
|
|
9a16cd026f | ||
|
|
e4710a16b0 | ||
|
|
ae2e99f6d3 | ||
|
|
c182a19fa5 | ||
|
|
2ddeaf4eb8 | ||
|
|
b4fd071efb | ||
|
|
9344280d5b | ||
|
|
ad037536cd | ||
|
|
d8e8af00b6 | ||
|
|
1e651a97b7 | ||
|
|
c2e49e169f | ||
|
|
6662cb0f5e | ||
|
|
c00d85890a | ||
|
|
c42c9ffb3d | ||
|
|
b5661976eb | ||
|
|
c1e66f8fc2 | ||
|
|
c2715040fe | ||
|
|
fc17dac2a5 | ||
|
|
0dfd8e3ba1 | ||
|
|
acbfd6d81d | ||
|
|
0d268a01e1 | ||
|
|
1e9cbb4633 | ||
|
|
7d3683df98 | ||
|
|
3b10bbbcd2 | ||
|
|
3ea40683c9 | ||
|
|
e6b789131a | ||
|
|
613dec0571 | ||
|
|
36b3692e9e | ||
|
|
59cde2fc8c | ||
|
|
e8027b3b95 | ||
|
|
579ab4c831 | ||
|
|
f54322c1f7 | ||
|
|
a5b85c533a | ||
|
|
149340669a | ||
|
|
5165bf5b29 | ||
|
|
fbc04ba199 | ||
|
|
e33f2d40dd | ||
|
|
bad62f0a16 | ||
|
|
b393b58cc1 | ||
|
|
4480825408 | ||
|
|
10fb31f1e5 | ||
|
|
789a2d8a88 | ||
|
|
b9ebd44c30 | ||
|
|
a65edf8fd5 | ||
|
|
89f33160bc | ||
|
|
e96a7657cd | ||
|
|
492270a3bf | ||
|
|
1cd34e3853 | ||
|
|
3ad7b389da | ||
|
|
bc58913272 | ||
|
|
415ba2bd17 | ||
|
|
a338f4c436 | ||
|
|
24507e22bb | ||
|
|
8e208b7dd3 | ||
|
|
d5c585b118 | ||
|
|
56b63b3b4c | ||
|
|
8c64d77276 | ||
|
|
406056bf52 | ||
|
|
f960d65e08 | ||
|
|
a3fc62a7c0 | ||
|
|
5a4e996b37 | ||
|
|
200647f0c5 | ||
|
|
99d6395845 | ||
|
|
fc0d5083e6 | ||
|
|
478a87c8d0 | ||
|
|
d3a8b37cf3 | ||
|
|
0f99cb20b0 | ||
|
|
df54864e43 | ||
|
|
9beae1f9c4 | ||
|
|
0761ee2f4a | ||
|
|
314dc5ba9e | ||
|
|
02a086e083 | ||
|
|
3a616f5e37 | ||
|
|
3f12ce28d8 | ||
|
|
a913c1fa55 | ||
|
|
363803ea9b | ||
|
|
1bbb9f432c | ||
|
|
4854afeb32 | ||
|
|
507832ac2b | ||
|
|
146b36d9ce | ||
|
|
77276d48ae | ||
|
|
c3f253ef64 | ||
|
|
93e51a6d43 | ||
|
|
a26d72f99d | ||
|
|
cd8b714ea6 | ||
|
|
909e9b3ee9 | ||
|
|
d10bcda693 | ||
|
|
7ddb673624 | ||
|
|
bbd11b90eb | ||
|
|
4fee737981 | ||
|
|
14143bf0ce | ||
|
|
0e8a9b078c | ||
|
|
c2ca459882 | ||
|
|
f80a11a982 | ||
|
|
29650cef8c | ||
|
|
4cf8017d7b | ||
|
|
f807b1f48c | ||
|
|
dc7e040087 | ||
|
|
4262716043 | ||
|
|
5f25238ba6 | ||
|
|
cf95129fc6 | ||
|
|
f8b6654cd6 | ||
|
|
cf001082e2 | ||
|
|
c8e2890f60 | ||
|
|
9075736cf1 | ||
|
|
e1cba702f7 | ||
|
|
9ffc4cf9dd | ||
|
|
94647152fc | ||
|
|
e4a69a63c0 | ||
|
|
05e2b483a8 | ||
|
|
f2e8c0c213 | ||
|
|
43c6be0859 | ||
|
|
fb5ef928fd | ||
|
|
3f9be575fd | ||
|
|
9985cfc50a | ||
|
|
be018b39fc | ||
|
|
da15c46429 | ||
|
|
0eb71f44d4 | ||
|
|
aa6618f002 | ||
|
|
e55e28e852 | ||
|
|
0e1c937892 | ||
|
|
65a112a4e9 | ||
|
|
0448ebb0e0 | ||
|
|
fec7d21ca4 | ||
|
|
2d29aa3666 | ||
|
|
23a4f5fa04 | ||
|
|
80bcc21562 | ||
|
|
5dcf0a6622 | ||
|
|
99c1be49a6 | ||
|
|
2a46b4ece7 | ||
|
|
1d77bbdf5a | ||
|
|
943517f07e | ||
|
|
93b664de45 | ||
|
|
695fed709e | ||
|
|
51735ac89d | ||
|
|
5a49699098 | ||
|
|
b2b6e82735 | ||
|
|
fd3ed2b7da | ||
|
|
4da018b8ce | ||
|
|
99ad315832 | ||
|
|
4bd20406a2 | ||
|
|
48b51c549a | ||
|
|
af0a95ddb8 | ||
|
|
5db9b6b9b5 | ||
|
|
e1bee48834 | ||
|
|
704f6fed89 | ||
|
|
c05962c6a6 | ||
|
|
17948e06d8 | ||
|
|
51777d47c9 | ||
|
|
1714cf6109 |
164
CHANGELOG.md
164
CHANGELOG.md
@@ -1,5 +1,169 @@
|
||||
# ZeroBrane Studio Changelog
|
||||
|
||||
## v0.37 (May 09 2013)
|
||||
|
||||
### Special thanks
|
||||
- To Samuel Dionne-Riel for wxwidgets 2.8 compatibility updates.
|
||||
- To Mat Hopwood for assistance with Marmalade Quick integration.
|
||||
|
||||
### Highlights
|
||||
- Added Marmalade Quick auto-complete support and API documentation.
|
||||
- Added full Marmalade Quick debugging support (requires Quick 1.1+).
|
||||
- Improved Find/Replace behavior and functionality.
|
||||
- Added Recent File history navigation.
|
||||
- Added Preferences menu to simplify access to system/user settings.
|
||||
|
||||
### Improvements
|
||||
- Added Preferences menu to simplify access to system/user settings.
|
||||
- Added Russian translation for Find/Replace dialog and (ref #70).
|
||||
- Added Russian translation for the Preferences menu (ref #70).
|
||||
- Added 'shaking' Find/Replace window when text is not found (closes #146).
|
||||
- Added 'wlua' to the list of recognized Lua extensions.
|
||||
- Added disabling Recent Files menu if the list is empty.
|
||||
- Added TomorrowContrast color scheme (thanks to Sergey Lerg).
|
||||
- Added detaching a child process to avoid crash when exiting during debugging.
|
||||
- Added Recent File history navigation (closes #66).
|
||||
- Added Marmalade auto-complete support and API documentation.
|
||||
- Added processing of `runonstart` when using remote debugging (closes #138).
|
||||
- Added suggesting proper extension after 'Save/Save As' based on current spec.
|
||||
- Added translation setup for Find/Replace dialog (closes #133).
|
||||
- Added `nomousezoom` option to disable zoom with mouse wheel in the editor.
|
||||
- Added selecting text and Cmd-F shortcut in Find dialog on OSX (ref #127).
|
||||
- Improved file activation when debugging is started (closes #137).
|
||||
- Reduced the minimum size of the Output/Console panel.
|
||||
- Refactored Recent Files history to make it faster and simpler.
|
||||
- Refactored and optimized directory scanning when loading IDE files.
|
||||
- Separated settings for function dropdown and project tree fonts (fixes #148).
|
||||
- Updated documentation about default EOL on OSX (ref #102).
|
||||
- Updated highlighting in Watch windows to not use editor styles.
|
||||
- Updated documentation for user settings (ref #113, #55).
|
||||
- Updated Monokai color scheme to fix current line color.
|
||||
|
||||
### Incompatibilities
|
||||
- (dev) `FileSysGet` has been replaced with `FileSysGetRecursive` with a different signature.
|
||||
|
||||
### Fixes
|
||||
- Fixed hiding all panels when switching to Full Screen mode.
|
||||
- Fixed loading a non-existing file.
|
||||
- Fixed activation of non-existing files/folders in the Project tree.
|
||||
- Fixed search results for lines without newline.
|
||||
- Fixed Find/Replace in folders with Unicode names (fixes #147); improved performance.
|
||||
- Fixed Un/Comment commands executed for empty lines.
|
||||
- Fixed fold/unfold for files starting with block/comment.
|
||||
- Fixed history after activating non-existing file in Recent Files.
|
||||
- Fixed scrolling to restored cursor position on OSX (when `usewrap` = false).
|
||||
- Fixed Find/Replace dialog to take Enter on OSX (fixes #140).
|
||||
- Fixed 'breaking' after executing OUT command that never reaches the target level.
|
||||
- Fixed stopping at a breakpoint at the initial line when `startwith` option is specified.
|
||||
- Fixed activation of a file loaded into active tab.
|
||||
- Fixed incorrect tab activation on OSX after using 'Open File'.
|
||||
- Fixed editor activation when file is loaded into an existing tab.
|
||||
- Fixed an error after opening non-existing file from 'Recent Files'.
|
||||
- Fixed blocking on reading app output without processing other events.
|
||||
- Fixed an issue with duplicate lines shown in the editor.
|
||||
- Fixed 'Replace All' to take 'Wrap Around' into account (fixes #132).
|
||||
- Fixed off-by-one error in searching consecutive matches.
|
||||
- Fixed 'Quick Find' not working without current selection (fixes #131).
|
||||
- Fixed looping in auto-complete on mistyped class (fixes #130).
|
||||
- Fixed compatibility with wx2.8 (thanks to Samuel Dionne-Riel; closes #128).
|
||||
- Fixed replacement logic in Find/Replace that could replace selected fragment (ref #127).
|
||||
- Fixed an error caused by allowing multiple Search/Replace windows (fixes #127).
|
||||
|
||||
## v0.361 (Apr 12 2013)
|
||||
|
||||
### Improvements
|
||||
- Added handling of Ctrl-Home and Ctrl-End on OSX (ref #89).
|
||||
- Added line copy/cut for Ctrl-C/Ctrl-X with no selection.
|
||||
- Updated About screen to be more configurable and flexible.
|
||||
- Updated Russian translation (thanks to toiffel).
|
||||
|
||||
### Fixes
|
||||
- Fixed launch command for Corona debugging on Windows.
|
||||
- Fixed 'control' check on OSX that changed with wx2.9.2+ (ref #89).
|
||||
- Fixed wrong tab activated on OSX after using New file in some cases.
|
||||
- Fixed cursor not being visible in some cases after file is loaded (ref #116).
|
||||
|
||||
## v0.36 (Apr 08 2013)
|
||||
|
||||
### Highlights
|
||||
- Added 32bit and 64bit **Linux binaries**.
|
||||
- Enabled **full debugging for Corona on OSX**.
|
||||
- Improved **debugger performance**.
|
||||
- Improved **performance of tab and project switching**.
|
||||
- Added **multiple selection and multi-cursor editing**.
|
||||
- Made Stack and Watch windows dockable and toggleable.
|
||||
|
||||
### Special thanks
|
||||
- To toiffel for build improvements and continuous work on wxwidgets 2.9 and Linux support.
|
||||
- To Marcel van Herk for testing and feedback on Stack and Watch windows behavior.
|
||||
- To Leo Bartoloni for Italian translation update.
|
||||
- To Fringale for updated French translation.
|
||||
- To neomantra for adding cdata processing in the serializer.
|
||||
|
||||
### Improvements
|
||||
- Added handling of case-insensitive filenames on OSX.
|
||||
- Added cdata processing (thanks to neomantra).
|
||||
- Added universal binaries for luasocket on OSX to allow debugging of 64bit applications (for example, LuaJIT) on OSX.
|
||||
- Added update of Stack and Watch windows after 'Debugging suspended' message.
|
||||
- Added toggling for View menu items.
|
||||
- Added auto-show/hide Stack and Watch windows during debugging (closes #110).
|
||||
- Added ignoring `-psn...` parameter on OSX when reading file names from command line.
|
||||
- Added migration of configuration file on Windows (helps #89).
|
||||
- Added check for different spellings of the same folder in the project tree.
|
||||
- Added scripts to install build prerequisites on Linux (helps #89).
|
||||
- Added linux binaries with support for x86 and x64 (helps #89).
|
||||
- Added window list button to the notepad with editor tabs.
|
||||
- Added centering of current line during debugging.
|
||||
- Added multiple selection and multi-cursor editing (wx2.9.5+).
|
||||
- Added dll proxy to make LfW libraries to work with the IDE.
|
||||
- Disabled showing 'value' in auto-complete after 'a:' (helps #101).
|
||||
- Enabled full debugging for Corona on OSX.
|
||||
- Improved debugging performance.
|
||||
- Improved performance of tab switching and project tree population.
|
||||
- Improved handling of upvalues with __tostring method in the Stack window.
|
||||
- Increased default font size for OSX; set 'Monaco' as default font (helps #89).
|
||||
- Made stack and watch windows dockable (closes #103).
|
||||
- Optimized project switching and added notebook freezing where possible (ref #89).
|
||||
- Reduced flicker in the project tree when a file is opened (ref #89).
|
||||
- Removed binary libraries not currently used.
|
||||
- Set 'Courier New' as the default font on Linux (ref #89).
|
||||
- Switched to 'native' menu on OSX and added 24x24 icons required (helps #89).
|
||||
- Updated Italian translation (thanks to Leo Bartoloni)
|
||||
- Updated 'method' type in auto-complete to only allow a:b syntax (closes #101).
|
||||
- Updated language files (es, it, ru) with new messages (ref #70).
|
||||
- Updated French translation with latest string changes, fixed a few typos (thanks to Fringale).
|
||||
- Updated Stack and Watch window to not refresh when not visible.
|
||||
- Upgraded Mobdebug (0.5222) to add serialization with metamethods and notification on incomplete output (closes #109).
|
||||
- Updated error messages from loading configuration files.
|
||||
- Updated Linux binaries to use libpng 1.6 with wxwidgets (helps #89).
|
||||
- Updated Windows/OSX build files to only build components needed (helps #89).
|
||||
- Updated windows executable to show properly scaled icons in the Explorer.
|
||||
- Updated status bar to use no border around fields.
|
||||
- Updated large icons for "native" toolbar on OSX (helps #89).
|
||||
- Updated function call indicator to use round box with wxwidgets upgrade (helps #89).
|
||||
- Updated handling of markdown styles to make it more robust (fixes #59).
|
||||
- Updated README with Marmalade Quick support and Corona tutorial.
|
||||
|
||||
### Incompatibilities
|
||||
- Configuration file (.ini) location has changed on Windows. The current file will be copied to the new location.
|
||||
- The debugger now stops on the next executable line after `.start()` call.
|
||||
|
||||
### Fixes
|
||||
- Fixed activating files in the project tree on a case insensitive system.
|
||||
- Fixed the Stack view being partially hidden when the root item is too wide (ref #110).
|
||||
- Fixed left side of the project panel being hidden when a file is activated (fixes #122).
|
||||
- Fixed breakpoint not firing on the first executable line in debugging (helps #121).
|
||||
- Fixed terminating debugging of an empty script.
|
||||
- Fixed reporting of initial line during debugging.
|
||||
- Fixed editor tab activation after closing another tab on Linux (ref #89).
|
||||
- Fixed 'Show tooltip' shortcut not working on Linux (fixes #118; ref #89).
|
||||
- Fixed cursor position being incorrectly restored (fixes #116; ref #89).
|
||||
- Fixed a warning about empty project directory in local console.
|
||||
- Fixed an issue with Enter used to select an item in project dropdown (ref #89).
|
||||
- Fixed an issue with the Project tree when project and app directories are the same.
|
||||
- Fixed debugger output not being suppressed on Linux and using wlua.
|
||||
- Fixed a static analyzer issue with anonymous functions defined in expressions (fixes #3).
|
||||
|
||||
## v0.35 (Feb 10 2013)
|
||||
|
||||
### Highlights
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[ZeroBrane Studio](http://studio.zerobrane.com/) is a lightweight Lua IDE with code completion, syntax
|
||||
highlighting, remote debugger, code analyzer, live coding, and debugging
|
||||
support for several Lua engines (LuaJIT, Löve 2D, Moai, Gideros, Corona,
|
||||
support for several Lua engines (LuaJIT, Löve 2D, Moai, Gideros, Corona, Marmalade Quick,
|
||||
MobileLua, GSL-shell, and others). It originated from the [Estrela Editor](http://www.luxinia.de/index.php/Estrela/).
|
||||
|
||||
## Features
|
||||
@@ -12,9 +12,8 @@ MobileLua, GSL-shell, and others). It originated from the [Estrela Editor](http:
|
||||
* Auto-completion for functions, keywords, and custom APIs.
|
||||
* Interactive console to directly test code snippets with local and remote execution.
|
||||
* Integrated debugger (with support for local and remote debugging).
|
||||
* Live coding with Lua ([demo](http://notebook.kulchenko.com/zerobrane/live-coding-in-lua-bret-victor-style)), Löve 2D ([demo](http://notebook.kulchenko.com/zerobrane/live-coding-with-love)), and Gideros ([demo](http://notebook.kulchenko.com/zerobrane/gideros-live-coding-with-zerobrane-studio-ide)).
|
||||
* Live coding with Lua ([demo](http://notebook.kulchenko.com/zerobrane/live-coding-in-lua-bret-victor-style)), Löve 2D ([demo](http://notebook.kulchenko.com/zerobrane/live-coding-with-love)), Gideros ([demo](http://notebook.kulchenko.com/zerobrane/gideros-live-coding-with-zerobrane-studio-ide)), Moai ([demo](http://notebook.kulchenko.com/zerobrane/live-coding-with-moai-and-zerobrane-studio)), and Corona SDK ([demo](http://notebook.kulchenko.com/zerobrane/debugging-and-live-coding-with-corona-sdk-applications-and-zerobrane-studio)).
|
||||
* Support for plugin-like components:
|
||||
- applications: overall control of applications settings;
|
||||
- specs (spec/): file syntax, lexer, keywords (e.g. glsl);
|
||||
- apis (api/): for code-completion and tool-tips;
|
||||
- interpreters (interpreters/): how a project is run;
|
||||
@@ -53,7 +52,7 @@ Loading custom configuration:
|
||||
|
||||
## Where is Estrela?
|
||||
|
||||
The projects have been merged again and zbstudio will lead the future.
|
||||
The projects have been merged and zbstudio will lead the future.
|
||||
Please reassociate files with zbstudio. To keep your history of files and
|
||||
projects copy the contents of the `EstrelaEditor.ini` in your HOME directory
|
||||
to `ZeroBraneStudio.ini`. If you have used Estrela for graphics shader
|
||||
|
||||
@@ -739,6 +739,7 @@ return {
|
||||
description = "When called with a file name, it opens the named file (in text mode), and sets its handle as the default input file. When called with a file handle, it simply sets this file handle as the default input file. When called without parameters, it returns the current default input file.\n\nIn case of errors this function raises the error, instead of returning an error code.",
|
||||
args = "([file: string|file])",
|
||||
returns = "([file])",
|
||||
valuetype = "f",
|
||||
},
|
||||
lines = {
|
||||
type = "function",
|
||||
@@ -751,18 +752,21 @@ return {
|
||||
description = "This function opens a file, in the mode specified in the string mode.\n\nIt returns a new file handle, or, in case of errors, nil plus an error message.\n\nThe mode string can be any of the following:\n\n* \"r\": read mode (the default);\n\n* \"w\": write mode;\n\n* \"a\": append mode;\n\n* \"r+\": update mode, all previous data is preserved;\n\n* \"w+\": update mode, all previous data is erased;\n\n* \"a+\": append update mode, previous data is preserved, writing is only allowed at the end of file.\n\nThe mode string can also have a 'b' at the end, which is needed in some systems to open the file in binary mode.",
|
||||
args = "(filename: string [, mode: string])",
|
||||
returns = "(file|nil [, string])",
|
||||
valuetype = "f",
|
||||
},
|
||||
output = {
|
||||
type = "function",
|
||||
description = "When called with a file name, it opens the named file (in text mode), and sets its handle as the default output file. When called with a file handle, it simply sets this file handle as the default output file. When called without parameters, it returns the current default output file.\n\nIn case of errors this function raises the error, instead of returning an error code.",
|
||||
args = "([file: string|file])",
|
||||
returns = "([file])",
|
||||
valuetype = "f",
|
||||
},
|
||||
popen = {
|
||||
type = "function",
|
||||
description = "Starts program prog in a separated process and returns a file handle that you can use to read data from this program (if mode is \"r\", the default) or to write data to this program (if mode is \"w\").\n\nThis function is system dependent and is not available on all platforms.",
|
||||
args = "(prog: string [, mode: string])",
|
||||
returns = "(file|nil [, string])",
|
||||
valuetype = "f",
|
||||
},
|
||||
read = {
|
||||
type = "function",
|
||||
@@ -775,6 +779,7 @@ return {
|
||||
description = "Returns a handle for a temporary file.\n\nThis file is opened in update mode and it is automatically removed when the program ends.",
|
||||
args = "()",
|
||||
returns = "(file)",
|
||||
valuetype = "f",
|
||||
},
|
||||
type = {
|
||||
type = "function",
|
||||
@@ -796,43 +801,43 @@ return {
|
||||
description = "Pseudoclass for operations on file handles.",
|
||||
childs = {
|
||||
close = {
|
||||
type = "function",
|
||||
type = "method",
|
||||
description = "Closes file.\n\nNote that files are automatically closed when their handles are garbage collected, but that takes an unpredictable amount of time to happen.\n\nWhen closing a file handle created with io.popen, file:close returns the same values returned by os.execute. RETURN SPECIAL CASE ADDED IN Lua 5.2.",
|
||||
args = "(file: file)",
|
||||
returns = "(boolean|nil [, string, number])",
|
||||
},
|
||||
flush = {
|
||||
type = "function",
|
||||
type = "method",
|
||||
description = "Saves any written data to file.",
|
||||
args = "(file: file)",
|
||||
returns = "(boolean|nil [, string])",
|
||||
},
|
||||
lines = {
|
||||
type = "function",
|
||||
type = "method",
|
||||
description = "Returns an iterator function that, each time it is called, reads the file according to the given formats.\n\nWhen no format is given, uses \"*l\" as a default. ARGUMENT ADDED IN Lua 5.2.\n\nUnlike io.lines, this function does not close the file when the loop ends.\n\nIn case of errors this function raises the error, instead of returning an error code.",
|
||||
args = "(file: file, ...)",
|
||||
returns = "(function)",
|
||||
},
|
||||
read = {
|
||||
type = "function",
|
||||
type = "method",
|
||||
description = "Reads the file file, according to the given formats, which specify what to read.\n\nFor each format, the function returns a string (or a number) with the characters read, or nil if it cannot read data with the specified format. When called without formats, it uses a default format that reads the next line (see below).\n\nThe available formats are\n\n* \"*n\": reads a number; this is the only format that returns a number instead of a string.\n\n* \"*a\": reads the whole file, starting at the current position. On end of file, it returns the empty string.\n\n* \"*l\": reads the next line skipping the end of line, returning nil on end of file. This is the default format.\n\n* \"*L\": reads the next line keeping the end of line (if present), returning nil on end of file. VALUE ADDED IN Lua 5.2.\n\n* number: reads a string with up to this number of bytes, returning nil on end of file. If number is zero, it reads nothing and returns an empty string, or nil on end of file.",
|
||||
args = "(file: file, ...)",
|
||||
returns = "(...)",
|
||||
},
|
||||
seek = {
|
||||
type = "function",
|
||||
type = "method",
|
||||
description = "Sets and gets the file position, measured from the beginning of the file, to the position given by offset plus a base specified by the string whence.\n\nThe string whence is specified as follows:\n\n* \"set\": base is position 0 (beginning of the file);\n\n* \"cur\": base is current position;\n\n* \"end\": base is end of file.\n\nIn case of success, seek returns the final file position, measured in bytes from the beginning of the file. If seek fails, it returns nil, plus a string describing the error.\n\nThe default value for whence is \"cur\", and for offset is 0. Therefore, the call file:seek() returns the current file position, without changing it; the call file:seek(\"set\") sets the position to the beginning of the file (and returns 0); and the call file:seek(\"end\") sets the position to the end of the file, and returns its size.",
|
||||
args = "(file: file, [whence: string [, offset: number]])",
|
||||
returns = "(number|nil [, string])",
|
||||
},
|
||||
setvbuf = {
|
||||
type = "function",
|
||||
type = "method",
|
||||
description = "Sets the buffering mode for an output file.\n\nThere are three available modes:\n\n* \"no\": no buffering; the result of any output operation appears immediately.\n\n* \"full\": full buffering; output operation is performed only when the buffer is full or when you explicitly flush the file (see io.flush).\n\n* \"line\": line buffering; output is buffered until a newline is output or there is any input from some special files (such as a terminal device).\n\nFor the last two cases, size specifies the size of the buffer, in bytes. The default is an appropriate size.",
|
||||
args = "(file: file, mode: string [, size: number])",
|
||||
returns = "(boolean|nil [, string])",
|
||||
},
|
||||
write = {
|
||||
type = "function",
|
||||
type = "method",
|
||||
description = "Writes the value of each of its arguments to file.\n\nThe arguments must be strings or numbers.\n\nIn case of success, this function returns file (RETURN CHANGED IN Lua 5.2, BOOLEAN IN LUA 5.1). Otherwise it returns nil plus a string describing the error.",
|
||||
args = "(file: file, ...)",
|
||||
returns = "(file|nil [, string])",
|
||||
|
||||
2488
api/lua/marmalade.lua
Normal file
2488
api/lua/marmalade.lua
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
BIN
bin/clibs/mime/core.dll
Executable file → Normal file
BIN
bin/clibs/mime/core.dll
Executable file → Normal file
Binary file not shown.
BIN
bin/clibs/mime/core.dylib
Normal file → Executable file
BIN
bin/clibs/mime/core.dylib
Normal file → Executable file
Binary file not shown.
Binary file not shown.
BIN
bin/clibs/socket/core.dll
Executable file → Normal file
BIN
bin/clibs/socket/core.dll
Executable file → Normal file
Binary file not shown.
BIN
bin/clibs/socket/core.dylib
Normal file → Executable file
BIN
bin/clibs/socket/core.dylib
Normal file → Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
bin/liblua.dylib
Executable file
BIN
bin/liblua.dylib
Executable file
Binary file not shown.
BIN
bin/libwx.dylib
Normal file → Executable file
BIN
bin/libwx.dylib
Normal file → Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
bin/libzmq.dll
BIN
bin/libzmq.dll
Binary file not shown.
BIN
bin/linux/x64/clibs/mime/core.so
Normal file
BIN
bin/linux/x64/clibs/mime/core.so
Normal file
Binary file not shown.
BIN
bin/linux/x64/clibs/socket/core.so
Normal file
BIN
bin/linux/x64/clibs/socket/core.so
Normal file
Binary file not shown.
BIN
bin/linux/x64/libwx.so
Normal file
BIN
bin/linux/x64/libwx.so
Normal file
Binary file not shown.
BIN
bin/linux/x64/lua
Executable file
BIN
bin/linux/x64/lua
Executable file
Binary file not shown.
BIN
bin/linux/x86/clibs/mime/core.so
Normal file
BIN
bin/linux/x86/clibs/mime/core.so
Normal file
Binary file not shown.
BIN
bin/linux/x86/clibs/socket/core.so
Normal file
BIN
bin/linux/x86/clibs/socket/core.so
Normal file
Binary file not shown.
BIN
bin/linux/x86/libwx.so
Normal file
BIN
bin/linux/x86/libwx.so
Normal file
Binary file not shown.
BIN
bin/linux/x86/lua
Executable file
BIN
bin/linux/x86/lua
Executable file
Binary file not shown.
Binary file not shown.
BIN
bin/lua.exe
Executable file → Normal file
BIN
bin/lua.exe
Executable file → Normal file
Binary file not shown.
BIN
bin/lua5.1.dll
Executable file → Normal file
BIN
bin/lua5.1.dll
Executable file → Normal file
Binary file not shown.
BIN
bin/lua51.dll
BIN
bin/lua51.dll
Binary file not shown.
BIN
bin/winapi.dll
BIN
bin/winapi.dll
Binary file not shown.
BIN
bin/wx.dll
Executable file → Normal file
BIN
bin/wx.dll
Executable file → Normal file
Binary file not shown.
Binary file not shown.
@@ -1,42 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -x
|
||||
|
||||
TEMPLATE_DMG=/tmp/ZeroBraneStudio-template.dmg
|
||||
BUILT_DMG=ZeroBraneStudio.dmg
|
||||
WKDIR=/tmp/zbs-build
|
||||
|
||||
# remove problematic symlink
|
||||
rm ../zbstudio/ZeroBraneStudio.app/Contents/ZeroBraneStudio
|
||||
|
||||
bunzip2 -kf ZeroBraneStudio.dmg.bz2
|
||||
mv ZeroBraneStudio.dmg $TEMPLATE_DMG
|
||||
hdiutil attach "${TEMPLATE_DMG}" -noautoopen -quiet -mountpoint "${WKDIR}"
|
||||
|
||||
rm -rf "${WKDIR}/ZeroBraneStudio.app"
|
||||
|
||||
# copy the app to where it should be
|
||||
cp -pr "../zbstudio/ZeroBraneStudio.app" "${WKDIR}/ZeroBraneStudio.app"
|
||||
|
||||
mkdir "${WKDIR}/ZeroBraneStudio.app/Contents/ZeroBraneStudio"
|
||||
|
||||
# only pick the files listed in manifests and 'myprograms' (if exists)
|
||||
if [[ -d ../myprograms ]]; then MYPROGRAMS=$(cd ..; find myprograms -iname *.lua); fi
|
||||
(cd ".."; tar cf - $MYPROGRAMS $(< zbstudio/MANIFEST) $(< zbstudio/MANIFEST-bin-macos) | (cd "${WKDIR}/ZeroBraneStudio.app/Contents/ZeroBraneStudio/"; tar xf -))
|
||||
|
||||
codesign -s "ZeroBrane LLC" ${WKDIR}/ZeroBraneStudio.app
|
||||
codesign --signature-size 6400 -s "ZeroBrane LLC" ${WKDIR}/ZeroBraneStudio.app/Contents/ZeroBraneStudio/bin/lua.app
|
||||
|
||||
# clean up
|
||||
sudo rm -rf "${WKDIR}/.Trashes"
|
||||
sudo rm -rf "${WKDIR}/.fseventsd"
|
||||
|
||||
hdiutil detach "${WKDIR}" -quiet -force
|
||||
hdiutil convert "${TEMPLATE_DMG}" -quiet -format UDZO -imagekey zlib-level=9 -o "${BUILT_DMG}"
|
||||
|
||||
rm -f "${TEMPLATE_DMG}"
|
||||
|
||||
cd ../zbstudio/ZeroBraneStudio.app/Contents
|
||||
ln -s ../../.. ZeroBraneStudio
|
||||
|
||||
echo Built ${BUILT_DMG}.
|
||||
22
build/build-linux-prep-deb.sh
Executable file
22
build/build-linux-prep-deb.sh
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
|
||||
# this script installs prerequisites to build binary files on Linux with deb
|
||||
|
||||
sudo apt-get install git-core
|
||||
sudo apt-get install g++
|
||||
sudo apt-get install subversion
|
||||
sudo apt-get install libgtk2.0-dev
|
||||
|
||||
# install cmake as wxwidgets needs 2.8.4+ but "sudo apt-get install cmake"
|
||||
# only installs 2.8.0 on some systems (like Ubuntu 10.4)
|
||||
mkdir build-cmake
|
||||
cd build-cmake
|
||||
wget http://www.cmake.org/files/v2.8/cmake-2.8.10.2.tar.gz
|
||||
gunzip cmake-2.8.10.2.tar.gz
|
||||
tar xvf cmake-2.8.10.2.tar
|
||||
cd cmake-2.8.10.2
|
||||
./bootstrap
|
||||
make
|
||||
sudo make install
|
||||
cd ../..
|
||||
rm -rf build-cmake
|
||||
9
build/build-linux-prep-rpm.sh
Normal file
9
build/build-linux-prep-rpm.sh
Normal file
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
# this script installs prerequisites to build binary files on Linux with rpm
|
||||
|
||||
sudo yum install gcc-c++
|
||||
sudo yum install git
|
||||
sudo yum install svn
|
||||
sudo yum install cmake
|
||||
sudo yum install gtk2-devel
|
||||
190
build/build-linux.sh
Executable file
190
build/build-linux.sh
Executable file
@@ -0,0 +1,190 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ "$(uname -m)" = "x86_64" ]; then
|
||||
FPIC="-fpic"
|
||||
ARCH="x64"
|
||||
else
|
||||
FPIC=""
|
||||
ARCH="x86"
|
||||
fi
|
||||
|
||||
# ZBS binary directory
|
||||
BIN_DIR="$(dirname "$PWD")/bin/linux/$ARCH"
|
||||
|
||||
# temporary installation directory for dependencies
|
||||
INSTALL_DIR="$PWD/deps"
|
||||
|
||||
# number of parallel jobs used for building
|
||||
MAKEFLAGS="-j4"
|
||||
|
||||
# flags for manual building with gcc
|
||||
BUILD_FLAGS="-O2 -shared -s -I $INSTALL_DIR/include -L $INSTALL_DIR/lib $FPIC"
|
||||
|
||||
# paths configuration
|
||||
WXWIDGETS_BASENAME="wxWidgets"
|
||||
WXWIDGETS_URL="http://svn.wxwidgets.org/svn/wx/wxWidgets/trunk"
|
||||
|
||||
LIBPNG_BASENAME="libpng-1.6.0"
|
||||
LIBPNG_FILENAME="$LIBPNG_BASENAME.tar.gz"
|
||||
LIBPNG_URL="http://sourceforge.net/projects/libpng/files/libpng16/1.6.0/libpng-1.6.0.tar.gz/download"
|
||||
|
||||
LUA_BASENAME="lua-5.1.5"
|
||||
LUA_FILENAME="$LUA_BASENAME.tar.gz"
|
||||
LUA_URL="http://www.lua.org/ftp/$LUA_FILENAME"
|
||||
|
||||
WXLUA_BASENAME="wxlua"
|
||||
WXLUA_URL="https://wxlua.svn.sourceforge.net/svnroot/wxlua/trunk"
|
||||
|
||||
LUASOCKET_BASENAME="luasocket-2.0.2"
|
||||
LUASOCKET_FILENAME="$LUASOCKET_BASENAME.tar.gz"
|
||||
LUASOCKET_URL="http://files.luaforge.net/releases/luasocket/luasocket/luasocket-2.0.2/$LUASOCKET_FILENAME"
|
||||
|
||||
# exit if the command line is empty
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Usage: $0 LIBRARY..."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# iterate through the command line arguments
|
||||
for ARG in "$@"; do
|
||||
case $ARG in
|
||||
wxwidgets)
|
||||
BUILD_WXWIDGETS=true
|
||||
;;
|
||||
lua)
|
||||
BUILD_LUA=true
|
||||
;;
|
||||
wxlua)
|
||||
BUILD_WXLUA=true
|
||||
;;
|
||||
luasocket)
|
||||
BUILD_LUASOCKET=true
|
||||
;;
|
||||
all)
|
||||
BUILD_WXWIDGETS=true
|
||||
BUILD_LUA=true
|
||||
BUILD_WXLUA=true
|
||||
BUILD_LUASOCKET=true
|
||||
;;
|
||||
*)
|
||||
echo "Error: invalid argument $ARG"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# check for g++
|
||||
if [ ! "$(which g++)" ]; then
|
||||
echo "Error: g++ isn't found. Please install GNU C++ compiler."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check for cmake
|
||||
if [ ! "$(which cmake)" ]; then
|
||||
echo "Error: cmake isn't found. Please install CMake and add it to PATH."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check for svn
|
||||
if [ ! "$(which svn)" ]; then
|
||||
echo "Error: svn isn't found. Please install console SVN client."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check for wget
|
||||
if [ ! "$(which wget)" ]; then
|
||||
echo "Error: wget isn't found. Please install GNU Wget."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# create the installation directory
|
||||
mkdir -p "$INSTALL_DIR" || { echo "Error: cannot create directory $INSTALL_DIR"; exit 1; }
|
||||
|
||||
# build wxWidgets
|
||||
if [ $BUILD_WXWIDGETS ]; then
|
||||
# first build get/configure libpng as v1.6 is needed
|
||||
wget -c "$LIBPNG_URL" -O "$LIBPNG_FILENAME" || { echo "Error: failed to download lbpng"; exit 1; }
|
||||
tar -xzf "$LIBPNG_FILENAME"
|
||||
(cd "$LIBPNG_BASENAME"; ./configure --with-libpng-prefix=wxpng_; make $MAKEFLAGS)
|
||||
|
||||
svn co "$WXWIDGETS_URL" "$WXWIDGETS_BASENAME" || { echo "Error: failed to checkout wxWidgets"; exit 1; }
|
||||
# replace src/png with the libpng folder
|
||||
rm -rf "$WXWIDGETS_BASENAME/src/png"
|
||||
mv "$LIBPNG_BASENAME" "$WXWIDGETS_BASENAME/src/png"
|
||||
|
||||
cd "$WXWIDGETS_BASENAME"
|
||||
./configure --prefix="$INSTALL_DIR" --disable-debug --disable-shared --enable-unicode \
|
||||
--with-libjpeg=builtin --with-libpng=builtin --with-libtiff=no --with-expat=no \
|
||||
--with-zlib=builtin --disable-richtext --with-gtk=2 \
|
||||
CFLAGS="-Os -fPIC" CXXFLAGS="-Os -fPIC"
|
||||
make $MAKEFLAGS || { echo "Error: failed to build wxWidgets"; exit 1; }
|
||||
make install
|
||||
cd ..
|
||||
rm -rf "$WXWIDGETS_BASENAME" "$LIBPNG_FILENAME"
|
||||
fi
|
||||
|
||||
# build Lua
|
||||
if [ $BUILD_LUA ]; then
|
||||
wget -c "$LUA_URL" -O "$LUA_FILENAME" || { echo "Error: failed to download Lua"; exit 1; }
|
||||
tar -xzf "$LUA_FILENAME"
|
||||
cd "$LUA_BASENAME"
|
||||
# use POSIX as it has minimum dependencies (no readline and no ncurses required)
|
||||
# LUA_USE_DLOPEN is required for loading libraries
|
||||
(cd src; make all MYCFLAGS="$FPIC -DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-Wl,-E -ldl") || { echo "Error: failed to build Lua"; exit 1; }
|
||||
make install INSTALL_TOP="$INSTALL_DIR"
|
||||
cd ..
|
||||
rm -rf "$LUA_FILENAME" "$LUA_BASENAME"
|
||||
fi
|
||||
|
||||
# build wxLua
|
||||
if [ $BUILD_WXLUA ]; then
|
||||
svn co "$WXLUA_URL" "$WXLUA_BASENAME" || { echo "Error: failed to checkout wxLua"; exit 1; }
|
||||
cd "$WXLUA_BASENAME/wxLua"
|
||||
# the following patches wxlua source to fix live coding support in wxlua apps
|
||||
# http://www.mail-archive.com/wxlua-users@lists.sourceforge.net/msg03225.html
|
||||
sed -i 's/\(m_wxlState = wxLuaState(wxlState.GetLuaState(), wxLUASTATE_GETSTATE|wxLUASTATE_ROOTSTATE);\)/\/\/ removed by ZBS build process \/\/ \1/' modules/wxlua/wxlcallb.cpp
|
||||
cmake -G "Unix Makefiles" -DBUILD_INSTALL_PREFIX="$INSTALL_DIR" -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SHARED_LIBS=FALSE \
|
||||
-DwxWidgets_CONFIG_EXECUTABLE="$INSTALL_DIR/bin/wx-config" \
|
||||
-DwxWidgets_COMPONENTS="stc;html;aui;adv;core;net;base" \
|
||||
-DwxLuaBind_COMPONENTS="stc;html;aui;adv;core;net;base" -DwxLua_LUA_LIBRARY_USE_BUILTIN=FALSE \
|
||||
-DwxLua_LUA_INCLUDE_DIR="$INSTALL_DIR/include" -DwxLua_LUA_LIBRARY="$INSTALL_DIR/lib/liblua.a" .
|
||||
(cd modules/luamodule; make $MAKEFLAGS) || { echo "Error: failed to build wxLua"; exit 1; }
|
||||
(cd modules/luamodule; make install/strip)
|
||||
[ -f "$INSTALL_DIR/lib/libwx.so" ] || { echo "Error: libwx.so isn't found"; exit 1; }
|
||||
cd ../..
|
||||
rm -rf "$WXLUA_BASENAME"
|
||||
fi
|
||||
|
||||
# build LuaSocket
|
||||
if [ $BUILD_LUASOCKET ]; then
|
||||
wget -c "$LUASOCKET_URL" -O "$LUASOCKET_FILENAME" || { echo "Error: failed to download LuaSocket"; exit 1; }
|
||||
tar -xzf "$LUASOCKET_FILENAME"
|
||||
cd "$LUASOCKET_BASENAME"
|
||||
mkdir -p "$INSTALL_DIR/lib/lua/5.1/"{mime,socket}
|
||||
gcc $BUILD_FLAGS -o "$INSTALL_DIR/lib/lua/5.1/mime/core.so" src/mime.c -llua \
|
||||
|| { echo "Error: failed to build LuaSocket"; exit 1; }
|
||||
gcc $BUILD_FLAGS -o "$INSTALL_DIR/lib/lua/5.1/socket/core.so" \
|
||||
src/{auxiliar.c,buffer.c,except.c,inet.c,io.c,luasocket.c,options.c,select.c,tcp.c,timeout.c,udp.c,usocket.c} -llua \
|
||||
|| { echo "Error: failed to build LuaSocket"; exit 1; }
|
||||
mkdir -p "$INSTALL_DIR/share/lua/5.1/socket"
|
||||
cp src/{ftp.lua,http.lua,smtp.lua,tp.lua,url.lua} "$INSTALL_DIR/share/lua/5.1/socket"
|
||||
cp src/{ltn12.lua,mime.lua,socket.lua} "$INSTALL_DIR/share/lua/5.1"
|
||||
[ -f "$INSTALL_DIR/lib/lua/5.1/mime/core.so" ] || { echo "Error: mime/core.so isn't found"; exit 1; }
|
||||
[ -f "$INSTALL_DIR/lib/lua/5.1/socket/core.so" ] || { echo "Error: socket/core.so isn't found"; exit 1; }
|
||||
cd ..
|
||||
rm -rf "$LUASOCKET_FILENAME" "$LUASOCKET_BASENAME"
|
||||
fi
|
||||
|
||||
# now copy the compiled dependencies to ZBS binary directory
|
||||
mkdir -p "$BIN_DIR" || { echo "Error: cannot create directory $BIN_DIR"; exit 1; }
|
||||
[ $BUILD_LUA ] && cp "$INSTALL_DIR/bin/lua" "$BIN_DIR"
|
||||
[ $BUILD_WXLUA ] && cp "$INSTALL_DIR/lib/libwx.so" "$BIN_DIR"
|
||||
if [ $BUILD_LUASOCKET ]; then
|
||||
mkdir -p "$BIN_DIR/clibs/"{mime,socket}
|
||||
cp "$INSTALL_DIR/lib/lua/5.1/mime/core.so" "$BIN_DIR/clibs/mime"
|
||||
cp "$INSTALL_DIR/lib/lua/5.1/socket/core.so" "$BIN_DIR/clibs/socket"
|
||||
fi
|
||||
|
||||
# show a message about successful completion
|
||||
echo "*** Build has been successfully completed ***"
|
||||
exit 0
|
||||
189
build/build-macosx.sh
Executable file
189
build/build-macosx.sh
Executable file
@@ -0,0 +1,189 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ZBS binary directory
|
||||
BIN_DIR="$(dirname "$PWD")/bin"
|
||||
|
||||
# temporary installation directory for dependencies
|
||||
INSTALL_DIR="$PWD/deps"
|
||||
|
||||
# Mac OS X global settings
|
||||
MACOSX_ARCH="i386"
|
||||
MACOSX_VERSION="10.6"
|
||||
MACOSX_SDK_PATH="/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.6.sdk"
|
||||
|
||||
# number of parallel jobs used for building
|
||||
MAKEFLAGS="-j4"
|
||||
|
||||
# flags for manual building with gcc; build universal binaries for luasocket
|
||||
MACOSX_FLAGS="-arch $MACOSX_ARCH -mmacosx-version-min=$MACOSX_VERSION -isysroot $MACOSX_SDK_PATH"
|
||||
BUILD_FLAGS="-O2 -arch x86_64 -dynamiclib -undefined dynamic_lookup $MACOSX_FLAGS -I $INSTALL_DIR/include -L $INSTALL_DIR/lib"
|
||||
|
||||
# paths configuration
|
||||
WXWIDGETS_BASENAME="wxWidgets"
|
||||
WXWIDGETS_URL="http://svn.wxwidgets.org/svn/wx/wxWidgets/trunk"
|
||||
|
||||
LUA_BASENAME="lua-5.1.5"
|
||||
LUA_FILENAME="$LUA_BASENAME.tar.gz"
|
||||
LUA_URL="http://www.lua.org/ftp/$LUA_FILENAME"
|
||||
|
||||
WXLUA_BASENAME="wxlua"
|
||||
WXLUA_URL="https://wxlua.svn.sourceforge.net/svnroot/wxlua/trunk"
|
||||
|
||||
LUASOCKET_BASENAME="luasocket-2.0.2"
|
||||
LUASOCKET_FILENAME="$LUASOCKET_BASENAME.tar.gz"
|
||||
LUASOCKET_URL="http://files.luaforge.net/releases/luasocket/luasocket/luasocket-2.0.2/$LUASOCKET_FILENAME"
|
||||
|
||||
# exit if the command line is empty
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Usage: $0 LIBRARY..."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# iterate through the command line arguments
|
||||
for ARG in "$@"; do
|
||||
case $ARG in
|
||||
wxwidgets)
|
||||
BUILD_WXWIDGETS=true
|
||||
;;
|
||||
lua)
|
||||
BUILD_LUA=true
|
||||
;;
|
||||
wxlua)
|
||||
BUILD_WXLUA=true
|
||||
;;
|
||||
luasocket)
|
||||
BUILD_LUASOCKET=true
|
||||
;;
|
||||
all)
|
||||
BUILD_WXWIDGETS=true
|
||||
BUILD_LUA=true
|
||||
BUILD_WXLUA=true
|
||||
BUILD_LUASOCKET=true
|
||||
;;
|
||||
*)
|
||||
echo "Error: invalid argument $ARG"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# check for g++
|
||||
if [ ! "$(which g++)" ]; then
|
||||
echo "Error: g++ isn't found. Please install GNU C++ compiler."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check for cmake
|
||||
if [ ! "$(which cmake)" ]; then
|
||||
echo "Error: cmake isn't found. Please install CMake and add it to PATH."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check for svn
|
||||
if [ ! "$(which svn)" ]; then
|
||||
echo "Error: svn isn't found. Please install console SVN client."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check for wget
|
||||
if [ ! "$(which wget)" ]; then
|
||||
echo "Error: wget isn't found. Please install GNU Wget."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# create the installation directory
|
||||
mkdir -p "$INSTALL_DIR" || { echo "Error: cannot create directory $INSTALL_DIR"; exit 1; }
|
||||
|
||||
# build wxWidgets
|
||||
if [ $BUILD_WXWIDGETS ]; then
|
||||
svn co "$WXWIDGETS_URL" "$WXWIDGETS_BASENAME" || { echo "Error: failed to checkout wxWidgets"; exit 1; }
|
||||
cd "$WXWIDGETS_BASENAME"
|
||||
./configure --prefix="$INSTALL_DIR" --disable-debug --disable-shared --enable-unicode \
|
||||
--with-libjpeg=builtin --with-libpng=builtin --with-libtiff=no --with-expat=no \
|
||||
--with-zlib=builtin --disable-richtext \
|
||||
--enable-macosx_arch=$MACOSX_ARCH --with-macosx-version-min=$MACOSX_VERSION --with-macosx-sdk="$MACOSX_SDK_PATH" \
|
||||
--with-osx_cocoa CFLAGS="-Os" CXXFLAGS="-Os"
|
||||
make $MAKEFLAGS || { echo "Error: failed to build wxWidgets"; exit 1; }
|
||||
make install
|
||||
cd ..
|
||||
rm -rf "$WXWIDGETS_BASENAME"
|
||||
fi
|
||||
|
||||
# build Lua
|
||||
if [ $BUILD_LUA ]; then
|
||||
wget -c "$LUA_URL" -O "$LUA_FILENAME" || { echo "Error: failed to download Lua"; exit 1; }
|
||||
tar -xzf "$LUA_FILENAME"
|
||||
cd "$LUA_BASENAME"
|
||||
sed -i "" 's/PLATS=/& macosx_dylib/' Makefile
|
||||
printf "macosx_dylib:\n" >> src/Makefile
|
||||
printf "\t\$(MAKE) LUA_A=\"liblua.dylib\" AR=\"\$(CC) -dynamiclib $MACOSX_FLAGS -o\" RANLIB=\"strip -u -r\" \\\\\n" >> src/Makefile
|
||||
printf "\tMYCFLAGS=\"-DLUA_USE_LINUX $MACOSX_FLAGS\" MYLDFLAGS=\"$MACOSX_FLAGS\" MYLIBS=\"-lreadline\" lua\n" >> src/Makefile
|
||||
printf "\t\$(MAKE) MYCFLAGS=\"-DLUA_USE_LINUX $MACOSX_FLAGS\" MYLDFLAGS=\"$MACOSX_FLAGS\" luac\n" >> src/Makefile
|
||||
make macosx_dylib || { echo "Error: failed to build Lua"; exit 1; }
|
||||
make install INSTALL_TOP="$INSTALL_DIR"
|
||||
strip -u -r "$INSTALL_DIR/bin/lua"
|
||||
cp src/liblua.dylib "$INSTALL_DIR/lib"
|
||||
[ -f "$INSTALL_DIR/lib/liblua.dylib" ] || { echo "Error: liblua.dylib isn't found"; exit 1; }
|
||||
cd ..
|
||||
rm -rf "$LUA_FILENAME" "$LUA_BASENAME"
|
||||
fi
|
||||
|
||||
# build wxLua
|
||||
if [ $BUILD_WXLUA ]; then
|
||||
svn co "$WXLUA_URL" "$WXLUA_BASENAME" || { echo "Error: failed to checkout wxLua"; exit 1; }
|
||||
cd "$WXLUA_BASENAME/wxLua"
|
||||
# the following patches wxlua source to fix live coding support in wxlua apps
|
||||
# http://www.mail-archive.com/wxlua-users@lists.sourceforge.net/msg03225.html
|
||||
sed -i "" 's/\(m_wxlState = wxLuaState(wxlState.GetLuaState(), wxLUASTATE_GETSTATE|wxLUASTATE_ROOTSTATE);\)/\/\/ removed by ZBS build process \/\/ \1/' modules/wxlua/wxlcallb.cpp
|
||||
cmake -G "Unix Makefiles" -DBUILD_INSTALL_PREFIX="$INSTALL_DIR" -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SHARED_LIBS=FALSE \
|
||||
-DCMAKE_OSX_ARCHITECTURES=$MACOSX_ARCH -DCMAKE_OSX_DEPLOYMENT_TARGET=$MACOSX_VERSION CMAKE_OSX_SYSROOT="$MACOSX_SDK_PATH" \
|
||||
-DCMAKE_C_COMPILER=/usr/bin/gcc -DCMAKE_CXX_COMPILER=/usr/bin/g++ -DwxWidgets_CONFIG_EXECUTABLE="$INSTALL_DIR/bin/wx-config" \
|
||||
-DwxWidgets_COMPONENTS="stc;html;aui;adv;core;net;base" \
|
||||
-DwxLuaBind_COMPONENTS="stc;html;aui;adv;core;net;base" -DwxLua_LUA_LIBRARY_USE_BUILTIN=FALSE \
|
||||
-DwxLua_LUA_INCLUDE_DIR="$INSTALL_DIR/include" -DwxLua_LUA_LIBRARY="$INSTALL_DIR/lib/liblua.dylib" .
|
||||
(cd modules/luamodule; make $MAKEFLAGS) || { echo "Error: failed to build wxLua"; exit 1; }
|
||||
(cd modules/luamodule; make install/strip)
|
||||
strip -u -r "$INSTALL_DIR/lib/libwx.dylib"
|
||||
[ -f "$INSTALL_DIR/lib/libwx.dylib" ] || { echo "Error: libwx.dylib isn't found"; exit 1; }
|
||||
cd ../..
|
||||
rm -rf "$WXLUA_BASENAME"
|
||||
fi
|
||||
|
||||
# build LuaSocket
|
||||
if [ $BUILD_LUASOCKET ]; then
|
||||
wget -c "$LUASOCKET_URL" -O "$LUASOCKET_FILENAME" || { echo "Error: failed to download LuaSocket"; exit 1; }
|
||||
tar -xzf "$LUASOCKET_FILENAME"
|
||||
cd "$LUASOCKET_BASENAME"
|
||||
mkdir -p "$INSTALL_DIR/lib/lua/5.1/"{mime,socket}
|
||||
gcc $BUILD_FLAGS -o "$INSTALL_DIR/lib/lua/5.1/mime/core.dylib" src/mime.c \
|
||||
|| { echo "Error: failed to build LuaSocket"; exit 1; }
|
||||
gcc $BUILD_FLAGS -o "$INSTALL_DIR/lib/lua/5.1/socket/core.dylib" \
|
||||
src/{auxiliar.c,buffer.c,except.c,inet.c,io.c,luasocket.c,options.c,select.c,tcp.c,timeout.c,udp.c,usocket.c} \
|
||||
|| { echo "Error: failed to build LuaSocket"; exit 1; }
|
||||
strip -u -r "$INSTALL_DIR/lib/lua/5.1/mime/core.dylib" "$INSTALL_DIR/lib/lua/5.1/socket/core.dylib"
|
||||
mkdir -p "$INSTALL_DIR/share/lua/5.1/socket"
|
||||
cp src/{ftp.lua,http.lua,smtp.lua,tp.lua,url.lua} "$INSTALL_DIR/share/lua/5.1/socket"
|
||||
cp src/{ltn12.lua,mime.lua,socket.lua} "$INSTALL_DIR/share/lua/5.1"
|
||||
[ -f "$INSTALL_DIR/lib/lua/5.1/mime/core.dylib" ] || { echo "Error: mime/core.dylib isn't found"; exit 1; }
|
||||
[ -f "$INSTALL_DIR/lib/lua/5.1/socket/core.dylib" ] || { echo "Error: socket/core.dylib isn't found"; exit 1; }
|
||||
cd ..
|
||||
rm -rf "$LUASOCKET_FILENAME" "$LUASOCKET_BASENAME"
|
||||
fi
|
||||
|
||||
# now copy the compiled dependencies to ZBS binary directory
|
||||
mkdir -p "$BIN_DIR" || { echo "Error: cannot create directory $BIN_DIR"; exit 1; }
|
||||
if [ $BUILD_LUA ]; then
|
||||
mkdir -p "$BIN_DIR/lua.app/Contents/MacOS"
|
||||
cp "$INSTALL_DIR/bin/lua" "$BIN_DIR/lua.app/Contents/MacOS"
|
||||
cp "$INSTALL_DIR/bin/lua" "$INSTALL_DIR/lib/liblua.dylib" "$BIN_DIR"
|
||||
fi
|
||||
[ $BUILD_WXLUA ] && cp "$INSTALL_DIR/lib/libwx.dylib" "$BIN_DIR"
|
||||
if [ $BUILD_LUASOCKET ]; then
|
||||
mkdir -p "$BIN_DIR/clibs/"{mime,socket}
|
||||
cp "$INSTALL_DIR/lib/lua/5.1/mime/core.dylib" "$BIN_DIR/clibs/mime"
|
||||
cp "$INSTALL_DIR/lib/lua/5.1/socket/core.dylib" "$BIN_DIR/clibs/socket"
|
||||
fi
|
||||
|
||||
# show a message about successful completion
|
||||
echo "*** Build has been successfully completed ***"
|
||||
exit 0
|
||||
216
build/build-win32.sh
Normal file
216
build/build-win32.sh
Normal file
@@ -0,0 +1,216 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ZBS binary directory
|
||||
BIN_DIR="$(dirname "$PWD")/bin"
|
||||
|
||||
# temporary installation directory for dependencies
|
||||
INSTALL_DIR="$PWD/deps"
|
||||
|
||||
# number of parallel jobs used for building
|
||||
MAKEFLAGS="-j4"
|
||||
|
||||
# flags for manual building with gcc
|
||||
BUILD_FLAGS="-O2 -shared -s -I $INSTALL_DIR/include -L $INSTALL_DIR/lib"
|
||||
|
||||
# paths configuration
|
||||
WXWIDGETS_BASENAME="wxWidgets"
|
||||
WXWIDGETS_URL="http://svn.wxwidgets.org/svn/wx/wxWidgets/trunk"
|
||||
|
||||
LUA_BASENAME="lua-5.1.5"
|
||||
LUA_FILENAME="$LUA_BASENAME.tar.gz"
|
||||
LUA_URL="http://www.lua.org/ftp/$LUA_FILENAME"
|
||||
|
||||
WXLUA_BASENAME="wxlua"
|
||||
WXLUA_URL="https://wxlua.svn.sourceforge.net/svnroot/wxlua/trunk"
|
||||
|
||||
LUASOCKET_BASENAME="luasocket-2.0.2"
|
||||
LUASOCKET_FILENAME="$LUASOCKET_BASENAME.tar.gz"
|
||||
LUASOCKET_URL="http://files.luaforge.net/releases/luasocket/luasocket/luasocket-2.0.2/$LUASOCKET_FILENAME"
|
||||
|
||||
WINAPI_BASENAME="winapi"
|
||||
WINAPI_URL="https://github.com/stevedonovan/winapi.git"
|
||||
|
||||
# exit if the command line is empty
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Usage: $0 LIBRARY..."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# iterate through the command line arguments
|
||||
for ARG in "$@"; do
|
||||
case $ARG in
|
||||
wxwidgets)
|
||||
BUILD_WXWIDGETS=true
|
||||
;;
|
||||
lua)
|
||||
BUILD_LUA=true
|
||||
;;
|
||||
wxlua)
|
||||
BUILD_WXLUA=true
|
||||
;;
|
||||
luasocket)
|
||||
BUILD_LUASOCKET=true
|
||||
;;
|
||||
winapi)
|
||||
BUILD_WINAPI=true
|
||||
;;
|
||||
zbstudio)
|
||||
BUILD_ZBSTUDIO=true
|
||||
;;
|
||||
all)
|
||||
BUILD_WXWIDGETS=true
|
||||
BUILD_LUA=true
|
||||
BUILD_WXLUA=true
|
||||
BUILD_LUASOCKET=true
|
||||
BUILD_WINAPI=true
|
||||
BUILD_ZBSTUDIO=true
|
||||
;;
|
||||
*)
|
||||
echo "Error: invalid argument $ARG"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# check for g++
|
||||
if [ ! "$(which g++)" ]; then
|
||||
echo "Error: g++ isn't found. Please install MinGW C++ compiler."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check for cmake
|
||||
if [ ! "$(which cmake)" ]; then
|
||||
echo "Error: cmake isn't found. Please install CMake and add it to PATH."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check for svn
|
||||
if [[ ($BUILD_WXWIDGETS || $BUILD_LUA) && ! "$(which svn)" ]]; then
|
||||
echo "Error: svn isn't found. Please install console SVN client."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check for git
|
||||
if [[ $BUILD_WINAPI && ! "$(which git)" ]]; then
|
||||
echo "Error: git isn't found. Please install console GIT client."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check for wget
|
||||
if [ ! "$(which wget)" ]; then
|
||||
# NOTE: can't check the return status since mingw-get always returns 0 even in the case of errors :(
|
||||
mingw-get install msys-wget
|
||||
fi
|
||||
|
||||
# create the installation directory
|
||||
mkdir -p "$INSTALL_DIR" || { echo "Error: cannot create directory $INSTALL_DIR"; exit 1; }
|
||||
|
||||
# build wxWidgets
|
||||
if [ $BUILD_WXWIDGETS ]; then
|
||||
svn co "$WXWIDGETS_URL" "$WXWIDGETS_BASENAME" || { echo "Error: failed to checkout wxWidgets"; exit 1; }
|
||||
svn revert -R "$WXWIDGETS_BASENAME"
|
||||
cd "$WXWIDGETS_BASENAME"
|
||||
./configure --prefix="$INSTALL_DIR" --disable-debug --disable-shared --enable-unicode \
|
||||
--with-libjpeg=builtin --with-libpng=builtin --with-libtiff=no --with-expat=no \
|
||||
--with-zlib=builtin --disable-richtext \
|
||||
CFLAGS="-Os -fno-keep-inline-dllexport" CXXFLAGS="-Os -fno-keep-inline-dllexport"
|
||||
make $MAKEFLAGS || { echo "Error: failed to build wxWidgets"; exit 1; }
|
||||
make install
|
||||
cd ..
|
||||
rm -rf "$WXWIDGETS_BASENAME"
|
||||
fi
|
||||
|
||||
# build Lua
|
||||
if [ $BUILD_LUA ]; then
|
||||
wget -c "$LUA_URL" -O "$LUA_FILENAME" || { echo "Error: failed to download Lua"; exit 1; }
|
||||
tar -xzf "$LUA_FILENAME"
|
||||
cd "$LUA_BASENAME"
|
||||
make mingw || { echo "Error: failed to build Lua"; exit 1; }
|
||||
make install INSTALL_TOP="$INSTALL_DIR"
|
||||
cp src/lua51.dll "$INSTALL_DIR/lib"
|
||||
[ -f "$INSTALL_DIR/lib/lua51.dll" ] || { echo "Error: lua51.dll isn't found"; exit 1; }
|
||||
cd ..
|
||||
rm -rf "$LUA_FILENAME" "$LUA_BASENAME"
|
||||
fi
|
||||
|
||||
# build wxLua
|
||||
if [ $BUILD_WXLUA ]; then
|
||||
svn co "$WXLUA_URL" "$WXLUA_BASENAME" || { echo "Error: failed to checkout wxLua"; exit 1; }
|
||||
svn revert -R "$WXLUA_BASENAME"
|
||||
cd "$WXLUA_BASENAME/wxLua"
|
||||
sed -i 's|:-/\(.\)/|:-\1:/|' "$INSTALL_DIR/bin/wx-config"
|
||||
sed -i 's/execute_process(COMMAND/& sh/' build/CMakewxAppLib.cmake modules/wxstedit/build/CMakewxAppLib.cmake
|
||||
# the following patches wxlua source to fix live coding support in wxlua apps
|
||||
# http://www.mail-archive.com/wxlua-users@lists.sourceforge.net/msg03225.html
|
||||
sed -i 's/\(m_wxlState = wxLuaState(wxlState.GetLuaState(), wxLUASTATE_GETSTATE|wxLUASTATE_ROOTSTATE);\)/\/\/ removed by ZBS build process \/\/ \1/' modules/wxlua/wxlcallb.cpp
|
||||
cp "$INSTALL_DIR/lib/libwxscintilla-2.9.a" "$INSTALL_DIR/lib/libwx_mswu_scintilla-2.9.a"
|
||||
echo "set_target_properties(wxLuaModule PROPERTIES LINK_FLAGS -static)" >> modules/luamodule/CMakeLists.txt
|
||||
cmake -G "MSYS Makefiles" -DBUILD_INSTALL_PREFIX="$INSTALL_DIR" -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SHARED_LIBS=FALSE \
|
||||
-DwxWidgets_CONFIG_EXECUTABLE="$INSTALL_DIR/bin/wx-config" \
|
||||
-DwxWidgets_COMPONENTS="stc;html;aui;adv;core;net;base" \
|
||||
-DwxLuaBind_COMPONENTS="stc;html;aui;adv;core;net;base" -DwxLua_LUA_LIBRARY_USE_BUILTIN=FALSE \
|
||||
-DwxLua_LUA_INCLUDE_DIR="$INSTALL_DIR/include" -DwxLua_LUA_LIBRARY="$INSTALL_DIR/lib/lua51.dll" .
|
||||
(cd modules/luamodule; make $MAKEFLAGS) || { echo "Error: failed to build wxLua"; exit 1; }
|
||||
(cd modules/luamodule; make install/strip)
|
||||
[ -f "$INSTALL_DIR/bin/libwx.dll" ] || { echo "Error: libwx.dll isn't found"; exit 1; }
|
||||
cd ../..
|
||||
rm -rf "$WXLUA_BASENAME"
|
||||
fi
|
||||
|
||||
# build LuaSocket
|
||||
if [ $BUILD_LUASOCKET ]; then
|
||||
wget -c "$LUASOCKET_URL" -O "$LUASOCKET_FILENAME" || { echo "Error: failed to download LuaSocket"; exit 1; }
|
||||
tar -xzf "$LUASOCKET_FILENAME"
|
||||
cd "$LUASOCKET_BASENAME"
|
||||
mkdir -p "$INSTALL_DIR/lib/lua/5.1/"{mime,socket}
|
||||
gcc $BUILD_FLAGS -o "$INSTALL_DIR/lib/lua/5.1/mime/core.dll" src/mime.c -llua51 \
|
||||
|| { echo "Error: failed to build LuaSocket"; exit 1; }
|
||||
gcc $BUILD_FLAGS -o "$INSTALL_DIR/lib/lua/5.1/socket/core.dll" \
|
||||
src/{auxiliar.c,buffer.c,except.c,inet.c,io.c,luasocket.c,options.c,select.c,tcp.c,timeout.c,udp.c,wsocket.c} -lwsock32 -llua51 \
|
||||
|| { echo "Error: failed to build LuaSocket"; exit 1; }
|
||||
mkdir -p "$INSTALL_DIR/share/lua/5.1/socket"
|
||||
cp src/{ftp.lua,http.lua,smtp.lua,tp.lua,url.lua} "$INSTALL_DIR/share/lua/5.1/socket"
|
||||
cp src/{ltn12.lua,mime.lua,socket.lua} "$INSTALL_DIR/share/lua/5.1"
|
||||
[ -f "$INSTALL_DIR/lib/lua/5.1/mime/core.dll" ] || { echo "Error: mime/core.dll isn't found"; exit 1; }
|
||||
[ -f "$INSTALL_DIR/lib/lua/5.1/socket/core.dll" ] || { echo "Error: socket/core.dll isn't found"; exit 1; }
|
||||
cd ..
|
||||
rm -rf "$LUASOCKET_FILENAME" "$LUASOCKET_BASENAME"
|
||||
fi
|
||||
|
||||
# build winapi
|
||||
if [ $BUILD_WINAPI ]; then
|
||||
git clone "$WINAPI_URL" "$WINAPI_BASENAME"
|
||||
cd "$WINAPI_BASENAME"
|
||||
gcc $BUILD_FLAGS -DPSAPI_VERSION=1 -o "$INSTALL_DIR/lib/lua/5.1/winapi.dll" winapi.c wutils.c -lpsapi -lmpr -llua51 \
|
||||
|| { echo "Error: failed to build winapi"; exit 1; }
|
||||
[ -f "$INSTALL_DIR/lib/lua/5.1/winapi.dll" ] || { echo "Error: winapi.dll isn't found"; exit 1; }
|
||||
cd ..
|
||||
rm -rf "$WINAPI_BASENAME"
|
||||
fi
|
||||
|
||||
# build ZBS launcher
|
||||
if [ $BUILD_ZBSTUDIO ]; then
|
||||
windres ../zbstudio/res/zbstudio.rc zbstudio.rc.o
|
||||
gcc -O2 -s -mwindows -o ../zbstudio.exe win32_starter.c zbstudio.rc.o
|
||||
rm zbstudio.rc.o
|
||||
[ -f ../zbstudio.exe ] || { echo "Error: zbstudio.exe isn't found"; exit 1; }
|
||||
fi
|
||||
|
||||
# now copy the compiled dependencies to ZBS binary directory
|
||||
mkdir -p "$BIN_DIR" || { echo "Error: cannot create directory $BIN_DIR"; exit 1; }
|
||||
[ $BUILD_LUA ] && cp "$INSTALL_DIR/bin/lua.exe" "$INSTALL_DIR/lib/lua51.dll" "$BIN_DIR"
|
||||
[ $BUILD_WXLUA ] && cp "$INSTALL_DIR/bin/libwx.dll" "$BIN_DIR/wx.dll"
|
||||
[ $BUILD_WINAPI ] && cp "$INSTALL_DIR/lib/lua/5.1/winapi.dll" "$BIN_DIR"
|
||||
if [ $BUILD_LUASOCKET ]; then
|
||||
mkdir -p "$BIN_DIR/clibs/"{mime,socket}
|
||||
cp "$INSTALL_DIR/lib/lua/5.1/mime/core.dll" "$BIN_DIR/clibs/mime"
|
||||
cp "$INSTALL_DIR/lib/lua/5.1/socket/core.dll" "$BIN_DIR/clibs/socket"
|
||||
fi
|
||||
|
||||
# To build lua5.1.dll proxy:
|
||||
# (1) get mkforwardlib-gcc.lua from http://lua-users.org/wiki/LuaProxyDllThree
|
||||
# (2) run it as "lua mkforwardlib-gcc.lua lua51 lua5.1 X86"
|
||||
|
||||
# show a message about successful completion
|
||||
echo "*** Build has been successfully completed ***"
|
||||
exit 0
|
||||
@@ -1,10 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "Installing wxlua modules from ZeroBrane Studio repository..."
|
||||
sudo add-apt-repository ppa:zerobranestudio/zerobranestudio
|
||||
sudo apt-get update
|
||||
sudo apt-get install wxlua28
|
||||
|
||||
# To remove wxlua and required packages use:
|
||||
# sudo apt-get purge wxlua28
|
||||
# sudo apt-get autoremove
|
||||
@@ -19,10 +19,21 @@ require "wx"
|
||||
function FileSysGet(dir,spec)
|
||||
local content = {}
|
||||
local browse = wx.wxFileSystem()
|
||||
local cwd = wx.wxGetCwd()
|
||||
if not wx.wxFileName(dir):DirExists() then return content end
|
||||
local f = browse:FindFirst(dir,spec)
|
||||
while #f>0 do
|
||||
table.insert(content,(f:gsub("^file:",""))) -- drop file: protocol (wx2.9+)
|
||||
if f:match("^file:") then -- remove file: protocol (wx2.9+)
|
||||
f = f:gsub(iswindows and "^file:/?" or "^file:","")
|
||||
:gsub('%%(%x%x)', function(n) return string.char(tonumber(n, 16)) end)
|
||||
end
|
||||
-- wx2.9+ return absolute path here instead of expected relative; fix it
|
||||
if wx.wxIsAbsolutePath(f) then
|
||||
local relative = wx.wxFileName(f)
|
||||
relative:MakeRelativeTo(cwd)
|
||||
f = relative:GetFullPath()
|
||||
end
|
||||
table.insert(content, f)
|
||||
f = browse:FindNext()
|
||||
end
|
||||
return content
|
||||
|
||||
@@ -164,7 +164,7 @@ int main (int argc, char *argv[])
|
||||
|
||||
|
||||
SetDllDirectory(".\\bin\\");
|
||||
hinstLib = LoadLibrary("lua5.1.dll");
|
||||
hinstLib = LoadLibrary("lua51.dll");
|
||||
if (hinstLib != NULL)
|
||||
{
|
||||
luaL_newstate = (voidfunc*) GetProcAddress(hinstLib, "luaL_newstate");
|
||||
@@ -214,7 +214,7 @@ int main (int argc, char *argv[])
|
||||
MB_OK|MB_ICONERROR);
|
||||
} else {
|
||||
MessageBox(NULL,
|
||||
TEXT("Could not load all functions that are supposed to be located in the lua5.1.dll\n"
|
||||
TEXT("Could not load all functions that are supposed to be located in the lua51.dll\n"
|
||||
"This is not supposed to be happening..."),
|
||||
TEXT("Failed to start editor"),
|
||||
MB_OK|MB_ICONERROR);
|
||||
@@ -224,7 +224,7 @@ int main (int argc, char *argv[])
|
||||
FreeLibrary(hinstLib);
|
||||
} else {
|
||||
MessageBox(NULL,
|
||||
TEXT("The lua5.1.dll could not be found or loaded, please check the working directory of the application.\n"),
|
||||
TEXT("The lua51.dll could not be found or loaded, please check the working directory of the application.\n"),
|
||||
TEXT("Failed to initialize editor"),
|
||||
MB_OK|MB_ICONERROR);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
return {
|
||||
[0] = function(c) return c == 1 and 1 or 2 end, -- plural
|
||||
["traced %d instruction"] = {"traced %d instruction", "traced %d instructions"}, -- src\editor\debugger.lua
|
||||
["%d instance"] = {"%d instance", "%d instances"}, -- src\editor\findreplace.lua
|
||||
}
|
||||
|
||||
@@ -6,10 +6,11 @@ return {
|
||||
["&About"] = "&Acerca de...", -- src\editor\menu_help.lua
|
||||
["&Add Watch"] = "Añadir observación", -- src\editor\debugger.lua
|
||||
["&Break"] = "Ruptura", -- src\editor\menu_project.lua
|
||||
["&Close Page"] = "Cerrar página", -- src\editor\menu_file.lua
|
||||
["&Close Page"] = "Cerrar página", -- src\editor\menu_file.lua, src\editor\gui.lua
|
||||
["&Compile"] = "Compilar", -- src\editor\menu_project.lua
|
||||
["&Copy"] = "Copiar", -- src\editor\editor.lua, src\editor\menu_edit.lua
|
||||
["&Default Layout"] = "Diseño por defecto", -- src\editor\menu_view.lua
|
||||
["&Delete Watch"] = "Eliminar observación", -- src\editor\debugger.lua
|
||||
["&Edit Watch"] = "Editar observación", -- src\editor\debugger.lua
|
||||
["&Edit"] = "Editar", -- src\editor\menu_edit.lua
|
||||
["&File"] = "Archivo", -- src\editor\menu_file.lua
|
||||
@@ -23,10 +24,9 @@ return {
|
||||
["&Paste"] = "Pegar", -- src\editor\editor.lua, src\editor\menu_edit.lua
|
||||
["&Project"] = "Proyecto", -- src\editor\menu_project.lua, src\editor\inspect.lua
|
||||
["&Redo"] = "Rehacer", -- src\editor\editor.lua, src\editor\menu_edit.lua
|
||||
["&Remove Watch"] = "Eliminar observación", -- src\editor\debugger.lua
|
||||
["&Replace"] = "Remplazar", -- src\editor\menu_search.lua
|
||||
["&Run"] = "Ejecutar", -- src\editor\menu_project.lua
|
||||
["&Save"] = "Guardar", -- src\editor\menu_file.lua
|
||||
["&Save"] = "Guardar", -- src\editor\menu_file.lua, src\editor\gui.lua
|
||||
["&Search"] = "Buscar", -- src\editor\menu_search.lua
|
||||
["&Sort"] = "Clasificar", -- src\editor\menu_search.lua
|
||||
["&Stack Window"] = "Ventana de la pila de ejecución", -- src\editor\menu_view.lua
|
||||
@@ -34,8 +34,7 @@ return {
|
||||
["&Undo"] = "Deshacer", -- src\editor\editor.lua, src\editor\menu_edit.lua
|
||||
["&View"] = "Ver", -- src\editor\menu_view.lua
|
||||
["&Watch Window"] = "Ventana de observaciones", -- src\editor\menu_view.lua
|
||||
["&Watches"] = "Observaciones", -- src\editor\debugger.lua
|
||||
["About ZeroBrane Studio"] = "Acerca de ZeroBrane Studio", -- src\editor\menu_help.lua
|
||||
["About %s"] = "Acerca de %s", -- src\editor\menu_help.lua
|
||||
["Add Watch Expression"] = "Añadir expresión de observación", -- src\editor\editor.lua
|
||||
["Add to Scratchpad"] = "Añadir al borrador", -- src\editor\editor.lua
|
||||
["All files"] = "Todos los archivos", -- src\editor\commands.lua
|
||||
@@ -53,9 +52,12 @@ return {
|
||||
["Can't run the entry point script ('%s')."] = "No se pude ejecutar el punto de entrada del script (%s).", -- src\editor\debugger.lua
|
||||
["Can't start debugging session due to internal error '%s'."] = "No se puede iniciar la sesión de depuración debido a un error interno '%s'.'", -- src\editor\debugger.lua
|
||||
["Can't start debugging without an opened file or with the current file not being saved ('%s')."] = "No se puede iniciar la depuración sin abrir un archivo o si no ha sido guardado ('%s').", -- src\editor\debugger.lua
|
||||
["Choose ..."] = nil, -- src\editor\menu_project.lua
|
||||
["Choose a project directory"] = "Elegir el directorio del proyecto", -- src\editor\menu_project.lua
|
||||
["Clear &Dynamic Words"] = "Limpiar las palabras dinámicas", -- src\editor\menu_edit.lua
|
||||
["Clear the output window before compiling or debugging"] = "Limpiar la ventana de salida antes de compilar o depurar", -- src\editor\menu_project.lua
|
||||
["Close &Other Pages"] = nil, -- src\editor\gui.lua
|
||||
["Close A&ll Pages"] = nil, -- src\editor\gui.lua
|
||||
["Close the current editor window"] = "Cerrar la ventana actual del editor", -- src\editor\menu_file.lua
|
||||
["Co&ntinue"] = "Continuar", -- src\editor\menu_project.lua
|
||||
["Col: %d"] = "Col: %d", -- src\editor\editor.lua
|
||||
@@ -65,23 +67,25 @@ return {
|
||||
["Compile the current file"] = "Compilar el archivo actual", -- src\editor\menu_project.lua
|
||||
["Complete &Identifier"] = "Completar identificador", -- src\editor\menu_edit.lua
|
||||
["Complete the current identifier"] = "Completar el actual identificador", -- src\editor\menu_edit.lua
|
||||
["Copy selected text to clipboard"] = "Copiar el texto seleccionado al portapapeles", -- src\editor\menu_edit.lua, src\editor\gui.lua
|
||||
["Copy selected text to clipboard"] = "Copiar el texto seleccionado al portapapeles", -- src\editor\menu_edit.lua
|
||||
["Couldn't activate file '%s' for debugging; continuing without it."] = "No se pudo activar el archivo '%s' para la depuración; continuar sin él.", -- src\editor\debugger.lua
|
||||
["Create an empty document"] = "Crear un documento en blanco", -- src\editor\menu_file.lua, src\editor\gui.lua
|
||||
["Cu&t"] = "Cortar", -- src\editor\editor.lua, src\editor\menu_edit.lua
|
||||
["Cut selected text to clipboard"] = "Cortar el texto selecionado al portapapeles", -- src\editor\menu_edit.lua, src\editor\gui.lua
|
||||
["Cut selected text to clipboard"] = "Cortar el texto selecionado al portapapeles", -- src\editor\menu_edit.lua
|
||||
["Debugger server started at %s:%d."] = "Servidor de depuración inciado en %s:%s", -- src\editor\debugger.lua
|
||||
["Debugging session completed (%s)."] = "Sesión de depuración completada (%s).", -- src\editor\debugger.lua
|
||||
["Debugging session started in '%s'."] = "Sesión de depuración iniciada en '%s'.", -- src\editor\debugger.lua
|
||||
["Debugging suspended at %s:%s (couldn't activate the file)."] = nil, -- src\editor\debugger.lua
|
||||
["Do you want to reload it?"] = "¿Quieres recargarlo?", -- src\editor\editor.lua
|
||||
["Do you want to save the changes to '%s'?"] = "¿Quieres guardar los cambios en '%s'?", -- src\editor\commands.lua
|
||||
["E&xit"] = "Salir", -- src\editor\menu_file.lua
|
||||
["Enter Lua code and press Enter to run it."] = "Introduce código Lua y pulsa <Entrer> para ejecutarlo.", -- src\editor\shellbox.lua
|
||||
["Enter line number"] = "Introduce número de línea", -- src\editor\menu_search.lua
|
||||
["Error while loading API file: %s"] = "Error mientras se cargaba el archivo de API: %s", -- src\editor\autocomplete.lua
|
||||
["Error while loading configuration file: %s"] = nil, -- src\editor\style.lua
|
||||
["Error while processing API file: %s"] = "Error mientras se procesaba el archivo de API: %s", -- src\editor\autocomplete.lua
|
||||
["Error while processing configuration file: %s"] = nil, -- src\editor\style.lua
|
||||
["Error"] = "Error", -- src\editor\commands.lua
|
||||
["Evaluate &Watches"] = "Evaluar las observaciones", -- src\editor\debugger.lua
|
||||
["Evaluate in Console"] = "Evaluar en consola", -- src\editor\editor.lua
|
||||
["Execute the current project/file and keep updating the code to see immediate results"] = "Ejecutar el proyecto/archivo actual y manteniendo actualizado el código para ver resultados en tiempo real", -- src\editor\menu_project.lua
|
||||
["Execute the current project/file"] = "Ejecutar el proyecto/archivo actual", -- src\editor\menu_project.lua
|
||||
@@ -113,12 +117,14 @@ return {
|
||||
["Ln: %d"] = "Ln: %d", -- src\editor\editor.lua
|
||||
["Local console"] = "Consola local", -- src\editor\shellbox.lua, src\editor\gui.lua
|
||||
["Lua &Interpreter"] = "Intérprete Lua", -- src\editor\menu_project.lua
|
||||
["Mapped remote request for '%s' to '%s'."] = nil, -- src\editor\debugger.lua
|
||||
["Mixed end-of-line encodings detected."] = nil, -- src\editor\commands.lua
|
||||
["OVR"] = "OVR", -- src\editor\editor.lua
|
||||
["Open an existing document"] = "Abrir un documento existente", -- src\editor\menu_file.lua, src\editor\gui.lua
|
||||
["Open file"] = "Abrir archivo", -- src\editor\commands.lua
|
||||
["Output (running)"] = "Salida (en ejecución)", -- src\editor\output.lua
|
||||
["Output"] = "Salida", -- src\editor\output.lua, src\editor\settings.lua, src\editor\gui.lua
|
||||
["Paste text from the clipboard"] = "Pegar texto desde el portapapeles", -- src\editor\menu_edit.lua, src\editor\gui.lua
|
||||
["Paste text from the clipboard"] = "Pegar texto desde el portapapeles", -- src\editor\menu_edit.lua
|
||||
["Prepend '=' to show complex values on multiple lines."] = "Antepón '=' para ver valores complejos en líneas múltiples", -- src\editor\shellbox.lua
|
||||
["Press cancel to abort."] = "Presiona cancelar para abortar.", -- src\editor\commands.lua
|
||||
["Program '%s' started in '%s' (pid: %d)."] = "Programa '%s' iniciado en '%s' (pid: %d).", -- src\editor\output.lua
|
||||
@@ -127,21 +133,23 @@ return {
|
||||
["Program starting as '%s'."] = "Programa iniciado como '%s'.", -- src\editor\output.lua
|
||||
["Program stopped (pid: %d)."] = "Programa parado (pid: %d).", -- src\editor\debugger.lua
|
||||
["Program unable to run as '%s'."] = "No se puede ejecutar el programa como '%s'.", -- src\editor\output.lua
|
||||
["Project Directory"] = nil, -- src\editor\menu_project.lua
|
||||
["Project"] = "Proyecto", -- src\editor\settings.lua, src\editor\gui.lua
|
||||
["Project/&FileTree Window"] = "Ventana de proyecto/árbol de archivos", -- src\editor\menu_view.lua
|
||||
["R/O"] = "R/O", -- src\editor\editor.lua
|
||||
["R/W"] = "R/W", -- src\editor\editor.lua
|
||||
["Re&place In Files"] = "Remplazar en archivos", -- src\editor\menu_search.lua
|
||||
["Recent Files"] = "Archivos recientes", -- src\editor\menu_file.lua
|
||||
["Redo last edit undone"] = "Rehacer la última edición deshecha", -- src\editor\menu_edit.lua, src\editor\gui.lua
|
||||
["Redo last edit undone"] = "Rehacer la última edición deshecha", -- src\editor\menu_edit.lua
|
||||
["Refused a request to start a new debugging session as there is one in progress already."] = "No se pudo lanzar una nueva sesión de depuración porque ya hay una en curso.", -- src\editor\debugger.lua
|
||||
["Remote console"] = "Consola remota", -- src\editor\shellbox.lua
|
||||
["Replaced an invalid UTF8 character with %s."] = nil, -- src\editor\commands.lua
|
||||
["Reset to default layout"] = "Restablecer el diseño por defecto", -- src\editor\menu_view.lua
|
||||
["Resets the dynamic word list for autocompletion"] = "Restablecer la lista dinámica de palabras para autocompletado", -- src\editor\menu_edit.lua
|
||||
["Run as Scratchpad"] = "Ejecutar como borrador", -- src\editor\menu_project.lua
|
||||
["S&top Debugging"] = "Parar depuración", -- src\editor\menu_project.lua
|
||||
["S&top Process"] = "Parar proceso", -- src\editor\menu_project.lua
|
||||
["Save &As..."] = "Guardar como...", -- src\editor\menu_file.lua
|
||||
["Save &As..."] = "Guardar como...", -- src\editor\menu_file.lua, src\editor\gui.lua
|
||||
["Save A&ll"] = "Guardar todo", -- src\editor\menu_file.lua
|
||||
["Save Changes?"] = "¿Guardar cambios?", -- src\editor\commands.lua
|
||||
["Save all open documents"] = "Guardar todos los documentos abiertos", -- src\editor\menu_file.lua, src\editor\gui.lua
|
||||
@@ -153,12 +161,14 @@ return {
|
||||
["Scratchpad error"] = "Error en el borrador", -- src\editor\debugger.lua
|
||||
["Select &All"] = "Seleccionar todo", -- src\editor\editor.lua, src\editor\menu_edit.lua
|
||||
["Select all text in the editor"] = "Seleccionar todo el texto en el editor", -- src\editor\menu_edit.lua
|
||||
["Set project directory from current file"] = "Establecer el directorio del proyecto del archivo actual", -- src\editor\gui.lua
|
||||
["Set From Current File"] = nil, -- src\editor\menu_project.lua
|
||||
["Set project directory from current file"] = "Establecer el directorio del proyecto del archivo actual", -- src\editor\menu_project.lua, src\editor\gui.lua
|
||||
["Set the interpreter to be used"] = "Establecer el intérprete a ser usado", -- src\editor\menu_project.lua
|
||||
["Set the project directory to be used"] = nil, -- src\editor\menu_project.lua
|
||||
["Show &Tooltip"] = "Ver tooltip", -- src\editor\menu_edit.lua
|
||||
["Show tooltip for current position; place cursor after opening bracket of function"] = "Ver tooltip para la posición actual; posicionar el cursor después de abrir el paréntisis de los argumentos de la función", -- src\editor\menu_edit.lua
|
||||
["Sort selected lines"] = "Clasificar las líneas seleccionadas", -- src\editor\menu_search.lua
|
||||
["Stack Window"] = "Ventana de la pila de ejecución", -- src\editor\debugger.lua
|
||||
["Stack"] = nil, -- src\editor\debugger.lua
|
||||
["Start &Debugging"] = "Comenzar depuración", -- src\editor\menu_project.lua
|
||||
["Start debugging"] = "Comenzar depuración", -- src\editor\menu_project.lua, src\editor\gui.lua
|
||||
["Step &Into"] = "Paso dentro", -- src\editor\menu_project.lua
|
||||
@@ -177,7 +187,9 @@ return {
|
||||
["Unable to load file '%s'."] = "No se pudo cargar el archivo '%s'.", -- src\editor\commands.lua
|
||||
["Unable to save file '%s': %s"] = "No se pudo guardar el archivo '%s': %s", -- src\editor\commands.lua
|
||||
["Unable to stop program (pid: %d), code %d."] = "No se puedo parar el programa (pid: %d), código %d.", -- src\editor\debugger.lua
|
||||
["Undo last edit"] = "Deshacer la última edición", -- src\editor\menu_edit.lua, src\editor\gui.lua
|
||||
["Undo last edit"] = "Deshacer la última edición", -- src\editor\menu_edit.lua
|
||||
["Use '%s' to see full description."] = nil, -- src\editor\editor.lua
|
||||
["Use '%s' to show line endings and '%s' to convert them."] = nil, -- src\editor\commands.lua
|
||||
["Use 'clear' to clear the shell output and the history."] = "Usa 'clear' para limpiar la consola de salida y el historial.", -- src\editor\shellbox.lua
|
||||
["Use Shift-Enter for multiline code."] = "Usa <Shift-Enter> para código multilínea.", -- src\editor\shellbox.lua
|
||||
["Value"] = "Valor", -- src\editor\debugger.lua
|
||||
@@ -185,7 +197,7 @@ return {
|
||||
["View the project/filetree window"] = "Ver la ventana de proyecto/árbol de archivos", -- src\editor\menu_view.lua
|
||||
["View the stack window"] = "Ver la ventana de la pila de ejecución", -- src\editor\menu_view.lua, src\editor\gui.lua
|
||||
["View the watch window"] = "Ver la ventana de observación", -- src\editor\menu_view.lua, src\editor\gui.lua
|
||||
["Watch Window"] = "Ventana de observación", -- src\editor\debugger.lua
|
||||
["Watch"] = nil, -- src\editor\debugger.lua
|
||||
["Welcome to the interactive Lua interpreter."] = "Bienvenido al intérprete interactico de Lua.", -- src\editor\shellbox.lua
|
||||
["You must save the program first."] = "Debes guardar el programa primero", -- src\editor\commands.lua
|
||||
["on line %d"] = "en la línea %d", -- src\editor\debugger.lua, src\editor\commands.lua
|
||||
|
||||
@@ -7,6 +7,7 @@ return {
|
||||
["&Compile"] = "&Compiler", -- src\editor\menu_project.lua
|
||||
["&Copy"] = "Co&pier", -- src\editor\editor.lua, src\editor\menu_edit.lua
|
||||
["&Default Layout"] = "Affichage par &défaut", -- src\editor\menu_view.lua
|
||||
["&Delete Watch"] = "&Supprimer une expression", -- src\editor\debugger.lua
|
||||
["&Edit Watch"] = "&Modifier une expression", -- src\editor\debugger.lua
|
||||
["&Edit"] = "É&dition", -- src\editor\menu_edit.lua
|
||||
["&File"] = "&Fichier", -- src\editor\menu_file.lua
|
||||
@@ -20,7 +21,6 @@ return {
|
||||
["&Paste"] = "Co&ller", -- src\editor\editor.lua, src\editor\menu_edit.lua
|
||||
["&Project"] = "&Projet", -- src\editor\menu_project.lua, src\editor\inspect.lua
|
||||
["&Redo"] = "&Rétablir", -- src\editor\editor.lua, src\editor\menu_edit.lua
|
||||
["&Remove Watch"] = "&Supprimer une expression", -- src\editor\debugger.lua
|
||||
["&Replace"] = "Re&mplacer...", -- src\editor\menu_search.lua
|
||||
["&Run"] = "&Exécuter", -- src\editor\menu_project.lua
|
||||
["&Save"] = "&Enregistrer", -- src\editor\menu_file.lua, src\editor\gui.lua
|
||||
@@ -31,8 +31,7 @@ return {
|
||||
["&Undo"] = "&Annuler", -- src\editor\editor.lua, src\editor\menu_edit.lua
|
||||
["&View"] = "&Affichage", -- src\editor\menu_view.lua
|
||||
["&Watch Window"] = "&Expressions espionnes", -- src\editor\menu_view.lua
|
||||
["&Watches"] = "&Expressions", -- src\editor\debugger.lua
|
||||
["About ZeroBrane Studio"] = "À propos de ZeroBrane Studio", -- src\editor\menu_help.lua
|
||||
["About %s"] = "À propos de %s", -- src\editor\menu_help.lua
|
||||
["Add Watch Expression"] = "Ajouter une expression", -- src\editor\editor.lua
|
||||
["Add to Scratchpad"] = "Ajouter au brouillon", -- src\editor\editor.lua
|
||||
["All files"] = "Tous les fichiers", -- src\editor\commands.lua
|
||||
@@ -60,16 +59,16 @@ return {
|
||||
["Co&ntinue"] = "Co&ntinuer", -- src\editor\menu_project.lua
|
||||
["Col: %d"] = "Col : %d", -- src\editor\editor.lua
|
||||
["Comment or uncomment current or selected lines"] = "Commenter ou décommenter les lignes courantes ou sélectionnées", -- src\editor\menu_edit.lua
|
||||
["Compilation error"] = "Erreur de commpilation", -- src\editor\debugger.lua, src\editor\commands.lua
|
||||
["Compilation error"] = "Erreur de compilation", -- src\editor\debugger.lua, src\editor\commands.lua
|
||||
["Compilation successful; %.0f%% success rate (%d/%d)."] = "Compilation réussie ; taux de succès : %.0f%% (%d/%d).", -- src\editor\commands.lua
|
||||
["Compile the current file"] = "Сompiler le fichier courant", -- src\editor\menu_project.lua
|
||||
["Complete &Identifier"] = "Compléter l'&identifiant", -- src\editor\menu_edit.lua
|
||||
["Complete the current identifier"] = "Compléter l'identifiant courant", -- src\editor\menu_edit.lua
|
||||
["Copy selected text to clipboard"] = "Copier le texte sélectionné dans le presse-papiers", -- src\editor\menu_edit.lua, src\editor\gui.lua
|
||||
["Copy selected text to clipboard"] = "Copier le texte sélectionné dans le presse-papiers", -- src\editor\menu_edit.lua
|
||||
["Couldn't activate file '%s' for debugging; continuing without it."] = "Impossible d'activer le fichier '%s' pour débogage ; poursuite du processus en ignorant le fichier.", -- src\editor\debugger.lua
|
||||
["Create an empty document"] = "Créer un document vierge", -- src\editor\menu_file.lua, src\editor\gui.lua
|
||||
["Cu&t"] = "&Couper", -- src\editor\editor.lua, src\editor\menu_edit.lua
|
||||
["Cut selected text to clipboard"] = "Couper le texte selectionné et copier dans le presse-papiers", -- src\editor\menu_edit.lua, src\editor\gui.lua
|
||||
["Cut selected text to clipboard"] = "Couper le texte sélectionné et copier dans le presse-papiers", -- src\editor\menu_edit.lua
|
||||
["Debugger server started at %s:%d."] = "Serveur de débogage démarré à %s:%d.", -- src\editor\debugger.lua
|
||||
["Debugging session completed (%s)."] = "Session de débogage terminée (%s).", -- src\editor\debugger.lua
|
||||
["Debugging session started in '%s'."] = "Session de débogage démarrée dans '%s'.", -- src\editor\debugger.lua
|
||||
@@ -84,8 +83,7 @@ return {
|
||||
["Error while processing API file: %s"] = "Erreur lors de la lecture du fichier d'API : %s", -- src\editor\autocomplete.lua
|
||||
["Error while processing configuration file: %s"] = "Erreur lors de la lecture du fichier de configuration : %s", -- src\editor\style.lua
|
||||
["Error"] = "Erreur", -- src\editor\commands.lua
|
||||
["Evaluate &Watches"] = "&Evaluer les expressions", -- src\editor\debugger.lua
|
||||
["Evaluate in Console"] = "Evaluer dans la console", -- src\editor\editor.lua
|
||||
["Evaluate in Console"] = "Évaluer dans la console", -- src\editor\editor.lua
|
||||
["Execute the current project/file and keep updating the code to see immediate results"] = "Exécuter le projet/fichier courant en mettant le code à jour afin de voir les résultats en temps réel", -- src\editor\menu_project.lua
|
||||
["Execute the current project/file"] = "Exécuter le projet/fichier courant", -- src\editor\menu_project.lua
|
||||
["Execution error"] = "Erreur d'exécution", -- src\editor\debugger.lua
|
||||
@@ -97,14 +95,14 @@ return {
|
||||
["File '%s' no longer exists."] = "Le fichier '%s' n'existe plus.", -- src\editor\editor.lua
|
||||
["File history"] = "Historique de fichier", -- src\editor\menu_file.lua
|
||||
["Find &In Files"] = "Rec&hercher dans les fichiers...", -- src\editor\menu_search.lua
|
||||
["Find &Next"] = "Rechercher l'occurence &suivante", -- src\editor\menu_search.lua
|
||||
["Find &Previous"] = "Rechercher l'occurence &précédente", -- src\editor\menu_search.lua
|
||||
["Find &Next"] = "Rechercher l'occurrence &suivante", -- src\editor\menu_search.lua
|
||||
["Find &Previous"] = "Rechercher l'occurrence &précédente", -- src\editor\menu_search.lua
|
||||
["Find and replace text in files"] = "Rechercher et remplacer le texte dans les fichiers", -- src\editor\menu_search.lua
|
||||
["Find and replace text"] = "Rechercher et remplacer le texte", -- src\editor\menu_search.lua, src\editor\gui.lua
|
||||
["Find text in files"] = "Rechercher le texte dans les fichiers", -- src\editor\menu_search.lua
|
||||
["Find text"] = "Rechercher le texte", -- src\editor\menu_search.lua, src\editor\gui.lua
|
||||
["Find the earlier text occurence"] = "Recherche l'occurence précédente du texte", -- src\editor\menu_search.lua
|
||||
["Find the next text occurrence"] = "Recherche l'occurence suivante du texte", -- src\editor\menu_search.lua
|
||||
["Find the earlier text occurence"] = "Recherche l'occurrence précédente du texte", -- src\editor\menu_search.lua
|
||||
["Find the next text occurrence"] = "Recherche l'occurrence suivante du texte", -- src\editor\menu_search.lua
|
||||
["Fold or unfold all code folds"] = "Replier ou déplier tous les blocs de code", -- src\editor\menu_edit.lua
|
||||
["Found auto-recovery record and restored saved session."] = "Une récupération automatique a été trouvé et la session a été restaurée.", -- src\editor\commands.lua
|
||||
["Full &Screen"] = "&Plein écran", -- src\editor\menu_view.lua
|
||||
@@ -116,12 +114,14 @@ return {
|
||||
["Ln: %d"] = "Lig : %d", -- src\editor\editor.lua
|
||||
["Local console"] = "Console locale", -- src\editor\shellbox.lua, src\editor\gui.lua
|
||||
["Lua &Interpreter"] = "Interpréteur L&ua", -- src\editor\menu_project.lua
|
||||
["Mapped remote request for '%s' to '%s'."] = "La requête distante pour '%s' a été associée à '%s'.", -- src\editor\debugger.lua
|
||||
["Mixed end-of-line encodings detected."] = "Plusieurs codages de fin de ligne détectés.", -- src\editor\commands.lua
|
||||
["OVR"] = "OVR", -- src\editor\editor.lua
|
||||
["Open an existing document"] = "Ouvrir un document existant", -- src\editor\menu_file.lua, src\editor\gui.lua
|
||||
["Open file"] = "Ouvrir un fichier", -- src\editor\commands.lua
|
||||
["Output (running)"] = "Sortie (en cours d'exécution)", -- src\editor\output.lua
|
||||
["Output"] = "Sortie", -- src\editor\output.lua, src\editor\settings.lua, src\editor\gui.lua
|
||||
["Paste text from the clipboard"] = "Coller le texte depuis le presse-papiers", -- src\editor\menu_edit.lua, src\editor\gui.lua
|
||||
["Paste text from the clipboard"] = "Coller le texte depuis le presse-papiers", -- src\editor\menu_edit.lua
|
||||
["Prepend '=' to show complex values on multiple lines."] = "Préfixez par '=' pour afficher les valeurs complexes sur plusieurs lignes.", -- src\editor\shellbox.lua
|
||||
["Press cancel to abort."] = "Cliquez sur Annuler pour annuler.", -- src\editor\commands.lua
|
||||
["Program '%s' started in '%s' (pid: %d)."] = "Programme '%s' démarré dans '%s' (pid : %d).", -- src\editor\output.lua
|
||||
@@ -137,9 +137,10 @@ return {
|
||||
["R/W"] = "R/W", -- src\editor\editor.lua
|
||||
["Re&place In Files"] = "Remp&lacer dans les fichiers...", -- src\editor\menu_search.lua
|
||||
["Recent Files"] = "Fichiers récents", -- src\editor\menu_file.lua
|
||||
["Redo last edit undone"] = "Rétablir la dernière modification", -- src\editor\menu_edit.lua, src\editor\gui.lua
|
||||
["Redo last edit undone"] = "Rétablir la dernière modification", -- src\editor\menu_edit.lua
|
||||
["Refused a request to start a new debugging session as there is one in progress already."] = "Une requête de lancement de débogage a été refusée car une session de débogage est déjà en cours.", -- src\editor\debugger.lua
|
||||
["Remote console"] = "Console à distance", -- src\editor\shellbox.lua
|
||||
["Replaced an invalid UTF8 character with %s."] = "Un caractère UTF8 invalide a été remplacé par %s.", -- src\editor\commands.lua
|
||||
["Reset to default layout"] = "Restaurer l'affichage par défaut", -- src\editor\menu_view.lua
|
||||
["Resets the dynamic word list for autocompletion"] = "Réinitialiser la liste des mots dynamiques pour l'auto-complétion", -- src\editor\menu_edit.lua
|
||||
["Run as Scratchpad"] = "Exécuter comme brouillon", -- src\editor\menu_project.lua
|
||||
@@ -164,7 +165,7 @@ return {
|
||||
["Show &Tooltip"] = "Afficher l'info-&bulle", -- src\editor\menu_edit.lua
|
||||
["Show tooltip for current position; place cursor after opening bracket of function"] = "Afficher l'info-bulle pour la position actuelle ; placez le curseur après la parenthèse ouvrante de la fonction", -- src\editor\menu_edit.lua
|
||||
["Sort selected lines"] = "Trier les lignes sélectionnées", -- src\editor\menu_search.lua
|
||||
["Stack Window"] = "Fenêtre de pile d'éxécution", -- src\editor\debugger.lua
|
||||
["Stack"] = "Pile d'exécution", -- src\editor\debugger.lua
|
||||
["Start &Debugging"] = "Lancer le &débogage", -- src\editor\menu_project.lua
|
||||
["Start debugging"] = "Lancer le débogage", -- src\editor\menu_project.lua, src\editor\gui.lua
|
||||
["Step &Into"] = "Pas à pas détai&llé", -- src\editor\menu_project.lua
|
||||
@@ -183,16 +184,17 @@ return {
|
||||
["Unable to load file '%s'."] = "Impossible de charger le le fichier '%s'.", -- src\editor\commands.lua
|
||||
["Unable to save file '%s': %s"] = "Impossible d'enregistrer le fichier '%s' : %s", -- src\editor\commands.lua
|
||||
["Unable to stop program (pid: %d), code %d."] = "Impossible d'arrêter le programme (pid : %d), code %d.", -- src\editor\debugger.lua
|
||||
["Undo last edit"] = "Annuler la dernière modification", -- src\editor\menu_edit.lua, src\editor\gui.lua
|
||||
["Undo last edit"] = "Annuler la dernière modification", -- src\editor\menu_edit.lua
|
||||
["Use '%s' to see full description."] = "Utilisez '%s' pour voir la description complète.", -- src\editor\editor.lua
|
||||
["Use '%s' to show line endings and '%s' to convert them."] = "Utilisez '%s' pour afficher les fins de ligne et '%s' pour les convertir.", -- src\editor\commands.lua
|
||||
["Use 'clear' to clear the shell output and the history."] = "Utilisez 'clear' pour effacer la sortie console et l´historique.", -- src\editor\shellbox.lua
|
||||
["Use Shift-Enter for multiline code."] = "Appuyez sur <Shift-Entrée> pour du code multiligne.", -- src\editor\shellbox.lua
|
||||
["Value"] = "Valeur", -- src\editor\debugger.lua
|
||||
["View the output/console window"] = "Afficher la fenêtre de sortie/console", -- src\editor\menu_view.lua
|
||||
["View the project/filetree window"] = "Afficher la fenêtre d'explorateur de projet", -- src\editor\menu_view.lua
|
||||
["View the stack window"] = "Afficher la fenêtre de pile d'éxécution", -- src\editor\menu_view.lua, src\editor\gui.lua
|
||||
["View the stack window"] = "Afficher la fenêtre de pile d'exécution", -- src\editor\menu_view.lua, src\editor\gui.lua
|
||||
["View the watch window"] = "Afficher la fenêtre d'expressions espionnes", -- src\editor\menu_view.lua, src\editor\gui.lua
|
||||
["Watch Window"] = "Fenêtre d'expressions espionnes", -- src\editor\debugger.lua
|
||||
["Watch"] = "Expressions espionnes", -- src\editor\debugger.lua
|
||||
["Welcome to the interactive Lua interpreter."] = "Bienvenue dans l´interpréteur interactif Lua.", -- src\editor\shellbox.lua
|
||||
["You must save the program first."] = "Vous devez d'abord enregistrer le programme.", -- src\editor\commands.lua
|
||||
["on line %d"] = "à la ligne %d", -- src\editor\debugger.lua, src\editor\commands.lua
|
||||
|
||||
@@ -3,10 +3,11 @@ return {
|
||||
["&About"] = "Informazioni", -- src\editor\menu_help.lua
|
||||
["&Add Watch"] = "&Aggiungi Espressione di Controllo", -- src\editor\debugger.lua
|
||||
["&Break"] = "Interrompi", -- src\editor\menu_project.lua
|
||||
["&Close Page"] = "&Chiudi pagina", -- src\editor\menu_file.lua
|
||||
["&Close Page"] = "&Chiudi pagina", -- src\editor\menu_file.lua, src\editor\gui.lua
|
||||
["&Compile"] = "&Compila", -- src\editor\menu_project.lua
|
||||
["&Copy"] = "&Copia", -- src\editor\editor.lua, src\editor\menu_edit.lua
|
||||
["&Default Layout"] = "Visualizzazione di &Default", -- src\editor\menu_view.lua
|
||||
["&Delete Watch"] = "Elimina Espressione di Controllo", -- src\editor\debugger.lua
|
||||
["&Edit Watch"] = "Modifica Espressione di Controllo", -- src\editor\debugger.lua
|
||||
["&Edit"] = "Modifica", -- src\editor\menu_edit.lua
|
||||
["&File"] = "File", -- src\editor\menu_file.lua
|
||||
@@ -20,10 +21,9 @@ return {
|
||||
["&Paste"] = "Incolla", -- src\editor\editor.lua, src\editor\menu_edit.lua
|
||||
["&Project"] = "&Progetto", -- src\editor\menu_project.lua, src\editor\inspect.lua
|
||||
["&Redo"] = "&Ripeti", -- src\editor\editor.lua, src\editor\menu_edit.lua
|
||||
["&Remove Watch"] = "Elimina Espressione di Controllo", -- src\editor\debugger.lua
|
||||
["&Replace"] = "Sostituisci", -- src\editor\menu_search.lua
|
||||
["&Run"] = "Lancia", -- src\editor\menu_project.lua
|
||||
["&Save"] = "&Salva", -- src\editor\menu_file.lua
|
||||
["&Save"] = "&Salva", -- src\editor\menu_file.lua, src\editor\gui.lua
|
||||
["&Search"] = "Ricerca", -- src\editor\menu_search.lua
|
||||
["&Sort"] = "Ordina", -- src\editor\menu_search.lua
|
||||
["&Stack Window"] = "Stack di chiamate", -- src\editor\menu_view.lua
|
||||
@@ -31,8 +31,7 @@ return {
|
||||
["&Undo"] = "Annulla", -- src\editor\editor.lua, src\editor\menu_edit.lua
|
||||
["&View"] = "Visualizza", -- src\editor\menu_view.lua
|
||||
["&Watch Window"] = "Finestra Espressioni di Controllo", -- src\editor\menu_view.lua
|
||||
["&Watches"] = "Espressioni di Controllo", -- src\editor\debugger.lua
|
||||
["About ZeroBrane Studio"] = "Informazioni su ZeroBrane Studio", -- src\editor\menu_help.lua
|
||||
["About %s"] = "Informazioni su %s", -- src\editor\menu_help.lua
|
||||
["Add Watch Expression"] = "Aggiungi Espressione di Controllo", -- src\editor\editor.lua
|
||||
["Add to Scratchpad"] = "Aggiungi a Scratchpad ", -- src\editor\editor.lua
|
||||
["All files"] = "Tutti i files", -- src\editor\commands.lua
|
||||
@@ -50,9 +49,12 @@ return {
|
||||
["Can't run the entry point script ('%s')."] = "Impossibile eseguire il punto di ingresos dello script (%s).", -- src\editor\debugger.lua
|
||||
["Can't start debugging session due to internal error '%s'."] = "Impossibile lanciare la sessione di debug: errore interno '%s'.'", -- src\editor\debugger.lua
|
||||
["Can't start debugging without an opened file or with the current file not being saved ('%s')."] = "Impossibile lanciare il debug senza aver aperto un file o se il file corrente non è stato salvato ('%s').", -- src\editor\debugger.lua
|
||||
["Choose ..."] = "Scegli...", -- src\editor\menu_project.lua
|
||||
["Choose a project directory"] = "Scegli la directory di un progetto", -- src\editor\menu_project.lua
|
||||
["Clear &Dynamic Words"] = "Elimna le &Dynamic Words", -- src\editor\menu_edit.lua
|
||||
["Clear the output window before compiling or debugging"] = "Pulisci la finestra di output prima di compilare o lanciare debug", -- src\editor\menu_project.lua
|
||||
["Close &Other Pages"] = "Chidi le Altre Pagine", -- src\editor\gui.lua
|
||||
["Close A&ll Pages"] = "Chiudi Tutte le Pagine", -- src\editor\gui.lua
|
||||
["Close the current editor window"] = "Chiude la finestra dell'edit corrente", -- src\editor\menu_file.lua
|
||||
["Co&ntinue"] = "Co&ntinua", -- src\editor\menu_project.lua
|
||||
["Col: %d"] = "Col: %d", -- src\editor\editor.lua
|
||||
@@ -62,23 +64,25 @@ return {
|
||||
["Compile the current file"] = "Compila il file corrente", -- src\editor\menu_project.lua
|
||||
["Complete &Identifier"] = "Completa l'&Identificatore", -- src\editor\menu_edit.lua
|
||||
["Complete the current identifier"] = "Completa l'identificatore corrente", -- src\editor\menu_edit.lua
|
||||
["Copy selected text to clipboard"] = "Copia il testo selezionato negli appunti", -- src\editor\menu_edit.lua, src\editor\gui.lua
|
||||
["Copy selected text to clipboard"] = "Copia il testo selezionato negli appunti", -- src\editor\menu_edit.lua
|
||||
["Couldn't activate file '%s' for debugging; continuing without it."] = "Impossibile attivare il file '%s' per debug; si prosegue senza.", -- src\editor\debugger.lua
|
||||
["Create an empty document"] = "Crea un documento vuoto", -- src\editor\menu_file.lua, src\editor\gui.lua
|
||||
["Cu&t"] = "&Taglia", -- src\editor\editor.lua, src\editor\menu_edit.lua
|
||||
["Cut selected text to clipboard"] = "Taglia il testo selezionato e mette negli appunti", -- src\editor\menu_edit.lua, src\editor\gui.lua
|
||||
["Cut selected text to clipboard"] = "Taglia il testo selezionato e mette negli appunti", -- src\editor\menu_edit.lua
|
||||
["Debugger server started at %s:%d."] = "Server Debugger iniziato %s:%s", -- src\editor\debugger.lua
|
||||
["Debugging session completed (%s)."] = "Sessione di debug completata (%s).", -- src\editor\debugger.lua
|
||||
["Debugging session started in '%s'."] = "Sessione di debug iniziata da '%s'.", -- src\editor\debugger.lua
|
||||
["Debugging suspended at %s:%s (couldn't activate the file)."] = "Debug sospeso a %s:%s (impossibile attivare il file).", -- src\editor\debugger.lua
|
||||
["Do you want to reload it?"] = "Vuoi ricaricarlo?", -- src\editor\editor.lua
|
||||
["Do you want to save the changes to '%s'?"] = "Vuoi salvare le modifiche a '%s'?", -- src\editor\commands.lua
|
||||
["E&xit"] = "Uscita", -- src\editor\menu_file.lua
|
||||
["Enter Lua code and press Enter to run it."] = "Inserisci codice Lua e premi <Enter> per eseguirlo.", -- src\editor\shellbox.lua
|
||||
["Enter line number"] = "Inserisci il numero di linea", -- src\editor\menu_search.lua
|
||||
["Error while loading API file: %s"] = "Errore durante il caricamento del file API: %s", -- src\editor\autocomplete.lua
|
||||
["Error while loading configuration file: %s"] = "Errore nel caricamento del file di configurazione: %s", -- src\editor\style.lua
|
||||
["Error while processing API file: %s"] = "Errore durante l'elaborazione del file API: %s", -- src\editor\autocomplete.lua
|
||||
["Error while processing configuration file: %s"] = "Errore durante l'elaborazione del file di configurazione: %s", -- src\editor\style.lua
|
||||
["Error"] = "Errore", -- src\editor\commands.lua
|
||||
["Evaluate &Watches"] = "Elabora Espressioni di Controllo", -- src\editor\debugger.lua
|
||||
["Evaluate in Console"] = "Elabora in console", -- src\editor\editor.lua
|
||||
["Execute the current project/file and keep updating the code to see immediate results"] = "Esegue il progetto/file corrente e permette di modificare il codice per vedere i risultati in tempo reale", -- src\editor\menu_project.lua
|
||||
["Execute the current project/file"] = "Esegue il progetto/file corrente", -- src\editor\menu_project.lua
|
||||
@@ -110,12 +114,14 @@ return {
|
||||
["Ln: %d"] = "Ln: %d", -- src\editor\editor.lua
|
||||
["Local console"] = "Console locale", -- src\editor\shellbox.lua, src\editor\gui.lua
|
||||
["Lua &Interpreter"] = "&Interprete Lua", -- src\editor\menu_project.lua
|
||||
["Mapped remote request for '%s' to '%s'."] = "Richiesta remota '%s' mappata su '%s'.", -- src\editor\debugger.lua
|
||||
["Mixed end-of-line encodings detected."] = "Trovata codifica Fine-Riga mista.", -- src\editor\commands.lua
|
||||
["OVR"] = "OVR", -- src\editor\editor.lua
|
||||
["Open an existing document"] = "Apri un documento esistente", -- src\editor\menu_file.lua, src\editor\gui.lua
|
||||
["Open file"] = "Apri un file", -- src\editor\commands.lua
|
||||
["Output (running)"] = "Output (in corso d'esecuzione)", -- src\editor\output.lua
|
||||
["Output"] = "Output", -- src\editor\output.lua, src\editor\settings.lua, src\editor\gui.lua
|
||||
["Paste text from the clipboard"] = "Incolla testo dagli appunti", -- src\editor\menu_edit.lua, src\editor\gui.lua
|
||||
["Paste text from the clipboard"] = "Incolla testo dagli appunti", -- src\editor\menu_edit.lua
|
||||
["Prepend '=' to show complex values on multiple lines."] = "Prefissa '=' per visualizzare valori complessi su piu` righe", -- src\editor\shellbox.lua
|
||||
["Press cancel to abort."] = "Premi cancel per bloccare.", -- src\editor\commands.lua
|
||||
["Program '%s' started in '%s' (pid: %d)."] = "Programma '%s' partito da '%s' (pid: %d).", -- src\editor\output.lua
|
||||
@@ -124,21 +130,23 @@ return {
|
||||
["Program starting as '%s'."] = "Programma partito da '%s'.", -- src\editor\output.lua
|
||||
["Program stopped (pid: %d)."] = "Programma fermato (pid: %d).", -- src\editor\debugger.lua
|
||||
["Program unable to run as '%s'."] = "Il programma non puo' partire '%s'.", -- src\editor\output.lua
|
||||
["Project Directory"] = "Directory del Progetto", -- src\editor\menu_project.lua
|
||||
["Project"] = "Progetto", -- src\editor\settings.lua, src\editor\gui.lua
|
||||
["Project/&FileTree Window"] = "Progetto/Explorer", -- src\editor\menu_view.lua
|
||||
["R/O"] = "R/O", -- src\editor\editor.lua
|
||||
["R/W"] = "R/W", -- src\editor\editor.lua
|
||||
["Re&place In Files"] = "Sostituisci nei files", -- src\editor\menu_search.lua
|
||||
["Recent Files"] = "Files recenti", -- src\editor\menu_file.lua
|
||||
["Redo last edit undone"] = "Ripeti l'ultima azione annullata", -- src\editor\menu_edit.lua, src\editor\gui.lua
|
||||
["Redo last edit undone"] = "Ripeti l'ultima azione annullata", -- src\editor\menu_edit.lua
|
||||
["Refused a request to start a new debugging session as there is one in progress already."] = "Impossibile aprire una nuova sessione di debug in quanto ne esiste una in corso", -- src\editor\debugger.lua
|
||||
["Remote console"] = "Console remota", -- src\editor\shellbox.lua
|
||||
["Replaced an invalid UTF8 character with %s."] = "Sostituito un carattere UTF8 invalido con %s.", -- src\editor\commands.lua
|
||||
["Reset to default layout"] = "Ritorna al default layout", -- src\editor\menu_view.lua
|
||||
["Resets the dynamic word list for autocompletion"] = "Azzera la lista di dynamic words per l'autocompletamento", -- src\editor\menu_edit.lua
|
||||
["Run as Scratchpad"] = "Esegui in Scratchpad (Live coding)", -- src\editor\menu_project.lua
|
||||
["S&top Debugging"] = "Ferma il debugger", -- src\editor\menu_project.lua
|
||||
["S&top Process"] = "Ferma il processo", -- src\editor\menu_project.lua
|
||||
["Save &As..."] = "S&alva con nome...", -- src\editor\menu_file.lua
|
||||
["Save &As..."] = "S&alva con nome...", -- src\editor\menu_file.lua, src\editor\gui.lua
|
||||
["Save A&ll"] = "Sa&lva tutto", -- src\editor\menu_file.lua
|
||||
["Save Changes?"] = "Vuoi salvare le modifiche?", -- src\editor\commands.lua
|
||||
["Save all open documents"] = "Salva tutti i documenti aperti", -- src\editor\menu_file.lua, src\editor\gui.lua
|
||||
@@ -150,12 +158,14 @@ return {
|
||||
["Scratchpad error"] = "Errore durente Scratchpad", -- src\editor\debugger.lua
|
||||
["Select &All"] = "Selezion&a Tutto", -- src\editor\editor.lua, src\editor\menu_edit.lua
|
||||
["Select all text in the editor"] = "Seleziona tutto il testo nell'editor", -- src\editor\menu_edit.lua
|
||||
["Set project directory from current file"] = "Definisci la directory del progeetto dal file corrente", -- src\editor\gui.lua
|
||||
["Set From Current File"] = "Impostato da file corrente", -- src\editor\menu_project.lua
|
||||
["Set project directory from current file"] = "Definisci la directory del progeetto dal file corrente", -- src\editor\menu_project.lua, src\editor\gui.lua
|
||||
["Set the interpreter to be used"] = "Definisci l'interprete da utilizzare", -- src\editor\menu_project.lua
|
||||
["Set the project directory to be used"] = "Imposta la directory di progetto da usare", -- src\editor\menu_project.lua
|
||||
["Show &Tooltip"] = "Mos&tra i consgli", -- src\editor\menu_edit.lua
|
||||
["Show tooltip for current position; place cursor after opening bracket of function"] = "Mostra i consigli per la posizione corrente; muovi il cursore dopo la parentesi o la funzione", -- src\editor\menu_edit.lua
|
||||
["Sort selected lines"] = "Ordina le righe selezionate", -- src\editor\menu_search.lua
|
||||
["Stack Window"] = "Finestra Stack", -- src\editor\debugger.lua
|
||||
["Stack"] = "Stack", -- src\editor\debugger.lua
|
||||
["Start &Debugging"] = "Inizia il &Debug", -- src\editor\menu_project.lua
|
||||
["Start debugging"] = "Inizia il Debug", -- src\editor\menu_project.lua, src\editor\gui.lua
|
||||
["Step &Into"] = "Step &Into", -- src\editor\menu_project.lua
|
||||
@@ -174,7 +184,9 @@ return {
|
||||
["Unable to load file '%s'."] = "Impossibile aprire il file '%s'.", -- src\editor\commands.lua
|
||||
["Unable to save file '%s': %s"] = "Impossibile salvare il file '%s': %s", -- src\editor\commands.lua
|
||||
["Unable to stop program (pid: %d), code %d."] = "Impossibile fermare il programma (pid: %d), code %d.", -- src\editor\debugger.lua
|
||||
["Undo last edit"] = "Annulla l'ultima azione di edit", -- src\editor\menu_edit.lua, src\editor\gui.lua
|
||||
["Undo last edit"] = "Annulla l'ultima azione di edit", -- src\editor\menu_edit.lua
|
||||
["Use '%s' to see full description."] = "Utilizza '%s' per vedere la descrizione completa.", -- src\editor\editor.lua
|
||||
["Use '%s' to show line endings and '%s' to convert them."] = "Utilizza '%s' per vedere la fine della riga e '%s' per convertirli.", -- src\editor\commands.lua
|
||||
["Use 'clear' to clear the shell output and the history."] = "Utilizza 'clear' per pulire l`output e lo storico.", -- src\editor\shellbox.lua
|
||||
["Use Shift-Enter for multiline code."] = "Premi <Shift-Invio> per inserire piu` righe di codice.", -- src\editor\shellbox.lua
|
||||
["Value"] = "Valore", -- src\editor\debugger.lua
|
||||
@@ -182,9 +194,9 @@ return {
|
||||
["View the project/filetree window"] = "Mostra la finestra di progetto/explorer", -- src\editor\menu_view.lua
|
||||
["View the stack window"] = "Mostra la finestra dello Stack", -- src\editor\menu_view.lua, src\editor\gui.lua
|
||||
["View the watch window"] = "Mostra la finestra delle Espressioni di Controllo", -- src\editor\menu_view.lua, src\editor\gui.lua
|
||||
["Watch Window"] = "Finestra Espressioni di Controllo", -- src\editor\debugger.lua
|
||||
["Watch"] = "Watch", -- src\editor\debugger.lua
|
||||
["Welcome to the interactive Lua interpreter."] = "Benvenuti nell`interprete interattivo Lua.", -- src\editor\shellbox.lua
|
||||
["You must save the program first."] = "Devi prima salvare il programma", -- src\editor\commands.lua
|
||||
["on line %d"] = "alla linea %d", -- src\editor\debugger.lua, src\editor\commands.lua
|
||||
["traced %d instruction"] = {"tracciata %d istruzione", "%d istruzioni tracciate"} -- src\editor\debugger.lua
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
return {
|
||||
[0] = function(c) return (c%10 == 1 and c%100 ~= 11) and 1 or (c%10 >= 2 and c%10 <= 4 and (c%100 < 10 or c%100 >= 20) and 2) or 3 end, -- plural
|
||||
[0] = function(c) c = (c-9)%100 < 9 and 9 or (c-1)%10 return c == 0 and 1 or c < 4 and 2 or 3 end, -- plural
|
||||
["%d instance"] = {"%d совпадение", "%d совпадения", "%d совпадений"}, -- src\editor\findreplace.lua
|
||||
["&About"] = "&О программе", -- src\editor\menu_help.lua
|
||||
["&Add Watch"] = "&Добавить выражение", -- src\editor\debugger.lua
|
||||
["&Break"] = "Пр&ервать", -- src\editor\menu_project.lua
|
||||
@@ -7,9 +8,13 @@ return {
|
||||
["&Compile"] = "&Компилировать", -- src\editor\menu_project.lua
|
||||
["&Copy"] = "&Копировать", -- src\editor\editor.lua, src\editor\menu_edit.lua
|
||||
["&Default Layout"] = "Вид по &умолчанию", -- src\editor\menu_view.lua
|
||||
["&Delete Watch"] = "&Удалить выражение", -- src\editor\debugger.lua
|
||||
["&Down"] = "Вниз", -- src\editor\findreplace.lua
|
||||
["&Edit Watch"] = "&Редактировать выражение", -- src\editor\debugger.lua
|
||||
["&Edit"] = "&Правка", -- src\editor\menu_edit.lua
|
||||
["&File"] = "&Файл", -- src\editor\menu_file.lua
|
||||
["&Find All"] = "Найти все", -- src\editor\findreplace.lua
|
||||
["&Find Next"] = "Найти далее", -- src\editor\findreplace.lua
|
||||
["&Find"] = "&Найти", -- src\editor\menu_search.lua
|
||||
["&Fold/Unfold All"] = "Св&ернуть/развернуть все", -- src\editor\menu_edit.lua
|
||||
["&Goto Line"] = "&Перейти к строке", -- src\editor\menu_search.lua
|
||||
@@ -20,20 +25,22 @@ return {
|
||||
["&Paste"] = "В&ставить", -- src\editor\editor.lua, src\editor\menu_edit.lua
|
||||
["&Project"] = "Пр&оект", -- src\editor\menu_project.lua, src\editor\inspect.lua
|
||||
["&Redo"] = "Верну&ть", -- src\editor\editor.lua, src\editor\menu_edit.lua
|
||||
["&Remove Watch"] = "&Удалить выражение", -- src\editor\debugger.lua
|
||||
["&Replace"] = "За&менить", -- src\editor\menu_search.lua
|
||||
["&Replace All"] = "Заменить всe", -- src\editor\findreplace.lua
|
||||
["&Replace"] = "За&менить", -- src\editor\findreplace.lua, src\editor\menu_search.lua
|
||||
["&Run"] = "За&пустить", -- src\editor\menu_project.lua
|
||||
["&Save"] = "&Сохранить", -- src\editor\menu_file.lua, src\editor\gui.lua
|
||||
["&Search"] = "По&иск", -- src\editor\menu_search.lua
|
||||
["&Sort"] = "&Cортировать", -- src\editor\menu_search.lua
|
||||
["&Stack Window"] = "Окно &стека", -- src\editor\menu_view.lua
|
||||
["&Start Debugger Server"] = "Запустить сервер отла&дки", -- src\editor\menu_project.lua
|
||||
["&Subdirectories"] = "В папках", -- src\editor\findreplace.lua
|
||||
["&Undo"] = "&Отменить", -- src\editor\editor.lua, src\editor\menu_edit.lua
|
||||
["&Up"] = "Вверх", -- src\editor\findreplace.lua
|
||||
["&View"] = "&Вид", -- src\editor\menu_view.lua
|
||||
["&Watch Window"] = "Окно &наблюдения", -- src\editor\menu_view.lua
|
||||
["&Watches"] = "&Выражения", -- src\editor\debugger.lua
|
||||
["About ZeroBrane Studio"] = "О ZeroBrane Studio", -- src\editor\menu_help.lua
|
||||
["Add Watch Expression"] = "Добавить в окно наблюдения", -- src\editor\editor.lua
|
||||
["&Watch Window"] = "Окно &выражений", -- src\editor\menu_view.lua
|
||||
[".&bak on Replace"] = ".&bak после замены", -- src\editor\findreplace.lua
|
||||
["About %s"] = "О %s", -- src\editor\menu_help.lua
|
||||
["Add Watch Expression"] = "Добавить выражение", -- src\editor\editor.lua
|
||||
["Add to Scratchpad"] = "Добавить в черновик", -- src\editor\editor.lua
|
||||
["All files"] = "Все файлы", -- src\editor\commands.lua
|
||||
["Allow external process to start debugging"] = "Разрешить внешнему процессу начать отладку", -- src\editor\menu_project.lua
|
||||
@@ -50,8 +57,9 @@ return {
|
||||
["Can't run the entry point script ('%s')."] = "Ошибка выполнения стартового скрипта ('%s').", -- src\editor\debugger.lua
|
||||
["Can't start debugging session due to internal error '%s'."] = "Невозможно начать отладочную сессию из-за внутренней ошибки '%s'.", -- src\editor\debugger.lua
|
||||
["Can't start debugging without an opened file or with the current file not being saved ('%s')."] = "Невозможно начать отладку без открытого файла или с несохраненным текущим файлом ('%s').", -- src\editor\debugger.lua
|
||||
["Cancel"] = "Отмена", -- src\editor\findreplace.lua
|
||||
["Choose ..."] = "Выбрать ...", -- src\editor\menu_project.lua
|
||||
["Choose a project directory"] = "Выберите каталог проекта", -- src\editor\menu_project.lua
|
||||
["Choose a project directory"] = "Выберите папку проекта", -- src\editor\findreplace.lua, src\editor\menu_project.lua
|
||||
["Clear &Dynamic Words"] = "Очистить &динамические слова", -- src\editor\menu_edit.lua
|
||||
["Clear the output window before compiling or debugging"] = "Очистить окно вывода перед компиляцией или отладкой", -- src\editor\menu_project.lua
|
||||
["Close &Other Pages"] = "Закрыть &остальные вкладки", -- src\editor\gui.lua
|
||||
@@ -65,15 +73,16 @@ return {
|
||||
["Compile the current file"] = "Скомпилировать текущий файл", -- src\editor\menu_project.lua
|
||||
["Complete &Identifier"] = "Дополнить &идентификатор", -- src\editor\menu_edit.lua
|
||||
["Complete the current identifier"] = "Дополнить текущий идентификатор", -- src\editor\menu_edit.lua
|
||||
["Copy selected text to clipboard"] = "Скопировать выделенный текст в буфер обмена", -- src\editor\menu_edit.lua, src\editor\gui.lua
|
||||
["Copy selected text to clipboard"] = "Скопировать выделенный текст в буфер обмена", -- src\editor\menu_edit.lua
|
||||
["Couldn't activate file '%s' for debugging; continuing without it."] = "Невозможно открыть файл '%s' для отладки; выполнение будет продолжено без него.", -- src\editor\debugger.lua
|
||||
["Create an empty document"] = "Создать новый документ", -- src\editor\menu_file.lua, src\editor\gui.lua
|
||||
["Cu&t"] = "Вы&резать", -- src\editor\editor.lua, src\editor\menu_edit.lua
|
||||
["Cut selected text to clipboard"] = "Вырезать выделенный текст в буфер обмена", -- src\editor\menu_edit.lua, src\editor\gui.lua
|
||||
["Cut selected text to clipboard"] = "Вырезать выделенный текст в буфер обмена", -- src\editor\menu_edit.lua
|
||||
["Debugger server started at %s:%d."] = "Сервер отладки запущен на %s:%d.", -- src\editor\debugger.lua
|
||||
["Debugging session completed (%s)."] = "Отладочная сессия завершена (%s).", -- src\editor\debugger.lua
|
||||
["Debugging session started in '%s'."] = "Отладочная сессия запущена в '%s'.", -- src\editor\debugger.lua
|
||||
["Debugging suspended at %s:%s (couldn't activate the file)."] = "Отладка остановлена на %s:%s (невозможно открыть файл).", -- src\editor\debugger.lua
|
||||
["Directory"] = "Папка", -- src\editor\findreplace.lua
|
||||
["Do you want to reload it?"] = "Перезагрузить его?", -- src\editor\editor.lua
|
||||
["Do you want to save the changes to '%s'?"] = "Сохранить изменения в '%s'?", -- src\editor\commands.lua
|
||||
["E&xit"] = "Вы&ход", -- src\editor\menu_file.lua
|
||||
@@ -84,7 +93,6 @@ return {
|
||||
["Error while processing API file: %s"] = "Ошибка обработки файла определений API: %s", -- src\editor\autocomplete.lua
|
||||
["Error while processing configuration file: %s"] = "Ошибка обработки файла конфигурации: %s", -- src\editor\style.lua
|
||||
["Error"] = "Ошибка", -- src\editor\commands.lua
|
||||
["Evaluate &Watches"] = "&Вычислить выражения", -- src\editor\debugger.lua
|
||||
["Evaluate in Console"] = "Выполнить в консоли", -- src\editor\editor.lua
|
||||
["Execute the current project/file and keep updating the code to see immediate results"] = "Запустить текущий проект/файл и продолжать вносить изменения в код с немедленным выводом результатов", -- src\editor\menu_project.lua
|
||||
["Execute the current project/file"] = "Запустить текущий проект/файл", -- src\editor\menu_project.lua
|
||||
@@ -94,34 +102,45 @@ return {
|
||||
["Expression"] = "Выражение", -- src\editor\debugger.lua
|
||||
["File '%s' has been modified on disk."] = "Файл '%s' был изменен на диске.", -- src\editor\editor.lua
|
||||
["File '%s' has more recent timestamp than restored '%s'; please review before saving."] = "Файл '%s' имеет более позднее время модификации, чем восстановленный '%s'; пожалуйста просмотрите его перед сохранением.", -- src\editor\commands.lua
|
||||
["File '%s' no longer exists."] = "Файл '%s' больше не существует.", -- src\editor\editor.lua
|
||||
["File '%s' no longer exists."] = "Файл '%s' больше не существует.", -- src\editor\editor.lua, src\editor\menu_file.lua
|
||||
["File Type"] = "Тип файла", -- src\editor\findreplace.lua
|
||||
["File history"] = "История файлов", -- src\editor\menu_file.lua
|
||||
["Find &In Files"] = "Н&айти в файлах", -- src\editor\menu_search.lua
|
||||
["Find &Next"] = "Найти &далее", -- src\editor\menu_search.lua
|
||||
["Find &Previous"] = "Найти &ранее", -- src\editor\menu_search.lua
|
||||
["Find In Files"] = "Найти в файлах", -- src\editor\findreplace.lua
|
||||
["Find and replace text in files"] = "Найти и заменить текст в файлах", -- src\editor\menu_search.lua
|
||||
["Find and replace text"] = "Найти и заменить текст", -- src\editor\menu_search.lua, src\editor\gui.lua
|
||||
["Find text in files"] = "Найти текст в файлах", -- src\editor\menu_search.lua
|
||||
["Find text"] = "Найти текст", -- src\editor\menu_search.lua, src\editor\gui.lua
|
||||
["Find the earlier text occurence"] = "Найти предыдущее вхождение текста", -- src\editor\menu_search.lua
|
||||
["Find the next text occurrence"] = "Найти следующее вхождение текста", -- src\editor\menu_search.lua
|
||||
["Find"] = "Найти", -- src\editor\findreplace.lua
|
||||
["Fold or unfold all code folds"] = "Свернуть или развернуть все блоки кода", -- src\editor\menu_edit.lua
|
||||
["Found auto-recovery record and restored saved session."] = "Найдена запись авто-восстановления и восстановлена сохраненная сессия.", -- src\editor\commands.lua
|
||||
["Found"] = "Найдено", -- src\editor\findreplace.lua
|
||||
["Full &Screen"] = "Во весь экр&ан", -- src\editor\menu_view.lua
|
||||
["Go to a selected line"] = "Перейти к заданной строке", -- src\editor\menu_search.lua
|
||||
["Goto Line"] = "Перейти к строке", -- src\editor\menu_search.lua
|
||||
["INS"] = "ВСТ", -- src\editor\editor.lua
|
||||
["In Files"] = "Установки файлов", -- src\editor\findreplace.lua
|
||||
["Jump to a function definition..."] = "Перейти к определению функции...", -- src\editor\editor.lua
|
||||
["Known Files"] = "Файлы Lua", -- src\editor\commands.lua
|
||||
["Ln: %d"] = "Стр: %d", -- src\editor\editor.lua
|
||||
["Local console"] = "Локальная консоль", -- src\editor\shellbox.lua, src\editor\gui.lua
|
||||
["Lua &Interpreter"] = "&Интерпретатор Lua", -- src\editor\menu_project.lua
|
||||
["Mapped remote request for '%s' to '%s'."] = "Удаленный запрос для '%s' отображен на '%s'.", -- src\editor\debugger.lua
|
||||
["Match &case"] = "Совпадение регистра", -- src\editor\findreplace.lua
|
||||
["Match &whole word"] = "Совпадение целого слова", -- src\editor\findreplace.lua
|
||||
["Mixed end-of-line encodings detected."] = "Обнаружены смешанные символы конца строки.", -- src\editor\commands.lua
|
||||
["OVR"] = "ЗАМ", -- src\editor\editor.lua
|
||||
["Open an existing document"] = "Открыть существующий документ", -- src\editor\menu_file.lua, src\editor\gui.lua
|
||||
["Open file"] = "Открыть файл", -- src\editor\commands.lua
|
||||
["Options"] = "Установки", -- src\editor\findreplace.lua
|
||||
["Output (running)"] = "Вывод (запущен)", -- src\editor\output.lua
|
||||
["Output"] = "Вывод", -- src\editor\output.lua, src\editor\settings.lua, src\editor\gui.lua
|
||||
["Paste text from the clipboard"] = "Вставить текст из буфера обмена", -- src\editor\menu_edit.lua, src\editor\gui.lua
|
||||
["Paste text from the clipboard"] = "Вставить текст из буфера обмена", -- src\editor\menu_edit.lua
|
||||
["Preferences"] = "Настройки", -- src\editor\menu_edit.lua
|
||||
["Prepend '=' to show complex values on multiple lines."] = "Укажите '=' в начале выражения для отображения сложных значений на нескольких строках.", -- src\editor\shellbox.lua
|
||||
["Press cancel to abort."] = "Нажмите Отмена для завершения.", -- src\editor\commands.lua
|
||||
["Program '%s' started in '%s' (pid: %d)."] = "Программа '%s' запущена в '%s' (pid: %d).", -- src\editor\output.lua
|
||||
@@ -130,16 +149,22 @@ return {
|
||||
["Program starting as '%s'."] = "Программа запускается как '%s'.", -- src\editor\output.lua
|
||||
["Program stopped (pid: %d)."] = "Программа завершена (pid: %d).", -- src\editor\debugger.lua
|
||||
["Program unable to run as '%s'."] = "Программа не может быть запущена как '%s'.", -- src\editor\output.lua
|
||||
["Project Directory"] = "Каталог проекта", -- src\editor\menu_project.lua
|
||||
["Project Directory"] = "Папка проекта", -- src\editor\menu_project.lua
|
||||
["Project"] = "Проект", -- src\editor\settings.lua, src\editor\gui.lua
|
||||
["Project/&FileTree Window"] = "Окно &проекта/списка файлов", -- src\editor\menu_view.lua
|
||||
["R/O"] = "R/O", -- src\editor\editor.lua
|
||||
["R/W"] = "R/W", -- src\editor\editor.lua
|
||||
["Re&place In Files"] = "Замени&ть в файлах", -- src\editor\menu_search.lua
|
||||
["Recent Files"] = "Недавние файлы", -- src\editor\menu_file.lua
|
||||
["Redo last edit undone"] = "Вернуть последнее отмененное изменение", -- src\editor\menu_edit.lua, src\editor\gui.lua
|
||||
["Redo last edit undone"] = "Вернуть последнее отмененное изменение", -- src\editor\menu_edit.lua
|
||||
["Refused a request to start a new debugging session as there is one in progress already."] = "Отказано в запросе на запуск новой отладочной сессии, поскольку одна сессия уже выполняется.", -- src\editor\debugger.lua
|
||||
["Regular &expression"] = "Регулярное выражение", -- src\editor\findreplace.lua
|
||||
["Remote console"] = "Удаленная консоль", -- src\editor\shellbox.lua
|
||||
["Replace &All"] = "Заменить все", -- src\editor\findreplace.lua
|
||||
["Replace"] = "Заменить", -- src\editor\findreplace.lua
|
||||
["Replaced an invalid UTF8 character with %s."] = "Некорректный символ UTF8 заменен на %s.", -- src\editor\commands.lua
|
||||
["Replaced"] = "Заменено", -- src\editor\findreplace.lua
|
||||
["Replacing"] = "Замена", -- src\editor\findreplace.lua
|
||||
["Reset to default layout"] = "Установить расположение окон по умолчанию", -- src\editor\menu_view.lua
|
||||
["Resets the dynamic word list for autocompletion"] = "Очистить список динамических слов для автодополнения", -- src\editor\menu_edit.lua
|
||||
["Run as Scratchpad"] = "Запустить как черновик", -- src\editor\menu_project.lua
|
||||
@@ -154,17 +179,21 @@ return {
|
||||
["Save the current document to a file with a new name"] = "Сохранить текущий документ в файл под новым именем", -- src\editor\menu_file.lua
|
||||
["Save the current document"] = "Сохранить текущий документ", -- src\editor\menu_file.lua, src\editor\gui.lua
|
||||
["Saved auto-recover at %s."] = "Сохранено авто-восст в %s.", -- src\editor\commands.lua
|
||||
["Scope"] = "Направление", -- src\editor\findreplace.lua
|
||||
["Scratchpad error"] = "Ошибка в черновике", -- src\editor\debugger.lua
|
||||
["Searching for"] = "Поиск", -- src\editor\findreplace.lua
|
||||
["Select &All"] = "Выделить &все", -- src\editor\editor.lua, src\editor\menu_edit.lua
|
||||
["Select all text in the editor"] = "Выделить весь текст в редакторе", -- src\editor\menu_edit.lua
|
||||
["Set From Current File"] = "Установить по текущему файлу", -- src\editor\menu_project.lua
|
||||
["Set project directory from current file"] = "Установить каталог проекта по текущему файлу", -- src\editor\menu_project.lua, src\editor\gui.lua
|
||||
["Set project directory from current file"] = "Установить папку проекта по текущему файлу", -- src\editor\menu_project.lua, src\editor\gui.lua
|
||||
["Set the interpreter to be used"] = "Установить используемый интерпретатор", -- src\editor\menu_project.lua
|
||||
["Set the project directory to be used"] = "Установить используемый каталог проекта", -- src\editor\menu_project.lua
|
||||
["Set the project directory to be used"] = "Установить используемую папку проекта", -- src\editor\menu_project.lua
|
||||
["Settings: System"] = "Установки: Системы", -- src\editor\menu_edit.lua
|
||||
["Settings: User"] = "Установки: Пользователя", -- src\editor\menu_edit.lua
|
||||
["Show &Tooltip"] = "Показать &подсказку", -- src\editor\menu_edit.lua
|
||||
["Show tooltip for current position; place cursor after opening bracket of function"] = "Показать подсказку в текущей позиции; переместите курсор в позицию после открывающей скобки функции", -- src\editor\menu_edit.lua
|
||||
["Sort selected lines"] = "Отсортировать выделенные строки", -- src\editor\menu_search.lua
|
||||
["Stack Window"] = "Окно стека", -- src\editor\debugger.lua
|
||||
["Stack"] = "Стек", -- src\editor\debugger.lua
|
||||
["Start &Debugging"] = "Начать &отладку", -- src\editor\menu_project.lua
|
||||
["Start debugging"] = "Начать отладку", -- src\editor\menu_project.lua, src\editor\gui.lua
|
||||
["Step &Into"] = "&Войти", -- src\editor\menu_project.lua
|
||||
@@ -175,7 +204,8 @@ return {
|
||||
["Step over"] = "Перейти на следующую строку", -- src\editor\menu_project.lua, src\editor\gui.lua
|
||||
["Stop the currently running process"] = "Завершить текущий процесс", -- src\editor\menu_project.lua, src\editor\gui.lua
|
||||
["Switch to or from full screen mode"] = "Переключить полноэкранный режим", -- src\editor\menu_view.lua
|
||||
["The API file must be located in a subdirectory of the API directory."] = "Файл определений API должен быть расположен в подкаталоге каталога API.", -- src\editor\autocomplete.lua
|
||||
["Text not found."] = "Текст не найден.", -- src\editor\findreplace.lua
|
||||
["The API file must be located in a subdirectory of the API directory."] = "Файл определений API должен быть расположен внутри папки API.", -- src\editor\autocomplete.lua
|
||||
["Toggle Break&point"] = "&Точка останова", -- src\editor\menu_project.lua
|
||||
["Toggle breakpoint"] = "Переключить точку останова", -- src\editor\menu_project.lua, src\editor\gui.lua
|
||||
["Tr&ace"] = "Т&рассировка", -- src\editor\menu_project.lua
|
||||
@@ -183,17 +213,19 @@ return {
|
||||
["Unable to load file '%s'."] = "Ошибка загрузки файла '%s'.", -- src\editor\commands.lua
|
||||
["Unable to save file '%s': %s"] = "Ошибка сохранения файла '%s': %s", -- src\editor\commands.lua
|
||||
["Unable to stop program (pid: %d), code %d."] = "Невозможно завершить программу (pid: %d), код %d.", -- src\editor\debugger.lua
|
||||
["Undo last edit"] = "Отменить последнее действие", -- src\editor\menu_edit.lua, src\editor\gui.lua
|
||||
["Undo last edit"] = "Отменить последнее действие", -- src\editor\menu_edit.lua
|
||||
["Use '%s' to see full description."] = "Используйте '%s' для полного описания.", -- src\editor\editor.lua
|
||||
["Use '%s' to show line endings and '%s' to convert them."] = "Используйте '%s' для отображения символов конца строки и '%s' для их преобразования.", -- src\editor\commands.lua
|
||||
["Use 'clear' to clear the shell output and the history."] = "Используйте команду 'clear' для очистки содержимого окна и истории.", -- src\editor\shellbox.lua
|
||||
["Use Shift-Enter for multiline code."] = "Используйте Shift-Enter для многострочного кода.", -- src\editor\shellbox.lua
|
||||
["Value"] = "Значение", -- src\editor\debugger.lua
|
||||
["View the output/console window"] = "Показать окно вывода/консоли", -- src\editor\menu_view.lua
|
||||
["View the project/filetree window"] = "Показать окно проекта/списка файлов", -- src\editor\menu_view.lua
|
||||
["View the stack window"] = "Показать окно стека", -- src\editor\menu_view.lua, src\editor\gui.lua
|
||||
["View the watch window"] = "Показать окно наблюдения", -- src\editor\menu_view.lua, src\editor\gui.lua
|
||||
["Watch Window"] = "Окно наблюдения", -- src\editor\debugger.lua
|
||||
["View the watch window"] = "Показать окно выражений", -- src\editor\menu_view.lua, src\editor\gui.lua
|
||||
["Watch"] = "Выражение", -- src\editor\debugger.lua
|
||||
["Welcome to the interactive Lua interpreter."] = "Добро пожаловать в интерактивный интерпретатор Lua.", -- src\editor\shellbox.lua
|
||||
["Wrap ar&ound"] = "Продолжить сначала", -- src\editor\findreplace.lua
|
||||
["You must save the program first."] = "Вы должны сначала сохранить программу.", -- src\editor\commands.lua
|
||||
["on line %d"] = "в строке %d", -- src\editor\debugger.lua, src\editor\commands.lua
|
||||
["traced %d instruction"] = {"выполнена %d инструкция", "выполнено %d инструкции", "выполнено %d инструкций"}, -- src\editor\debugger.lua
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
--[[
|
||||
1. Pick a color scheme by clicking on a link:
|
||||
- [Tomorrow](macro:shell(ApplyStyleConfig('cfg/tomorrow.lua','Tomorrow')))
|
||||
- [TomorrowContrast](macro:shell(ApplyStyleConfig('cfg/tomorrow.lua','TomorrowContrast')))
|
||||
- [TomorrowNight](macro:shell(ApplyStyleConfig('cfg/tomorrow.lua','TomorrowNight')))
|
||||
- [TomorrowNightBlue](macro:shell(ApplyStyleConfig('cfg/tomorrow.lua','TomorrowNightBlue')))
|
||||
- [TomorrowNightBright](macro:shell(ApplyStyleConfig('cfg/tomorrow.lua','TomorrowNightBright')))
|
||||
|
||||
@@ -37,6 +37,20 @@ local colors = {
|
||||
Blue = H'4271ae',
|
||||
Purple = H'8959a8',
|
||||
},
|
||||
TomorrowContrast = { -- contributed by Sergey Lerg
|
||||
Background = H'f7f7f7',
|
||||
CurrentLine = H'efefef',
|
||||
Selection = H'd6d6d6',
|
||||
Foreground = H'202020',
|
||||
Comment = H'8e908c',
|
||||
Red = H'4669ff', --numbers
|
||||
Orange = H'f5871f',
|
||||
Yellow = H'eab700',
|
||||
Green = H'108010', --strings
|
||||
Aqua = H'4060b0', --built in functions
|
||||
Blue = H'101080', --keywords
|
||||
Purple = H'a01090',
|
||||
},
|
||||
TomorrowNight = {
|
||||
Background = H'1d1f21',
|
||||
CurrentLine = H'282a2e',
|
||||
@@ -109,7 +123,7 @@ local colors = {
|
||||
},
|
||||
Monokai = {
|
||||
Background = H'272822',
|
||||
CurrentLine = H'49483E',
|
||||
CurrentLine = H'2D2F29',
|
||||
Selection = H'49483E',
|
||||
Foreground = H'F8F8F2',
|
||||
Comment = H'75715E',
|
||||
@@ -182,15 +196,15 @@ return {
|
||||
-- wxstc.wxSTC_LUA_NUMBER
|
||||
number = {fg = C.Red},
|
||||
|
||||
-- wxstc.wxSTC_LUA_WORD, wxstc.wxSTC_LUA_WORD#
|
||||
-- wxstc.wxSTC_LUA_WORD, wxstc.wxSTC_LUA_WORD2-8
|
||||
keywords0 = {fg = C.Blue, b = true},
|
||||
keywords1 = {fg = C.Aqua, b = false},
|
||||
keywords2 = {fg = C.Aqua, b = true},
|
||||
keywords3 = {fg = C.Purple, b = true},
|
||||
keywords4 = {fg = C.Purple, b = true},
|
||||
keywords5 = {fg = C.Purple, b = true},
|
||||
keywords6 = {fg = C.Purple, b = true},
|
||||
keywords7 = {fg = C.Purple, b = true},
|
||||
keywords3 = {fg = C.Purple, b = false},
|
||||
keywords4 = {fg = C.Purple, b = false},
|
||||
keywords5 = {fg = C.Purple, b = false},
|
||||
keywords6 = {fg = C.Purple, b = false},
|
||||
keywords7 = {fg = C.Purple, b = false},
|
||||
|
||||
-- common (inherit fg/bg from text)
|
||||
-- wxstc.wxSTC_LUA_IDENTIFIER
|
||||
@@ -218,7 +232,7 @@ return {
|
||||
wxSTC_INDIC_DIAGONAL Diagonal hatching
|
||||
wxSTC_INDIC_STRIKE Strike-out
|
||||
wxSTC_INDIC_BOX Box
|
||||
wxSTC_INDIC_ROUNDBOX Rounded Box (not suppored in the current version?)
|
||||
wxSTC_INDIC_ROUNDBOX Rounded Box
|
||||
--]]
|
||||
|
||||
-- markup
|
||||
@@ -244,8 +258,4 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
---- Zenburn license ----
|
||||
|
||||
GNU GPL, http://www.gnu.org/licenses/gpl.html
|
||||
|
||||
--]]
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
--[[-- Copy required content from this file to `user.lua`
|
||||
--[[-- This file shows examples of settings you can adjust.
|
||||
|
||||
Configuration files are loaded in the following order
|
||||
Configuration files with preferences are loaded in the following order:
|
||||
1. cfg/user.lua (system-wide configuration)
|
||||
2. HOME/.zbstudio/user.lua (per-user configuration)
|
||||
3. -cfg <lua code fragment|filename> (command line configuration)
|
||||
|
||||
1. <application>\config.lua
|
||||
2. cfg\user.lua
|
||||
3. ~\.zbstudio\user.lua
|
||||
4. -cfg commandline strings
|
||||
See [configuration](http://studio.zerobrane.com/doc-configuration.html) page for information about location of configuration files.
|
||||
|
||||
--]]--
|
||||
|
||||
@@ -47,7 +47,7 @@ path.lua = 'd:/lua/lua'
|
||||
path.gslshell = [[D:\Lua\gsl-shell\gsl-shell.exe]]
|
||||
|
||||
-- to provide output filter for those engines that support redirecting
|
||||
-- of "print" output to the IDE (like Corona SDK and Gideros)
|
||||
-- of "print" output to the IDE (like Corona SDK or Gideros)
|
||||
debugger.outputfilter = function(m) return #m < 124 and m or m:sub(1,120).."...\n" end
|
||||
|
||||
-- to fix an issue with 0d0d0a line endings in MOAI examples,
|
||||
@@ -109,7 +109,7 @@ styles.fncall.st = wxstc.wxSTC_INDIC_PLAIN
|
||||
wxSTC_INDIC_DIAGONAL Diagonal hatching
|
||||
wxSTC_INDIC_STRIKE Strike-out
|
||||
wxSTC_INDIC_BOX Box
|
||||
wxSTC_INDIC_ROUNDBOX Rounded Box (not suppored in the current version?)
|
||||
wxSTC_INDIC_ROUNDBOX Rounded Box
|
||||
--]]
|
||||
|
||||
-- to enable additional spec files (like spec/cpp.lua)
|
||||
@@ -117,8 +117,8 @@ load.specs(function(file) return file:find('spec[/\\]cpp%.lua$') end)
|
||||
|
||||
-- to specify a default EOL encoding to be used for new files:
|
||||
-- `wxstc.wxSTC_EOL_CRLF` or `wxstc.wxSTC_EOL_LF`;
|
||||
-- `nil` means OS default: CRLF on Windows and OSX and LF on Linux/Unix.
|
||||
-- CRLF as a default on OSX is a bug and is likely to change in future versions.
|
||||
-- `nil` means OS default: CRLF on Windows and LF on Linux/Unix and OSX.
|
||||
-- (OSX had CRLF as a default until v0.36, which fixed it).
|
||||
editor.defaulteol = wxstc.wxSTC_EOL_LF
|
||||
|
||||
-- to turn off checking for mixed end-of-line encodings in loaded files
|
||||
@@ -132,3 +132,6 @@ debugger.runonstart = true
|
||||
|
||||
-- to set compact fold that doesn't include empty lines after a block
|
||||
editor.foldcompact = true
|
||||
|
||||
-- to disable zoom with mouse wheel as it may be too sensitive on OSX
|
||||
editor.nomousezoom = true
|
||||
|
||||
59
cfg/user-snippet.lua
Normal file
59
cfg/user-snippet.lua
Normal file
@@ -0,0 +1,59 @@
|
||||
--[[-- Copy snippets from this file to `user.lua` --]]--
|
||||
|
||||
--[[ Add a shortcut to generate `~` if your keyboard doesn't have one
|
||||
local G = ... -- this now points to the global environment in the script
|
||||
local ide, wx, TR, ID = G.ide, G.wx, G.TR, G.ID
|
||||
local postinit = ide.app.postinit
|
||||
ide.app.postinit = function()
|
||||
if postinit then postinit() end
|
||||
local menu = ide.frame.menuBar:GetMenu(ide.frame.menuBar:FindMenu(TR("&Edit")))
|
||||
menu:Append(ID "tilde", "Tilde\tAlt-'")
|
||||
ide.frame:Connect(ID "tilde", wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function () GetEditor():AddText("~") end)
|
||||
end
|
||||
--]]
|
||||
|
||||
--[[ Add `Evaluate in Console` option to the Edit menu
|
||||
local G = ... -- this now points to the global environment in the script
|
||||
local ide, wx, TR, ID = G.ide, G.wx, G.TR, G.ID
|
||||
local postinit = ide.app.postinit
|
||||
ide.app.postinit = function()
|
||||
if postinit then postinit() end
|
||||
local menu = ide.frame.menuBar:GetMenu(ide.frame.menuBar:FindMenu(TR("&Edit")))
|
||||
menu:Append(ID "eval", "Evaluate in Console\tCtrl-E")
|
||||
ide.frame:Connect(ID "eval", wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function () ShellExecuteCode(GetEditor():GetSelectedText()) end)
|
||||
ide.frame:Connect(ID "eval", wx.wxEVT_UPDATE_UI,
|
||||
function (event) event:Enable(GetEditor() and #GetEditor():GetSelectedText() > 0) end)
|
||||
end
|
||||
--]]
|
||||
|
||||
--[[ Add `Zoom` menu to increase/decrease/reset font in the editor
|
||||
local G = ... -- this now points to the global environment in the script
|
||||
local ide, wx, TR, ID = G.ide, G.wx, G.TR, G.ID
|
||||
local postinit = ide.app.postinit
|
||||
ide.app.postinit = function()
|
||||
if postinit then postinit() end
|
||||
|
||||
local zoomMenu = wx.wxMenu{
|
||||
{ID "zoomreset", "Zoom to 100%\tCtrl-0"},
|
||||
{ID "zoomin", "Zoom In\tCtrl-+"},
|
||||
{ID "zoomout", "Zoom Out\tCtrl--"},
|
||||
}
|
||||
local menu = ide.frame.menuBar:GetMenu(ide.frame.menuBar:FindMenu(TR("&View")))
|
||||
menu:Append(ID "zoom", "Zoom", zoomMenu)
|
||||
|
||||
ide.frame:Connect(ID "zoomreset", wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function () GetEditor():SetZoom(1) end)
|
||||
ide.frame:Connect(ID "zoomin", wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function () GetEditor():SetZoom(GetEditor():GetZoom()+1) end)
|
||||
ide.frame:Connect(ID "zoomout", wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function () GetEditor():SetZoom(GetEditor():GetZoom()-1) end)
|
||||
|
||||
-- only enable if there is an editor
|
||||
for _, m in G.ipairs({"zoomreset", "zoomin", "zoomout"}) do
|
||||
ide.frame:Connect(ID(m), wx.wxEVT_UPDATE_UI,
|
||||
function (event) event:Enable(GetEditor() ~= nil) end)
|
||||
end
|
||||
end
|
||||
--]]
|
||||
@@ -65,8 +65,7 @@ local xcode = {
|
||||
-- Watch window menu items
|
||||
[G.ID_ADDWATCH] = "Ins",
|
||||
[G.ID_EDITWATCH] = "F2",
|
||||
[G.ID_REMOVEWATCH] = "Del",
|
||||
[G.ID_EVALUATEWATCH] = "",
|
||||
[G.ID_DELETEWATCH] = "Del",
|
||||
-- Editor popup menu items
|
||||
[G.ID_QUICKADDWATCH] = "",
|
||||
[G.ID_QUICKEVAL] = "",
|
||||
|
||||
@@ -40,13 +40,10 @@ return {
|
||||
return
|
||||
end
|
||||
|
||||
-- can we really do debugging? do if asked and if not on mac OSX where it's not supported
|
||||
local debug = rundebug and not mac
|
||||
if rundebug then
|
||||
-- start running the application right away
|
||||
DebuggerAttachDefault({startwith = file,
|
||||
runstart = ide.config.debugger.runonstart ~= false,
|
||||
redirect = debug and "c", noshell = mac or nil, noeval = mac or nil})
|
||||
DebuggerAttachDefault({startwith = file, redirect = mac and "r" or "c",
|
||||
runstart = ide.config.debugger.runonstart ~= false})
|
||||
|
||||
-- copy mobdebug.lua to Resources/ folder on Win and to the project folder on OSX
|
||||
-- as copying it to Resources/ folder seems to break the signature of the app.
|
||||
@@ -60,7 +57,8 @@ return {
|
||||
end
|
||||
end
|
||||
|
||||
local cmd = ('"%s" %s"%s"'):format(corona, debug and "-debug " or "", file)
|
||||
local debugopt = mac and "-debug 1 -project " or "-debug "
|
||||
local cmd = ('"%s" %s"%s"'):format(corona, rundebug and debugopt or "", file)
|
||||
-- CommandLineRun(cmd,wdir,tooutput,nohide,stringcallback,uid,endcallback)
|
||||
return CommandLineRun(cmd,self:fworkdir(wfilename),true,false,nil,nil,
|
||||
function() ide.debugger.pid = nil end)
|
||||
|
||||
@@ -4,15 +4,6 @@ local gideros
|
||||
local win = ide.osname == "Windows"
|
||||
local mac = ide.osname == "Macintosh"
|
||||
|
||||
local function exePath()
|
||||
local mainpath = ide.editorFilename:gsub("[^/\\]+$","")
|
||||
local macExe = mainpath..'bin/lua.app/Contents/MacOS/lua'
|
||||
return ide.config.path.lua or
|
||||
(ide.osname == "Windows" and mainpath..[[bin\lua.exe]]
|
||||
or (ide.osname == "Unix" and [[lua]]) -- using installed lua
|
||||
or (wx.wxFileExists(macExe) and macExe or mainpath..[[bin/lua]]))
|
||||
end
|
||||
|
||||
local function isValidPid(bid, cmd)
|
||||
if not bid or bid == -1 or bid == 0 then
|
||||
DisplayOutputLn(("Program unable to run as '%s'."):format(cmd))
|
||||
@@ -74,7 +65,7 @@ return {
|
||||
|
||||
-- find *.gproj file in the project directory
|
||||
local file
|
||||
for _, proj in ipairs(FileSysGet(self:fworkdir(wfilename).."/*.gproj", wx.wxFILE)) do
|
||||
for _, proj in ipairs(FileSysGetRecursive(self:fworkdir(wfilename), false, "*.gproj")) do
|
||||
if file then
|
||||
DisplayOutputLn("Found multiple .gproj files in the project directory; ignored '"..proj.."'.")
|
||||
end
|
||||
|
||||
@@ -5,7 +5,7 @@ local function exePath()
|
||||
local macExe = mainpath..'bin/lua.app/Contents/MacOS/lua'
|
||||
return ide.config.path.lua or
|
||||
(ide.osname == "Windows" and mainpath..[[bin\lua.exe]]
|
||||
or (ide.osname == "Unix" and [[lua]]) -- using installed lua
|
||||
or (ide.osname == "Unix" and mainpath..([[bin/linux/%s/lua]]):format(ide.osarch))
|
||||
or (wx.wxFileExists(macExe) and macExe or mainpath..[[bin/lua]]))
|
||||
end
|
||||
|
||||
@@ -16,10 +16,8 @@ return {
|
||||
frun = function(self,wfilename,rundebug)
|
||||
exe = exe or exePath()
|
||||
local filepath = wfilename:GetFullPath()
|
||||
local script
|
||||
if rundebug then
|
||||
DebuggerAttachDefault({runstart = ide.config.debugger.runonstart == true})
|
||||
script = rundebug
|
||||
else
|
||||
-- if running on Windows and can't open the file, this may mean that
|
||||
-- the file path includes unicode characters that need special handling
|
||||
@@ -30,11 +28,11 @@ return {
|
||||
winapi.set_encoding(winapi.CP_UTF8)
|
||||
filepath = winapi.short_path(filepath)
|
||||
end
|
||||
|
||||
script = ('dofile [[%s]]'):format(filepath)
|
||||
end
|
||||
local code = ([[xpcall(function() io.stdout:setvbuf('no'); %s end,function(err) print(debug.traceback(err)) end)]]):format(script)
|
||||
local cmd = '"'..exe..'" -e "'..code..'"'
|
||||
local code = rundebug
|
||||
and ([[-e "io.stdout:setvbuf('no'); %s"]]):format(rundebug)
|
||||
or ([[-e "io.stdout:setvbuf('no')" "%s"]]):format(filepath)
|
||||
local cmd = '"'..exe..'" '..code
|
||||
-- CommandLineRun(cmd,wdir,tooutput,nohide,stringcallback,uid,endcallback)
|
||||
return CommandLineRun(cmd,self:fworkdir(wfilename),true,false,nil,nil,
|
||||
function() ide.debugger.pid = nil end)
|
||||
|
||||
@@ -9,7 +9,7 @@ local s3e = os.getenv("S3E_DIR")
|
||||
return {
|
||||
name = "Marmalade Quick",
|
||||
description = "Marmalade Quick mobile framework",
|
||||
api = {"baselib"},
|
||||
api = {"baselib", "marmalade"},
|
||||
frun = function(self,wfilename,rundebug)
|
||||
quick = quick or ide.config.path.quick or (s3e and GetFullPathIfExists(s3e, exe))
|
||||
if not quick then
|
||||
@@ -25,7 +25,7 @@ return {
|
||||
local candidates, paths = {}, {}
|
||||
for p in path:gmatch("[^"..sep.."]+") do
|
||||
table.insert(paths, p)
|
||||
for _, candidate in ipairs(FileSysGet(p.."/*.*", wx.wxDIR)) do
|
||||
for _, candidate in ipairs(FileSysGetRecursive(p, false, "*")) do
|
||||
if GetFullPathIfExists(candidate, exe) then table.insert(candidates, candidate) end
|
||||
if GetFullPathIfExists(candidate.."/s3e", exe) then table.insert(candidates, candidate.."/s3e") end
|
||||
end
|
||||
@@ -52,10 +52,10 @@ return {
|
||||
|
||||
-- check for *.mkb file; it can be in the same or in the parent folder
|
||||
local mproj, mfile = MergeFullPath(projdir, "./")
|
||||
for _, file in ipairs(FileSysGet(mproj.."*.mkb", wx.wxFILE)) do mfile = file end
|
||||
for _, file in ipairs(FileSysGetRecursive(mproj, false, "*.mkb")) do mfile = file end
|
||||
if not mfile then
|
||||
mproj, mfile = MergeFullPath(projdir, "../")
|
||||
for _, file in ipairs(FileSysGet(mproj.."*.mkb", wx.wxFILE)) do mfile = file end
|
||||
for _, file in ipairs(FileSysGetRecursive(mproj, false, "*.mkb")) do mfile = file end
|
||||
end
|
||||
if not mfile then
|
||||
DisplayOutputLn(("Can't find '%s' project file."):format(mproj))
|
||||
@@ -90,7 +90,8 @@ return {
|
||||
end
|
||||
end
|
||||
|
||||
local dll = MergeFullPath(s3e, "../quick/target/quick_prebuilt_d.s86")
|
||||
local dll = GetFullPathIfExists(s3e, "../quick/target/quick_prebuilt_d.s86")
|
||||
or MergeFullPath(s3e, ("../quick/target/%s/quick_prebuilt_d.s86"):format(mac and 'osx' or 'win'))
|
||||
local options = table.concat({
|
||||
([[--dll="%s"]]):format(dll),
|
||||
(datadir and ([[--data="%s"]]):format(datadir) or ''),
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
--
|
||||
-- MobDebug 0.517
|
||||
-- Copyright 2011-12 Paul Kulchenko
|
||||
-- MobDebug 0.526
|
||||
-- Copyright 2011-13 Paul Kulchenko
|
||||
-- Based on RemDebug 1.0 Copyright Kepler Project 2005
|
||||
--
|
||||
|
||||
local mobdebug = {
|
||||
_NAME = "mobdebug",
|
||||
_VERSION = 0.517,
|
||||
_VERSION = 0.526,
|
||||
_COPYRIGHT = "Paul Kulchenko",
|
||||
_DESCRIPTION = "Mobile Remote Debugger for the Lua programming language",
|
||||
port = os and os.getenv and os.getenv("MOBDEBUG_PORT") or 8172,
|
||||
checkcount = 200,
|
||||
yieldtimeout = 0.02,
|
||||
}
|
||||
|
||||
@@ -58,9 +59,11 @@ end
|
||||
-- check for OS and convert file names to lower case on windows
|
||||
-- (its file system is case insensitive, but case preserving), as setting a
|
||||
-- breakpoint on x:\Foo.lua will not work if the file was loaded as X:\foo.lua.
|
||||
local iswindows = os and os.getenv and (os.getenv('WINDIR')
|
||||
or (os.getenv('OS') or ''):match('[Ww]indows'))
|
||||
or pcall(require, "winapi")
|
||||
-- OSX and Windows behave the same way (case insensitive, but case preserving)
|
||||
local iscasepreserving = os and os.getenv and (os.getenv('WINDIR')
|
||||
or (os.getenv('OS') or ''):match('[Ww]indows')
|
||||
or os.getenv('DYLD_LIBRARY_PATH'))
|
||||
or not io.open("/proc")
|
||||
|
||||
-- turn jit off based on Mike Pall's comment in this discussion:
|
||||
-- http://www.freelists.org/post/luajit/Debug-hooks-and-JIT,2
|
||||
@@ -81,14 +84,13 @@ local lastfile
|
||||
local watchescnt = 0
|
||||
local abort -- default value is nil; this is used in start/loop distinction
|
||||
local seen_hook = false
|
||||
local skip
|
||||
local skipcount = 0
|
||||
local checkcount = 0
|
||||
local step_into = false
|
||||
local step_over = false
|
||||
local step_level = 0
|
||||
local stack_level = 0
|
||||
local server
|
||||
local rset
|
||||
local buf
|
||||
local outputs = {}
|
||||
local iobase = {print = print}
|
||||
local basedir = ""
|
||||
@@ -101,10 +103,10 @@ end
|
||||
local function q(s) return s:gsub('([%(%)%.%%%+%-%*%?%[%^%$%]])','%%%1') end
|
||||
|
||||
local serpent = (function() ---- include Serpent module for serialization
|
||||
local n, v = "serpent", 0.22 -- (C) 2012 Paul Kulchenko; MIT License
|
||||
local c, d = "Paul Kulchenko", "Serializer and pretty printer of Lua data types"
|
||||
local n, v = "serpent", 0.23 -- (C) 2012-13 Paul Kulchenko; MIT License
|
||||
local c, d = "Paul Kulchenko", "Lua serializer and pretty printer"
|
||||
local snum = {[tostring(1/0)]='1/0 --[[math.huge]]',[tostring(-1/0)]='-1/0 --[[-math.huge]]',[tostring(0/0)]='0/0'}
|
||||
local badtype = {thread = true, userdata = true}
|
||||
local badtype = {thread = true, userdata = true, cdata = true}
|
||||
local keyword, globals, G = {}, {}, (_G or _ENV)
|
||||
for _,k in ipairs({'and', 'break', 'do', 'else', 'elseif', 'end', 'false',
|
||||
'for', 'function', 'goto', 'if', 'in', 'local', 'nil', 'not', 'or', 'repeat',
|
||||
@@ -117,9 +119,10 @@ local function s(t, opts)
|
||||
local name, indent, fatal = opts.name, opts.indent, opts.fatal
|
||||
local sparse, custom, huge = opts.sparse, opts.custom, not opts.nohuge
|
||||
local space, maxl = (opts.compact and '' or ' '), (opts.maxlevel or math.huge)
|
||||
local comm = opts.comment and (tonumber(opts.comment) or math.huge)
|
||||
local seen, sref, syms, symn = {}, {}, {}, 0
|
||||
local function gensym(val) return (tostring(val):gsub("[^%w]",""):gsub("(%d%w+)",
|
||||
local iname, comm = '_'..(name or ''), opts.comment and (tonumber(opts.comment) or math.huge)
|
||||
local seen, sref, syms, symn = {}, {'local '..iname..'={}'}, {}, 0
|
||||
local function gensym(val) return '_'..(tostring(tostring(val)):gsub("[^%w]",""):gsub("(%d%w+)",
|
||||
-- tostring(val) is needed because __tostring may return a non-string value
|
||||
function(s) if not syms[s] then symn = symn+1; syms[s] = symn end return syms[s] end)) end
|
||||
local function safestr(s) return type(s) == "number" and (huge and snum[tostring(s)] or s)
|
||||
or type(s) ~= "string" and tostring(s) -- escape NEWLINE/010 and EOF/026
|
||||
@@ -132,41 +135,34 @@ local function s(t, opts)
|
||||
local plain = type(n) == "string" and n:match("^[%l%u_][%w_]*$") and not keyword[n]
|
||||
local safe = plain and n or '['..safestr(n)..']'
|
||||
return (path or '')..(plain and path and '.' or '')..safe, safe end
|
||||
local alphanumsort = type(opts.sortkeys) == 'function' and opts.sortkeys or function(o, n)
|
||||
local alphanumsort = type(opts.sortkeys) == 'function' and opts.sortkeys or function(k, o, n) -- k=keys, o=originaltable, n=padding
|
||||
local maxn, to = tonumber(n) or 12, {number = 'a', string = 'b'}
|
||||
local function padnum(d) return ("%0"..maxn.."d"):format(d) end
|
||||
table.sort(o, function(a,b)
|
||||
return (o[a] and 0 or to[type(a)] or 'z')..(tostring(a):gsub("%d+",padnum))
|
||||
< (o[b] and 0 or to[type(b)] or 'z')..(tostring(b):gsub("%d+",padnum)) end) end
|
||||
table.sort(k, function(a,b)
|
||||
-- sort numeric keys first: k[key] is non-nil for numeric keys
|
||||
return (k[a] and 0 or to[type(a)] or 'z')..(tostring(a):gsub("%d+",padnum))
|
||||
< (k[b] and 0 or to[type(b)] or 'z')..(tostring(b):gsub("%d+",padnum)) end) end
|
||||
local function val2str(t, name, indent, insref, path, plainindex, level)
|
||||
local ttype, level = type(t), (level or 0)
|
||||
local ttype, level, mt = type(t), (level or 0), getmetatable(t)
|
||||
local spath, sname = safename(path, name)
|
||||
local tag = plainindex and
|
||||
((type(name) == "number") and '' or name..space..'='..space) or
|
||||
(name ~= nil and sname..space..'='..space or '')
|
||||
if seen[t] then -- if already seen and in sref processing,
|
||||
if insref then return tag..seen[t] end -- then emit right away
|
||||
if seen[t] then -- already seen this element
|
||||
table.insert(sref, spath..space..'='..space..seen[t])
|
||||
return tag..'nil'..comment('ref', level)
|
||||
elseif badtype[ttype] then
|
||||
seen[t] = spath
|
||||
return tag..globerr(t, level)
|
||||
elseif ttype == 'function' then
|
||||
return tag..'nil'..comment('ref', level) end
|
||||
if mt and (mt.__serialize or mt.__tostring) then -- knows how to serialize itself
|
||||
seen[t] = insref or spath
|
||||
local ok, res = pcall(string.dump, t)
|
||||
local func = ok and ((opts.nocode and "function() --[[..skipped..]] end" or
|
||||
"loadstring("..safestr(res)..",'@serialized')")..comment(t, level))
|
||||
return tag..(func or globerr(t, level))
|
||||
elseif ttype == "table" then
|
||||
if mt.__serialize then t = mt.__serialize(t) else t = tostring(t) end
|
||||
ttype = type(t) end -- new value falls through to be serialized
|
||||
if ttype == "table" then
|
||||
if level >= maxl then return tag..'{}'..comment('max', level) end
|
||||
seen[t] = insref or spath -- set path to use as reference
|
||||
if getmetatable(t) and getmetatable(t).__tostring
|
||||
then return tag..val2str(tostring(t),nil,indent,false,nil,nil,level+1)..comment("meta", level) end
|
||||
seen[t] = insref or spath
|
||||
if next(t) == nil then return tag..'{}'..comment(t, level) end -- table empty
|
||||
local maxn, o, out = #t, {}, {}
|
||||
for key = 1, maxn do table.insert(o, key) end
|
||||
for key in pairs(t) do if not o[key] then table.insert(o, key) end end
|
||||
if opts.sortkeys then alphanumsort(o, opts.sortkeys) end
|
||||
if opts.sortkeys then alphanumsort(o, t, opts.sortkeys) end
|
||||
for n, key in ipairs(o) do
|
||||
local value, ktype, plainindex = t[key], type(key), n <= maxn and not sparse
|
||||
if opts.valignore and opts.valignore[value] -- skip ignored values; do nothing
|
||||
@@ -176,7 +172,8 @@ local function s(t, opts)
|
||||
elseif ktype == 'table' or ktype == 'function' or badtype[ktype] then
|
||||
if not seen[key] and not globals[key] then
|
||||
table.insert(sref, 'placeholder')
|
||||
sref[#sref] = 'local '..val2str(key,gensym(key),indent,gensym(key)) end
|
||||
local sname = safename(iname, gensym(key)) -- iname is table for local variables
|
||||
sref[#sref] = val2str(key,sname,indent,sname,iname,true) end
|
||||
table.insert(sref, 'placeholder')
|
||||
local path = seen[t]..'['..(seen[key] or globals[key] or gensym(key))..']'
|
||||
sref[#sref] = path..space..'='..space..(seen[value] or val2str(value,nil,indent,path))
|
||||
@@ -189,12 +186,22 @@ local function s(t, opts)
|
||||
local body = table.concat(out, ','..(indent and '\n'..prefix..indent or space))
|
||||
local tail = indent and "\n"..prefix..'}' or '}'
|
||||
return (custom and custom(tag,head,body,tail) or tag..head..body..tail)..comment(t, level)
|
||||
elseif badtype[ttype] then
|
||||
seen[t] = insref or spath
|
||||
return tag..globerr(t, level)
|
||||
elseif ttype == 'function' then
|
||||
seen[t] = insref or spath
|
||||
local ok, res = pcall(string.dump, t)
|
||||
local func = ok and ((opts.nocode and "function() --[[..skipped..]] end" or
|
||||
"loadstring("..safestr(res)..",'@serialized')")..comment(t, level))
|
||||
return tag..(func or globerr(t, level))
|
||||
else return tag..safestr(t) end -- handle all other types
|
||||
end
|
||||
local sepr = indent and "\n" or ";"..space
|
||||
local body = val2str(t, name, indent) -- this call also populates sref
|
||||
local tail = #sref>0 and table.concat(sref, sepr)..sepr or ''
|
||||
return not name and body or "do local "..body..sepr..tail.."return "..name..sepr.."end"
|
||||
local tail = #sref>1 and table.concat(sref, sepr)..sepr or ''
|
||||
local warn = opts.comment and #sref>1 and space.."--[[incomplete output with shared/self-references skipped]]" or ''
|
||||
return not name and body..warn or "do local "..body..sepr..tail.."return "..name..sepr.."end"
|
||||
end
|
||||
|
||||
local function merge(a, b) if b then for k,v in pairs(b) do a[k] = v end end; return a; end
|
||||
@@ -205,7 +212,7 @@ return { _NAME = n, _COPYRIGHT = c, _DESCRIPTION = d, _VERSION = v, serialize =
|
||||
end)() ---- end of Serpent module
|
||||
|
||||
local function removebasedir(path, basedir)
|
||||
if iswindows then
|
||||
if iscasepreserving then
|
||||
-- check if the lowercased path matches the basedir
|
||||
-- if so, return substring of the original path (to not lowercase it)
|
||||
return path:lower():find('^'..q(basedir:lower()))
|
||||
@@ -242,14 +249,13 @@ local function stack(start)
|
||||
local source = debug.getinfo(i, "Snl")
|
||||
if not source then break end
|
||||
|
||||
-- remove basedir from source
|
||||
local src = source.source
|
||||
if src:find("@") == 1 then
|
||||
src = src:sub(2):gsub("\\", "/")
|
||||
if src:find("%./") == 1 then src = src:sub(3) end
|
||||
end
|
||||
|
||||
table.insert(stack, {
|
||||
table.insert(stack, { -- remove basedir from source
|
||||
{source.name, removebasedir(src, basedir), source.linedefined,
|
||||
source.currentline, source.what, source.namewhat, source.short_src},
|
||||
vars(i+1)})
|
||||
@@ -260,20 +266,20 @@ end
|
||||
|
||||
local function set_breakpoint(file, line)
|
||||
if file == '-' and lastfile then file = lastfile
|
||||
elseif iswindows then file = string.lower(file) end
|
||||
if not breakpoints[file] then breakpoints[file] = {} end
|
||||
breakpoints[file][line] = true
|
||||
elseif iscasepreserving then file = string.lower(file) end
|
||||
if not breakpoints[line] then breakpoints[line] = {} end
|
||||
breakpoints[line][file] = true
|
||||
end
|
||||
|
||||
local function remove_breakpoint(file, line)
|
||||
if file == '-' and lastfile then file = lastfile
|
||||
elseif iswindows then file = string.lower(file) end
|
||||
if breakpoints[file] then breakpoints[file][line] = nil end
|
||||
elseif iscasepreserving then file = string.lower(file) end
|
||||
if breakpoints[line] then breakpoints[line][file] = nil end
|
||||
end
|
||||
|
||||
-- this file name is already converted to lower case on windows.
|
||||
local function has_breakpoint(file, line)
|
||||
return breakpoints[file] and breakpoints[file][line]
|
||||
return breakpoints[line] and breakpoints[line][file]
|
||||
end
|
||||
|
||||
local function restore_vars(vars)
|
||||
@@ -366,6 +372,17 @@ local function in_debugger()
|
||||
return false
|
||||
end
|
||||
|
||||
local function is_pending(peer)
|
||||
-- if there is something already in the buffer, skip check
|
||||
if not buf and checkcount >= mobdebug.checkcount then
|
||||
peer:settimeout(0) -- non-blocking
|
||||
buf = peer:receive(1)
|
||||
peer:settimeout() -- back to blocking
|
||||
checkcount = 0
|
||||
end
|
||||
return buf
|
||||
end
|
||||
|
||||
local function debug_hook(event, line)
|
||||
-- (1) LuaJIT needs special treatment. Because debug_hook is set for
|
||||
-- *all* coroutines, and not just the one being debugged as in regular Lua
|
||||
@@ -397,13 +414,18 @@ local function debug_hook(event, line)
|
||||
elseif event == "return" or event == "tail return" then
|
||||
stack_level = stack_level - 1
|
||||
elseif event == "line" then
|
||||
-- may need to fall through because of the following:
|
||||
-- (1) step_into
|
||||
-- (2) step_over and stack_level <= step_level (need stack_level)
|
||||
-- (3) breakpoint; check for line first as it's known; then for file
|
||||
-- (4) socket call (only do every Xth check)
|
||||
-- (5) at least one watch is registered
|
||||
if not (
|
||||
step_into or step_over or breakpoints[line] or watchescnt > 0
|
||||
or is_pending(server)
|
||||
) then checkcount = checkcount + 1; return end
|
||||
|
||||
-- check if we need to skip some callbacks (to save time)
|
||||
if skip then
|
||||
skipcount = skipcount + 1
|
||||
if skipcount < skip or not is_safe(stack_level) then return end
|
||||
skipcount = 0
|
||||
end
|
||||
checkcount = mobdebug.checkcount -- force check on the next command
|
||||
|
||||
-- this is needed to check if the stack got shorter or longer.
|
||||
-- unfortunately counting call/return calls is not reliable.
|
||||
@@ -417,6 +439,7 @@ local function debug_hook(event, line)
|
||||
-- have any other instructions to execute. it triggers three returns:
|
||||
-- "return, tail return, return", which needs to be accounted for.
|
||||
stack_level = stack_depth(stack_level+1)
|
||||
|
||||
local caller = debug.getinfo(2, "S")
|
||||
|
||||
-- grab the filename and fix it if needed
|
||||
@@ -429,10 +452,10 @@ local function debug_hook(event, line)
|
||||
-- so we handle all sources as filenames
|
||||
file = file:gsub("^@", ""):gsub("\\", "/")
|
||||
-- need this conversion to be applied to relative and absolute
|
||||
-- file names as you may write "require 'Foo'" on Windows to
|
||||
-- load "foo.lua" (as it's case insensitive) and breakpoints
|
||||
-- file names as you may write "require 'Foo'" to
|
||||
-- load "foo.lua" (on a case insensitive file system) and breakpoints
|
||||
-- set on foo.lua will not work if not converted to the same case.
|
||||
if iswindows then file = string.lower(file) end
|
||||
if iscasepreserving then file = string.lower(file) end
|
||||
if file:find("%./") == 1 then file = file:sub(3)
|
||||
else file = file:gsub('^'..q(basedir), '') end
|
||||
|
||||
@@ -467,7 +490,7 @@ local function debug_hook(event, line)
|
||||
(step_into
|
||||
or (step_over and stack_level <= step_level)
|
||||
or has_breakpoint(file, line)
|
||||
or (socket.select(rset, nil, 0))[server])
|
||||
or is_pending(server))
|
||||
|
||||
if getin then
|
||||
vars = vars or capture_vars()
|
||||
@@ -556,6 +579,8 @@ local function debugger_loop(sev, svars, sfile, sline)
|
||||
elseif not line and err == "closed" then
|
||||
error("Debugger connection unexpectedly closed", 0)
|
||||
else
|
||||
-- if there is something in the pending buffer, prepend it to the line
|
||||
if buf then line = buf .. line; buf = nil end
|
||||
break
|
||||
end
|
||||
end
|
||||
@@ -614,7 +639,7 @@ local function debugger_loop(sev, svars, sfile, sline)
|
||||
if not loaded[k] then package.loaded[k] = nil end
|
||||
end
|
||||
|
||||
if size == 0 then -- RELOAD the current script being debugged
|
||||
if size == 0 and name == '-' then -- RELOAD the current script being debugged
|
||||
server:send("200 OK 0\n")
|
||||
coroutine.yield("load")
|
||||
else
|
||||
@@ -715,7 +740,9 @@ local function debugger_loop(sev, svars, sfile, sline)
|
||||
elseif command == "BASEDIR" then
|
||||
local _, _, dir = string.find(line, "^[A-Z]+%s+(.+)%s*$")
|
||||
if dir then
|
||||
basedir = iswindows and string.lower(dir) or dir
|
||||
basedir = iscasepreserving and string.lower(dir) or dir
|
||||
-- reset cached source as it may change with basedir
|
||||
lastsource = nil
|
||||
server:send("200 OK\n")
|
||||
else
|
||||
server:send("400 Bad Request\n")
|
||||
@@ -791,17 +818,6 @@ local function start(controller_host, controller_port)
|
||||
|
||||
server = (socket.connect4 or socket.connect)(controller_host, controller_port)
|
||||
if server then
|
||||
rset = {server} -- store hash to avoid recreating it later
|
||||
-- check if we are called from the debugger as this may happen
|
||||
-- when another debugger function calls start(); only check one level deep
|
||||
local this = debug.getinfo(1, "S").source
|
||||
local info = debug.getinfo(2, "Sl")
|
||||
if info.source == this then info = debug.getinfo(3, "Sl") end
|
||||
|
||||
local file = info.source
|
||||
if string.find(file, "@") == 1 then file = string.sub(file, 2) end
|
||||
if string.find(file, "%.[/\\]") == 1 then file = string.sub(file, 3) end
|
||||
|
||||
-- correct stack depth which already has some calls on it
|
||||
-- so it doesn't go into negative when those calls return
|
||||
-- as this breaks subsequence checks in stack_depth().
|
||||
@@ -811,30 +827,45 @@ local function start(controller_host, controller_port)
|
||||
-- provide our own traceback function to report the error remotely
|
||||
do
|
||||
local dtraceback = debug.traceback
|
||||
debug.traceback = function (err) genv.print(dtraceback(err, 3)) end
|
||||
debug.traceback = function (...)
|
||||
if select('#', ...) >= 1 then
|
||||
local err, lvl = ...
|
||||
if err and type(err) ~= 'thread' then
|
||||
local trace = dtraceback(err, (lvl or 2)+1)
|
||||
if genv.print == iobase.print then -- no remote redirect
|
||||
return trace
|
||||
else
|
||||
genv.print(trace) -- report the error remotely
|
||||
return -- don't report locally to avoid double reporting
|
||||
end
|
||||
end
|
||||
end
|
||||
-- direct call to debug.traceback: return the original.
|
||||
-- debug.traceback(nil, level) doesn't work in Lua 5.1
|
||||
-- (http://lua-users.org/lists/lua-l/2011-06/msg00574.html), so
|
||||
-- simply remove first frame from the stack trace
|
||||
return (dtraceback(...):gsub("(stack traceback:\n)[^\n]*\n", "%1"))
|
||||
end
|
||||
end
|
||||
coro_debugger = coroutine.create(debugger_loop)
|
||||
debug.sethook(debug_hook, "lcr")
|
||||
local ok, res = coroutine.resume(coro_debugger, events.RESTART, capture_vars(), file, info.currentline)
|
||||
if not ok and res then error(res, 2) end
|
||||
step_into = true -- start with step command
|
||||
return true
|
||||
else
|
||||
print("Could not connect to " .. controller_host .. ":" .. controller_port)
|
||||
end
|
||||
end
|
||||
|
||||
local function controller(controller_host, controller_port)
|
||||
local function controller(controller_host, controller_port, scratchpad)
|
||||
-- only one debugging session can be run (as there is only one debug hook)
|
||||
if isrunning() then return end
|
||||
|
||||
controller_host = controller_host or "localhost"
|
||||
controller_port = controller_port or mobdebug.port
|
||||
|
||||
local exitonerror = not skip -- exit if not running a scratchpad
|
||||
local exitonerror = not scratchpad
|
||||
server = (socket.connect4 or socket.connect)(controller_host, controller_port)
|
||||
if server then
|
||||
rset = {server} -- store hash to avoid recreating it later
|
||||
|
||||
local function report(trace, err)
|
||||
local msg = err .. "\n" .. trace
|
||||
server:send("401 Error in Execution " .. #msg .. "\n")
|
||||
@@ -848,7 +879,7 @@ local function controller(controller_host, controller_port)
|
||||
while true do
|
||||
step_into = true -- start with step command
|
||||
abort = false -- reset abort flag from the previous loop
|
||||
if skip then skipcount = skip end -- force suspend right away
|
||||
if scratchpad then checkcount = mobdebug.checkcount end -- force suspend right away
|
||||
|
||||
coro_debugee = coroutine.create(debugee)
|
||||
debug.sethook(coro_debugee, debug_hook, "lcr")
|
||||
@@ -886,14 +917,12 @@ local function controller(controller_host, controller_port)
|
||||
return true
|
||||
end
|
||||
|
||||
local function scratchpad(controller_host, controller_port, frequency)
|
||||
skip = frequency or 100
|
||||
return controller(controller_host, controller_port)
|
||||
local function scratchpad(controller_host, controller_port)
|
||||
return controller(controller_host, controller_port, true)
|
||||
end
|
||||
|
||||
local function loop(controller_host, controller_port)
|
||||
skip = nil -- just in case if loop() is called after scratchpad()
|
||||
return controller(controller_host, controller_port)
|
||||
return controller(controller_host, controller_port, false)
|
||||
end
|
||||
|
||||
local function on()
|
||||
@@ -983,9 +1012,8 @@ local function handle(params, client, options)
|
||||
file = string.gsub(file, "\\", "/") -- convert slash
|
||||
file = removebasedir(file, basedir)
|
||||
client:send("SETB " .. file .. " " .. line .. "\n")
|
||||
if client:receive() == "200 OK" then
|
||||
if not breakpoints[file] then breakpoints[file] = {} end
|
||||
breakpoints[file][line] = true
|
||||
if client:receive() == "200 OK" then
|
||||
set_breakpoint(file, line)
|
||||
else
|
||||
print("Error: breakpoint not inserted")
|
||||
end
|
||||
@@ -1020,7 +1048,7 @@ local function handle(params, client, options)
|
||||
file = removebasedir(file, basedir)
|
||||
client:send("DELB " .. file .. " " .. line .. "\n")
|
||||
if client:receive() == "200 OK" then
|
||||
if breakpoints[file] then breakpoints[file][line] = nil end
|
||||
remove_breakpoint(file, line)
|
||||
else
|
||||
print("Error: breakpoint not removed")
|
||||
end
|
||||
@@ -1028,11 +1056,11 @@ local function handle(params, client, options)
|
||||
print("Invalid command")
|
||||
end
|
||||
elseif command == "delallb" then
|
||||
for file, breaks in pairs(breakpoints) do
|
||||
for line, _ in pairs(breaks) do
|
||||
for line, breaks in pairs(breakpoints) do
|
||||
for file, _ in pairs(breaks) do
|
||||
client:send("DELB " .. file .. " " .. line .. "\n")
|
||||
if client:receive() == "200 OK" then
|
||||
breakpoints[file][line] = nil
|
||||
if client:receive() == "200 OK" then
|
||||
remove_breakpoint(file, line)
|
||||
else
|
||||
print("Error: breakpoint at file " .. file .. " line " .. line .. " not removed")
|
||||
end
|
||||
@@ -1154,12 +1182,10 @@ local function handle(params, client, options)
|
||||
print("Invalid command")
|
||||
end
|
||||
elseif command == "listb" then
|
||||
for k, v in pairs(breakpoints) do
|
||||
local b = k .. ": " -- get filename
|
||||
for k in pairs(v) do
|
||||
b = b .. k .. " " -- get line numbers
|
||||
for l, v in pairs(breakpoints) do
|
||||
for f in pairs(v) do
|
||||
print(f .. ": " .. l)
|
||||
end
|
||||
print(b)
|
||||
end
|
||||
elseif command == "listw" then
|
||||
for i, v in pairs(watches) do
|
||||
|
||||
43
spec/lua.lua
43
spec/lua.lua
@@ -27,7 +27,7 @@ local function isfndef(str)
|
||||
end
|
||||
|
||||
return {
|
||||
exts = {"lua", "rockspec"},
|
||||
exts = {"lua", "rockspec", "wlua"},
|
||||
lexer = wxstc.wxSTC_LEX_LUA,
|
||||
apitype = "lua",
|
||||
linecomment = "--",
|
||||
@@ -93,7 +93,6 @@ return {
|
||||
line = line -1
|
||||
end
|
||||
|
||||
local added
|
||||
while (line <= endline) do
|
||||
local ls = editor:PositionFromLine(line)
|
||||
local s = bit.band(editor:GetStyleAt(ls),31)
|
||||
@@ -103,35 +102,47 @@ return {
|
||||
|
||||
-- check for assignments
|
||||
local varname = "([%w_%.]+)"
|
||||
local identifier = "([%w_%.:]+)"
|
||||
local identifier = "([%w_%.:%s]+)"
|
||||
|
||||
-- special hint
|
||||
local typ,var = tx:match("%s*%-%-=%s*"..varname.."%s+"..identifier)
|
||||
if (var and typ) then
|
||||
typ = typ:gsub("%s","")
|
||||
assigns[var] = typ
|
||||
added = true
|
||||
else
|
||||
-- real assignments
|
||||
local var,typ,rest = tx:match("%s*"..identifier.."%s*=%s*"..identifier.."(.*)")
|
||||
local comment = rest and rest:match(".*%-%-=%s*"..varname.."%s*$")
|
||||
local comma = rest and rest:match(".-%s*([,]*)%s*$")
|
||||
if (var and comment) then
|
||||
assigns[var] = comment
|
||||
added = true
|
||||
elseif (var and typ and comma=="") then
|
||||
local var,typ = tx:match("%s*"..identifier.."%s*=%s*([^;]+)")
|
||||
|
||||
var = var and var:gsub("local","")
|
||||
var = var and var:gsub("%s","")
|
||||
typ = typ and typ:gsub("%b[]","")
|
||||
typ = typ and typ:gsub("%b()","")
|
||||
typ = typ and typ:gsub("%b{}","")
|
||||
if (typ and (typ:match(",") or typ:match("%sor%s") or typ:match("%sand%s"))) then
|
||||
typ = nil
|
||||
end
|
||||
typ = typ and typ:gsub("%s","")
|
||||
if (var and typ) then
|
||||
class,func = typ:match(varname.."[%.:]"..varname)
|
||||
if (func) then
|
||||
if (assigns[typ]) then
|
||||
assigns[var] = assigns[typ]
|
||||
elseif (func) then
|
||||
-- FIXME remove this, in favor of proper api definitions
|
||||
local added
|
||||
local funcnames = {"new","load","create"}
|
||||
for i,v in ipairs(funcnames) do
|
||||
if (func:match("^"..v)) then
|
||||
if (func == v) then
|
||||
assigns[var] = class
|
||||
added = true
|
||||
break
|
||||
end
|
||||
end
|
||||
elseif (assigns[typ]) then
|
||||
assigns[var] = assigns[typ]
|
||||
added = true
|
||||
if (not added) then
|
||||
-- let's hope autocomplete info can resolve this
|
||||
assigns[var] = typ
|
||||
end
|
||||
else
|
||||
assigns[var] = typ
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
11
src/defs.lua
11
src/defs.lua
@@ -105,6 +105,7 @@ config = {
|
||||
-- also report mixed eol encodings
|
||||
defaulteol = nil, -- default line-endings for new files; valid values are
|
||||
-- wxstc.wxSTC_EOL_CRLF, wxstc.wxSTC_EOL_LF and nil (OS default)
|
||||
nomousezoom = nil, -- disable zooming using mouse wheel
|
||||
},
|
||||
|
||||
default = {
|
||||
@@ -193,11 +194,17 @@ app = {
|
||||
api = {
|
||||
-- global space words, e.g "table"
|
||||
["blah"] = {
|
||||
-- "function", "class", "keyword", "value", "lib"
|
||||
-- "function", "class", "keyword", "value", "lib", "method"
|
||||
-- method is for class:func functions
|
||||
type = "function",
|
||||
description = "this does something",
|
||||
|
||||
-- value and function:
|
||||
-- value/function/method:
|
||||
-- for autocomplete type guessing, insert the string
|
||||
-- that the variable name is replace with
|
||||
-- e.g. "test = somefunc()" somefunc has valuetype of "math"
|
||||
-- then typing "test." will be treated as "math." in
|
||||
-- autcomplete logic
|
||||
valuetype = "api.ClassName",
|
||||
|
||||
-- function:
|
||||
|
||||
@@ -44,8 +44,8 @@ end
|
||||
-- API loading
|
||||
|
||||
local function addAPI(apifile,only,subapis,known) -- relative to API directory
|
||||
local ftype,fname = apifile:match("api[/\\]([^/\\]+)[/\\](.*)%.")
|
||||
if not ftype then
|
||||
local ftype, fname = apifile:match("api[/\\]([^/\\]+)[/\\](.*)%.")
|
||||
if not ftype or not fname then
|
||||
DisplayOutputLn(TR("The API file must be located in a subdirectory of the API directory."))
|
||||
return
|
||||
end
|
||||
@@ -82,12 +82,8 @@ local function addAPI(apifile,only,subapis,known) -- relative to API directory
|
||||
end
|
||||
|
||||
local function loadallAPIs (only,subapis,known)
|
||||
for _, dir in ipairs(FileSysGet("api/*", wx.wxDIR)) do
|
||||
for _, file in ipairs(FileSysGet(dir.."/*.*", wx.wxFILE)) do
|
||||
if file:match "%.lua$" then
|
||||
addAPI(file,only,subapis,known)
|
||||
end
|
||||
end
|
||||
for _, file in ipairs(FileSysGetRecursive("api", true, "*.lua")) do
|
||||
if not file:match(string_Pathsep.."$") then addAPI(file,only,subapis,known) end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -119,7 +115,7 @@ local function fillTips(api,apibasename,apiname)
|
||||
if not tab.childs then return end
|
||||
for key,info in pairs(tab.childs) do
|
||||
traverse(info,key)
|
||||
if info.type == "function" then
|
||||
if info.type == "function" or info.type == "method" then
|
||||
local libstr = libname ~= "" and libname.."." or ""
|
||||
|
||||
-- fix description
|
||||
@@ -206,23 +202,35 @@ local function resolveAssign(editor,tx)
|
||||
return tab,a
|
||||
end
|
||||
|
||||
local classname
|
||||
local c = ""
|
||||
local c
|
||||
if (assigns) then
|
||||
-- find assign
|
||||
for w,s in tx:gmatch("([%w_]*)([%.:]?)") do
|
||||
|
||||
local old = classname
|
||||
classname = classname or (assigns[c..w])
|
||||
if (s ~= "" and old ~= classname) then
|
||||
c = classname..s
|
||||
else
|
||||
c = c..w..s
|
||||
local change = true
|
||||
while (change) do
|
||||
local classname = nil
|
||||
c = ""
|
||||
change = false
|
||||
for w,s in tx:gmatch("([%w_]+)([%.:]?)") do
|
||||
local old = classname
|
||||
-- check if what we have so far can be matched with a class name
|
||||
-- this can happen if it's a reference to a value with a known type
|
||||
classname = classname or assigns[c..w]
|
||||
if (s ~= "" and old ~= classname) then
|
||||
c = classname..s
|
||||
change = true
|
||||
else
|
||||
c = c..w..s
|
||||
end
|
||||
end
|
||||
-- abort if the same value is returned; no need to continue.
|
||||
-- this can happen after typing "smth = smth:new(); smth:"
|
||||
if tx == c then break end
|
||||
tx = c
|
||||
end
|
||||
else
|
||||
c = tx
|
||||
end
|
||||
|
||||
-- then work from api
|
||||
return getclass(ac,c)
|
||||
end
|
||||
@@ -367,19 +375,31 @@ end
|
||||
------------
|
||||
-- Final Autocomplete
|
||||
|
||||
local cache = {}
|
||||
local cachemain = {}
|
||||
local cachemethod = {}
|
||||
local laststrategy
|
||||
local function getAutoCompApiList(childs,fragment)
|
||||
local lastmethod
|
||||
local function getAutoCompApiList(childs,fragment,method)
|
||||
fragment = fragment:lower()
|
||||
local strategy = ide.config.acandtip.strategy
|
||||
if (laststrategy ~= strategy) then cache = {}; laststrategy = strategy end
|
||||
if (laststrategy ~= strategy) then
|
||||
cachemain = {}
|
||||
cachemethod = {}
|
||||
laststrategy = strategy
|
||||
end
|
||||
|
||||
local cache = method and cachemethod or cachemain
|
||||
|
||||
if (strategy == 2) then
|
||||
local wlist = cache[childs]
|
||||
if not wlist then
|
||||
wlist = " "
|
||||
for i in pairs(childs) do
|
||||
wlist = wlist..i.." "
|
||||
for i,v in pairs(childs) do
|
||||
-- if a:b typed, then value (type == "value") not allowed
|
||||
-- if a.b typed, then method (type == "method") not allowed
|
||||
if (method and v.type ~= "value") or (not method and v.type ~= "method") then
|
||||
wlist = wlist..i.." "
|
||||
end
|
||||
end
|
||||
cache[childs] = wlist
|
||||
end
|
||||
@@ -406,29 +426,33 @@ local function getAutoCompApiList(childs,fragment)
|
||||
cache[childs] = t
|
||||
|
||||
local sub = strategy == 1
|
||||
for key in pairs(childs) do
|
||||
local used = {}
|
||||
--
|
||||
local kl = key:lower()
|
||||
for i=0,#key do
|
||||
local k = kl:sub(1,i)
|
||||
t[k] = t[k] or {}
|
||||
used[k] = true
|
||||
table.insert(t[k],key)
|
||||
end
|
||||
if (sub) then
|
||||
-- find camel case / _ separated subwords
|
||||
-- glfwGetGammaRamp -> g, gg, ggr
|
||||
-- GL_POINT_SPRIT -> g, gp, gps
|
||||
local last = ""
|
||||
for ks in string.gmatch(key,"([A-Z%d]*[a-z%d]*_?)") do
|
||||
local k = last..(ks:sub(1,1):lower())
|
||||
last = k
|
||||
|
||||
for key,v in pairs(childs) do
|
||||
-- if a:b typed, then value (type == "value") not allowed
|
||||
-- if a.b typed, then method (type == "method") not allowed
|
||||
if (method and v.type ~= "value") or (not method and v.type ~= "method") then
|
||||
local used = {}
|
||||
--
|
||||
local kl = key:lower()
|
||||
for i=0,#key do
|
||||
local k = kl:sub(1,i)
|
||||
t[k] = t[k] or {}
|
||||
if (not used[k]) then
|
||||
used[k] = true
|
||||
table.insert(t[k],key)
|
||||
used[k] = true
|
||||
table.insert(t[k],key)
|
||||
end
|
||||
if (sub) then
|
||||
-- find camel case / _ separated subwords
|
||||
-- glfwGetGammaRamp -> g, gg, ggr
|
||||
-- GL_POINT_SPRIT -> g, gp, gps
|
||||
local last = ""
|
||||
for ks in string.gmatch(key,"([A-Z%d]*[a-z%d]*_?)") do
|
||||
local k = last..(ks:sub(1,1):lower())
|
||||
last = k
|
||||
|
||||
t[k] = t[k] or {}
|
||||
if (not used[k]) then
|
||||
used[k] = true
|
||||
table.insert(t[k],key)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -447,6 +471,8 @@ function CreateAutoCompList(editor,key)
|
||||
local tip = api.tip
|
||||
local ac = api.ac
|
||||
|
||||
local method = key:match(":[^:%.]*$") ~= nil
|
||||
|
||||
-- ignore keywords
|
||||
if tip.keys[key] then return end
|
||||
|
||||
@@ -499,7 +525,7 @@ function CreateAutoCompList(editor,key)
|
||||
end
|
||||
|
||||
-- list from api
|
||||
local apilist = getAutoCompApiList(tab.childs or tab,rest)
|
||||
local apilist = getAutoCompApiList(tab.childs or tab,rest,method)
|
||||
local compstr = ""
|
||||
if apilist then
|
||||
if (#rest > 0) then
|
||||
|
||||
@@ -14,13 +14,14 @@ local BREAKPOINT_MARKER = StylesGetMarker("breakpoint")
|
||||
function NewFile(event)
|
||||
local editor = CreateEditor()
|
||||
SetupKeywords(editor, "lua")
|
||||
AddEditor(editor, ide.config.default.fullname)
|
||||
local doc = AddEditor(editor, ide.config.default.fullname)
|
||||
if doc then SetEditorSelection(doc.index) end
|
||||
return editor
|
||||
end
|
||||
|
||||
-- Find an editor page that hasn't been used at all, eg. an untouched NewFile()
|
||||
local function findDocumentToReuse()
|
||||
local editor = nil
|
||||
local function findUnusedEditor()
|
||||
local editor
|
||||
for id, document in pairs(openDocuments) do
|
||||
if (document.editor:GetLength() == 0) and
|
||||
(not document.isModified) and (not document.filePath) and
|
||||
@@ -40,7 +41,10 @@ function LoadFile(filePath, editor, file_must_exist, skipselection)
|
||||
if (not editor) then
|
||||
for id, doc in pairs(openDocuments) do
|
||||
if doc.filePath and filePath:SameAs(wx.wxFileName(doc.filePath)) then
|
||||
if not skipselection then notebook:SetSelection(doc.index) end
|
||||
if not skipselection and doc.index ~= notebook:GetSelection() then
|
||||
-- selecting the same tab doesn't trigger PAGE_CHANGE event,
|
||||
-- but moves the focus to the tab bar, which needs to be avoided.
|
||||
notebook:SetSelection(doc.index) end
|
||||
return doc.editor
|
||||
end
|
||||
end
|
||||
@@ -58,20 +62,17 @@ function LoadFile(filePath, editor, file_must_exist, skipselection)
|
||||
end
|
||||
|
||||
local current = editor and editor:GetCurrentPos()
|
||||
editor = editor or findDocumentToReuse() or CreateEditor()
|
||||
editor = editor or findUnusedEditor() or CreateEditor()
|
||||
|
||||
editor:Freeze()
|
||||
editor:Clear()
|
||||
editor:ClearAll()
|
||||
SetupKeywords(editor, GetFileExt(filePath))
|
||||
editor:MarkerDeleteAll(BREAKPOINT_MARKER)
|
||||
editor:MarkerDeleteAll(CURRENT_LINE_MARKER)
|
||||
editor:AppendText(file_text or "")
|
||||
editor:MarkerDeleteAll(-1)
|
||||
editor:SetText(file_text or "")
|
||||
|
||||
-- check the editor as it can be empty if the file has malformed UTF8;
|
||||
-- skip binary files as they may have any sequences; can't show them anyway.
|
||||
if file_text and #file_text > 0 and not isBinary(file_text)
|
||||
and #(editor:GetText()) == 0 then
|
||||
if file_text and #file_text > 0 and #(editor:GetText()) == 0
|
||||
and not isBinary(file_text) then
|
||||
local replacement, invalid = "\022"
|
||||
file_text, invalid = fixUTF8(file_text, replacement)
|
||||
if #invalid > 0 then
|
||||
@@ -92,12 +93,12 @@ function LoadFile(filePath, editor, file_must_exist, skipselection)
|
||||
editor:Thaw()
|
||||
|
||||
if current then editor:GotoPos(current) end
|
||||
if (ide.config.editor.autotabs) then
|
||||
if (file_text and ide.config.editor.autotabs) then
|
||||
local found = string.find(file_text,"\t") ~= nil
|
||||
editor:SetUseTabs(found)
|
||||
end
|
||||
|
||||
if (ide.config.editor.checkeol) then
|
||||
if (file_text and ide.config.editor.checkeol) then
|
||||
-- Auto-detect CRLF/LF line-endings
|
||||
local foundcrlf = string.find(file_text,"\r\n") ~= nil
|
||||
local foundlf = (string.find(file_text,"[^\r]\n") ~= nil)
|
||||
@@ -117,7 +118,9 @@ function LoadFile(filePath, editor, file_must_exist, skipselection)
|
||||
|
||||
editor:EmptyUndoBuffer()
|
||||
local id = editor:GetId()
|
||||
if not openDocuments[id] then -- the editor has not been added to notebook
|
||||
if openDocuments[id] then -- existing editor; switch to the tab
|
||||
notebook:SetSelection(openDocuments[id].index)
|
||||
else -- the editor has not been added to notebook
|
||||
AddEditor(editor, wx.wxFileName(filePath):GetFullName()
|
||||
or ide.config.default.fullname)
|
||||
end
|
||||
@@ -126,10 +129,6 @@ function LoadFile(filePath, editor, file_must_exist, skipselection)
|
||||
openDocuments[id].modTime = GetFileModTime(filePath)
|
||||
SetDocumentModified(id, false)
|
||||
|
||||
IndicateFunctions(editor)
|
||||
|
||||
SettingsAppendFileToHistory(filePath)
|
||||
|
||||
-- activate the editor; this is needed for those cases when the editor is
|
||||
-- created from some other element, for example, from a project tree.
|
||||
if not skipselection then SetEditorSelection() end
|
||||
@@ -149,9 +148,7 @@ local function getExtsString()
|
||||
knownexts = knownexts:len() > 0 and knownexts:sub(1,-2) or nil
|
||||
|
||||
local exts = knownexts and TR("Known Files").." ("..knownexts..")|"..knownexts.."|" or ""
|
||||
exts = exts..TR("All files").." (*)|*"
|
||||
|
||||
return exts
|
||||
return exts..TR("All files").." (*)|*"
|
||||
end
|
||||
|
||||
function OpenFile(event)
|
||||
@@ -216,10 +213,17 @@ function SaveFileAs(editor)
|
||||
fn:Normalize() -- want absolute path for dialog
|
||||
|
||||
local ext = fn:GetExt()
|
||||
if (not ext or #ext == 0) and editor.spec and editor.spec.exts then
|
||||
ext = editor.spec.exts[1]
|
||||
-- set the extension on the file if assigned as this is used by OSX/Linux
|
||||
-- to present the correct default "save as type" choice.
|
||||
if ext then fn:SetExt(ext) end
|
||||
end
|
||||
local fileDialog = wx.wxFileDialog(ide.frame, TR("Save file as"),
|
||||
fn:GetPath(wx.wxPATH_GET_VOLUME),
|
||||
fn:GetFullName(),
|
||||
"*."..(ext and #ext > 0 and ext or "*"),
|
||||
-- specify the current extension plus all other extensions based on specs
|
||||
(ext and #ext > 0 and "*."..ext.."|*."..ext.."|" or "")..getExtsString(),
|
||||
wx.wxFD_SAVE)
|
||||
|
||||
if fileDialog:ShowModal() == wx.wxID_OK then
|
||||
@@ -229,9 +233,12 @@ function SaveFileAs(editor)
|
||||
SetEditorSelection() -- update title of the editor
|
||||
FileTreeRefresh() -- refresh the tree to reflect the new file
|
||||
FileTreeMarkSelected(filePath)
|
||||
SetupKeywords(editor, GetFileExt(filePath))
|
||||
IndicateFunctions(editor)
|
||||
if MarkupStyle then MarkupStyle(editor) end
|
||||
if ext ~= GetFileExt(filePath) then
|
||||
-- new extension, so setup new keywords and re-apply indicators
|
||||
SetupKeywords(editor, GetFileExt(filePath))
|
||||
IndicateFunctions(editor)
|
||||
MarkupStyle(editor)
|
||||
end
|
||||
saved = true
|
||||
end
|
||||
end
|
||||
@@ -295,7 +302,8 @@ local function removePage(index)
|
||||
notebook:SetSelection(prevIndex)
|
||||
end
|
||||
|
||||
SetEditorSelection() -- will use notebook GetSelection to update
|
||||
-- need to set editor selection as it's called *after* PAGE_CHANGED event
|
||||
SetEditorSelection()
|
||||
end
|
||||
|
||||
function ClosePage(selection)
|
||||
@@ -384,50 +392,47 @@ function SaveOnExit(allow_cancel)
|
||||
return true
|
||||
end
|
||||
|
||||
-- circle through "fold all" => "hide base lines" => "unfold all"
|
||||
function FoldSome()
|
||||
local editor = GetEditor()
|
||||
editor:Colourise(0, -1) -- update doc's folding info
|
||||
local visible, baseFound, expanded, folded
|
||||
for ln = 2, editor.LineCount - 1 do
|
||||
local foldall = false -- at least on header unfolded => fold all
|
||||
local hidebase = false -- at least one base is visible => hide all
|
||||
|
||||
for ln = 0, editor.LineCount - 1 do
|
||||
local foldRaw = editor:GetFoldLevel(ln)
|
||||
local foldLvl = math.mod(foldRaw, 4096)
|
||||
local foldHdr = math.mod(math.floor(foldRaw / 8192), 2) == 1
|
||||
if not baseFound and (foldLvl == wxstc.wxSTC_FOLDLEVELBASE) then
|
||||
baseFound = true
|
||||
visible = editor:GetLineVisible(ln)
|
||||
end
|
||||
if foldHdr then
|
||||
if editor:GetFoldExpanded(ln) then
|
||||
expanded = true
|
||||
else
|
||||
folded = true
|
||||
end
|
||||
end
|
||||
if expanded and folded and baseFound then break end
|
||||
end
|
||||
local show = not visible or (not baseFound and expanded) or (expanded and folded)
|
||||
local hide = visible and folded
|
||||
|
||||
if show then
|
||||
editor:ShowLines(1, editor.LineCount-1)
|
||||
-- at least one header is expanded
|
||||
foldall = foldall or (foldHdr and editor:GetFoldExpanded(ln))
|
||||
|
||||
-- at least one base can be hidden
|
||||
hidebase = hidebase or (
|
||||
not foldHdr
|
||||
and ln > 1 -- first line can't be hidden, so ignore it
|
||||
and foldLvl == wxstc.wxSTC_FOLDLEVELBASE
|
||||
and bit.band(foldRaw, wxstc.wxSTC_FOLDLEVELWHITEFLAG) == 0
|
||||
and editor:GetLineVisible(ln))
|
||||
end
|
||||
|
||||
for ln = 1, editor.LineCount - 1 do
|
||||
-- shows lines; this doesn't change fold status for folded lines
|
||||
if not foldall and not hidebase then editor:ShowLines(0, editor.LineCount-1) end
|
||||
|
||||
for ln = 0, editor.LineCount-1 do
|
||||
local foldRaw = editor:GetFoldLevel(ln)
|
||||
local foldLvl = math.mod(foldRaw, 4096)
|
||||
local foldHdr = math.mod(math.floor(foldRaw / 8192), 2) == 1
|
||||
if show then
|
||||
if foldHdr then
|
||||
if not editor:GetFoldExpanded(ln) then editor:ToggleFold(ln) end
|
||||
end
|
||||
elseif hide and (foldLvl == wxstc.wxSTC_FOLDLEVELBASE) then
|
||||
if not foldHdr then
|
||||
editor:HideLines(ln, ln)
|
||||
end
|
||||
elseif foldHdr then
|
||||
if editor:GetFoldExpanded(ln) then
|
||||
editor:ToggleFold(ln)
|
||||
end
|
||||
|
||||
if foldall then
|
||||
if foldHdr and editor:GetFoldExpanded(ln) then
|
||||
editor:ToggleFold(ln) end
|
||||
elseif hidebase then
|
||||
if not foldHdr and (foldLvl == wxstc.wxSTC_FOLDLEVELBASE) then
|
||||
editor:HideLines(ln, ln) end
|
||||
else -- unfold all
|
||||
if foldHdr and not editor:GetFoldExpanded(ln) then
|
||||
editor:ToggleFold(ln) end
|
||||
end
|
||||
end
|
||||
editor:EnsureCaretVisible()
|
||||
@@ -546,12 +551,7 @@ end
|
||||
function SetOpenFiles(nametab,params)
|
||||
for i,doc in ipairs(nametab) do
|
||||
local editor = LoadFile(doc.filename,nil,true,true) -- skip selection
|
||||
if editor then
|
||||
editor:SetCurrentPos(doc.cursorpos or 0)
|
||||
editor:SetSelectionStart(doc.cursorpos or 0)
|
||||
editor:SetSelectionEnd(doc.cursorpos or 0)
|
||||
editor:EnsureCaretVisible()
|
||||
end
|
||||
if editor then editor:GotoPosDelayed(doc.cursorpos or 0) end
|
||||
end
|
||||
notebook:SetSelection(params and params.index or 0)
|
||||
SetEditorSelection()
|
||||
@@ -561,33 +561,35 @@ local beforeFullScreenPerspective
|
||||
function ShowFullScreen(setFullScreen)
|
||||
if setFullScreen then
|
||||
beforeFullScreenPerspective = uimgr:SavePerspective()
|
||||
uimgr:GetPane("bottomnotebook"):Show(false)
|
||||
uimgr:GetPane("projpanel"):Show(false)
|
||||
|
||||
local panes = frame.uimgr:GetAllPanes()
|
||||
for index = 0, panes:GetCount()-1 do
|
||||
local name = panes:Item(index).name
|
||||
if name ~= "notebook" then frame.uimgr:GetPane(name):Hide() end
|
||||
end
|
||||
uimgr:Update()
|
||||
SetEditorSelection() -- make sure the focus is on the editor
|
||||
elseif beforeFullScreenPerspective then
|
||||
uimgr:LoadPerspective(beforeFullScreenPerspective)
|
||||
uimgr:LoadPerspective(beforeFullScreenPerspective, true)
|
||||
beforeFullScreenPerspective = nil
|
||||
end
|
||||
|
||||
uimgr:GetPane("toolBar"):Show(not setFullScreen)
|
||||
uimgr:Update()
|
||||
-- On OSX, toolbar and status bar are not hidden when switched to
|
||||
-- full screen: http://trac.wxwidgets.org/ticket/14259; do manually.
|
||||
-- need to turn off before showing full screen and turn on after,
|
||||
-- otherwise the window is restored incorrectly and is reduced in size.
|
||||
if ide.osname == 'Macintosh' and setFullScreen then
|
||||
frame:GetStatusBar():Hide()
|
||||
frame:GetToolBar():Hide()
|
||||
end
|
||||
|
||||
-- protect from systems that don't have ShowFullScreen (GTK on linux?)
|
||||
pcall(function() frame:ShowFullScreen(setFullScreen) end)
|
||||
end
|
||||
|
||||
local function restoreFiles(files)
|
||||
-- open files, but ignore some functions that are not needed;
|
||||
-- as we may be opening multiple files, it doesn't make sense to
|
||||
-- select editor and do some other similar work after each file.
|
||||
local noop, func = function() end, LoadFile
|
||||
local genv = {SetEditorSelection = noop, SettingsAppendFileToHistory = noop}
|
||||
setmetatable(genv, {__index = _G})
|
||||
local env = getfenv(func)
|
||||
setfenv(func, genv)
|
||||
-- provide fake index so that it doesn't activate it as the index may be not
|
||||
-- quite correct if some of the existing files are already open in the IDE.
|
||||
SetOpenFiles(files, {index = #files + notebook:GetPageCount()})
|
||||
setfenv(func, env)
|
||||
if ide.osname == 'Macintosh' and not setFullScreen then
|
||||
frame:GetStatusBar():Show()
|
||||
frame:GetToolBar():Show()
|
||||
end
|
||||
end
|
||||
|
||||
function ProjectConfig(dir, config)
|
||||
@@ -614,10 +616,7 @@ function SetOpenTabs(params)
|
||||
:format(doc.filename, doc.tabname))
|
||||
end
|
||||
end
|
||||
editor:SetCurrentPos(doc.cursorpos or 0)
|
||||
editor:SetSelectionStart(doc.cursorpos or 0)
|
||||
editor:SetSelectionEnd(doc.cursorpos or 0)
|
||||
editor:EnsureCaretVisible()
|
||||
editor:GotoPosDelayed(doc.cursorpos or 0)
|
||||
end
|
||||
notebook:SetSelection(params and params.index or 0)
|
||||
SetEditorSelection()
|
||||
@@ -665,11 +664,22 @@ local function saveAutoRecovery(event)
|
||||
TR("Saved auto-recover at %s."):format(os.date("%H:%M:%S")), 1)
|
||||
end
|
||||
|
||||
local function fastWrap(func, ...)
|
||||
-- ignore SetEditorSelection that is not needed as `func` may work on
|
||||
-- multipe files, but editor needs to be selected once.
|
||||
local SES = SetEditorSelection
|
||||
SetEditorSelection = function() end
|
||||
func(...)
|
||||
SetEditorSelection = SES
|
||||
end
|
||||
|
||||
function StoreRestoreProjectTabs(curdir, newdir)
|
||||
local win = ide.osname == 'Windows'
|
||||
local interpreter = ide.interpreter.fname
|
||||
local current, closing, restore = notebook:GetSelection(), 0, false
|
||||
|
||||
if ide.osname ~= 'Macintosh' then notebook:Freeze() end
|
||||
|
||||
if curdir and #curdir > 0 then
|
||||
local lowcurdir = win and string.lower(curdir) or curdir
|
||||
local lownewdir = win and string.lower(newdir) or newdir
|
||||
@@ -695,16 +705,22 @@ function StoreRestoreProjectTabs(curdir, newdir)
|
||||
|
||||
-- close pages for those files that match the project in the reverse order
|
||||
-- (as ids shift when pages are closed)
|
||||
for i = #closdocs, 1, -1 do ClosePage(closdocs[i].id) end
|
||||
for i = #closdocs, 1, -1 do fastWrap(ClosePage, closdocs[i].id) end
|
||||
end
|
||||
|
||||
local files, params = ProjectConfig(newdir)
|
||||
if files then restoreFiles(files) end
|
||||
if files then
|
||||
-- provide fake index so that it doesn't activate it as the index may be not
|
||||
-- quite correct if some of the existing files are already open in the IDE.
|
||||
fastWrap(SetOpenFiles, files, {index = #files + notebook:GetPageCount()})
|
||||
end
|
||||
|
||||
if params and params.interpreter and ide.interpreter.fname ~= params.interpreter then
|
||||
ProjectSetInterpreter(params.interpreter) -- set the interpreter
|
||||
end
|
||||
|
||||
if ide.osname ~= 'Macintosh' then notebook:Thaw() end
|
||||
|
||||
local index = params and params.index
|
||||
if notebook:GetPageCount() == 0 then NewFile()
|
||||
elseif restore and current >= 0 then notebook:SetSelection(current)
|
||||
@@ -720,7 +736,7 @@ function StoreRestoreProjectTabs(curdir, newdir)
|
||||
ProjectConfig(newdir, {})
|
||||
end
|
||||
|
||||
function CloseWindow(event)
|
||||
local function closeWindow(event)
|
||||
-- if the app is already exiting, then help it exit; wxwidgets on Windows
|
||||
-- is supposed to report Shutdown/logoff events by setting CanVeto() to
|
||||
-- false, but it doesn't happen. We simply leverage the fact that
|
||||
@@ -737,20 +753,32 @@ function CloseWindow(event)
|
||||
end
|
||||
|
||||
ShowFullScreen(false)
|
||||
ide.frame:Hide() -- hide everything while the IDE exits
|
||||
SettingsSaveAll()
|
||||
if DebuggerCloseWatchWindow then DebuggerCloseWatchWindow() end
|
||||
if DebuggerCloseStackWindow then DebuggerCloseStackWindow() end
|
||||
if DebuggerShutdown then DebuggerShutdown() end
|
||||
ide.settings:delete() -- always delete the config
|
||||
if ide.session.timer then ide.session.timer:Stop() end
|
||||
event:Skip()
|
||||
|
||||
-- without explicit exit() the IDE crashes with SIGILL exception when closed
|
||||
-- on MacOS compiled under 64bit with wxwidgets 2.9.3
|
||||
if ide.osname == "Macintosh" then os.exit() end
|
||||
SettingsSaveAll()
|
||||
ide.settings:Flush()
|
||||
|
||||
do -- hide all floating panes first
|
||||
local panes = frame.uimgr:GetAllPanes()
|
||||
for index = 0, panes:GetCount()-1 do
|
||||
local pane = frame.uimgr:GetPane(panes:Item(index).name)
|
||||
if pane:IsFloating() then pane:Hide() end
|
||||
end
|
||||
end
|
||||
frame.uimgr:Update() -- hide floating panes
|
||||
frame.uimgr:UnInit()
|
||||
frame:Hide() -- hide the main frame while the IDE exits
|
||||
|
||||
-- first need to detach all processes IDE has launched as the current
|
||||
-- process is likely to terminate before child processes are terminated,
|
||||
-- which may lead to a crash when EVT_END_PROCESS event is called.
|
||||
DetachChildProcess()
|
||||
DebuggerShutdown()
|
||||
|
||||
if ide.session.timer then ide.session.timer:Stop() end
|
||||
|
||||
event:Skip()
|
||||
end
|
||||
frame:Connect(wx.wxEVT_CLOSE_WINDOW, CloseWindow)
|
||||
frame:Connect(wx.wxEVT_CLOSE_WINDOW, closeWindow)
|
||||
|
||||
frame:Connect(wx.wxEVT_TIMER, saveAutoRecovery)
|
||||
|
||||
|
||||
@@ -13,10 +13,9 @@ debugger.server = nil -- DebuggerServer object when debugging, else nil
|
||||
debugger.running = false -- true when the debuggee is running
|
||||
debugger.listening = false -- true when the debugger is listening for a client
|
||||
debugger.portnumber = ide.config.debugger.port or mobdebug.port -- the port # to use for debugging
|
||||
debugger.watchWindow = nil -- the watchWindow, nil when not created
|
||||
debugger.watchCtrl = nil -- the child ctrl in the watchWindow
|
||||
debugger.stackWindow = nil -- the stackWindow, nil when not created
|
||||
debugger.stackCtrl = nil -- the child ctrl in the stackWindow
|
||||
debugger.watchCtrl = nil -- the watch ctrl that shows watch information
|
||||
debugger.stackCtrl = nil -- the stack ctrl that shows stack information
|
||||
debugger.toggleview = { stackpanel = false, watchpanel = false }
|
||||
debugger.hostname = ide.config.debugger.hostname or (function()
|
||||
local addr = wx.wxIPV4address() -- check what address is resolvable
|
||||
for _, host in ipairs({wx.wxGetHostName(), wx.wxGetFullHostName()}) do
|
||||
@@ -32,12 +31,18 @@ local CURRENT_LINE_MARKER_VALUE = 2^CURRENT_LINE_MARKER
|
||||
local BREAKPOINT_MARKER = StylesGetMarker("breakpoint")
|
||||
local BREAKPOINT_MARKER_VALUE = 2^BREAKPOINT_MARKER
|
||||
|
||||
local activate = {CHECKONLY = 1, NOREPORT = 2}
|
||||
|
||||
local function q(s) return s:gsub('([%(%)%.%%%+%-%*%?%[%^%$%]])','%%%1') end
|
||||
|
||||
local function updateWatchesSync(num)
|
||||
local watchCtrl = debugger.watchCtrl
|
||||
if watchCtrl and debugger.server and not debugger.running
|
||||
and ide.frame.uimgr:GetPane("watchpanel"):IsShown()
|
||||
and not debugger.scratchpad and not (debugger.options or {}).noeval then
|
||||
local bgcl = watchCtrl:GetBackgroundColour()
|
||||
local hicl = wx.wxColour(math.floor(bgcl:Red()*.9),
|
||||
math.floor(bgcl:Green()*.9), math.floor(bgcl:Blue()*.9))
|
||||
for idx = 0, watchCtrl:GetItemCount() - 1 do
|
||||
if not num or idx == num then
|
||||
local expression = watchCtrl:GetItemText(idx)
|
||||
@@ -54,9 +59,7 @@ local function updateWatchesSync(num)
|
||||
watchCtrl:GetItem(litem)
|
||||
watchCtrl:SetItemBackgroundColour(idx,
|
||||
watchCtrl:GetItem(litem) and newval ~= litem:GetText()
|
||||
and ide.config.styles.caretlinebg
|
||||
and wx.wxColour(unpack(ide.config.styles.caretlinebg.bg))
|
||||
or watchCtrl:GetBackgroundColour())
|
||||
and hicl or bgcl)
|
||||
end
|
||||
|
||||
watchCtrl:SetItem(idx, 1, newval)
|
||||
@@ -79,8 +82,9 @@ end
|
||||
|
||||
local function updateStackSync()
|
||||
local stackCtrl = debugger.stackCtrl
|
||||
if stackCtrl and debugger.server
|
||||
and not debugger.running and not debugger.scratchpad then
|
||||
if stackCtrl and debugger.server and not debugger.running
|
||||
and ide.frame.uimgr:GetPane("stackpanel"):IsShown()
|
||||
and not debugger.scratchpad then
|
||||
local stack, _, err = debugger.stack()
|
||||
if not stack or #stack == 0 then
|
||||
stackCtrl:DeleteAllItems()
|
||||
@@ -123,7 +127,7 @@ local function updateStackSync()
|
||||
end
|
||||
end
|
||||
for name,val in pairs(frame[3]) do
|
||||
local value, comment = val[1], val[2]
|
||||
local value, comment = val[1], tostring(val[2])
|
||||
local text = ("%s = %s%s"):
|
||||
format(name, mobdebug.line(value, params),
|
||||
simpleType[type(value)] and "" or (" --[["..comment.."]]"))
|
||||
@@ -136,6 +140,7 @@ local function updateStackSync()
|
||||
stackCtrl:Expand(callitem)
|
||||
end
|
||||
stackCtrl:EnsureVisible(stackCtrl:GetFirstChild(root))
|
||||
stackCtrl:SetScrollPos(wx.wxHORIZONTAL, 0, true)
|
||||
stackCtrl:Thaw()
|
||||
end
|
||||
end
|
||||
@@ -158,6 +163,28 @@ local function updateWatches(num)
|
||||
end
|
||||
end
|
||||
|
||||
local function debuggerToggleViews(show)
|
||||
local mgr = ide.frame.uimgr
|
||||
local refresh = false
|
||||
for view, needed in pairs(debugger.toggleview) do
|
||||
local pane = mgr:GetPane(view)
|
||||
if show then -- starting debugging and pane is not shown
|
||||
debugger.toggleview[view] = not pane:IsShown()
|
||||
if debugger.toggleview[view] and needed then
|
||||
pane:Show()
|
||||
refresh = true
|
||||
end
|
||||
else -- completing debugging and pane is shown
|
||||
debugger.toggleview[view] = pane:IsShown() and needed
|
||||
if debugger.toggleview[view] then
|
||||
pane:Hide()
|
||||
refresh = true
|
||||
end
|
||||
end
|
||||
end
|
||||
if refresh then mgr:Update() end
|
||||
end
|
||||
|
||||
local function killClient()
|
||||
if (debugger.pid) then
|
||||
-- using SIGTERM for some reason kills not only the debugee process,
|
||||
@@ -174,7 +201,7 @@ local function killClient()
|
||||
end
|
||||
end
|
||||
|
||||
local function activateDocument(file, line, skipauto)
|
||||
local function activateDocument(file, line, activatehow)
|
||||
if not file then return end
|
||||
|
||||
if not wx.wxIsAbsolutePath(file) and debugger.basedir then
|
||||
@@ -188,30 +215,56 @@ local function activateDocument(file, line, skipauto)
|
||||
-- skip those tabs that may have file without names (untitled.lua)
|
||||
if document.filePath and fileName:SameAs(wx.wxFileName(document.filePath)) then
|
||||
local editor = document.editor
|
||||
|
||||
ClearAllCurrentLineMarkers()
|
||||
if line then
|
||||
if line == 0 then -- special case; find the first executable line
|
||||
line = math.huge
|
||||
local func = loadstring(editor:GetText())
|
||||
if func then -- .activelines == {[3] = true, [4] = true, ...}
|
||||
for l in pairs(debug.getinfo(func, "L").activelines) do
|
||||
if l < line then line = l end
|
||||
end
|
||||
end
|
||||
if line == math.huge then line = 1 end
|
||||
end
|
||||
local line = line - 1 -- editor line operations are zero-based
|
||||
editor:MarkerAdd(line, CURRENT_LINE_MARKER)
|
||||
|
||||
-- found and marked what we are looking for;
|
||||
-- don't need to activate with CHECKONLY (this assumes line is given)
|
||||
if activatehow == activate.CHECKONLY then return editor end
|
||||
|
||||
local firstline = editor:DocLineFromVisible(editor:GetFirstVisibleLine())
|
||||
local lastline = math.min(editor:GetLineCount(),
|
||||
editor:DocLineFromVisible(editor:GetFirstVisibleLine() + editor:LinesOnScreen()))
|
||||
-- if the line is already on the screen, then don't enforce policy
|
||||
if line <= firstline or line >= lastline then
|
||||
editor:EnsureVisibleEnforcePolicy(line)
|
||||
end
|
||||
end
|
||||
|
||||
local selection = document.index
|
||||
RequestAttention()
|
||||
notebook:SetSelection(selection)
|
||||
SetEditorSelection(selection)
|
||||
ClearAllCurrentLineMarkers()
|
||||
if line then
|
||||
editor:MarkerAdd(line-1, CURRENT_LINE_MARKER)
|
||||
editor:EnsureVisibleEnforcePolicy(line-1)
|
||||
end
|
||||
|
||||
activated = editor
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not (activated or indebugger or debugger.loop or skipauto)
|
||||
if not (activated or indebugger or debugger.loop or activatehow == activate.CHECKONLY)
|
||||
and ide.config.editor.autoactivate then
|
||||
-- found file, but can't activate yet (because this part may be executed
|
||||
-- in a different co-routine), so schedule pending activation.
|
||||
-- in a different coroutine), so schedule pending activation.
|
||||
if wx.wxFileName(file):FileExists() then
|
||||
debugger.activate = {file, line}
|
||||
return true -- report successful activation, even though it's pending
|
||||
end
|
||||
|
||||
if not debugger.missing[file] then -- only report files once per session
|
||||
-- only report files once per session and if not asked to skip
|
||||
if not debugger.missing[file] and activatehow ~= activate.NOREPORT then
|
||||
debugger.missing[file] = true
|
||||
DisplayOutputLn(TR("Couldn't activate file '%s' for debugging; continuing without it.")
|
||||
:format(file))
|
||||
@@ -297,6 +350,16 @@ debugger.shell = function(expression, isstatement)
|
||||
end
|
||||
end
|
||||
|
||||
local function stoppedAtBreakpoint(file, line)
|
||||
-- if this document can be activated and the current line has a breakpoint
|
||||
local editor = activateDocument(file, line, activate.CHECKONLY)
|
||||
if not editor then return false end
|
||||
|
||||
local current = editor:MarkerNext(0, CURRENT_LINE_MARKER_VALUE)
|
||||
local breakpoint = editor:MarkerNext(current, BREAKPOINT_MARKER_VALUE)
|
||||
return breakpoint > -1 and breakpoint == current
|
||||
end
|
||||
|
||||
debugger.listen = function()
|
||||
local server = socket.bind("*", debugger.portnumber)
|
||||
DisplayOutputLn(TR("Debugger server started at %s:%d.")
|
||||
@@ -314,6 +377,10 @@ debugger.listen = function()
|
||||
end)
|
||||
|
||||
local options = debugger.options or {}
|
||||
-- this may be a remote call without using an interpreter and as such
|
||||
-- debugger.options may not be set, but runonstart is still configured.
|
||||
if not options.runstart then options.runstart = ide.config.debugger.runonstart end
|
||||
|
||||
if not debugger.scratchpad then SetAllEditorsReadOnly(true) end
|
||||
|
||||
debugger.server = copas.wrap(skt)
|
||||
@@ -378,6 +445,9 @@ debugger.listen = function()
|
||||
.." "..TR("Compilation error")
|
||||
..":\n"..err)
|
||||
return debugger.terminate()
|
||||
elseif options.runstart and stoppedAtBreakpoint(file, line) then
|
||||
activateDocument(file, line)
|
||||
options.runstart = false
|
||||
end
|
||||
elseif not (options.run or debugger.scratchpad) then
|
||||
local file, line, err = debugger.loadfile(startfile)
|
||||
@@ -391,13 +461,16 @@ debugger.listen = function()
|
||||
..":\n"..err)
|
||||
return debugger.terminate()
|
||||
elseif options.runstart then
|
||||
-- do nothing as no activation is required; the script will be run
|
||||
if stoppedAtBreakpoint(file or startfile, line or 0) then
|
||||
activateDocument(file or startfile, line or 0)
|
||||
options.runstart = false
|
||||
end
|
||||
elseif file and line then
|
||||
local activated = activateDocument(file, line, true)
|
||||
local activated = activateDocument(file, line, activate.NOREPORT)
|
||||
|
||||
-- if not found, check using full file path and reset basedir
|
||||
if not activated and not wx.wxIsAbsolutePath(file) then
|
||||
activated = activateDocument(startpath..file, line, true)
|
||||
activated = activateDocument(startpath..file, line, activate.NOREPORT)
|
||||
if activated then
|
||||
debugger.basedir = startpath
|
||||
debugger.handle("basedir " .. debugger.basedir)
|
||||
@@ -431,7 +504,7 @@ debugger.listen = function()
|
||||
end
|
||||
|
||||
-- if found a local mapping under basedir
|
||||
activated = longestpath and activateDocument(longestpath, line, true)
|
||||
activated = longestpath and activateDocument(longestpath, line, activate.NOREPORT)
|
||||
if activated then
|
||||
-- find remote basedir by removing the tail from remote file
|
||||
debugger.handle("basedir " .. debugger.basedir .. "\t" .. remotedir)
|
||||
@@ -453,7 +526,7 @@ debugger.listen = function()
|
||||
debugger.scratchable = ide.interpreter.scratchextloop ~= nil
|
||||
else
|
||||
debugger.scratchable = true
|
||||
activateDocument(startfile, 1)
|
||||
activateDocument(startfile, 0) -- find the appropriate line
|
||||
end
|
||||
end
|
||||
|
||||
@@ -461,6 +534,7 @@ debugger.listen = function()
|
||||
ShellSupportRemote(debugger.shell)
|
||||
end
|
||||
|
||||
debuggerToggleViews(true)
|
||||
updateStackSync()
|
||||
updateWatchesSync()
|
||||
|
||||
@@ -486,9 +560,7 @@ debugger.handle = function(command, server, options)
|
||||
local verbose = ide.config.debugger.verbose
|
||||
local osexit, gprint
|
||||
osexit, os.exit = os.exit, function () end
|
||||
if (verbose) then
|
||||
gprint, _G.print = _G.print, function (...) DisplayOutputLn(...) end
|
||||
end
|
||||
gprint, _G.print = _G.print, function (...) if verbose then DisplayOutputLn(...) end end
|
||||
|
||||
debugger.running = true
|
||||
if verbose then DisplayOutputLn("Debugger sent (command):", command) end
|
||||
@@ -497,7 +569,7 @@ debugger.handle = function(command, server, options)
|
||||
debugger.running = false
|
||||
|
||||
os.exit = osexit
|
||||
if (verbose) then _G.print = gprint end
|
||||
_G.print = gprint
|
||||
return file, line, err
|
||||
end
|
||||
|
||||
@@ -541,6 +613,7 @@ debugger.exec = function(command)
|
||||
if debugger.breaking then
|
||||
DisplayOutputLn(TR("Debugging suspended at %s:%s (couldn't activate the file).")
|
||||
:format(file, line))
|
||||
updateStackAndWatches()
|
||||
return
|
||||
end
|
||||
-- redo now; if the call is from the debugger, then repeat
|
||||
@@ -644,57 +717,6 @@ debugger.quickeval = function(var, callback)
|
||||
end
|
||||
end
|
||||
|
||||
----------------------------------------------
|
||||
-- public api
|
||||
|
||||
function DebuggerAttachDefault(options)
|
||||
debugger.options = options
|
||||
if (debugger.listening) then return end
|
||||
debugger.listen()
|
||||
end
|
||||
|
||||
function DebuggerShutdown()
|
||||
if debugger.server then debugger.terminate() end
|
||||
if debugger.pid then killClient() end
|
||||
-- wait for a little bit as in some rare cases when closing the debugger
|
||||
-- with a running application under OSX, the process crashes (wxlua2.8.12).
|
||||
if ide.osname == "Macintosh" then wx.wxMilliSleep(100) end
|
||||
end
|
||||
|
||||
function DebuggerStop()
|
||||
if (debugger.server) then
|
||||
debugger.server = nil
|
||||
debugger.pid = nil
|
||||
SetAllEditorsReadOnly(false)
|
||||
ShellSupportRemote(nil)
|
||||
ClearAllCurrentLineMarkers()
|
||||
DebuggerScratchpadOff()
|
||||
local lines = TR("traced %d instruction", debugger.stats.line):format(debugger.stats.line)
|
||||
DisplayOutputLn(TR("Debugging session completed (%s)."):format(lines))
|
||||
else
|
||||
-- it's possible that the application couldn't start, or that the
|
||||
-- debugger in the application didn't start, which means there is
|
||||
-- no debugger.server, but scratchpad may still be on. Turn it off.
|
||||
DebuggerScratchpadOff()
|
||||
end
|
||||
end
|
||||
|
||||
function DebuggerCloseStackWindow()
|
||||
if (debugger.stackWindow) then
|
||||
SettingsSaveFramePosition(debugger.stackWindow, "StackWindow")
|
||||
debugger.stackCtrl = nil
|
||||
debugger.stackWindow = nil
|
||||
end
|
||||
end
|
||||
|
||||
function DebuggerCloseWatchWindow()
|
||||
if (debugger.watchWindow) then
|
||||
SettingsSaveFramePosition(debugger.watchWindow, "WatchWindow")
|
||||
debugger.watchCtrl = nil
|
||||
debugger.watchWindow = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- need imglist to be a file local variable as SetImageList takes ownership
|
||||
-- of it and if done inside a function, icons do not work as expected
|
||||
local imglist = wx.wxImageList(16,16)
|
||||
@@ -709,34 +731,15 @@ do
|
||||
imglist:Add(getBitmap(wx.wxART_REPORT_VIEW, wx.wxART_OTHER, size))
|
||||
end
|
||||
|
||||
function DebuggerCreateStackWindow()
|
||||
if (debugger.stackWindow) then return updateStackAndWatches() end
|
||||
local width = 360
|
||||
local stackWindow = wx.wxFrame(ide.frame, wx.wxID_ANY,
|
||||
TR("Stack Window"),
|
||||
wx.wxDefaultPosition, wx.wxSize(width, 200),
|
||||
wx.wxDEFAULT_FRAME_STYLE + wx.wxFRAME_FLOAT_ON_PARENT)
|
||||
|
||||
debugger.stackWindow = stackWindow
|
||||
|
||||
local stackCtrl = wx.wxTreeCtrl(stackWindow, wx.wxID_ANY,
|
||||
wx.wxDefaultPosition, wx.wxDefaultSize,
|
||||
local width, height = 360, 200
|
||||
function debuggerCreateStackWindow()
|
||||
local stackCtrl = wx.wxTreeCtrl(ide.frame, wx.wxID_ANY,
|
||||
wx.wxDefaultPosition, wx.wxSize(width, height),
|
||||
wx.wxTR_LINES_AT_ROOT + wx.wxTR_HAS_BUTTONS + wx.wxTR_SINGLE + wx.wxTR_HIDE_ROOT)
|
||||
|
||||
debugger.stackCtrl = stackCtrl
|
||||
|
||||
stackCtrl:SetImageList(imglist)
|
||||
stackWindow:CentreOnParent()
|
||||
SettingsRestoreFramePosition(stackWindow, "StackWindow")
|
||||
stackWindow:Show(true)
|
||||
|
||||
stackWindow:Connect(wx.wxEVT_CLOSE_WINDOW,
|
||||
function (event)
|
||||
DebuggerCloseStackWindow()
|
||||
stackWindow = nil
|
||||
stackCtrl = nil
|
||||
event:Skip()
|
||||
end)
|
||||
|
||||
stackCtrl:Connect( wx.wxEVT_COMMAND_TREE_ITEM_EXPANDING,
|
||||
function (event)
|
||||
@@ -761,33 +764,24 @@ function DebuggerCreateStackWindow()
|
||||
stackCtrl:SortChildren(item_id)
|
||||
return true
|
||||
end)
|
||||
stackCtrl:Connect( wx.wxEVT_COMMAND_TREE_ITEM_COLLAPSED,
|
||||
function() return true end)
|
||||
|
||||
updateStackAndWatches()
|
||||
local notebook = wxaui.wxAuiNotebook(frame, wx.wxID_ANY,
|
||||
wx.wxDefaultPosition, wx.wxDefaultSize,
|
||||
wxaui.wxAUI_NB_DEFAULT_STYLE + wxaui.wxAUI_NB_TAB_EXTERNAL_MOVE
|
||||
- wxaui.wxAUI_NB_CLOSE_ON_ACTIVE_TAB + wx.wxNO_BORDER)
|
||||
notebook:AddPage(stackCtrl, TR("Stack"), true)
|
||||
|
||||
local mgr = ide.frame.uimgr
|
||||
mgr:AddPane(notebook, wxaui.wxAuiPaneInfo():
|
||||
Name("stackpanel"):Float():
|
||||
MinSize(width/2,height/2):
|
||||
BestSize(width,height):FloatingSize(width,height):
|
||||
PinButton(true):Hide())
|
||||
mgr.defaultPerspective = mgr:SavePerspective() -- resave default perspective
|
||||
end
|
||||
|
||||
function DebuggerCreateWatchWindow()
|
||||
if (debugger.watchWindow) then return updateWatches() end
|
||||
local width = 360
|
||||
local watchWindow = wx.wxFrame(ide.frame, wx.wxID_ANY,
|
||||
TR("Watch Window"),
|
||||
wx.wxDefaultPosition, wx.wxSize(width, 200),
|
||||
wx.wxDEFAULT_FRAME_STYLE + wx.wxFRAME_FLOAT_ON_PARENT)
|
||||
|
||||
debugger.watchWindow = watchWindow
|
||||
|
||||
local watchMenu = wx.wxMenu{
|
||||
{ ID_ADDWATCH, TR("&Add Watch")..KSC(ID_ADDWATCH) },
|
||||
{ ID_EDITWATCH, TR("&Edit Watch")..KSC(ID_EDITWATCH) },
|
||||
{ ID_REMOVEWATCH, TR("&Remove Watch")..KSC(ID_REMOVEWATCH) },
|
||||
{ ID_EVALUATEWATCH, TR("Evaluate &Watches")..KSC(ID_EVALUATEWATCH) }}
|
||||
|
||||
local watchMenuBar = wx.wxMenuBar()
|
||||
watchMenuBar:Append(watchMenu, TR("&Watches"))
|
||||
watchWindow:SetMenuBar(watchMenuBar)
|
||||
|
||||
local watchCtrl = wx.wxListCtrl(watchWindow, wx.wxID_ANY,
|
||||
local function debuggerCreateWatchWindow()
|
||||
local watchCtrl = wx.wxListCtrl(frame, wx.wxID_ANY,
|
||||
wx.wxDefaultPosition, wx.wxDefaultSize,
|
||||
wx.wxLC_REPORT + wx.wxLC_EDIT_LABELS)
|
||||
|
||||
@@ -803,9 +797,10 @@ function DebuggerCreateWatchWindow()
|
||||
info:SetWidth(width * 0.56)
|
||||
watchCtrl:InsertColumn(1, info)
|
||||
|
||||
watchWindow:CentreOnParent()
|
||||
SettingsRestoreFramePosition(watchWindow, "WatchWindow")
|
||||
watchWindow:Show(true)
|
||||
local watchMenu = wx.wxMenu{
|
||||
{ ID_ADDWATCH, TR("&Add Watch")..KSC(ID_ADDWATCH) },
|
||||
{ ID_EDITWATCH, TR("&Edit Watch")..KSC(ID_EDITWATCH) },
|
||||
{ ID_DELETEWATCH, TR("&Delete Watch")..KSC(ID_DELETEWATCH) }}
|
||||
|
||||
local function findSelectedWatchItem()
|
||||
local count = watchCtrl:GetSelectedItemCount()
|
||||
@@ -820,53 +815,47 @@ function DebuggerCreateWatchWindow()
|
||||
end
|
||||
|
||||
local defaultExpr = ""
|
||||
local function addWatch()
|
||||
local row = watchCtrl:InsertItem(watchCtrl:GetItemCount(), TR("Expr"))
|
||||
watchCtrl:SetItem(row, 0, defaultExpr)
|
||||
watchCtrl:SetItem(row, 1, TR("Value"))
|
||||
watchCtrl:EditLabel(row)
|
||||
end
|
||||
|
||||
watchWindow:Connect(wx.wxEVT_CLOSE_WINDOW,
|
||||
local function editWatch()
|
||||
local row = findSelectedWatchItem()
|
||||
if row >= 0 then watchCtrl:EditLabel(row) end
|
||||
end
|
||||
|
||||
local function deleteWatch()
|
||||
local row = findSelectedWatchItem()
|
||||
if row >= 0 then watchCtrl:DeleteItem(row) end
|
||||
end
|
||||
|
||||
watchCtrl:Connect(wx.wxEVT_CONTEXT_MENU,
|
||||
function (event)
|
||||
DebuggerCloseWatchWindow()
|
||||
watchWindow = nil
|
||||
watchCtrl = nil
|
||||
watchCtrl:PopupMenu(watchMenu)
|
||||
end)
|
||||
|
||||
watchCtrl:Connect(wx.wxEVT_KEY_DOWN,
|
||||
function (event)
|
||||
local keycode = event:GetKeyCode()
|
||||
if (keycode == wx.WXK_DELETE) then return deleteWatch()
|
||||
elseif (keycode == wx.WXK_INSERT) then return addWatch()
|
||||
elseif (keycode == wx.WXK_F2) then return editWatch()
|
||||
end
|
||||
event:Skip()
|
||||
end)
|
||||
|
||||
watchWindow:Connect(ID_ADDWATCH, wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function ()
|
||||
local row = watchCtrl:InsertItem(watchCtrl:GetItemCount(), TR("Expr"))
|
||||
watchCtrl:SetItem(row, 0, defaultExpr)
|
||||
watchCtrl:SetItem(row, 1, TR("Value"))
|
||||
watchCtrl:EditLabel(row)
|
||||
end)
|
||||
watchCtrl:Connect(ID_ADDWATCH, wx.wxEVT_COMMAND_MENU_SELECTED, addWatch)
|
||||
|
||||
watchWindow:Connect(ID_EDITWATCH, wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function ()
|
||||
local row = findSelectedWatchItem()
|
||||
if row >= 0 then
|
||||
watchCtrl:EditLabel(row)
|
||||
end
|
||||
end)
|
||||
watchWindow:Connect(ID_EDITWATCH, wx.wxEVT_UPDATE_UI,
|
||||
function (event)
|
||||
event:Enable(watchCtrl:GetSelectedItemCount() > 0)
|
||||
end)
|
||||
watchCtrl:Connect(ID_EDITWATCH, wx.wxEVT_COMMAND_MENU_SELECTED, editWatch)
|
||||
watchCtrl:Connect(ID_EDITWATCH, wx.wxEVT_UPDATE_UI,
|
||||
function (event) event:Enable(watchCtrl:GetSelectedItemCount() > 0) end)
|
||||
|
||||
watchWindow:Connect(ID_REMOVEWATCH, wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function ()
|
||||
local row = findSelectedWatchItem()
|
||||
if row >= 0 then
|
||||
watchCtrl:DeleteItem(row)
|
||||
end
|
||||
end)
|
||||
watchWindow:Connect(ID_REMOVEWATCH, wx.wxEVT_UPDATE_UI,
|
||||
function (event)
|
||||
event:Enable(watchCtrl:GetSelectedItemCount() > 0)
|
||||
end)
|
||||
|
||||
watchWindow:Connect(ID_EVALUATEWATCH, wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function () updateWatches() end)
|
||||
watchWindow:Connect(ID_EVALUATEWATCH, wx.wxEVT_UPDATE_UI,
|
||||
function (event)
|
||||
event:Enable(watchCtrl:GetItemCount() > 0)
|
||||
end)
|
||||
watchCtrl:Connect(ID_DELETEWATCH, wx.wxEVT_COMMAND_MENU_SELECTED, deleteWatch)
|
||||
watchCtrl:Connect(ID_DELETEWATCH, wx.wxEVT_UPDATE_UI,
|
||||
function (event) event:Enable(watchCtrl:GetSelectedItemCount() > 0) end)
|
||||
|
||||
watchCtrl:Connect(wx.wxEVT_COMMAND_LIST_END_LABEL_EDIT,
|
||||
function (event)
|
||||
@@ -881,10 +870,37 @@ function DebuggerCreateWatchWindow()
|
||||
end
|
||||
event:Skip()
|
||||
end)
|
||||
|
||||
local notebook = wxaui.wxAuiNotebook(frame, wx.wxID_ANY,
|
||||
wx.wxDefaultPosition, wx.wxDefaultSize,
|
||||
wxaui.wxAUI_NB_DEFAULT_STYLE + wxaui.wxAUI_NB_TAB_EXTERNAL_MOVE
|
||||
- wxaui.wxAUI_NB_CLOSE_ON_ACTIVE_TAB + wx.wxNO_BORDER)
|
||||
notebook:AddPage(watchCtrl, TR("Watch"), true)
|
||||
|
||||
local mgr = ide.frame.uimgr
|
||||
mgr:AddPane(notebook, wxaui.wxAuiPaneInfo():
|
||||
Name("watchpanel"):Float():
|
||||
MinSize(width/2,height/2):
|
||||
BestSize(width,height):FloatingSize(width,height):
|
||||
PinButton(true):Hide())
|
||||
mgr.defaultPerspective = mgr:SavePerspective() -- resave default perspective
|
||||
end
|
||||
|
||||
debuggerCreateStackWindow()
|
||||
debuggerCreateWatchWindow()
|
||||
|
||||
----------------------------------------------
|
||||
-- public api
|
||||
|
||||
DebuggerRefreshPanels = updateStackAndWatches
|
||||
|
||||
function DebuggerAddWatch(watch)
|
||||
if (not debugger.watchWindow) then DebuggerCreateWatchWindow() end
|
||||
local mgr = ide.frame.uimgr
|
||||
local pane = mgr:GetPane("watchpanel")
|
||||
if (not pane:IsShown()) then
|
||||
pane:Show()
|
||||
mgr:Update()
|
||||
end
|
||||
|
||||
local watchCtrl = debugger.watchCtrl
|
||||
-- check if this expression is already on the list
|
||||
@@ -899,6 +915,36 @@ function DebuggerAddWatch(watch)
|
||||
updateWatches(row)
|
||||
end
|
||||
|
||||
function DebuggerAttachDefault(options)
|
||||
debugger.options = options
|
||||
if (debugger.listening) then return end
|
||||
debugger.listen()
|
||||
end
|
||||
|
||||
function DebuggerShutdown()
|
||||
if debugger.server then debugger.terminate() end
|
||||
if debugger.pid then killClient() end
|
||||
end
|
||||
|
||||
function DebuggerStop()
|
||||
if (debugger.server) then
|
||||
debugger.server = nil
|
||||
debugger.pid = nil
|
||||
SetAllEditorsReadOnly(false)
|
||||
ShellSupportRemote(nil)
|
||||
ClearAllCurrentLineMarkers()
|
||||
DebuggerScratchpadOff()
|
||||
debuggerToggleViews(false)
|
||||
local lines = TR("traced %d instruction", debugger.stats.line):format(debugger.stats.line)
|
||||
DisplayOutputLn(TR("Debugging session completed (%s)."):format(lines))
|
||||
else
|
||||
-- it's possible that the application couldn't start, or that the
|
||||
-- debugger in the application didn't start, which means there is
|
||||
-- no debugger.server, but scratchpad may still be on. Turn it off.
|
||||
DebuggerScratchpadOff()
|
||||
end
|
||||
end
|
||||
|
||||
function DebuggerMakeFileName(editor, filePath)
|
||||
return filePath or ide.config.default.fullname
|
||||
end
|
||||
|
||||
@@ -17,8 +17,7 @@ local projcombobox = ide.frame.projpanel.projcombobox
|
||||
-- Only update if the text has changed.
|
||||
local statusTextTable = { "OVR?", "R/O?", "Cursor Pos" }
|
||||
|
||||
-- set funclist font to be the same as the combobox in the project dropdown
|
||||
funclist:SetFont(ide.font.fNormal)
|
||||
funclist:SetFont(ide.font.dNormal)
|
||||
|
||||
local function updateStatusText(editor)
|
||||
local texts = { "", "", "" }
|
||||
@@ -151,6 +150,7 @@ function SetEditorSelection(selection)
|
||||
editor:SetSTCFocus(true)
|
||||
local id = editor:GetId()
|
||||
FileTreeMarkSelected(openDocuments[id] and openDocuments[id].filePath or '')
|
||||
AddToFileHistory(openDocuments[id] and openDocuments[id].filePath)
|
||||
else
|
||||
FileTreeMarkSelected('')
|
||||
end
|
||||
@@ -212,7 +212,12 @@ function EditorAutoComplete(editor)
|
||||
|
||||
local lt = linetx:sub(1,localpos)
|
||||
lt = lt:gsub("%s*(["..editor.spec.sep.."])%s*", "%1")
|
||||
lt = lt:match("[^%[%(%s]*$")
|
||||
-- strip closed brace scopes
|
||||
lt = lt:gsub("%b()","")
|
||||
lt = lt:gsub("%b[]","")
|
||||
lt = lt:gsub("%b{}","")
|
||||
-- match from starting brace
|
||||
lt = lt:match("[^%[%(%{%s]*$")
|
||||
|
||||
-- know now which string is to be completed
|
||||
local userList = CreateAutoCompList(editor,lt)
|
||||
@@ -348,7 +353,7 @@ function CreateEditor()
|
||||
|
||||
editor:SetCaretLineVisible(ide.config.editor.caretline and 1 or 0)
|
||||
|
||||
editor:SetVisiblePolicy(wxstc.wxSTC_VISIBLE_SLOP, 3)
|
||||
editor:SetVisiblePolicy(wxstc.wxSTC_VISIBLE_STRICT, 3)
|
||||
|
||||
editor:SetMarginWidth(0, editor:TextWidth(32, "99999_")) -- line # margin
|
||||
|
||||
@@ -367,9 +372,12 @@ function CreateEditor()
|
||||
editor:SetFoldFlags(wxstc.wxSTC_FOLDFLAG_LINEBEFORE_CONTRACTED +
|
||||
wxstc.wxSTC_FOLDFLAG_LINEAFTER_CONTRACTED)
|
||||
|
||||
editor:SetProperty("fold", "1")
|
||||
editor:SetProperty("fold.compact", ide.config.editor.foldcompact and "1" or "0")
|
||||
editor:SetProperty("fold.comment", "1")
|
||||
-- allow multiple selection and multi-cursor editing if supported
|
||||
if ide.wxver >= "2.9.5" then
|
||||
editor:SetMultipleSelection(1)
|
||||
editor:SetAdditionalCaretsBlink(1)
|
||||
editor:SetAdditionalSelectionTyping(1)
|
||||
end
|
||||
|
||||
do
|
||||
local fg, bg = wx.wxWHITE, wx.wxColour(128, 128, 128)
|
||||
@@ -393,6 +401,34 @@ function CreateEditor()
|
||||
editor:AutoCompStops([[ \n\t=-+():.,;*/!"'$%&~'#°^@?´`<>][|}{]])
|
||||
end
|
||||
|
||||
-- GotoPos should work by itself, but it doesn't (wx 2.9.5).
|
||||
-- This is likely because the editor window hasn't been refreshed yet,
|
||||
-- so its LinesOnScreen method returns 0/-1, which skews the calculations.
|
||||
-- To avoid this, the caret line is made visible at the first opportunity.
|
||||
do
|
||||
local redolater
|
||||
function editor:GotoPosDelayed(pos)
|
||||
local badtime = self:LinesOnScreen() <= 0 -- -1 on OSX, 0 on Windows
|
||||
if pos then
|
||||
if badtime then
|
||||
redolater = pos
|
||||
-- without this GotoPos the content is not scrolled correctly on
|
||||
-- Windows, but with this it's not scrolled correctly on OSX.
|
||||
if ide.osname ~= 'Macintosh' then self:GotoPos(pos) end
|
||||
else
|
||||
redolater = nil
|
||||
self:GotoPos(pos)
|
||||
end
|
||||
elseif not badtime and redolater then
|
||||
-- reset the left margin first to make sure that the position
|
||||
-- is set "from the left" to get the best content displayed.
|
||||
self:SetXOffset(0)
|
||||
self:GotoPos(redolater)
|
||||
redolater = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
editor.ev = {}
|
||||
editor:Connect(wxstc.wxEVT_STC_MARGINCLICK,
|
||||
function (event)
|
||||
@@ -414,17 +450,17 @@ function CreateEditor()
|
||||
|
||||
editor:Connect(wxstc.wxEVT_STC_MODIFIED,
|
||||
function (event)
|
||||
SetAutoRecoveryMark()
|
||||
|
||||
if (editor.assignscache and editor:GetCurrentLine() ~= editor.assignscache.line) then
|
||||
editor.assignscache = false
|
||||
end
|
||||
local evtype = event:GetModificationType()
|
||||
if (bit.band(evtype,wxstc.wxSTC_MOD_INSERTTEXT) ~= 0) then
|
||||
SetAutoRecoveryMark()
|
||||
table.insert(editor.ev,{event:GetPosition(),event:GetLinesAdded()})
|
||||
DynamicWordsAdd("post",editor,nil,editor:LineFromPosition(event:GetPosition()),event:GetLinesAdded())
|
||||
end
|
||||
if (bit.band(evtype,wxstc.wxSTC_MOD_DELETETEXT) ~= 0) then
|
||||
SetAutoRecoveryMark()
|
||||
table.insert(editor.ev,{event:GetPosition(),0})
|
||||
DynamicWordsAdd("post",editor,nil,editor:LineFromPosition(event:GetPosition()),0)
|
||||
end
|
||||
@@ -565,16 +601,33 @@ function CreateEditor()
|
||||
SetDocumentModified(editor:GetId(), true)
|
||||
end)
|
||||
|
||||
-- "updateStatusText" should be called in UPDATEUI event, but it creates
|
||||
-- several performance problems on Windows (using wx2.9.5+) when
|
||||
-- brackets or backspace is used (very slow screen repaint with 0.5s delay).
|
||||
-- Moving it to PAINTED event creates problems on OSX (using wx2.9.5+),
|
||||
-- where refresh of R/W and R/O status in the status bar is delayed.
|
||||
|
||||
editor:Connect(wxstc.wxEVT_STC_PAINTED,
|
||||
function ()
|
||||
if ide.osname == 'Windows' then updateStatusText(editor) end
|
||||
end)
|
||||
|
||||
editor:Connect(wxstc.wxEVT_STC_UPDATEUI,
|
||||
function ()
|
||||
updateStatusText(editor)
|
||||
if ide.osname ~= 'Windows' then updateStatusText(editor) end
|
||||
|
||||
editor:GotoPosDelayed()
|
||||
updateBraceMatch(editor)
|
||||
local minupdated
|
||||
for _,iv in ipairs(editor.ev) do
|
||||
local line = editor:LineFromPosition(iv[1])
|
||||
if not minupdated or line < minupdated then minupdated = line end
|
||||
IndicateFunctions(editor,line,line+iv[2])
|
||||
if MarkupStyle then MarkupStyle(editor,line,line+iv[2]+1) end
|
||||
end
|
||||
if MarkupStyleRefresh then MarkupStyleRefresh(editor, editor.ev) end
|
||||
local firstline = editor:DocLineFromVisible(editor:GetFirstVisibleLine())
|
||||
local lastline = math.min(editor:GetLineCount(),
|
||||
editor:DocLineFromVisible(editor:GetFirstVisibleLine() + editor:LinesOnScreen()))
|
||||
MarkupStyle(editor,minupdated or firstline,lastline)
|
||||
editor.ev = {}
|
||||
end)
|
||||
|
||||
@@ -589,6 +642,16 @@ function CreateEditor()
|
||||
event:Skip()
|
||||
end)
|
||||
|
||||
if ide.config.editor.nomousezoom then
|
||||
-- disable zoom using mouse wheel as it triggers zooming when scrolling
|
||||
-- on OSX with kinetic scroll and then pressing CMD.
|
||||
editor:Connect(wx.wxEVT_MOUSEWHEEL,
|
||||
function (event)
|
||||
if wx.wxGetKeyState(wx.WXK_CONTROL) then return end
|
||||
event:Skip()
|
||||
end)
|
||||
end
|
||||
|
||||
local inhandler = false
|
||||
editor:Connect(wx.wxEVT_SET_FOCUS,
|
||||
function (event)
|
||||
@@ -602,23 +665,30 @@ function CreateEditor()
|
||||
editor:Connect(wx.wxEVT_KEY_DOWN,
|
||||
function (event)
|
||||
local keycode = event:GetKeyCode()
|
||||
local mod = event:GetModifiers()
|
||||
local first, last = 0, notebook:GetPageCount()-1
|
||||
if keycode == wx.WXK_ESCAPE and frame:IsFullScreen() then
|
||||
ShowFullScreen(false)
|
||||
elseif event:ControlDown() and
|
||||
(keycode == wx.WXK_PAGEUP or keycode == wx.WXK_TAB and event:ShiftDown()) then
|
||||
-- Ctrl-Home and Ctrl-End don't work on OSX with 2.9.5+; fix it
|
||||
elseif ide.osname == 'Macintosh' and ide.wxver >= "2.9.5"
|
||||
and (mod == wx.wxMOD_RAW_CONTROL or mod == (wx.wxMOD_RAW_CONTROL + wx.wxMOD_SHIFT))
|
||||
and (keycode == wx.WXK_HOME or keycode == wx.WXK_END) then
|
||||
local pos = keycode == wx.WXK_HOME and 0 or editor:GetLength()
|
||||
if event:ShiftDown() -- mark selection and scroll to caret
|
||||
then editor:SetCurrentPos(pos) editor:EnsureCaretVisible()
|
||||
else editor:GotoPos(pos) end
|
||||
elseif mod == wx.wxMOD_RAW_CONTROL and keycode == wx.WXK_PAGEUP
|
||||
or mod == (wx.wxMOD_RAW_CONTROL + wx.wxMOD_SHIFT) and keycode == wx.WXK_TAB then
|
||||
if notebook:GetSelection() == first
|
||||
then notebook:SetSelection(last)
|
||||
else notebook:AdvanceSelection(false) end
|
||||
elseif event:ControlDown() and
|
||||
(keycode == wx.WXK_PAGEDOWN or keycode == wx.WXK_TAB) then
|
||||
elseif mod == wx.wxMOD_RAW_CONTROL
|
||||
and (keycode == wx.WXK_PAGEDOWN or keycode == wx.WXK_TAB) then
|
||||
if notebook:GetSelection() == last
|
||||
then notebook:SetSelection(first)
|
||||
else notebook:AdvanceSelection(true) end
|
||||
elseif (keycode == wx.WXK_DELETE or keycode == wx.WXK_BACK)
|
||||
-- ide.osname == 'Macintosh' has wx.wxMOD_NONE not defined
|
||||
-- for some reason (at least in wxlua 2.8.12.1)
|
||||
and (event:GetModifiers() == (wx.wxMOD_NONE or 0)) then
|
||||
and (mod == wx.wxMOD_NONE) then
|
||||
-- Delete and Backspace behave the same way for selected text
|
||||
if #(editor:GetSelectedText()) > 0 then
|
||||
editor:SetTargetStart(editor:GetSelectionStart())
|
||||
@@ -644,8 +714,12 @@ function CreateEditor()
|
||||
editor:SetTargetEnd(pos+1)
|
||||
end
|
||||
editor:ReplaceTarget("")
|
||||
elseif ide.osname == "Unix" and ide.wxver >= "2.9.5"
|
||||
and keycode == ('T'):byte() and mod == wx.wxMOD_CONTROL then
|
||||
ide.frame:AddPendingEvent(wx.wxCommandEvent(
|
||||
wx.wxEVT_COMMAND_MENU_SELECTED, ID_SHOWTOOLTIP))
|
||||
else
|
||||
if ide.osname == 'Macintosh' and event:CmdDown() then
|
||||
if ide.osname == 'Macintosh' and mod == wx.wxMOD_META then
|
||||
return -- ignore a key press if Command key is also pressed
|
||||
end
|
||||
event:Skip()
|
||||
@@ -702,7 +776,7 @@ function AddEditor(editor, name)
|
||||
local id = editor:GetId()
|
||||
local document = {}
|
||||
document.editor = editor
|
||||
document.index = notebook:GetSelection()
|
||||
document.index = notebook:GetPageIndex(editor)
|
||||
document.fileName = nil
|
||||
document.filePath = nil
|
||||
document.modTime = nil
|
||||
@@ -825,6 +899,17 @@ function SetupKeywords(editor, ext, forcespec, styles, font, fontitalic)
|
||||
editor.spec = ide.specs.none
|
||||
end
|
||||
|
||||
-- need to set folding property after lexer is set, otherwise
|
||||
-- the folds are not shown (wxwidgets 2.9.5)
|
||||
editor:SetProperty("fold", "1")
|
||||
editor:SetProperty("fold.compact", ide.config.editor.foldcompact and "1" or "0")
|
||||
editor:SetProperty("fold.comment", "1")
|
||||
|
||||
-- quickfix to prevent weird looks, otherwise need to update styling mechanism for cpp
|
||||
-- cpp "greyed out" styles are styleid + 64
|
||||
editor:SetProperty("lexer.cpp.track.preprocessor", "0")
|
||||
editor:SetProperty("lexer.cpp.update.preprocessor", "0")
|
||||
|
||||
StylesApplyToEditor(styles or ide.config.styles, editor,
|
||||
font or ide.font.eNormal,fontitalic or ide.font.eItalic,lexerstyleconvert)
|
||||
end
|
||||
@@ -832,42 +917,50 @@ end
|
||||
----------------------------------------------------
|
||||
-- function list for current file
|
||||
|
||||
-- wx.wxEVT_SET_FOCUS is not triggered for wxChoice on Mac (wx 2.8.12),
|
||||
-- so use wx.wxEVT_LEFT_DOWN instead
|
||||
funclist:Connect(ide.osname == 'Macintosh' and wx.wxEVT_LEFT_DOWN or wx.wxEVT_SET_FOCUS,
|
||||
function (event)
|
||||
event:Skip()
|
||||
local function refreshFunctionList(event)
|
||||
event:Skip()
|
||||
|
||||
local editor = GetEditor()
|
||||
if (editor and not (editor.spec and editor.spec.isfndef)) then return end
|
||||
local editor = GetEditor()
|
||||
if (editor and not (editor.spec and editor.spec.isfndef)) then return end
|
||||
|
||||
-- parse current file and update list
|
||||
-- first populate with the current label to minimize flicker
|
||||
-- then populate the list and update the label
|
||||
local current = funclist:GetCurrentSelection()
|
||||
local label = funclist:GetString(current)
|
||||
local default = funclist:GetString(0)
|
||||
funclist:Clear()
|
||||
funclist:Append(current ~= wx.wxNOT_FOUND and label or default, 0)
|
||||
funclist:SetSelection(0)
|
||||
-- parse current file and update list
|
||||
-- first populate with the current label to minimize flicker
|
||||
-- then populate the list and update the label
|
||||
local current = funclist:GetCurrentSelection()
|
||||
local label = funclist:GetString(current)
|
||||
local default = funclist:GetString(0)
|
||||
funclist:Clear()
|
||||
funclist:Append(current ~= wx.wxNOT_FOUND and label or default, 0)
|
||||
funclist:SetSelection(0)
|
||||
|
||||
local lines = 0
|
||||
local linee = (editor and editor:GetLineCount() or 0)-1
|
||||
for line=lines,linee do
|
||||
local tx = editor:GetLine(line)
|
||||
local s,_,cap,l = editor.spec.isfndef(tx)
|
||||
if (s) then
|
||||
local ls = editor:PositionFromLine(line)
|
||||
local style = bit.band(editor:GetStyleAt(ls+s),31)
|
||||
if not (editor.spec.iscomment[style] or editor.spec.isstring[style]) then
|
||||
funclist:Append((l and " " or "")..cap,line)
|
||||
end
|
||||
local lines = 0
|
||||
local linee = (editor and editor:GetLineCount() or 0)-1
|
||||
for line=lines,linee do
|
||||
local tx = editor:GetLine(line)
|
||||
local s,_,cap,l = editor.spec.isfndef(tx)
|
||||
if (s) then
|
||||
local ls = editor:PositionFromLine(line)
|
||||
local style = bit.band(editor:GetStyleAt(ls+s),31)
|
||||
if not (editor.spec.iscomment[style] or editor.spec.isstring[style]) then
|
||||
funclist:Append((l and " " or "")..cap,line)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
funclist:SetString(0, default)
|
||||
funclist:SetSelection(current ~= wx.wxNOT_FOUND and current or 0)
|
||||
end)
|
||||
funclist:SetString(0, default)
|
||||
funclist:SetSelection(current ~= wx.wxNOT_FOUND and current or 0)
|
||||
end
|
||||
|
||||
-- wx.wxEVT_SET_FOCUS is not triggered for wxChoice on Mac (wx 2.8.12),
|
||||
-- so use wx.wxEVT_LEFT_DOWN instead; none of the events are triggered for
|
||||
-- wxChoice on Linux (wx 2.9.5+), so use EVT_ENTER_WINDOW attached to the
|
||||
-- toolbar itself until something better is available.
|
||||
if ide.osname == 'Unix' then
|
||||
ide.frame.toolBar:Connect(wx.wxEVT_ENTER_WINDOW, refreshFunctionList)
|
||||
else
|
||||
local event = ide.osname == 'Macintosh' and wx.wxEVT_LEFT_DOWN or wx.wxEVT_SET_FOCUS
|
||||
funclist:Connect(event, refreshFunctionList)
|
||||
end
|
||||
|
||||
funclist:Connect(wx.wxEVT_COMMAND_CHOICE_SELECTED,
|
||||
function (event)
|
||||
|
||||
@@ -26,9 +26,13 @@ ide.filetree = {
|
||||
}
|
||||
local filetree = ide.filetree
|
||||
|
||||
local iscaseinsensitive = wx.wxFileName("A"):SameAs(wx.wxFileName("a"))
|
||||
|
||||
-- generic tree
|
||||
-- ------------
|
||||
|
||||
local IMG_DIRECTORY, IMG_FILE_KNOWN, IMG_FILE_OTHER = 0, 1, 2
|
||||
|
||||
do
|
||||
local getBitmap = (ide.app.createbitmap or wx.wxArtProvider.GetBitmap)
|
||||
local size = wx.wxSize(16, 16)
|
||||
@@ -37,51 +41,25 @@ do
|
||||
filetree.imglist:Add(getBitmap(wx.wxART_FOLDER, wx.wxART_OTHER, size))
|
||||
-- 1 = file known spec
|
||||
filetree.imglist:Add(getBitmap(wx.wxART_HELP_PAGE, wx.wxART_OTHER, size))
|
||||
-- 2 = file rest
|
||||
-- 2 = file other
|
||||
filetree.imglist:Add(getBitmap(wx.wxART_NORMAL_FILE, wx.wxART_OTHER, size))
|
||||
end
|
||||
|
||||
local function treeAddDir(tree,parent_id,rootdir)
|
||||
local item, cookie = tree:GetFirstChild(parent_id)
|
||||
local items = {}
|
||||
while true do
|
||||
if not item:IsOk() then break end
|
||||
local item, cookie = tree:GetFirstChild(parent_id)
|
||||
while item:IsOk() do
|
||||
items[tree:GetItemText(item) .. tree:GetItemImage(item)] = item
|
||||
item, cookie = tree:GetNextChild(parent_id, cookie)
|
||||
end
|
||||
|
||||
local cache = {}
|
||||
local curr
|
||||
local search = rootdir..string_Pathsep.."*"
|
||||
|
||||
-- append directories
|
||||
for _,dir in ipairs(FileSysGet(search,wx.wxDIR)) do
|
||||
local name = dir:match("("..stringset_File.."+)$")
|
||||
local icon = 0
|
||||
local item = items[name .. icon]
|
||||
if item then -- existing item
|
||||
-- keep deleting items until we find item
|
||||
while true do
|
||||
local next = curr and tree:GetNextSibling(curr)
|
||||
or tree:GetFirstChild(parent_id)
|
||||
if not next:IsOk() or name == tree:GetItemText(next) then
|
||||
curr = next
|
||||
break
|
||||
end
|
||||
tree:Delete(next)
|
||||
end
|
||||
else -- new item
|
||||
local dir_id = curr and tree:InsertItem(parent_id, curr, name, icon)
|
||||
or tree:PrependItem(parent_id, name, icon)
|
||||
tree:SetItemHasChildren(dir_id,FileSysHasContent(dir))
|
||||
curr = dir_id
|
||||
end
|
||||
end
|
||||
|
||||
-- then append files
|
||||
for _,file in ipairs(FileSysGet(search,wx.wxFILE)) do
|
||||
local name = file:match("("..stringset_File.."+)$")
|
||||
for _, file in ipairs(FileSysGetRecursive(rootdir)) do
|
||||
local name, dir = file:match("("..stringset_File.."+)("..string_Pathsep.."?)$")
|
||||
local known = GetSpec(GetFileExt(name))
|
||||
local icon = known and 1 or 2
|
||||
local icon = #dir>0 and IMG_DIRECTORY or known and IMG_FILE_KNOWN or IMG_FILE_OTHER
|
||||
local item = items[name .. icon]
|
||||
if item then -- existing item
|
||||
-- keep deleting items until we find item
|
||||
@@ -97,7 +75,9 @@ local function treeAddDir(tree,parent_id,rootdir)
|
||||
else -- new item
|
||||
curr = curr and tree:InsertItem(parent_id, curr, name, icon)
|
||||
or tree:PrependItem(parent_id, name, icon)
|
||||
if #dir>0 then tree:SetItemHasChildren(curr, FileSysHasContent(file)) end
|
||||
end
|
||||
if curr:IsOk() then cache[iscaseinsensitive and name:lower() or name] = curr end
|
||||
end
|
||||
|
||||
-- delete any leftovers (something that exists in the tree, but not on disk)
|
||||
@@ -108,6 +88,11 @@ local function treeAddDir(tree,parent_id,rootdir)
|
||||
tree:Delete(next)
|
||||
end
|
||||
|
||||
-- cache the mapping from names to tree items
|
||||
local data = wx.wxLuaTreeItemData()
|
||||
data:SetData(cache)
|
||||
tree:SetItemData(parent_id, data)
|
||||
|
||||
tree:SetItemHasChildren(parent_id,
|
||||
tree:GetChildrenCount(parent_id, false) > 0)
|
||||
end
|
||||
@@ -118,10 +103,11 @@ local function treeGetItemFullName(tree,treedata,item_id)
|
||||
|
||||
while (#cur > 0) do
|
||||
item_id = tree:GetItemParent(item_id)
|
||||
if not item_id:IsOk() then break end
|
||||
cur = tree:GetItemText(item_id)
|
||||
if cur and string.len(cur) > 0 then str = cur..string_Pathsep..str end
|
||||
end
|
||||
-- as root may already include path separate, normalize the path
|
||||
-- as root may already include path separator, normalize the path
|
||||
local fullPath = wx.wxFileName(
|
||||
filetree.showroot and str or filetree.projdata.rootdir .. str)
|
||||
fullPath:Normalize()
|
||||
@@ -135,25 +121,34 @@ local function treeSetRoot(tree,treedata,rootdir)
|
||||
return
|
||||
end
|
||||
|
||||
local root_id = tree:AddRoot(rootdir,0)
|
||||
local root_id = tree:AddRoot(rootdir, IMG_DIRECTORY)
|
||||
treedata.root_id = root_id
|
||||
treedata.rootdir = rootdir
|
||||
|
||||
treeAddDir(tree,root_id,rootdir)
|
||||
filetree.newfiledir = rootdir
|
||||
|
||||
tree:Expand(root_id)
|
||||
-- make sure that the item can expand
|
||||
tree:SetItemHasChildren(root_id, true)
|
||||
tree:Expand(root_id) -- this will also populate the tree
|
||||
end
|
||||
|
||||
local function treeSetConnectorsAndIcons(tree,treedata)
|
||||
tree:SetImageList(filetree.imglist)
|
||||
|
||||
local function refreshAncestors(node)
|
||||
while node:IsOk() do
|
||||
local dir = treeGetItemFullName(tree,treedata,node)
|
||||
treeAddDir(tree,node,dir)
|
||||
node = tree:GetItemParent(node)
|
||||
end
|
||||
end
|
||||
|
||||
-- connect to some events from the wxTreeCtrl
|
||||
tree:Connect( wx.wxEVT_COMMAND_TREE_ITEM_EXPANDING,
|
||||
function( event )
|
||||
local item_id = event:GetItem()
|
||||
local dir = treeGetItemFullName(tree,treedata,item_id)
|
||||
treeAddDir(tree,item_id,dir)
|
||||
|
||||
if wx.wxDirExists(dir) then treeAddDir(tree,item_id,dir) -- refresh folder
|
||||
else refreshAncestors(tree:GetItemParent(item_id)) end -- stale content
|
||||
return true
|
||||
end)
|
||||
tree:Connect( wx.wxEVT_COMMAND_TREE_ITEM_COLLAPSED,
|
||||
@@ -161,21 +156,14 @@ local function treeSetConnectorsAndIcons(tree,treedata)
|
||||
tree:Connect( wx.wxEVT_COMMAND_TREE_ITEM_ACTIVATED,
|
||||
function( event )
|
||||
local item_id = event:GetItem()
|
||||
|
||||
local name = treeGetItemFullName(tree,treedata,item_id)
|
||||
-- refresh the folder
|
||||
if (tree:GetItemImage(item_id) == 0) then
|
||||
if wx.wxFileName(name):DirExists() then
|
||||
treeAddDir(tree,item_id,name) -- refresh the content
|
||||
else -- stale filetree information; rescan
|
||||
treeAddDir(tree,tree:GetItemParent(item_id),name)
|
||||
end
|
||||
if (tree:GetItemImage(item_id) == IMG_DIRECTORY) then
|
||||
if wx.wxDirExists(name) then treeAddDir(tree,item_id,name)
|
||||
else refreshAncestors(tree:GetItemParent(item_id)) end -- stale content
|
||||
else -- open file
|
||||
if wx.wxFileName(name):FileExists() then
|
||||
LoadFile(name,nil,true)
|
||||
else -- stale filetree information; rescan
|
||||
treeAddDir(tree,tree:GetItemParent(item_id),name)
|
||||
end
|
||||
if wx.wxFileExists(name) then LoadFile(name,nil,true)
|
||||
else refreshAncestors(tree:GetItemParent(item_id)) end -- stale content
|
||||
end
|
||||
end)
|
||||
-- toggle a folder on
|
||||
@@ -183,7 +171,7 @@ local function treeSetConnectorsAndIcons(tree,treedata)
|
||||
function( event )
|
||||
local item_id = tree:HitTest(event:GetPosition())
|
||||
-- only toggle if this is a folder and the click is on the label
|
||||
if item_id and tree:GetItemImage(item_id) == 0 then
|
||||
if item_id and tree:GetItemImage(item_id) == IMG_DIRECTORY then
|
||||
tree:Toggle(item_id)
|
||||
tree:SelectItem(item_id)
|
||||
else
|
||||
@@ -229,12 +217,19 @@ projpanel:SetSizer(projSizer)
|
||||
-- proj connectors
|
||||
-- ---------------
|
||||
|
||||
local inupdate = false
|
||||
local function projcomboboxUpdate(event)
|
||||
if inupdate then return end
|
||||
local cur = projcombobox:GetValue()
|
||||
local fn = wx.wxFileName(cur)
|
||||
fn:Normalize()
|
||||
|
||||
-- on Windows, wxwidgets (2.9.5+) generates two COMMAND_COMBOBOX_SELECTED
|
||||
-- events when the selection is done with ENTER, which causes recursive
|
||||
-- call of updateProjectDir. To prevent this the second call is ignored.
|
||||
inupdate = true
|
||||
filetree:updateProjectDir(fn:GetFullPath(), event:GetEventType() == wx.wxEVT_COMMAND_COMBOBOX_SELECTED)
|
||||
inupdate = false
|
||||
end
|
||||
|
||||
projpanel:Connect(ID "filetree.proj.drivecb", wx.wxEVT_COMMAND_COMBOBOX_SELECTED, projcomboboxUpdate)
|
||||
@@ -246,11 +241,13 @@ treeSetConnectorsAndIcons(projtree,filetree.projdata)
|
||||
-- ---------------
|
||||
|
||||
function filetree:updateProjectDir(newdir, cboxsel)
|
||||
if (newdir and newdir:sub(-3,-2) == string_Pathsep) then
|
||||
newdir = newdir:sub(0,-2)
|
||||
end
|
||||
if (not newdir) or not wx.wxDirExists(newdir) then return end
|
||||
local dirname = wx.wxFileName.DirName(newdir)
|
||||
|
||||
if ((not newdir) or filetree.projdirText == newdir or not wx.wxDirExists(newdir)) then return end
|
||||
if filetree.projdirText and #filetree.projdirText > 0
|
||||
and dirname:SameAs(wx.wxFileName.DirName(filetree.projdirText)) then return end
|
||||
-- strip the last path separator if any
|
||||
local newdir = dirname:GetPath(wx.wxPATH_GET_VOLUME)
|
||||
|
||||
if ide.config.projectautoopen and filetree.projdirText then
|
||||
StoreRestoreProjectTabs(filetree.projdirText, newdir)
|
||||
@@ -285,8 +282,8 @@ projpanel.projcombobox = projcombobox
|
||||
projpanel.projtree = projtree
|
||||
|
||||
function FileTreeGetDir()
|
||||
return projpanel:IsShown() and filetree.newfiledir
|
||||
and wx.wxFileName.DirName(filetree.newfiledir):GetFullPath()
|
||||
return projpanel:IsShown() and filetree.projdata.rootdir
|
||||
and wx.wxFileName.DirName(filetree.projdata.rootdir):GetFullPath()
|
||||
end
|
||||
|
||||
function FileTreeSetProjects(tab)
|
||||
@@ -304,21 +301,33 @@ local function findItem(tree, match)
|
||||
local node = projtree:GetRootItem()
|
||||
local label = tree:GetItemText(node)
|
||||
|
||||
local s, e = string.find(match, label, 1, true)
|
||||
local s, e
|
||||
if iscaseinsensitive then
|
||||
s, e = string.find(match:lower(), label:lower(), 1, true)
|
||||
else
|
||||
s, e = string.find(match, label, 1, true)
|
||||
end
|
||||
if not s or s ~= 1 then return end
|
||||
|
||||
for token in string.gmatch(string.sub(match,e+1), "[^%"..string_Pathsep.."]+") do
|
||||
local dir = treeGetItemFullName(tree,filetree.projdata,node)
|
||||
treeAddDir(tree,node,dir)
|
||||
local data = tree:GetItemData(node)
|
||||
local cache = data and data:GetData()
|
||||
if cache and cache[iscaseinsensitive and token:lower() or token] then
|
||||
node = cache[iscaseinsensitive and token:lower() or token]
|
||||
else
|
||||
-- token is missing; may need to re-scan the folder; maybe new file
|
||||
local dir = treeGetItemFullName(tree,filetree.projdata,node)
|
||||
treeAddDir(tree,node,dir)
|
||||
|
||||
local item, cookie = tree:GetFirstChild(node)
|
||||
while true do
|
||||
if not item:IsOk() then return end -- not found
|
||||
if tree:GetItemText(item) == token then
|
||||
node = item
|
||||
break
|
||||
local item, cookie = tree:GetFirstChild(node)
|
||||
while true do
|
||||
if not item:IsOk() then return end -- not found
|
||||
if tree:GetItemText(item) == token then
|
||||
node = item
|
||||
break
|
||||
end
|
||||
item, cookie = tree:GetNextChild(node, cookie)
|
||||
end
|
||||
item, cookie = tree:GetNextChild(node, cookie)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -345,10 +354,12 @@ function FileTreeMarkSelected(file)
|
||||
end
|
||||
if item_id then
|
||||
projtree:EnsureVisible(item_id)
|
||||
projtree:SetScrollPos(wx.wxHORIZONTAL, 0, true)
|
||||
projtree:SetItemBold(item_id, true)
|
||||
end
|
||||
curr_file = file
|
||||
projtree:Refresh() -- to force refresh on Mac (ide.osname == 'Macintosh')
|
||||
if ide.wxver < "2.9.5" and ide.osname == 'Macintosh' then
|
||||
projtree:Refresh() end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -53,19 +53,23 @@ local function setSearchFlags(editor)
|
||||
editor:SetSearchFlags(flags)
|
||||
end
|
||||
|
||||
local function setTarget(editor, fDown, fInclude)
|
||||
local function setTarget(editor, fDown, fAll, fWrap)
|
||||
local selStart = editor:GetSelectionStart()
|
||||
local selEnd = editor:GetSelectionEnd()
|
||||
local len = editor:GetLength()
|
||||
local s, e
|
||||
if fDown then
|
||||
e= len
|
||||
s = iff(fInclude, selStart, selEnd +1)
|
||||
s = iff(fAll, selStart, selEnd)
|
||||
e = len
|
||||
else
|
||||
s = 0
|
||||
e = iff(fInclude, selEnd, selStart-1)
|
||||
e = iff(fAll, selEnd, selStart)
|
||||
end
|
||||
if not fDown and not fInclude then s, e = e, s end
|
||||
-- if going up and not search/replace All, then switch the range to
|
||||
-- allow the next match to be properly marked
|
||||
if not fDown and not fAll then s, e = e, s end
|
||||
-- if wrap around and search all requested, then search the entire document
|
||||
if fAll and fWrap then s, e = 0, len end
|
||||
editor:SetTargetStart(s)
|
||||
editor:SetTargetEnd(e)
|
||||
return e
|
||||
@@ -92,17 +96,33 @@ function findReplace:GetSelectedString()
|
||||
local endSel = editor:GetSelectionEnd()
|
||||
if (startSel ~= endSel) and (editor:LineFromPosition(startSel) == editor:LineFromPosition(endSel)) then
|
||||
findReplace.findText = editor:GetSelectedText()
|
||||
findReplace.foundString = true
|
||||
return true
|
||||
end
|
||||
end
|
||||
return editor and findReplace.foundString
|
||||
return false
|
||||
end
|
||||
|
||||
local function shake(window, shakes, duration, vigour)
|
||||
shakes = shakes or 4
|
||||
duration = duration or 0.5
|
||||
vigour = vigour or 0.05
|
||||
|
||||
local delay = math.floor(duration/shakes/2)
|
||||
local position = window:GetPosition() -- get current position
|
||||
local deltax = window:GetSize():GetWidth()*vigour
|
||||
for s = 1, shakes do
|
||||
window:Move(position:GetX()-deltax, position:GetY())
|
||||
wx.wxMilliSleep(delay)
|
||||
window:Move(position:GetX()+deltax, position:GetY())
|
||||
wx.wxMilliSleep(delay)
|
||||
end
|
||||
window:Move(position) -- restore position
|
||||
end
|
||||
|
||||
function findReplace:FindString(reverse)
|
||||
if findReplace:HasText() then
|
||||
local editor = findReplace:GetEditor()
|
||||
local fDown = iff(reverse, not findReplace.fDown, findReplace.fDown)
|
||||
local lenFind = string.len(findReplace.findText)
|
||||
setSearchFlags(editor)
|
||||
setTarget(editor, fDown)
|
||||
local posFind = editor:SearchInTarget(findReplace.findText)
|
||||
@@ -113,13 +133,15 @@ function findReplace:FindString(reverse)
|
||||
end
|
||||
if posFind == -1 then
|
||||
findReplace.foundString = false
|
||||
ide.frame:SetStatusText("Text not found.")
|
||||
ide.frame:SetStatusText(TR("Text not found."))
|
||||
shake(findReplace.dialog)
|
||||
else
|
||||
findReplace.foundString = true
|
||||
local start = editor:GetTargetStart()
|
||||
local finish = editor:GetTargetEnd()
|
||||
EnsureRangeVisible(start, finish)
|
||||
editor:SetSelection(start, finish)
|
||||
ide.frame:SetStatusText("")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -157,34 +179,40 @@ end
|
||||
-- registers every position item was found
|
||||
-- supposed for "Search/Replace in Files"
|
||||
|
||||
function findReplace:ReplaceString(fReplaceAll,inFileRegister)
|
||||
function findReplace:ReplaceString(fReplaceAll, inFileRegister)
|
||||
local replaced = false
|
||||
|
||||
if findReplace:HasText() then
|
||||
local replaceLen = string.len(findReplace.replaceText)
|
||||
local findLen = string.len(findReplace.findText)
|
||||
local editor = findReplace:GetEditor()
|
||||
local endTarget = inFileRegister and setTargetAll(editor) or
|
||||
setTarget(editor, findReplace.fDown, fReplaceAll)
|
||||
setTarget(editor, findReplace.fDown, fReplaceAll, findReplace.fWrap)
|
||||
|
||||
if fReplaceAll then
|
||||
setSearchFlags(editor)
|
||||
local occurrences = 0
|
||||
local posFind = editor:SearchInTarget(findReplace.findText)
|
||||
if (posFind ~= -1) then
|
||||
if(not inFileRegister) then editor:BeginUndoAction() end
|
||||
if (not inFileRegister) then editor:BeginUndoAction() end
|
||||
while posFind ~= -1 do
|
||||
if(inFileRegister) then inFileRegister(posFind) end
|
||||
if (inFileRegister) then inFileRegister(posFind) end
|
||||
|
||||
local length = editor:GetLength()
|
||||
editor:ReplaceTarget(findReplace.replaceText)
|
||||
editor:SetTargetStart(posFind + replaceLen)
|
||||
endTarget = endTarget + replaceLen - findLen
|
||||
-- adjust the endTarget as the position could have changed;
|
||||
-- can't simply subtract findText length as it could be a regexp
|
||||
endTarget = endTarget + (editor:GetLength() - length)
|
||||
editor:SetTargetEnd(endTarget)
|
||||
posFind = editor:SearchInTarget(findReplace.findText)
|
||||
occurrences = occurrences + 1
|
||||
end
|
||||
if(not inFileRegister) then editor:EndUndoAction() end
|
||||
if (not inFileRegister) then editor:EndUndoAction() end
|
||||
|
||||
replaced = true
|
||||
end
|
||||
ide.frame:SetStatusText(("%s %s."):format(
|
||||
TR("Replaced"), TR("%d instance", occurrences):format(occurrences)))
|
||||
else
|
||||
if findReplace.foundString then
|
||||
local start = editor:GetSelectionStart()
|
||||
@@ -206,22 +234,17 @@ local function onFileRegister(pos)
|
||||
local line = editor:LineFromPosition(pos)
|
||||
local linepos = pos - editor:PositionFromLine(line)
|
||||
local result = "("..(line+1)..","..(linepos+1).."): "..editor:GetLine(line)
|
||||
DisplayOutput(findReplace.curfilename..result)
|
||||
DisplayOutputLn(findReplace.curfilename..result:gsub("\r?\n$",""))
|
||||
findReplace.occurrences = findReplace.occurrences + 1
|
||||
end
|
||||
|
||||
local function ProcInFiles(startdir,mask,subdirs,replace)
|
||||
if (subdirs) then
|
||||
local dirs = FileSysGet(startdir..string_Pathsep.."*",wx.wxDIR)
|
||||
for _,dir in ipairs(dirs) do
|
||||
ProcInFiles(dir,mask,true,replace)
|
||||
end
|
||||
end
|
||||
|
||||
local files = FileSysGet(startdir..string_Pathsep..mask,wx.wxFILE)
|
||||
local files = FileSysGetRecursive(startdir,subdirs,mask)
|
||||
for _,file in ipairs(files) do
|
||||
-- ignore .bak files when replacing and asked to store .bak files
|
||||
if not (replace and findReplace.fMakeBak and file:find('.bak$')) then
|
||||
-- and skip folders as these are included in the list as well
|
||||
if not (replace and findReplace.fMakeBak and file:find('.bak$'))
|
||||
and not file:match(string_Pathsep.."$") then
|
||||
findReplace.curfilename = file
|
||||
|
||||
local filetext = FileRead(file)
|
||||
@@ -251,38 +274,51 @@ function findReplace:RunInFiles(replace)
|
||||
wx.wxDefaultPosition, wx.wxSize(1,1), wx.wxBORDER_STATIC)
|
||||
findReplace.occurrences = 0
|
||||
|
||||
local fname = wx.wxFileName(findReplace.filedirText)
|
||||
local startdir = findReplace.filedirText
|
||||
DisplayOutput("FindInFiles: "..(replace and "Replacing" or "Searching for").." '"..findReplace.findText.."'.\n")
|
||||
DisplayOutputLn(("%s '%s'."):format(
|
||||
(replace and TR("Replacing") or TR("Searching for")),
|
||||
findReplace.findText))
|
||||
|
||||
ProcInFiles(startdir, findReplace.filemaskText, findReplace.fSubDirs, replace)
|
||||
|
||||
DisplayOutput("FindInFiles: "..findReplace.occurrences.." instance(s) have been "..
|
||||
(replace and "replaced" or "found")..".\n")
|
||||
DisplayOutputLn(("%s %s."):format(
|
||||
(replace and TR("Replaced") or TR("Found")),
|
||||
TR("%d instance", findReplace.occurrences):format(findReplace.occurrences)))
|
||||
|
||||
findReplace.oveditor = nil
|
||||
end
|
||||
|
||||
local function createFindReplaceDialog(replace,infiles)
|
||||
function findReplace:createDialog(replace,infiles)
|
||||
local ID_FIND_NEXT = 1
|
||||
local ID_REPLACE = 2
|
||||
local ID_REPLACE_ALL = 3
|
||||
local ID_SETDIR = 4
|
||||
|
||||
local mac = ide.osname == 'Macintosh'
|
||||
|
||||
local findReplace = self
|
||||
|
||||
local position = wx.wxDefaultPosition
|
||||
if findReplace.dialog then
|
||||
-- grab current position before destroying the dialog
|
||||
position = findReplace.dialog:GetPosition()
|
||||
findReplace.dialog:Destroy()
|
||||
end
|
||||
|
||||
local findDialog = wx.wxDialog(ide.frame, wx.wxID_ANY, infiles and TR("Find In Files") or TR("Find"),
|
||||
position, wx.wxDefaultSize, wx.wxDEFAULT_DIALOG_STYLE)
|
||||
|
||||
findReplace.replace = replace
|
||||
findReplace.infiles = infiles
|
||||
|
||||
local findDialog = wx.wxDialog(ide.frame, wx.wxID_ANY, infiles and "Find In Files" or "Find",
|
||||
wx.wxDefaultPosition, wx.wxDefaultSize, wx.wxDEFAULT_DIALOG_STYLE)
|
||||
|
||||
-- Create right hand buttons and sizer
|
||||
local findButton = wx.wxButton(findDialog, ID_FIND_NEXT, infiles and "&Find All" or "&Find Next")
|
||||
findButton:SetDefault()
|
||||
local replaceButton = wx.wxButton(findDialog, ID_REPLACE, infiles and replace and "&Replace All" or "&Replace")
|
||||
local findButton = wx.wxButton(findDialog, ID_FIND_NEXT, infiles and TR("&Find All") or TR("&Find Next"))
|
||||
local replaceButton = wx.wxButton(findDialog, ID_REPLACE, infiles and replace and TR("&Replace All") or TR("&Replace"))
|
||||
local replaceAllButton = nil
|
||||
if (replace and not infiles) then
|
||||
replaceAllButton = wx.wxButton(findDialog, ID_REPLACE_ALL, "Replace &All")
|
||||
replaceAllButton = wx.wxButton(findDialog, ID_REPLACE_ALL, TR("Replace &All"))
|
||||
end
|
||||
local cancelButton = wx.wxButton(findDialog, wx.wxID_CANCEL, "Cancel")
|
||||
local cancelButton = wx.wxButton(findDialog, wx.wxID_CANCEL, TR("Cancel"))
|
||||
|
||||
local buttonsSizer = wx.wxBoxSizer(wx.wxVERTICAL)
|
||||
buttonsSizer:Add(findButton, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 3)
|
||||
@@ -293,15 +329,16 @@ local function createFindReplaceDialog(replace,infiles)
|
||||
buttonsSizer:Add(cancelButton, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 3)
|
||||
|
||||
-- Create find/replace text entry sizer
|
||||
local findStatText = wx.wxStaticText( findDialog, wx.wxID_ANY, "Find: ")
|
||||
local findStatText = wx.wxStaticText(findDialog, wx.wxID_ANY, TR("Find")..": ")
|
||||
local findTextCombo = wx.wxComboBox(findDialog, wx.wxID_ANY, findReplace.findText,
|
||||
wx.wxDefaultPosition, wx.wxDefaultSize, findReplace.findTextArray, wx.wxCB_DROPDOWN)
|
||||
wx.wxDefaultPosition, wx.wxDefaultSize, findReplace.findTextArray,
|
||||
wx.wxCB_DROPDOWN + (mac and wx.wxTE_PROCESS_ENTER or 0))
|
||||
findTextCombo:SetFocus()
|
||||
|
||||
local infilesMaskStat,infilesMaskCombo
|
||||
local infilesDirStat,infilesDirCombo,infilesDirButton
|
||||
if (infiles) then
|
||||
infilesMaskStat = wx.wxStaticText( findDialog, wx.wxID_ANY, "File Type: ")
|
||||
infilesMaskStat = wx.wxStaticText(findDialog, wx.wxID_ANY, TR("File Type")..": ")
|
||||
infilesMaskCombo = wx.wxComboBox(findDialog, wx.wxID_ANY, findReplace.filemaskText,
|
||||
wx.wxDefaultPosition, wx.wxDefaultSize, findReplace.filemaskTextArray)
|
||||
|
||||
@@ -310,15 +347,18 @@ local function createFindReplaceDialog(replace,infiles)
|
||||
findReplace.filedirText = fname:GetPath(wx.wxPATH_GET_VOLUME)
|
||||
end
|
||||
|
||||
infilesDirStat = wx.wxStaticText( findDialog, wx.wxID_ANY, "Directory: ")
|
||||
infilesDirCombo = wx.wxComboBox(findDialog, wx.wxID_ANY, findReplace.filedirText, wx.wxDefaultPosition, wx.wxDefaultSize, findReplace.filedirTextArray)
|
||||
infilesDirStat = wx.wxStaticText(findDialog, wx.wxID_ANY, TR("Directory")..": ")
|
||||
infilesDirCombo = wx.wxComboBox(findDialog, wx.wxID_ANY, findReplace.filedirText,
|
||||
wx.wxDefaultPosition, wx.wxDefaultSize, findReplace.filedirTextArray)
|
||||
infilesDirButton = wx.wxButton(findDialog, ID_SETDIR, "...",wx.wxDefaultPosition, wx.wxSize(26,20))
|
||||
end
|
||||
|
||||
local replaceStatText, replaceTextCombo
|
||||
if (replace) then
|
||||
replaceStatText = wx.wxStaticText( findDialog, wx.wxID_ANY, "Replace: ")
|
||||
replaceTextCombo = wx.wxComboBox(findDialog, wx.wxID_ANY, findReplace.replaceText, wx.wxDefaultPosition, wx.wxDefaultSize, findReplace.replaceTextArray)
|
||||
replaceStatText = wx.wxStaticText(findDialog, wx.wxID_ANY, TR("Replace")..": ")
|
||||
replaceTextCombo = wx.wxComboBox(findDialog, wx.wxID_ANY, findReplace.replaceText,
|
||||
wx.wxDefaultPosition, wx.wxDefaultSize, findReplace.replaceTextArray,
|
||||
wx.wxCB_DROPDOWN + (mac and wx.wxTE_PROCESS_ENTER or 0))
|
||||
end
|
||||
|
||||
local findReplaceSizer = wx.wxFlexGridSizer(2, 3, 0, 0)
|
||||
@@ -345,13 +385,13 @@ local function createFindReplaceDialog(replace,infiles)
|
||||
-- the StaticBox(Sizer) needs to be created before checkboxes, otherwise
|
||||
-- checkboxes don't get any clicks on OSX (ide.osname == 'Macintosh')
|
||||
-- as the z-order for event traversal appears to be incorrect.
|
||||
local optionsSizer = wx.wxStaticBoxSizer(wx.wxVERTICAL, findDialog, "Options" )
|
||||
local optionsSizer = wx.wxStaticBoxSizer(wx.wxVERTICAL, findDialog, TR("Options"))
|
||||
|
||||
-- Create find/replace option checkboxes
|
||||
local wholeWordCheckBox = wx.wxCheckBox(findDialog, wx.wxID_ANY, "Match &whole word")
|
||||
local matchCaseCheckBox = wx.wxCheckBox(findDialog, wx.wxID_ANY, "Match &case")
|
||||
local wrapAroundCheckBox = wx.wxCheckBox(findDialog, wx.wxID_ANY, "Wrap ar&ound")
|
||||
local regexCheckBox = wx.wxCheckBox(findDialog, wx.wxID_ANY, "Regular &expression")
|
||||
local wholeWordCheckBox = wx.wxCheckBox(findDialog, wx.wxID_ANY, TR("Match &whole word"))
|
||||
local matchCaseCheckBox = wx.wxCheckBox(findDialog, wx.wxID_ANY, TR("Match &case"))
|
||||
local wrapAroundCheckBox = wx.wxCheckBox(findDialog, wx.wxID_ANY, TR("Wrap ar&ound"))
|
||||
local regexCheckBox = wx.wxCheckBox(findDialog, wx.wxID_ANY, TR("Regular &expression"))
|
||||
wholeWordCheckBox:SetValue(findReplace.fWholeWord)
|
||||
matchCaseCheckBox:SetValue(findReplace.fMatchCase)
|
||||
wrapAroundCheckBox:SetValue(findReplace.fWrap)
|
||||
@@ -373,10 +413,10 @@ local function createFindReplaceDialog(replace,infiles)
|
||||
local scopeSizer
|
||||
if (infiles) then
|
||||
-- the StaticBox(Sizer) needs to be created before checkboxes
|
||||
scopeSizer = wx.wxStaticBoxSizer(wx.wxVERTICAL, findDialog, "In Files")
|
||||
scopeSizer = wx.wxStaticBoxSizer(wx.wxVERTICAL, findDialog, TR("In Files"))
|
||||
|
||||
subDirCheckBox = wx.wxCheckBox(findDialog, wx.wxID_ANY, "&Subdirectories")
|
||||
makeBakCheckBox = wx.wxCheckBox(findDialog, wx.wxID_ANY, ".&bak on Replace")
|
||||
subDirCheckBox = wx.wxCheckBox(findDialog, wx.wxID_ANY, TR("&Subdirectories"))
|
||||
makeBakCheckBox = wx.wxCheckBox(findDialog, wx.wxID_ANY, TR(".&bak on Replace"))
|
||||
subDirCheckBox:SetValue(findReplace.fSubDirs)
|
||||
makeBakCheckBox:SetValue(findReplace.fMakeBak)
|
||||
|
||||
@@ -386,7 +426,8 @@ local function createFindReplaceDialog(replace,infiles)
|
||||
|
||||
scopeSizer:Add(optionSizer, 0, 0, 5)
|
||||
else
|
||||
scopeRadioBox = wx.wxRadioBox(findDialog, wx.wxID_ANY, "Scope", wx.wxDefaultPosition, wx.wxDefaultSize, {"&Up", "&Down"}, 1, wx.wxRA_SPECIFY_COLS)
|
||||
scopeRadioBox = wx.wxRadioBox(findDialog, wx.wxID_ANY, TR("Scope"), wx.wxDefaultPosition,
|
||||
wx.wxDefaultSize, {TR("&Up"), TR("&Down")}, 1, wx.wxRA_SPECIFY_COLS)
|
||||
scopeRadioBox:SetSelection(iff(findReplace.fDown, 1, 0))
|
||||
|
||||
scopeSizer = wx.wxBoxSizer(wx.wxVERTICAL, findDialog)
|
||||
@@ -406,7 +447,7 @@ local function createFindReplaceDialog(replace,infiles)
|
||||
mainSizer:Add(leftSizer, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 10)
|
||||
mainSizer:Add(buttonsSizer, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 10)
|
||||
|
||||
mainSizer:SetSizeHints( findDialog )
|
||||
mainSizer:SetSizeHints(findDialog)
|
||||
findDialog:SetSizer(mainSizer)
|
||||
|
||||
local function TransferDataFromWindow()
|
||||
@@ -437,12 +478,26 @@ local function createFindReplaceDialog(replace,infiles)
|
||||
return true
|
||||
end
|
||||
|
||||
-- this is a workaround for Enter issue in wxComboBox on OSX:
|
||||
-- https://groups.google.com/d/msg/wx-users/EVJr8GqyNUA/CUALp585E78J
|
||||
if (mac and ide.wxver >= "2.9.5") then
|
||||
local function simulateEnter()
|
||||
findDialog:AddPendingEvent(wx.wxCommandEvent(
|
||||
wx.wxEVT_COMMAND_BUTTON_CLICKED, ID_FIND_NEXT))
|
||||
end
|
||||
findTextCombo:Connect(wx.wxEVT_COMMAND_TEXT_ENTER, simulateEnter)
|
||||
if replace then
|
||||
replaceTextCombo:Connect(wx.wxEVT_COMMAND_TEXT_ENTER, simulateEnter)
|
||||
end
|
||||
end
|
||||
|
||||
findDialog:Connect(ID_FIND_NEXT, wx.wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
function()
|
||||
TransferDataFromWindow()
|
||||
if (findReplace.infiles) then
|
||||
findReplace:RunInFiles()
|
||||
findReplace.dialog:Destroy()
|
||||
findReplace.dialog = nil
|
||||
else
|
||||
findReplace:FindString()
|
||||
end
|
||||
@@ -456,13 +511,12 @@ local function createFindReplaceDialog(replace,infiles)
|
||||
if (findReplace.infiles) then
|
||||
findReplace:RunInFiles(true)
|
||||
findReplace.dialog:Destroy()
|
||||
findReplace.dialog = nil
|
||||
else
|
||||
findReplace:ReplaceString()
|
||||
end
|
||||
else
|
||||
findReplace.dialog:Destroy()
|
||||
findReplace.dialog = createFindReplaceDialog(true,infiles)
|
||||
findReplace.dialog:Show(true)
|
||||
findReplace:createDialog(true,infiles)
|
||||
end
|
||||
end)
|
||||
|
||||
@@ -478,7 +532,7 @@ local function createFindReplaceDialog(replace,infiles)
|
||||
if infilesDirButton then
|
||||
findDialog:Connect(ID_SETDIR, wx.wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
function()
|
||||
local filePicker = wx.wxDirDialog(findDialog, "Choose a project directory",
|
||||
local filePicker = wx.wxDirDialog(findDialog, TR("Choose a project directory"),
|
||||
findReplace.filedirText~="" and findReplace.filedirText or wx.wxGetCwd(),wx.wxFLP_USE_TEXTCTRL)
|
||||
|
||||
local res = filePicker:ShowModal(true)
|
||||
@@ -486,22 +540,26 @@ local function createFindReplaceDialog(replace,infiles)
|
||||
infilesDirCombo:SetValue(filePicker:GetPath())
|
||||
end
|
||||
end)
|
||||
|
||||
end
|
||||
|
||||
findDialog:Connect(wx.wxID_ANY, wx.wxEVT_CLOSE_WINDOW,
|
||||
function (event)
|
||||
TransferDataFromWindow()
|
||||
event:Skip()
|
||||
findDialog:Show(false)
|
||||
findDialog:Destroy()
|
||||
end)
|
||||
-- if on OSX then select the current value of the default dropdown
|
||||
-- and don't set the default as it doesn't make Enter to work, but
|
||||
-- prevents associated hotkey (Cmd-F) from working (wx2.9.5).
|
||||
if ide.osname == 'Macintosh' then
|
||||
findTextCombo:SetSelection(0, #findTextCombo:GetValue())
|
||||
else
|
||||
findButton:SetDefault()
|
||||
end
|
||||
|
||||
-- reset search when re-creating dialog to avoid modifying selected
|
||||
-- fragment after successful search and updated replacement
|
||||
findReplace.foundString = false
|
||||
findReplace.dialog = findDialog
|
||||
findDialog:Show(true)
|
||||
return findDialog
|
||||
end
|
||||
|
||||
function findReplace:Show(replace,infiles)
|
||||
self.dialog = nil
|
||||
self.dialog = createFindReplaceDialog(replace,infiles)
|
||||
self.dialog:Show(true)
|
||||
self:GetSelectedString()
|
||||
self:createDialog(replace,infiles)
|
||||
end
|
||||
|
||||
@@ -4,22 +4,30 @@
|
||||
local ide = ide
|
||||
|
||||
-- Pick some reasonable fixed width fonts to use for the editor
|
||||
local function setFont(style, config, name, size)
|
||||
local function setFont(style, config)
|
||||
return wx.wxFont(config.fontsize or size or 10, wx.wxFONTFAMILY_MODERN, style,
|
||||
wx.wxFONTWEIGHT_NORMAL, false, config.fontname or name,
|
||||
wx.wxFONTWEIGHT_NORMAL, false, config.fontname or "",
|
||||
config.fontencoding or wx.wxFONTENCODING_DEFAULT)
|
||||
end
|
||||
ide.font.eNormal = setFont(wx.wxFONTSTYLE_NORMAL, ide.config.editor, wx.__WXMSW__ and "Courier New" or "")
|
||||
ide.font.eItalic = setFont(wx.wxFONTSTYLE_ITALIC, ide.config.editor, wx.__WXMSW__ and "Courier New" or "")
|
||||
ide.font.eNormal = setFont(wx.wxFONTSTYLE_NORMAL, ide.config.editor)
|
||||
ide.font.eItalic = setFont(wx.wxFONTSTYLE_ITALIC, ide.config.editor)
|
||||
|
||||
ide.font.oNormal = setFont(wx.wxFONTSTYLE_NORMAL, ide.config.outputshell, wx.__WXMSW__ and "Courier New" or "")
|
||||
ide.font.oItalic = setFont(wx.wxFONTSTYLE_ITALIC, ide.config.outputshell, wx.__WXMSW__ and "Courier New" or "")
|
||||
ide.font.oNormal = setFont(wx.wxFONTSTYLE_NORMAL, ide.config.outputshell)
|
||||
ide.font.oItalic = setFont(wx.wxFONTSTYLE_ITALIC, ide.config.outputshell)
|
||||
|
||||
-- treeCtrl font requires slightly different handling
|
||||
local gui, config = wx.wxTreeCtrl():GetFont(), ide.config.filetree
|
||||
if config.fontsize then gui:SetPointSize(config.fontsize) end
|
||||
if config.fontname then gui:SetFaceName(config.fontname) end
|
||||
ide.font.fNormal = gui
|
||||
do local gui, config = wx.wxTreeCtrl():GetFont(), ide.config.filetree
|
||||
if config.fontsize then gui:SetPointSize(config.fontsize) end
|
||||
if config.fontname then gui:SetFaceName(config.fontname) end
|
||||
ide.font.fNormal = gui
|
||||
end
|
||||
|
||||
-- funcList font requires similar handling
|
||||
do local gui, config = wx.wxTreeCtrl():GetFont(), ide.config.funclist
|
||||
if config.fontsize then gui:SetPointSize(config.fontsize) end
|
||||
if config.fontname then gui:SetFaceName(config.fontname) end
|
||||
ide.font.dNormal = gui
|
||||
end
|
||||
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- Create the wxFrame
|
||||
@@ -42,8 +50,8 @@ local function createFrame()
|
||||
local menuBar = wx.wxMenuBar()
|
||||
local statusBar = frame:CreateStatusBar(6)
|
||||
local section_width = statusBar:GetTextExtent("OVRW")
|
||||
statusBar:SetStatusStyles({wx.wxSB_RAISED, wx.wxSB_RAISED, wx.wxSB_RAISED,
|
||||
wx.wxSB_RAISED, wx.wxSB_RAISED, wx.wxSB_RAISED})
|
||||
statusBar:SetStatusStyles({wx.wxSB_FLAT, wx.wxSB_FLAT, wx.wxSB_FLAT,
|
||||
wx.wxSB_FLAT, wx.wxSB_FLAT, wx.wxSB_FLAT})
|
||||
statusBar:SetStatusWidths(
|
||||
{-1, section_width*6, section_width, section_width, section_width*4, section_width*4})
|
||||
statusBar:SetStatusText(GetIDEString("statuswelcome"))
|
||||
@@ -64,30 +72,20 @@ local function SCinB(id) -- shortcut in brackets
|
||||
end
|
||||
|
||||
local function createToolBar(frame)
|
||||
local toolBar = wx.wxToolBar(frame, wx.wxID_ANY,
|
||||
wx.wxDefaultPosition, wx.wxDefaultSize, wx.wxTB_FLAT + wx.wxTB_NODIVIDER)
|
||||
local toolBar = frame:CreateToolBar(wx.wxTB_FLAT + wx.wxTB_NODIVIDER, wx.wxID_ANY)
|
||||
-- wxChoice is a bit too narrow on Linux, so make it a bit larger
|
||||
local funclist = wx.wxChoice.new(toolBar, ID "toolBar.funclist",
|
||||
-- Linux requires a bit larger size for the function list in the toolbar.
|
||||
-- Mac also requires a bit larger size, but setting it to 20 resets
|
||||
-- back to 16 when the toolbar is refreshed.
|
||||
-- Windows with wxwidgets 2.9.x also requires a larger size.
|
||||
wx.wxDefaultPosition, wx.wxSize.new(240,
|
||||
(ide.osname == "Unix" or ide.osname == "Windows") and 24 or 16))
|
||||
wx.wxDefaultPosition, wx.wxSize.new(240, ide.osname == 'Unix' and 28 or 24))
|
||||
|
||||
-- usually the bmp size isn't necessary, but the HELP icon is not the right size in MSW
|
||||
-- there are two sets of icons: use 24 on OSX and 16 on others.
|
||||
local toolBmpSize =
|
||||
ide.osname == 'Macintosh' and wx.wxSize(24, 24) or wx.wxSize(16, 16)
|
||||
local getBitmap = (ide.app.createbitmap or wx.wxArtProvider.GetBitmap)
|
||||
local toolBmpSize = wx.wxSize(16, 16)
|
||||
toolBar:AddTool(ID_NEW, "New", getBitmap(wx.wxART_NORMAL_FILE, wx.wxART_TOOLBAR, toolBmpSize), TR("Create an empty document")..SCinB(ID_NEW))
|
||||
toolBar:AddTool(ID_OPEN, "Open", getBitmap(wx.wxART_FILE_OPEN, wx.wxART_TOOLBAR, toolBmpSize), TR("Open an existing document")..SCinB(ID_OPEN))
|
||||
toolBar:AddTool(ID_SAVE, "Save", getBitmap(wx.wxART_FILE_SAVE, wx.wxART_TOOLBAR, toolBmpSize), TR("Save the current document")..SCinB(ID_SAVE))
|
||||
toolBar:AddTool(ID_SAVEALL, "Save All", getBitmap(wx.wxART_NEW_DIR, wx.wxART_TOOLBAR, toolBmpSize), TR("Save all open documents")..SCinB(ID_SAVEALL))
|
||||
toolBar:AddSeparator()
|
||||
toolBar:AddTool(ID_CUT, "Cut", getBitmap(wx.wxART_CUT, wx.wxART_TOOLBAR, toolBmpSize), TR("Cut selected text to clipboard")..SCinB(ID_CUT))
|
||||
toolBar:AddTool(ID_COPY, "Copy", getBitmap(wx.wxART_COPY, wx.wxART_TOOLBAR, toolBmpSize), TR("Copy selected text to clipboard")..SCinB(ID_COPY))
|
||||
toolBar:AddTool(ID_PASTE, "Paste", getBitmap(wx.wxART_PASTE, wx.wxART_TOOLBAR, toolBmpSize), TR("Paste text from the clipboard")..SCinB(ID_PASTE))
|
||||
toolBar:AddSeparator()
|
||||
toolBar:AddTool(ID_UNDO, "Undo", getBitmap(wx.wxART_UNDO, wx.wxART_TOOLBAR, toolBmpSize), TR("Undo last edit")..SCinB(ID_UNDO))
|
||||
toolBar:AddTool(ID_REDO, "Redo", getBitmap(wx.wxART_REDO, wx.wxART_TOOLBAR, toolBmpSize), TR("Redo last edit undone")..SCinB(ID_REDO))
|
||||
toolBar:AddTool(ID_PROJECTDIRFROMFILE, "Update", getBitmap(wx.wxART_GO_DIR_UP , wx.wxART_TOOLBAR, toolBmpSize), TR("Set project directory from current file")..SCinB(ID_PROJECTDIRFROMFILE))
|
||||
toolBar:AddSeparator()
|
||||
toolBar:AddTool(ID_FIND, "Find", getBitmap(wx.wxART_FIND, wx.wxART_TOOLBAR, toolBmpSize), TR("Find text")..SCinB(ID_FIND))
|
||||
toolBar:AddTool(ID_REPLACE, "Replace", getBitmap(wx.wxART_FIND_AND_REPLACE, wx.wxART_TOOLBAR, toolBmpSize), TR("Find and replace text")..SCinB(ID_REPLACE))
|
||||
@@ -105,8 +103,6 @@ local function createToolBar(frame)
|
||||
toolBar:AddTool(ID_VIEWWATCHWINDOW, "Watch window", getBitmap("wxART_DEBUG_WATCH", wx.wxART_TOOLBAR, toolBmpSize), TR("View the watch window")..SCinB(ID_VIEWWATCHWINDOW))
|
||||
end
|
||||
toolBar:AddSeparator()
|
||||
toolBar:AddTool(ID_PROJECTDIRFROMFILE, "Update", getBitmap(wx.wxART_GO_DIR_UP , wx.wxART_TOOLBAR, toolBmpSize), TR("Set project directory from current file")..SCinB(ID_PROJECTDIRFROMFILE))
|
||||
toolBar:AddSeparator()
|
||||
toolBar:AddControl(funclist)
|
||||
toolBar:Realize()
|
||||
|
||||
@@ -120,22 +116,29 @@ local function createNotebook(frame)
|
||||
local notebook = wxaui.wxAuiNotebook(frame, wx.wxID_ANY,
|
||||
wx.wxDefaultPosition, wx.wxDefaultSize,
|
||||
wxaui.wxAUI_NB_DEFAULT_STYLE + wxaui.wxAUI_NB_TAB_EXTERNAL_MOVE
|
||||
+ wx.wxNO_BORDER)
|
||||
+ wxaui.wxAUI_NB_WINDOWLIST_BUTTON + wx.wxNO_BORDER)
|
||||
|
||||
-- the following group of event handlers allows the active editor
|
||||
-- to get/keep focus after execution of Run and other commands
|
||||
local current -- the currently active editor, needed by the focus selection
|
||||
local function onPageChange(event)
|
||||
current = event:GetSelection() -- update the active editor reference
|
||||
SetEditorSelection(current)
|
||||
event:Skip() -- skip to let page change
|
||||
end
|
||||
notebook:Connect(wx.wxEVT_SET_FOCUS, -- Notepad tabs shouldn't be selectable,
|
||||
-- wxEVT_SET_FOCUS could be used, but it only works on Windows with wx2.9.5+
|
||||
notebook:Connect(wxaui.wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED,
|
||||
function (event)
|
||||
SetEditorSelection(current) -- select the currently active editor
|
||||
local ed = GetEditor(notebook:GetSelection())
|
||||
local doc = ed and ed:GetId() and ide.openDocuments[ed:GetId()]
|
||||
|
||||
-- skip activation when any of the following is true:
|
||||
-- (1) there is no document yet, the editor tab was just added,
|
||||
-- so no changes needed as there will be a proper later call;
|
||||
-- (2) the page change event was triggered after a tab is closed;
|
||||
-- (3) on OSX from AddPage event when changing from the last tab
|
||||
-- (this is to work around a duplicate event generated in this case
|
||||
-- that first activates the added tab and then some other tab (2.9.5)).
|
||||
|
||||
local double = (ide.osname == 'Macintosh'
|
||||
and event:GetOldSelection() == notebook:GetPageCount()
|
||||
and debug:traceback():find("'AddPage'"))
|
||||
|
||||
if doc and event:GetOldSelection() ~= -1 and not double then
|
||||
SetEditorSelection(notebook:GetSelection()) end
|
||||
end)
|
||||
notebook:Connect(wx.wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, onPageChange)
|
||||
notebook:Connect(wxaui.wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, onPageChange)
|
||||
|
||||
notebook:Connect(wxaui.wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE,
|
||||
function (event)
|
||||
@@ -143,6 +146,21 @@ local function createNotebook(frame)
|
||||
event:Veto() -- don't propagate the event as the page is already closed
|
||||
end)
|
||||
|
||||
-- tabs can be dragged around which may change their indexes;
|
||||
-- when this happens stored indexes need to be updated to reflect the change.
|
||||
-- there is DRAG_DONE event that I'd prefer to use, but it
|
||||
-- doesn't fire for some reason using wxwidgets 2.9.5 (tested on Windows).
|
||||
if ide.wxver >= "2.9.5" then
|
||||
notebook:Connect(wxaui.wxEVT_COMMAND_AUINOTEBOOK_END_DRAG,
|
||||
function (event)
|
||||
for page = 0, notebook:GetPageCount()-1 do
|
||||
local editor = GetEditor(page)
|
||||
if editor then ide.openDocuments[editor:GetId()].index = page end
|
||||
end
|
||||
event:Skip()
|
||||
end)
|
||||
end
|
||||
|
||||
local selection
|
||||
notebook:Connect(wxaui.wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP,
|
||||
function (event)
|
||||
@@ -203,10 +221,6 @@ local function createBottomNotebook(frame)
|
||||
|
||||
bottomnotebook:AddPage(errorlog, TR("Output"), true)
|
||||
bottomnotebook:AddPage(shellbox, TR("Local console"), false)
|
||||
bottomnotebook:Connect(wxaui.wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE,
|
||||
function (event)
|
||||
event:Veto() -- don't allow closing pages in this notebook
|
||||
end)
|
||||
|
||||
frame.bottomnotebook = bottomnotebook
|
||||
bottomnotebook.errorlog = errorlog
|
||||
@@ -235,35 +249,19 @@ do
|
||||
local frame = ide.frame
|
||||
local mgr = frame.uimgr
|
||||
|
||||
mgr:AddPane(frame.toolBar, wxaui.wxAuiPaneInfo():
|
||||
Name("toolBar"):Caption("Main Toolbar"):
|
||||
MinSize(300,16):
|
||||
ToolbarPane():Top():CloseButton(false):
|
||||
LeftDockable(false):RightDockable(false):Hide())
|
||||
|
||||
mgr:AddPane(frame.notebook, wxaui.wxAuiPaneInfo():
|
||||
Name("notebook"):
|
||||
CenterPane():PaneBorder(false):Hide())
|
||||
|
||||
CenterPane():PaneBorder(false))
|
||||
mgr:AddPane(frame.projpanel, wxaui.wxAuiPaneInfo():
|
||||
Name("projpanel"):Caption(TR("Project")):
|
||||
MinSize(200,200):FloatingSize(200,400):
|
||||
Left():Layer(1):Position(1):
|
||||
CloseButton(true):MaximizeButton(false):PinButton(true):Hide())
|
||||
|
||||
CloseButton(true):MaximizeButton(false):PinButton(true))
|
||||
mgr:AddPane(frame.bottomnotebook, wxaui.wxAuiPaneInfo():
|
||||
Name("bottomnotebook"):
|
||||
MinSize(200,200):FloatingSize(400,250):
|
||||
MinSize(100,100):BestSize(200,200):FloatingSize(400,200):
|
||||
Bottom():Layer(1):Position(1):
|
||||
CloseButton(true):MaximizeButton(false):PinButton(true):Hide())
|
||||
|
||||
mgr:GetPane("toolBar"):Show(true)
|
||||
mgr:GetPane("bottomnotebook"):Show(true)
|
||||
mgr:GetPane("projpanel"):Show(true)
|
||||
mgr:GetPane("notebook"):Show(true)
|
||||
|
||||
local pp = mgr:SavePerspective()
|
||||
mgr.defaultPerspective = pp
|
||||
|
||||
mgr:Update()
|
||||
CloseButton(true):MaximizeButton(false):PinButton(true))
|
||||
|
||||
mgr.defaultPerspective = mgr:SavePerspective()
|
||||
end
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
-- Generate a unique new wxWindowID
|
||||
local ID_IDCOUNTER = wx.wxID_HIGHEST + 1
|
||||
function NewID()
|
||||
ID_IDCOUNTER = ID_IDCOUNTER + 1
|
||||
return ID_IDCOUNTER
|
||||
ID_IDCOUNTER = ID_IDCOUNTER + 1
|
||||
return ID_IDCOUNTER
|
||||
end
|
||||
|
||||
-- File menu
|
||||
@@ -19,6 +19,8 @@ ID_SAVE = wx.wxID_SAVE
|
||||
ID_SAVEAS = wx.wxID_SAVEAS
|
||||
ID_SAVEALL = NewID()
|
||||
ID_RECENTFILES = NewID()
|
||||
ID_RECENTFILESPREV = NewID()
|
||||
ID_RECENTFILESNEXT = NewID()
|
||||
ID_EXIT = wx.wxID_EXIT
|
||||
-- Edit menu
|
||||
ID_CUT = wx.wxID_CUT
|
||||
@@ -33,6 +35,11 @@ ID_AUTOCOMPLETEENABLE = NewID()
|
||||
ID_COMMENT = NewID()
|
||||
ID_FOLD = NewID()
|
||||
ID_CLEARDYNAMICWORDS = NewID()
|
||||
-- don't use wx.wxID_PREFERENCES to avoid merging with OSX app menu, because
|
||||
-- Apple guidelines describe Preferences as a "normal" item without submenus.
|
||||
ID_PREFERENCES = NewID()
|
||||
ID_PREFERENCESSYSTEM = NewID()
|
||||
ID_PREFERENCESUSER = NewID()
|
||||
-- Search menu
|
||||
ID_FIND = wx.wxID_FIND
|
||||
ID_FINDNEXT = NewID()
|
||||
@@ -73,8 +80,7 @@ ID_ABOUT = wx.wxID_ABOUT
|
||||
-- Watch window menu items
|
||||
ID_ADDWATCH = NewID()
|
||||
ID_EDITWATCH = NewID()
|
||||
ID_REMOVEWATCH = NewID()
|
||||
ID_EVALUATEWATCH = NewID()
|
||||
ID_DELETEWATCH = NewID()
|
||||
-- Editor popup menu items
|
||||
ID_QUICKADDWATCH = NewID()
|
||||
ID_QUICKEVAL = NewID()
|
||||
|
||||
@@ -68,20 +68,25 @@ function M.show_warnings(top_ast)
|
||||
if name ~= 'self' then
|
||||
local func = parent.parent and parent.parent.parent
|
||||
local assignment = not func.tag or func.tag == 'Set' or func.tag == 'Localrec'
|
||||
-- anonymous functions can also be defined in expressions,
|
||||
-- for example, 'Op' or 'Return' tags
|
||||
local expression = not assignment and func.tag
|
||||
local func1 = func[1][1]
|
||||
local fname = assignment and func1 and type(func1[1]) == 'string' and func1[1]
|
||||
or (func1.tag == 'Index' and index(func1))
|
||||
local fname = assignment and func1 and type(func1[1]) == 'string'
|
||||
and func1[1] or (func1 and func1.tag == 'Index' and index(func1))
|
||||
-- "function foo(bar)" => func.tag == 'Set'
|
||||
-- `Set{{`Id{"foo"}},{`Function{{`Id{"bar"}},{}}}}
|
||||
-- "local function foo(bar)" => func.tag == 'Localrec'
|
||||
-- "local _, foo = 1, function(bar)" => func.tag == 'Local'
|
||||
-- "print(function(bar) end)" => func.tag == nil
|
||||
-- "a = a or function(bar) end" => func.tag == nil
|
||||
-- "return(function(bar) end)" => func.tag == 'Return'
|
||||
-- "function tbl:foo(bar)" => func.tag == 'Set'
|
||||
-- `Set{{`Index{`Id{"tbl"},`String{"foo"}}},{`Function{{`Id{"self"},`Id{"bar"}},{}}}}
|
||||
-- "function tbl.abc:foo(bar)" => func.tag == 'Set'
|
||||
-- `Set{{`Index{`Index{`Id{"tbl"},`String{"abc"}},`String{"foo"}}},{`Function{{`Id{"self"},`Id{"bar"}},{}}}},
|
||||
warn("unused parameter '" .. name .. "'" ..
|
||||
(func and assignment
|
||||
(func and (assignment or expression)
|
||||
and (fname and func.tag
|
||||
and (" in function '" .. fname .. "'")
|
||||
or " in anonymous function")
|
||||
|
||||
@@ -32,6 +32,8 @@ ide.config.keymap = {
|
||||
[ID_SAVEAS] = "Alt-Shift-S",
|
||||
[ID_SAVEALL] = "",
|
||||
[ID_RECENTFILES] = "",
|
||||
[ID_RECENTFILESPREV] = "Ctrl-<",
|
||||
[ID_RECENTFILESNEXT] = "Ctrl->",
|
||||
[ID_EXIT] = "Ctrl-Q",
|
||||
-- Edit menu
|
||||
[ID_CUT] = "Ctrl-X",
|
||||
@@ -84,8 +86,7 @@ ide.config.keymap = {
|
||||
-- Watch window menu items
|
||||
[ID_ADDWATCH] = "Ins",
|
||||
[ID_EDITWATCH] = "F2",
|
||||
[ID_REMOVEWATCH] = "Del",
|
||||
[ID_EVALUATEWATCH] = "",
|
||||
[ID_DELETEWATCH] = "Del",
|
||||
-- Editor popup menu items
|
||||
[ID_QUICKADDWATCH] = "",
|
||||
[ID_QUICKEVAL] = "",
|
||||
|
||||
@@ -41,7 +41,7 @@ end
|
||||
local function q(s) return s:gsub('(.)','%%%1') end
|
||||
|
||||
local MD_MARK_PTRN = '' -- combination of all markup marks that can start styling
|
||||
for key,value in pairs(markup) do
|
||||
for key in pairs(markup) do
|
||||
if key ~= MD_MARK_MARK then MD_MARK_PTRN = MD_MARK_PTRN .. q(key) end
|
||||
end
|
||||
MarkupAddStyles(ide.config.styles)
|
||||
@@ -76,12 +76,9 @@ function MarkupHotspotClick(pos, editor)
|
||||
-- check if requested to open in a new window
|
||||
local newwindow = string.find(text, MD_LINK_NEWWINDOW, 1, true) -- plain search
|
||||
if newwindow then text = string.gsub(text, "^%" .. MD_LINK_NEWWINDOW, "") end
|
||||
local name = wx.wxFileName(filepath):GetPath(wx.wxPATH_GET_VOLUME
|
||||
+ wx.wxPATH_GET_SEPARATOR) .. text
|
||||
-- load/activate file
|
||||
local filename = wx.wxFileName(name)
|
||||
filename:Normalize() -- remove .., ., and other similar elements
|
||||
if filename:FileExists() and
|
||||
local filename = GetFullPathIfExists(
|
||||
wx.wxFileName(filepath):GetPath(wx.wxPATH_GET_VOLUME), text)
|
||||
if filename and
|
||||
(newwindow or SaveModifiedDialog(editor, true) ~= wx.wxID_CANCEL) then
|
||||
if not newwindow and ide.osname == 'Macintosh' then editor:GotoPos(0) end
|
||||
LoadFile(filename,not newwindow and editor or nil,true)
|
||||
@@ -135,22 +132,28 @@ function MarkupStyle(editor, lines, linee)
|
||||
-- always style to the end as there may be comments that need re-styling
|
||||
-- technically, this should be GetLineCount()-1, but we want to style
|
||||
-- beyond the last line to make sure it is styled correctly
|
||||
local linee = linee or editor:GetLineCount()
|
||||
local linec = editor:GetLineCount()
|
||||
local linee = linee or linec
|
||||
|
||||
local iscomment = {}
|
||||
for i,v in pairs(editor.spec.iscomment) do
|
||||
iscomment[i] = v
|
||||
end
|
||||
|
||||
local es = editor:GetEndStyled()
|
||||
local needfix = false
|
||||
|
||||
for line=lines,linee do
|
||||
local tx = editor:GetLine(line)
|
||||
local ls = editor:PositionFromLine(line)
|
||||
|
||||
editor:StartStyling(ls, 0)
|
||||
|
||||
local from = 1
|
||||
local off = -1
|
||||
|
||||
-- doing WrapCount(line) when line == linec (which may be beyond
|
||||
-- the last line) occasionally crashes the application on OSX.
|
||||
local wrapped = line < linec and editor:WrapCount(line) or 0
|
||||
|
||||
while from do
|
||||
tx = string.sub(tx,from)
|
||||
local f,t,w,mark = ismarkup(tx)
|
||||
@@ -181,33 +184,17 @@ function MarkupStyle(editor, lines, linee)
|
||||
end
|
||||
from = t and (t+1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- this could work by calling MarkupStyle directly from EVT_UPDATEUI,
|
||||
-- but the styling didn't work correctly as the style on block comments
|
||||
-- (which is used to identify where the markup should be applied)
|
||||
-- was not always correct during UPDATEUI event.
|
||||
-- to rectify this, we style immediately (by calling MarkupStyle
|
||||
-- from UPDATEUI), but also store the starting point and re-style during
|
||||
-- the next UPDATEUI/IDLE event when the block comment style is correct.
|
||||
local needStyle = {}
|
||||
local frame
|
||||
function MarkupStyleRefresh(editor, ev)
|
||||
if not frame then
|
||||
frame = ide.frame
|
||||
frame:Connect(wx.wxEVT_IDLE,
|
||||
function(event) MarkupStyleRefresh(); event:Skip() end)
|
||||
end
|
||||
|
||||
if not ev or #ev == 0 then -- no new records, refresh deferred ones
|
||||
for ed,line in pairs(needStyle) do
|
||||
MarkupStyle(ed, line)
|
||||
needStyle[ed] = nil
|
||||
end
|
||||
else -- store records from the event table to defer refresh
|
||||
for _,pos in ipairs(ev) do
|
||||
needStyle[editor] = editor:LineFromPosition(pos[1])
|
||||
end
|
||||
|
||||
-- has this line changed its wrapping because of invisible styling?
|
||||
if wrapped > 1 and editor:WrapCount(line) < wrapped then needfix = true end
|
||||
end
|
||||
editor:StartStyling(es, 31)
|
||||
|
||||
-- if any wrapped lines have changed, then reset WrapMode to fix the drawing
|
||||
if needfix then
|
||||
-- this fixes an issue with duplicate lines in Scintilla when
|
||||
-- invisible styles hide some of the content that would be wrapped.
|
||||
local wrapmode = editor:GetWrapMode()
|
||||
if wrapmode ~= wxstc.wxSTC_WRAP_NONE then editor:SetWrapMode(wrapmode) end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -25,7 +25,14 @@ local editMenu = wx.wxMenu{
|
||||
{ },
|
||||
{ ID_FOLD, TR("&Fold/Unfold All")..KSC(ID_FOLD), TR("Fold or unfold all code folds") },
|
||||
{ ID_CLEARDYNAMICWORDS, TR("Clear &Dynamic Words")..KSC(ID_CLEARDYNAMICWORDS), TR("Resets the dynamic word list for autocompletion") },
|
||||
{ },
|
||||
}
|
||||
|
||||
local preferencesMenu = wx.wxMenu{
|
||||
{ID_PREFERENCESSYSTEM, TR("Settings: System")..KSC(ID_PREFERENCESSYSTEM)},
|
||||
{ID_PREFERENCESUSER, TR("Settings: User")..KSC(ID_PREFERENCESUSER)},
|
||||
}
|
||||
editMenu:Append(ID_PREFERENCES, TR("Preferences"), preferencesMenu)
|
||||
menuBar:Append(editMenu, TR("&Edit"))
|
||||
|
||||
editMenu:Check(ID_AUTOCOMPLETEENABLE, ide.config.autocomplete)
|
||||
@@ -47,12 +54,11 @@ function OnUpdateUIEditMenu(event)
|
||||
if editor == nil then event:Enable(false); return end
|
||||
|
||||
local alwaysOn = { [ID_SELECTALL] = true, [ID_FOLD] = true,
|
||||
-- allow Cut and Copy commands as these work on a line if no selection
|
||||
[ID_COPY] = true, [ID_CUT] = true,
|
||||
[ID_COMMENT] = true, [ID_AUTOCOMPLETE] = true}
|
||||
local menu_id = event:GetId()
|
||||
local enable =
|
||||
((menu_id == ID_COPY or menu_id == ID_CUT) and
|
||||
(editor:GetClassInfo():GetClassName() ~= 'wxStyledTextCtrl'
|
||||
or editor:GetSelectionStart() ~= editor:GetSelectionEnd())) or
|
||||
menu_id == ID_PASTE and editor:CanPaste() or
|
||||
menu_id == ID_UNDO and editor:CanUndo() or
|
||||
menu_id == ID_REDO and editor:CanRedo() or
|
||||
@@ -74,8 +80,12 @@ function OnEditMenu(event)
|
||||
then event:Skip(); return end
|
||||
|
||||
local menu_id = event:GetId()
|
||||
if menu_id == ID_CUT then editor:Cut()
|
||||
elseif menu_id == ID_COPY then editor:Copy()
|
||||
if menu_id == ID_CUT then
|
||||
if editor:GetSelectionStart() == editor:GetSelectionEnd()
|
||||
then editor:LineCut() else editor:Cut() end
|
||||
elseif menu_id == ID_COPY then
|
||||
if editor:GetSelectionStart() == editor:GetSelectionEnd()
|
||||
then editor:LineCopy() else editor:Copy() end
|
||||
elseif menu_id == ID_PASTE then editor:Paste()
|
||||
elseif menu_id == ID_SELECTALL then editor:SelectAll()
|
||||
elseif menu_id == ID_UNDO then editor:Undo()
|
||||
@@ -88,6 +98,32 @@ for _, event in pairs({ID_CUT, ID_COPY, ID_PASTE, ID_SELECTALL, ID_UNDO, ID_REDO
|
||||
frame:Connect(event, wx.wxEVT_UPDATE_UI, OnUpdateUIEditMenu)
|
||||
end
|
||||
|
||||
local function generateConfigMessage(type)
|
||||
return ([==[--[[--
|
||||
Use this file to specify %s preferences.
|
||||
Review [examples](+%s) or check [online documentation](%s) for details.
|
||||
--]]--
|
||||
]==])
|
||||
:format(type, MergeFullPath(ide.editorFilename, "../cfg/user-sample.lua"),
|
||||
"http://studio.zerobrane.com/documentation.html")
|
||||
end
|
||||
|
||||
frame:Connect(ID_PREFERENCESSYSTEM, wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function ()
|
||||
local editor = LoadFile(ide.configs.system)
|
||||
if editor and #editor:GetText() == 0 then
|
||||
editor:AddText(generateConfigMessage("System")) end
|
||||
end)
|
||||
|
||||
frame:Connect(ID_PREFERENCESUSER, wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function ()
|
||||
local editor = LoadFile(ide.configs.user)
|
||||
if editor and #editor:GetText() == 0 then
|
||||
editor:AddText(generateConfigMessage("User")) end
|
||||
end)
|
||||
frame:Connect(ID_PREFERENCESUSER, wx.wxEVT_UPDATE_UI,
|
||||
function (event) event:Enable(ide.configs.user ~= nil) end)
|
||||
|
||||
frame:Connect(ID_CLEARDYNAMICWORDS, wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function () DynamicWordsReset() end)
|
||||
|
||||
@@ -126,9 +162,9 @@ frame:Connect(ID_COMMENT, wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
end
|
||||
local lc = editor.spec.linecomment
|
||||
for line in string.gmatch(editor:GetSelectedText()..'\n', "(.-)\r?\n") do
|
||||
if string.sub(line,1,2) == lc then
|
||||
line = string.sub(line,3)
|
||||
else
|
||||
if string.sub(line,1,#lc) == lc then
|
||||
line = string.sub(line,#lc+1)
|
||||
elseif #line > 0 then
|
||||
line = lc..line
|
||||
end
|
||||
table.insert(buf, line)
|
||||
|
||||
@@ -25,26 +25,133 @@ local filehistorymenu = wx.wxMenu({})
|
||||
local filehistory = wx.wxMenuItem(fileMenu, ID_RECENTFILES,
|
||||
TR("Recent Files")..KSC(ID_RECENTFILES), TR("File history"), wx.wxITEM_NORMAL, filehistorymenu)
|
||||
fileMenu:Insert(8,filehistory)
|
||||
function UpdateFileHistoryUI(list)
|
||||
-- remove all at first
|
||||
for i=1,filehistorymenu:GetMenuItemCount() do
|
||||
filehistorymenu:Delete( ID("file.recentfiles."..i))
|
||||
end
|
||||
for i=1,#list do
|
||||
local file = list[i].filename
|
||||
local item = wx.wxMenuItem(filehistorymenu, ID("file.recentfiles."..i),file,"")
|
||||
filehistorymenu:Append(item)
|
||||
end
|
||||
end
|
||||
|
||||
for i=1,ide.config.filehistorylength do
|
||||
frame:Connect(ID("file.recentfiles."..i), wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function (event)
|
||||
local item = filehistorymenu:FindItemByPosition(i-1)
|
||||
local filename = item:GetLabel()
|
||||
LoadFile(filename)
|
||||
do -- recent file history
|
||||
local iscaseinsensitive = wx.wxFileName("A"):SameAs(wx.wxFileName("a"))
|
||||
local function isSameAs(f1, f2)
|
||||
return f1 == f2 or iscaseinsensitive and f1:lower() == f2:lower()
|
||||
end
|
||||
|
||||
local filehistory = {[0] = 1}
|
||||
|
||||
-- add file to the file history removing duplicates
|
||||
local function addFileHistory(filename)
|
||||
-- a new (empty) tab is opened; don't change the history
|
||||
if not filename then return end
|
||||
|
||||
local fn = wx.wxFileName(filename)
|
||||
if fn:Normalize() then filename = fn:GetFullPath() end
|
||||
|
||||
local index = filehistory[0]
|
||||
|
||||
-- special case: selecting the current file (or moving through the history)
|
||||
if filehistory[index] and isSameAs(filename, filehistory[index].filename) then return end
|
||||
|
||||
-- something else is selected
|
||||
-- (1) flip the history from 1 to the current index
|
||||
for i = 1, math.floor(index/2) do
|
||||
filehistory[i], filehistory[index-i+1] = filehistory[index-i+1], filehistory[i]
|
||||
end
|
||||
)
|
||||
|
||||
-- (2) if the file is in the history, remove it
|
||||
for i = #filehistory, 1, -1 do
|
||||
if isSameAs(filename, filehistory[i].filename) then
|
||||
table.remove(filehistory, i)
|
||||
end
|
||||
end
|
||||
|
||||
-- (3) add the file to the top and update the index
|
||||
table.insert(filehistory, 1, {filename=filename})
|
||||
filehistory[0] = 1
|
||||
|
||||
-- (4) remove all entries that are no longer needed
|
||||
while #filehistory>ide.config.filehistorylength do table.remove(filehistory) end
|
||||
end
|
||||
|
||||
local function remFileHistory(filename)
|
||||
if not filename then return end
|
||||
|
||||
local fn = wx.wxFileName(filename)
|
||||
if fn:Normalize() then filename = fn:GetFullPath() end
|
||||
|
||||
local index = filehistory[0]
|
||||
|
||||
-- special case: removing the current file
|
||||
if filehistory[index] and isSameAs(filename, filehistory[index].filename) then
|
||||
-- (1) flip the history from 1 to the current index
|
||||
for i = 1, math.floor(index/2) do
|
||||
filehistory[i], filehistory[index-i+1] = filehistory[index-i+1], filehistory[i]
|
||||
end
|
||||
end
|
||||
|
||||
-- (2) if the file is in the history, remove it
|
||||
for i = #filehistory, 1, -1 do
|
||||
if isSameAs(filename, filehistory[i].filename) then
|
||||
table.remove(filehistory, i)
|
||||
end
|
||||
end
|
||||
|
||||
-- (3) update index
|
||||
filehistory[0] = 1
|
||||
end
|
||||
|
||||
local updateRecentFiles -- need forward declaration because of recursive refs
|
||||
|
||||
local function loadRecent(event)
|
||||
local id = event:GetId()
|
||||
local item = filehistorymenu:FindItem(id)
|
||||
local filename = item:GetLabel()
|
||||
local index = filehistory[0]
|
||||
filehistory[0] = (
|
||||
(index > 1 and id == ID("file.recentfiles."..(index-1)) and index-1) or
|
||||
(index < #filehistory) and id == ID("file.recentfiles."..(index+1)) and index+1 or
|
||||
1)
|
||||
if not LoadFile(filename, nil, true) then
|
||||
wx.wxMessageBox(
|
||||
TR("File '%s' no longer exists."):format(filename),
|
||||
GetIDEString("editormessage"),
|
||||
wx.wxOK + wx.wxCENTRE, ide.frame)
|
||||
remFileHistory(filename)
|
||||
updateRecentFiles(filehistory)
|
||||
end
|
||||
end
|
||||
|
||||
updateRecentFiles = function (list)
|
||||
local items = filehistorymenu:GetMenuItemCount()
|
||||
for i=1, #list do
|
||||
local file = list[i].filename
|
||||
local id = ID("file.recentfiles."..i)
|
||||
local label = file..(
|
||||
i == list[0]-1 and KSC(ID_RECENTFILESNEXT) or
|
||||
i == list[0]+1 and KSC(ID_RECENTFILESPREV) or
|
||||
"")
|
||||
if i <= items then -- this is an existing item; update the label
|
||||
filehistorymenu:FindItem(id):SetItemLabel(label)
|
||||
else -- need to add an item
|
||||
local item = wx.wxMenuItem(filehistorymenu, id, label, "")
|
||||
filehistorymenu:Append(item)
|
||||
frame:Connect(id, wx.wxEVT_COMMAND_MENU_SELECTED, loadRecent)
|
||||
end
|
||||
end
|
||||
for i=items, #list+1, -1 do -- delete the rest if the list got shorter
|
||||
filehistorymenu:Delete(filehistorymenu:FindItemByPosition(i-1))
|
||||
end
|
||||
|
||||
-- enable if there are any recent files
|
||||
fileMenu:Enable(ID_RECENTFILES, #list > 0)
|
||||
end
|
||||
|
||||
-- public methods
|
||||
function GetFileHistory() return filehistory end
|
||||
function SetFileHistory(fh)
|
||||
filehistory = fh
|
||||
filehistory[0] = 1
|
||||
updateRecentFiles(filehistory)
|
||||
end
|
||||
function AddToFileHistory(filename)
|
||||
addFileHistory(filename)
|
||||
updateRecentFiles(filehistory)
|
||||
end
|
||||
end
|
||||
|
||||
frame:Connect(ID_NEW, wx.wxEVT_COMMAND_MENU_SELECTED, NewFile)
|
||||
|
||||
@@ -9,23 +9,26 @@ local menuBar = frame.menuBar
|
||||
local mobdebug = require "mobdebug"
|
||||
|
||||
local helpMenu = wx.wxMenu{
|
||||
{ ID_ABOUT, TR("&About")..KSC(ID_ABOUT), TR("About ZeroBrane Studio") },
|
||||
{ ID_ABOUT, TR("&About")..KSC(ID_ABOUT), TR("About %s"):format(GetIDEString("editor")) },
|
||||
}
|
||||
-- do not translate Help menu on Mac as it won't merge with "standard" menus
|
||||
menuBar:Append(helpMenu, ide.osname == 'Macintosh' and "&Help" or TR("&Help"))
|
||||
|
||||
local function DisplayAbout(event)
|
||||
local page = [[
|
||||
local logo = ide.config.path.app.."/"..GetIDEString("logo")
|
||||
local logoimg = wx.wxFileName(logo):FileExists() and
|
||||
([[<tr><td><img src="%s"></td></tr>]]):format(logo) or ""
|
||||
local page = ([[
|
||||
<html>
|
||||
<body text="#777777">
|
||||
<table border="0" width="100%">
|
||||
<tr><td><img src="zbstudio/res/zerobrane.png"></td></tr>
|
||||
<table border="0" width="100%%">
|
||||
%s
|
||||
<tr><td>
|
||||
<table cellspacing="3" cellpadding="3" width="100%">
|
||||
<table cellspacing="3" cellpadding="3" width="100%%">
|
||||
<tr>
|
||||
<td>
|
||||
<b>ZeroBrane Studio (]]..ide.VERSION..[[; MobDebug ]]..mobdebug._VERSION..[[)</b><br>
|
||||
<b>Copyright © 2011-2012 ZeroBrane LLC</b><br>
|
||||
<b>ZeroBrane Studio (%s; MobDebug %s)</b><br>
|
||||
<b>Copyright © 2011-2013 ZeroBrane LLC</b><br>
|
||||
Paul Kulchenko<br>
|
||||
Licensed under the MIT License.
|
||||
</td>
|
||||
@@ -41,7 +44,7 @@ local function DisplayAbout(event)
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Based on wxLua editor (]]..wxlua.wxLUA_VERSION_STRING..[[)</b><br>
|
||||
<b>Based on wxLua editor (%s)</b><br>
|
||||
<b>Copyright © 2002-2005 Lomtick Software</b><br>
|
||||
J. Winwood, John Labenski<br>
|
||||
Licensed under wxWindows Library License, v3.
|
||||
@@ -49,36 +52,43 @@ local function DisplayAbout(event)
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Built with ]]..wx.wxVERSION_STRING..[[</b>
|
||||
<b>Built with %s</b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td></tr></table>
|
||||
</body>
|
||||
</html>]]
|
||||
</html>]])
|
||||
:format(logoimg, ide.VERSION, mobdebug._VERSION,
|
||||
wxlua.wxLUA_VERSION_STRING, wx.wxVERSION_STRING)
|
||||
|
||||
local dlg = wx.wxDialog(frame, wx.wxID_ANY, TR("About %s"):format(GetIDEString("editor")))
|
||||
|
||||
-- this is needed because wxLuaHtmlWindow only seems to take into account
|
||||
-- the initial size, but not the one set with SetSize using
|
||||
-- wxlua 2.8.12.2 and wxwidgets 2.9.5+.
|
||||
local tmp = wx.wxLuaHtmlWindow(dlg, wx.wxID_ANY, wx.wxDefaultPosition, wx.wxSize(450, 260))
|
||||
tmp:SetPage(page)
|
||||
local w = tmp:GetInternalRepresentation():GetWidth()
|
||||
local h = tmp:GetInternalRepresentation():GetHeight()
|
||||
tmp:Destroy()
|
||||
|
||||
local dlg = wx.wxDialog(frame, wx.wxID_ANY, TR("About ZeroBrane Studio"))
|
||||
local html = wx.wxLuaHtmlWindow(dlg, wx.wxID_ANY,
|
||||
wx.wxDefaultPosition, wx.wxSize(440, 270),
|
||||
wx.wxHW_SCROLLBAR_NEVER)
|
||||
local line = wx.wxStaticLine(dlg, wx.wxID_ANY)
|
||||
local button = wx.wxButton(dlg, wx.wxID_OK, "OK")
|
||||
|
||||
button:SetDefault()
|
||||
wx.wxDefaultPosition, wx.wxSize(w, h), wx.wxHW_SCROLLBAR_NEVER)
|
||||
|
||||
html:SetBorders(0)
|
||||
html:SetPage(page)
|
||||
html:SetSize(html:GetInternalRepresentation():GetWidth(),
|
||||
html:GetInternalRepresentation():GetHeight())
|
||||
|
||||
local line = wx.wxStaticLine(dlg, wx.wxID_ANY)
|
||||
local button = wx.wxButton(dlg, wx.wxID_OK, "OK")
|
||||
button:SetDefault()
|
||||
|
||||
local topsizer = wx.wxBoxSizer(wx.wxVERTICAL)
|
||||
topsizer:Add(html, 1, wx.wxALL, 10)
|
||||
topsizer:Add(html, 1, wx.wxEXPAND + wx.wxALL, 10)
|
||||
topsizer:Add(line, 0, wx.wxEXPAND + wx.wxLEFT + wx.wxRIGHT, 10)
|
||||
topsizer:Add(button, 0, wx.wxALL + wx.wxALIGN_RIGHT, 10)
|
||||
topsizer:Fit(dlg)
|
||||
|
||||
dlg:SetAutoLayout(true)
|
||||
dlg:SetSizer(topsizer)
|
||||
dlg:SetSizerAndFit(topsizer)
|
||||
dlg:ShowModal()
|
||||
dlg:Destroy()
|
||||
end
|
||||
|
||||
@@ -139,7 +139,8 @@ local function selectInterpreter(id)
|
||||
|
||||
ide.interpreter = interpreters[id]
|
||||
|
||||
if DebuggerShutdown then DebuggerShutdown() end
|
||||
DebuggerShutdown()
|
||||
|
||||
ide.frame.statusBar:SetStatusText(ide.interpreter.name or "", 5)
|
||||
ReloadLuaAPI()
|
||||
end
|
||||
@@ -190,8 +191,10 @@ end
|
||||
function ActivateOutput()
|
||||
if not ide.config.activateoutput then return end
|
||||
-- show output/errorlog pane
|
||||
uimgr:GetPane("bottomnotebook"):Show(true)
|
||||
uimgr:Update()
|
||||
if not uimgr:GetPane("bottomnotebook"):IsShown() then
|
||||
uimgr:GetPane("bottomnotebook"):Show(true)
|
||||
uimgr:Update()
|
||||
end
|
||||
-- activate output/errorlog window
|
||||
local index = bottomnotebook:GetPageIndex(bottomnotebook.errorlog)
|
||||
if bottomnotebook:GetSelection() ~= index then
|
||||
|
||||
@@ -27,38 +27,34 @@ function OnUpdateUISearchMenu(event) event:Enable(GetEditor() ~= nil) end
|
||||
|
||||
frame:Connect(ID_FIND, wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function (event)
|
||||
findReplace:GetSelectedString()
|
||||
findReplace:Show(false)
|
||||
end)
|
||||
frame:Connect(ID_FIND, wx.wxEVT_UPDATE_UI, OnUpdateUISearchMenu)
|
||||
|
||||
frame:Connect(ID_REPLACE, wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function (event)
|
||||
findReplace:GetSelectedString()
|
||||
findReplace:Show(true)
|
||||
end)
|
||||
frame:Connect(ID_REPLACE, wx.wxEVT_UPDATE_UI, OnUpdateUISearchMenu)
|
||||
|
||||
frame:Connect(ID_FINDINFILES, wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function (event)
|
||||
findReplace:GetSelectedString()
|
||||
findReplace:Show(false,true)
|
||||
end)
|
||||
frame:Connect(ID_REPLACEINFILES, wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function (event)
|
||||
findReplace:GetSelectedString()
|
||||
findReplace:Show(true,true)
|
||||
end)
|
||||
|
||||
frame:Connect(ID_FINDNEXT, wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function (event) findReplace:GetSelectedString() findReplace:FindString() end)
|
||||
frame:Connect(ID_FINDNEXT, wx.wxEVT_UPDATE_UI,
|
||||
function (event) event:Enable(findReplace:GetSelectedString() and findReplace:HasText()) end)
|
||||
function (event) event:Enable(findReplace:GetSelectedString() or findReplace:HasText()) end)
|
||||
|
||||
frame:Connect(ID_FINDPREV, wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function (event) findReplace:GetSelectedString() findReplace:FindString(true) end)
|
||||
frame:Connect(ID_FINDPREV, wx.wxEVT_UPDATE_UI,
|
||||
function (event) event:Enable(findReplace:GetSelectedString() and findReplace:HasText()) end)
|
||||
function (event) event:Enable(findReplace:GetSelectedString() or findReplace:HasText()) end)
|
||||
|
||||
-------------------- Find replace end
|
||||
|
||||
|
||||
@@ -7,42 +7,57 @@ local menuBar = frame.menuBar
|
||||
local uimgr = frame.uimgr
|
||||
|
||||
local viewMenu = wx.wxMenu {
|
||||
{ ID_VIEWFILETREE, TR("Project/&FileTree Window")..KSC(ID_VIEWFILETREE), TR("View the project/filetree window") },
|
||||
{ ID_VIEWOUTPUT, TR("&Output/Console Window")..KSC(ID_VIEWOUTPUT), TR("View the output/console window") },
|
||||
{ ID_VIEWWATCHWINDOW, TR("&Watch Window")..KSC(ID_VIEWWATCHWINDOW), TR("View the watch window") },
|
||||
{ ID_VIEWCALLSTACK, TR("&Stack Window")..KSC(ID_VIEWCALLSTACK), TR("View the stack window") },
|
||||
{ ID_VIEWFILETREE, TR("Project/&FileTree Window")..KSC(ID_VIEWFILETREE), TR("View the project/filetree window"), wx.wxITEM_CHECK },
|
||||
{ ID_VIEWOUTPUT, TR("&Output/Console Window")..KSC(ID_VIEWOUTPUT), TR("View the output/console window"), wx.wxITEM_CHECK },
|
||||
{ ID_VIEWWATCHWINDOW, TR("&Watch Window")..KSC(ID_VIEWWATCHWINDOW), TR("View the watch window"), wx.wxITEM_CHECK },
|
||||
{ ID_VIEWCALLSTACK, TR("&Stack Window")..KSC(ID_VIEWCALLSTACK), TR("View the stack window"), wx.wxITEM_CHECK },
|
||||
{ },
|
||||
{ ID_VIEWDEFAULTLAYOUT, TR("&Default Layout")..KSC(ID_VIEWDEFAULTLAYOUT), TR("Reset to default layout") },
|
||||
{ ID_VIEWFULLSCREEN, TR("Full &Screen")..KSC(ID_VIEWFULLSCREEN), TR("Switch to or from full screen mode") },
|
||||
}
|
||||
menuBar:Append(viewMenu, TR("&View"))
|
||||
|
||||
local panels = {
|
||||
[ID_VIEWOUTPUT] = "bottomnotebook",
|
||||
[ID_VIEWFILETREE] = "projpanel",
|
||||
[ID_VIEWWATCHWINDOW] = "watchpanel",
|
||||
[ID_VIEWCALLSTACK] = "stackpanel"
|
||||
}
|
||||
|
||||
local function togglePanel(event)
|
||||
local panel = panels[event:GetId()]
|
||||
local mgr = ide.frame.uimgr
|
||||
local shown = not mgr:GetPane(panel):IsShown()
|
||||
mgr:GetPane(panel):Show(shown)
|
||||
mgr:Update()
|
||||
|
||||
return shown
|
||||
end
|
||||
|
||||
local function checkPanel(event)
|
||||
local panel = panels[event:GetId()]
|
||||
local shown = ide.frame.uimgr:GetPane(panel):IsShown()
|
||||
if ide.frame.menuBar:IsChecked(event:GetId()) ~= shown then
|
||||
ide.frame.menuBar:Check(event:GetId(), shown)
|
||||
end
|
||||
end
|
||||
|
||||
frame:Connect(ID_VIEWDEFAULTLAYOUT, wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function (event)
|
||||
uimgr:LoadPerspective(uimgr.defaultPerspective)
|
||||
uimgr:Update()
|
||||
uimgr:LoadPerspective(uimgr.defaultPerspective, true)
|
||||
end)
|
||||
|
||||
frame:Connect(ID_VIEWOUTPUT, wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function ()
|
||||
uimgr:GetPane("bottomnotebook"):Show(true)
|
||||
uimgr:Update()
|
||||
end)
|
||||
|
||||
frame:Connect(ID_VIEWFILETREE, wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function ()
|
||||
uimgr:GetPane("projpanel"):Show(true)
|
||||
uimgr:Update()
|
||||
end)
|
||||
|
||||
frame:Connect(ID_VIEWFULLSCREEN, wx.wxEVT_COMMAND_MENU_SELECTED, function ()
|
||||
pcall(function() ShowFullScreen(not frame:IsFullScreen()) end)
|
||||
end)
|
||||
frame:Connect(ID_VIEWFULLSCREEN, wx.wxEVT_UPDATE_UI,
|
||||
function (event) event:Enable(GetEditor() ~= nil) end)
|
||||
|
||||
frame:Connect(ID_VIEWOUTPUT, wx.wxEVT_COMMAND_MENU_SELECTED, togglePanel)
|
||||
frame:Connect(ID_VIEWFILETREE, wx.wxEVT_COMMAND_MENU_SELECTED, togglePanel)
|
||||
frame:Connect(ID_VIEWWATCHWINDOW, wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function () DebuggerCreateWatchWindow() end)
|
||||
|
||||
function (event) if togglePanel(event) then DebuggerRefreshPanels() end end)
|
||||
frame:Connect(ID_VIEWCALLSTACK, wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function () DebuggerCreateStackWindow() end)
|
||||
function (event) if togglePanel(event) then DebuggerRefreshPanels() end end)
|
||||
|
||||
for id in pairs(panels) do frame:Connect(id, wx.wxEVT_UPDATE_UI, checkPanel) end
|
||||
|
||||
@@ -60,9 +60,15 @@ local streamouts = {}
|
||||
local customprocs = {}
|
||||
local textout = '' -- this is a buffer for any text sent to external scripts
|
||||
|
||||
function DetachChildProcess()
|
||||
for _, custom in pairs(customprocs) do
|
||||
if (custom and custom.proc) then custom.proc:Detach() end
|
||||
end
|
||||
end
|
||||
|
||||
function CommandLineRunning(uid)
|
||||
for pid,custom in pairs(customprocs) do
|
||||
if (custom.uid == uid and custom.proc and custom.proc.Exists(tonumber(tostring(pid))) )then
|
||||
if (custom.uid == uid and custom.proc and custom.proc.Exists(tonumber(tostring(pid)))) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
@@ -140,9 +146,9 @@ function CommandLineRun(cmd,wdir,tooutput,nohide,stringcallback,uid,endcallback)
|
||||
local proc = wx.wxProcess(errorlog)
|
||||
if (tooutput) then proc:Redirect() end -- redirect the output if requested
|
||||
|
||||
-- manipulate working directory
|
||||
-- set working directory if specified
|
||||
local oldcwd
|
||||
if (wdir) then
|
||||
if (wdir and #wdir > 0) then -- directory can be empty; ignore in this case
|
||||
oldcwd = wx.wxFileName.GetCwd()
|
||||
oldcwd = wx.wxFileName.SetCwd(wdir) and oldcwd
|
||||
end
|
||||
@@ -203,11 +209,17 @@ local function updateInputMarker()
|
||||
inputBound = #getInputText()
|
||||
end
|
||||
|
||||
local readonce = 4096
|
||||
local maxread = readonce * 10 -- maximum number of bytes to read before pausing
|
||||
local function getStreams()
|
||||
local function readStream(tab)
|
||||
for _,v in pairs(tab) do
|
||||
while(v.stream:CanRead()) do
|
||||
local str = v.stream:Read(4096)
|
||||
-- periodically stop reading to get a chance to process other events
|
||||
local processed = 0
|
||||
while (v.stream:CanRead() and processed <= maxread) do
|
||||
local str = v.stream:Read(readonce)
|
||||
processed = processed + #str
|
||||
|
||||
local pfn
|
||||
if (v.callback) then
|
||||
str,pfn = v.callback(str)
|
||||
|
||||
@@ -1,303 +0,0 @@
|
||||
-- authors: Luxinia Dev (Eike Decker & Christoph Kubisch)
|
||||
---------------------------------------------------------
|
||||
local ide = ide
|
||||
-- the preferences dialog
|
||||
|
||||
preferencesDialog = {
|
||||
category = {};
|
||||
uifactory = {};
|
||||
}
|
||||
local cats = preferencesDialog.category
|
||||
|
||||
local function checkstring (v,m)
|
||||
if type(v)~="string" then
|
||||
error(m.." ("..type(v)..")")
|
||||
end
|
||||
end
|
||||
|
||||
function preferencesDialog.addCategory(category)
|
||||
checkstring(category.title,"Invalid category title")
|
||||
checkstring(category.category,"No category")
|
||||
assert(not cats[category.category],"Category already declared")
|
||||
cats[category.category] = category
|
||||
cats[#cats+1] = category
|
||||
category.order = category.order or #cats
|
||||
category.entry = {}
|
||||
end
|
||||
|
||||
function preferencesDialog.addPage(page)
|
||||
assert(page.category and cats[page.category],"Invalid category given")
|
||||
checkstring(page.title,"Invalid title")
|
||||
local c = cats[page.category]
|
||||
c.entry[#c.entry+1] = page
|
||||
page.order = page.order or #c.entry
|
||||
end
|
||||
|
||||
function preferencesDialog.uifactory.space(page,layout,element)
|
||||
layout.currentx = layout.currentx + element.space
|
||||
return layout
|
||||
end
|
||||
function preferencesDialog.uifactory.group(page,layout,element)
|
||||
local margin = element.margin or 6
|
||||
local nl = {
|
||||
currentx = margin;
|
||||
currenty = margin+ (element.title and 12 or 8);
|
||||
maxsizex = 0;
|
||||
maxsizey = 0;
|
||||
minwidth = element.minwidth or 0;
|
||||
minheight = element.minheight or 0;
|
||||
margin = margin;
|
||||
layout = layout;
|
||||
parent = wx.wxStaticBox(layout.parent,wx.wxID_ANY,element.title or "",
|
||||
wx.wxPoint(layout.currentx,layout.currenty),
|
||||
wx.wxDefaultSize, element.borderstyle and wx["wxBORDER_"..element.borderstyle:upper()] or 0);
|
||||
}
|
||||
return nl
|
||||
end
|
||||
function preferencesDialog.uifactory.finishgroup(page,layout,element)
|
||||
local l = layout.layout
|
||||
layout.maxsizex = math.max(layout.minwidth,layout.maxsizex + layout.margin)
|
||||
layout.maxsizey = math.max(layout.minheight,layout.maxsizey + layout.margin)
|
||||
l.maxsizey = math.max(l.maxsizey,layout.maxsizey+l.currenty)
|
||||
l.currentx = l.currentx + layout.maxsizex
|
||||
l.maxsizex = math.max(l.maxsizex,l.currentx)
|
||||
layout.parent:SetSize(wx.wxSize(layout.maxsizex,layout.maxsizey))
|
||||
return l
|
||||
end
|
||||
|
||||
local function pos(layout) return layout.currentx,layout.currenty end
|
||||
local function fitin(el,layout)
|
||||
local x,y = pos(layout)
|
||||
local sz = el:GetBestFittingSize()
|
||||
el:SetSize(sz)
|
||||
layout.maxsizex = math.max(x+sz:GetWidth(),layout.maxsizex)
|
||||
layout.maxsizey = math.max(y+sz:GetHeight(),layout.maxsizey)
|
||||
layout.currentx = x+sz:GetWidth()
|
||||
return layout
|
||||
end
|
||||
|
||||
function preferencesDialog.uifactory.combobox(page,layout,element,value)
|
||||
local x,y = pos(layout)
|
||||
local id = ID("view.preferences.dialog.page."..page.title.."."..element.name)
|
||||
local cbox = wx.wxComboBox(layout.parent,id,"",wx.wxPoint(x,y-4),wx.wxDefaultSize,
|
||||
wx.wxArrayString(),wx.wxCB_READONLY)
|
||||
|
||||
if value then
|
||||
for i=1,#value do
|
||||
cbox:Append(value[i])
|
||||
end
|
||||
end
|
||||
|
||||
return fitin(cbox,layout)
|
||||
end
|
||||
|
||||
function preferencesDialog.uifactory.dirpicker(page,layout,element,value)
|
||||
local x,y = pos(layout)
|
||||
local id = ID("view.preferences.dialog.page."..page.title.."."..element.name)
|
||||
local picker = wx.wxDirPickerCtrl(layout.parent,id,value or "",element.title or "",wx.wxPoint(x,y-4))
|
||||
return fitin(picker,layout)
|
||||
end
|
||||
|
||||
function preferencesDialog.uifactory.edit (page,layout,element,value)
|
||||
local x,y = pos(layout)
|
||||
local id = ID("view.preferences.dialog.page."..page.title.."."..element.name)
|
||||
local edit = wx.wxTextCtrl(layout.parent,id,value or (""..x..","..y), wx.wxPoint(x,y-4))
|
||||
return fitin(edit,layout)
|
||||
end
|
||||
|
||||
function preferencesDialog.uifactory.linebreak(page,layout,element)
|
||||
layout.currentx = layout.margin or 0
|
||||
layout.currenty = layout.maxsizey + (element.space or 0)
|
||||
return layout
|
||||
end
|
||||
function preferencesDialog.uifactory.checkbox (page,layout,element, value)
|
||||
local x,y = pos(layout)
|
||||
local id = ID("view.preferences.dialog.page."..page.title.."."..element.name)
|
||||
local cbox = wx.wxCheckBox(layout.parent,id,element.title,wx.wxPoint(x,y))
|
||||
if value then cbox:SetValue(value) end
|
||||
return fitin(cbox,layout)
|
||||
end
|
||||
function preferencesDialog.uifactory.static(page,layout,element)
|
||||
local x,y = pos(layout)
|
||||
local static = wx.wxStaticText(layout.parent,wx.wxID_ANY,element.title,wx.wxPoint(x,y))
|
||||
return fitin(static,layout)
|
||||
end
|
||||
|
||||
function preferencesDialog.uifactory.space(page,layout,element)
|
||||
layout.currentx = layout.currentx + element.space
|
||||
return layout
|
||||
end
|
||||
function preferencesDialog.uifactory.group(page,layout,element)
|
||||
local margin = element.margin or 6
|
||||
local nl = {
|
||||
currentx = margin;
|
||||
currenty = margin+ (element.title and 12 or 8);
|
||||
maxsizex = 0;
|
||||
maxsizey = 0;
|
||||
minwidth = element.minwidth or 0;
|
||||
minheight = element.minheight or 0;
|
||||
margin = margin;
|
||||
layout = layout;
|
||||
parent = wx.wxStaticBox(layout.parent,wx.wxID_ANY,element.title or "",
|
||||
wx.wxPoint(layout.currentx,layout.currenty),
|
||||
wx.wxDefaultSize, element.borderstyle and wx["wxBORDER_"..element.borderstyle:upper()] or 0);
|
||||
}
|
||||
return nl
|
||||
end
|
||||
function preferencesDialog.uifactory.finishgroup(page,layout,element)
|
||||
local l = layout.layout
|
||||
layout.maxsizex = math.max(layout.minwidth,layout.maxsizex + layout.margin)
|
||||
layout.maxsizey = math.max(layout.minheight,layout.maxsizey + layout.margin)
|
||||
l.maxsizey = math.max(l.maxsizey,layout.maxsizey+l.currenty)
|
||||
l.currentx = l.currentx + layout.maxsizex
|
||||
l.maxsizex = math.max(l.maxsizex,l.currentx)
|
||||
layout.parent:SetSize(wx.wxSize(layout.maxsizex,layout.maxsizey))
|
||||
return l
|
||||
end
|
||||
function preferencesDialog.uifactory.linebreak(page,layout,element)
|
||||
layout.currentx = layout.margin or 0
|
||||
layout.currenty = layout.maxsizey + (element.space or 0)
|
||||
return layout
|
||||
end
|
||||
function preferencesDialog.uifactory.checkbox (page,layout,element, value)
|
||||
local x,y = layout.currentx,layout.currenty
|
||||
local id = ID("view.preferences.dialog.page."..page.title.."."..element.name)
|
||||
local cbox = wx.wxCheckBox(layout.parent,id,element.title,wx.wxPoint(x,y))
|
||||
local sz = cbox:GetBestFittingSize()
|
||||
cbox:SetSize(sz)
|
||||
layout.maxsizex = math.max(x+sz:GetWidth(),layout.maxsizex)
|
||||
layout.maxsizey = math.max(y+sz:GetHeight(),layout.maxsizey)
|
||||
layout.currentx = layout.maxsizex
|
||||
if value then cbox:SetValue(value) end
|
||||
return layout
|
||||
end
|
||||
function preferencesDialog.uifactory.static(page,layout,element)
|
||||
local x,y = layout.currentx,layout.currenty
|
||||
local static = wx.wxStaticText(layout.parent,wx.wxID_ANY,element.title,wx.wxPoint(x,y))
|
||||
local sz = static:GetBestFittingSize()
|
||||
static:SetSize(sz)
|
||||
layout.maxsizex = math.max(x+sz:GetWidth(),layout.maxsizex)
|
||||
layout.maxsizey = math.max(y+sz:GetHeight(),layout.maxsizey)
|
||||
layout.currentx = layout.maxsizex
|
||||
|
||||
return layout
|
||||
end
|
||||
|
||||
local function showpage(panel,page)
|
||||
--TODO: layout the page, load values, etc
|
||||
local data = page.onload()
|
||||
local layout = page.layout
|
||||
local layoutdata = {
|
||||
currentx = 0;
|
||||
currenty = 0;
|
||||
maxsizex = 0;
|
||||
maxsizey = 0;
|
||||
parent = panel;
|
||||
}
|
||||
for i,el in ipairs(layout) do
|
||||
assert(preferencesDialog.uifactory[el.type],"Unknown ui type type")
|
||||
layoutdata = assert(
|
||||
preferencesDialog.uifactory[el.type](page,layoutdata,el,data[el.name])
|
||||
)
|
||||
end
|
||||
panel:SetSize(layoutdata.maxsizex,layoutdata.maxsizey)
|
||||
--print(layoutdata.maxsizex,layoutdata.maxsizey)
|
||||
end
|
||||
|
||||
function preferencesDialog.show(event)
|
||||
local dialog = wx.wxDialog(ide.frame, ID "view.preferences.dialog","Preferences")
|
||||
|
||||
local id_btn_ok = ID "view.preferences.dialog.button.ok"
|
||||
local id_btn_cancel = ID "view.preferences.dialog.button.cancel"
|
||||
local id_btn_apply = ID "view.preferences.dialog.button.apply"
|
||||
|
||||
local panel_buttons = wx.wxPanel(dialog,ID "view.preferences.dialog.buttonpanel")
|
||||
local btn_ok = wx.wxButton(panel_buttons,id_btn_ok, "OK")
|
||||
local btn_cancel = wx.wxButton(panel_buttons,id_btn_cancel, "Cancel")
|
||||
local btn_apply = wx.wxButton(panel_buttons,id_btn_apply, "Apply")
|
||||
|
||||
dialog:Connect(id_btn_cancel, wx.wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
function (event)
|
||||
dialog:EndModal(0)
|
||||
end)
|
||||
dialog:Connect(id_btn_ok, wx.wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
function (event)
|
||||
dialog:EndModal(0)
|
||||
end)
|
||||
|
||||
local panel = wx.wxPanel(dialog,ID "view.preferences.dialog.panel",
|
||||
wx.wxDefaultPosition, wx.wxSize(600,400))
|
||||
|
||||
local projtree = wx.wxTreeCtrl(panel, ID "view.preferences.dialog.panel.tree",
|
||||
wx.wxDefaultPosition, wx.wxSize(180,400),
|
||||
wx.wxTR_HAS_BUTTONS + wx.wxTR_SINGLE + wx.wxTR_HIDE_ROOT)
|
||||
local preferencesPage = wx.wxPanel(panel,ID "view.preferences.dialog.page",
|
||||
wx.wxDefaultPosition, wx.wxSize(500,400))
|
||||
local panelsizer = wx.wxBoxSizer(wx.wxHORIZONTAL)
|
||||
panelsizer:Add(projtree,0,wx.wxALL + wx.wxALIGN_LEFT + wx.wxTOP + wx.wxBOTTOM,0)
|
||||
panelsizer:AddSpacer(5)
|
||||
panelsizer:Add(preferencesPage)
|
||||
panel:SetSizer(panelsizer)
|
||||
|
||||
local treecats = {}
|
||||
local catdata = {}
|
||||
table.sort(cats,function(a,b) return a.order < b.order end)
|
||||
local rootit = projtree:AddRoot("")
|
||||
|
||||
catdata[rootit:GetValue()] = {category = "root", children = treecats}
|
||||
for i=1,#cats do
|
||||
local it = projtree:AppendItem(rootit,cats[i].title)
|
||||
treecats[i] = it
|
||||
local c = cats[i]
|
||||
local children = {}
|
||||
catdata[it:GetValue()] = {category = c,children = children}
|
||||
for i=1,#c.entry do
|
||||
local e = c.entry[i]
|
||||
local it = projtree:AppendItem(it,e.title)
|
||||
catdata[it:GetValue()] = {page = e}
|
||||
children[i] = it
|
||||
end
|
||||
projtree:Expand(it)
|
||||
end
|
||||
|
||||
projtree:Expand(rootit)
|
||||
|
||||
local preferencesContent
|
||||
projtree:Connect( wx.wxEVT_COMMAND_TREE_SEL_CHANGED,
|
||||
function( event )
|
||||
local item_id = event:GetItem():GetValue()
|
||||
local data = catdata[item_id]
|
||||
if data.category then
|
||||
if data.children[1] then
|
||||
projtree:SelectItem(data.children[1])
|
||||
end
|
||||
else
|
||||
if preferencesContent then
|
||||
preferencesPage:RemoveChild(preferencesContent)
|
||||
end
|
||||
preferencesContent = wx.wxPanel(preferencesPage,wx.wxID_ANY)
|
||||
|
||||
showpage(preferencesContent,data.page)
|
||||
end
|
||||
end )
|
||||
|
||||
local topsizer = wx.wxBoxSizer(wx.wxVERTICAL)
|
||||
topsizer:Add(panel,0,wx.wxALL + wx.wxALIGN_CENTER,10)
|
||||
topsizer:Add(wx.wxStaticLine(dialog, wx.wxID_ANY), 0, wx.wxEXPAND + wx.wxLEFT + wx.wxRIGHT, 10)
|
||||
topsizer:Add(panel_buttons, 0, wx.wxALL + wx.wxALIGN_RIGHT, 10)
|
||||
|
||||
local buttonpanelsizer = wx.wxBoxSizer(wx.wxHORIZONTAL)
|
||||
buttonpanelsizer:Add(btn_cancel,0,wx.wxALL + wx.wxALIGN_RIGHT,0)
|
||||
buttonpanelsizer:AddSpacer(5)
|
||||
buttonpanelsizer:Add(btn_apply,0,wx.wxALL + wx.wxALIGN_RIGHT,0)
|
||||
buttonpanelsizer:AddSpacer(5)
|
||||
buttonpanelsizer:Add(btn_ok,0,wx.wxALL + wx.wxALIGN_RIGHT,0)
|
||||
panel_buttons:SetSizer(buttonpanelsizer)
|
||||
buttonpanelsizer:Fit(panel_buttons)
|
||||
|
||||
dialog:SetAutoLayout(true)
|
||||
dialog:SetSizer(topsizer)
|
||||
topsizer:Fit(dialog)
|
||||
dialog:Center()
|
||||
dialog:ShowModal()
|
||||
end
|
||||
@@ -100,30 +100,16 @@ function SettingsRestoreFileHistory(fntab)
|
||||
return outtab
|
||||
end
|
||||
|
||||
function SettingsAppendFileToHistory (filename)
|
||||
function SettingsSaveFileHistory (filehistory)
|
||||
local listname = "/filehistory"
|
||||
local oldlist = SettingsRestoreFileHistory(nil,listname)
|
||||
|
||||
-- if the file has been in the history before, remove it
|
||||
for i=#oldlist,1,-1 do
|
||||
if oldlist[i] == filename then table.remove(oldlist,i) end
|
||||
end
|
||||
|
||||
table.insert(oldlist,1,{filename=filename})
|
||||
|
||||
-- remove all entries that are no longer needed
|
||||
while #oldlist>ide.config.filehistorylength do table.remove(oldlist) end
|
||||
|
||||
local path = settings:GetPath()
|
||||
settings:DeleteGroup(listname)
|
||||
settings:SetPath(listname)
|
||||
|
||||
for i,doc in ipairs(oldlist) do
|
||||
for i,doc in ipairs(filehistory) do
|
||||
settings:Write(tostring(i), doc.filename)
|
||||
end
|
||||
|
||||
UpdateFileHistoryUI(oldlist)
|
||||
|
||||
settings:SetPath(path)
|
||||
end
|
||||
|
||||
@@ -371,13 +357,20 @@ function SettingsRestoreView()
|
||||
local layoutcur = uimgr:SavePerspective()
|
||||
local layout = settingsReadSafe(settings,"uimgrlayout",layoutcur)
|
||||
if (layout ~= layoutcur) then
|
||||
uimgr:LoadPerspective(layout)
|
||||
uimgr:LoadPerspective(layout, false)
|
||||
|
||||
-- check if debugging panes are not mentioned and float them
|
||||
local panes = frame.uimgr:GetAllPanes()
|
||||
for _, name in pairs({"stackpanel", "watchpanel"}) do
|
||||
local pane = frame.uimgr:GetPane(name)
|
||||
if not layout:find(name) then pane:Float() end
|
||||
end
|
||||
-- unfortunately need to explicitly (re-)assign the caption,
|
||||
-- as it's going to be restored from the config regardless of how
|
||||
-- it is set now (which affects its translation)
|
||||
uimgr:GetPane("projpanel"):Caption(TR("Project"))
|
||||
uimgr:Update()
|
||||
end
|
||||
uimgr:Update()
|
||||
|
||||
local layoutcur = saveNotebook(frame.notebook)
|
||||
local layout = settingsReadSafe(settings,"nblayout",layoutcur)
|
||||
@@ -443,6 +436,7 @@ function SettingsSaveAll()
|
||||
SettingsSaveProjectSession(FileTreeGetProjects())
|
||||
SettingsSaveFileSession(GetOpenFiles())
|
||||
SettingsSaveView()
|
||||
SettingsSaveFileHistory(GetFileHistory())
|
||||
SettingsSaveFramePosition(ide.frame, "MainFrame")
|
||||
SettingsSaveEditorSettings()
|
||||
end
|
||||
|
||||
@@ -280,8 +280,8 @@ local function executeShellCode(tx)
|
||||
|
||||
-- set the project dir as the current dir to allow "require" calls
|
||||
-- to work from shell
|
||||
local projectDir, cwd = FileTreeGetDir()
|
||||
if projectDir then
|
||||
local projectDir, cwd = FileTreeGetDir(), nil
|
||||
if projectDir and #projectDir > 0 then
|
||||
cwd = wx.wxFileName.GetCwd()
|
||||
wx.wxFileName.SetCwd(projectDir)
|
||||
end
|
||||
@@ -292,7 +292,7 @@ local function executeShellCode(tx)
|
||||
end))
|
||||
|
||||
-- restore the current dir
|
||||
if projectDir then wx.wxFileName.SetCwd(cwd) end
|
||||
if cwd then wx.wxFileName.SetCwd(cwd) end
|
||||
|
||||
if ok and (addedret or #res > 0) then
|
||||
if addedret then
|
||||
@@ -431,10 +431,37 @@ out:Connect(wx.wxEVT_KEY_DOWN,
|
||||
end)
|
||||
|
||||
local function inputEditable(line)
|
||||
return caretOnPromptLine(fale, line) and
|
||||
return caretOnPromptLine(false, line) and
|
||||
not (out:LineFromPosition(out:GetSelectionStart()) < getPromptLine())
|
||||
end
|
||||
|
||||
-- new Scintilla changed the way markers move when the text is updated
|
||||
-- ticket: http://sourceforge.net/p/scintilla/bugs/939/
|
||||
-- discussion: https://groups.google.com/forum/?hl=en&fromgroups#!topic/scintilla-interest/4giFiKG4VXo
|
||||
if ide.wxver >= "2.9.5" then
|
||||
-- this is a workaround that stores a position of the last prompt marker
|
||||
-- before insert and restores the same position after (as the marker)
|
||||
-- could have moved if the text is added at the beginning of the line.
|
||||
local promptAt
|
||||
out:Connect(wxstc.wxEVT_STC_MODIFIED,
|
||||
function (event)
|
||||
local evtype = event:GetModificationType()
|
||||
if bit.band(evtype, wxstc.wxSTC_MOD_BEFOREINSERT) ~= 0 then
|
||||
local promptLine = getPromptLine()
|
||||
if promptLine and event:GetPosition() == out:PositionFromLine(promptLine)
|
||||
then promptAt = promptLine end
|
||||
end
|
||||
if bit.band(evtype, wxstc.wxSTC_MOD_INSERTTEXT) ~= 0 then
|
||||
local promptLine = getPromptLine()
|
||||
if promptLine and promptAt then
|
||||
out:MarkerDelete(promptLine, PROMPT_MARKER)
|
||||
out:MarkerAdd(promptAt, PROMPT_MARKER)
|
||||
promptAt = nil
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
out:Connect(wxstc.wxEVT_STC_UPDATEUI,
|
||||
function (event) out:SetReadOnly(not inputEditable()) end)
|
||||
|
||||
|
||||
@@ -69,14 +69,15 @@ else -- something different is running on our port
|
||||
local failed = false
|
||||
for index = 2, #arg do
|
||||
local fileName = arg[index]
|
||||
if fileName ~= "--" then
|
||||
if fileName ~= "--"
|
||||
-- on OSX, the command line includes -psn parameter, so ignore it
|
||||
and (ide.osname ~= 'Macintosh' or not fileName:find("^-psn")) then
|
||||
cln:send(protocol.client.requestloading:format(fileName))
|
||||
|
||||
local msg,err = cln:receive()
|
||||
if msg ~= protocol.server.answerok then
|
||||
failed = true
|
||||
print(err,msg)
|
||||
else
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -42,7 +42,7 @@ function StylesGetDefault()
|
||||
bracematch = {fg = {0, 0, 255}, b = true},
|
||||
bracemiss = {fg = {255, 0, 0 }, b = true},
|
||||
ctrlchar = nil,
|
||||
indent = {fg = {192, 192, 192}, bg = {255, 255, 255}},
|
||||
indent = {fg = {192, 192, 230}, bg = {255, 255, 255}},
|
||||
calltip = nil,
|
||||
|
||||
-- common special (need custom fg & bg)
|
||||
@@ -53,7 +53,8 @@ function StylesGetDefault()
|
||||
fold = {fg = {90, 90, 80}, bg = {250, 250, 250}},
|
||||
whitespace = nil,
|
||||
|
||||
fncall = {fg = {175, 175, 255}, st = wxstc.wxSTC_INDIC_TT},
|
||||
fncall = {fg = {128, 128, 255},
|
||||
st = ide.wxver >= "2.9.5" and wxstc.wxSTC_INDIC_ROUNDBOX or wxstc.wxSTC_INDIC_TT},
|
||||
|
||||
-- markup
|
||||
['|'] = {fg = {127, 0, 127}},
|
||||
|
||||
153
src/main.lua
153
src/main.lua
@@ -3,33 +3,34 @@
|
||||
|
||||
-- put bin/ and lualibs/ first to avoid conflicts with included modules
|
||||
-- that may have other versions present somewhere else in path/cpath.
|
||||
-- don't need to do this on Linux where we expect all the libraries
|
||||
-- and binaries to be installed in *regular* places.
|
||||
local iswindows = os.getenv('WINDIR') or (os.getenv('OS') or ''):match('[Ww]indows')
|
||||
local islinux = not iswindows and not os.getenv('DYLD_LIBRARY_PATH') and io.open("/proc")
|
||||
local arch = "x86" -- use 32bit by default
|
||||
|
||||
if iswindows or not pcall(require, "wx")
|
||||
or wx.wxPlatformInfo.Get():GetOperatingSystemFamilyName() == 'Macintosh' then
|
||||
package.cpath = (iswindows
|
||||
and 'bin/?.dll;bin/clibs/?.dll;'
|
||||
or 'bin/clibs/?.dylib;bin/lib?.dylib;')
|
||||
.. package.cpath
|
||||
if islinux then
|
||||
local file = io.popen("uname -m")
|
||||
if file then
|
||||
arch = file:read("*a"):find("x86_64") and "x64" or "x86"
|
||||
file:close()
|
||||
end
|
||||
end
|
||||
|
||||
package.cpath = (
|
||||
iswindows and 'bin/?.dll;bin/clibs/?.dll;' or
|
||||
islinux and ('bin/linux/%s/lib?.so;bin/linux/%s/clibs/?.so;'):format(arch,arch) or
|
||||
--[[isosx]] 'bin/lib?.dylib;bin/clibs/?.dylib;')
|
||||
.. package.cpath
|
||||
package.path = 'lualibs/?.lua;lualibs/?/?.lua;lualibs/?/init.lua;lualibs/?/?/?.lua;lualibs/?/?/init.lua;'
|
||||
.. package.path
|
||||
|
||||
require("wx")
|
||||
require("bit")
|
||||
|
||||
dofile "src/misc/util.lua"
|
||||
dofile "src/util.lua"
|
||||
|
||||
-----------
|
||||
-- IDE
|
||||
--
|
||||
-- Setup important defaults
|
||||
dofile "src/editor/ids.lua"
|
||||
dofile "src/editor/style.lua"
|
||||
|
||||
ide = {
|
||||
config = {
|
||||
path = {
|
||||
@@ -51,13 +52,14 @@ ide = {
|
||||
},
|
||||
outputshell = {},
|
||||
filetree = {},
|
||||
funclist = {},
|
||||
|
||||
keymap = {},
|
||||
messages = {},
|
||||
language = "en",
|
||||
|
||||
styles = StylesGetDefault(),
|
||||
stylesoutshell = StylesGetDefault(),
|
||||
styles = nil,
|
||||
stylesoutshell = nil,
|
||||
interpreter = "_undefined_",
|
||||
|
||||
autocomplete = true,
|
||||
@@ -121,12 +123,30 @@ ide = {
|
||||
oNormal = nil,
|
||||
oItalic = nil,
|
||||
fNormal = nil,
|
||||
}
|
||||
dNormal = nil,
|
||||
},
|
||||
|
||||
osname = wx.wxPlatformInfo.Get():GetOperatingSystemFamilyName(),
|
||||
osarch = arch,
|
||||
wxver = string.match(wx.wxVERSION_STRING, "[%d%.]+"),
|
||||
}
|
||||
|
||||
-- add wx.wxMOD_RAW_CONTROL as it's missing in wxlua 2.8.12.3;
|
||||
-- provide default for wx.wxMOD_CONTROL as it's missing in wxlua 2.8 that
|
||||
-- is available through Linux package managers
|
||||
if not wx.wxMOD_CONTROL then wx.wxMOD_CONTROL = 0x02 end
|
||||
if not wx.wxMOD_RAW_CONTROL then
|
||||
wx.wxMOD_RAW_CONTROL = ide.osname == 'Macintosh' and 0x10 or wx.wxMOD_CONTROL
|
||||
end
|
||||
|
||||
dofile "src/editor/ids.lua"
|
||||
dofile "src/editor/style.lua"
|
||||
dofile "src/editor/keymap.lua"
|
||||
|
||||
function setLuaPaths(mainpath, osname)
|
||||
ide.config.styles = StylesGetDefault()
|
||||
ide.config.stylesoutshell = StylesGetDefault()
|
||||
|
||||
local function setLuaPaths(mainpath, osname)
|
||||
-- use LUA_DEV to setup paths for Lua for Windows modules if installed
|
||||
local luadev = osname == "Windows" and os.getenv('LUA_DEV')
|
||||
local luadev_path = (luadev
|
||||
@@ -152,7 +172,9 @@ function setLuaPaths(mainpath, osname)
|
||||
local clibs =
|
||||
osname == "Windows" and mainpath.."bin/?.dll;"..mainpath.."bin/clibs/?.dll" or
|
||||
osname == "Macintosh" and mainpath.."bin/lib?.dylib;"..mainpath.."bin/clibs/?.dylib" or
|
||||
osname == "Unix" and mainpath.."bin/?.so;"..mainpath.."bin/clibs/?.so" or nil
|
||||
osname == "Unix" and mainpath..("bin/linux/%s/lib?.so;"):format(arch)
|
||||
..mainpath..("bin/linux/%s/clibs/?.so"):format(arch) or
|
||||
nil
|
||||
if clibs then wx.wxSetEnv("LUA_CPATH",
|
||||
package.cpath .. ';' .. clibs .. ';' .. luadev_cpath) end
|
||||
end
|
||||
@@ -163,11 +185,10 @@ local filenames = {}
|
||||
local configs = {}
|
||||
do
|
||||
local arg = {...}
|
||||
local fullPath = arg[1] -- first argument must be the application name
|
||||
assert(type(fullPath) == "string", "first argument must be application name")
|
||||
-- application name is expected as the first argument
|
||||
local fullPath = arg[1] or "zbstudio"
|
||||
|
||||
ide.arg = arg
|
||||
ide.osname = wx.wxPlatformInfo.Get():GetOperatingSystemFamilyName()
|
||||
|
||||
-- on Windows use GetExecutablePath, which is Unicode friendly,
|
||||
-- whereas wxGetCwd() is not (at least in wxlua 2.8.12.2).
|
||||
@@ -185,12 +206,7 @@ do
|
||||
|
||||
for index = 2, #arg do
|
||||
if (arg[index] == "-cfg" and index+1 <= #arg) then
|
||||
local str = arg[index+1]
|
||||
if #str < 4 then
|
||||
print("Comandline: -cfg arg data not passed as string")
|
||||
else
|
||||
table.insert(configs,str)
|
||||
end
|
||||
table.insert(configs,arg[index+1])
|
||||
elseif arg[index-1] ~= "-cfg" then
|
||||
table.insert(filenames,arg[index])
|
||||
end
|
||||
@@ -203,18 +219,17 @@ end
|
||||
-- process application
|
||||
|
||||
ide.app = dofile(ide.config.path.app.."/app.lua")
|
||||
local app = ide.app
|
||||
assert(app)
|
||||
local app = assert(ide.app)
|
||||
|
||||
local function addToTab(tab,file)
|
||||
local cfgfn,err = loadfile(file)
|
||||
if not cfgfn then
|
||||
print(("Error while loading configuration file: %s"):format(err))
|
||||
print(("Error while loading configuration file: '%s'."):format(err))
|
||||
else
|
||||
local name = file:match("([a-zA-Z_0-9]+)%.lua$")
|
||||
local success, result = pcall(function()return cfgfn(assert(_G or _ENV))end)
|
||||
if not success then
|
||||
print(("Error while processing configuration file: %s"):format(result))
|
||||
print(("Error while processing configuration file: '%s'."):format(result))
|
||||
elseif name then
|
||||
if (tab[name]) then
|
||||
local out = tab[name]
|
||||
@@ -230,8 +245,8 @@ end
|
||||
|
||||
-- load interpreters
|
||||
local function loadInterpreters(filter)
|
||||
for _, file in ipairs(FileSysGet("interpreters/*.*", wx.wxFILE)) do
|
||||
if file:match "%.lua$" and (filter or app.loadfilters.interpreters)(file) then
|
||||
for _, file in ipairs(FileSysGetRecursive("interpreters", true, "*.lua")) do
|
||||
if (filter or app.loadfilters.interpreters)(file) then
|
||||
addToTab(ide.interpreters,file)
|
||||
end
|
||||
end
|
||||
@@ -239,8 +254,8 @@ end
|
||||
|
||||
-- load specs
|
||||
local function loadSpecs(filter)
|
||||
for _, file in ipairs(FileSysGet("spec/*.*", wx.wxFILE)) do
|
||||
if file:match("%.lua$") and (filter or app.loadfilters.specs)(file) then
|
||||
for _, file in ipairs(FileSysGetRecursive("spec", true, "*.lua")) do
|
||||
if (filter or app.loadfilters.specs)(file) then
|
||||
addToTab(ide.specs,file)
|
||||
end
|
||||
end
|
||||
@@ -272,8 +287,8 @@ end
|
||||
|
||||
-- load tools
|
||||
local function loadTools(filter)
|
||||
for _, file in ipairs(FileSysGet("tools/*.*", wx.wxFILE)) do
|
||||
if file:match "%.lua$" and (filter or app.loadfilters.tools)(file) then
|
||||
for _, file in ipairs(FileSysGetRecursive("tools", false, "*.lua")) do
|
||||
if (filter or app.loadfilters.tools)(file) then
|
||||
addToTab(ide.tools,file)
|
||||
end
|
||||
end
|
||||
@@ -287,13 +302,14 @@ local resumePrint do
|
||||
print = function(...) errors[#errors+1] = {...} end
|
||||
resumePrint = function()
|
||||
print = origprint
|
||||
for _, e in ipairs(errors) do DisplayOutput(unpack(e), "\n") end
|
||||
for _, e in ipairs(errors) do DisplayOutputLn(unpack(e)) end
|
||||
end
|
||||
end
|
||||
|
||||
-----------------------
|
||||
-- load config
|
||||
local function addConfig(filename,isstring)
|
||||
if not filename then return end
|
||||
-- skip those files that don't exist
|
||||
if not isstring and not wx.wxFileName(filename):FileExists() then return end
|
||||
-- if it's marked as command, but exists as a file, load it as a file
|
||||
@@ -305,7 +321,7 @@ local function addConfig(filename,isstring)
|
||||
else msg, cfgfn, err = "file", loadfile(filename) end
|
||||
|
||||
if not cfgfn then
|
||||
print(("Error while loading configuration %s: %s"):format(msg, err))
|
||||
print(("Error while loading configuration %s: '%s'."):format(msg, err))
|
||||
else
|
||||
ide.config.os = os
|
||||
ide.config.wxstc = wxstc
|
||||
@@ -314,7 +330,7 @@ local function addConfig(filename,isstring)
|
||||
setfenv(cfgfn,ide.config)
|
||||
local _, err = pcall(function()cfgfn(assert(_G or _ENV))end)
|
||||
if err then
|
||||
print(("Error while processing configuration %s: %s"):format(msg, err))
|
||||
print(("Error while processing configuration %s: '%s'."):format(msg, err))
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -328,6 +344,22 @@ end
|
||||
|
||||
addConfig(ide.config.path.app.."/config.lua")
|
||||
|
||||
ide.editorApp:SetAppName(GetIDEString("settingsapp"))
|
||||
|
||||
-- check if the .ini file needs to be migrated on Windows
|
||||
if ide.osname == 'Windows' and ide.wxver >= "2.9.5" then
|
||||
-- Windows used to have local ini file kept in wx.wxGetHomeDir (before 2.9),
|
||||
-- but since 2.9 it's in GetUserConfigDir(), so migrate it.
|
||||
local ini = ide.editorApp:GetAppName() .. ".ini"
|
||||
local old = wx.wxFileName(wx.wxGetHomeDir(), ini)
|
||||
local new = wx.wxFileName(wx.wxStandardPaths.Get():GetUserConfigDir(), ini)
|
||||
if old:FileExists() and not new:FileExists() then
|
||||
FileCopy(old:GetFullPath(), new:GetFullPath())
|
||||
print(("Migrated configuration file from '%s' to '%s'.")
|
||||
:format(old:GetFullPath(), new:GetFullPath()))
|
||||
end
|
||||
end
|
||||
|
||||
----------------------
|
||||
-- process plugins
|
||||
|
||||
@@ -338,20 +370,19 @@ loadSpecs()
|
||||
loadTools()
|
||||
|
||||
do
|
||||
-- process user config
|
||||
for _, file in ipairs(FileSysGet("cfg/user.lua", wx.wxFILE)) do
|
||||
addConfig(file)
|
||||
end
|
||||
local home = os.getenv("HOME")
|
||||
if home then
|
||||
for _, file in ipairs(FileSysGet(home .. "/.zbstudio/user.lua", wx.wxFILE)) do
|
||||
addConfig(file)
|
||||
end
|
||||
end
|
||||
ide.configs = {
|
||||
system = MergeFullPath("cfg", "user.lua"),
|
||||
user = home and MergeFullPath(home, ".zbstudio/user.lua"),
|
||||
}
|
||||
|
||||
-- process configs
|
||||
addConfig(ide.configs.system)
|
||||
addConfig(ide.configs.user)
|
||||
|
||||
-- process all other configs (if any)
|
||||
for _, v in ipairs(configs) do
|
||||
addConfig(v, true)
|
||||
end
|
||||
for _, v in ipairs(configs) do addConfig(v, true) end
|
||||
|
||||
configs = nil
|
||||
local sep = string_Pathsep
|
||||
if ide.config.language then
|
||||
@@ -359,15 +390,12 @@ do
|
||||
end
|
||||
end
|
||||
|
||||
-- load this after preinit and processing configs to allow
|
||||
-- each of the lists to be modified
|
||||
|
||||
---------------
|
||||
-- Load App
|
||||
|
||||
for _, file in ipairs({
|
||||
"markup", "settings", "singleinstance", "iofilters",
|
||||
"gui", "filetree", "output", "debugger", "preferences",
|
||||
"gui", "filetree", "output", "debugger",
|
||||
"editor", "findreplace", "commands", "autocomplete", "shellbox",
|
||||
"menu_file", "menu_edit", "menu_search",
|
||||
"menu_view", "menu_project", "menu_tools", "menu_help",
|
||||
@@ -375,19 +403,17 @@ for _, file in ipairs({
|
||||
dofile("src/editor/"..file..".lua")
|
||||
end
|
||||
|
||||
dofile "src/preferences/editor.lua"
|
||||
dofile "src/preferences/project.lua"
|
||||
dofile "src/version.lua"
|
||||
|
||||
-- load rest of settings
|
||||
SettingsRestoreEditorSettings()
|
||||
SettingsRestoreFramePosition(ide.frame, "MainFrame")
|
||||
SettingsRestoreFileHistory(SetFileHistory)
|
||||
SettingsRestoreFileSession(function(tabs, params)
|
||||
if params and params.recovery
|
||||
then return SetOpenTabs(params)
|
||||
else return SetOpenFiles(tabs, params) end
|
||||
end)
|
||||
SettingsRestoreFileHistory(UpdateFileHistoryUI)
|
||||
SettingsRestoreProjectSession(FileTreeSetProjects)
|
||||
SettingsRestoreView()
|
||||
|
||||
@@ -411,7 +437,7 @@ if app.postinit then app.postinit() end
|
||||
-- app-specific menus (Help/About), which are not recognized by MacOS
|
||||
-- as special items unless SetMenuBar is done after menus are populated.
|
||||
ide.frame:SetMenuBar(ide.frame.menuBar)
|
||||
if ide.osname == 'Macintosh' then -- force refresh to fix the filetree
|
||||
if ide.wxver < "2.9.5" and ide.osname == 'Macintosh' then -- force refresh to fix the filetree
|
||||
pcall(function() ide.frame:ShowFullScreen(true) ide.frame:ShowFullScreen(false) end)
|
||||
end
|
||||
|
||||
@@ -419,3 +445,10 @@ resumePrint()
|
||||
|
||||
ide.frame:Show(true)
|
||||
wx.wxGetApp():MainLoop()
|
||||
|
||||
-- There are several reasons for this call:
|
||||
-- (1) to fix a crash on OSX when closing with debugging in progress.
|
||||
-- (2) to fix a crash on Linux 32/64bit during GC cleanup in wxlua
|
||||
-- after an external process has been started from the IDE.
|
||||
-- (3) to fix exit on Windows when started as "bin\lua src\main.lua".
|
||||
os.exit()
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
-- authors: Luxinia Dev (Eike Decker & Christoph Kubisch)
|
||||
---------------------------------------------------------
|
||||
|
||||
preferencesDialog.addCategory {
|
||||
category = "editor";
|
||||
title = "Editor";
|
||||
}
|
||||
|
||||
preferencesDialog.addPage {
|
||||
title = "Basic preferences";
|
||||
category = "editor";
|
||||
layout = {
|
||||
{type = 'group',title="Sessions"; minheight = 100; minwidth = 100};
|
||||
{type = "checkbox"; title = "Reopen files";name = 'session_restore'};
|
||||
{type = 'finishgroup'};
|
||||
{type = 'space'; space = 4};
|
||||
};
|
||||
onload = function ()
|
||||
return {testbox = true}
|
||||
end;
|
||||
onsave = function (values)
|
||||
end
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
-- authors: Luxinia Dev (Eike Decker & Christoph Kubisch)
|
||||
---------------------------------------------------------
|
||||
|
||||
preferencesDialog.addCategory {
|
||||
category = "project";
|
||||
title = "Project";
|
||||
}
|
||||
|
||||
preferencesDialog.addPage {
|
||||
title = "Project settings";
|
||||
category = "project";
|
||||
layout = {
|
||||
{type = 'group',title="Visible menus"; minheight = 100; minwidth = 100};
|
||||
{type = "checkbox"; title = "Tools";name = 'tools'};
|
||||
{type = 'linebreak'; space = 4};
|
||||
{type = "checkbox"; title = "Help";name = 'help'};
|
||||
{type = 'linebreak'; space = 4};
|
||||
--{type='static'; title = "foo"};
|
||||
{type = 'finishgroup'};
|
||||
{type = "space"; space = 4};
|
||||
{type = 'group',title="Interpreter"; minheight = 100; minwidth = 100};
|
||||
{type = "static"; title = "Interpreter"};
|
||||
{type = "space"; space = 4};
|
||||
{type = "combobox"; name = "interpreterlist"};
|
||||
{type = 'linebreak'; space = 4};
|
||||
{type = "static";title = "Working directory"};
|
||||
{type = "dirpicker"; name = "workingdir", title='Working directory'};
|
||||
{type = 'linebreak'; space = 4};
|
||||
{type = "static"; title = "Argument"};
|
||||
{type = "edit"; name = "argument"};
|
||||
{type = 'finishgroup'};
|
||||
};
|
||||
onload = function () return {
|
||||
interpreterlist = {"1","2"}
|
||||
} end;
|
||||
onsave = function (values) end;
|
||||
}
|
||||
@@ -161,25 +161,39 @@ function FileSysHasContent(dir)
|
||||
return #f>0
|
||||
end
|
||||
|
||||
function FileSysGet(dir,spec)
|
||||
function FileSysGetRecursive(path, recursive, spec, skip)
|
||||
spec = spec or "*"
|
||||
local content = {}
|
||||
local browse = wx.wxFileSystem()
|
||||
if not wx.wxFileName(dir):DirExists() then
|
||||
return content
|
||||
end
|
||||
local f = browse:FindFirst(dir,spec)
|
||||
while #f>0 do
|
||||
if f:match("^file:") then -- remove file: protocol (wx2.9+)
|
||||
f = f:gsub(ide.osname == "Windows" and "^file:/?" or "^file:","")
|
||||
:gsub('%%(%x%x)', function(n) return string.char(tonumber(n, 16)) end)
|
||||
local sep = string.char(wx.wxFileName.GetPathSeparator())
|
||||
|
||||
-- recursion is done in all folders but only those folders that match
|
||||
-- the spec are returned. This is the pattern that matches the spec.
|
||||
local specmask = spec:gsub("%.", "%%."):gsub("%*", ".*").."$"
|
||||
|
||||
local function getDir(path, spec)
|
||||
local dir = wx.wxDir(path)
|
||||
if not dir:IsOpened() then return end
|
||||
|
||||
local found, file = dir:GetFirst("*", wx.wxDIR_DIRS)
|
||||
while found do
|
||||
if not skip or not file:find(skip) then
|
||||
local fname = wx.wxFileName(path, file):GetFullPath()
|
||||
if fname:find(specmask) then table.insert(content, fname..sep) end
|
||||
if recursive then getDir(fname, spec) end
|
||||
end
|
||||
found, file = dir:GetNext()
|
||||
end
|
||||
local found, file = dir:GetFirst(spec, wx.wxDIR_FILES)
|
||||
while found do
|
||||
if not skip or not file:find(skip) then
|
||||
local fname = wx.wxFileName(path, file):GetFullPath()
|
||||
table.insert(content, fname)
|
||||
end
|
||||
found, file = dir:GetNext()
|
||||
end
|
||||
local file = wx.wxFileName(f)
|
||||
-- normalize path if possible to correct separators for the local FS
|
||||
table.insert(content,
|
||||
file:Normalize(wx.wxPATH_NORM_ALL) and file:GetFullPath() or f)
|
||||
f = browse:FindNext()
|
||||
end
|
||||
if ide.osname == 'Unix' then table.sort(content) end
|
||||
getDir(path, spec)
|
||||
|
||||
return content
|
||||
end
|
||||
|
||||
@@ -190,7 +204,8 @@ function GetFullPathIfExists(p, f)
|
||||
-- f = 'xyz/main.lua' work correctly. Normalize() returns true if done.
|
||||
return (file:Normalize(wx.wxPATH_NORM_ALL, p)
|
||||
and file:FileExists()
|
||||
and file:GetFullPath())
|
||||
and file:GetFullPath()
|
||||
or nil)
|
||||
end
|
||||
|
||||
function MergeFullPath(p, f)
|
||||
@@ -199,7 +214,8 @@ function MergeFullPath(p, f)
|
||||
-- Normalize call is needed to make the case of p = '/abc/def' and
|
||||
-- f = 'xyz/main.lua' work correctly. Normalize() returns true if done.
|
||||
return (file:Normalize(wx.wxPATH_NORM_ALL, p)
|
||||
and file:GetFullPath())
|
||||
and file:GetFullPath()
|
||||
or nil)
|
||||
end
|
||||
|
||||
function FileWrite(file,content)
|
||||
63
t/1-findreplace.lua
Normal file
63
t/1-findreplace.lua
Normal file
@@ -0,0 +1,63 @@
|
||||
local findReplace = ide.findReplace
|
||||
|
||||
local editor = NewFile()
|
||||
ok(editor, "Open New file.")
|
||||
|
||||
local search = "123"
|
||||
local replace = "4"
|
||||
editor:AppendText(search..search.."\n"..search..search)
|
||||
|
||||
ide.frame:ProcessEvent(wx.wxCommandEvent(wx.wxEVT_COMMAND_MENU_SELECTED, ID_FIND))
|
||||
ok(findReplace.dialog, "Open Find/Replace dialog.")
|
||||
|
||||
findReplace.findText = search
|
||||
ok(findReplace:HasText(), "Update text to search.")
|
||||
|
||||
findReplace:FindString()
|
||||
ok(editor:GetSelectionStart() ~= editor:GetSelectionEnd(), "Find text with Find Next.")
|
||||
|
||||
local selend = editor:GetSelectionEnd()
|
||||
findReplace:FindString()
|
||||
is(editor:GetSelectionStart(), selend, "Find Next doesn't skip consecutive matches.")
|
||||
|
||||
editor:GotoPos(0) -- reset current selection
|
||||
local findnext = wx.wxUpdateUIEvent(ID_FINDNEXT)
|
||||
ide.frame:ProcessEvent(findnext)
|
||||
ok(findnext:GetEnabled(), "Quick find is enabled without current selection.")
|
||||
|
||||
ide.frame:ProcessEvent(wx.wxCommandEvent(wx.wxEVT_COMMAND_MENU_SELECTED, ID_FINDNEXT))
|
||||
is(editor:GetSelectionEnd(), selend, "Quick Find works based on previous search.")
|
||||
|
||||
ide.frame:ProcessEvent(wx.wxCommandEvent(wx.wxEVT_COMMAND_MENU_SELECTED, ID_FINDNEXT))
|
||||
is(editor:GetSelectionStart(), selend, "Quick Find finds next match.")
|
||||
|
||||
-- replace the text once
|
||||
findReplace.replaceText = replace
|
||||
findReplace:ReplaceString()
|
||||
local _, replacements = editor:GetText():gsub(replace, replace)
|
||||
is(replacements, 1, "Replace replaces once.")
|
||||
|
||||
-- replace the current text and to the end of file
|
||||
editor:GotoPos(3)
|
||||
findReplace.fWrap = false
|
||||
findReplace:ReplaceString(true)
|
||||
local _, replacements = editor:GetText():gsub(replace, replace)
|
||||
is(replacements, 3, "Replace All without wrapping replaces to the end of file.")
|
||||
|
||||
local expected = search..replace.."\n"..replace..replace
|
||||
is(editor:GetText(), expected, "Replace All with Wrap Around result is as expected.")
|
||||
|
||||
-- start after the match to test wrapping
|
||||
editor:AppendText("\n"..search..search)
|
||||
editor:GotoPos(3)
|
||||
findReplace.fWrap = true
|
||||
findReplace:ReplaceString(true)
|
||||
ok(not editor:GetText():find(search), "Replace All with Wrap Around replaces everything.")
|
||||
|
||||
local expected = replace..replace.."\n"..replace..replace.."\n"..replace..replace
|
||||
is(editor:GetText(), expected, "Replace All without Wrap Around result is as expected.")
|
||||
|
||||
-- cleanup
|
||||
ide.findReplace.dialog:Hide()
|
||||
while editor:CanUndo() do editor:Undo() end
|
||||
ClosePage()
|
||||
2
t/test.bat
Normal file
2
t/test.bat
Normal file
@@ -0,0 +1,2 @@
|
||||
@echo off
|
||||
zbstudio -cfg t/test.lua
|
||||
42
t/test.lua
Normal file
42
t/test.lua
Normal file
@@ -0,0 +1,42 @@
|
||||
local G = ... -- this now points to the global environment in the script
|
||||
|
||||
local env = {}
|
||||
G.setmetatable(env, {__index = G})
|
||||
|
||||
local ide = G.ide
|
||||
local postinit = ide.app.postinit
|
||||
ide.app.postinit = function()
|
||||
if postinit then postinit() end
|
||||
|
||||
-- load test module in the environment for tests
|
||||
local function testwell(report)
|
||||
local tw = require "testwell"
|
||||
if report then tw.report() end
|
||||
end
|
||||
setfenv(testwell, env)
|
||||
testwell()
|
||||
|
||||
-- find all test files and load them
|
||||
local files = FileSysGetRecursive("t", true, "*.lua")
|
||||
for k, v in ipairs(files) do
|
||||
if v:find("[/\\]test%.lua$") then files[k] = nil end
|
||||
end
|
||||
table.sort(files)
|
||||
|
||||
for _,file in ipairs(files) do
|
||||
local testfn, err = loadfile(file)
|
||||
if not testfn then
|
||||
print(("Error loading test file '%s': '%s'."):format(file, err))
|
||||
else
|
||||
setfenv(testfn, env)
|
||||
local ok, err = pcall(testfn)
|
||||
if not ok then
|
||||
print(("Error executing test file '%s': '%s'."):format(file, err))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
testwell(true)
|
||||
end
|
||||
|
||||
G.setfenv(ide.app.postinit, env)
|
||||
352
tools/glslc.lua
Normal file
352
tools/glslc.lua
Normal file
@@ -0,0 +1,352 @@
|
||||
-- authors: Luxinia Dev (Eike Decker & Christoph Kubisch)
|
||||
---------------------------------------------------------
|
||||
|
||||
local binpath = os.getenv("GLSLC_BIN_PATH")
|
||||
|
||||
return binpath and {
|
||||
fninit = function(frame,menuBar)
|
||||
binpath = ide.config.path.glslcbin or os.getenv("GLSLC_BIN_PATH")
|
||||
|
||||
local myMenu = wx.wxMenu{
|
||||
{ ID "glslc.compile.input", "&Custom Args\tCtrl-L", "when set a popup for custom compiler args will be envoked", wx.wxITEM_CHECK },
|
||||
{ },
|
||||
{ ID "glslc.compile.vertex", "Compile &Vertex\tCtrl-1", "Compile Vertex program" },
|
||||
{ ID "glslc.compile.fragment", "Compile &Fragment\tCtrl-2", "Compile Fragment program" },
|
||||
{ ID "glslc.compile.geometry", "Compile &Geometry\tCtrl-3", "Compile Geometry program" },
|
||||
{ ID "glslc.compile.tessctrl", "Compile T.Ctrl\tCtrl-4", "Compile T.Ctrl program" },
|
||||
{ ID "glslc.compile.tesseval", "Compile T.Eval\tCtrl-5", "Compile T.Eval program" },
|
||||
{ ID "glslc.compile.compute", "Compile Compute\tCtrl-6", "Compile Compute program" },
|
||||
{ },
|
||||
{ ID "glslc.format.asm", "Annotate ASM", "indent and add comments to ASM output" },
|
||||
}
|
||||
menuBar:Append(myMenu, "&GLSL")
|
||||
|
||||
local data = {}
|
||||
data.customarg = false
|
||||
data.custom = ""
|
||||
data.domains = {
|
||||
[ID "glslc.compile.vertex"] = 1,
|
||||
[ID "glslc.compile.fragment"] = 2,
|
||||
[ID "glslc.compile.geometry"] = 3,
|
||||
[ID "glslc.compile.tessctrl"] = 4,
|
||||
[ID "glslc.compile.tesseval"] = 5,
|
||||
[ID "glslc.compile.compute"] = 6,
|
||||
}
|
||||
data.domainprofiles = {
|
||||
"vertex",
|
||||
"fragment",
|
||||
"geometry",
|
||||
"tesscontrol",
|
||||
"tessevaluation",
|
||||
"compute",
|
||||
}
|
||||
data.domaindefs = {
|
||||
" -D_VERTEX_ ",
|
||||
" -D_FRAGMENT_ ",
|
||||
" -D_GEOMETRY_ ",
|
||||
" -D_TESS_CONTROL_ ",
|
||||
" -D_TESS_EVAL_ ",
|
||||
" -D_COMPUTE_ ",
|
||||
}
|
||||
|
||||
local function beautifyAsm(tx)
|
||||
local newtx = ""
|
||||
local indent = 0
|
||||
local maxindent = 0
|
||||
local startindent = {
|
||||
["IF"]=true,["REP"]=true,["ELSE"]=true,["LOOP"]=true,["BB"]=true,
|
||||
}
|
||||
local endindent = {
|
||||
["ENDIF"]=true,["ENDREP"]=true,["ELSE"]=true,["ENDLOOP"]=true,["END"]=true,["RET"]=true,
|
||||
}
|
||||
|
||||
local function checknesting(str,tab)
|
||||
local res
|
||||
local chk = str:match("%s*(BB)%d+.*:")
|
||||
chk = chk or str:match("%s*(%w+)")
|
||||
res = chk and tab[chk] and chk
|
||||
|
||||
return res
|
||||
end
|
||||
|
||||
local argregistry = {}
|
||||
local argbuffersfixed = false
|
||||
|
||||
local registercc = 0
|
||||
local registermem = 0
|
||||
local registers = 0
|
||||
local instructions = 0
|
||||
|
||||
local function fixargbuffers()
|
||||
if (argbuffersfixed) then return end
|
||||
|
||||
local argnew = {}
|
||||
for i,v in pairs(argregistry) do
|
||||
local buf,bufstart = string.match(i,"buf(%d+)%[(%d+)%]")
|
||||
if (buf and bufstart) then
|
||||
bufstart = tonumber(bufstart)/16
|
||||
argnew["buf"..buf.."["..tostring(bufstart).."]"] = v
|
||||
else
|
||||
argnew[i] = v
|
||||
end
|
||||
end
|
||||
argregistry = argnew
|
||||
argbuffersfixed = true
|
||||
end
|
||||
|
||||
local function checkregistry(w)
|
||||
local regsuccess = true
|
||||
|
||||
local vtype,vname,sem,resource,pnum,pref = string.match(w,"#var ([_%w]+) ([%[%]%._%w]+) : ([^%:]*) : ([^%:]*) : ([^%:]*) : (%d*)")
|
||||
local funcname,subroutine = string.match(w,"#function %d+ ([_%w]+)%((%d+)%)")
|
||||
if (pref == "1") then
|
||||
local descriptor = vtype.." "..vname
|
||||
|
||||
-- check if resource is array
|
||||
local resstart,rescnt = string.match(resource,"c%[(%d+)%], (%d+)")
|
||||
resstart = tonumber(resstart)
|
||||
rescnt = tonumber(rescnt)
|
||||
|
||||
-- check if resource is buffer/buffer array
|
||||
local buf,bufstart,bufcnt = string.match(resource,"buffer%[(%d+)%]%[(%d+)%],? ?(%d*)")
|
||||
buf = tonumber(buf)
|
||||
bufstart = tonumber(bufstart)
|
||||
bufcnt = tonumber(bufcnt)
|
||||
|
||||
-- check if texture
|
||||
local texnum = string.match(resource,"texunit (%d+)")
|
||||
|
||||
local argnames = {}
|
||||
if (rescnt) then
|
||||
for i=0,(rescnt-1) do
|
||||
table.insert(argnames,"c["..tostring(resstart + i).."]")
|
||||
end
|
||||
elseif (texnum) then
|
||||
table.insert(argnames,"texture["..tostring(texnum).."]")
|
||||
table.insert(argnames,"texture"..tostring(texnum))
|
||||
elseif (buf) then
|
||||
table.insert(argnames,"buf"..tostring(buf).."["..tostring(bufstart).."]")
|
||||
else
|
||||
table.insert(argnames,resource)
|
||||
end
|
||||
|
||||
for i,v in ipairs(argnames) do
|
||||
argregistry[v] = descriptor
|
||||
end
|
||||
elseif (funcname and subroutine) then
|
||||
argregistry["SUBROUTINENUM("..subroutine..")"] = "function "..funcname
|
||||
elseif string.find(w,"BUFFER4 ") then
|
||||
fixargbuffers()
|
||||
elseif string.find(w,"TEMP ") then
|
||||
--TEMP R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11;
|
||||
--TEMP RC, HC;
|
||||
--TEMP lmem[9];
|
||||
for i in string.gmatch(w,"C") do
|
||||
registercc = registercc + 1
|
||||
end
|
||||
for i in string.gmatch(w,"R%d+") do
|
||||
registers = registers + 1
|
||||
end
|
||||
registermem = tonumber(string.match(w,"lmem%[(%d+)%]"))
|
||||
elseif (string.find(w,"CBUFFER ") or string.find(w,"ATTRIB ") or string.find(w,"OPTION ") or
|
||||
string.find(w,"OUTPUT ") or string.find(w,"PARAM ") or string.find(w,"!!NV")) then
|
||||
|
||||
else
|
||||
regsuccess = false
|
||||
end
|
||||
|
||||
return regsuccess
|
||||
end
|
||||
|
||||
local function checkargs(str)
|
||||
local comment = "#"
|
||||
local declared = {}
|
||||
for i in string.gmatch(str,"([%[%]%(%)%w]+)") do
|
||||
local descr = argregistry[i]
|
||||
if (descr and not declared[i]) then
|
||||
comment = comment.." "..i.." = "..descr
|
||||
declared[i] = true
|
||||
end
|
||||
end
|
||||
|
||||
return comment ~= "#" and comment
|
||||
end
|
||||
|
||||
local registerlevels = {{}}
|
||||
local function checkregisters(str,indent)
|
||||
if (indent < 0) then return end
|
||||
local cur = registerlevels[indent+1]
|
||||
for i in string.gmatch(str,"R(%d+)") do
|
||||
cur[i] = true
|
||||
end
|
||||
end
|
||||
|
||||
local function clearregisters(indent)
|
||||
registerlevels[math.max(0,indent)+1] = {}
|
||||
end
|
||||
|
||||
local function outputregisters(indent)
|
||||
if (indent < 0) then return "" end
|
||||
local tab = registerlevels[indent+1]
|
||||
local out = {}
|
||||
for i,v in pairs(tab) do
|
||||
table.insert(out,i)
|
||||
end
|
||||
table.sort(out)
|
||||
local cnt = #out
|
||||
if (cnt < 1) then return "" end
|
||||
|
||||
local str = string.rep(" ",indent).."# "..tostring(cnt).." R used: "
|
||||
for i,v in ipairs(out) do
|
||||
str = str..tostring(v)..((i==cnt) and "" or ", ")
|
||||
end
|
||||
return str.."\n"
|
||||
end
|
||||
|
||||
-- check declarations
|
||||
local lastline = ""
|
||||
local addinstr = false
|
||||
for w in string.gmatch(tx, "[^\n]*\n") do
|
||||
if (not checkregistry(w)) then
|
||||
|
||||
if (not w:match("%s*#")) then
|
||||
instructions = instructions + 1
|
||||
end
|
||||
|
||||
if (checknesting(w,endindent)) then
|
||||
newtx = newtx..outputregisters(indent)
|
||||
if (indent == 0) then clearregisters(indent) end
|
||||
indent = math.max(0,indent - 1)
|
||||
end
|
||||
|
||||
local firstchar = string.sub(w,1,1)
|
||||
local indentstr = (firstchar ~= " " and firstchar ~= "\t" and string.rep(" ",indent) or "")
|
||||
local linestr = indentstr..w
|
||||
local argcomment = (firstchar ~= "#") and checkargs(w)
|
||||
|
||||
checkregisters(w,indent)
|
||||
|
||||
newtx = newtx..(argcomment and (indentstr..argcomment.."\n") or "")
|
||||
newtx = newtx..linestr
|
||||
|
||||
if (checknesting(w,startindent)) then
|
||||
indent = indent + 1
|
||||
maxindent = math.max(maxindent,indent)
|
||||
clearregisters(indent)
|
||||
end
|
||||
else
|
||||
newtx = newtx..w
|
||||
end
|
||||
lastline = w
|
||||
end
|
||||
|
||||
local registers = tonumber(string.match(lastline, "(%d+) R%-regs")) or registers
|
||||
registermem = registermem or 0
|
||||
registercc = registercc or 0
|
||||
local stats = "# "..instructions.." instructions\n"
|
||||
stats = stats.."# "..registers.." R-regs\n"
|
||||
stats = stats.."# "..tostring(registercc).." C-regs, "..tostring(registermem).." L-regs\n"
|
||||
stats = stats.."# "..tostring(registercc + registermem + registers).." maximum registers\n"
|
||||
stats = stats.."# "..maxindent.." maximum nesting level\n"
|
||||
newtx = newtx..stats
|
||||
|
||||
return newtx,stats
|
||||
end
|
||||
|
||||
local function beautifyAsmFile(filePath)
|
||||
local file_text = ""
|
||||
local statlines = ""
|
||||
local handle = io.open(filePath, "rb")
|
||||
if handle then
|
||||
file_text = handle:read("*a")
|
||||
file_text,statlines = beautifyAsm(file_text)
|
||||
handle:close()
|
||||
end
|
||||
|
||||
if (file_text == "") then return end
|
||||
|
||||
local handle = io.open(filePath, "wb")
|
||||
if handle then
|
||||
handle:write(file_text)
|
||||
handle:close()
|
||||
end
|
||||
return statlines
|
||||
end
|
||||
|
||||
-- Compile Arg
|
||||
frame:Connect(ID "glslc.compile.input",wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function(event)
|
||||
data.customarg = event:IsChecked()
|
||||
end)
|
||||
|
||||
-- Compile
|
||||
local function evCompile(event)
|
||||
local filename,info = GetEditorFileAndCurInfo()
|
||||
local editor = GetEditor()
|
||||
local glsl = true
|
||||
|
||||
if (not (filename and binpath)) then
|
||||
DisplayOutput("Error: GLSL Compile: Insufficient parameters (nofile)\n")
|
||||
return
|
||||
end
|
||||
|
||||
local domain = data.domains[event:GetId()]
|
||||
local profile = data.domainprofiles[domain]
|
||||
|
||||
-- popup for custom input
|
||||
data.custom = data.customarg and wx.wxGetTextFromUser("Compiler Args","GLSLC",data.custom) or data.custom
|
||||
local args = data.customarg and data.custom or ""
|
||||
args = args:len() > 0 and args or nil
|
||||
|
||||
local fullname = filename:GetFullPath()
|
||||
local outname = fullname..".main^"
|
||||
outname = args and outname..args:gsub("%s*[%-%/]",";-")..";^" or outname
|
||||
outname = outname..profile..".glp"
|
||||
outname = '"'..outname..'"'
|
||||
|
||||
local cmdline = "-profile "..profile.." "
|
||||
cmdline = args and cmdline..args.." " or cmdline
|
||||
cmdline = cmdline..data.domaindefs[domain].." "
|
||||
cmdline = cmdline.."-o "..outname.." "
|
||||
cmdline = cmdline..'"'..fullname..'"'
|
||||
cmdline = binpath.."/glslc.exe "..cmdline
|
||||
|
||||
local function compilecallback(str)
|
||||
local postfunc
|
||||
-- check for errors, if none, launch nvperf
|
||||
-- and indentation
|
||||
if (string.find(str,"successfully compiled")) then
|
||||
postfunc = function()
|
||||
-- beautify asm
|
||||
if (true) then
|
||||
local statlines = beautifyAsmFile(outname:sub(2,-2))
|
||||
DisplayOutput(statlines)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return str,postfunc
|
||||
end
|
||||
|
||||
-- run compiler process
|
||||
CommandLineRun(cmdline,nil,true,nil,compilecallback)
|
||||
|
||||
end
|
||||
|
||||
frame:Connect(ID "glslc.compile.vertex",wx.wxEVT_COMMAND_MENU_SELECTED,evCompile)
|
||||
frame:Connect(ID "glslc.compile.fragment",wx.wxEVT_COMMAND_MENU_SELECTED,evCompile)
|
||||
frame:Connect(ID "glslc.compile.geometry",wx.wxEVT_COMMAND_MENU_SELECTED,evCompile)
|
||||
frame:Connect(ID "glslc.compile.tessctrl",wx.wxEVT_COMMAND_MENU_SELECTED,evCompile)
|
||||
frame:Connect(ID "glslc.compile.tesseval",wx.wxEVT_COMMAND_MENU_SELECTED,evCompile)
|
||||
frame:Connect(ID "glslc.compile.compute",wx.wxEVT_COMMAND_MENU_SELECTED,evCompile)
|
||||
|
||||
-- indent asm
|
||||
frame:Connect(ID "glslc.format.asm", wx.wxEVT_COMMAND_MENU_SELECTED,
|
||||
function(event)
|
||||
local curedit = GetEditor()
|
||||
local newtx = beautifyAsm( curedit:GetText() )
|
||||
|
||||
curedit:SetText(newtx)
|
||||
end)
|
||||
end,
|
||||
}
|
||||
BIN
zbstudio.exe
Executable file → Normal file
BIN
zbstudio.exe
Executable file → Normal file
Binary file not shown.
@@ -3,7 +3,6 @@
|
||||
if [[ $(uname) == 'Darwin' ]]; then
|
||||
open zbstudio/ZeroBraneStudio.app --args "$@"
|
||||
else
|
||||
type lua 2>/dev/null >&2 && lua -e "os.exit(pcall(require, 'wx') and 0 or 1)"
|
||||
if [[ "$?" != "0" ]]; then (cd build; bash install-deb.sh); fi
|
||||
lua src/main.lua zbstudio "$@"
|
||||
if [[ "$(uname -m)" == "x86_64" ]]; then ARCH="x64"; else ARCH="x86"; fi
|
||||
bin/linux/$ARCH/lua src/main.lua zbstudio "$@" &
|
||||
fi
|
||||
|
||||
@@ -71,48 +71,21 @@ src/editor/menu_search.lua
|
||||
src/editor/menu_tools.lua
|
||||
src/editor/menu_view.lua
|
||||
src/editor/output.lua
|
||||
src/editor/preferences.lua
|
||||
src/editor/settings.lua
|
||||
src/editor/shellbox.lua
|
||||
src/editor/singleinstance.lua
|
||||
src/editor/style.lua
|
||||
src/main.lua
|
||||
src/misc/util.lua
|
||||
src/preferences/editor.lua
|
||||
src/preferences/project.lua
|
||||
src/util.lua
|
||||
src/version.lua
|
||||
tools/*.lua
|
||||
zbstudio/app.lua
|
||||
zbstudio/config.lua
|
||||
zbstudio/res/16.ico
|
||||
zbstudio/res/16/LICENSE
|
||||
zbstudio/res/16/wxART_COPY.png
|
||||
zbstudio/res/16/wxART_CUT.png
|
||||
zbstudio/res/16/wxART_DEBUG_BREAK.png
|
||||
zbstudio/res/16/wxART_DEBUG_BREAKPOINT_TOGGLE.png
|
||||
zbstudio/res/16/wxART_DEBUG_CALLSTACK.png
|
||||
zbstudio/res/16/wxART_DEBUG_START.png
|
||||
zbstudio/res/16/wxART_DEBUG_STEP_INTO.png
|
||||
zbstudio/res/16/wxART_DEBUG_STEP_OUT.png
|
||||
zbstudio/res/16/wxART_DEBUG_STEP_OVER.png
|
||||
zbstudio/res/16/wxART_DEBUG_STOP.png
|
||||
zbstudio/res/16/wxART_DEBUG_WATCH.png
|
||||
zbstudio/res/16/wxART_FILE_OPEN.png
|
||||
zbstudio/res/16/wxART_FILE_SAVE.png
|
||||
zbstudio/res/16/wxART_FIND.png
|
||||
zbstudio/res/16/wxART_FIND_AND_REPLACE.png
|
||||
zbstudio/res/16/wxART_FOLDER.png
|
||||
zbstudio/res/16/wxART_GO_DIR_UP.png
|
||||
zbstudio/res/16/wxART_GO_FORWARD-wxART_OTHER_C.png
|
||||
zbstudio/res/16/wxART_HELP_PAGE.png
|
||||
zbstudio/res/16/wxART_LIST_VIEW-wxART_OTHER_C.png
|
||||
zbstudio/res/16/wxART_NEW_DIR.png
|
||||
zbstudio/res/16/wxART_NORMAL_FILE-wxART_OTHER_C.png
|
||||
zbstudio/res/16/wxART_NORMAL_FILE.png
|
||||
zbstudio/res/16/wxART_PASTE.png
|
||||
zbstudio/res/16/wxART_REDO.png
|
||||
zbstudio/res/16/wxART_REPORT_VIEW-wxART_OTHER_C.png
|
||||
zbstudio/res/16/wxART_UNDO.png
|
||||
zbstudio/res/16/*.png
|
||||
zbstudio/res/24/LICENSE
|
||||
zbstudio/res/24/*.png
|
||||
zbstudio/res/32.ico
|
||||
zbstudio/res/estrela.png
|
||||
zbstudio/res/zerobrane.png
|
||||
|
||||
3
zbstudio/MANIFEST-bin-linux
Normal file
3
zbstudio/MANIFEST-bin-linux
Normal file
@@ -0,0 +1,3 @@
|
||||
bin/linux/*
|
||||
zbstudio/res/*
|
||||
zbstudio.sh
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user