📄 buffer.java
字号:
default: break loop; } } int idealIndent = getIndentForLine(lineIndex); if(idealIndent == -1) return false; if(!canDecreaseIndent && idealIndent <= currentIndent) return false; if(!canIncreaseIndent && idealIndent >= currentIndent) return false; // Do it try { beginCompoundEdit(); int start = getLineStartOffset(lineIndex); remove(start,whitespaceChars); insert(start,MiscUtilities.createWhiteSpace( idealIndent,(getBooleanProperty("noTabs") ? 0 : tabSize))); } finally { endCompoundEdit(); } return true; } //}}} //{{{ indentLines() method /** * Indents all specified lines. * @param start The first line to indent * @param end The last line to indent * @since jEdit 3.1pre3 */ public void indentLines(int start, int end) { try { beginCompoundEdit(); for(int i = start; i <= end; i++) indentLine(i,true,true); } finally { endCompoundEdit(); } } //}}} //{{{ indentLines() method /** * Indents all specified lines. * @param lines The line numbers * @since jEdit 3.2pre1 */ public void indentLines(int[] lines) { try { beginCompoundEdit(); for(int i = 0; i < lines.length; i++) indentLine(lines[i],true,true); } finally { endCompoundEdit(); } } //}}} //{{{ getIndentForLine() method /** * Returns the ideal leading indent for the specified line. * This will apply the various auto-indent rules. * @param lineIndex The line number */ public int getIndentForLine(int lineIndex) { final String EXPLICIT_START = "{{{"; final String EXPLICIT_END = "}}}"; if(lineIndex == 0) return -1; //{{{ Get properties String openBrackets = getStringProperty("indentOpenBrackets"); if(openBrackets == null) openBrackets = ""; String closeBrackets = getStringProperty("indentCloseBrackets"); if(closeBrackets == null) closeBrackets = ""; RE indentNextLineRE; try { indentNextLineRE = getRegexpProperty("indentNextLine", RE.REG_ICASE,RESearchMatcher.RE_SYNTAX_JEDIT); } catch(REException re) { indentNextLineRE = null; Log.log(Log.ERROR,this,"Invalid indentNextLine regexp"); Log.log(Log.ERROR,this,re); } RE indentNextLinesRE; try { indentNextLinesRE = getRegexpProperty("indentNextLines", RE.REG_ICASE,RESearchMatcher.RE_SYNTAX_JEDIT); } catch(REException re) { indentNextLinesRE = null; Log.log(Log.ERROR,this,"Invalid indentNextLines regexp"); Log.log(Log.ERROR,this,re); } boolean doubleBracketIndent = getBooleanProperty("doubleBracketIndent"); boolean lineUpClosingBracket = getBooleanProperty("lineUpClosingBracket"); int tabSize = getTabSize(); int indentSize = getIndentSize(); //}}} //{{{ Get indent attributes of previous line int prevLineIndex = getPriorNonEmptyLine(lineIndex); if(prevLineIndex == -1) return -1; String prevLine = getLineText(prevLineIndex); /* * On the previous line, * if(bob) { --> +1 * if(bob) { } --> 0 * } else if(bob) { --> +1 */ boolean prevLineStart = true; // False after initial indent int indent = 0; // Indent width (tab expanded) int prevLineBrackets = 0; // Additional bracket indent int prevLineCloseBracketIndex = -1; // For finding whether we're in // this kind of construct: // if (cond1) // while (cond2) // if (cond3){ // // } // So we know to indent the next line under the 1st if. for(int i = 0; i < prevLine.length(); i++) { char c = prevLine.charAt(i); switch(c) { case ' ': if(prevLineStart) indent++; break; case '\t': if(prevLineStart) { indent += (tabSize - (indent % tabSize)); } break; default: prevLineStart = false; if(closeBrackets.indexOf(c) != -1) { if(prevLine.regionMatches(false, i,EXPLICIT_END,0,3)) i += 2; else { prevLineBrackets--; if(prevLineBrackets < 0) { if(lineUpClosingBracket) prevLineBrackets = 0; prevLineCloseBracketIndex = i; } } } else if(openBrackets.indexOf(c) != -1) { if(prevLine.regionMatches(false, i,EXPLICIT_START,0,3)) i += 2; else prevLineBrackets++; } break; } } String line = getLineText(lineIndex); //}}} //{{{ Get indent attributes for current line /* * On the current line, * } --> -1 * } else if(bob) { --> -1 * if(bob) { } --> 0 */ int lineBrackets = 0; // Additional bracket indent int closeBracketIndex = -1; // For lining up closing // and opening brackets for(int i = 0; i < line.length(); i++) { char c = line.charAt(i); if(closeBrackets.indexOf(c) != -1) { if(line.regionMatches(false, i,EXPLICIT_END,0,3)) i += 2; else { closeBracketIndex = i; lineBrackets--; } } else if(openBrackets.indexOf(c) != -1) { if(line.regionMatches(false, i,EXPLICIT_START,0,3)) i += 2; else if(lineBrackets >= 0) lineBrackets++; } } //}}} //{{{ Handle brackets if(prevLineBrackets > 0) indent += (indentSize * prevLineBrackets); if(lineUpClosingBracket) { if(lineBrackets < 0) { int offset = TextUtilities.findMatchingBracket( this,lineIndex,closeBracketIndex); if(offset != -1) { String closeLine = getLineText(getLineOfOffset(offset)); indent = MiscUtilities.getLeadingWhiteSpaceWidth( closeLine,tabSize); } else return -1; } } else { if(prevLineBrackets < 0) { int offset = TextUtilities.findMatchingBracket( this,prevLineIndex,prevLineCloseBracketIndex); if(offset != -1) { String closeLine = getLineText(getLineOfOffset(offset)); indent = MiscUtilities.getLeadingWhiteSpaceWidth( closeLine,tabSize); } else return -1; } }//}}} //{{{ Handle regexps if(lineBrackets == 0 || (doubleBracketIndent && lineBrackets > 0)) { // If the previous line matches indentNextLine or indentNextLines, // add a level of indent if(indentNextLinesRE != null && indentNextLinesRE.isMatch(prevLine)) indent += indentSize; else if(indentNextLineRE != null) { if(indentNextLineRE.isMatch(prevLine)) indent += indentSize; // we don't want // if(foo) // { // <--- decreased indent else if(prevLineBrackets == 0) { // While prior lines match indentNextLine, remove a level of indent // this correctly handles constructs like: // if(foo) // if(bar) // if(baz) // <--- put indent here int prevPrevLineIndex; /* if(prevLineCloseBracketIndex != -1) { int offset = TextUtilities.findMatchingBracket( this,prevLineIndex,prevLineCloseBracketIndex); if(offset == -1) return -1; prevPrevLineIndex = getLineOfOffset(offset); } else */ prevPrevLineIndex = getPriorNonEmptyLine(prevLineIndex); while(prevPrevLineIndex != -1) { if(indentNextLineRE.isMatch(getLineText(prevPrevLineIndex))) indent -= indentSize; else break; prevPrevLineIndex = getPriorNonEmptyLine(prevPrevLineIndex); } } } } //}}} return indent; } //}}} //{{{ getVirtualWidth() method /** * Returns the virtual column number (taking tabs into account) of the * specified position. * * @param line The line number * @param column The column number * @since jEdit 4.1pre1 */ public int getVirtualWidth(int line, int column) { try { readLock(); int start = getLineStartOffset(line); getText(start,column,seg); return MiscUtilities.getVirtualWidth(seg,getTabSize()); } finally { readUnlock(); } } //}}} //{{{ getOffsetOfVirtualColumn() method /** * Returns the array offset of a virtual column number (taking tabs * into account) in the segment. * * @param line The line number * @param column The virtual column number * @param totalVirtualWidth If this array is non-null, the total * virtual width will be stored in its first location if this method * returns -1. * * @return -1 if the column is out of bounds * * @since jEdit 4.1pre1 */ public int getOffsetOfVirtualColumn(int line, int column, int[] totalVirtualWidth) { try { readLock(); getLineText(line,seg); return MiscUtilities.getOffsetOfVirtualColumn(seg, getTabSize(),column,totalVirtualWidth); } finally { readUnlock(); } } //}}} //{{{ insertAtColumn() /** * Like the {@link #insert(int,String)} method, but inserts the string at * the specified virtual column. Inserts spaces as appropriate if * the line is shorter than the column. * @param line The line number * @param col The virtual column number * @param str The string */ public void insertAtColumn(int line, int col, String str) { try { writeLock(); int[] total = new int[1]; int offset = getOffsetOfVirtualColumn(line,col,total); if(offset == -1) { offset = getLineEndOffset(line) - 1; str = MiscUtilities.createWhiteSpace(col - total[0],0) + str; } else offset += getLineStartOffset(line); insert(offset,str); } finally { writeUnlock(); } } //}}} //}}} //{{{ Deprecated methods //{{{ putProperty() method /** * @deprecated Call <code>setProperty()</code> instead. */ public void putProperty(Object name, Object value) { // for backwards compatibility if(!(name instanceof String)) return; setProperty((String)name,value); } //}}} //{{{ putBooleanProperty() method /** * @deprecated Call <code>setBooleanProperty()</code> instead */ public void putBooleanProperty(String name, boolean value) { setBooleanProperty(name,value); } //}}} //{{{ markTokens() method /** * @deprecated Use org.gjt.sp.jedit.syntax.DefaultTokenHandler instead */ public static class TokenList extends DefaultTokenHandler { public Token getFirstToken() { return getTokens(); } } /** * @deprecated Use the other form of <code>markTokens()</code> instead */ public TokenList markTokens(int lineIndex) { TokenList list = new TokenList(); markTokens(lineIndex,list); return list; } //}}} //{{{ getRootElements() method /** * @deprecated */ public Element[] getRootElements() { return new Element[] { getDefaultRootElement() }; } //}}} //{{{ getParagraphElement() method /** * @deprecated */ public Element getParagraphElement(int offset) { return new LineElement(this,getLineOfOffset(offset)); } //}}} //{{{ getDefaultRootElement() method /** * @deprecated Use <code>getLineOfOffset()</code>, * <code>getLineStartOffset()</code>, and * <code>getLineEndOffset()</code> instead. */ public Element getDefaultRootElement() { return new RootElement(this); } //}}} //{{{ insertString() method /** * @deprecated Call <code>insert()</code> instead. */ public void insertString(int offset, String str, AttributeSet attr) { insert(offset,str); } //}}} //{{{ getFile() method /** * @deprecated Do not call this method, use {@link #getPath()} * instead. */ public final File getFile() { return file; } //}}} //}}} //{{{ Folding methods //{{{ isFoldStart() method /** * Returns if the specified line begins a fold. * @since jEdit 3.1pre1 */ public boolean isFoldStart(int line) { return (line != getLineCount() - 1 && getFoldLevel(line) < getFoldLevel(line + 1)); } //}}} //{{{ invalidateCachedFoldLevels() method /** * Invalidates all cached fold level information. * @since jEdit 4.1pre11 */ public void invalidateCachedFoldLevels() { offsetMgr.lineInfoChangedFrom(0); for(int i = 0; i < inUseFVMs.length; i++) { if(inUseFVMs[i] != null) inUseFVMs[i]._invalidate(0); } fireFoldLevelChanged(0,getLineCount()); } //}}} //{{{ getFoldLevel() method /** * Returns the fold level of the specified line. * @param line A physical line index * @since jEdit 3.1pre1 */ public int getFoldLevel(int line) { try { writeLock(); if(line < 0 || line >= offsetMgr.getLineCount()) throw new ArrayIndexOutOfBoundsException(line); if(offsetMgr.isFoldLevelValid(line)) { return offsetMgr.getFoldLevel(line); } else { //System.err.println("level invalid: " + line + ":" // + offsetMgr.getFoldLevel(line)); int start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -