001: /*
002: * DeepIndentRule.java
003: * :tabSize=8:indentSize=8:noTabs=false:
004: * :folding=explicit:collapseFolds=1:
005: *
006: * Copyright (C) 2006 Matthieu Casanova
007: *
008: * This program is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU General Public License
010: * as published by the Free Software Foundation; either version 2
011: * of the License, or any later version.
012: *
013: * This program is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016: * GNU General Public License for more details.
017: *
018: * You should have received a copy of the GNU General Public License
019: * along with this program; if not, write to the Free Software
020: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
021: */
022:
023: package org.gjt.sp.jedit.indent;
024:
025: import org.gjt.sp.jedit.TextUtilities;
026: import org.gjt.sp.jedit.buffer.JEditBuffer;
027:
028: import java.util.List;
029:
030: /**
031: * Deep indent rule.
032: *
033: * @author Matthieu Casanova
034: * @version $Id: DeepIndentRule.java 9516 2007-05-09 20:25:23Z kpouer $
035: */
036: public class DeepIndentRule implements IndentRule {
037: private final char openChar;
038: private final char closeChar;
039:
040: public DeepIndentRule(char openChar, char closeChar) {
041: this .openChar = openChar;
042: this .closeChar = closeChar;
043: }
044:
045: //{{{ getLastParens() method
046: /**
047: * Return the indexes of the last closing and the last opening parens in a line
048: *
049: * @param s the line text
050: * @param pos the starting pos from the end (or -1 for entire line)
051: *
052: * @return the last pos of the parens in the line
053: */
054: private Parens getLastParens(String s, int pos) {
055: int lastClose;
056: int lastOpen;
057: if (pos == -1) {
058: lastClose = s.lastIndexOf(closeChar);
059: lastOpen = s.lastIndexOf(openChar);
060: } else {
061: lastClose = s.lastIndexOf(closeChar, pos);
062: lastOpen = s.lastIndexOf(openChar, pos);
063: }
064: return new Parens(lastOpen, lastClose);
065: } //}}}
066:
067: //{{{ apply() method
068: public void apply(JEditBuffer buffer, int this LineIndex,
069: int prevLineIndex, int prevPrevLineIndex,
070: List<IndentAction> indentActions) {
071: if (prevLineIndex == -1)
072: return;
073:
074: int lineIndex = prevLineIndex;
075: int oldLineIndex = lineIndex;
076: String lineText = buffer.getLineText(lineIndex);
077: int searchPos = -1;
078: while (true) {
079: if (lineIndex != oldLineIndex) {
080: lineText = buffer.getLineText(lineIndex);
081: oldLineIndex = lineIndex;
082: }
083: Parens parens = getLastParens(lineText, searchPos);
084: if (parens.openOffset > parens.closeOffset) {
085: // recalculate column (when using tabs instead of spaces)
086: int indent = parens.openOffset
087: + TextUtilities.tabsToSpaces(lineText,
088: buffer.getTabSize()).length()
089: - lineText.length();
090: indentActions.add(new IndentAction.AlignParameter(
091: indent, lineText));
092: return;
093: }
094:
095: // No parens on prev line
096: if (parens.openOffset == -1 && parens.closeOffset == -1) {
097: return;
098: }
099: int openParenOffset = TextUtilities.findMatchingBracket(
100: buffer, lineIndex, parens.closeOffset);
101: if (openParenOffset >= 0) {
102: lineIndex = buffer.getLineOfOffset(openParenOffset);
103: searchPos = openParenOffset
104: - buffer.getLineStartOffset(lineIndex) - 1;
105: if (searchPos < 0)
106: break;
107: } else
108: break;
109: }
110: } //}}}
111:
112: //{{{ Parens() class
113: private static class Parens {
114: final int openOffset;
115: final int closeOffset;
116:
117: Parens(int openOffset, int closeOffset) {
118: this .openOffset = openOffset;
119: this .closeOffset = closeOffset;
120: }
121:
122: @Override
123: public String toString() {
124: return "Parens(" + openOffset + ',' + closeOffset + ')';
125: }
126: } //}}}
127: }
|