Results tagged “lua”

Moonscript is an interesting dynamic scripting language that compiles to Lua. Moonscript can be dynamically compiled and run using a component called moonloader and because moonloader keeps a mapping between the moonscript code and the produced Lua code, I thought it could be possible to extend the debugging in ZeroBrane Studio to take that mapping into account in some way.

The version of the debugging bundled with ZeroBrane Studio v0.70+ provides a way to specify a line mapper that can be used to map the current line in the Lua code to the line number in the "original" moonscript code. This code is "injected" in the debugger when the debugging session is started, so any line number used by the debugger (whether to show the current line, set a breakpoint, or display a stack trace) goes through that mapping.

Let's see how you can now debug moonscript files.

ZeroBrane Studio configuration.

1. Get ZeroBrane Studio (0.70+). These instructions are for Windows, but the debugging should work on Linux and OSX as well.

2. Get Moonscript plugin and save it to ZBS/packages/ or HOME/.zbstudio/packages folder (where ZBS is the path to ZeroBrane Studio location and HOME is the path specified by the HOME environment variable); the second option may also be preferable for Mac OS X users as the packages/ folder may be overwritten during an application upgrade.

3. (Optional) If moon executable is in a folder listed in the PATH environment variable, you don't need to do anything as the plugin will find it; if the executable is in some other location, you may need to add path.moonscript = [[/full/path/moon.exe]] to the ZBS configuration file (Edit | Preferences | Settings: User).

4. Start ZBS (zbstudio.exe or zbstudio.sh).

Script debugging.

Let's now debug a simple three line script:

sum = (x, y) ->
  x + y
print "The sum is ", sum 10, 20

Save it as sum.moon and set the project directory to the folder where you saved the script (Project | Project Directory | Set From Current File) and select Moonscript as the current interpreter by going to Project | Lua Interpreter | Moonscript (this option is only available when the Moonscript plugin is installed).

Now if you Run the script, you should see "The sum is 30" in the output. If you select Debug, you should see the debugging started at line 1 and should be able to step through the script, set breakpoints, look at the stack trace, and use all other debugging functionality available in ZeroBrane Studio. Note that all the line numbers are from the moonscript source and not from the (dynamically) generated Lua code, as can be seen on the screenshot:

Moonscript debugging

You may notice that stepping in the debugger through the moonscript code spends more time on the same line than you'd expect. One of the most prominent examples is class definitions or table comprehensions that map few lines of Moonscript code to a (potentially) large number of lines in the corresponding Lua code, which causes the debugger to stay on the same line for each "step" through the Lua code. This may be improved in the future, but for now it's something to keep in mind; if you want to get to your destination faster, you can use breakpoints.

That's not all you can use the debugger for. You can also use moonscript expressions in the Watch panel; for example, if you enter sum 10, 20, you'll see 30 as the result after sum function is defined.

But there is more. You can also execute moonscript expressions in the Remote console. As can be seen on the screenshot, you can execute sum 1, 2 and get 3 as the result. You can also execute export mult = (x, y) -> x * y and then execute mult 10, 20 to get 200 as the result. Essentially, you can use the Remote console as Moonscript REPL with access to your application state. The only current limitation with the console commands is that they need to be single commands; this is a feature of command execution in the console that "flattens" multi-line scripts into one-liners (which doesn't work well with Moonscript, because of its whitespace sensitivity).

And one more thing. Not only syntax highlighting and folding is supported to some degree (as it's based on the Coffeescript lexer), but auto-complete for Lua functions also works with both . and \ notations, so using str = "" and str\ will offer "string" methods in the auto-complete list.

This functionality is highly experimental and has been tested with Moonscript 0.2.5 and 0.2.6 using the current ZeroBrane Studio (0.70). Give it a try with your moonscript application and share your experience in the comments or using any other method that works for you.

Fresh on the heels of getting OpenResty debugging to work with ZeroBrane Studio, I thought I would take a look at Lapis debugging. Lapis is a web framework for Lua or Moonscript, which runs inside OpenResty. Leaf Corcoran just released v1.0, which got better Lua support and more extensive documentation.

Since Lapis runs inside OpenResty, I'll be using a very similar setup to what was used for OpenResty debugging while following instructions on Creating a Lapis Application with Lua page.

ZeroBrane Studio configuration.

1. Get ZeroBrane Studio (0.70+). These instructions are for Windows, but the debugging should work on Linux and OSX as well.

2. Start ZBS (zbstudio.exe or zbstudio.sh) and start the debugger Project | Start Debugger Server.

Lapis configuration.

The easiest way to get Lapis and its dependencies is to use luarocks package manager and run luarocks install lapis command. You then need to make Lapis and its dependencies available to Nginx/OpenResty. If you don't have luarocks installed or prefer to do things manually, try the following:

1. Download Lapis and copy lapis folder inside of it to <NGINX>/lua folder.

2. Download ansicolor.lua and copy it into <NGINX>/lua folder.

3. Download and compile lpeg and cjson libraries and copy the resulting dynamic libraries to the same folder where you have lua51 dynamic library (.dll, .so, or .dylib). If you are using Windows and get those libraries from LuaForWindows, LuaDist, or similar binary distribution, you may need to copy <ZBS>/bin/lua5.1.dll (not lua51.dll!) to the same folder where you copied the libraries (where lua51.dll file is located). This is necessary because those dll files are likely to be linked to lua5.1.dll, but OpenResty comes with lua51.dll and this lua5.1.dll acts as a proxy.

OpenResty configuration.

1. I'm using a very basic config (<NGINX>/conf/nginx.conf):

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    lua_package_path '<ZBS>/lualibs/?/?.lua;<ZBS>/lualibs/?.lua;;';
    lua_package_cpath '<ZBS>/bin/clibs/?.dll;;';
    server {
        location / {
            default_type 'text/html';
            content_by_lua_file 'lua/web.lua';
        }
    }
}

Make sure you replace <ZBS> with the actual path to ZeroBrane Studio location. If you are running on OSX, replace ?.dll with ?.dylib and if you are running on Linux, replace bin/clibs/?.dll with either bin/linux/x86/clibs/?.so or bin/linux/x64/clibs/?.so depending on your platform.

2. Create the file we are going to debug (<NGINX>/lua/web.lua), which may look like this:

local lapis = require("lapis")
require('mobdebug').start('192.168.1.22')
lapis.serve(require("my_app"))
require('mobdebug').done()

Note that start() call takes the IP of the computer running the IDE. It uses "localhost" by default, but since your nginx instance is running there, you will need to specify the IP address of the computer running the IDE (in my case it is 192.168.1.22).

3. Create the application file as described in Creating a Lapis Application with Lua (<NGINX>/lua/my_app.lua):

local lapis = require "lapis"
local app = lapis.Application()
app:get("/", function(self)
  return "Hello world"
end)
return app

4. Open both files (web.lua and my_app.lua) in the IDE and set the project directory to lua folder by going to Project | Project Directory | Set From Current File.

If you already have a Lapis application you want to debug, you only need to update the Nginx config to include references to ZeroBrane Studio libraries and add require('mobdebug').start(....) and require('mobdebug').done() calls to web.lua file.

Script debugging.

Now start nginx and go to http://localhost/. If everything is done correctly, you should see ZeroBrane Studio activated with the green arrow pointing to the third line in the web.lua files. You can now set breakpoints, step through the code, look at the stack and so on.

Using step into command (Project | Step Into) will allow you to step into my_app.lua file. If you want the application to stop in the handler that returns "Hello world", you can set a breakpoint on line 4 and then use "Run" command (Project | Run).

Note that the browser window will be showing "waiting for..." message until the execution of web.lua file is completed, at which point you should see "Hello world" text there.

Debugging of Lapis files.

In addition to debugging your own application, you may also step through Lapis files if you are interested. If you open one of Lapis files in the IDE, you will be able to set breakpoints and step through it. You may also configure the IDE to auto-open any Lua file the control gets into by setting editor.autoactivate = true in the configuration file.

ZeroBrane Studio has already been used to debug various Lua engines -- game frameworks (like Corona, Gideros, Moai, Love2d), home automation devices, wireshark scripts, Adobe Lightroom plugins, and more -- but there have been several Lua environments that I haven't tried it on. One of them is OpenResty/Nginx Lua scripts. OpenResty is a web application server built around nginx, a very fast web server, that provides non-blocking IO with various backends (Redis, Memcached, MySQL, HTTP servers, and others) and supports Lua as its scripting language.

I first tried to use the non-blocking socket API that OpenResty provides, but couldn't get the debugging to work because socket calls that were supposed to be blocking were returning too early, which was breaking the interaction between the debugger in the application and the IDE. Based on advice from Yichun Zhang (agentzh), the maintainer of the OpenResty bundle, I then tried to use the same luasocket library that ZeroBrane Studio is using and got it all working. These are the steps you can follow to try it yourself:

ZeroBrane Studio configuration.

1. Get ZeroBrane Studio. These instructions are for Windows, but the debugging should work on Linux and OSX as well.

2. Start ZBS (zbstudio.exe or zbstudio.sh) and start the debugger Project | Start Debugger Server.

OpenResty configuration.

1. I'm using a very basic config (<NGINX>/conf/nginx.conf):

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    lua_package_path '<ZBS>/lualibs/?/?.lua;<ZBS>/lualibs/?.lua;;';
    lua_package_cpath '<ZBS>/bin/clibs/?.dll;;';
    server {
        location /hellolua {
           default_type 'text/plain';
           content_by_lua_file 'lua/content.lua';
        }
    }
}

Make sure you replace <ZBS> with the actual path to ZeroBrane Studio location. If you are running on OSX, replace ?.dll with ?.dylib and if you are running on Linux, replace bin/clibs/?.dll with either bin/linux/x86/clibs/?.so or bin/linux/x64/clibs/?.so depending on your platform.

2. Create the file we are going to debug (<NGINX>/lua/content.lua), which may look like this:

require('mobdebug').start('192.168.1.22')
local name = ngx.var.arg_name or "Anonymous"
ngx.say("Hello, ", name, "!")
ngx.say("Done debugging.")
require('mobdebug').done()

Note that start() call takes the IP of the computer running the IDE. It uses "localhost" by default, but since your nginx instance is running there, you will need to specify the IP address of the computer running the IDE (in my case it is 192.168.1.22).

3. Open this file (<NGINX>/lua/content.lua) file in the IDE and set the project directory to lua folder by going to Project | Project Directory | Set From Current File.

Script debugging.

Now start nginx and go to http://localhost/hellolua. If everything is right, you should see ZeroBrane Studio activated with the green arrow pointing to the second line (similar to what can be seen in the screenshot above). You can now set breakpoints, step through the code, look at the stack and so on.

You can also go to the remote console and run any ngx command there. For example, if you run ngx.say("Message from console") (as shown in the screenshot), you will see this text in the output after the script is done.

If you get "attempt to yield across C-call boundary" error in Nginx logs when you start debugging, try with a more recent ZeroBrane Studio (0.70+) as it includes several improvements that make debugging to work with recent versions of OpenResty.

Continue reading Debugging OpenResty and Nginx Lua scripts with ZeroBrane Studio

ZeroBrane Studio is often used for remote debugging, when the application being debugged is running on a different computer or a device, and it is very convenient to be able to "redirect" its printed output to the IDE. The IDE supports this functionality and not only allows "redirecting" of the printed output, but also pretty prints the results such that local t = {a = 1, b = 2} print(t) will print {a = 1, b = 2}. This option is turned on by default for some interpreters and can be explicitly enabled using debugger.redirect configuration option.

This is all good, but what if you have a long running process and want to be able to use this "remote" printing as a log file. The plugin below allows you to do just that: it will dump all the "remote" output to a file (output.log by default) in the current project folder. It also limits the number of records in the Output window (100 by default) to allow you to generate a large number of records without taking more memory.

Continue reading Saving debugging output to a file

Lua ecosystem has two package managers: LuaDist and LuaRocks. Both managers allow users to install Lua and C modules and work on Windows, Mac OS X and Linux, but have some important differences in how they operate, which I'll briefly go over.

LuaDist:

  • Unified build system for all modules based on CMake.
  • Mixed binary/source distribution that allows to use whatever dependency is available in the repository.
  • Everything is stored in git (using github as host) including the repository manifest. Tags are used for versions and branches for binary distributions.
  • Provides "batteries included" binary distributions (as a successor to Lua for Windows).
  • Relies on few Lua modules (luasocket, lfs, lua-git) for its implementation.
  • Allows for building the modules manually without using LuaDist.
  • Can be used from a command line or as a library (local ld = require "dist"; ld.install("luaexpat"))
  • Uses dist.info files for package specification information (mostly for dependency tracking, no build information).
  • Provides support for packaging modules for distribution.
  • Includes about 260 projects (as of November 2013; based on the number of sub-modules in the repository).
  • Includes a good number of pre-compiled binaries for Windows, but many for outdated module versions.

LuaRocks:

  • Supports local and remote repositories.
  • Distributed as a Lua scripts without dependencies, but relies on Unix tools for module deployment and installation.
  • Uses .rockspec files as a package specification file.
  • Uses "native" build instructions for each rock.
  • Includes rocks for 330 projects (as of November 2013).
  • Have several repositories: main one with manual curation and rocks.moonscript repository that supports (non-curated) rock submission and download statistics.

As we are talking about Lua module distribution, I'll also mention a nice project of Pierre Chapuis: lua toolbox. It provides a list of modules with short descriptions and their endorsement by various users (along with a simple tagging mechanism).

Both systems are easy to use as command-line tools. When you have one of the package managers installed, it's a matter of running luarocks install module or luadist install module commands to get the modules you need (assuming you have the tools available and don't run into compilation issues). It is certainly possible to setup LuaDist and LuaRocks to deploy modules to the directories you need and make those directories available to your project (see for example this nice write up by Thijs Schreijer on Setting up Lua installation on Windows using Lua Rocks and ZeroBrane Studio), but I'd prefer to have something simpler for users who may be new to programming and Lua.

I teach a semester long computer science class at a local high school during summer (using Lua and ZeroBrane Studio) and sometimes want to install Lua modules like penlight to my students' computers and use them from ZeroBrane Studio. I have 18 students using their own laptops running different systems and want to be able to say "install penlight" and then make "require 'pl.strict'" to work in their Lua scripts. The coming version (v0.40) of ZeroBrane Studio (and the current master branch) integrates with LuaDist and allows you to do just that.

Continue reading Lua package managers and integration with ZeroBrane Studio

It's expected to be able to watch an expression in the debugger and ZeroBrane Studio provides that functionality. You can specify an expression and it will be evaluated when the application is stopped in the debugger.

This is all good, but the application needs to be stopped to refresh the values and there are situations when you want to see the values while your application is running. ZeroBrane Studio supports redirecting of program output to the Output window in the IDE (when debugging) and (with a bit of magic) this can be leveraged to send the values you want to appear in the Watch window.

What does it give you? You can then include in your code print statements of the form print("foo=", someValue) and print("bar=", someOtherValue) and those values will be shown in the Watch window as foo and bar. The values can be complex values that will be pretty-printed for you (this is the same functionality that "prints" complex values to the Output window during debugging). For example, the script below will show values for a, b, c, and d as defined in the print expressions:

for i = 1, 1000 do
  require('socket').sleep(0.01)
  print("a=", {i, i*2})
  if 0 == i % 10 then print("b=", {i, i*3}, collectgarbage("count")) end
  if 0 == i % 100 then print("c=", {i, i*4}, os.clock()) end
  print("d=", math.random())
end

Since the "printed" output is sent over sockets, this also works when you debug your application remotely, for example, when you debug something running on a mobile device from ZeroBrane Studio running on a desktop.

For simple values (like d in the example above) the plugin will also calculate min, max, avg, and count values. The result may look similar to this (if you run it you will see that the numbers are updated while your app is running):

Here is the plugin code; you can save it into packages/ folder in the ZeroBrane Studio folder as realtimewatch.lua and restart the IDE.

The latest version of ZeroBrane Studio includes several recent updates: LuaJIT is now a default interpreter instead of Lua 5.1, Lua 5.2 is included for all supported platforms (just select "Lua 5.2" from the list of interpreters), and luasocket has been upgraded to v3.0.

Note that "normal" Lua5.1 interpreter is no longer included, but as before you can continue using the IDE to debug your Lua 5.1 applications (you can also use your own Lua 5.1 interpreter if you want).

LuaJIT is compiled with LUAJIT_ENABLE_LUA52COMPAT, which enables some of Lua5.2 features (see this link for details) and allows to do syntax checks for "goto" and other features. The local console is using LuaJIT as well.

All these changes are going to be included in the coming release (0.39), so please report any issues or incompatibilities you notice.

Note that while Lua 5.2 (and luasocket compiled against Lua 5.2) are included, you may still run into issues if you debug your own Lua 5.2 applications that statically link the interpreter (at least on Windows). The reason for that is that when you load luasocket, it loads lua52.dll and you end up with multiple VMs (and may get "PANIC: unprotected error in call to Lua API (multiple Lua VMs detected)" message). There are (at least) two ways to resolve this: (1) compile luasocket into your app the same way you include lua interpreter itself; you won't need anything else except one mobdebug.lua file to debug your app, or (2) use proxy dll; it will look like lua52.dll, but will actually proxy your calls to your statically compiled lua library, avoiding problems with multiple VMs. The proxy dll is for Lua 5.1, but you can tweak the script to make it work for Lua 5.2. See this SO answer for related discussion.

I received several questions about whether it's possible to add ability to see the same file in different editor tabs in ZeroBrane Studio and thought it would be a good test for the current plugin interface.

The Scintilla editor component that is used in ZeroBrane Studio includes a nice feature that allows two editors to share the same document, with changes made in one editor being immediately seen in the other one. The code is very simple ('e1' is the editor you are cloning and 'e2' is the new editor):

 local docpointer = e1:GetDocPointer()
 e2:SetDocPointer(docpointer)

I wrapped this code in a plugin that allows users to clone an editor tab vertically or horizontally. Save this plugin as cloneview.lua to packages/ folder, restart ZeroBrane Studio, and right click on one of editor tabs to select 'Clone Vertically' and 'Clone Horizontally'.

return {
  name = "Clone view plugin",
  description = "Clones the current editor tab.",
  author = "Paul Kulchenko",
  version = 0.11,

  onMenuEditorTab = function(self, menu, notebook, event, index)
    local idvert = ID(self.fname..".clone.vert")
    local idhorz = ID(self.fname..".clone.horz")

    local cloner = function(event)
      local e1 = ide:GetEditor(index)
      local e2 = NewFile("clone: "..ide:GetDocument(e1):GetFileName())
      local docpointer = e1:GetDocPointer()
      e2:SetDocPointer(docpointer)
      ide:GetEditorNotebook():Split(notebook:GetSelection(),
        event:GetId() == idhorz and wx.wxRIGHT or wx.wxBOTTOM)
      notebook:SetSelection(index)
    end

    menu:AppendSeparator()
    menu:Append(idhorz, "Clone Horizontally")
    menu:Append(idvert, "Clone Vertically")
    notebook:Connect(idvert, wx.wxEVT_COMMAND_MENU_SELECTED, cloner)
    notebook:Connect(idhorz, wx.wxEVT_COMMAND_MENU_SELECTED, cloner)
  end,
}

[Updated on 09/21/2013] The plugin code has been updated to use index parameter that refers to a correct index in split notebook situations. This functionality requires using v0.39 of ZeroBrane Studio (when released) or the current master.

There has been recent interest in getting ZeroBrane Studio to work with Cocos2d-x, so I decided to put my notes together on how this can be accomplished.

Debugging with ZeroBrane Studio requires using luasocket and because it can be integrated with a Cocos2d-x project in different ways, you may have several options to consider.

Continue reading Cocos2d-x simulator and on-device debugging with ZeroBrane Studio

[Update 10/18/2013] The bounty was for a specific issue with ZeroBrane Studio IDE (as documented below) and not for any problem related to this website.

[Update 10/04/2013] The bounty has been withdrawn as the issue appears to be fixed. If you can still reproduce it with the current master, please leave a comment.

Bug bounty programs are nothing new; Google, Mozilla, Microsoft and many others use them to find security vulnerabilities and bugs (and these program are reported to be cost effective). There has been an issue in ZeroBrane Studio that have been bugging me for almost two months, so I decided to offer a bounty for it.

I offer $250 dollars to the first person who can figure out what's causing the bug and I'll add $150 if you can provide a fix for it (so $400 USD total for a fix), payable via PayPal or as an Amazon giftcard. All the source code for ZeroBrane Studio is available on github and the code for wxwidgets and wxlua is available as well.

The details of the crash as well as associated stack traces are available in this ticket. Please use the ticket for discussion.

The bug only happens under Windows 7 64bit. I have received several reports of the same crash happening on different computers, all running Windows 7 64bit. I also have several users who use the same system, but have never experienced this crash. The crash most likely happens when typing text and is likely to be related to auto-complete, but I have so far been unable to reproduce it.

There are some strange things showing up on the stack trace that I've discussed with John Labenski (the author of wxlua). I can provide wx.dll built with debug information (it's rather large, 186M) or you can build one yourself using this build script (run it as bash build-win32.sh wxwidgets lua wxlua debug). Note that you don't need to build anything else and can run ZeroBrane Studio from a cloned repository.

The fix has to include code that can be applied to ZeroBrane Studio or upstream (wxlua or wxwidgets) to eliminate the issue. The bounty will not be awarded if it is illegal to do so.

ZeroBrane Studio is now available in seven languages! Thanks to all who contributed translations:

Starting from v0.38 ZeroBrane Studio includes experimental support for scope aware variable indicators. These indicators are added to mark local, global, masked, and masking variables and are calculated in real-time as the code is being written. Having this ability changes the way you write code, and does catch a lot of errors and 'wrong thinking' cases.

ZeroBrane Studio provides default indicators that can be updated; both the colors and the appearance can be changed as described in the documentation. For example, styles.indicator.varmasked = nil will disable masked indicator.

In addition to providing real-time indicators, the IDE uses the same mechanism to provide "Go To Definition" and "Rename All Instances" options available from the popup menu in the editor. The items in the popup menu also show the number of instances detected and the line where the definition is found. "Go To Definition" item is enabled for local variables/functions, function parameters, and loop variables.

You can quickly select instances of a variable by doing Ctrl/Cmd-DblClick on it. All instances get selected with the main one having slightly darker background and can be edited to update the name. In addition to that you can navigate selected instances using Find Next/F3 and Find Previous/Shift-F3; it will move the selection to the next/previous instance (and scroll the editor to make it visible).

From its very first version ZeroBrane Studio supported debugging of embedded Lua code; it was only a matter of adding require('mobdebug').start() (when running on the same computer) and it would start a debugging session in the IDE.

There was one case though when it didn't work: if the environment that loads some Lua code doesn't provide a file name, the IDE doesn't have information about what resource to load for debugging. The simplest example to see this to try to try to do something like loadstring("print(1); print(2)"). When this code is executed under the debugger, the source of this code is shown as print(1); print(2). One workaround for this was to specify the second parameter to loadstring: chunkname, which is then used by the Lua debug interface where it reports the source.

This workaround only works when you can modify the fragment that loads Lua code and in those cases where this is not an option (for example, when you need to use luaL_loadstring, which provides no way to label the chunk with its file path) you were out of luck.

This situation has changed now. Starting from v0.38, ZeroBrane Studio provides a way to debug these code chunks without any additional configuration. When it gets a request that has a code fragment instead of a file name as its source, it will try to find an open editor with the content that matches that source and if there is no match will open a new editor and load the fragment in it.

This allows to use the debugger to "step into" calls to functions returned by loadstring and also debug Lua scripts executed in environments like LuaJava. You can also look at the stack trace, set breakpoints, and use local console as you can normally do in the debugger.

Marmalade SDK is a cross-platform toolkit for developing games and mobile applications on a variety of desktop and mobile platforms. It also provides Marmalade Quick, a flexible programming environment based on Cocos2d-x with Lua scripting, which makes it a good fit to support in ZeroBrane Studio. Starting from v0.35, ZeroBrane Studio provides integration with Marmalade Quick and implements debugging support for Quick scripts; the video below demonstrates these capabilities (you may need to switch the video to 720p to make the text more readable):

The first thing you need to do is to open main.lua file from the project you want to work with (you can do this by using File | Open...) and then set the project directory to the directory with your main.lua file. You can do this by going to Project | Project Directory | Choose...
or using Project | Project Directory | Set From Current File.

To enable the integration shown in the demo, you need to select Marmalade Quick as an interpreter in ZeroBrane Studio by going to Program | Lua Interpreters | Marmalade Quick. If you installed Marmalade in the default location on OSX (/Developer/Marmalade) or on Windows (C:\Marmalade or D:\Marmalade, or in \Program Files\Marmalade), it will be found and used by the IDE. The IDE will also check for the Marmalade .MKB file in the project folder or its parent folder and will use the information from that file to set the environment for running your project.

After this is done, you can use Project | Run command to run the application. If there is a problem with finding the Marmalade Quick environment, you will see an error message in the Output window.

Enabling debugging

Add require("mobdebug").start() line to your main.lua script. This will allow you to use Project | Start Debugging to debug your application.

Continue reading Marmalade Quick debugging with ZeroBrane Studio

