📄 sqlsyntaxdocument.java
字号:
private boolean isOpenBrace(char brace) { switch (brace) { case '(': case '[': case '{': return true; } return false; } private boolean isBrace(char charAt) { for (int i = 0; i < Constants.BRACES.length; i++) { if (charAt == Constants.BRACES[i]) { return true; } } return false; } /** temp string buffer for insertion text */ private StringBuffer buffer = new StringBuffer(); /* * Override to apply syntax highlighting after * the document has been updated */ public void insertString(int offset, String text, AttributeSet attrs) throws BadLocationException { //Log.debug("insert"); int length = text.length(); // check overwrite mode if(insertMode == QueryEditorConstants.OVERWRITE_MODE && length == 1 && offset != getLength()) { remove(offset, 1); } if (length == 1) { char firstChar = text.charAt(0); /* check if we convert tabs to spaces */ if ((firstChar == Constants.TAB_CHAR) && tabsToSpaces) { text = QueryEditorSettings.getTabs(); length = text.length(); } /* auto-indent the next line */ else if (firstChar == Constants.NEW_LINE_CHAR) { int index = rootElement.getElementIndex(offset); Element line = rootElement.getElement(index); char SPACE = ' '; buffer.append(text); int start = line.getStartOffset(); int end = line.getEndOffset(); String _text = getText(start, end - start); char[] chars = _text.toCharArray(); for (int i = 0; i < chars.length; i++) { if ((Character.isWhitespace(chars[i])) && (chars[i] != Constants.NEW_LINE_CHAR)) { buffer.append(SPACE); } else { break; } } text = buffer.toString(); length = text.length(); } } resetBracePosition(); /* call super method and default to normal style */ super.insertString(offset, text, styles[WORD]); processChangedLines(offset, length); updateBraces(offset + 1); buffer.setLength(0); } /* NOTE: * method process for text entry into the document: * * 1. replace(...) * 2. insertString(...) * * remove called once only on text/character removal */ /* * Override to apply syntax highlighting after * the document has been updated */ public void remove(int offset, int length) throws BadLocationException { //Log.debug("remove"); resetBracePosition(); int currentLength = getLength(); super.remove(offset, length); processChangedLines(offset, 0); if (offset > 0) { updateBraces(offset); } } /** Mulit-line comment tokens from the last scan */ private List<Token> multiLineComments = new ArrayList<Token>(); private void processChangedLines(int offset, int length) throws BadLocationException { int documentLength = getLength(); if (documentLength == 0) { return; } int tokenStart = -1; int tokenEnd = 0; int endOffset = offset + length; String content = getText(0, documentLength); // scan for multi-line comments List<Token> tokens = new ArrayList<Token>(); while ((tokenStart = content.indexOf(OPEN_COMMENT, tokenEnd)) != -1) { tokenEnd = content.indexOf(CLOSE_COMMENT, tokenStart); if (tokenEnd != -1) { tokenEnd += 2; } tokens.add(new Token(tokenStart, tokenEnd)); if (tokenEnd == -1) { break; } } // scan the lines for highlighting scanLines(offset, length, content, documentLength, tokens); // scan multi comment tokens for apply/reapply boolean applyStyle = true; int tokenCount = tokens.size(); int lastTokenCount = multiLineComments.size(); // check for multi-line comments that do not exist anymore for (int j = 0; j < lastTokenCount; j++) { Token lastToken = multiLineComments.get(j); tokenStart = lastToken.getStartIndex(); tokenEnd = lastToken.getEndIndex(); applyStyle = true; for (int i = 0; i < tokenCount; i++) { Token token = tokens.get(i); if (token.equals(lastToken)) { applyStyle = false; break; } } // reapply the styles to the portion from the last // scan that no longer exists if (applyStyle) { // if end was -1 set to the end of the document if (tokenEnd == -1) { tokenEnd = documentLength - 1; } scanLines(tokenStart, tokenEnd - tokenStart, content, documentLength, tokens); } } // apply multi-line comment style where it did not exist before for (int i = 0; i < tokenCount; i++) { Token token = tokens.get(i); tokenStart = token.getStartIndex(); tokenEnd = token.getEndIndex(); // if we have a dangling open comment // apply to the rest of the document if (token.getEndIndex() == -1) { setCharacterAttributes(tokenStart, content.length() - tokenStart, styles[COMMENT], false); break; } applyStyle = true; // check the last multiline comments for (int j = 0; j < lastTokenCount; j++) { Token lastToken = multiLineComments.get(j); // check if the current token existed in the last scan if (lastToken.equals(token)) { // style not applied if it did applyStyle = false; break; } // where previously there was no close comment tag // reapply to the rest of the text from the current end else if (lastToken.getEndIndex() == -1) { applyStyle = false; // rescan that section that was previously still open scanLines(tokenEnd, documentLength - tokenEnd, content, documentLength, tokens); break; } } // check for the tokens intersecting the current offset // and reapply to cover the comment correctly regardless // of the current state of the apply flag if (token.intersects(offset, endOffset)) { setCharacterAttributes(tokenStart, token.getLength(), styles[COMMENT], false); } else { if (applyStyle) { // if we have a close tag if (tokenEnd > 0) { setCharacterAttributes(tokenStart, token.getLength(), styles[COMMENT], false); } // otherwise set style to the // remainder of the document else { setCharacterAttributes(tokenStart, content.length() - tokenStart, styles[COMMENT], false); } } } } // reassign the multi-line comments list multiLineComments = tokens; } private void scanLines(int offset, int length, String content, int documentLength, List<Token> tokens) { // The lines affected by the latest document update int startLine = rootElement.getElementIndex(offset); int endLine = rootElement.getElementIndex(offset + length); boolean applyStyle = true; int tokenCount = tokens.size(); for (int i = startLine; i <= endLine; i++) { Element element = rootElement.getElement(i); int startOffset = element.getStartOffset(); int endOffset = element.getEndOffset() - 1; if (endOffset < 0) { endOffset = 0; } applyStyle = true; for (int j = 0; j < tokenCount; j++) { Token token = tokens.get(j); if (token.contains(startOffset, endOffset)) { applyStyle = false; break; } } if (applyStyle) { String textSnippet = content.substring(startOffset, endOffset); applySyntaxColours(textSnippet, startOffset, endOffset, documentLength); } } } private void applySyntaxColours(String text, int startOffset, int endOffset, int contentLength) { int lineLength = endOffset - startOffset; if (endOffset >= contentLength) { endOffset = contentLength - 1; } // set the plain style setCharacterAttributes(startOffset, lineLength, styles[WORD], false); for (int i = 0; i < matchers.length; i++) { if (matchers[i] != null) { // check case keywords not initialised applyHighlights(i, text, startOffset, matchers[i].getMatcher(), matchers[i].getStyle(), (i == SINGLE_LINE_COMMENT_MATCH)); } } } private void applyHighlights(int matcherType, String text, int startOffset, Matcher matcher, Style style, boolean replace) { if (matcherType == STRING_MATCH ) { stringTokens.clear(); } int start = 0; int end = 0; int realStart = 0; int realEnd = 0; boolean applyStyle = true; matcher.reset(text); // the string token count for when we are not // processing string tokens int stringTokenCount = stringTokens.size(); int length = text.length(); int matcherStart = 0; while (matcher.find(matcherStart)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -