introduce super class with common methods
diff --git a/plugins/org.eclipse.dltk.python.ui/src/org/eclipse/dltk/python/internal/ui/text/PythonAutoEditStrategy.java b/plugins/org.eclipse.dltk.python.ui/src/org/eclipse/dltk/python/internal/ui/text/PythonAutoEditStrategy.java index 163e552..7b3dbe6 100644 --- a/plugins/org.eclipse.dltk.python.ui/src/org/eclipse/dltk/python/internal/ui/text/PythonAutoEditStrategy.java +++ b/plugins/org.eclipse.dltk.python.ui/src/org/eclipse/dltk/python/internal/ui/text/PythonAutoEditStrategy.java
@@ -13,11 +13,10 @@ import org.eclipse.dltk.core.DLTKCore; import org.eclipse.dltk.python.ui.text.IPythonPartitions; -import org.eclipse.dltk.ui.CodeFormatterConstants; import org.eclipse.dltk.ui.PreferenceConstants; +import org.eclipse.dltk.ui.text.ScriptDefaultIndentLineAutoEditStrategy; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.DocumentCommand; import org.eclipse.jface.text.DocumentRewriteSession; @@ -27,81 +26,53 @@ import org.eclipse.jface.text.TextUtilities; import org.eclipse.jface.text.rules.FastPartitioner; -public class PythonAutoEditStrategy extends DefaultIndentLineAutoEditStrategy { +public class PythonAutoEditStrategy extends + ScriptDefaultIndentLineAutoEditStrategy { IPreferenceStore fStore; String fPartitioning; final int maxCharsAway = 100; - public PythonAutoEditStrategy(IPreferenceStore store, String part) { + super(store); fStore = store; fPartitioning = part; } - + /* * possible prefereces: * - * general indent on/off - * smart tab key behaviour - * autoclose "strings", 'strings' - * autoclose {brackets}, [], () - * smart paste + * general indent on/off smart tab key behaviour autoclose "strings", + * 'strings' autoclose {brackets}, [], () smart paste */ - - private boolean isSmartTab() { + + private boolean isSmartTab() { return fStore.getBoolean(PreferenceConstants.EDITOR_SMART_TAB); } - - private boolean isSmartMode() { + + private boolean isSmartMode() { return fStore.getBoolean(PreferenceConstants.EDITOR_SMART_INDENT); - } - + } + private boolean closeBrackets() { return fStore.getBoolean(PreferenceConstants.EDITOR_CLOSE_BRACKETS); } - + private boolean isSmartPaste() { return fStore.getBoolean(PreferenceConstants.EDITOR_SMART_PASTE); } - - private boolean closeStrings () { + + private boolean closeStrings() { return fStore.getBoolean(PreferenceConstants.EDITOR_CLOSE_STRINGS); } - - private int getIndentSize() { - return fStore.getInt(CodeFormatterConstants.FORMATTER_INDENTATION_SIZE); - } - - private String getTabStyle() { - return fStore.getString(CodeFormatterConstants.FORMATTER_TAB_CHAR); - } - - private String getIndent() { - if (getTabStyle().equals (CodeFormatterConstants.SPACE)) { - int size = getIndentSize(); - String res = ""; - for (int i = 0; i < size; i++) - res += " "; - return res; - } else - return "\t"; - } - - private boolean isLineDelimiter(IDocument document, String text) { - String[] delimiters = document.getLegalLineDelimiters(); - if (delimiters != null) - return TextUtilities.equals(delimiters, text) > -1; - return false; - } /** * Returns the leading whitespaces and tabs. * - * @param document - - * the document being parsed - * @param line - - * the line being searched + * @param document + * - the document being parsed + * @param line + * - the line being searched * @return the leading whitespace * @throws BadLocationException * in case <code>line</code> is invalid in the document @@ -110,38 +81,38 @@ throws BadLocationException { if (line > -1) { int start = document.getLineOffset(line); - int end = start + document.getLineLength(line); //was - 1 + int end = start + document.getLineLength(line); // was - 1 int whiteend = findEndOfWhiteSpace(document, start, end); return document.get(start, whiteend - start); } return ""; //$NON-NLS-1$ } - + /** * Returns the leading whitespaces and tabs. * - * @param line - - * the line being searched + * @param line + * - the line being searched * @return the leading whitespace */ - public String getLineIndent(String line) { + public String getLineIndent(String line) { int end = line.length(); int whiteend = end; int offset = 0; while (offset < end) { - char c= line.charAt(offset); + char c = line.charAt(offset); if (c != ' ' && c != '\t') { - whiteend = offset; + whiteend = offset; break; } offset++; - } + } return line.substring(0, whiteend); } /** - * Find line with number <=line, that is not empty and is - * not a comment line starting with # + * Find line with number <=line, that is not empty and is not a comment line + * starting with # * * @param d * the document to search in @@ -155,7 +126,7 @@ int res = line; while (res > -1) { - String str = getDocumentLine(d, res).trim(); + String str = getDocumentLine(d, res).trim(); if ((!str.startsWith("#")) && str.length() > 0) return res; res--; @@ -166,10 +137,14 @@ /** * Fetched line from document - * @param d the document - * @param line number of req. line + * + * @param d + * the document + * @param line + * number of req. line * @return string with line - * @throws BadLocationException if <b>line</b> is not correct line number + * @throws BadLocationException + * if <b>line</b> is not correct line number */ public String getDocumentLine(IDocument d, int line) throws BadLocationException { @@ -188,16 +163,17 @@ */ private String getRegionType(IDocument d, int offset) throws BadLocationException { - int p = ((offset == d.getLength())?offset - 1:offset); - ITypedRegion region = TextUtilities.getPartition(d, fPartitioning, - p, true); + int p = ((offset == d.getLength()) ? offset - 1 : offset); + ITypedRegion region = TextUtilities.getPartition(d, fPartitioning, p, + true); return region.getType(); } /** - * Searchs an pair from offset, forward of backwards. Can skip - * strings and comments (uses python partitioning). Doesn't goes more - * maxCharsAway chars away from offset. + * Searchs an pair from offset, forward of backwards. Can skip strings and + * comments (uses python partitioning). Doesn't goes more maxCharsAway chars + * away from offset. + * * @param d * @param offset * @param forward @@ -210,23 +186,25 @@ */ private int searchPair(IDocument d, int offset, boolean forward, char opening, char closing, boolean skipCommentLines, - boolean skipStrings) throws BadLocationException { + boolean skipStrings) throws BadLocationException { int deep = 0; int i = offset; if (forward) { while (i < d.getLength()) { - ITypedRegion region = TextUtilities.getPartition(d, fPartitioning, - i, true); - if (region.getType() == IPythonPartitions.PYTHON_COMMENT && skipCommentLines) { + ITypedRegion region = TextUtilities.getPartition(d, + fPartitioning, i, true); + if (region.getType() == IPythonPartitions.PYTHON_COMMENT + && skipCommentLines) { i = region.getOffset() + region.getLength(); continue; } - if (region.getType() == IPythonPartitions.PYTHON_STRING && skipStrings) { + if (region.getType() == IPythonPartitions.PYTHON_STRING + && skipStrings) { i = region.getOffset() + region.getLength(); continue; } char c = d.getChar(i); - if (c == opening) + if (c == opening) deep++; if (c == closing) { if (deep == 0) @@ -239,18 +217,20 @@ } } else { while (i >= 0) { - ITypedRegion region = TextUtilities.getPartition(d, fPartitioning, - i, true); - if (region.getType() == IPythonPartitions.PYTHON_COMMENT && skipCommentLines) { + ITypedRegion region = TextUtilities.getPartition(d, + fPartitioning, i, true); + if (region.getType() == IPythonPartitions.PYTHON_COMMENT + && skipCommentLines) { i = region.getOffset() - 1; continue; } - if (region.getType() == IPythonPartitions.PYTHON_STRING && skipStrings) { + if (region.getType() == IPythonPartitions.PYTHON_STRING + && skipStrings) { i = region.getOffset() - 1; continue; } char c = d.getChar(i); - if (c == closing) + if (c == closing) deep++; if (c == opening) { if (deep == 0) @@ -266,21 +246,25 @@ } /** - * Finds line < <b>line</b>, such the indent of it is less than - * of <b>line</b> - * @param d the document to search in - * @param line appropriate line number + * Finds line < <b>line</b>, such the indent of it is less than of + * <b>line</b> + * + * @param d + * the document to search in + * @param line + * appropriate line number * @return if found, number < <b>line</b>, else <b>line</b> */ - private int findIndentStart (IDocument d, int line) throws BadLocationException { - String curIndent = getLineIndent (d, line); + private int findIndentStart(IDocument d, int line) + throws BadLocationException { + String curIndent = getLineIndent(d, line); int curIndentLength = getPhysicalLength(curIndent); int cur = line - 1; while (cur >= 0) { - String curLine = getDocumentLine(d, cur); - String ind = getLineIndent (d, cur); - if ((!curLine.trim().startsWith("#")) && - getPhysicalLength(ind) < curIndentLength) + String curLine = getDocumentLine(d, cur); + String ind = getLineIndent(d, cur); + if ((!curLine.trim().startsWith("#")) + && getPhysicalLength(ind) < curIndentLength) return cur; cur--; } @@ -288,19 +272,21 @@ } /** - * Calculates real length of string. So any char - * except \t has length 1, \t has length 8. - * @param str string to process + * Calculates real length of string. So any char except \t has length 1, \t + * has length 8. + * + * @param str + * string to process * @return length */ public int getPhysicalLength(String str) { int res = 0; for (int i = 0; i < str.length(); i++) { if (str.charAt(i) == '\t') - res += 8; //in python \t always equals eight spaces! + res += 8; // in python \t always equals eight spaces! else res++; - } + } return res; } @@ -332,7 +318,7 @@ } return b; } - + /** * Installs a partitioner with <code>document</code>. * @@ -341,90 +327,100 @@ */ private static void installStuff(Document document) { String[] types = new String[] { IPythonPartitions.PYTHON_STRING, - IPythonPartitions.PYTHON_COMMENT, IDocument.DEFAULT_CONTENT_TYPE }; + IPythonPartitions.PYTHON_COMMENT, + IDocument.DEFAULT_CONTENT_TYPE }; FastPartitioner partitioner = new FastPartitioner( new PythonPartitionScanner(), types); partitioner.connect(document); document.setDocumentPartitioner(IPythonPartitions.PYTHON_PARTITIONING, partitioner); } - + /** * Removes partitioner with <code>document</code>. - * - * @param document the document + * + * @param document + * the document */ private static void removeStuff(Document document) { - document.setDocumentPartitioner(IPythonPartitions.PYTHON_PARTITIONING, null); + document.setDocumentPartitioner(IPythonPartitions.PYTHON_PARTITIONING, + null); } - - + /** * STRATEGIES */ - + /** * Main indenting algorithm. Needs correct partitioning to work. - * @param d the processed document - * @param line line, indenting of which we wanna know - * @param newLine if <b>line</b> is new line, so we have pressed enter-key, - * and need indentation for new line - * @param offset position, where we have jumped to new line - * @return correct indent for line, or null if we should use "default" indent. - * So calling side should determine, change indent or not, or may be use - * indent of previous line. + * + * @param d + * the processed document + * @param line + * line, indenting of which we wanna know + * @param newLine + * if <b>line</b> is new line, so we have pressed enter-key, and + * need indentation for new line + * @param offset + * position, where we have jumped to new line + * @return correct indent for line, or null if we should use "default" + * indent. So calling side should determine, change indent or not, + * or may be use indent of previous line. * @throws BadLocationException */ - private String calcLineIndent(IDocument d, int line, boolean newLine, int offset) - throws BadLocationException { - + private String calcLineIndent(IDocument d, int line, boolean newLine, + int offset) throws BadLocationException { + boolean isDocumentEnd = (offset == d.getLength()); - - //STRINGS + + // STRINGS if (newLine) { - //if we wrap string - if (getRegionType (d, offset) == IPythonPartitions.PYTHON_STRING) { - int realLine = d.getLineOfOffset (offset); - String curIndent = getLineIndent (d, realLine); - //if we just closed string + // if we wrap string + if (getRegionType(d, offset) == IPythonPartitions.PYTHON_STRING) { + int realLine = d.getLineOfOffset(offset); + String curIndent = getLineIndent(d, realLine); + // if we just closed string if (d.getChar(offset - 1) != '"') { - //if we are fully in string - if (getRegionType (d, d.getLineOffset(realLine)) == IPythonPartitions.PYTHON_STRING) { + // if we are fully in string + if (getRegionType(d, d.getLineOffset(realLine)) == IPythonPartitions.PYTHON_STRING) { return curIndent; } - //if we first time wrap string - return curIndent + getIndent (); + // if we first time wrap string + return curIndent + getIndent(); } } } else { - // don't correct strings - if (getRegionType (d, d.getLineOffset(line)) == IPythonPartitions.PYTHON_STRING) { - return getLineIndent (d, line); //notice, that we don't use null - } + // don't correct strings + if (getRegionType(d, d.getLineOffset(line)) == IPythonPartitions.PYTHON_STRING) { + return getLineIndent(d, line); // notice, that we don't use null + } } - - //LINE JOINING + + // LINE JOINING if (newLine) { int realLine = d.getLineOfOffset(offset); - if (line > 0 ) { + if (line > 0) { String previousLine = ""; if (realLine == line - 1) { int start = d.getLineOffset(realLine); - previousLine = d.get (start, offset - start); + previousLine = d.get(start, offset - start); } else - previousLine = getDocumentLine(d, line - 1); + previousLine = getDocumentLine(d, line - 1); if (previousLine.trim().endsWith("\\")) { String prePreviousLine = getDocumentLine(d, line - 2); if (prePreviousLine.trim().endsWith("\\")) return getLineIndent(d, line - 1); - return getLineIndent(d, line - 1) + getIndent() + getIndent(); + return getLineIndent(d, line - 1) + getIndent() + + getIndent(); } if (line > 1) { String prePreviousLine = getDocumentLine(d, line - 2); if (prePreviousLine.trim().endsWith("\\")) { - //find start + // find start int t = line - 2; - while (t > 0 && getDocumentLine(d, t - 1).trim().endsWith("\\")) { + while (t > 0 + && getDocumentLine(d, t - 1).trim().endsWith( + "\\")) { t--; } return getLineIndent(d, t); @@ -442,26 +438,25 @@ if (line > 1) { String prePreviousLine = getDocumentLine(d, line - 2); if (prePreviousLine.trim().endsWith("\\")) - return getLineIndent(d, line - 1); + return getLineIndent(d, line - 1); } - return getLineIndent(d, line - 1) + getIndent() + getIndent(); + return getLineIndent(d, line - 1) + getIndent() + + getIndent(); } } } - - // Search backwards for the previous non-empty line. int lastNonEmptyLine = getLastNonEmptyLine(d, line - 1); - if (lastNonEmptyLine < 0) { // This is the first non-empty line, use zero indent. return ""; } - - //first check, if we not inside string, if yes, jump to start - ITypedRegion region = TextUtilities.getPartition(d, fPartitioning, d.getLineOffset(lastNonEmptyLine), true); + + // first check, if we not inside string, if yes, jump to start + ITypedRegion region = TextUtilities.getPartition(d, fPartitioning, + d.getLineOffset(lastNonEmptyLine), true); if (region.getType() == IPythonPartitions.PYTHON_STRING) { lastNonEmptyLine = d.getLineOfOffset(region.getOffset()); } @@ -472,47 +467,47 @@ String previousLineIndent = ""; int pairOffset = searchPair(d, d.getLineOffset(lastNonEmptyLine), false, '(', ')', true, true); - + if (pairOffset >= 0) { plnumstart = d.getLineOfOffset(pairOffset); - previousLineIndent = getLineIndent (d, plnumstart); + previousLineIndent = getLineIndent(d, plnumstart); } else { plnumstart = lastNonEmptyLine; - previousLineIndent = getLineIndent (d, lastNonEmptyLine); + previousLineIndent = getLineIndent(d, lastNonEmptyLine); } - + /* * When inside parenthesis: If at the first line below the parenthesis - * add two 'shiftwidth', otherwise same as previous line. - * i = (a - * + b - * + c) - */ + * add two 'shiftwidth', otherwise same as previous line. i = (a + b + + * c) + */ int p = searchPair(d, offset - 1, false, '(', ')', true, true); if (p >= 0) { if (d.getLineOfOffset(p) == lastNonEmptyLine) { - //When the start is inside parenthesis, only indent one 'shiftwidth'. - int pp = searchPair(d, p, - false, '(', ')', true, true); - if (pp >= 0) - return getLineIndent (d, lastNonEmptyLine) + getIndent(); - return getLineIndent (d, lastNonEmptyLine) + getIndent() + getIndent(); + // When the start is inside parenthesis, only indent one + // 'shiftwidth'. + int pp = searchPair(d, p, false, '(', ')', true, true); + if (pp >= 0) + return getLineIndent(d, lastNonEmptyLine) + getIndent(); + return getLineIndent(d, lastNonEmptyLine) + getIndent() + + getIndent(); } if (d.getLineOfOffset(p) == plnumstart) { - return getLineIndent (d, lastNonEmptyLine); + return getLineIndent(d, lastNonEmptyLine); } if (d.getLineOfOffset(p) == line && !newLine) return null; return previousLineIndent; } - - //Get the line and remove a trailing comment. - + + // Get the line and remove a trailing comment. + String pline = ""; - if (lastNonEmptyLine == line - 1 && newLine) { - pline = d.get(d.getLineOffset(line - 1), offset - d.getLineOffset(line - 1)); + if (lastNonEmptyLine == line - 1 && newLine) { + pline = d.get(d.getLineOffset(line - 1), + offset - d.getLineOffset(line - 1)); } else { - pline = getDocumentLine(d, lastNonEmptyLine); + pline = getDocumentLine(d, lastNonEmptyLine); } int plineLen = pline.length(); int i; @@ -520,93 +515,91 @@ if (pline.charAt(i) == '#') { pline = pline.substring(0, i); break; - } + } } - - - String plineTrimmed = pline.trim(); - try {//If the current line begins with a keyword that lines up with "try" - String curLine = ""; - if (lastNonEmptyLine == line - 1 && newLine) { - curLine = d.get(offset, d.getLineLength(line - 1) + d.getLineOffset(line - 1) - offset); + String plineTrimmed = pline.trim(); + + try {// If the current line begins with a keyword that lines up with + // "try" + String curLine = ""; + if (lastNonEmptyLine == line - 1 && newLine) { + curLine = d.get(offset, + d.getLineLength(line - 1) + d.getLineOffset(line - 1) + - offset); } else { curLine = getDocumentLine(d, line).trim(); } - if (curLine.startsWith("except") || - curLine.startsWith("finally")) { + if (curLine.startsWith("except") || curLine.startsWith("finally")) { int lnum = line - 1; - + while (lnum >= 0) { - String temp = getDocumentLine(d, lnum).trim(); - if (temp.startsWith("try") || - temp.startsWith("except")) { - String ind = getLineIndent (d, lnum); + String temp = getDocumentLine(d, lnum).trim(); + if (temp.startsWith("try") || temp.startsWith("except")) { + String ind = getLineIndent(d, lnum); return ind; } lnum--; } - //no mathing "try" -// System.out.println ("No matching 'try'!"); + // no mathing "try" + // System.out.println ("No matching 'try'!"); return null; } - //If the current line begins with a header keyword, dedent - if (curLine.startsWith("elif") || - curLine.startsWith("else")) { + // If the current line begins with a header keyword, dedent + if (curLine.startsWith("elif") || curLine.startsWith("else")) { - //Unless the previous line was a one-liner + // Unless the previous line was a one-liner String temp = getDocumentLine(d, lastNonEmptyLine).trim(); - if (temp.startsWith("for") || - temp.startsWith("if") || - temp.startsWith("try") || - temp.startsWith("while")) { + if (temp.startsWith("for") || temp.startsWith("if") + || temp.startsWith("try") || temp.startsWith("while")) { return previousLineIndent; } - int sline = findIndentStart (d, lastNonEmptyLine); - String reqIndent = getLineIndent (d, sline); + int sline = findIndentStart(d, lastNonEmptyLine); + String reqIndent = getLineIndent(d, sline); return reqIndent; } - - + } catch (BadLocationException e) { - //do nothing, we just don't have current line + // do nothing, we just don't have current line } - -// If the previous line was a stop-execution statement... + + // If the previous line was a stop-execution statement... String regex = "^\\s*(break|continue|raise|pass|return)(\\s+.*$|$)"; - if (Pattern.matches(regex, plineTrimmed)){ - //find indent - int sline = findIndentStart (d, lastNonEmptyLine); - String reqIndent = getLineIndent (d, sline); - if (newLine || isDocumentEnd || (getPhysicalLength(getLineIndent(d, line)) > getPhysicalLength(reqIndent))) { + if (Pattern.matches(regex, plineTrimmed)) { + // find indent + int sline = findIndentStart(d, lastNonEmptyLine); + String reqIndent = getLineIndent(d, sline); + if (newLine + || isDocumentEnd + || (getPhysicalLength(getLineIndent(d, line)) > getPhysicalLength(reqIndent))) { return reqIndent; } - //trust the user + // trust the user return null; - } - - //If the previous line ended with a colon, indent this line + } + + // If the previous line ended with a colon, indent this line if (plineTrimmed.endsWith(":")) return previousLineIndent + getIndent(); - - if (pairOffset >= 0 && newLine) { + + if (pairOffset >= 0 && newLine) { return previousLineIndent; } - - //after-string + + // after-string int prevLine = getLastNonEmptyLine(d, line - 1); if (getRegionType(d, d.getLineOffset(prevLine)) == IPythonPartitions.PYTHON_STRING) return previousLineIndent; - - return null; + + return null; } - /** - * If we have pressed ":" for example, than we need to reindent line. - * This function changes document and sets correct indent for current line. + * If we have pressed ":" for example, than we need to reindent line. This + * function changes document and sets correct indent for current line. + * * @param d * @param c */ @@ -622,13 +615,14 @@ if (getPhysicalLength(curIndent) < getPhysicalLength(newIndent)) return; d.replace(d.getLineOffset(line), curIndent.length(), newIndent); - c.offset += (newIndent.length() - curIndent.length()); - } catch (BadLocationException e) { - } + c.offset += (newIndent.length() - curIndent.length()); + } catch (BadLocationException e) { + } } - + /** * Processes command in work with brackets, strings, etc + * * @param d * @param c */ @@ -644,85 +638,84 @@ return; if ('\'' == c.text.charAt(0) && !closeStrings()) return; - if (!closeBrackets() && - ('[' == c.text.charAt(0) || - '(' == c.text.charAt(0) || - '{' == c.text.charAt(0)) - ) + if (!closeBrackets() + && ('[' == c.text.charAt(0) || '(' == c.text.charAt(0) || '{' == c.text + .charAt(0))) return; try { - - switch (c.text.charAt(0)) { - case '\"': - case '\'': - // if we close existing quote, do nothing - if ('\"' == c.text.charAt(0) && c.offset > 0 - && "\"".equals(d.get(c.offset - 1, 1))) - return; - - if ('\'' == c.text.charAt(0) && c.offset > 0 - && "\'".equals(d.get(c.offset - 1, 1))) - return; - - if (c.offset != d.getLength() && - c.text.charAt(0) == d.get(c.offset, 1).charAt(0)) - c.text = ""; - else { - c.text += c.text; - c.length = 0; - } - - c.shiftsCaret = false; - c.caretOffset = c.offset + 1; - break; - case '(': - case '{': - case '[': -// check partition - if (getRegionType(d, c.offset) != IDocument.DEFAULT_CONTENT_TYPE) - return; - if (c.offset != d.getLength() && - c.text.charAt(0) == d.get(c.offset, 1).charAt(0)) - return; - - try { //in class closing - String regex = "^\\s*class\\s+.*"; - String regex2 = ".*\\(.*\\).*"; - int start = d.getLineOffset(d.getLineOfOffset(c.offset)); - String curLine = d.get(start, c.offset - start); - if (Pattern.matches(regex, curLine) && - !Pattern.matches(regex2, curLine)) { - c.text = "():"; - c.shiftsCaret = false; - c.caretOffset = c.offset + 1; - return; - } - } catch (BadLocationException e) {} - - //add closing peer - c.text = c.text + getBracePair(c.text.charAt(0)); + + switch (c.text.charAt(0)) { + case '\"': + case '\'': + // if we close existing quote, do nothing + if ('\"' == c.text.charAt(0) && c.offset > 0 + && "\"".equals(d.get(c.offset - 1, 1))) + return; + + if ('\'' == c.text.charAt(0) && c.offset > 0 + && "\'".equals(d.get(c.offset - 1, 1))) + return; + + if (c.offset != d.getLength() + && c.text.charAt(0) == d.get(c.offset, 1).charAt(0)) + c.text = ""; + else { + c.text += c.text; c.length = 0; - - c.shiftsCaret = false; - c.caretOffset = c.offset + 1; - break; - case '}': - case ']': - case ')': -// check partition - if (getRegionType(d, c.offset) != IDocument.DEFAULT_CONTENT_TYPE) - return; - if (!closeBrackets()) - return; - // if we already have bracket we should jump over it - if (c.offset != d.getLength() - && c.text.charAt(0) == d.get(c.offset, 1).charAt(0)) { - c.text = ""; + } + + c.shiftsCaret = false; + c.caretOffset = c.offset + 1; + break; + case '(': + case '{': + case '[': + // check partition + if (getRegionType(d, c.offset) != IDocument.DEFAULT_CONTENT_TYPE) + return; + if (c.offset != d.getLength() + && c.text.charAt(0) == d.get(c.offset, 1).charAt(0)) + return; + + try { // in class closing + String regex = "^\\s*class\\s+.*"; + String regex2 = ".*\\(.*\\).*"; + int start = d.getLineOffset(d.getLineOfOffset(c.offset)); + String curLine = d.get(start, c.offset - start); + if (Pattern.matches(regex, curLine) + && !Pattern.matches(regex2, curLine)) { + c.text = "():"; c.shiftsCaret = false; c.caretOffset = c.offset + 1; return; } - break; + } catch (BadLocationException e) { + } + + // add closing peer + c.text = c.text + getBracePair(c.text.charAt(0)); + c.length = 0; + + c.shiftsCaret = false; + c.caretOffset = c.offset + 1; + break; + case '}': + case ']': + case ')': + // check partition + if (getRegionType(d, c.offset) != IDocument.DEFAULT_CONTENT_TYPE) + return; + if (!closeBrackets()) + return; + // if we already have bracket we should jump over it + if (c.offset != d.getLength() + && c.text.charAt(0) == d.get(c.offset, 1).charAt(0)) { + c.text = ""; + c.shiftsCaret = false; + c.caretOffset = c.offset + 1; + return; + } + break; } } catch (BadLocationException e) { e.printStackTrace(); @@ -730,50 +723,53 @@ } /** - * When we have pressed \t, sometimes we wanna not to tabulate, and - * jump to correct line start position. + * When we have pressed \t, sometimes we wanna not to tabulate, and jump to + * correct line start position. + * * @param d * @param c * @return */ private boolean smartIndentJump(IDocument d, DocumentCommand c) { if (c.offset == -1 || d.getLength() == 0) - return false; + return false; try { - //int p = (c.offset == d.getLength() ? c.offset - 1 : c.offset); + // int p = (c.offset == d.getLength() ? c.offset - 1 : c.offset); int line = d.getLineOfOffset(c.offset); int start = d.getLineOffset(line); - // calculate indentation of this line + // calculate indentation of this line String resultIndent = calcLineIndent(d, line, false, start); String currentIndent = getLineIndent(d, line); - if (resultIndent == null) { //we should save indentation + if (resultIndent == null) { // we should save indentation String curLine = getDocumentLine(d, line); - if (curLine.trim().length() > 0) //if indentation is "real", use it + if (curLine.trim().length() > 0) // if indentation is "real", + // use it resultIndent = currentIndent; else { - //get current block level - int pl = getLastNonEmptyLine(d, line - 1); //find last code line + // get current block level + int pl = getLastNonEmptyLine(d, line - 1); // find last code + // line if (pl >= 0) { String plStr = getDocumentLine(d, pl).trim(); - //simple indent-guess strategy + // simple indent-guess strategy String regex = "^\\s*(break|continue|raise|pass|return)(\\s+.*$|$)"; if (plStr.endsWith(":")) - resultIndent = getLineIndent (plStr) + getIndent(); - else if (Pattern.matches(regex, plStr)) { - //find indent - int sline = findIndentStart (d, pl); - resultIndent = getLineIndent (d, sline); + resultIndent = getLineIndent(plStr) + getIndent(); + else if (Pattern.matches(regex, plStr)) { + // find indent + int sline = findIndentStart(d, pl); + resultIndent = getLineIndent(d, sline); } else - resultIndent = getLineIndent (d, pl); - } else - return false; //no indent is applicable, do nothing + resultIndent = getLineIndent(d, pl); + } else + return false; // no indent is applicable, do nothing } } - + if (c.offset >= start + resultIndent.length()) return false; // we already in the place - - if (!currentIndent.startsWith(resultIndent)) { //create indent + + if (!currentIndent.startsWith(resultIndent)) { // create indent c.offset = start; c.length = currentIndent.length(); c.shiftsCaret = false; @@ -792,73 +788,79 @@ } return false; } - + /** - * Reindents c.text when pasting. + * Reindents c.text when pasting. + * * @param d * @param c */ private void smartPaste(IDocument d, DocumentCommand c) { /* - * We are creating temp document, inserting text as is, and - * then sequentially calling calcLineIndent for each new line. + * We are creating temp document, inserting text as is, and then + * sequentially calling calcLineIndent for each new line. */ try { String content = d.get(0, c.offset) + c.text; Document temp = new Document(content); - DocumentRewriteSession session = temp.startRewriteSession(DocumentRewriteSessionType.STRICTLY_SEQUENTIAL); - installStuff (temp); - int offset = c.offset; + DocumentRewriteSession session = temp + .startRewriteSession(DocumentRewriteSessionType.STRICTLY_SEQUENTIAL); + installStuff(temp); + int offset = c.offset; int line = temp.getLineOfOffset(offset); String lastIndent = getLineIndent(temp, line); int firstLineOffset = temp.getLineOffset(line); - String commonIndent = temp.get (firstLineOffset, c.offset - firstLineOffset); - line++; + String commonIndent = temp.get(firstLineOffset, c.offset + - firstLineOffset); + line++; try { while (getDocumentLine(temp, line).trim().length() == 0) line++; offset = temp.getLineOffset(line); } catch (BadLocationException e) { - //ok, we are inserting only one string... + // ok, we are inserting only one string... offset = temp.getLength(); } - while (offset < temp.getLength()) { - //calculate indentation of this line - String resultIndent = calcLineIndent(temp, line, false, temp.getLineOffset(line)); - //change current line offset + while (offset < temp.getLength()) { + // calculate indentation of this line + String resultIndent = calcLineIndent(temp, line, false, + temp.getLineOffset(line)); + // change current line offset String currentIndent = getLineIndent(temp, line); - //String dbg = temp.get (); + // String dbg = temp.get (); if (resultIndent == null) { resultIndent = commonIndent + currentIndent; if (getPhysicalLength(resultIndent) > getPhysicalLength(lastIndent)) resultIndent = lastIndent; } temp.replace(offset, currentIndent.length(), resultIndent); - String currentLine = getDocumentLine(temp, line); - if (currentLine.trim().length() > 0 && (!currentLine.trim().startsWith("#"))) + String currentLine = getDocumentLine(temp, line); + if (currentLine.trim().length() > 0 + && (!currentLine.trim().startsWith("#"))) lastIndent = resultIndent; - - //dbg = temp.get (); - if (temp.getLineOffset(line) + temp.getLineLength(line) == temp.getLength()) + + // dbg = temp.get (); + if (temp.getLineOffset(line) + temp.getLineLength(line) == temp + .getLength()) break; - line++; - offset = temp.getLineOffset(line); + line++; + offset = temp.getLineOffset(line); } temp.stopRewriteSession(session); - removeStuff (temp); - c.text = temp.get (c.offset, temp.getLength() - c.offset); + removeStuff(temp); + c.text = temp.get(c.offset, temp.getLength() - c.offset); } catch (BadLocationException e) { e.printStackTrace(); } - + } - - + /* * (non-Javadoc) * - * @see org.eclipse.jface.text.IAutoEditStrategy#customizeDocumentCommand(org.eclipse.jface.text.IDocument, - * org.eclipse.jface.text.DocumentCommand) + * @see + * org.eclipse.jface.text.IAutoEditStrategy#customizeDocumentCommand(org + * .eclipse.jface.text.IDocument, org.eclipse.jface.text.DocumentCommand) */ public void customizeDocumentCommand(IDocument d, DocumentCommand c) { if (c.doit == false) @@ -869,20 +871,22 @@ return; } try { - String indent = calcLineIndent(d, d.getLineOfOffset(c.offset) + 1, true, c.offset); + String indent = calcLineIndent(d, + d.getLineOfOffset(c.offset) + 1, true, c.offset); if (indent == null) super.customizeDocumentCommand(d, c); else { if (DLTKCore.DEBUG) { System.err.println("Bug:PTN-9"); } -// if (c.offset - 1 >= 0 && -// d.getChar(c.offset - 1) != '"' && -// getRegionType(d, c.offset - 1) == IPythonPartitions.PYTHON_STRING) -// c.text = "\\" + c.text + indent; -// else { - c.text = c.text + indent; -// } + // if (c.offset - 1 >= 0 && + // d.getChar(c.offset - 1) != '"' && + // getRegionType(d, c.offset - 1) == + // IPythonPartitions.PYTHON_STRING) + // c.text = "\\" + c.text + indent; + // else { + c.text = c.text + indent; + // } } } catch (BadLocationException e) { super.customizeDocumentCommand(d, c); @@ -890,7 +894,7 @@ return; } else { if (c.length <= 1 && c.text.length() == 1) { - switch (c.text.charAt(0)) { + switch (c.text.charAt(0)) { case ':': reindent(d, c); break; @@ -906,17 +910,17 @@ break; case '\t': boolean jumped = false; - if (isSmartTab()) { + if (isSmartTab()) { jumped = smartIndentJump(d, c); } if (!jumped) { - c.text = getIndent (); + c.text = getIndent(); } break; } } else if (c.text.length() >= 1 && isSmartPaste()) smartPaste(d, c); // no smart backspace for paste - } + } } }