External lexer language type to name?

2008-12-30
2012-11-14
  • Thell Fowler

    Thell Fowler - 2008-12-30

    When using an external lexer and listening for messages (ie NPPN_FILEOPENED, or even SCN_MODIFIED) how can filtering be done so actions are only taken for languages that that specific lexer plugin is made to handle?

    For example, with our Powershe11 lexer plugin, we need to be able to identify when a powershell file is first opened or changed; yet NPPM_GETCURRENTLANGTYPE only reports it as an external, and SCI_GETLEXER reports the language ID number but neither reveals the language name to match against the languages being styled by the plugin, or a way to determine the language ID associated with the lexer plugins languages.  I imagine this is OK when there aren't many external lexers in use but what about when then are multiple ones?

    I've been able to identify a few ways to 'closely' accomplish this, but something along the lines of a GETCURRENTLANGNAME and then iterating through the plugins styled languages would be of great benefit.

    Thanks,
    almostautomated

     
    • Don HO

      Don HO - 2009-01-02

      Use SCI_GETLEXER to get your lexer ID is a better approach than getting lexer name, since the ID is uniq.

      In NPPN_LANGCHANGED case, you should get your SCEXT_POWERSHELL_LANGID ID if a document power shell is switched in.

      So I don't see the problem and I don't think you need getLexerName message.
      Do I miss something?

      Don

       
      • Thell Fowler

        Thell Fowler - 2009-01-02

        Nope, you hit the nail on the head.  Using the GETLEXER to filter message handling actions reduced overhead dramatically!

         
    • Don HO

      Don HO - 2008-12-31

      > I've been able to identify a few ways to 'closely' accomplish this

      What's your approach?

      > but something along the lines of a GETCURRENTLANGNAME and then
      > iterating through the plugins styled languages would be of great benefit.

      In the current implementation, GETCURRENTLANGNAME can work with internal language, but not with external lexer.
      If your approach work, then great, otherwise I'll find a solution.

      Don

       
    • Thell Fowler

      Thell Fowler - 2008-12-31

      Don,

      Here's what I ended up doing...

      in the initial call to the exported Lex()
      if(lexer == 0) {
          if(!SCEXT_POWERSHELL_LANGID) {
              SCEXT_POWERSHELL_LANGID = messageProc(SCI_GETLEXER, 0, 0);
              // If the lexer uses indicators that depend on styler stylat calls the whole doc may need lexing first.
              bInitializeLexing = true;
          }
          InternalLexOrFold(0, startPos, length, initStyle, words, window, props);
      }

      in beNotified:
      case NPPN_FILEOPENED:
      {
          // Force lexing from start of doc to full length for proper initialization of indicators
          int langID = ::SendMessage(hCurrentLexerView, SCI_GETLEXER, 0, 0);
          if (langID == SCEXT_POWERSHELL_LANGID) {
              bInitializeLexing = true;
          }
          break;
      }

      This looks to be working.  No new messages needed :)

      Unfortunately this approach doesn't work so good with NPPN_BEFFERLANGCHANGED since that message is sent AFTER the call to the Lex() routine; so to handle that case:
      case NPPN_LANGCHANGED:
      {
          // Catch buffer language changes to ensure proper indicator initialization
          int langID = ::SendMessage(hCurrentLexerView, SCI_GETLEXER, 0, 0);
          if (langID == SCEXT_POWERSHELL_LANGID) {
              bLanguageChanged = true;
              ::SendMessage(hCurrentLexerView, SCI_STARTSTYLING, 0, 0);
          }
          break;
      }

      almostautomated

       

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks