[Pydev-cvs] org.python.pydev/src/org/python/pydev/editor/autoedit PyAutoIndentStrategy.java,1.9,1.10
Brought to you by:
fabioz
From: Fabio Z. <fa...@us...> - 2005-07-20 12:03:02
|
Update of /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/autoedit In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6790/src/org/python/pydev/editor/autoedit Modified Files: PyAutoIndentStrategy.java Log Message: patch http://sourceforge.net/tracker/index.php?func=detail&aid=1241508&group_id=85796&atid=577329 Index: PyAutoIndentStrategy.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/autoedit/PyAutoIndentStrategy.java,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** PyAutoIndentStrategy.java 19 Jul 2005 01:09:05 -0000 1.9 --- PyAutoIndentStrategy.java 20 Jul 2005 12:02:53 -0000 1.10 *************** *** 13,16 **** --- 13,17 ---- import org.eclipse.jface.text.IRegion; import org.python.copiedfromeclipsesrc.PythonPairMatcher; + import org.python.pydev.core.docutils.DocUtils; import org.python.pydev.editor.PyDoubleClickStrategy; import org.python.pydev.editor.actions.PyAction; *************** *** 18,57 **** /** ! * Implements indenting behavior. * ! * Tabs vs. spaces indentation */ public class PyAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy { - /** - * Field representing a semicolon. - */ - public static final char SEMICOLON = ';'; - - /** - * Field representing a colon; - */ - public static final char COLON = ':'; - - /** - * Field representing a comma. - */ - public static final char COMMA = ','; - - /** - * Field representing a space. - */ - public static final char SPACE = ' '; - - /** - * Field representing a beginning parenthesis, i.e., ( - */ - public static final char BEGIN_PARENTHESIS = '('; - - /** - * Field representing an ending parenthesis, i.e., ) - */ - public static final char END_PARENTHESIS = ')'; - private IIndentPrefs prefs; --- 19,31 ---- /** ! * Class which implements the following behaviors: ! * - indenting: after 'class' or 'def' ! * - replacement: when typing colons or parentheses * ! * This class uses the org.python.pydev.core.docutils.DocUtils class extensively ! * for some document-related operations. */ public class PyAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy { private IIndentPrefs prefs; *************** *** 67,77 **** } - public static String createSpaceString(int width) { - StringBuffer b = new StringBuffer(width); - while (width-- > 0) - b.append(SPACE); - return b.toString(); - } - /** * Set indentation automatically after newline. --- 41,44 ---- *************** *** 92,96 **** //we dont want whitespaces ! while (offset > 0 && lastChar == SPACE) { offset--; lastChar = document.getChar(offset - 1); --- 59,63 ---- //we dont want whitespaces ! while (offset > 0 && lastChar == DocUtils.SPACE) { offset--; lastChar = document.getChar(offset - 1); *************** *** 99,108 **** if (offset > 0) { ! if (lastChar == COLON) { String initial = text; text = initial + prefs.getIndentationString(); ! } else if (lastChar == COMMA) { text = indentAfterCommaNewline(document, text, offset); } --- 66,75 ---- if (offset > 0) { ! if (lastChar == DocUtils.COLON) { String initial = text; text = initial + prefs.getIndentationString(); ! } else if (lastChar == DocUtils.COMMA) { text = indentAfterCommaNewline(document, text, offset); } *************** *** 113,205 **** } - /** - * Create the indentation string after comma and a newline. - * - * @param document - * @param text - * @param offset - * @return Indentation String - * @throws BadLocationException - */ - private String indentAfterCommaNewline(IDocument document, String text, int offset) - throws BadLocationException { - int smartIndent = totalIndentAmountAfterCommaNewline(document, offset); - if (smartIndent > 0) { - String initial = text; - - // Discard everything but the newline from initial, since we'll - // build the smart indent from scratch anyway. - int initialLength = initial.length(); - for (int i = 0; i < initialLength; i++) { - char theChar = initial.charAt(i); - // This covers all cases I know of, but if there is any platform - // with weird newline then this would need to be smarter. - if (theChar != '\r' && theChar != '\n') { - if (i > 0) { - initial = initial.substring(0, i); - smartIndent -= --i; - } - break; - } - } - - // Create the actual indentation string - String indentationString = prefs.getIndentationString(); - int indentationSteps = smartIndent / prefs.getTabWidth(); - int spaceSteps = smartIndent % prefs.getTabWidth(); - StringBuffer b = new StringBuffer(smartIndent); - while (indentationSteps-- > 0) - b.append(indentationString); - while (spaceSteps-- >= 0) - b.append(Character.toString(SPACE)); - - return initial + b.toString(); - } - return text; - } - - /** - * Return smart indent amount for new line. This should be done for multiline structures like function parameters, tuples, lists and dictionaries. - * - * Example: - * - * a=foo(1, # - * - * We would return the indentation needed to place the caret at the # position. - * - * @param document The document - * @param offset The document offset of the last character on the previous line - * @return indent, or -1 if smart indent could not be determined (fall back to default) - */ - private int totalIndentAmountAfterCommaNewline(IDocument document, int offset) - throws BadLocationException { - int lineStart = document.getLineInformationOfOffset(offset).getOffset(); - String line = document.get(lineStart, offset - lineStart); - int lineLength = line.length(); - - for (int i = 0; i < lineLength - 1; i++) { - char theChar = line.charAt(i); - - // This covers all cases I know of, but if there is any platform - // with weird newline then this would need to be smarter. - if (theChar == '\r' || theChar == '\n') - break; - - if (theChar == '(' || theChar == '[' || theChar == '{') { - //ok, it's not just returning the line now, we have to check for tabs and make each - //tab count for the tabWidth. - int smartIndent = lineLength - (lineLength - i) + 1; - String string = line.substring(0, smartIndent - 1); - for (int j = 0; j < string.length(); j++) { - char c = string.charAt(j); - if (c == '\t') { - smartIndent += prefs.getTabWidth() - 1; - } - } - return smartIndent; - } - } - return -1; - } /** --- 80,83 ---- *************** *** 214,221 **** try { command.text = autoIndentNewline(document, command.length, command.text, command.offset); - prefs.convertToStd(document, command); ! if (command.text.equals(Character.toString(BEGIN_PARENTHESIS)) && prefs.getAutoParentesis()) { PySelection ps = new PySelection(document, command.offset); String line = ps.getLine(); --- 92,99 ---- try { command.text = autoIndentNewline(document, command.length, command.text, command.offset); prefs.convertToStd(document, command); + ! if (command.text.equals(Character.toString(DocUtils.BEGIN_PARENTHESIS)) && prefs.getAutoParentesis()) { PySelection ps = new PySelection(document, command.offset); String line = ps.getLine(); *************** *** 262,266 **** * another colon */ ! else if (command.text.equals(Character.toString(COLON)) && prefs.getAutoColon()) { performColonReplacement(document, command); } --- 140,144 ---- * another colon */ ! else if (command.text.equals(Character.toString(DocUtils.COLON)) && prefs.getAutoColon()) { performColonReplacement(document, command); } *************** *** 303,336 **** /** ! * Private function to call to perform any replacement of braces. ! * ! * The Eclipse Java editor does this by default, and it is very useful. If ! * you try to insert some kind of pair, be it a parenthesis or bracket in ! * Java, the character will not insert and instead the editor just puts your ! * cursor at the next position. * - * This function performs the equivalent for the Python editor. - * * @param document ! * @param command if the command does not contain a brace, this function does nothing. */ ! private void performPairReplacement(IDocument document, DocumentCommand command) { ! PySelection ps = new PySelection(document, command.offset); ! /* ! * Start matching. ! */ ! /* ! * TODO: Might have to optimize and check for less braces if delay ! * between user's typing characters is too big. ! * ! * You can do this by passing a small array to PythonPairMatcher() ! */ ! PythonPairMatcher matcher = new PythonPairMatcher(PyDoubleClickStrategy.BRACKETS); ! IRegion region = matcher.match(ps.getDoc(), command.offset + 1); ! if (region != null) { ! command.text = ""; ! command.caretOffset = command.offset + 1; } } --- 181,227 ---- /** ! * Create the indentation string after comma and a newline. * * @param document ! * @param text ! * @param offset ! * @return Indentation String ! * @throws BadLocationException */ ! private String indentAfterCommaNewline(IDocument document, String text, int offset) ! throws BadLocationException { ! int smartIndent = totalIndentAmountAfterCommaNewline(document, offset); ! if (smartIndent > 0) { ! String initial = text; ! // Discard everything but the newline from initial, since we'll ! // build the smart indent from scratch anyway. ! int initialLength = initial.length(); ! for (int i = 0; i < initialLength; i++) { ! char theChar = initial.charAt(i); ! // This covers all cases I know of, but if there is any platform ! // with weird newline then this would need to be smarter. ! if (theChar != '\r' && theChar != '\n') { ! if (i > 0) { ! initial = initial.substring(0, i); ! smartIndent -= --i; ! } ! break; ! } ! } ! ! // Create the actual indentation string ! String indentationString = prefs.getIndentationString(); ! int indentationSteps = smartIndent / prefs.getTabWidth(); ! int spaceSteps = smartIndent % prefs.getTabWidth(); ! StringBuffer b = new StringBuffer(smartIndent); ! while (indentationSteps-- > 0) ! b.append(indentationString); ! while (spaceSteps-- >= 0) ! b.append(Character.toString(DocUtils.SPACE)); ! ! return initial + b.toString(); } + return text; } *************** *** 358,363 **** char currentCharacter = document.getChar(absoluteOffset); ! if (currentCharacter == COLON) { ! command.text = ""; command.caretOffset = command.offset + 1; } --- 249,254 ---- char currentCharacter = document.getChar(absoluteOffset); ! if (currentCharacter == DocUtils.COLON) { ! command.text = DocUtils.EMPTY_STRING; command.caretOffset = command.offset + 1; } *************** *** 372,375 **** --- 263,299 ---- /** + * Private function to call to perform any replacement of braces. + * + * The Eclipse Java editor does this by default, and it is very useful. If + * you try to insert some kind of pair, be it a parenthesis or bracket in + * Java, the character will not insert and instead the editor just puts your + * cursor at the next position. + * + * This function performs the equivalent for the Python editor. + * + * @param document + * @param command if the command does not contain a brace, this function does nothing. + */ + private void performPairReplacement(IDocument document, DocumentCommand command) { + PySelection ps = new PySelection(document, command.offset); + + /* + * Start matching. + */ + /* + * TODO: Might have to optimize and check for less braces if delay + * between user's typing characters is too big. + * + * You can do this by passing a smaller array to PythonPairMatcher() + */ + PythonPairMatcher matcher = new PythonPairMatcher(PyDoubleClickStrategy.BRACKETS); + IRegion region = matcher.match(ps.getDoc(), command.offset + 1); + if (region != null) { + command.text = DocUtils.EMPTY_STRING; + command.caretOffset = command.offset + 1; + } + } + + /** * @param ps * @return *************** *** 387,392 **** } ! int i = PyAction.countChars(BEGIN_PARENTHESIS, line); ! int j = PyAction.countChars(END_PARENTHESIS, line); if (j > i) { --- 311,316 ---- } ! int i = PyAction.countChars(DocUtils.BEGIN_PARENTHESIS, line); ! int j = PyAction.countChars(DocUtils.END_PARENTHESIS, line); if (j > i) { *************** *** 397,399 **** --- 321,372 ---- } + /** + * Return smart indent amount for new line. This should be done for + * multiline structures like function parameters, tuples, lists and + * dictionaries. + * + * Example: + * + * a=foo(1, # + * + * We would return the indentation needed to place the caret at the # + * position. + * + * @param document + * The document + * @param offset + * The document offset of the last character on the previous line + * @return indent, or -1 if smart indent could not be determined (fall back + * to default) + */ + private int totalIndentAmountAfterCommaNewline(IDocument document, int offset) + throws BadLocationException { + int lineStart = document.getLineInformationOfOffset(offset).getOffset(); + String line = document.get(lineStart, offset - lineStart); + int lineLength = line.length(); + + for (int i = lineLength - 1; i > 0; i--) { + char theChar = line.charAt(i); + + // This covers all cases I know of, but if there is any platform + // with weird newline then this would need to be smarter. + if (theChar == '\r' || theChar == '\n') + break; + + if (theChar == '(' || theChar == '[' || theChar == '{') { + //ok, it's not just returning the line now, we have to check for tabs and make each + //tab count for the tabWidth. + int smartIndent = lineLength - (lineLength - i) + 1; + String string = line.substring(0, smartIndent - 1); + for (int j = 0; j < string.length(); j++) { + char c = string.charAt(j); + if (c == DocUtils.TAB) { + smartIndent += prefs.getTabWidth() - 1; + } + } + return smartIndent; + } + } + return -1; + } } \ No newline at end of file |