/** * Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved. * Licensed under the terms of the Eclipse Public License (EPL). * Please see the license.txt included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ /* * Created on Feb 11, 2006 */ package org.python.pydev.parser.prettyprinterv2; import java.io.IOException; import org.python.pydev.core.docutils.StringUtils; import org.python.pydev.core.log.Log; import com.aptana.shared_core.string.FastStringBuffer; /** * Helper to write things in the document marking the last thing written, indent, etc. * */ public class WriteStateV2 implements IWriterEraser { private IWriterEraser writer; private IPrettyPrinterPrefs prefs; private FastStringBuffer indentation = new FastStringBuffer(40); private boolean nextMustBeNewLineOrComment = false; private boolean nextMustBeNewLine = true; public final static int INITIAL_STATE = -1; public final static int LAST_STATE_NEW_LINE = 0; public final static int LAST_STATE_INDENT = 1; public final static int LAST_STATE_WRITE = 2; private int lastWrite = 0; int lastState = INITIAL_STATE; public WriteStateV2(IWriterEraser writer, IPrettyPrinterPrefs prefs) { this.writer = writer; this.prefs = prefs; } public String getIndentString() { return indentation.toString(); } public int getIndentLen() { return indentation.length(); } public String getIndentChars(int numberOfChars) { return indentation.toString().substring(indentation.length() - numberOfChars); } public void indent() { indentation.append(prefs.getIndent()); } public void dedent() { int len = indentation.length(); int indentLen = prefs.getIndent().length(); try { indentation.delete(len - indentLen, len); } catch (Exception e) { Log.log(e); } eraseIndent(); } public void eraseIndent() { if (indentation.length() > 0) { writer.erase(prefs.getIndent()); } } //Writing public void writeIndent() throws IOException { lastState = LAST_STATE_INDENT; writer.write(indentation.toString()); lastWrite++; } public void writeNewLine() throws IOException { writeNewLine(true); } public boolean writeNewLine(boolean force) throws IOException { if (force || lastState == LAST_STATE_WRITE) { FastStringBuffer buffer = writer.getBuffer(); if (buffer.endsWith(": ")) { buffer.deleteLast(); } if (lastState == LAST_STATE_NEW_LINE) { this.writeIndent(); } this.nextMustBeNewLineOrComment = false; this.nextMustBeNewLine = false; lastState = LAST_STATE_NEW_LINE; writer.write(prefs.getNewLine()); lastWrite++; return true; } return false; } /** * Writes something, but indents if the last thing written was a new line. */ public void write(String o) throws IOException { if ((nextMustBeNewLineOrComment || nextMustBeNewLine) && this.getBuffer().length() > 0 && lastState != LAST_STATE_NEW_LINE && lastState != LAST_STATE_INDENT) { if (nextMustBeNewLine) { this.writeNewLine(); } else if (nextMustBeNewLineOrComment && !o.trim().startsWith("#")) { this.writeNewLine(); } } nextMustBeNewLineOrComment = false; nextMustBeNewLine = false; if (lastState == LAST_STATE_NEW_LINE) { this.writeIndent(); } FastStringBuffer buf = this.getBuffer(); if (buf.endsWith("\r") || buf.endsWith("\n") || buf.endsWith(" ") || buf.endsWith("\t")) { writeRaw(StringUtils.leftTrim(o)); } else { writeRaw(o); } } /** * Writes something as it comes (independent on the state) */ public void writeRaw(String o) throws IOException { lastState = LAST_STATE_WRITE; writer.write(o); lastWrite++; } public void writeWithoutChangingState(String string) throws IOException { writer.write(string); lastWrite++; } public void writeSpacesBeforeComment() throws IOException { if (lastState == LAST_STATE_WRITE) { if (!this.writer.endsWithSpace()) { writeRaw(prefs.getSpacesBeforeComment()); } } } // Erase public void erase(String o) { writer.erase(o); } // Temp buffer public void pushTempBuffer() { writer.pushTempBuffer(); } public String popTempBuffer() { return writer.popTempBuffer(); } // State public boolean lastIsWrite() { return lastState == LAST_STATE_WRITE; } public boolean lastIsIndent() { return lastState == LAST_STATE_INDENT; } public boolean lastIsNewLine() { return lastState == LAST_STATE_NEW_LINE; } @Override public String toString() { return writer.toString(); } public int getLastWrite() { return lastWrite; } public void requireNextNewLineOrComment() { this.nextMustBeNewLineOrComment = true; } public void requireNextNewLine() { this.nextMustBeNewLine = true; } public boolean endsWithSpace() { return this.writer.endsWithSpace(); } public FastStringBuffer getBuffer() { return writer.getBuffer(); } }