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; }