private void insertBreakInMLC(ActionEvent e, RSyntaxTextArea textArea, int line) {

      Matcher m = null;
      int start = -1;
      int end = -1;
      try {
        start = textArea.getLineStartOffset(line);
        end = textArea.getLineEndOffset(line);
        String text = textArea.getText(start, end - start);
        m = p.matcher(text);
      } catch (BadLocationException ble) { // Never happens
        UIManager.getLookAndFeel().provideErrorFeedback(textArea);
        ble.printStackTrace();
        return;
      }

      if (m.lookingAt()) {

        String leadingWS = m.group(1);
        String mlcMarker = m.group(2);

        // If the caret is "inside" any leading whitespace or MLC
        // marker, move it to the end of the line.
        int dot = textArea.getCaretPosition();
        if (dot >= start && dot < start + leadingWS.length() + mlcMarker.length()) {
          // If we're in the whitespace before the very start of the
          // MLC though, just insert a normal newline
          if (mlcMarker.charAt(0) == '/') {
            handleInsertBreak(textArea, true);
            return;
          }
          textArea.setCaretPosition(end - 1);
        }

        boolean firstMlcLine = mlcMarker.charAt(0) == '/';
        boolean nested = appearsNested(textArea, line, start + leadingWS.length() + 2);
        String header = leadingWS + (firstMlcLine ? " * " : "*") + m.group(3);
        textArea.replaceSelection("\n" + header);
        if (nested) {
          dot = textArea.getCaretPosition(); // Has changed
          textArea.insert("\n" + leadingWS + " */", dot);
          textArea.setCaretPosition(dot);
        }

      } else {
        handleInsertBreak(textArea, true);
      }
    }
 /**
  * Returns the template that should be inserted at the current caret position, assuming the
  * trigger character was pressed.
  *
  * @param textArea The text area that's getting text inserted into it.
  * @return A template that should be inserted, if appropriate, or <code>null</code> if no template
  *     should be inserted.
  */
 public CodeTemplate getTemplate(RSyntaxTextArea textArea) {
   int caretPos = textArea.getCaretPosition();
   int charsToGet = Math.min(caretPos, maxTemplateIDLength);
   try {
     Document doc = textArea.getDocument();
     doc.getText(caretPos - charsToGet, charsToGet, s);
     int index = Collections.binarySearch(templates, s, comparator);
     return index >= 0 ? (CodeTemplate) templates.get(index) : null;
   } catch (BadLocationException ble) {
     ble.printStackTrace();
     throw new InternalError("Error in CodeTemplateManager");
   }
 }
  public static int getMatchingBracketPosition(RSyntaxTextArea textArea) {

    try {

      // Actually position just BEFORE caret.
      int caretPosition = textArea.getCaretPosition() - 1;
      if (caretPosition > -1) {

        // Some variables that will be used later.
        Token token;
        Element map;
        int curLine;
        Element line;
        int start, end;
        RSyntaxDocument doc = (RSyntaxDocument) textArea.getDocument();
        char bracket = doc.charAt(caretPosition);

        // First, see if the previous char was a bracket
        // ('{', '}', '(', ')', '[', ']').
        // If it was, then make sure this bracket isn't sitting in
        // the middle of a comment or string.  If it isn't, then
        // initialize some stuff so we can continue on.
        char bracketMatch;
        boolean goForward;
        switch (bracket) {
          case '{':
          case '(':
          case '[':

            // Ensure this bracket isn't in a comment.
            map = doc.getDefaultRootElement();
            curLine = map.getElementIndex(caretPosition);
            line = map.getElement(curLine);
            start = line.getStartOffset();
            end = line.getEndOffset();
            token = doc.getTokenListForLine(curLine);
            token = RSyntaxUtilities.getTokenAtOffset(token, caretPosition);
            // All brackets are always returned as "separators."
            if (token.type != Token.SEPARATOR) {
              return -1;
            }
            bracketMatch = bracket == '{' ? '}' : (bracket == '(' ? ')' : ']');
            goForward = true;
            break;

          case '}':
          case ')':
          case ']':

            // Ensure this bracket isn't in a comment.
            map = doc.getDefaultRootElement();
            curLine = map.getElementIndex(caretPosition);
            line = map.getElement(curLine);
            start = line.getStartOffset();
            end = line.getEndOffset();
            token = doc.getTokenListForLine(curLine);
            token = RSyntaxUtilities.getTokenAtOffset(token, caretPosition);
            // All brackets are always returned as "separators."
            if (token.type != Token.SEPARATOR) {
              return -1;
            }
            bracketMatch = bracket == '}' ? '{' : (bracket == ')' ? '(' : '[');
            goForward = false;
            break;

          default:
            return -1;
        }

        if (goForward) {

          int lastLine = map.getElementCount();

          // Start just after the found bracket since we're sure
          // we're not in a comment.
          start = caretPosition + 1;
          int numEmbedded = 0;
          boolean haveTokenList = false;

          while (true) {

            doc.getText(start, end - start, charSegment);
            int segOffset = charSegment.offset;

            for (int i = segOffset; i < segOffset + charSegment.count; i++) {

              char ch = charSegment.array[i];

              if (ch == bracket) {
                if (haveTokenList == false) {
                  token = doc.getTokenListForLine(curLine);
                  haveTokenList = true;
                }
                int offset = start + (i - segOffset);
                token = RSyntaxUtilities.getTokenAtOffset(token, offset);
                if (token.type == Token.SEPARATOR) numEmbedded++;
              } else if (ch == bracketMatch) {
                if (haveTokenList == false) {
                  token = doc.getTokenListForLine(curLine);
                  haveTokenList = true;
                }
                int offset = start + (i - segOffset);
                token = RSyntaxUtilities.getTokenAtOffset(token, offset);
                if (token.type == Token.SEPARATOR) {
                  if (numEmbedded == 0) return offset;
                  numEmbedded--;
                }
              }
            } // End of for (int i=segOffset; i<segOffset+charSegment.count; i++).

            // Bail out if we've gone through all lines and
            // haven't found the match.
            if (++curLine == lastLine) return -1;

            // Otherwise, go through the next line.
            haveTokenList = false;
            line = map.getElement(curLine);
            start = line.getStartOffset();
            end = line.getEndOffset();
          } // End of while (true).

        } // End of if (goForward).

        // Otherwise, we're going backward through the file
        // (since we found '}', ')' or ']').
        else { // goForward==false

          // End just before the found bracket since we're sure
          // we're not in a comment.
          end = caretPosition; // - 1;
          int numEmbedded = 0;
          boolean haveTokenList = false;
          Token t2;

          while (true) {

            doc.getText(start, end - start, charSegment);
            int segOffset = charSegment.offset;
            int iStart = segOffset + charSegment.count - 1;

            for (int i = iStart; i >= segOffset; i--) {

              char ch = charSegment.array[i];

              if (ch == bracket) {
                if (haveTokenList == false) {
                  token = doc.getTokenListForLine(curLine);
                  haveTokenList = true;
                }
                int offset = start + (i - segOffset);
                t2 = RSyntaxUtilities.getTokenAtOffset(token, offset);
                if (t2.type == Token.SEPARATOR) numEmbedded++;
              } else if (ch == bracketMatch) {
                if (haveTokenList == false) {
                  token = doc.getTokenListForLine(curLine);
                  haveTokenList = true;
                }
                int offset = start + (i - segOffset);
                t2 = RSyntaxUtilities.getTokenAtOffset(token, offset);
                if (t2.type == Token.SEPARATOR) {
                  if (numEmbedded == 0) return offset;
                  numEmbedded--;
                }
              }
            } // End of for (int i=segOffset; i<segOffset+charSegment.count; i++).

            // Bail out if we've gone through all lines and
            // haven't found the match.
            if (--curLine == -1) return -1;

            // Otherwise, get ready for going through the
            // next line.
            haveTokenList = false;
            line = map.getElement(curLine);
            start = line.getStartOffset();
            end = line.getEndOffset();
          } // End of while (true).
        } // End of else.
      } // End of if (caretPosition>-1).

    } catch (BadLocationException ble) {
      // Shouldn't ever happen.
      ble.printStackTrace();
    }

    // Something went wrong...
    return -1;
  }