How does user determine LangID for an external lexer used in Function List?

  • smitchell

    smitchell - 2014-02-05

    Hi All,

    How does one add an entry to <AssociationMap> in functionList.xml for an external lexer?
    When creating the association, <association LangID="??" id="file_node"/>, where do we get a value for LangID?

    For an internal lexer, the LangID is fixed at a value from the LangType enumeration in Notepad_plus_msgs.h. For an external lexer, the LangID is L_EXTERNAL, L_EXTERNAL+1, ... depending on the order in which external lexers are installed. In addition, the value of L_EXTERNAL depends on N++ version.

    I have come up with a technique for determining the LangID. My approach goes like this ...

    • Get the main HMENU of N++
    • Iterate over Submenu strings to find "&Language" menu
    • Iterate over Submenu (and SubSubmenu) strings of Language HMENU
    • While iterating get menuItemIDEx for external lexer of interest, and determine max menuItemIDMax of internal lexers
    • Evaluate L_EXTERNAL as "(menuItemIDMax - IDM_LANG) + 1"
    • Evaluate LangID as L_EXTERNAL + (menuItemIDEx - IDM_LANG_EXTERNAL)
      (IDM_LANG and IDM_LANG_EXTERNAL are defined in menuCmdID.h)

    I plan to display the LangID in the plugin's About box so a user can easily find it.
    Does anyone have suggestions for a better way of doing this or see any problems with using this approach?


  • cchris

    cchris - 2014-02-05

    Simply give your association an attribute
    userDefinedLangName="language name"
    and langID = 15, which is L_USER.
    You shouldn't need to provide extensions, unless you wish to trigger the parser on some of the extensions for the UDL.


    Last edit: cchris 2014-02-05
    • smitchell

      smitchell - 2014-02-06

      Hi CChris,

      Thanks for your comments. I tried what you suggested, using this association entry:

       <association langID="15" userDefinedLangName="GEDCOM" id="gedcom_name"/>

      but that prevents my parser from being called. The only association I've found that works is this:

       <association langID="57" id="gedcom_name"/>

      From the "Link to Language" description at at the bottom of the page, it states that langID takes precedence over UDL and extension.

      The files that I'm parsing for the Function List have an external lexer (GedcomLexer.dll), and apparently that forces the langID to be >= L_EXTERNAL. So unless there is some other way to define the association, it looks like I need to know the langID.


  • cchris

    cchris - 2014-02-06

    Oh! Indeed.
    User defined languages are those which you may import from the UDL dialog, and for them the procedure I outlined works.
    Yours is an external language, which is not taken care of in the same way, and for which you need to retrieve anan explicit langID.

    Please note that langIDs are assigned dynamically as the lexers are loaded. If for any reason the order or number of lexers changes, the langID will probably differ. Folder sort options may interfere as well, since N++ loads plugins in the order Windows chooses for listing them. Admittedly, this begs for specific external language support.


  • smitchell

    smitchell - 2014-02-06

    Thanks for the follow up, confirming that the langID is needed. I thought you might have missed the fact that it is an external language. :)