Writing a self-contained lexer for scintilla
scintilla is a script editing component http://www.scintilla.org for more information.



This document covers the use of writing a self-contained lexer for scintilla
I figure once you can color the document based on the first character of each line,
that you should be able to color anything...
So that's all I cover, first-character of each line styling.


Register the on style needed event for the window (this is windows specific)
static const int WINDOW_ID = 900;

BEGIN_MESSAGE_MAP(CDocumentWindow, CDocumentWindowsBaseClass)
  ON_NOTIFY(SCN_STYLENEEDED, WINDOW_ID, OnStyleNeeded)
END_MESSAGE_MAP()

(WINDOW_ID is used in the CreateWindow call when you create the window)



Create some constants for styling...
static const int SCE_STYLE_ORANGE = 11;
static const int SCE_STYLE_PURPLE = 12;
static const int SCE_STYLE_BLUE   = 13;

Set the lexer type
(This should probably be done in the document's constructor or on create method)
  SendEditor(SCI_SETLEXER, SCLEX_CONTAINER);

Set the default colors and such
  static const COLORREF black   = 0x000000;
  static const COLORREF white   = 0xFFFFFF;

  SendEditor(SCI_STYLESETFORE, STYLE_DEFAULT, black);
  SendEditor(SCI_STYLESETBACK, STYLE_DEFAULT, white);
  SendEditor(SCI_STYLECLEARALL);

Set the colors for our styling types
  static const COLORREF blue    = RGB(0, 0, 0xFF);
  static const COLORREF purple  = RGB(0xFF, 0, 0xFF);
  static const COLORREF orange  = RGB(0xFF, 128, 0);

  SendEditor(SCI_STYLESETFORE, SCE_STYLE_BLACK,  black);
  SendEditor(SCI_STYLESETFORE, SCE_STYLE_ORANGE, orange);
  SendEditor(SCI_STYLESETFORE, SCE_STYLE_PURPLE, purple);
  SendEditor(SCI_STYLESETFORE, SCE_STYLE_BLUE,   blue);

Add the OnStyleNeeded method (note that the method prototype is windows specific)
/**
 * Simple first-character of each line lexer
 * [-] = line should be SCE_STYLE_ORANGE
 * [/] = line should be SCE_STYLE_PURPLE
 * [*] = line should be SCE_STYLE_BLUE
 * Anything else = SCE_STYLE_BLACK
 */
afx_msg void
CDocumentWindow::OnStyleNeeded(NMHDR* nmhdr, LRESULT* result)
{
  SCNotification* notify = (SCNotification*)nmhdr;
  const int line_number = SendEditor(SCI_LINEFROMPOSITION, SendEditor(SCI_GETENDSTYLED));
  const int start_pos = SendEditor(SCI_POSITIONFROMLINE, (WPARAM)line_number);
  const int end_pos = notify->position;

  int line_length = SendEditor(SCI_LINELENGTH, (WPARAM)line_number);
  if (line_length > 0) {
    char first_char = SendEditor(SCI_GETCHARAT, (WPARAM)start_pos);

    // The SCI_STARTSTYLING here is important
    SendEditor(SCI_STARTSTYLING, start_pos, 0x1f);

    switch (first_char)
    {
      case '-':
        SendEditor(SCI_SETSTYLING, line_length, SCE_STYLE_ORANGE);
      break;

      case '/':
        SendEditor(SCI_SETSTYLING, line_length, SCE_STYLE_PURPLE);
      break;

      case '*':
        SendEditor(SCI_SETSTYLING, line_length, SCE_STYLE_BLUE);
      break;

      default:
          SendEditor(SCI_SETSTYLING, line_length, SCE_STYLE_BLACK);
      break;
    }
  }
}
That's it, enjoy.
You can send any comments or suggestions about this to vascy@hotmail.com