package com.liferay.ide.velocity.ui.editor.xml; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy; import org.eclipse.jface.text.DocumentCommand; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocumentPartitioner; import org.eclipse.jface.text.ITypedRegion; import org.eclipse.jface.text.source.ISourceViewer; import com.liferay.ide.velocity.editor.EditorsUtil; import com.liferay.ide.velocity.vaulttec.ui.VelocityPlugin; import com.liferay.ide.velocity.vaulttec.ui.editor.VelocityConfiguration; import com.liferay.ide.velocity.vaulttec.ui.model.Directive; /** * DOCUMENT ME! * * @version $Revision: 13 $ * @author <a href="mailto:akmal.sarhan@gmail.com">Akmal Sarhan </a> */ public class VelocityAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy { public static final String NAME = "VelocityAutoIndentStrategy"; public static Set fEMPTY_TAG_SET; static { fEMPTY_TAG_SET = new HashSet(); for (int i = 0; i < IHTMLConstants.EMPTY_TAGS.length; i++) { fEMPTY_TAG_SET.add(IHTMLConstants.EMPTY_TAGS[i]); } } public IEditorConfiguration fConfig; public ISourceViewer fViewer; public int fTabWidth; public String fTab; public boolean isUsingTab; public VelocityAutoIndentStrategy(IEditorConfiguration cf, ISourceViewer viewer) { fConfig = cf; fViewer = viewer; initPreferences(); } /** * DOCUMENT ME! */ public void initPreferences() { fTabWidth = fConfig.getTabWidth(fViewer); fTab = fConfig.getTab(fViewer); isUsingTab = "\t".equals(fTab); } /** * DOCUMENT ME! * * @param document * DOCUMENT ME! * @param cmd * DOCUMENT ME! */ public void customizeDocumentCommand(IDocument document, DocumentCommand cmd) { if ((cmd.length == 0) && (cmd.text != null) && EditorsUtil.isLineDelimiter(document, cmd.text)) { smartIndentAfterNewLine(document, cmd); } else if (">".equals(cmd.text)) { smartIndentOnTagClose(document, cmd); } else if ("\t".equals(cmd.text)) { smartIndentOnTab(document, cmd); } else if ("".equals(cmd.text) && (cmd.length == 1)) { smartIndentOnBackspace(document, cmd); } else if (cmd.text != null) { String re = ""; boolean replace = false; int s = 0; try { s = cmd.text.charAt(0); } catch (Exception e) { return; } if (VelocityPlugin.getDefault().isAutoCompletionEnabled()) { switch (s) { case '\'': case '\"': replace = true; re = cmd.text; break; case '(': replace = true; re = ")"; break; case '[': replace = true; re = "]"; break; case '{': replace = true; re = "}"; break; default: break; } } if (replace) { try { document.replace(cmd.offset, cmd.length, re); } catch (BadLocationException e) { e.printStackTrace(); } } } } public void smartIndentAfterNewLine(IDocument doc, DocumentCommand cmd) { int docLength = doc.getLength(); if ((cmd.offset == -1) || (docLength == 0)) { return; } String f = getVeloIdentifier(doc, cmd.offset - 4, cmd.offset + 1); if ((f != null) && f.equals("#end")) { smartIndentOnVeloTagClose(doc, cmd); return; } try { int p = (cmd.offset != docLength) ? cmd.offset : (cmd.offset - 1); int line = doc.getLineOfOffset(p); int start = doc.getLineOffset(line); int whiteend = findEndOfWhiteSpace(doc, cmd.offset, start + doc.getLineLength(line)); int indent; if (isInsidePreformattedPartitions(p, doc)) { for (; line >= 0; line--) { if (!EditorsUtil.isBlankLine(doc, line)) { break; } } if (line >= 0) { indent = getIndentOfLine(doc, line); } else { indent = 0; } if (whiteend > 0) { cmd.length += (whiteend - cmd.offset); } cmd.text += getIndentString(indent).toString(); return; } if (EditorsUtil.isInsidePartition(p, new String[] {IEditorConfiguration.MULTI_LINE_COMMENT, IEditorConfiguration.COMMENT_PARTITION, IEditorConfiguration.TAG_PARTITION }, doc)) { IDocumentPartitioner partitioner = doc.getDocumentPartitioner(); int matchoffset = partitioner.getPartition(p).getOffset(); indent = getIndentOfLine(doc, doc.getLineOfOffset(matchoffset)); indent = indent(indent, 1); indent = unIndentOnTagEnd(indent, cmd.offset, doc); if (whiteend > 0) { cmd.length += (whiteend - cmd.offset); } cmd.text += getIndentString(indent).toString(); return; } int i = 0; if ((i = isEndTag(cmd.offset, doc)) > 0) { int matchoffset = 0; String _f = getVeloIdentifier(doc, i, i + 5); if ((_f != null) && _f.equalsIgnoreCase("#end")) { matchoffset = findStartVeloBefore(cmd.offset, doc); } else { matchoffset = findMatchingOpenTagBefore(cmd.offset, doc); } if (matchoffset < 0) { return; } indent = getIndentOfLine(doc, doc.getLineOfOffset(matchoffset)); if (whiteend > 0) { cmd.length += (whiteend - cmd.offset); } cmd.text += getIndentString(indent).toString(); return; } line = getNonBlankLineAbove(line + 1, doc); if (line >= 0) { indent = getIndentOfLine(doc, line); } else { indent = 0; } start = doc.getLineOffset(line); int n = getTagCount(doc, start, cmd.offset, true); if (n > 0) { indent = indent(indent, n); } else if (n < 0) { indent = unIndent(indent, -n); } if (whiteend > 0) { cmd.length += (whiteend - cmd.offset); } cmd.text += getIndentString(indent).toString(); } catch (BadLocationException e) { } } public void smartIndentOnTagClose(IDocument doc, DocumentCommand cmd) { if ((cmd.offset == -1) || (doc.getLength() == 0)) { return; } if (isInsidePreformattedPartitions(cmd.offset, doc)) { return; } try { int p = (cmd.offset != doc.getLength()) ? cmd.offset : (cmd.offset - 1); int line = doc.getLineOfOffset(p); int start = doc.getLineOffset(line); int whiteend = findEndOfWhiteSpace(doc, start, cmd.offset); int matchoffset; if (((cmd.offset - 1) == whiteend) && (doc.getChar(cmd.offset - 1) == '/')) { matchoffset = findMatchingOpenTagBefore(whiteend, doc); if ((matchoffset < 0) || (matchoffset == whiteend)) { return; } else { sameIndentAs(matchoffset, line, doc, cmd); return; } } char c; if (((cmd.offset - 2) == whiteend) && (cmd.offset > 1) && ((c = doc.getChar(cmd.offset - 1)) == doc.getChar(cmd.offset - 2)) && (c == '-')) { IDocumentPartitioner partitioner = doc.getDocumentPartitioner(); matchoffset = partitioner.getPartition(p).getOffset(); if ((matchoffset < 0) || (matchoffset == whiteend)) { return; } else { sameIndentAs(matchoffset, line, doc, cmd); return; } } matchoffset = findOpenBracketBefore(cmd.offset, doc); if (matchoffset != whiteend) { return; } if (doc.getChar(matchoffset + 1) == '/') { matchoffset = findMatchingOpenTagBefore(whiteend, doc); if (matchoffset < 0) { return; } else { sameIndentAs(matchoffset, line, doc, cmd); return; } } else { return; } } catch (BadLocationException e) { } } public void smartIndentOnVeloTagClose(IDocument doc, DocumentCommand cmd) { if ((cmd.offset == -1) || (doc.getLength() == 0)) { return; } String f = getVeloIdentifier(doc, cmd.offset - 4, cmd.offset + 1); if ((f == null) || !f.equals("#end")) { return; } if (isInsidePreformattedPartitions(cmd.offset, doc)) { return; } try { int p = (cmd.offset != doc.getLength()) ? cmd.offset : (cmd.offset - 1); int line = doc.getLineOfOffset(p); int start = doc.getLineOffset(line); int whiteend = findEndOfWhiteSpace(doc, start, cmd.offset); int matchoffset; if (((cmd.offset - 1) == whiteend) && (doc.getChar(cmd.offset - 1) == '/')) { matchoffset = findMatchingOpenTagBefore(whiteend, doc); if ((matchoffset < 0) || (matchoffset == whiteend)) { return; } else { sameIndentAs(matchoffset, line, doc, cmd); return; } } char c; if (((cmd.offset - 2) == whiteend) && (cmd.offset > 1) && ((c = doc.getChar(cmd.offset - 1)) == doc.getChar(cmd.offset - 2)) && (c == '-')) { IDocumentPartitioner partitioner = doc.getDocumentPartitioner(); matchoffset = partitioner.getPartition(p).getOffset(); if ((matchoffset < 0) || (matchoffset == whiteend)) { return; } else { sameIndentAs(matchoffset, line, doc, cmd); return; } } matchoffset = findOpenVeloBefore(cmd.offset - 1, doc); if (matchoffset != whiteend) { return; } matchoffset = findStartVeloBefore(whiteend, doc); if (matchoffset < 0) { return; } else { sameIndentAs(matchoffset, line, doc, cmd); int indent = getIndentOfLine(doc, doc.getLineOfOffset(matchoffset)); cmd.text += getIndentString(indent).toString(); return; } } catch (BadLocationException e) { } } /** * @param i * @param doc * @return */ private int findOpenVeloBefore(int end, IDocument document) { try { for (end--; end >= 0; end--) { char c = document.getChar(end); if (c == '#') { return end; } if ((c == '"') || (c == '\'')) { end = getStringStart(document, end, c); } } } catch (BadLocationException badlocationexception) { } return -1; } /** * DOCUMENT ME! * * @param end * DOCUMENT ME! * @param document * DOCUMENT ME! * * @return DOCUMENT ME! */ public static int findStartVeloBefore(int end, IDocument document) { try { int moveNext = 0; for (end--; end >= 0; end--) { char c = document.getChar(end); if (c == '#') { String id = getVeloIdentifier(document, end, end + 9); if ((moveNext == 0) && (id.equalsIgnoreCase("#if") || id.equalsIgnoreCase("#foreach") || id.equalsIgnoreCase("#macro"))) { return end; } else if (id.equalsIgnoreCase("#end")) { ++moveNext; } if ((moveNext > 0) && (id.equalsIgnoreCase("#if") || id.equalsIgnoreCase("#foreach") || id.equalsIgnoreCase("#macro"))) { --moveNext; } } if ((c == '"') || (c == '\'')) { end = getStringStart(document, end, c); } } } catch (BadLocationException badlocationexception) { } return -1; } public void smartIndentOnTab(IDocument doc, DocumentCommand cmd) { int originalCmdOffset = cmd.offset; if ((originalCmdOffset == -1) || (doc.getLength() == 0)) { return; } if (isInsidePreformattedPartitions(originalCmdOffset, doc)) { return; } try { int len = doc.getLength(); int p = (originalCmdOffset != len) ? originalCmdOffset : (originalCmdOffset - 1); int line = doc.getLineOfOffset(p); int start = doc.getLineOffset(line); int whiteend = findEndOfWhiteSpace(doc, start, start + doc.getLineLength(line)); String f = getVeloIdentifier(doc, whiteend, whiteend + 5); if ((f != null) && f.equals("#end")) { smartindentonVeloTab(doc, cmd); return; } if (originalCmdOffset > whiteend) { return; } int indent; int i = 0; if ((i = isEndTag(whiteend, doc)) > 0) { int matchoffset = findMatchingOpenTagBefore(i, doc); if (matchoffset < 0) { return; } indent = getIndentOfLine(doc, doc.getLineOfOffset(matchoffset)); } else { indent = 0; line = getNonBlankLineAbove(line, doc); // here we have to handle comments if (line >= 0) { indent = getIndentOfLine(doc, line); indent = unIndentOnTagEnd(indent, whiteend, doc); int n = getTagCount(doc, doc.getLineOffset(line), start, true); if (n > 0) { indent = indent(indent, n); } else if (n < 0) { indent = unIndent(indent, -n); } } } if (indent == indentWidthOf(doc.get(start, whiteend - start), fTabWidth)) { indent = indent(indent, 1); } cmd.offset = start; cmd.length = whiteend - start; cmd.text = getIndentString(indent).toString(); } catch (BadLocationException e) { } } public void smartIndentOnBackspace(IDocument doc, DocumentCommand cmd) { if (isUsingTab) { return; } if ((cmd.offset == -1) || (doc.getLength() == 0)) { return; } try { int len = doc.getLength(); int p = (cmd.offset != len) ? cmd.offset : (cmd.offset - 1); int line = doc.getLineOfOffset(p); int start = doc.getLineOffset(line); int whiteend = findEndOfWhiteSpace(doc, start, start + doc.getLineLength(line)); if ((cmd.offset + 1) != whiteend) { return; } int indent = indentWidthOf(doc.get(start, whiteend - start), fTabWidth); indent = unIndent(indent, 1); cmd.offset = start; cmd.length = whiteend - start; cmd.text = getIndentString(indent).toString(); } catch (BadLocationException e) { } } public boolean isStartOfLine(int offset, int line, IDocument document) { try { if (document.getLineOfOffset(offset) != line) { return false; } int start = document.getLineOffset(line); return findEndOfWhiteSpace(document, start, offset) == offset; } catch (BadLocationException e) { return false; } } public void sameIndentAs(int matchoffset, int line, IDocument document, DocumentCommand cmd) { try { int indent = getIndentOfLine(document, document.getLineOfOffset(matchoffset)); StringBuffer buf = getIndentString(indent); int start = (line < 0) ? 0 : document.getLineOffset(line); int whiteend = findEndOfWhiteSpace(document, start, cmd.offset); buf.append(document.get(whiteend, cmd.offset - whiteend)); buf.append(cmd.text); cmd.length += (cmd.offset - start); cmd.offset = start; cmd.text = buf.toString(); } catch (BadLocationException e) { } } public int findOpenBracketBefore(int end, IDocument document) { try { for (end--; end >= 0; end--) { char c = document.getChar(end); if (c == '<') { return end; } if ((c == '"') || (c == '\'')) { end = getStringStart(document, end, c); } } } catch (BadLocationException badlocationexception) { } return -1; } public int getNonBlankLineAbove(int line, IDocument doc) { IDocumentPartitioner partitioner = doc.getDocumentPartitioner(); while (--line >= 0) { if (EditorsUtil.isBlankLine(doc, line)) { continue; } try { int start = doc.getLineOffset(line); if (EditorsUtil.isInsidePartition(start, new String[] { IEditorConfiguration.CDATA_PARTITION }, true, doc)) { line = doc.getLineOfOffset(partitioner.getPartition(start).getOffset()); continue; } if (isInsideEscapedPartitions(start, doc)) { line = doc.getLineOfOffset(partitioner.getPartition(start).getOffset()) +1; continue; } } catch (BadLocationException e) { } return line; } return line; } public int getIndentOfLine(IDocument d, int line) throws BadLocationException { if (line >= 0) { int start = d.getLineOffset(line); int end = (start + d.getLineLength(line)) - 1; int whiteend = findEndOfWhiteSpace(d, start, end); return indentWidthOf(d.get(start, whiteend - start), fTabWidth); } else { return 0; } } public StringBuffer getIndentString(int indent) { StringBuffer ret = new StringBuffer(); int n = indent / fTabWidth; for (int i = 0; i < n; i++) { ret.append(fTab); } n = indent - (n * fTabWidth); for (int i = 0; i < n; i++) { ret.append(' '); } return ret; } public int indent(int indent, int n) { return ((indent / fTabWidth) + n) * fTabWidth; } public int unIndent(int indent, int n) { return ((((indent - 1) / fTabWidth) - n) + 1) * fTabWidth; } public int unIndentOnTagEnd(int indent, int offset, IDocument doc) { if (isEndTag(offset, doc) > 0) { return unIndent(indent, 1); } else { return indent; } } public int isEndTag(int offset, IDocument doc) { int len = doc.getLength(); if ((offset + 1) >= len) { return 0; } try { int i = offset; char c = '\0'; try { i = findEndOfWhiteSpace(doc, offset, offset + 20); c = doc.getChar(i); } catch (Exception e) { i = offset; } char cc = doc.getChar(i + 1); char ccc = '\0'; if ((offset + 2) < len) { ccc = doc.getChar(i + 2); } String f = getVeloIdentifier(doc, i, i + 5); if (((c == '<') && (cc == '/')) || ((c == '/') && (cc == '>')) || ((c == '-') && (cc == '-') && (ccc == '>'))) { return i; } else if ((f != null) && f.equalsIgnoreCase("#end")) { return i; } } catch (BadLocationException e) { } return 0; } public int getStringEnd(IDocument d, int pos, int end, char ch) throws BadLocationException { while (pos < end) { char curr = d.getChar(pos); pos++; if (curr == '\\') { pos++; } else if (curr == ch) { return pos; } } return end; } public static int getStringStart(IDocument document, int end, char quote) { try { for (end--; end >= 0; end--) { char c = document.getChar(end); if (c == quote) { if ((end == 0) || (document.getChar(end - 1) != '\\')) { return end; } end--; } } } catch (BadLocationException e) { } return -1; } public boolean isBlankLine(IDocument d, int line) { try { int start = d.getLineOffset(line); int len = d.getLineLength(line); for (int i = 0; i < len; i++) { if (!Character.isWhitespace(d.getChar(start + i))) { return false; } } } catch (BadLocationException badlocationexception) { } return true; } public boolean startsWithDelimiter(IDocument d, int line) { String[] delimiters = d.getLegalLineDelimiters(); try { int start = d.getLineOffset(line); int len = d.getLineLength(line); for (int i = 0; i < delimiters.length; i++) { String delimiter = delimiters[i]; if (len >= delimiter.length()) { boolean found = true; for (int k = 0; k < delimiter.length(); k++) { if (d.getChar(start + k) == delimiter.charAt(k)) { continue; } found = false; break; } if (found) { return true; } } } } catch (BadLocationException badlocationexception) { } return false; } public boolean endsWithDelimiter(IDocument d, String txt) { String[] delimiters = d.getLegalLineDelimiters(); for (int i = 0; i < delimiters.length; i++) { if (txt.endsWith(delimiters[i])) { return true; } } return false; } public boolean isInsideEscapedPartitions(int offset, IDocument doc) { if (EditorsUtil.isInsidePartition(offset, VelocityConfiguration.CDATA_PARTITIONS, true, doc)) { return true; } else { return EditorsUtil.isInsidePartition(offset, VelocityConfiguration.ESCAPED_PARTITIONS, doc); } } public boolean isInsidePreformattedPartitions(int offset, IDocument doc) { if (EditorsUtil.isInsidePartition(offset, VelocityConfiguration.CDATA_PARTITIONS, true, doc)) { return true; } else { return EditorsUtil.isInsidePartition(offset, VelocityConfiguration.PREFORMATTED_PARTITIONS, doc); } } /** * DOCUMENT ME! * * @param end * DOCUMENT ME! * @param doc * DOCUMENT ME! * * @return DOCUMENT ME! */ public static int findMatchingOpenTagBefore(int end, IDocument doc) { int level = 1; String idorg = getIdentifier(doc, end + 2, doc.getLength()); try { char prev = '\0'; for (end--; end >= 0; end--) { if (EditorsUtil.isInsidePartition(end, VelocityConfiguration.CDATA_PARTITIONS, true, doc)) { end = doc.getPartition(end).getOffset() - 1; } else if (EditorsUtil.isInsidePartition(end, VelocityConfiguration.ESCAPED_PARTITIONS, doc)) { end = doc.getPartition(end).getOffset()-1; } char c = doc.getChar(end); if(c=='/' && prev=='>') level++; if (c == '<') { if (prev == '/') { level++; } else if ((prev != '!') && (prev != '?') && (prev != '%') && (prev != '#')) { String id = getIdentifier(doc, end + 1, doc.getLength()); // if (!fEMPTY_TAG_SET.contains(id.toUpperCase()) && !id.equals("")) // { level--; // } if ((level == 0) && idorg.equalsIgnoreCase(id)) // if (level == 0 ) { return end; } } } else if ((c == '"') || (c == '\'')) { end = getStringStart(doc, end, c); } // TODO if(c=='/' && prev=='>') level++; prev = c; } } catch (BadLocationException e) { } return -1; } public int getTagCount(IDocument document, int start, int end, boolean skip) throws BadLocationException { int bracketcount = 0; while (start < end) { if (EditorsUtil.isInsidePartition(start, VelocityConfiguration.ESCAPED_PARTITIONS, true, document)) { ITypedRegion partition = document.getPartition(start); start = partition.getOffset() + partition.getLength(); } char c = document.getChar(start); start++; switch (c) { default: break; // case 35: // '#' // //////// case 35: // '#' { if (start >= end) { break; } char c1 = document.getChar(start); // if ((c1 == '!') || (c1 == '?') || (c1 == '%') || (c1 == // '#')) // { // skip = false; // // break; // } if (c1 != '#') { String id = getIdentifier(document, start, end + 1).toLowerCase(); if (Arrays.asList(Directive.INDENT_DIRECTIVES).contains(id)) { bracketcount++; skip = false; } break; } if (!skip) { bracketcount--; start++; } break; } // /////// case 37: // '%' case 47: // '/' case 63: // '?' { if (start >= end) { break; } char c1 = document.getChar(start); if ((c1 == '>') && !skip) { bracketcount--; start++; } break; } case 60: // '<' { if (start >= end) { break; } char c1 = document.getChar(start); if ((c1 == '!') || (c1 == '?') || (c1 == '%') || (c1 == '#')) { skip = false; break; } if (c1 != '/') { String id = getIdentifier(document, start, end).toUpperCase(); // if (!fEMPTY_TAG_SET.contains(id)) // { bracketcount++; skip = false; // } break; } if (!skip) { bracketcount--; start++; } break; } case 34: // '"' case 39: // '\'' { start = getStringEnd(document, start, end, c); break; } } } return bracketcount; } // public int isEndTag(int offset, IDocument doc) { // return this.isEndTag(offset, doc); // } public static String getVeloIdentifier(IDocument document, int start, int end) { start = skipWhitespace(document, start, end); if (start >= end) { return ""; } StringBuffer ret = new StringBuffer(); try { char c = document.getChar(start++); if (isVeloIdentifierStart(c)) { while (start < end) { ret.append(c); c = document.getChar(start++); if (!isIdentifierChar(c)) { break; } } } } catch (BadLocationException e) { } return ret.toString(); } public static boolean isVeloIdentifierStart(char c) { return c == '#'; } public static String getIdentifier(IDocument document, int start, int end) { start = skipWhitespace(document, start, end); if (start >= end) { return ""; } StringBuffer ret = new StringBuffer(); try { char c = document.getChar(start++); if (isIdentifierStart(c)) { while (start < end) { ret.append(c); c = document.getChar(start++); if (!isIdentifierChar(c)) { break; } } } } catch (BadLocationException e) { } return ret.toString(); } public static int skipWhitespace(IDocument document, int start, int end) { try { for (char c = document.getChar(start); (start < end) && Character.isWhitespace(c); c = document.getChar(++start)) { } } catch (BadLocationException e) { } return start; } public static boolean isIdentifierStart(char c) { return Character.isLetter(c); } public static boolean isIdentifierChar(char c) { return Character.isLetterOrDigit(c) || c == ':' || c == '.' ; } /** * DOCUMENT ME! * * @param doc * DOCUMENT ME! * @param cmd * DOCUMENT ME! */ public void smartindentonVeloTab(IDocument doc, DocumentCommand cmd) { try { int len = doc.getLength(); int p = (cmd.offset != len) ? cmd.offset : (cmd.offset - 1); int line = doc.getLineOfOffset(p); int start = doc.getLineOffset(line); int whiteend = findEndOfWhiteSpace(doc, start, start + doc.getLineLength(line)); int indent; if ((isEndTag(whiteend, doc)) > 0) { int matchoffset = findStartVeloBefore(start, doc); if (matchoffset < 0) { return; } indent = getIndentOfLine(doc, doc.getLineOfOffset(matchoffset)); } else { indent = 0; line = getNonBlankLineAbove(line, doc); if (line >= 0) { indent = getIndentOfLine(doc, line); indent = unIndentOnTagEnd(indent, whiteend, doc); int n = getTagCount(doc, doc.getLineOffset(line), start, true); if (n > 0) { indent = indent(indent, n); } else if (n < 0) { indent = unIndent(indent, -n); } } } if (indent == indentWidthOf(doc.get(start, whiteend - start), fTabWidth)) { indent = indent(indent, 1); } cmd.offset = start; cmd.length = whiteend - start; cmd.text = getIndentString(indent).toString(); } catch (BadLocationException e) { } } /** * DOCUMENT ME! * * @param str * DOCUMENT ME! * @param tabwidth * DOCUMENT ME! * * @return DOCUMENT ME! */ public static int indentWidthOf(String str, int tabwidth) { return indentWidthOf(str, 0, tabwidth); } /** * DOCUMENT ME! * * @param str * DOCUMENT ME! * @param start * DOCUMENT ME! * @param tabwidth * DOCUMENT ME! * * @return DOCUMENT ME! */ public static int indentWidthOf(String str, int start, int tabwidth) { int ret = 0; for (int len = str.length(); start < len; start++) { char c = str.charAt(start); if (c == '\t') { ret = ((ret / tabwidth) + 1) * tabwidth; continue; } if ((c == ' ') || (c == '\240')) { ret++; continue; } if ((c != '\n') && (c != '\r')) { break; } ret = 0; } return ret; } }