[Pydev-cvs] org.python.pydev/src_completions/org/python/pydev/editor/codecompletion PyCalltipsCont
Brought to you by:
fabioz
Update of /cvsroot/pydev/org.python.pydev/src_completions/org/python/pydev/editor/codecompletion In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25756/src_completions/org/python/pydev/editor/codecompletion Modified Files: PyCalltipsContextInformation.java AbstractPyCodeCompletion.java PyContextInformationValidator.java Log Message: - Interactive console: backspace will also delete the selected text - Code completion: calltips context info correctly made 'bold' Index: PyCalltipsContextInformation.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src_completions/org/python/pydev/editor/codecompletion/PyCalltipsContextInformation.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** PyCalltipsContextInformation.java 12 Apr 2008 13:04:08 -0000 1.3 --- PyCalltipsContextInformation.java 12 Apr 2008 15:40:09 -0000 1.4 *************** *** 12,47 **** ! /** The name of the context. */ ! private final String fContextDisplayString; ! /** The information to be displayed. */ ! private final String fInformationDisplayString; ! /** The image to be displayed. */ private final Image fImage; ! /** * Creates a new context information without an image. * ! * @param contextDisplayString the string to be used when presenting the context ! * @param informationDisplayString the string to be displayed when presenting the context information */ ! public PyCalltipsContextInformation(String contextDisplayString, String informationDisplayString) { ! this(null, contextDisplayString, informationDisplayString); } /** * Creates a new context information with an image. * * @param image the image to display when presenting the context information ! * @param contextDisplayString the string to be used when presenting the context ! * @param informationDisplayString the string to be displayed when presenting the context information, ! * may not be <code>null</code> */ ! public PyCalltipsContextInformation(Image image, String contextDisplayString, String informationDisplayString) { ! ! Assert.isNotNull(informationDisplayString); fImage= image; ! fContextDisplayString= contextDisplayString; ! fInformationDisplayString= informationDisplayString; } --- 12,60 ---- ! /** ! * The arguments to be displayed. ! */ ! private final String argumentsWithParens; ! ! /** ! * The information to be displayed (calculated when requested) ! */ ! private String argumentsWithoutParens; ! ! /** ! * The image to be displayed. ! */ private final Image fImage; ! ! /** ! * The place where the replacement started. ! */ ! private int fReplacementOffset; ! /** * Creates a new context information without an image. * ! * @param argumentsWithParens the arguments available. ! * @param replacementOffset the offset where the replacement for the arguments started (the place right after the ! * parenthesis start) */ ! public PyCalltipsContextInformation(String arguments, int replacementOffset) { ! this(null, arguments, replacementOffset); } + /** * Creates a new context information with an image. * * @param image the image to display when presenting the context information ! * @param argumentsWithParens the arguments available. ! * @param replacementOffset the offset where the replacement started */ ! public PyCalltipsContextInformation(Image image, String argumentsWithParens, int replacementOffset) { ! Assert.isNotNull(argumentsWithParens); fImage= image; ! this.argumentsWithParens = argumentsWithParens; ! fReplacementOffset = replacementOffset; } *************** *** 50,59 **** */ public boolean equals(Object object) { ! if (object instanceof IContextInformation) { ! IContextInformation contextInformation= (IContextInformation) object; ! boolean equals= fInformationDisplayString.equalsIgnoreCase(contextInformation.getInformationDisplayString()); ! if (fContextDisplayString != null) ! equals= equals && fContextDisplayString.equalsIgnoreCase(contextInformation.getContextDisplayString()); ! return equals; } return false; --- 63,69 ---- */ public boolean equals(Object object) { ! if (object instanceof PyCalltipsContextInformation) { ! PyCalltipsContextInformation contextInformation= (PyCalltipsContextInformation) object; ! return argumentsWithParens.equalsIgnoreCase(contextInformation.argumentsWithParens); } return false; *************** *** 65,70 **** */ public int hashCode() { ! int low= fContextDisplayString != null ? fContextDisplayString.hashCode() : 0; ! return (fInformationDisplayString.hashCode() << 16) | low; } --- 75,79 ---- */ public int hashCode() { ! return argumentsWithParens.hashCode(); } *************** *** 73,77 **** */ public String getInformationDisplayString() { ! return fInformationDisplayString; } --- 82,89 ---- */ public String getInformationDisplayString() { ! if(argumentsWithoutParens == null){ ! argumentsWithoutParens = argumentsWithParens.substring(1, argumentsWithParens.length()-1); //remove the parenthesis ! } ! return argumentsWithoutParens; } *************** *** 87,93 **** */ public String getContextDisplayString() { ! if (fContextDisplayString != null) ! return fContextDisplayString; ! return fInformationDisplayString; } --- 99,108 ---- */ public String getContextDisplayString() { ! return getInformationDisplayString(); ! } ! ! ! public int getReplacementOffset() { ! return this.fReplacementOffset; } Index: PyContextInformationValidator.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src_completions/org/python/pydev/editor/codecompletion/PyContextInformationValidator.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** PyContextInformationValidator.java 13 Jun 2007 01:32:05 -0000 1.2 --- PyContextInformationValidator.java 12 Apr 2008 15:40:09 -0000 1.3 *************** *** 27,217 **** * @author Fabio */ ! public class PyContextInformationValidator implements IContextInformationValidator, IContextInformationPresenter{ public PyCalltipsContextInformation fInformation; ! public int fPosition; public IDocument doc; public int fCurrentParameter; public boolean returnedFalseOnce; ! public PyContextInformationValidator() { ! } ! //--- interface from IContextInformationValidator public void install(IContextInformation info, IDocument doc, int offset) { ! this.returnedFalseOnce = false; this.fInformation = (PyCalltipsContextInformation) info; this.doc = doc; ! ! this.fPosition =offset; ! fCurrentParameter= -1; ! //update the offset to the first parentesis ! while(offset > 0){ ! try { ! char c = doc.getChar(offset); ! if(c == '('){ ! offset++; ! break; ! } ! ! if(c == '\r' || c == '\n'){ ! return; ! } ! } catch (BadLocationException e) { ! //just ignore it -- and go with offset-1, as we did get a char > than the doc len ! } ! offset--; ! } ! if(offset != 0){ ! this.fPosition =offset; ! } } ! public void install(IContextInformation info, ITextViewer viewer, int offset) { install(info, viewer.getDocument(), offset); } - public int getCharCount(IDocument document, final int start, final int end, String increments, String decrements, boolean considerNesting) throws BadLocationException { - - Assert.isTrue((increments.length() != 0 || decrements.length() != 0) && !increments.equals(decrements)); - - final int NONE= 0; - final int BRACKET= 1; - final int BRACE= 2; - final int PAREN= 3; - final int ANGLE= 4; - - int nestingMode= NONE; - int nestingLevel= 0; - - int charCount= 0; - int offset= start; - while (offset < end) { - char curr= document.getChar(offset++); - switch (curr) { - case '#': - if (offset < end) { - // '#' comment: nothing to do anymore on this line - offset= end; - } - break; - case '"': - case '\'': - int eaten = ParsingUtils.eatLiterals(document, new StringBuffer(), offset-1)+1; - if (eaten > offset){ - offset= eaten; - } - break; - case '[': - if (considerNesting) { - if (nestingMode == BRACKET || nestingMode == NONE) { - nestingMode= BRACKET; - nestingLevel++; - } - break; - } - case ']': - if (considerNesting) { - if (nestingMode == BRACKET) - if (--nestingLevel == 0) - nestingMode= NONE; - break; - } - case '(': - if (considerNesting) { - if (nestingMode == ANGLE) { - // generics heuristic failed - nestingMode=PAREN; - nestingLevel= 1; - } - if (nestingMode == PAREN || nestingMode == NONE) { - nestingMode= PAREN; - nestingLevel++; - } - break; - } - case ')': - if (considerNesting) { - if (nestingMode == PAREN) - if (--nestingLevel == 0) - nestingMode= NONE; - break; - } - case '{': - if (considerNesting) { - if (nestingMode == ANGLE) { - // generics heuristic failed - nestingMode=BRACE; - nestingLevel= 1; - } - if (nestingMode == BRACE || nestingMode == NONE) { - nestingMode= BRACE; - nestingLevel++; - } - break; - } - case '}': - if (considerNesting) { - if (nestingMode == BRACE) - if (--nestingLevel == 0) - nestingMode= NONE; - break; - } - - default: - if (nestingLevel != 0) - continue; - - if (increments.indexOf(curr) >= 0) { - ++ charCount; - } - - if (decrements.indexOf(curr) >= 0) { - -- charCount; - } - } - } - - return charCount; - } - - /** * @see IContextInformationValidator#isContextInformationValid(int) */ public boolean isContextInformationValid(int position) { ! //System.out.println("isContextInformationValid:"+position); ! if(doc == null){ ! this.returnedFalseOnce = true; ! return false; ! } try { ! if (position < fPosition){ ! this.returnedFalseOnce = true; return false; } ! IDocument document= doc; ! IRegion line= document.getLineInformationOfOffset(fPosition); ! if (position < line.getOffset() || position >= document.getLength()){ ! this.returnedFalseOnce = true; return false; } ! boolean ret = getCharCount(document, fPosition, position, "(", ")", false) >= 0; //$NON-NLS-1$ //$NON-NLS-2$ ! if(ret == false){ ! returnedFalseOnce = true; } return ret; } catch (BadLocationException x) { ! this.returnedFalseOnce = true; return false; } catch (Exception x) { ! this.returnedFalseOnce = true; ! PydevPlugin.log(x); ! return false; } } --- 27,104 ---- * @author Fabio */ ! public class PyContextInformationValidator implements IContextInformationValidator, IContextInformationPresenter { public PyCalltipsContextInformation fInformation; ! public IDocument doc; + public int fCurrentParameter; + public boolean returnedFalseOnce; ! private int fPosition; ! /** ! * Holds the comma positions for the context information to display ! */ ! int[] commaPositions; ! ! /** ! * IContextInformationValidator ! */ public void install(IContextInformation info, IDocument doc, int offset) { ! System.out.println("Install"); ! this.returnedFalseOnce = false; this.fInformation = (PyCalltipsContextInformation) info; this.doc = doc; ! this.fPosition = fInformation.getReplacementOffset(); ! this.fCurrentParameter = -1; ! this.commaPositions = null; } ! ! /** ! * IContextInformationPresenter ! */ public void install(IContextInformation info, ITextViewer viewer, int offset) { install(info, viewer.getDocument(), offset); } /** * @see IContextInformationValidator#isContextInformationValid(int) */ public boolean isContextInformationValid(int position) { ! System.out.println("isContextInformationValid:" + position); ! if (doc == null) { ! this.returnedFalseOnce = true; ! return false; ! } try { ! if (position < fPosition) { ! this.returnedFalseOnce = true; return false; } ! IDocument document = doc; ! IRegion line = document.getLineInformationOfOffset(fPosition); ! if (position < line.getOffset() || position >= document.getLength()) { ! this.returnedFalseOnce = true; return false; } ! boolean ret = getCurrentParameter(document, fPosition, position, "(", ")", false) >= 0; //$NON-NLS-1$ //$NON-NLS-2$ ! if (ret == false) { ! returnedFalseOnce = true; } return ret; } catch (BadLocationException x) { ! this.returnedFalseOnce = true; return false; } catch (Exception x) { ! this.returnedFalseOnce = true; ! PydevPlugin.log(x); ! return false; } } *************** *** 223,245 **** */ public boolean updatePresentation(int position, TextPresentation presentation) { ! ! int currentParameter= -1; try { ! currentParameter= getCharCount(doc, fPosition, position, ",", "", true); } catch (BadLocationException x) { return false; } if (fCurrentParameter != -1) { ! if (currentParameter == fCurrentParameter) return false; } presentation.clear(); ! fCurrentParameter= currentParameter; ! String s= fInformation.getInformationDisplayString(); ! int[] commas= computeCommaPositions(s); if (commas.length - 2 < fCurrentParameter) { --- 110,134 ---- */ public boolean updatePresentation(int position, TextPresentation presentation) { ! System.out.println("updatePresentation: " + position); ! int currentParameter = -1; try { ! currentParameter = getCurrentParameter(doc, fPosition, position, ",", "", true); } catch (BadLocationException x) { return false; } + System.out.println("updatePresentation: current param: " + currentParameter); if (fCurrentParameter != -1) { ! if (currentParameter == fCurrentParameter) { return false; + } } presentation.clear(); ! fCurrentParameter = currentParameter; ! String s = fInformation.getInformationDisplayString(); ! int[] commas = computeCommaPositions(); if (commas.length - 2 < fCurrentParameter) { *************** *** 247,262 **** return true; } ! ! int start= commas[fCurrentParameter] + 1; ! int end= commas[fCurrentParameter + 1]; ! if (start > 0){ presentation.addStyleRange(new StyleRange(0, start, null, null, SWT.NORMAL)); } ! if (end > start){ presentation.addStyleRange(new StyleRange(start, end - start, null, null, SWT.BOLD)); } ! if (end < s.length()){ presentation.addStyleRange(new StyleRange(end, s.length() - end, null, null, SWT.NORMAL)); } --- 136,151 ---- return true; } ! ! int start = commas[fCurrentParameter] + 1; ! int end = commas[fCurrentParameter + 1]; ! if (start > 0) { presentation.addStyleRange(new StyleRange(0, start, null, null, SWT.NORMAL)); } ! if (end > start) { presentation.addStyleRange(new StyleRange(start, end - start, null, null, SWT.BOLD)); } ! if (end < s.length()) { presentation.addStyleRange(new StyleRange(end, s.length() - end, null, null, SWT.NORMAL)); } *************** *** 264,276 **** return true; } ! ! private int[] computeCommaPositions(String code) { ! final int length= code.length(); ! int pos= 0; ! List<Integer> positions= new ArrayList<Integer>(); ! positions.add(new Integer(-1)); ! while (pos < length && pos != -1) { ! char ch= code.charAt(pos); ! switch (ch) { case ',': positions.add(new Integer(pos)); --- 153,167 ---- return true; } ! ! private int[] computeCommaPositions() { ! if (commaPositions == null) { ! final String code = fInformation.getInformationDisplayString(); ! final int length = code.length(); ! int pos = 0; ! List<Integer> positions = new ArrayList<Integer>(); ! positions.add(new Integer(-1)); ! while (pos < length && pos != -1) { ! char ch = code.charAt(pos); ! switch (ch) { case ',': positions.add(new Integer(pos)); *************** *** 278,294 **** default: break; } ! if (pos != -1) ! pos++; } ! positions.add(new Integer(length)); ! ! int[] fields= new int[positions.size()]; ! for (int i= 0; i < fields.length; i++){ ! fields[i]= ((Integer) positions.get(i)).intValue(); } ! return fields; } } - --- 169,302 ---- default: break; + } + if (pos != -1) + pos++; } ! positions.add(new Integer(length)); ! ! int[] fields = new int[positions.size()]; ! for (int i = 0; i < fields.length; i++) { ! fields[i] = ((Integer) positions.get(i)).intValue(); ! } ! commaPositions = fields; } ! return commaPositions; ! } ! ! /** ! * ! * @param document the document from where the contents should be gotten. ! * @param start ! * @param end ! * @param increments this is the string that when found will increment the current parameter ! * @param decrements this is the string that when found will decrement the current parameter ! * @param considerNesting ! * @return ! * @throws BadLocationException ! */ ! public int getCurrentParameter(IDocument document, final int start, final int end, String increments, ! String decrements, boolean considerNesting) throws BadLocationException { ! ! Assert.isTrue((increments.length() != 0 || decrements.length() != 0) && !increments.equals(decrements)); ! ! final int NONE = 0; ! final int BRACKET = 1; ! final int BRACE = 2; ! final int PAREN = 3; ! final int ANGLE = 4; ! ! int nestingMode = NONE; ! int nestingLevel = 0; ! ! int charCount = 0; ! int offset = start; ! while (offset < end) { ! char curr = document.getChar(offset++); ! switch (curr) { ! case '#': ! if (offset < end) { ! // '#' comment: nothing to do anymore on this line ! offset = end; ! } ! break; ! case '"': ! case '\'': ! int eaten = ParsingUtils.eatLiterals(document, new StringBuffer(), offset - 1) + 1; ! if (eaten > offset) { ! offset = eaten; ! } ! break; ! case '[': ! if (considerNesting) { ! if (nestingMode == BRACKET || nestingMode == NONE) { ! nestingMode = BRACKET; ! nestingLevel++; ! } ! break; ! } ! case ']': ! if (considerNesting) { ! if (nestingMode == BRACKET) ! if (--nestingLevel == 0) ! nestingMode = NONE; ! break; ! } ! case '(': ! if (considerNesting) { ! if (nestingMode == ANGLE) { ! // generics heuristic failed ! nestingMode = PAREN; ! nestingLevel = 1; ! } ! if (nestingMode == PAREN || nestingMode == NONE) { ! nestingMode = PAREN; ! nestingLevel++; ! } ! break; ! } ! case ')': ! if (considerNesting) { ! if (nestingMode == PAREN) ! if (--nestingLevel == 0) ! nestingMode = NONE; ! break; ! } ! case '{': ! if (considerNesting) { ! if (nestingMode == ANGLE) { ! // generics heuristic failed ! nestingMode = BRACE; ! nestingLevel = 1; ! } ! if (nestingMode == BRACE || nestingMode == NONE) { ! nestingMode = BRACE; ! nestingLevel++; ! } ! break; ! } ! case '}': ! if (considerNesting) { ! if (nestingMode == BRACE) ! if (--nestingLevel == 0) ! nestingMode = NONE; ! break; ! } ! ! default: ! if (nestingLevel != 0) ! continue; ! ! if (increments.indexOf(curr) >= 0) { ! ++charCount; ! } ! ! if (decrements.indexOf(curr) >= 0) { ! --charCount; ! } ! } } ! ! return charCount; } } Index: AbstractPyCodeCompletion.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src_completions/org/python/pydev/editor/codecompletion/AbstractPyCodeCompletion.java,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** AbstractPyCodeCompletion.java 12 Apr 2008 13:04:08 -0000 1.8 --- AbstractPyCodeCompletion.java 12 Apr 2008 15:40:09 -0000 1.9 *************** *** 78,83 **** --- 78,86 ---- } + //that's negated so that we can use it as an integer later on (to sum it) + int notInCalltip = 1; int onApplyAction = PyCompletionProposal.ON_APPLY_DEFAULT; if(request.isInCalltip){ + notInCalltip = 0; //when we're in the calltip, we don't have to add a char '(' to the start of the context information. if(request.alreadyHasParams){ onApplyAction = PyCompletionProposal.ON_APPLY_JUST_SHOW_CTX_INFO; *************** *** 87,97 **** } } PyCalltipsContextInformation pyContextInformation = null; if(args.length() > 2){ ! String contextArgs = args.substring(1, args.length()-1); //remove the parentesis ! pyContextInformation = new PyCalltipsContextInformation(contextArgs, contextArgs); } PyCompletionProposal proposal = new PyLinkedModeCompletionProposal(name+args, ! request.documentOffset - request.qlen, request.qlen, l, element, null, pyContextInformation, priority, onApplyAction, args); --- 90,100 ---- } } + int replacementOffset = request.documentOffset - request.qlen; PyCalltipsContextInformation pyContextInformation = null; if(args.length() > 2){ ! pyContextInformation = new PyCalltipsContextInformation(args, replacementOffset+name.length()+notInCalltip); //just after the parenthesis } PyCompletionProposal proposal = new PyLinkedModeCompletionProposal(name+args, ! replacementOffset, request.qlen, l, element, null, pyContextInformation, priority, onApplyAction, args); |