Komodo

Getting / Setting a Komodo preference

Question: 

How do I change a specific Komodo preference?

Answer: 

Komodo's uses a number of preferences to control how the program is run. Most preferences are modified through the Komodo preferences dialog, though there are some that are not exposed through the UI.

The preferences are based on a default "prefs.xml" which can be found inside your Komodo installation directory, and then any preference changes to the base preferences are stored into your Komodo user data directory. This file stores a number of different preference types:

You can see the base OpenKomodo (Komodo Edit) "prefs.xml" file here:
http://svn.openkomodo.com/openkomodo/view/openkomodo/trunk/src/prefs/pre...

These preferences can be modified by changing the XML files manually (and then restarting Komodo), or can be changed using the Komodo API, such as through a JavaScript macro.

Some example JavaScript macros (which can be added to your Komodo toolbox) for changing preferences are listed below:

Getting a boolean preference

var pref_name = ko.interpolate.interpolateStrings(["%(ask: Boolean pref name)"]);
if (pref_name) {
    var prefs = Components.classes['@activestate.com/koPrefService;1'].getService(Components.interfaces.koIPrefService).prefs;
    if (prefs.hasBooleanPref(pref_name)) {
        alert("'" + pref_name + "': " + prefs.getBooleanPref(pref_name));
    } else {
        alert("No boolean pref exists for '" + pref_name + "'");
    }
}

Setting a boolean preference

var pref_name = ko.interpolate.interpolateStrings(["%(ask: Pref name)"]);
if (pref_name) {
    var pref_value = ko.interpolate.interpolateStrings(["%(ask: Value: 1)"]);
    if (pref_value !== null) {
        var prefs = Components.classes['@activestate.com/koPrefService;1'].getService(Components.interfaces.koIPrefService).prefs;
        //dump("Setting pref '" + pref_name + "' to '" + pref_value + "'\n");
        if (pref_value == "1" || pref_value.toLowerCase() == "true") {
            prefs.setBooleanPref(pref_name, true);
        } else {
            prefs.setBooleanPref(pref_name, false);
        }
    }
}

Setting a string preference

var pref_name = ko.interpolate.interpolateStrings(["%(ask: Pref name)"]);
if (pref_name) {
    var pref_value = ko.interpolate.interpolateStrings(["%(ask: Value)"]);
    if (pref_value !== null) {
        var prefs = Components.classes['@activestate.com/koPrefService;1'].getService(Components.interfaces.koIPrefService).prefs;
        //dump("Setting pref '" + pref_name + "' to '" + pref_value + "'\n");
        prefs.setStringPref(pref_name, pref_value);
    }
}

Setting a number preference

var pref_name = ko.interpolate.interpolateStrings(["%(ask: Pref name)"]);
if (pref_name) {
    var pref_value = ko.interpolate.interpolateStrings(["%(ask: Value)"]);
    if (pref_value !== null) {
        var prefs = Components.classes['@activestate.com/koPrefService;1'].getService(Components.interfaces.koIPrefService).prefs;
        //dump("Setting pref '" + pref_name + "' to '" + pref_value + "'\n");
        prefs.setLongPref(pref_name, parseInt(pref_value));
    }
}

API methods on a Komodo PreferenceSet

To see a full list of API methods when writing a JavaScript macro, you'll need to query the preference into a Komodo preference set, example:

var prefs = Components.classes['@activestate.com/koPrefService;1'].getService(Components.interfaces.koIPrefService).prefs;
var prefset = prefs.QueryInterface(Components.interfaces.koIPreferenceSet);
prefset.<|> // Completions seen here.

The Many Ways of Extending Komodo

Product: Komodo | tags: extensions macros source hacking

Every once in a while I write a short overview on the various ways you can make Komodo work the way you want. This article's mostly for the benefit of recent arrivals to the Komodo way of slinging code, but since I've picked up a few things since the last time I wrote this, it might be worth hanging around a bit if you're a vet.

