Oracle Database Explorer in Komodo IDE 8.5.3

According to the documentation of Komodo IDE 8.x there should be a possibility to explore Oracle databases with the “Database Explorer” feature. Unfortunately, the only add-on I’ve found so far is “Oracle Database Explorer” that is supported from version 6.x to 7.x .
Is there a possibility that the documentation is wrong about this? Or am I looking at the wrong place to enable Oracle DB exploring?

I think @ericp just needs to update the install.rdf for the Oracle Database Explorer addon. You can do this yourself by following these steps, or wait for @ericp to update the addon.

I’ve attempted to modify the install.rdf, it was a success … but however it still generates errors on attempt to add an Oracle connection. I think we’ll just have to assume @ericp will update his addon.

Other than that, I love this tool, just discovered snippets/abbreviations. Btw, since there is no udl or autocomplete tooltip for PL-SQL, is there a way to make the abbreviations pop-up in a tooltip while typing? Other then CMD+SHIFT+K that is.
In case it’s not possible I’ll have to take figure out how udl works I guess.

Not that I’m aware of, but we should probably make an example auto-complete lib to help people along with stuff like this. Noted.

You could use a Komodo macro to show custom completions:
http://code.activestate.com/recipes/577012-komodo-js-macro-show-custom-code-completions/

Hy toddw, this is very interesting!! I’m gonna try the following in pseudo, for now with a hotkey, if possible while typing:

– Press hotkey or While typing min 3 chars
– Read last word input by user
– Use last word/wordpart to search in abbreviations for matches
– Show autocomplete with max 5 matches
– Choose an answer and store the value
– Trigger abbreviation by selected answer

This looks promising! http://docs.activestate.com/komodo/8.5/komodo-js-api.html

Hi, I’ve been experimenting a bit with the javascript macros and stumbled upon a few issues.

First of all, very nice we can make these ourselves and thanks for the very extensive documentation. One of the most troubling issues I have is that there is no console to figure out the API. So I make some script, dump it into the macro, apply it to an empty file and wait for the results. And that is a slow process.

I’ve downloaded Tiny JS Debugger, but I think I’m using it wrong, cause it’s not helping either. Also I’ve tried Javascript Shell extended, but same goes there, I’m using it all wrong.
[Update]
I’ve somewhat figured out how to use the JS Shell extended. It was hard to determine the scope and to work with the ko.views …
So if I would trigger the autoComplete and request its methods I would’ve expected to find a function that I could use to catch the select event:

ko.views.manager.currentView.scimoz.autoCShow(0, ["option1","option2"].join(String.fromCharCode(ko.views.manager.currentView.scimoz.autoCSeparator)));

If I run that command from the Shell it shows the autocomplete popup, and the available methods in scimoz for the autoC are: autoCShow, autoCCancel, autoCActive, autoCPosStart, autoCComplete, autoCStops, autoCSeparator, autoCSelect, autoCCancelAtStart, autoCSetFillUps, autoCChooseSingle, autoCIgnoreCase, autoCAutoHide, autoCDropRestOfWord, autoCTypeSeparator, autoCMaxWidth, autoCMaxHeight, autoCCurrent, autoCGetCurrentText, autoCCaseInsensitiveBehaviour, autoCOrder .
But these are all actions instead of events … so I can manipulate the autocomplete but not retrieve the selected value in any way.

The following is what I currently have, and I only have 1 issue to fix until I can use it as an autocomplete for abbreviations. The issue is that the autocomplete does not complete the currentword, but it adds the full selected match at the current cursor position. On top of that, I can’t find a trigger being fired when a value is selected from the autocomplete. That would help me to complete the word myself and trigger the correct abbreviation.

if (typeof(window.extensions) == 'undefined') {
    window.extensions = {};
}
if (extensions.abbreviation_autocomplete && extensions.abbreviation_autocomplete.onkeypress_handler) {
    // Remove the existing trigger handler, we'll re-instate it.
    var editor_pane = ko.views.manager.currentView;
    editor_pane.removeEventListener('keyup', extensions.abbreviation_autocomplete.onkeypress_handler, true);
}
extensions.abbreviation_autocomplete = {};
(function(){
    var log = ko.logging.getLogger("AbbreviationAutocomplete");
    var scimoz = ko.views.manager.currentView.scimoz;
    var sep = String.fromCharCode(scimoz.autoCSeparator);
    var completions = ["function", "apex_debug","function_declaration"];
    var lastWord = "";
    //log.setLevel(ko.logging.LOG_DEBUG);
    this.onkeypress_handler = function(e) {
        try {
            var autocompleteArray = [];
            var currentWord = ko.interpolate.getWordUnderCursor(scimoz);
            if (currentWord.length >= 3 && lastWord != currentWord) {
                lastWord = currentWord;
                for (var i=0; i < completions.length;i++) {
                    var option = completions[i];
                    var regex = new RegExp(currentWord + ".*");
                    var match = option.match(regex);
                    if (match && option != currentWord) {
                        autocompleteArray.push(option);
                    }
                }
                scimoz.autoCShow(0, autocompleteArray.join(sep));
            }
            log.debug("this works?");
        } catch(ex) {
            alert(ex);
            log.exception(ex);
        }
    }
    var editor_pane = ko.views.manager.currentView;
    editor_pane.addEventListener('keyup', this.onkeypress_handler, true);
    alert("applied");
}).apply(extensions.abbreviation_autocomplete);

Just want to make sure you’re aware that you can check your logged entries in your pystderr.log file.

As for replacing the word under the caret, you will want to set the first argument you’re passing to scimoz.autoCShow, note that autoCShow performs the matching based on this argument, so if your word under cursor is foo, and you’re passing autoCShow(3, ["foobar", "hello"].join(sep)) then only foo will show as an autocomplete. Similarly if none match the previous N characters then no autocomplete will be shown at all.

Hi Nathan,

I’ve indeed replaced the following line:

 scimoz.autoCShow(0, autocompleteArray.join(sep));
 -->
 scimoz.autoCShow(currentWord.length, autocompleteArray.join(sep));

This works way better, it actually completes the word instead of concatenating the whole keyword with the already typed part. As for filtering options, I’ve tried without modifying my Array, but the autoC shows all the options regardless of the current input.

triggered with the following line:

 ko.views.manager.currentView.scimoz.autoCShow(3, ["option1","select2"].join(String.fromCharCode(ko.views.manager.currentView.scimoz.autoCSeparator)));

So now the only thing remaining is how to capture the selected value or maybe capture a “return” key press to initiate the abbreviation based on the completed word. I’m still not convinced that the JS API with the scimoz.autoC is able to do this…

as for the logging, much obliged sir :wink: works like a charm to debug:

so in console:

cd /Users//Library/Application Support/KomodoEdit/8.5
tail -f pystderr.log

In Javascript shell:

var log = ko.logging.getLogger(“AbbreviationAutocomplete”);
log.setLevel(ko.logging.LOG_INFO)
log.info(“this logging works”)

And the output in console:

[2014-05-15 14:40:43,152] [INFO] view.tabbed: getViews(recursive=false)
[2014-05-15 14:40:43,152] [INFO] view.tabbed: getViews(recursive=false)
[2014-05-15 14:40:43,187] [INFO] koFileStatusService: _process:: starting file status check
[2014-05-15 14:40:43,199] [INFO] koFileStatusService: num files to check: 55, isBackgroundCheck: False
[2014-05-15 14:40:52,029] [INFO] root: this logging works

I’m not sure what you mean by “initiate the abbreviation”? Are your autocompletions basically snippet names? Ie. they are not the actual autocompletions?

You might be able to simply set a variable when you initiate an autocomplete popup, and then capture the enter keypress event to trigger the autocompletion. You’d also need to handle keypress events such as ESC to cancel out of this logic.

From what I can tell Scintilla does not send you any events for this, unfortunately.

Very odd that it still shows you matches that do not match with the previous N chars btw, I couldn’t get it to do that myself. Maybe it’s a new feature in the version of Scintilla that I’m running.

These are indeed snippets without the auto-abbreviation flag:

In this case it would start looking a lot like an IDE for PL/SQL , and that is exactly what I’m missing.
To capture the enter keypress event would be an option, but what if a developer double clicks on an option? That would leave the keypress event unhandled. Do you perhaps know the “ID” of the autocomplete popup? Cause the whole thing can be managed by Javascript, so I’m assuming it’s an HTML page with a DOM tree?

