示例#1
1
    // TODO: make this a method of SikuliDocument, no need to pass document as argument
    private void changeIndentation(DefaultStyledDocument doc, int linenum, int columns)
        throws BadLocationException {
      PreferencesUser pref = PreferencesUser.getInstance();
      boolean expandTab = pref.getExpandTab();
      int tabWidth = pref.getTabWidth();

      if (linenum < 0) {
        throw new BadLocationException("Negative line", -1);
      }
      Element map = doc.getDefaultRootElement();
      if (linenum >= map.getElementCount()) {
        throw new BadLocationException("No such line", doc.getLength() + 1);
      }
      if (columns == 0) {
        return;
      }

      Element lineElem = map.getElement(linenum);
      int lineStart = lineElem.getStartOffset();
      int lineLength = lineElem.getEndOffset() - lineStart;
      String line = doc.getText(lineStart, lineLength);

      // determine current indentation and number of whitespace characters
      int wsChars;
      int indentation = 0;
      for (wsChars = 0; wsChars < line.length(); wsChars++) {
        char c = line.charAt(wsChars);
        if (c == ' ') {
          indentation++;
        } else if (c == '\t') {
          indentation += tabWidth;
        } else {
          break;
        }
      }

      int newIndentation = indentation + columns;
      if (newIndentation <= 0) {
        doc.remove(lineStart, wsChars);
        return;
      }

      // build whitespace string for new indentation
      StringBuilder newWs = new StringBuilder(newIndentation / tabWidth + tabWidth - 1);
      int ind = 0;
      if (!expandTab) {
        for (; ind + tabWidth <= newIndentation; ind += tabWidth) {
          newWs.append('\t');
        }
      }
      for (; ind < newIndentation; ind++) {
        newWs.append(' ');
      }
      doc.replace(lineStart, wsChars, newWs.toString(), null);
    }
示例#2
0
  /**
   * Highlight lines to start or end delimiter.
   *
   * @param content the content to parse
   * @param line the line number
   * @throws BadLocationException if offsets are wrong
   */
  protected void highlightLinesAfter(String content, int line) throws BadLocationException {
    int offset = m_RootElement.getElement(line).getEndOffset();

    // Start/End delimiter not found, nothing to do

    int startDelimiter = -1;
    int endDelimiter = -1;
    if (getMultiLineComment()) {
      startDelimiter = indexOf(content, getMultiLineCommentStart(), offset);
      endDelimiter = indexOf(content, getMultiLineCommentEnd(), offset);
    }

    if (startDelimiter < 0) startDelimiter = content.length();

    if (endDelimiter < 0) endDelimiter = content.length();

    int delimiter = Math.min(startDelimiter, endDelimiter);

    if (delimiter < offset) return;

    // Start/End delimiter found, reapply highlighting

    int endLine = m_RootElement.getElementIndex(delimiter);

    for (int i = line + 1; i < endLine; i++) {
      Element branch = m_RootElement.getElement(i);
      Element leaf = m_Self.getCharacterElement(branch.getStartOffset());
      AttributeSet as = leaf.getAttributes();

      if (as.isEqual(DEFAULT_COMMENT)) applyHighlighting(content, i);
    }
  }
示例#3
0
  /**
   * Adds the matching block end.
   *
   * @param offset the offset
   * @return the string after adding the matching block end
   * @throws BadLocationException if the offset is invalid
   */
  protected String addMatchingBlockEnd(int offset) throws BadLocationException {
    StringBuffer result;
    StringBuffer whiteSpace = new StringBuffer();
    int line = m_RootElement.getElementIndex(offset);
    int i = m_RootElement.getElement(line).getStartOffset();

    while (true) {
      String temp = m_Self.getText(i, 1);

      if (temp.equals(" ") || temp.equals("\t")) {
        whiteSpace.append(temp);
        i++;
      } else {
        break;
      }
    }

    // assemble string
    result = new StringBuffer();
    result.append(m_BlockStart);
    result.append("\n");
    result.append(whiteSpace.toString());
    if (m_UseBlanks) result.append(m_Indentation);
    else result.append("\t");
    result.append("\n");
    result.append(whiteSpace.toString());
    result.append(m_BlockEnd);

    return result.toString();
  }
示例#4
0
  /**
   * Searches for a quote token.
   *
   * @param content the content to search
   * @param startOffset the start of the search
   * @param endOffset the end of the search
   * @return the new position
   */
  protected int getQuoteToken(String content, int startOffset, int endOffset) {
    String quoteDelimiter = content.substring(startOffset, startOffset + 1);
    String escapeString = escapeQuote(quoteDelimiter);

    int index;
    int endOfQuote = startOffset;

    // skip over the escape quotes in this quote

    index = content.indexOf(escapeString, endOfQuote + 1);

    while ((index > -1) && (index < endOffset)) {
      endOfQuote = index + 1;
      index = content.indexOf(escapeString, endOfQuote);
    }

    // now find the matching delimiter

    index = content.indexOf(quoteDelimiter, endOfQuote + 1);

    if ((index < 0) || (index > endOffset)) endOfQuote = endOffset;
    else endOfQuote = index;

    m_Self.setCharacterAttributes(startOffset, endOfQuote - startOffset + 1, DEFAULT_STRING, false);

    return endOfQuote + 1;
  }
示例#5
0
  /**
   * Override to apply syntax highlighting after the document has been updated.
   *
   * @param offset the offset
   * @param str the string to insert
   * @param a the attribute set, can be null
   * @throws BadLocationException if offset is invalid
   */
  public void insertString(int offset, String str, AttributeSet a) throws BadLocationException {
    if (m_AddMatchingEndBlocks && (m_BlockStart.length() > 0) && str.equals(m_BlockStart))
      str = addMatchingBlockEnd(offset);
    else if (m_UseBlanks && str.equals("\t")) str = m_Indentation;

    super.insertString(offset, str, a);
    processChangedLines(offset, str.length());
  }
示例#6
0
  /**
   * Initializes the document.
   *
   * @param props the properties to obtain the setup from
   */
  public SyntaxDocument(Properties props) {
    m_Self = this;
    m_RootElement = m_Self.getDefaultRootElement();
    m_Keywords = new HashMap<String, MutableAttributeSet>();
    m_FontSize = DEFAULT_FONT_SIZE;
    m_FontName = DEFAULT_FONT_FAMILY;
    putProperty(DefaultEditorKit.EndOfLineStringProperty, "\n");

    setup(props);
  }
 public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
   if ((getLength() + str.length()) <= size) {
     super.insertString(offs, str, a);
   } else {
     System.err.println(
         "Tried to make field "
             + (getLength() + str.length())
             + " characters long when max length is "
             + size);
     Toolkit.getDefaultToolkit().beep();
   }
 }
示例#8
0
  /**
   * Parse the line to determine the appropriate highlighting.
   *
   * @param content the content to parse
   * @param line the line number
   * @throws BadLocationException if offsets are invalid
   */
  protected void applyHighlighting(String content, int line) throws BadLocationException {
    int startOffset = m_RootElement.getElement(line).getStartOffset();
    int endOffset = m_RootElement.getElement(line).getEndOffset() - 1;

    int lineLength = endOffset - startOffset;
    int contentLength = content.length();

    if (endOffset >= contentLength) endOffset = contentLength - 1;

    // check for multi line comments
    // (always set the comment attribute for the entire line)

    if (getMultiLineComment()) {
      if (endingMultiLineComment(content, startOffset, endOffset)
          || isMultiLineComment()
          || startingMultiLineComment(content, startOffset, endOffset)) {
        m_Self.setCharacterAttributes(
            startOffset, endOffset - startOffset + 1, DEFAULT_COMMENT, false);
        return;
      }
    }

    // set normal attributes for the line

    m_Self.setCharacterAttributes(startOffset, lineLength, DEFAULT_NORMAL, true);

    // check for single line comment

    int index = content.indexOf(getSingleLineCommentStart(), startOffset);

    if ((index > -1) && (index < endOffset)) {
      m_Self.setCharacterAttributes(index, endOffset - index + 1, DEFAULT_COMMENT, false);
      endOffset = index - 1;
    }

    // check for tokens

    checkForTokens(content, startOffset, endOffset);
  }
示例#9
0
 public void write(Writer out, Document doc, int pos, int len, Map<String, String> copiedImgs)
     throws IOException, BadLocationException {
   Debug.log(9, "SikuliEditorKit.write %d %d", pos, len);
   DefaultStyledDocument sdoc = (DefaultStyledDocument) doc;
   int i = pos;
   String absPath;
   while (i < pos + len) {
     Element e = sdoc.getCharacterElement(i);
     int start = e.getStartOffset(), end = e.getEndOffset();
     if (e.getName().equals(StyleConstants.ComponentElementName)) {
       // A image argument to be filled
       AttributeSet attr = e.getAttributes();
       Component com = StyleConstants.getComponent(attr);
       out.write(com.toString());
       if (copiedImgs != null
           && (com instanceof EditorPatternButton || com instanceof EditorPatternLabel)) {
         if (com instanceof EditorPatternButton) {
           absPath = ((EditorPatternButton) com).getFilename();
         } else {
           absPath = ((EditorPatternLabel) com).getFile();
         }
         String fname = (new File(absPath)).getName();
         copiedImgs.put(fname, absPath);
         Debug.log(3, "save image for copy&paste: " + fname + " -> " + absPath);
       }
     } else {
       if (start < pos) {
         start = pos;
       }
       if (end > pos + len) {
         end = pos + len;
       }
       out.write(doc.getText(start, end - start));
     }
     i = end;
   }
   out.close();
 }
