Keyword SmartIndent?

The plugin I am working on for Komodo uses keyword smart indent. The _indenting_statements and the _dedenting_statements work as expected , but _keyword_dedenting_keywords does not seem to do anything.

_indenting_statements = [‘a’]
_dedenting_statements = [‘b’]
_keyword_dedenting_keywords = [‘c’]

When I type ‘a’ (and hit enter), it indents correctly. When I type ‘b’, it dedents correctly, but when I type ‘c’ (and hit enter) it does nothing.

I get:

a
    <code>
    c

I expect:

a
    <code>
c

Is there some other detail that I need to get this working?

Is “c” defined as a keyword?

I do define a, b and c as keywords (and they highlight correctly), the related code looks like:

koTest_UDL_Language.py:

supportsSmartIndent = "keyword"
_indenting_statements = ['a']
_dedenting_statements = ['b']
_keyword_dedenting_keywords = ['c']

test-mainlex.udl:

keywords [
    "a",
    "b",
    "c"
]

codeintel_test.py: (not sure this actually matters, but I did it anyway)

keywords = [
    "a",
    "b",
    "c"
]

Another oddity, if I type ‘a’ and hit enter, it does not indent correctly, it only does so if any other allowed character (a space, an operator, etc…), follows “a” (the same oddity does not effect ‘b’, and ‘c’ just doesn’t work at all)

Could you see if increasing the length of the keywords has something to do with it? Make each keyword at least 2 characters and see what that does.

Originally, before I posted, I was using multi-character keywords, I only trimmed them down to a single character for testing simplicity. The only difference between multi-character keywords and single character keywords is that with the multi-character keywords the _indenting_statements work without requiring an additional character. Either way, “c” does not work (even if I change it to “csdf”).

@mitchell any ideas?

If it helps, later today I can make a minimal example and upload the source.

Edit: I have a sample, generated with the Komodo > Projects > New From Template > Komodo Language with a few modifications (just adding the indent statements), and it doesn’t work. I can either upload this (if I can find a place) or if you want, all I added to the template generated project was (in kotest_UDL_language.py):

supportsSmartIndent = "keyword"
_indenting_statements = ['qwer']
_dedenting_statements = ['asdf']
_keyword_dedenting_keywords = ['zxcv']

(with obviously having qwer, asdf, and zxcv as keywords)

Hi, your language must utilize koLanguageKeywordBase. Something like this worked for me:

# Registers the Test language in Komodo.

import logging
from koLanguageKeywordBase import KoLanguageKeywordBase
from koLanguageServiceBase import koLangSvcStyleInfo
from koUDLLanguageBase import KoUDLLanguage

log = logging.getLogger("koTestLanguage")
#log.setLevel(logging.DEBUG)

def registerLanguage(registry):
    log.debug("Registering language Test")
    registry.registerLanguage(KoTestLanguage())

class KoTestLanguage(KoUDLLanguage, KoLanguageKeywordBase):

    # ------------ Komodo Registration Information ------------ #

    name = "Test"
    lexresLangName = "Test"
    _reg_desc_ = "%s Language" % name
    _reg_contractid_ = "@activestate.com/koLanguage?language=%s;1" % name
    _reg_categories_ = [("komodo-language", name)]
    _reg_clsid_ = "70b8b1fe-d5f6-4378-895d-995e274dc63b"

    defaultExtension = '.test'
    primary = 1  # Whether the language shows up in Komodo's first level language menus.

    # ------------ Commenting Controls ------------ #

    commentDelimiterInfo = {
        "line": [
                #'//',   # C-style one line comments
                #'#',    # Hash-style one line comments
                #'--',   # SQL-style one line comments
                #';',    # Lisp-style one line comments
                #'%',    # Erlang-style one line comments
                ],
        "block": [
                #('/*', '*/')   # C-style block comments
                #('(*', '*)')   # Pascal-style block comments
                ],
    }

    # ------------ Indentation Controls ------------ #

    # To support automatic indenting and dedenting after "{([" and "})]"
    supportsSmartIndent = "keyword"
    # Other smart indenting types are:
    #   'text', 'python', 'XML' and 'keyword'

    # Indent/dedent after these words.
    _indenting_statements = ['foo']
    _dedenting_statements = ['bar']
    _keyword_dedenting_keywords = ['baz']

    # ------------ Sub-language Controls ------------ #

    #Check: Update 'lang_from_udl_family' as appropriate for your
    #      lexer definition. There are four UDL language families:
    #           M (markup), i.e. HTML or XML
    #           CSL (client-side language), e.g. JavaScript
    #           SSL (server-side language), e.g. Perl, PHP, Python
    #           TPL (template language), e.g. RHTML, Django, Smarty
    #      'lang_from_udl_family' maps each UDL family code (M,
    #      CSL, ...) to the sub-language name in your language.
    #      Some examples:
    #        lang_from_udl_family = {   # A PHP file can contain
    #           'M': 'HTML',            #   HTML
    #           'SSL': 'PHP',           #   PHP
    #           'CSL': 'JavaScript',    #   JavaScript
    #        }
    #        lang_from_udl_family = {   # An RHTML file can contain
    #           'M': 'HTML',            #   HTML
    #           'SSL': 'Ruby',          #   Ruby
    #           'CSL': 'JavaScript',    #   JavaScript
    #           'TPL': 'RHTML',         #   RHTML template code
    #        }
    #        lang_from_udl_family = {   # A plain XML can just contain
    #           'M': 'XML',             #   XML
    #        }
    lang_from_udl_family = {'SSL': 'Test'}
    
    def __init__(self):
        KoLanguageKeywordBase.__init__(self)
        KoUDLLanguage.__init__(self)
        
        # Manually set up styles since the defaults are no good thanks to Ruby.
        from xpcom import components
        ScintillaConstants = components.interfaces.ISciMoz
        self._style_info = koLangSvcStyleInfo(
            _indent_styles = [ScintillaConstants.SCE_UDL_SSL_OPERATOR],
            _indent_open_styles = [ScintillaConstants.SCE_UDL_SSL_OPERATOR],
            _indent_close_styles = [ScintillaConstants.SCE_UDL_SSL_OPERATOR],
            _lineup_close_styles = [ScintillaConstants.SCE_UDL_SSL_OPERATOR],
            _lineup_styles = [ScintillaConstants.SCE_UDL_SSL_OPERATOR],
            _comment_styles=[ScintillaConstants.SCE_UDL_SSL_COMMENT,
                             ScintillaConstants.SCE_UDL_SSL_COMMENTBLOCK],
            _block_comment_styles=[ScintillaConstants.SCE_UDL_SSL_COMMENT,
                                   ScintillaConstants.SCE_UDL_SSL_COMMENTBLOCK],
            _keyword_styles = [ScintillaConstants.SCE_UDL_SSL_WORD],
            _number_styles = [ScintillaConstants.SCE_UDL_SSL_NUMBER],
            _string_styles = [ScintillaConstants.SCE_UDL_SSL_STRING],
            _regex_styles = [ScintillaConstants.SCE_UDL_SSL_REGEX],
            _variable_styles = [ScintillaConstants.SCE_UDL_SSL_VARIABLE],
            _default_styles = [ScintillaConstants.SCE_UDL_SSL_DEFAULT],
            _multiline_styles = [ScintillaConstants.SCE_UDL_SSL_STRING]
        )
    
    def _keyPressed(self, ch, scimoz, style_info):
        return KoLanguageKeywordBase._keyPressed(self, ch, scimoz, style_info)
    
    def _keyPressedAux(self, ch, scimoz, style_info):
        return KoLanguageKeywordBase._keyPressedAux(self, ch, scimoz, style_info)

If I try and use the code you pasted as the kotest_UDL_Language.py file, with the template generated Komodo language plugin (adding foo, bar, and baz as keywords in the test-mainlex.udl), then Komodo crashes any time it loads the plugin (any time I have a .test file open).

Is there some other detail missing from your example that makes it work, some detail in another one of the generated template files?

Hi, I didn’t do anything other than use Komodo to generate new language files from a template and modify the Python file I posted above. Would you please post the contents of your error log file after the crash? (It’s “pystderr.log” and located as described here: Important File Locations). Note that this file is cleared every time you start Komodo.

Reading the contents of the log, it does not mention anything about crashing, or any errors at all, just a couple warnings. Here is the log, if it helps any.

[2015-10-19 09:12:28,515] [INFO] Startup: Welcome to Komodo Edit 9.2.1 build 15998 (platform macosx, running on Darwin 14.3.0 version Darwin Kernel Version 14.3.0: Mon Mar 23 11:59:05 PDT 2015; root:xnu-2782.20.48~5/RELEASE_X86_64)
[2015-10-19 09:12:28,516] [INFO] Startup: /Applications/Komodo Edit 9.app/Contents/MacOS/komodo built on Wed Sep 2 00:18:38 2015
[2015-10-19 09:12:28,576] [WARNING] koInitService: Unable to determine the current locale settings, defaulting to mac-roman
[2015-10-19 09:12:28,782] [WARNING] console-logger: mutating the [[Prototype]] of an object will cause your code to run very slowly; instead create the object with the correct initial [[Prototype]] value using Object.create (1) in resource://gre/modules/Preferences.jsm:381
[2015-10-19 09:12:28,800] [WARNING] console-logger: Expected end of value but found 'solid'.  Error in parsing value for 'border-width'.  Declaration dropped. (1) in chrome://global/skin/global.css:2358
[2015-10-19 09:12:28,969] [WARNING] root: ko.logging has been converted to a CommonJS module; use require("ko/logging") instead (since Komodo 9.0.0a1).
@chrome://komodo/content/komodo.js:48:1

[2015-10-19 09:12:29,491] [WARNING] console-logger: mutating the [[Prototype]] of an object will cause your code to run very slowly; instead create the object with the correct initial [[Prototype]] value using Object.create (1) in file:///Applications/Komodo%20Edit%209.app/Contents/Resources/components/koamAddonManager.js:138
[2015-10-19 09:12:29,524] [WARNING] keybindings: [Meta+Shift+Down] was used for 'cmd_selectDocumentHome', overriding to use 'cmd_selectDocumentEnd'
[2015-10-19 09:12:30,429] [WARNING] language styles: addNewUDLLanguage: overwriting statemap for lang Test
[2015-10-19 09:12:30,432] [WARNING] KoUDLLanguageBase: no lexer resource was found for 'Test' language (no 'Test.lexres' in lexers dirs)

Could you try the latest 9.3.0 pre-release? I know @mitchell fixed at least one bug related to generated languages, perhaps that’s affecting you?

It still crashes when I load/create a .test file or select test from the languages. I tried “recompiling” the plugin, and uninstall/reinstalling it, but it still crashed.

The pystderr.log looks pretty much the same as it did with 9.2

I can send the whole test project to someone (or I can try a project generated by someone else). Maybe copy/paste threw off the python indentation and I just need an actual file to test.