Ext Direct errors

Note to self: when Ext Direct calls start failing, look in the request headers for error messages.  I'm not sure whether it's Ext itself or just our framework, but for whatever reason, Ext Direct calls seem to more or less swallow server-side errors.

In this particular case, I was experimenting with some of the code that our in-house development framework uses to render maps.  We have OpenLayers on the front-end a custom PHP back-end that we communicate with in part through Ext Direct, which is the handy-dandy AJAX RPC framework that comes packaged with Sencha's ExtJS.

So anyway, I made some changes, reloaded the page, and all my Ext Direct calls were failing.  No meaningful error messages, nothing in the JavaScript console, and the response body was just empty.  So what the heck was happening?  (Yeah, I know, I could have just run the unit tests, since we actually have unit tests for the framework code.  But that didn't occur to me because so much of the application code is missing them and I was just experimenting anyway.  Get off my back!) 

Then I noticed, just by chance, that the request headers in the network tab of Chrome's dev tools looked weird.  In particular, it contained this header:
X-Powered-By:PHP/5.3.21 Missing argument 1 for...

So that's what happened to the error message — it got dumped into the headers.  Not terribly helpful, but good to know.

VI makes so much more sense now

Thanks to this answer from StackOverflow, the key mappings in VI and Vim make soooo much more sense now.  It's all explained by this keyboard layout:

The keyboard layout that was used when VI was created.

The more I use Vim, or the Vim emulation in Komodo, the less sense it makes to use the "escape" key to switch out of insert mode.  I mean, you have to move your hand way away from the home row just to reach it, which is exactly the opposite of how things are supposed to work.  But if you're using this keyboard, then it seems like a completely obvious choice.

Incidentally, after far too many years of suffering with the escape key, I've switched to using the other choices for getting out of insert mode — Ctrl-C and Ctrl-[.  Both do the same thing as the escape key, but require significantly less hand movement and so are faster to type.  Especially Ctrl-C, as most of us are used to using that for copying text to the clipboard.

Incidentally, since I'm using the Vim emulation for Komodo IDE/Edit, I should probably mention that it does support Ctrl-[ out of the box, but not Ctrl-C — that is, naturally, reserved for the "copy" operation.  However, it's easy to change that.  Simply create a new macro with the following code and set the key binding for it to Ctrl-C (you may have to unbind the standard "copy" operation first):

var scimoz = ko.views.manager.currentView.scimoz;
if (scimoz && scimoz.selText.length == 0) {
    ko.commands.doCommand('cmd_vim_cancel');
} else {
    ko.commands.doCommand('cmd_copy');
}

This macro preserves the standard copy behavior by checking if you have any text selected when it executes.  If you do, it does a standard "copy to clipboard".  If you don't, it switches the editor from "insert" mode to "normal" mode.

Project commit in Komodo IDE

Edit (2014-10-09): An improved version of this macro can be found in this post.

So I finally got around to writing a little macro for Komodo IDE that I've been missing for a while.  It has a very simple task - perform a "source control commit" operation on the currently project.  You'd think this would be built in, and it wort of is, but it doesn't work very well. 

In Komodo IDE, the SCC commit action is tied to files and directories.  So if you want to commit an entire directory, you need to select it in the "places" pane (i.e. the file system browser).  And if you want to commit the directory that's currently set as the root of the file view, you either have to go up a level and select it or right-click on an empty spot in the file browser.  So, in other words, it's grossly inconvenient.

Hence this little macro.  Just create a new macro in your toolbox and paste this code into it (note that this doesn't work in Komodo Edit).  Note that this is a little hacky, as some of the SCC initialization seems to be asynchronous and I don't know what (if any) events are fired on completion.  But hey, it works, so close enough.

(function() {
    var curr_project_url =  ko.projects.manager.getCurrentProject().importDirectoryURI,
        fileSvc = Components.classes["@activestate.com/koFileService;1"]
                            .getService(Components.interfaces.koIFileService),
        kodir = fileSvc.getFileFromURI(curr_project_url),
        count = 0;
    
    // HACK: For some reason, the SCC type takes some time to populate.
    // I don't know if there's any event for this, so instead just try it again
    // if it's empty.
    var runner = function() {
        var cid = '',
            sccSvc = undefined;
            
        if (kodir.sccDirType) {
            cid = "@activestate.com/koSCC?type=" + kodir.sccDirType + ";1";
            sccSvc = Components.classes[cid].getService(Components.interfaces.koISCC);
            
            // Get the koISCC service object
            if (!sccSvc || !sccSvc.isFunctional) {
                alert("Didn't get back a functional SCC service. :(");
            } else {
                ko.scc.Commit(sccSvc, [curr_project_url]);
            }
        } else if (count < 10) { // Just in case this never actually works....
            count += 1;
            setTimeout(runner, 100);
        }
    };
    
    runner();
})();