Corona SDK is a mobile application development framework that supports Lua scripting. While the integration and debugging of Corona applications has been available in ZeroBrane Studio since v0.34, starting from v0.35, ZeroBrane Studio also provides live coding. The video below demonstrates how you can use debugging and live coding with Corona applications (you may need to switch the video to 720p to make the text more readable):

The first thing you need to do is to open main.lua file from the project you want to work with (you can do this by using File | Open...) and then set the project directory to the directory with your main.lua file. You can do this by going to Project | Project Directory | Choose...
or using Project | Project Directory | Set From Current File.

To enable the integration shown in the demo, you need to select Corona as an interpreter in ZeroBrane Studio by going to Program | Lua Interpreters | Corona. If you installed Corona in the default location on OSX (/Applications/CoronaSDK) or on Windows (C:\Program Files\Corona Labs\Corona SDK or D:\Program Files\Corona Labs\Corona SDK), it will be found and used by the IDE.

After this is done, you can use Project | Run command to run the application. If there is a problem with finding the Corona simulator, you will see an error message in the Output window.

Enabling debugging

Add require("mobdebug").start() line to your main.lua script. This will allow you to use Project | Start Debugging to debug your application.

Continue reading Debugging and live coding with Corona SDK

I received several reports of files being loaded empty in ZeroBrane Studio and it turned out that it is caused by malformed UTF-8 code; the most frequent offenders are quotes copied from text with other encodings. For example, ISO 8859-1 has grave and acute accents with codes 0x91 and 0x92 and Windows CP1250 has single and double quotation marks with codes 0x91-0x94, with all these codes being invalid in UTF8 ("an unexpected continuation byte"). You can check ASCII and Unicode quotation marks for some details on various types of quotation marks).

There is no shortage of recommendations on how to detect malformed UTF-8 code, but most of them are based on using iconv and I was looking for something Lua-based. There is a StackOverflow answer that provides a clever way to iterate over UTF-8 code points, but it only works correctly over valid UTF-8 strings.

So I turned to other languages and found exactly what I was looking for in Test::utf8: a regexp to detect a valid UTF-8 sequence. The rest was easy; here is the fixUTF8 method that takes a string and "fixes" it:

function fixUTF8(s, replacement)
  local p, len, invalid = 1, #s, {}
  while p <= len do
    if     p == s:find("[%z\1-\127]", p) then p = p + 1
    elseif p == s:find("[\194-\223][\128-\191]", p) then p = p + 2
    elseif p == s:find(       "\224[\160-\191][\128-\191]", p)
        or p == s:find("[\225-\236][\128-\191][\128-\191]", p)
        or p == s:find(       "\237[\128-\159][\128-\191]", p)
        or p == s:find("[\238-\239][\128-\191][\128-\191]", p) then p = p + 3
    elseif p == s:find(       "\240[\144-\191][\128-\191][\128-\191]", p)
        or p == s:find("[\241-\243][\128-\191][\128-\191][\128-\191]", p)
        or p == s:find(       "\244[\128-\143][\128-\191][\128-\191]", p) then p = p + 4
    else
      s = s:sub(1, p-1)..replacement..s:sub(p+1)
      table.insert(invalid, p)
    end
  end
  return s, invalid
end

The logic is very simple: it checks for all valid code points of various length and replaces those characters that do not match.

The reason to have replacement is that you wouldn't want to silently remove malformed characters; ideally you'd replace them with some infrequent, but valid character that would be easy to find if needed. I picked "\022" as it is a control character that is rarely seen in texts and is usually shown as [SYN] glyph. Now ZeroBrane Studio will generate a message like this: "Replaced an invalid UTF8 character with [SYN]."

This is not the fastest way, but works well if there are few replacements. If you expect a large number of replacements, you can store all fragments in an array and concatenate them all at once using table.concat function to avoid repeated memory allocation to store a modified string.

[Updated 10/01/2013] Fixed an issue with UTF8 sequences; thanks to Enrique García for the fix.
[Updated 10/29/2013] Fixed an issue with one of the sequences that allowed for some invalid characters to pass as valid; thanks to Vadim Zeitlin for bringing this up.

I added a documentation section to the project website that covers various aspects of the ZeroBrane Studio IDE:

I also updated the screenshots page and added a community page with information about an IRC channel and a maillist.

Some of the users of ZeroBrane Studio had troubles running the live coding demo that Andy Bower put together, so I decided to post a very simple example that can be used as a starting point. I also packaged these files as a ZeroBraneEduPack project, so you can browse and download all these files together (they will also be packaged with the next release of ZeroBrane Studio).

Continue reading Gideros live coding: a simple example

About a year ago I released the first public version of ZeroBrane Studio. I would like to use this opportunity and thank many people who helped with this project and made it so much fun.

I'd like to first thank Christoph Kubisch who worked on Estrela Editor that ZeroBrane Studio originated from and continued contributing to ZBS. Thanks to the Kepler project for their work on RemDebug that MobDebug originated from, which is at the core of many capabilities that ZeroBrane Studio provides. I'd like to thank my son, Daniil Kulchenko for his feedback and his help with Linux and OSX builds.

I'd like to thank many users for their feedback, support, and contributions (including payments for ZBS). I'd like to thank those who helped with patches, improvements, and their time to test changes. This is an incomplete list in no particular order:

  • Srdjan Markovic for Corona auto-complete support and Zenburn color scheme.
  • Roland Yonaba for French translation.
  • Leo Bartoloni for Italian translation.
  • Inigo Sola for Spanish translation.
  • toiffel for Russian translation, Linux/OSX/Windows CMake-based launcher build, and several patches.
  • Fringale for spec and API files cleanup and update for Lua 5.2.
  • Marcel van Herk for assistance with scratchpad break/resume functionality.
  • Andy Bower and Atilim Cetin for their assistance with Gideros integration and live coding.
  • Jonathan Shieh for his work on project navigation and user settings.
  • Aidar Rakhmatullin for his help with unicode support on Windows.
  • John Labenski for his help with wxlua fixes and builds.
  • Students in the introductory computer science class I taught last summer for stress-testing the IDE. How else would I find out that the system had an issue with single quotes or exclamation marks in file names?
Continue reading ZeroBrane Studio is one year old

GSL Shell is an interesting project by Francesco Abbate that implements an interactive shell with access to a collection of mathematical methods for numerical computations in GNU Scientific Library (GSL). It's based on LuaJIT engine, which makes it very fast; it also includes extensive documentation with many examples.

One of ZeroBrane Studio users opened an issue asking about integration with GSL shell and I decided to take a look. After solving several problems with the help of GSL Shell author (Francesco Abbate) and enthusiastic users (coppolajj and Marcel van Herk), things started to work. Note that you need to download and install luasocket library compiled to work with GSL shell.

It is now possible and is (going to be) available in ZeroBrane Studio v0.34 to run and debug GSL shell scripts, like the one below, which plots the Moebius surface:

use 'math'
require 'plot3d'
x = |u,v| (1 + 1/2 * v *cos(u/2))*cos(u)
y = |u,v| (1 + 1/2 * v *cos(u/2))*sin(u)
z = |u,v| 1/2 * v * sin(u/2)

require('mobdebug').start()

graph.surfplot({x, y, z}, 0, -1, 2*pi, 1,
  {gridu= 60, gridv= 4, stroke= true})

There are several things that are interesting about this small example. First, you need to specify require('mobdebug').start() to start debugging (this is the same way you do it for Love2d, Gideros, and some other engines). You also need to select "GSL-shell" as the interpreter by going to Project | Lua Interpreter.

Second, one can debug functions x, y, and z, even though GSL shell provides an alternative non-standard (for Lua) syntax to define functions, which is used in this example. You can not only set breakpoints on lines where these functions are defined, but you can also split those one-line functions into multiple lines and step through them, inspect variables, modify them, and so on. This is possible because ZeroBrane Studio debugger (MobDebug) is using debugging facilities provided by Lua and GSL shell transforms this syntax into structures that LuaJIT can correctly report on.

Another things is that if you run this example with and without the debugger, you will notice a significant difference in performance: on my windows laptop it is executed in about 3s with the debugger, but in 20ms without it. As I described earlier, MobDebug provides a mechanism to turn debugging on and off in your script. For example, if you add require('mobdebug').off() after require('mobdebug').start(), then the script will execute in 20ms instead of 3s, but all the debugging functionality will be turned off (you wont be able to step through the code and breakpoints will not fire). You can add require('mobdebug').on() line to your script and all commands executed after this on() call is executed will be again available for debugging. This gives you a flexible mechanism to specify what fragments of your code need to run with debugging on and what fragments need to run at full speed.

This GSL shell integration is available in ZeroBrane Studio v0.34; you can also get the latest code from GitHub to give it a try.

Close