/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.nbstudio.core.mac; import javax.swing.text.BadLocationException; import org.netbeans.editor.BaseDocument; import org.netbeans.editor.Utilities; import org.netbeans.modules.editor.indent.spi.Context; import org.netbeans.modules.editor.indent.spi.ExtraLock; import org.netbeans.modules.editor.indent.spi.IndentTask; /** * * @author daimor */ public class macIndentTask implements IndentTask { private final Context context; private final CodeStyle codeStyle; public macIndentTask(Context context) { this.context = context; this.codeStyle = CodeStyle.getCodeStyle(context.document()); } @Override public void reindent() throws BadLocationException { int caretOffset = context.caretOffset(); int lineOffset = context.lineStartOffset(caretOffset); final BaseDocument doc = (BaseDocument) context.document(); int lastNonWhite = Utilities.getFirstNonWhiteBwd(doc, lineOffset); IndentMode mode = getMode(lineOffset, lastNonWhite, doc); int currentIndent = getCurrentIndent(lastNonWhite, doc); switch (mode) { case NEW_BLOCK: indentNewBlock(lineOffset, currentIndent); break; case SAME_LEVEL: indentSameLevel(lineOffset, currentIndent); break; } } @Override public ExtraLock indentLock() { return null; } private IndentMode getMode(int lineOffset, int lastNonWhite, BaseDocument doc) throws BadLocationException { IndentMode mode = IndentMode.UNKNOWN; if (lastNonWhite >= 0 && lastNonWhite < lineOffset) { String s = doc.getText(lastNonWhite, 1); if (s != null && s.equals("{")) { mode = IndentMode.NEW_BLOCK; } else { mode = IndentMode.SAME_LEVEL; } } return mode; } private int getCurrentIndent(int lastNonWhite, BaseDocument doc) throws BadLocationException { int prevLineStart = Utilities.getRowStart(doc, lastNonWhite); int currentIndent = 0; if (prevLineStart >= 0) { int p = Utilities.getFirstNonWhiteFwd(doc, prevLineStart); if (p >= 0 && p >= prevLineStart && p <= lastNonWhite) { String s = doc.getText(prevLineStart, p - prevLineStart); for (int i = 0; i < s.length(); ++i) { if (s.charAt(i) == '\t') { currentIndent += codeStyle.getTabSize(); } else { currentIndent++; } } } } return currentIndent; } private void indentNewBlock(int lineOffset, int indent) throws BadLocationException { final BaseDocument doc = (BaseDocument) context.document(); int countLCurl = getCurlCount(false, lineOffset, doc); int countRCurl = getCurlCount(true, lineOffset, doc); String s = getIndentString(indent + codeStyle.getIndentSize()); int newCaretPos = lineOffset + s.length(); if (countLCurl == (countRCurl + 1)) { s += "\n"; s += getIndentString(indent); s += "}"; } doc.insertString(lineOffset, s, null); context.setCaretOffset(newCaretPos); } private void indentSameLevel(int lineOffset, int indent) throws BadLocationException { final BaseDocument doc = (BaseDocument) context.document(); String s = getIndentString(indent); int newCaretPos = lineOffset + s.length(); doc.insertString(lineOffset, s, null); context.setCaretOffset(newCaretPos); } private int getCurlCount(boolean forward, int offset, BaseDocument doc) throws BadLocationException { char fwchar, bwchar; int from; int to; int incval; if (forward) { fwchar = '}'; bwchar = '{'; from = offset; to = doc.getLength(); incval = 1; } else { fwchar = '{'; bwchar = '}'; from = offset; to = 0; incval = -1; } int count = 0; char ca[] = new char[1]; int mode = 0; // 1 = ', 2 = " for (int i = from; i != to; i += incval) { doc.getChars(i, ca, 0, 1); char c = ca[0]; if (c == fwchar && mode == 0) { count++; } if (c == bwchar && mode == 0) { count--; } if (c == '"') { if (mode == 0) { mode = 2; } else if (mode == 2) { mode = 0; } } if (c == '\'') { if (mode == 0) { mode = 1; } else if (mode == 1) { mode = 0; } } } return count; } private String getIndentString(int indent) { StringBuilder sb = new StringBuilder(indent + 2); if (codeStyle.getExpandTabToSpaces()) { for (int i = 0; i < indent; ++i) { sb.append(' '); } } else { int tabCount = indent / codeStyle.getTabSize(); int spaceCount = indent % codeStyle.getTabSize(); for (int i = 0; i < tabCount; ++i) { sb.append('\t'); } for (int i = 0; i < spaceCount; ++i) { sb.append(' '); } } return sb.toString(); } private enum IndentMode { UNKNOWN, NEW_BLOCK, SAME_LEVEL }; }