public void removeTrailingWhitespace() { int end = textArea.getDocument().getLength(); // remove trailing empty lines int realEnd = end; if (eolAt(end - 1)) { while (eolAt(end - 2) || getText(end - 2, end - 1).equals("\r")) end--; if (end < realEnd) textArea.replaceRange("", end - 1, realEnd - 1); } // remove trailing white space from each line for (int i = textArea.getLineCount() - 1; i >= 0; i--) try { int start = textArea.getLineStartOffset(i); if (eolAt(end - 1)) end--; if (start == end) continue; String line = getText(start, end); realEnd = end; while (start < end && Character.isWhitespace(line.charAt(end - start - 1))) end--; if (end < realEnd) textArea.replaceRange("", end, realEnd); end = start; } catch (BadLocationException e) { /* cannot happen */ } }
/** * Overridden to show the content of a collapsed fold on mouse-overs. * * @param e The mouse location. */ public String getToolTipText(MouseEvent e) { String text = null; RSyntaxTextArea rsta = (RSyntaxTextArea) textArea; if (rsta.isCodeFoldingEnabled()) { FoldManager fm = rsta.getFoldManager(); int pos = rsta.viewToModel(new Point(0, e.getY())); if (pos >= 0) { // Not -1 int line = 0; try { line = rsta.getLineOfOffset(pos); } catch (BadLocationException ble) { ble.printStackTrace(); // Never happens return null; } Fold fold = fm.getFoldForLine(line); if (fold != null && fold.isCollapsed()) { int endLine = fold.getEndLine(); if (fold.getLineCount() > 25) { // Not too big endLine = fold.getStartLine() + 25; } StringBuffer sb = new StringBuffer("<html><nobr>"); while (line <= endLine && line < rsta.getLineCount()) { // Sanity Token t = rsta.getTokenListForLine(line); while (t != null && t.isPaintable()) { t.appendHTMLRepresentation(sb, rsta, true, true); t = t.getNextToken(); } sb.append("<br>"); line++; } text = sb.toString(); } } } return text; }
/** {@inheritDoc} */ @Override public List<Fold> getFolds(RSyntaxTextArea textArea) { List<Fold> folds = new ArrayList<Fold>(); Fold currentFold = null; int lineCount = textArea.getLineCount(); boolean inMLC = false; int mlcStart = 0; int importStartLine = -1; int lastSeenImportLine = -1; int importGroupStartOffs = -1; int importGroupEndOffs = -1; int lastRightCurlyLine = -1; Fold prevFold = null; try { for (int line = 0; line < lineCount; line++) { Token t = textArea.getTokenListForLine(line); while (t != null && t.isPaintable()) { if (getFoldableMultiLineComments() && t.isComment()) { // Java-specific stuff if (java) { if (importStartLine > -1) { if (lastSeenImportLine > importStartLine) { Fold fold = null; // Any imports found *should* be a top-level fold, // but we're extra lenient here and allow groups // of them anywhere to keep our parser better-behaved // if they have random "imports" throughout code. if (currentFold == null) { fold = new Fold(FoldType.IMPORTS, textArea, importGroupStartOffs); folds.add(fold); } else { fold = currentFold.createChild(FoldType.IMPORTS, importGroupStartOffs); } fold.setEndOffset(importGroupEndOffs); } importStartLine = lastSeenImportLine = importGroupStartOffs = importGroupEndOffs = -1; } } if (inMLC) { // If we found the end of an MLC that started // on a previous line... if (t.endsWith(C_MLC_END)) { int mlcEnd = t.getEndOffset() - 1; if (currentFold == null) { currentFold = new Fold(FoldType.COMMENT, textArea, mlcStart); currentFold.setEndOffset(mlcEnd); folds.add(currentFold); currentFold = null; } else { currentFold = currentFold.createChild(FoldType.COMMENT, mlcStart); currentFold.setEndOffset(mlcEnd); currentFold = currentFold.getParent(); } // System.out.println("Ending MLC at: " + mlcEnd + ", parent==" + currentFold); inMLC = false; mlcStart = 0; } // Otherwise, this MLC is continuing on to yet // another line. } else { // If we're an MLC that ends on a later line... if (t.getType() != Token.COMMENT_EOL && !t.endsWith(C_MLC_END)) { // System.out.println("Starting MLC at: " + t.offset); inMLC = true; mlcStart = t.getOffset(); } } } else if (isLeftCurly(t)) { // Java-specific stuff if (java) { if (importStartLine > -1) { if (lastSeenImportLine > importStartLine) { Fold fold = null; // Any imports found *should* be a top-level fold, // but we're extra lenient here and allow groups // of them anywhere to keep our parser better-behaved // if they have random "imports" throughout code. if (currentFold == null) { fold = new Fold(FoldType.IMPORTS, textArea, importGroupStartOffs); folds.add(fold); } else { fold = currentFold.createChild(FoldType.IMPORTS, importGroupStartOffs); } fold.setEndOffset(importGroupEndOffs); } importStartLine = lastSeenImportLine = importGroupStartOffs = importGroupEndOffs = -1; } } // If a new fold block starts on the same line as the // previous one ends, we treat it as one big block // (e.g. K&R-style "} else {") if (prevFold != null && line == lastRightCurlyLine) { currentFold = prevFold; // Keep currentFold.endOffset where it was, so that // unclosed folds at end of the file work as well // as possible prevFold = null; lastRightCurlyLine = -1; } else if (currentFold == null) { // A top-level fold currentFold = new Fold(FoldType.CODE, textArea, t.getOffset()); folds.add(currentFold); } else { // A nested fold currentFold = currentFold.createChild(FoldType.CODE, t.getOffset()); } } else if (isRightCurly(t)) { if (currentFold != null) { currentFold.setEndOffset(t.getOffset()); Fold parentFold = currentFold.getParent(); // System.out.println("... Adding regular fold at " + t.offset + ", parent==" + // parentFold); // Don't add fold markers for single-line blocks if (currentFold.isOnSingleLine()) { if (!currentFold.removeFromParent()) { folds.remove(folds.size() - 1); } } else { // Remember the end of the last completed fold, // in case it needs to get merged with the next // one (e.g. K&R "} else {" style) lastRightCurlyLine = line; prevFold = currentFold; } currentFold = parentFold; } } // Java-specific folding rules else if (java) { if (t.is(Token.RESERVED_WORD, KEYWORD_IMPORT)) { if (importStartLine == -1) { importStartLine = line; importGroupStartOffs = t.getOffset(); importGroupEndOffs = t.getOffset(); } lastSeenImportLine = line; } else if (importStartLine > -1 && t.isIdentifier() && // SEPARATOR && t.isSingleChar(';')) { importGroupEndOffs = t.getOffset(); } } t = t.getNextToken(); } } } catch (BadLocationException ble) { // Should never happen ble.printStackTrace(); } return folds; }