boolean insertBreakSpecialHandling(ActionEvent e) {
   Action a = tokenMaker.getInsertBreakAction();
   if (a != null) {
     a.actionPerformed(e);
     return true;
   }
   return false;
 }
  /**
   * Alerts all listeners to this document of an insertion. This is overridden so we can update our
   * syntax highlighting stuff.
   *
   * <p>The syntax highlighting stuff has to be here instead of in <code>insertUpdate</code> because
   * <code>insertUpdate</code> is not called by the undo/redo actions, but this method is.
   *
   * @param e The change.
   */
  protected void fireInsertUpdate(DocumentEvent e) {

    /*
     * Now that the text is actually inserted into the content and
     * element structure, we can update our token elements and "last
     * tokens on lines" structure.
     */

    Element lineMap = getDefaultRootElement();
    DocumentEvent.ElementChange change = e.getChange(lineMap);
    Element[] added = change == null ? null : change.getChildrenAdded();

    int numLines = lineMap.getElementCount();
    int line = lineMap.getElementIndex(e.getOffset());
    int previousLine = line - 1;
    int previousTokenType = (previousLine > -1 ? lastTokensOnLines.get(previousLine) : Token.NULL);

    // If entire lines were added...
    if (added != null && added.length > 0) {

      Element[] removed = change.getChildrenRemoved();
      int numRemoved = removed != null ? removed.length : 0;

      int endBefore = line + added.length - numRemoved;
      // System.err.println("... adding lines: " + line + " - " + (endBefore-1));
      // System.err.println("... ... added: " + added.length + ", removed:" + numRemoved);
      for (int i = line; i < endBefore; i++) {

        setSharedSegment(i); // Loads line i's text into s.

        int tokenType = tokenMaker.getLastTokenTypeOnLine(s, previousTokenType);
        lastTokensOnLines.add(i, tokenType);
        // System.err.println("--------- lastTokensOnLines.size() == " +
        // lastTokensOnLines.getSize());

        previousTokenType = tokenType;
      } // End of for (int i=line; i<endBefore; i++).

      // Update last tokens for lines below until they stop changing.
      updateLastTokensBelow(endBefore, numLines, previousTokenType);

    } // End of if (added!=null && added.length>0).

    // Otherwise, text was inserted on a single line...
    else {

      // Update last tokens for lines below until they stop changing.
      updateLastTokensBelow(line, numLines, previousTokenType);
    } // End of else.

    // Let all listeners know about the insertion.
    super.fireInsertUpdate(e);
  }
  /**
   * Loops through the last-tokens-on-lines array from a specified point onward, updating last-token
   * values until they stop changing. This should be called when lines are updated/inserted/removed,
   * as doing so may cause lines below to change color.
   *
   * @param line The first line to check for a change in last-token value.
   * @param numLines The number of lines in the document.
   * @param previousTokenType The last-token value of the line just before <code>line</code>.
   * @return The last line that needs repainting.
   */
  private int updateLastTokensBelow(int line, int numLines, int previousTokenType) {

    int firstLine = line;

    // Loop through all lines past our starting point.  Update even the last
    // line's info, even though there aren't any lines after it that depend
    // on it changing for them to be changed, as its state may be used
    // elsewhere in the library.
    int end = numLines;
    // System.err.println("--- end==" + end + " (numLines==" + numLines + ")");
    while (line < end) {

      setSharedSegment(line); // Sets s's text to that of line 'line' in the document.

      int oldTokenType = lastTokensOnLines.get(line);
      int newTokenType = tokenMaker.getLastTokenTypeOnLine(s, previousTokenType);
      // System.err.println("---------------- line " + line + "; oldTokenType==" + oldTokenType + ",
      // newTokenType==" + newTokenType + ", s=='" + s + "'");

      // If this line's end-token value didn't change, stop here.  Note
      // that we're saying this line needs repainting; this is because
      // the beginning of this line did indeed change color, but the
      // end didn't.
      if (oldTokenType == newTokenType) {
        // System.err.println("... ... ... repainting lines " + firstLine + "-" + line);
        fireChangedUpdate(
            new DefaultDocumentEvent(firstLine, line, DocumentEvent.EventType.CHANGE));
        return line;
      }

      // If the line's end-token value did change, update it and
      // keep going.
      // NOTE: "setUnsafe" is okay here as the bounds checking was
      // already done in lastTokensOnLines.get(line) above.
      lastTokensOnLines.setUnsafe(line, newTokenType);
      previousTokenType = newTokenType;
      line++;
    } // End of while (line<numLines).

    // If any lines had their token types changed, fire a changed update
    // for them.  The view will repaint the area covered by the lines.
    // FIXME:  We currently cheat and send the line range that needs to be
    // repainted as the "offset and length" of the change, since this is
    // what the view needs.  We really should send the actual offset and
    // length.
    if (line > firstLine) {
      // System.err.println("... ... ... repainting lines " + firstLine + "-" + line);
      fireChangedUpdate(new DefaultDocumentEvent(firstLine, line, DocumentEvent.EventType.CHANGE));
    }

    return line;
  }
 /**
  * Returns a token list for the specified segment of text representing the specified line number.
  * This method is basically a wrapper for <code>tokenMaker.getTokenList</code> that takes into
  * account the last token on the previous line to assure token accuracy.
  *
  * @param line The line number of <code>text</code> in the document, >= 0.
  * @return A token list representing the specified line.
  */
 public final Token getTokenListForLine(int line) {
   Element map = getDefaultRootElement();
   Element elem = map.getElement(line);
   int startOffset = elem.getStartOffset();
   // int endOffset = (line==map.getElementCount()-1 ? elem.getEndOffset() - 1:
   //									elem.getEndOffset() - 1);
   int endOffset = elem.getEndOffset() - 1; // Why always "-1"?
   try {
     getText(startOffset, endOffset - startOffset, s);
   } catch (BadLocationException ble) {
     ble.printStackTrace();
     return null;
   }
   int initialTokenType = line == 0 ? Token.NULL : getLastTokenTypeOnLine(line - 1);
   return tokenMaker.getTokenList(s, initialTokenType, startOffset);
 }
  /**
   * Updates internal state information; e.g. the "last tokens on lines" data. After this, a changed
   * update is fired to let listeners know that the document's structure has changed.
   *
   * <p>This is called internally whenever the syntax style changes.
   */
  protected void updateSyntaxHighlightingInformation() {

    // Reinitialize the "last token on each line" array.  Note that since
    // the actual text in the document isn't changing, the number of lines
    // is the same.
    Element map = getDefaultRootElement();
    int numLines = map.getElementCount();
    int lastTokenType = Token.NULL;
    for (int i = 0; i < numLines; i++) {
      setSharedSegment(i);
      lastTokenType = tokenMaker.getLastTokenTypeOnLine(s, lastTokenType);
      lastTokensOnLines.set(i, lastTokenType);
    }

    // Let everybody know that syntax styles have (probably) changed.
    fireChangedUpdate(new DefaultDocumentEvent(0, numLines - 1, DocumentEvent.EventType.CHANGE));
  }
 /**
  * Sets whether whitespace is visible. This property is actually setting whether the tokens
  * generated from this document "paint" something when they represent whitespace.
  *
  * @param visible Whether whitespace should be visible.
  * @see #isWhitespaceVisible()
  */
 public void setWhitespaceVisible(boolean visible) {
   tokenMaker.setWhitespaceVisible(visible);
 }
 /**
  * Sets the syntax style being used for syntax highlighting in this document. You should call this
  * method if you've created a custom token maker for a language not normally supported by <code>
  * RSyntaxTextArea</code>.
  *
  * @param tokenMaker The new token maker to use.
  */
 public void setSyntaxStyle(TokenMaker tokenMaker) {
   tokenMaker.setWhitespaceVisible(isWhitespaceVisible());
   this.tokenMaker = tokenMaker;
   updateSyntaxHighlightingInformation();
 }
 /**
  * Sets the syntax style being used for syntax highlighting in this document. What styles are
  * supported by a document is determined by its {@link TokenMakerFactory}. By default, all <code>
  * RSyntaxDocument</code>s support all languages built into <code>RSyntaxTextArea</code>.
  *
  * @param styleKey The new style to use, such as {@link SyntaxConstants#SYNTAX_STYLE_JAVA}. If
  *     this style is not known or supported by this document, then {@link
  *     SyntaxConstants#SYNTAX_STYLE_NONE} is used.
  */
 public void setSyntaxStyle(String styleKey) {
   boolean wsVisible = isWhitespaceVisible();
   tokenMaker = tokenMakerFactory.getTokenMaker(styleKey);
   tokenMaker.setWhitespaceVisible(wsVisible);
   updateSyntaxHighlightingInformation();
 }
 /**
  * Returns whether whitespace is visible.
  *
  * @return Whether whitespace is visible.
  * @see #setWhitespaceVisible(boolean)
  */
 public boolean isWhitespaceVisible() {
   return tokenMaker == null ? false : tokenMaker.isWhitespaceVisible();
 }
 /**
  * This method returns whether auto indentation should be done if Enter is pressed at the end of
  * the specified line.
  *
  * @param line The line to check.
  * @return Whether an extra indentation should be done.
  */
 public boolean getShouldIndentNextLine(int line) {
   Token t = getTokenListForLine(line);
   t = t.getLastNonCommentNonWhitespaceToken();
   return tokenMaker.getShouldIndentNextLineAfter(t);
 }
 /**
  * Returns whether tokens of the specified type should have "mark occurrences" enabled for the
  * current programming language.
  *
  * @param type The token type.
  * @return Whether tokens of this type should have "mark occurrences" enabled.
  */
 boolean getMarkOccurrencesOfTokenType(int type) {
   return tokenMaker.getMarkOccurrencesOfTokenType(type);
 }
 /**
  * Returns the text to place at the beginning and end of a line to "comment" it in the current
  * programming language.
  *
  * @return The start and end strings to add to a line to "comment" it out. A <code>null</code>
  *     value for either means there is no string to add for that part. A value of <code>null
  *     </code> for the array means this language does not support commenting/uncommenting lines.
  */
 public String[] getLineCommentStartAndEnd() {
   return tokenMaker.getLineCommentStartAndEnd();
 }
 /**
  * Returns whether the current language is a markup language, such as HTML, XML or PHP.
  *
  * @return Whether the current language is a markup language.
  */
 public boolean getLanguageIsMarkup() {
   return tokenMaker.isMarkupLanguage();
 }
 /**
  * Returns whether the current programming language uses curly braces ('<tt>{</tt>' and
  * '<tt>}</tt>') to denote code blocks.
  *
  * @return Whether curly braces denote code blocks.
  */
 public boolean getCurlyBracesDenoteCodeBlocks() {
   return tokenMaker.getCurlyBracesDenoteCodeBlocks();
 }