Komodo is no black box. It's based on Mozilla, which means most of the interesting code is shipped as part of the product. Here are a few different ways you can take advantage of this to make Komodo work the way you want it to, or at least embark on that interesting journey.

First, it helps to know where the source is. There's a lot of code, spread out in various areas, but the two main parts of the code are based off something I'll call "mozhome" (which is &lt;installDir>/lib/mozilla on Windows and Linux, and /Applications/Komodo.app/Contents/MacOS on OS X). While there are a few other areas, the main Komodo code is split into the front-end, in these two directories:

  mozhome/chrome/komodo.jar
  mozhome/chrome/xtk.jar

and the back-end, in these two areas:

  mozhome/python/komodo
  mozhome/components/ko*.py

To explore the chrome code, copy the jar file to a separate directory (it should be empty), unzip it there, and at a later point, if you make modifications you can zip it up and replace the shipped komodo.jar file with your own.

For both Python and chrome files, changes will automatically be picked up by Komodo on restart.

If you know an identifier name, or a string of text, you can search for it quickly at http://grok.openkomodo.com/source/xref/openkomodo/trunk/. Note that this is the code base for Komodo Edit. You can work with features specific to Komodo IDE, but you'll only have local searching. Also if you're using Komodo IDE but looking at the Komodo Edit source, line numbers are different because the files have different licenses at the start of their source. Finally, some of the source files go through preprocessing before being packaged into the Komodo distro, and their name will contain an extra extension such as ".p" or ".unprocessed".

Macros

Now that we've covered where the code is, here's how to extend it.

The quickest way to get started is by using the Macro Recorder, saving the recorded macros in the toolbox, and using them. These often work, but some operations aren't recorded (such as setting items in a dialog box), and due to the way the macros are serialized, they don't always work once they're saved in the toolbox. In particular, macro lines that work with the editor by manipulating Komodo commands should use the Komodo editor API directly.

For example, if you record a sequence of moving down three lines, and to the right by two characters, you'll get this macro:

komodo.assertMacroVersion(2);
if (komodo.view) { komodo.view.setFocus() };
komodo.doCommand('cmd_lineNext')
komodo.doCommand('cmd_lineNext')
komodo.doCommand('cmd_lineNext')
komodo.doCommand('cmd_right')
komodo.doCommand('cmd_right')

If you're thinking of writing macros (or extensions) that work with the editor, it's never too soon to start working with the editor API. It's based on Scintilla, so you can find plenty of documentation on it, as well as in Komodo's help. The above macro would be rewritten like so:

var scimoz = ko.views.manager.currentView.scimoz;
scimoz.lineDown();
scimoz.lineDown();
scimoz.lineDown();
scimoz.charRight();
scimoz.charRight();

Think of the doCommand statements that Komodo generates for you as scaffolding, which you eventually should replace before you're ready to unleash your macros on the world.

Next, macros can be written in either JavaScript or Python. Usually if you're interacting with the front-end, JavaScript means you can manipulate it more directly. However, sometimes there are common libraries in Python that make it too compelling. For example, I have a macro I use constantly that lets me reformat single-line paragraphs into blocks of text more suited for people who read email with older text-based agents. Here's the code:

    import textwrap
    paragraphs = re.split(r'\r?\n\r?\n(?=.)', text)
    lines = []
    for p in paragraphs:
        if longLine_re.search(p):
            lines += textwrap.wrap(p)
        else:
            lines += re.split('\r?\n', p)
        lines.append(eol)

You might be wondering why I'm talking about email packages in an article on hacking Komodo, which isn't known for its mail capabilities. It turns out this macro uses the clipboard for its I/O. I'll show the code, as it shows how to interface Python with Mozilla:

class ClipboardWrapper():
    def __init__(self):
        self.clipboard = components.classes["@mozilla.org/widget/clipboard;1"].getService(components.interfaces.nsIClipboard)
        self.transferable = components.classes["@mozilla.org/widget/transferable;1"].createInstance(components.interfaces.nsITransferable)
        self.transferable.addDataFlavor("text/unicode")
       
    def _getTextFromClipboard(self):
        self.clipboard.getData(self.transferable, self.clipboard.kGlobalClipboard)
        (str, strLength) = self.transferable.getTransferData("text/unicode")
        return str.QueryInterface(components.interfaces.nsISupportsString).data[:strLength/2]

    def _copyTextToClipboard(self, text):
        data = components.classes["@mozilla.org/supports-string;1"].createInstance(components.interfaces.nsISupportsString)
        data.data = text
        self.transferable.setTransferData("text/unicode", data, len(text) * 2)
        self.clipboard.setData(self.transferable, None, self.clipboard.kGlobalClipboard)

This code also shows you how to interface with the Mozilla API via XPCOM. It turns out this is actually slightly easier from Python than from JavaScript, as the PyXPCOM library knows how to manage out-variables. In JavaScript you'd have to write the above getter like so:

var str = {};
var strLength = {};
this.transferable.getTransferData("text/unicode", str, strLength);
return str.value.QueryInterface(Components.interfaces.nsISupportsString).
       data.substring(0, strLength.value / 2);

For some reason, the Python XPCOM library spells "Components" with a lower-case "c". If you're getting tripped up by this, you can get around it with this line:

from xpcom import components as Components

If you're thinking I've left out a lot of material, you're right. The Komodo API is large, and the Mozilla XPCOM library is larger.

It's also worth mentioning that Komodo picks up changes to macros immediately, as opposed to any other kind of change.

Macro Documentation

Both macros in JavaScript and Python let you take advantage of a higher-level Komodo API, documented at http://docs.activestate.com/komodo/5.0/macroapi.html (note that these functions are available only inside macros). You can find info on the standard Komodo API at http://docs.activestate.com/komodo/5.0/komodo-js-api.html

Debugging Macros

There might be an easy way of debugging macros, but I doubt it. Both JavaScript and Python macros are run with a single eval block (exec for Python). The JavaScript debuggers I've tried won't step into these eval blocks. You can't easily use print statements either, and writing to the Komodo output window is more complicated than one would want for a quick print statement. Instead I use the Komodo version of Ted's Extension Developer Extension, available here, and in particular use the JavaScript shell to test out macro lines incrementally. It might look like you can only enter one line at a time in the shell. To enter a block of code, you can either press Shift-Return at the end of each line, or better still, write the code in Komodo, select and copy it, and paste it into the shell, which knows how to handle multi-line insertions.

The extension is also a reasonable way of interactively exploring much of Komodo's front-end code. Type "ko." followed by two tabs to get a list of the main components in the "ko" namespace. Most of the time you'll be working with ko.views for editor files, and ko.projects.

Restyling Komodo

While you could modify the CSS files in komodo.jar, Komodo supports the same mechanism other Mozilla apps use, and you can simply override Komodo's default settings by providing a "userChrome.css" file in your profile. See http://community.activestate.com/faq/customizing-the-komodo-ui for more info.

Extensions

Once you've reached the limits of what you can do with macros, the next step is to write an extension. In Komodo this gives you access to adding new parts to the UI, new menu items, new sidebars. Most of the resources I mentioned above are useful for extension writing as well.

The "Komodo Extension" project template will help you get started, but like recorded macros, it's more of a scaffold generator than a code generator.

It's definitely worth spending time reading the source of extensions you use, to understand how they're assembled. The best source for Komodo extensions is at http://community.activestate.com/addons. Extensions end with ".xpi", so the host application (that's Komodo here, but also Firefox and other Mozilla apps) knows how to load them when they try to open them, but they're just zip files.

When you're working on an extension, you might find the following cycle gets old fast:

  • Edit and save extension source
  • Rebuild and rezip
  • Reinstall the extension into Komodo
  • Restart Komodo
  • Test changes

Here's a useful shortcut for Mozilla extensions I wish I had learned years ago. These extensions live in the application profile directory, which is something like /5.0/host-hostname/XRE/extensions. Let's say you're working on an extension called foo@mycom.org -- normally installing an extension in Komodo will create a directory called "foo@mycom.org" in the extensions directory, and the contents of this directory will contain the extension. However, you can use a platform-independent shortcut -- delete the installed foo@mycom.org directory (you have the source for this elsewhere, right), and replace it with a file with the same name, "foo@mycom.org". Its contents should be one line containing the absolute path to the extension code (the Komodo extension project template will create this automatically). Now you don't need to reinstall your extension each time. Instead the work cycle is now:

  • Edit and save extension source
  • Rebuild
  • killall komodo-bin (or use the Task Manager on Windows to quickly close Komodo). When you're in this cycle you most likely don't want to take the extra time Komodo needs to shut down gracefully.
  • Restart Komodo
  • Test changes

Same number of steps, but you no longer need to do the extension install dance.

There is much more on writing extensions, but this is supposed to be a short article.

Hacking and Patching

As you write increasingly ambitious macros and extensions, you'll no doubt have spent some time reading Komodo code, and found some opportunities to make improvements.

The main problem with this is that while macros and extensions live across versions (although extensions will need to be reinstalled, and macros will often need to be exported into a package, and then reloaded in the new version), changes to the Komodo code base will remain with earlier versions. At this point you're advised to submit your patches -- see http://www.openkomodo.com/participate for details.

Komodo 5.0 features

Product: Komodo

This is an overview of the major items included in the Komodo 5.0 release. Some of these new features below are only available in the Komodo IDE version.

Improved Look and Feel

Komodo now provides a more native look and feel across all platforms, with tabs and sidebars being re-designed to be simpler and easier to use.

The user interface changes are more prominent on Mac OS X and Linux systems, with Linux using native OS theming... Yay!

Multiple Window support

Use the "Window->New Window" to open multiple Komodo interfaces. Open different work projects into separate Komodo instances to help compartmentalize your development focus.

Komodo will even restore your multiple instances with the same workspace, including desktop location upon shutting down and restarting Komodo!

Code Formatters (IDE only)

You can use code formatters for quickly reformatting your documents within Komodo. For example, if you have a JSON (JavaScript) file that contains all information on the one line, make it readable by using the built-in JavaScript formatter JS Beautify. You will go from:

to a nicely formatted:

Komodo comes with a number of pre-configured formatters, with the ability to configure additional language formatters through the Komodo preferences system.

SCC Support for Mercurial, Bazaar and Git (IDE only)

Three new Source Code Control (SCC) systems were added to Komodo 5, these were Mercurial, Bazaar and Git, which takes Komodo's supported SCC count to 6 (CVS, Subversion and Perforce were already supported).

Komodo requires these SCC clients to be installed on your machine and you can configure the settings through Komodo's SCC preferences.

SCC Checkout Wizard (IDE only)

Komodo provides a wizard to assist is making a checkout from Source Code Control. Simply choose the SCC type, provide the source and destinations and check it out!

All of the SCC components are support except for Perforce (as Perforce is using a completely different checkout mechanism).

Improved Tabstops

The tab-stop support in Komodo 5 has been greatly improved. Tab-stops can be used within snippets and new file templates in assist in quickly add a piece of templated information.

Tab-stop improvements:

  • they are now visually highlighted
  • you can create linked tab-stops to update repeated instances
  • linked tab-stop instances are updated inline when the main tab-stop is updated
  • you can create nested tab-stops
  • removed the use of specific tab-stop markers (chevrons)

Add-ons Searching and Installation

You can use Komodo's "Tools->Add-ons" menu to bring up the add-ons dialog. You can see a list of recommended add-ons, search for specific add-ons, and install directly from the dialog.

Add-ons are also known as extensions, you can even port existing Firefox extensions to Komodo.

Crash Reporting

Whenever Komodo has a serious problem and is unable to operate correctly (i.e. it crashes), the crash reporter dialog will appear, offering the ability to submit the fault to the Komodo development team.

It is recommended you submit all crash reports, as these crash reports contain crucial information to assist the development team in diagnosing the problem.

Other Komodo releases

Resetting the Komodo user data directory

Question: 

How do I:

  • reset my preferences
  • fix corruption in the code intelligence database or preferences
  • reinstall Komodo "from scratch"
  • etc. ?
Answer: 

Komodo keeps user preferences, a code intelligence database, and a number of other files in a user data directory. It's location on various platforms is described here:

http://docs.activestate.com/komodo/5.0/trouble.html#appdata_dir

Sometimes files in this directory can become corrupted, causing problems running Komodo. If this problem can't be tracked down to a particular file in the user data directory, there is a nuclear option:

  • close Komodo if it's running
  • delete, move or rename the user data directory
  • restart Komodo

Komodo will generate a fresh user data directory.

If you have preferences or a Toolbox you want to keep, move or rename the directory (e.g. "5.0-corrupt") instead of deleting it. You can then try moving some of the files (e.g. prefs.xml or toolbox.kpf) from the original directory back into the fresh user data directory.

IndexError: list index out of range

Question: 

I'm getting "IndexError: list index out of range" when I try to install Komodo on Linux. Why?

Answer: 

The Komodo installer is a gzipped tarball. It needs to be decompressed and untarred with g(un)zip and GNU tar compatible tools ('tar xzvf ...' should work on most systems).

Unpacking the tar.gz file using some other tools (such as WinZip) may cause the archive to be corrupted or missing components, leading to install errors like this one:

install: Installing ActiveState Komodo to '/opt/Komodo-IDE-4'...
Traceback (most recent call last):
File "./support/_install.py", line 620, in <module>
sys.exit( main(sys.argv) )
File "./support/_install.py", line 607, in main
interactiveInstall(suppressShortcut)
File "./support/_install.py", line 506, in interactiveInstall
install(installDir, suppressShortcut)
File "./support/_install.py", line 515, in install
destDir=destDir)
File "./support/_install.py", line 397, in _install
"libpython?.?.so"))[0]
IndexError: list index out of range

If you are seeing errors like this, try re-downloading the tar.gz file and unpacking it with 'tar -xzvf Komodo-<version>-<platform>.tar.gz'.

Writing Unittest Harnesses for Komodo 4.4: An Introduction

Product: Komodo | tags: extensible harness testplan unittest

In the good old days (i.e. two months ago), like the Model T, you could run any unittest harness in Komodo you wanted as long as it was black. Now Komodo allows you to write test harnesses for any language, and have the results show up in Komodo's Test Results area. This article shows how.

Adding a Test Harness to Komodo

We shipped a unittest harness in version 4.3 of Komodo, but strictly speaking it was closer to 1.0 functionality. We hard-wired four separate test harnesses, one for each of Perl, Python, Ruby, and PHP. Naturally, as soon as we launched 4.3 there was a barrage of requests for new test harnesses. With the functionality in 4.4 we're sharing the joy in writing tests. This document will explain how the test plans are structured, and what you need to do to write your own.

What is Sleuth?

"Sleuth" is a name we internally use for the unittest integration component. It has a well-defined meaning in English, but is rarely used, and therefore less likely to conflict or create confusion with existing systems. For example, Komodo has its own unittest framework. If we called this component "UnitTest", it could lead to confusion.

Structure of a Test Harness

The file sleuth.py defines two classes, KoSleuthHarness and KoSleuthHarnessRunner. KoSleuthHarnessRunner is the higher-level class, and is the one Komodo uses to run a set of tests. KoSleuthHarness is a lower-level class that launches the actual test process, reads its output, filters it, parses it, and writes information back to Komodo for it to display in the Test Results tab.

Neither class is an XPCOM class, so there are no IDL files that Komodo ships, but these are their external interfaces:

class KoSleuthHarness:
    def __init__(self, args, launch_dir=None):
        # args: array of strings
        # launch_dir: directory to run program from
    def filter_line(self, line, line_num):
        # line: string
        # Callback, return True if the line should be filtered (not parsed)
    def run(self):
        # An inner generator called by KoSleuthHarnessRunner.run
    def stop(self):
        # An inner function called by KoSleuthHarnessRunner.stop
        
class KoSleuthHarnessRunner:
    def __init__(self):
        # Initializes this class
    def lookupOutsideKoPath(self, programName):
        # programName : string, like "perl"
        # returns either the full path, or None
    def run(self):
        # A generator, yields a stream of lines read from the process
    def stop(self):
        # Called by Komodo to end the process

By itself, the code in sleuth.py cannot run any test harnesses. Each test harness is represented by a pure-Python module that needs to do the following things:

  • Live in a file with a name and location that Komodo can discover. The section on writing extensions will cover the directory structure to use. Harness filenames must end with "_harness.py".
  • Define a subclass of KoSleuthHarnessRunner.
  • Most harnesses will also need to define a subclass of KoSleuthHarness, although currently the koPHP_PHPUnit_harness.py harness defines a trivial subclass of it.
  • Set a module global called harnessName to the name of your harness. Harness names should be namespaced, to avoid collision -- currently the last harness loaded wins at run-time. These values will appear in harness selection menus in the Komodo dialogs for creating and editing test plans.
  • Define a register function that Komodo will call at startup time:
    class PHP_PHPUnit_SleuthHarness:
        # ...
    harness_name = "PHP - PHPUnit"
    def register(sleuthManager):
        sleuthManager.register('PHP', harness_name, PHP_PHPUnit_SleuthHarness)

Whenever Komodo wants to run your harness, it will create a new instance of the class passed in the third argument to the register method. This means you can't maintain persistent data in each of these classes; use module globals if you need to.

Have a look at the harnesses that Komodo ships. Notice that the PHP and Python harnesses are relatively thin wrappers around sleuth.py. By contrast, the Perl TAP harness has to do much more work, as it's parsing output, rather than plugging code into the underlying test harness.

Notice also that error messages are relayed back to the UI by setting the self._initial_msgs field to a list of sleuth-formatted error messages back to sleuth.py. The upper-level HarnessRunner class checks for these before launching the actual process; if it finds any, it normally relays them back to the caller (remember that the run method is a generator, not a function). This is a good way to present missing prerequisites back to the user.

Talking to Komodo: the Sleuth Language

These are the six different directives Komodo is watching for:

    @suite_started@:
    start a new test suite
    
    @test_started@: testname
    
    @fault@: line
    - a line of a possibly multi-line fault associated with the current test.
    
    @into@: line
    - non-error information the user might find interesting
    
    @test_result@: P | F | E
    
    @suite_finished@: N:n P:p F:f E:e; t
    - finished the current test suite. n, p, f, e stand for the number
    of tests, number passed, number failures, and number errors.
    t gives the elapsed time

Any other output is emitted to Komodo and treated as part of either the current fault or info event, or will be discarded.

Yes, tests that emit any of the above strings as part of their output will confuse Komodo.

Defining New Test Harnesses

In general, you'll need to spend more time figuring out how to plug in your test-runner into the framework you're targeting, or parse its output, then you should spend getting a new framework to work with Komodo. Test harness extensions are very simple, and follow this layout:

dir/
    - install.rdf
    - sleuth-harnesses/
        - *
            - *_harness.py

That's it. The sleuth-harnesses may contain more than one subdirectory: each of those subdirectories can define one or more test harnesses. The reason for the extra level of directories is to make it easier to package several different types of harnesses in a single extension.

The nose.xpi extension implements not one but two harnesses for working with Python's nose testing framework. Nose is good at "sniffing" out things to test in a directory, much better than the unittest-based test harness shipped with Komodo. I noticed that by adding a --with-doctests argument to the invocation of Nose, it would run docstring-based tests instead of tests that implemented unittest. I first duplicated the contents of as_nose_harness.py into as_nose_doctest_harness.py, got it to work (by adding one extra argument), and then refactored the common part of the two files into as_nose_common.py. These harnesses work with versions 0.9 and 0.10 of Nose.

Before you can use them, you need to install Nose, of course, and also install the sleuthplug.py module that I bundled in the extension. At some point I'll touch base with Brandon Corfman, who first directed my attention to this framework, to find out a way to run plugins without installing them. But meanwhile I've got a Ruby Test::Unit harness to write.

Komodo 4.4 features

Product: Komodo

This is an overview of the major items included in the Komodo 4.4 release. These new features below are only available in the Komodo IDE version.

You can also watch a screencast of these new features here:
http://community.activestate.com/new-features-komodo-4-4

Sections menulist

The sections menulist is a new item added to the Komodo statusbar. Upon clicking this statusbar element (or using the command - Ctrl-F8) a menulist will appear that outlines the main sections contained in your current Komodo editor file.

You can select an item in the menulist which will proceed to take you to the matching location in your document. When you type additional characters, the list will be filtered down to those items partially matching your input.

The benefits of the sections menulist over the code browser are:

  • Shows only the current file context
  • Shows only the functions and classes (not variables)
  • It provides layout information for non-codeintel languages (C++, Java, )
  • Regex based, so can be easily customized
  • Easy to add support for additional languages

Multi file SCC commit

Komodo now has an updated commit dialog that is used for SCC Commit operations. The dialog will show update-to-date scc status for all files listed in the tree, updating itself asynchronously. The dialog makes it easy to add additional files/directories. The dialog also offers the ability to see the diff from the files you are about to check in.

SCC changelist

Komodo now provides the ability to manage groups of scc files. You can find this new tab in the right-hand pane (next to the Komodo toolbox). This is very useful when working on a specific set of files, create a new changelist and then drag/drop the files you wish to have involved. SCC operations can be performed on these changelist items, which operate on the group of files inside the changelist. Komodo keeps track of the scc files you edit in a default changelist set, which quickly shows you the files your likely interested in.

Unit testing

There have been a number of improvements made to Komodo's integrated Unit Testing components.

Extensibility: Komodo now finds and registers the unit test harnesses dynamically. Additional unit test harnesses are best added through Komodo extensions. See the Komodo addons site for a Python Nose extension which provides two test harnesses, one for the PyUnit library and the other for Python doctest.

UI improvements: Test plans can now be associated either with project preferences, as in version 4.3, or through the individual file preferences. There are no longer any global test plans. The Tools|Test menu is now used to manage file-based test plans. A "[Tools|Test|Move Global Test Plans to Document...]" allows the copying of any existing global test plan created in version 4.3 to migrate to a file-based test.

Other Komodo releases

How to setup and use CakePHP with Komodo

Question: 

How do I setup Komodo to best work with my CakePHP applications?

Answer: 

Prerequisites
CakePHP relies on many applications: a web server (like Apache), a database (like MySQL) and PHP 4.3.2 or greater, so ensure you follow the necessary instructions for setting this up for your operating system, see the CakePHP installation section for details:
http://manual.cakephp.org/chapter/installing

I will not cover the setting up of a CakePHP application, but expect the user has an existing CakePHP application they want to work on using Komodo.