Thanks a lot for the assistance so far, I’ve learned a great deal about Komodo. I will be looking further into extensions and maybe will add the PL/SQL support through UDL some time :smile:
I’m not mistaken if I say that the UDL provides full language support as in variable recognition, autocomplete keywords, initiate snippets, etc … ?

Unfortunately the autcomplete API you’re currently using is part of Scintilla, which is not exactly part of the DOM - it’s a bit complicated. I will direct @ericp to this thread once he’s in, he’s the expert on Scintilla.

UDL is our “tool” for defining our own languages, it may be better suited for what you are trying to do but it’s also a lot more involved. If you’re interested in going down that road I’d recommend you start with the documentation and have a look at other languages that the community has provided.

You might want to try using User List instead - it’s exactly like autocomplete, but the benefit is there is a DOM event sent to notify when the user makes a completion selection (insertion):

window.addEventListener("codeintel_userlist_selected", function(event) {
        var position = event.getData("position");
        var text = event.getData("text");
        alert("user list selected, text: " + text + ", position: " + position);
    }, true);
ko.views.manager.currentView.scimoz.userListShow(3, ["option1","select2"].join(String.fromCharCode(ko.views.manager.currentView.scimoz.autoCSeparator)));

Thank you Tod, this is indeed the better alternative for event listening. Although I’m surprised I have to bind this to the window element to make it work. It doesn’t seem to work in the ko.views.manager.currentView . Also, I can’t remove an event listener from window… , probable because I’m dealing with multiple window elements when switching files?
At this point it almost works as I would expect it to, just that the userListShow does not complete the word, nor does the insertAbbrevSnippet() removes the current word. I’m looking into it, but if you know how to manipulate the current word, you are welcome to share :wink: .

on selecting a value:

Current code:

if (typeof(window.extensions) == 'undefined') {
    window.extensions = {};
}
if (extensions.abbreviation_autocomplete && extensions.abbreviation_autocomplete.onkeypress_handler) {
    var editor_pane = ko.views.manager.currentView;
    editor_pane.removeEventListener('keyup', extensions.abbreviation_autocomplete.onkeypress_handler, true);
}
if (extensions.abbreviation_autocomplete && extensions.abbreviation_autocomplete.codeintel_userlist_select_handler) {
    window.removeEventListener('codeintel_userlist_selected', extensions.abbreviation_autocomplete.codeintel_userlist_select_handler, true);
}
extensions.abbreviation_autocomplete = {};
(function(){
    var log = ko.logging.getLogger("AbbreviationAutocomplete");
    var scimoz = ko.views.manager.currentView.scimoz;
    var separator = String.fromCharCode(scimoz.autoCSeparator);
    var completions = ["function", "apex_debug","function_declaration"];
    var lastWord = "";
    //log.setLevel(ko.logging.LOG_DEBUG);
    this.codeintel_userlist_select_handler = function(event){
        var position = event.getData("position");
        var text = event.getData("text");
        var abbr = ko.abbrev.findAbbrevSnippet(text, "PLSQL");
        ko.abbrev.insertAbbrevSnippet(abbr);
    }
    this.onkeypress_handler = function(event) {
        try {
            var autocompleteArray = [];
            var currentWord = ko.interpolate.getWordUnderCursor(scimoz);
            if (currentWord.length >= 3 && lastWord != currentWord) {
                lastWord = currentWord;
                for (var i=0; i < completions.length;i++) {
                    var option = completions[i];
                    var regex = new RegExp(currentWord + ".*");
                    var match = option.match(regex);
                    if (match && option != currentWord) {
                        autocompleteArray.push(option);
                    }
                }
                if (autocompleteArray.length > 0) {
                    scimoz.userListShow(currentWord.length, autocompleteArray.join(separator));
                }
            }
            log.debug("this works?");
        } catch(ex) {
            alert(ex);
            log.exception(ex);
        }
    }
    var editor_pane = ko.views.manager.currentView;
    editor_pane.addEventListener('keyup', this.onkeypress_handler, true);
    window.addEventListener('codeintel_userlist_selected', this.codeintel_userlist_select_handler, true);
    alert("applied");
}).apply(extensions.abbreviation_autocomplete);

I believe ko.projects.snippetInsert will do what you are looking for, for an example check here: https://gist.github.com/Naatan/e82011550823421e7013

Also note that the window element refers to the base Komodo window, not the editor tab that you currently have open. So using the window element should cover events for each of your editor tabs.