示例#10
0
  /**
   * Determine how many lines have been changed, then apply highlighting to each line.
   *
   * @param offset the offset of the changed lines
   * @param length the length of the change
   * @throws BadLocationException if offset is invalid
   */
  public void processChangedLines(int offset, int length) throws BadLocationException {
    String content = m_Self.getText(0, m_Self.getLength());

    // The lines affected by the latest document update

    int startLine = m_RootElement.getElementIndex(offset);
    int endLine = m_RootElement.getElementIndex(offset + length);

    // Make sure all comment lines prior to the start line are commented
    // and determine if the start line is still in a multi line comment

    if (getMultiLineComment()) setInsideMultiLineComment(commentLinesBefore(content, startLine));

    // Do the actual highlighting

    for (int i = startLine; i <= endLine; i++) {
      applyHighlighting(content, i);
    }

    // Resolve highlighting to the next end multi line delimiter

    if (isMultiLineComment()) commentLinesAfter(content, endLine);
    else highlightLinesAfter(content, endLine);
  }
示例#11
0
  /**
   * Searches for a keyword token.
   *
   * @param content the content to search in
   * @param startOffset the position to start the search fromm
   * @param endOffset the position to end the search
   * @return the new position
   */
  protected int getOtherToken(String content, int startOffset, int endOffset) {
    int endOfToken = startOffset + 1;

    while (endOfToken <= endOffset) {
      if (isDelimiter(content.substring(endOfToken, endOfToken + 1))) break;
      endOfToken++;
    }

    String token = content.substring(startOffset, endOfToken);

    // see if this token has a highlighting format associated with it
    MutableAttributeSet attr = getKeywordFormatting(token);
    if (attr != null)
      m_Self.setCharacterAttributes(startOffset, endOfToken - startOffset, attr, false);

    return endOfToken + 1;
  }
示例#12
0
  /**
   * Highlight comment lines to matching end delimiter.
   *
   * @param content the content to parse
   * @param line the line number
   */
  protected void commentLinesAfter(String content, int line) {
    int offset = m_RootElement.getElement(line).getEndOffset();

    // End of comment not found, nothing to do

    int endDelimiter = -1;
    if (getMultiLineComment()) endDelimiter = indexOf(content, getMultiLineCommentEnd(), offset);

    if (endDelimiter < 0) return;

    // Matching start/end of comment found, comment the lines

    int startDelimiter = lastIndexOf(content, getMultiLineCommentStart(), endDelimiter);

    if (startDelimiter < 0 || startDelimiter <= offset) {
      m_Self.setCharacterAttributes(offset, endDelimiter - offset + 1, DEFAULT_COMMENT, false);
    }
  }
示例#13
0
  /**
   * Highlight lines when a multi line comment is still 'open' (ie. matching end delimiter has not
   * yet been encountered).
   *
   * @param content the content to check
   * @param line the line number
   * @return true if there are comment lines before
   */
  protected boolean commentLinesBefore(String content, int line) {
    int offset = m_RootElement.getElement(line).getStartOffset();

    // Start of comment not found, nothing to do

    int startDelimiter = -1;
    if (getMultiLineComment())
      startDelimiter = lastIndexOf(content, getMultiLineCommentStart(), offset - 2);

    if (startDelimiter < 0) return false;

    // Matching start/end of comment found, nothing to do

    int endDelimiter = indexOf(content, getMultiLineCommentEnd(), startDelimiter);

    if (endDelimiter < offset & endDelimiter != -1) return false;

    // End of comment not found, highlight the lines

    m_Self.setCharacterAttributes(
        startDelimiter, offset - startDelimiter + 1, DEFAULT_COMMENT, false);
    return true;
  }
示例#14
0
 private void highlightArea(int pos, int len, String col) {
   SimpleAttributeSet attrs = new SimpleAttributeSet();
   StyleConstants.setForeground(attrs, getColour(col));
   document.setCharacterAttributes(pos, len, attrs, true);
 }
示例#15
0
 /**
  * Applies syntax highlighting after the document has been updated.
  *
  * @param offset the offset of the deletion
  * @param length the length of the deletion
  * @throws BadLocationException if offsets are invalid
  */
 public void remove(int offset, int length) throws BadLocationException {
   super.remove(offset, length);
   processChangedLines(offset, 0);
 }