Configuring Komodo to work with CakePHP

  • PHP interpreter
    Komodo needs to know where the PHP interpreter is, this is so Komodo can provide PHP specific functionality such as Syntax Checking, Debugging and Code Completion.
    • Go to the Komodo preferences, select the "Languages->PHP" category and check/set the PHP interpreter to point to the PHP executable you have installed.
  • PHP Frameworks
    Komodo needs to know where your third-party PHP code is located, so that it can assist in providing adequate PHP code completions, calltips and code intelligence benefits. Generally for applications that install as part of the PHP standard library location or are added to the php interpreter's php.ini file, this is not necessary, but for frameworks that are configured through the web platform (i.e. http.conf) this step is necessary.
    • Go to the Komodo preferences, select the "Languages->PHP" category and in the "PHP Directories" area, select the "Add..." button to browse to where the core CakePHP libraries are installed, i.e. "/wwwroot/cake/cake" on my linux machine.
  • Setup your project
    Komodo provides help for managing your application development through the use of projects. Projects let you view the application layout, edit and manage files/folders as well as providing command, macro and snippet tools.
    • Use the menu "File->New->Project" to start creating a new project. Save the project to the base directory where your CakePHP application resides, i.e. "/wwwroot/cake/app/App1.kpf"
    • Once saved, the project itself and the list of files/folders should appear in Komodo's project pane, where you sort, expand/collapse and click on to open for editing
    • As you edit your CakePHP application files, you should notice completions for CakePHP functions and classes, try this for an example:
      $session = new CakeSession();
      $session->

      You should have calltip/completions when you type the open paren "new CakeSession(", when you type "$s" and when you type the "session->".

  • Bake run command
    Bake is a command line PHP script that will automagically generate a model, controller, and views based on the design of your database.
    • On your application project, right-click and select menu "Add->New Command...", call it "Bake", set the "Start in:" field to be "%p" which means the active project and then use the command text below:
    • For the command, use
      %(php) /wwwroot/cake/cake/scripts/bake.php

      , or if the script is provided as a windows batch file, you can simply just specifiy this file as

      /wwwroot/cake/cake/scripts/bake.bat
    • Bake runs interactively, so you can either run it through Komodo Command Output Tab (the default) or choose to run it in it's own separate console window, whichever is your preference.

Other Komodo/CakePHP resources
Komodo Macros for inserting CakePHP template hints

Advantages of using Komodo IDE
The advantages of using Komodo are many (just note that I am of course somewhat biased, heh).

  • Komodo comes already prepared with most things you need for PHP development, such as integrated source code control and code intelligence helpers, so you don't need to play around with specific plugins or download a special build to get up and running.
  • Komodo provides code completions and calltips easily, simply define what PHP frameworks you need and and it's done, calltips and completions appear immediately afterwards.
  • Komodo IDE provides debugging tools to help analyse your code and data in real time.
  • Komodo IDE provides additional web tools to help with client/server development, such as the HTTP Inspector and the JavaScript debugger.
  • Most of Komodo is open source, so you can dig into the code and contribute if you feel like it: http://www.openkomodo.com/

Hope that helps.

Cheers,
Todd

JavaScript Debugger Incompatibility

Question: 

Javascript debugging will not work, when I try to debug the page hangs and nothing happens in Komodo, even though Komodo states there is a debugging session.

Answer: 

The current JavaScript debugger included with Komodo 4 has a known incompatibility with the 'Flashgot' Firefox extension, first reported here:

http://community.activestate.com/forum-topic/cant-debug-javascript-komod...

The user reports that uninstalling Flashgot solved the issue. There may be incompatibilities with other Firefox extensions, so if you are having similar problems but do not have Flashgot installed, try this approach to troubleshooting the problem:

- in the Firefox Addons manager, disable all extensions except for JSLib and the Komodo JS Debugger
- verify that JS debugging now works
- try enabling your extensions one by one and re-test JS debugging. This should allow you to identify which extension is causing the problem.
- please report the incompatible extension in the comments to this FAQ.

Tcl not supported in Komodo Edit

Question: 

Tcl syntax checking support seems to have been dropped in Komodo Edit 4.3. What's the deal?

Answer: 

The Tcl syntax checker used in Komodo IDE and previous releases of Komodo Edit is not open source, therefore we decided to remove it from the main build of Komodo Edit as of version 4.3 and provide it as a closed-source extension instead:

http://community.activestate.com/xpi/tcl-syntax-checker