⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pyautoindentstrategy.java

📁 Python Development Environment (Python IDE plugin for Eclipse). Features editor, code completion, re
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
                    String ifIndent = PySelection.getIndentationFromLine(previousIfLine);
                    String lineIndent = PySelection.getIndentationFromLine(lineContents);
                    
                    String indent = prefs.getIndentationString();
                    if(lineIndent.length() == ifIndent.length()+indent.length()){
                        Tuple<String,Integer> dedented = removeFirstIndent(lineContents);
                        ps.replaceLineContentsToSelection(dedented.o1);
                        command.offset = command.offset - dedented.o2;
                        return dedented;
                    }
                }
            }        
        }
        return null;
    }
    
    public Tuple<String, Integer> autoDedentAfterColon(IDocument document, DocumentCommand command) throws BadLocationException {
        Tuple<String, Integer> ret = null;
        if((ret = autoDedentAfterColon(document, command, "else", PySelection.TOKENS_BEFORE_ELSE)) != null){
            return ret;
        }
        if((ret = autoDedentAfterColon(document, command, "except", PySelection.TOKENS_BEFORE_EXCEPT)) != null){
            return ret;
        }
        if((ret = autoDedentAfterColon(document, command, "finally", PySelection.TOKENS_BEFORE_FINALLY)) != null){
            return ret;
        }
        return null;
    }

    /**
     * This function makes the else auto-dedent (if available)
     * @return the new indent and the number of chars it has been dedented (so, that has to be considered as a shift to the left
     * on subsequent things).
     */
    public Tuple<String, Integer> autoDedentElif(IDocument document, DocumentCommand command) throws BadLocationException {
    	return autoDedentAfterColon(document, command, "elif", PySelection.TOKENS_BEFORE_ELSE);
    }
    

    /**
     * Create the indentation string after comma and a newline.
     * 
     * @param document
     * @param text
     * @param offset
     * @param selection 
     * @return Indentation String
     * @throws BadLocationException
     */
    private String makeSmartIndent(String text, int smartIndent)
            throws BadLocationException {
        if (smartIndent > 0) {
            String initial = text;

            // Discard everything but the newline from initial, since we'll
            // build the smart indent from scratch anyway.
            initial = getCharsBeforeNewLine(initial);

            // 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){
                indentationSteps -= 1;
                b.append(indentationString);
            }
            
            if(prefs.getUseSpaces()){
                while (spaceSteps >= 0){
                    spaceSteps -= 1;
                    b.append(" ");
                }
            }

            return initial + b.toString();
        }
        return text;
    }

    /**
     * @param initial
     * @return
     */
    private String getCharsBeforeNewLine(String initial) {
        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);
                }
                break;
            }
        }
        return initial;
    }

    /**
     * Private function which is called when a colon is the command.
     * 
     * The following code will auto-replace colons in function declaractions
     * e.g., def something(self): ^ cursor before the end colon
     * 
     * Typing another colon (i.e, ':') at that position will not insert another
     * colon
     * 
     * @param document
     * @param command
     * @throws BadLocationException
     */
    private void performColonReplacement(IDocument document, DocumentCommand command) {
        PySelection ps = new PySelection(document, command.offset);
        int absoluteOffset = ps.getAbsoluteCursorOffset();
        int documentLength = ps.getDoc().getLength();

        // need to check whether whether we're at the very end of the document
        if (absoluteOffset < documentLength) {
            try {
                char currentCharacter = document.getChar(absoluteOffset);

                if (currentCharacter == ':') {
                    command.text = DocUtils.EMPTY_STRING;
                    command.caretOffset = command.offset + 1;
                }

            } catch (BadLocationException e) {
                // should never happen because I just checked the length 
                throw new RuntimeException(e);
            }

        }
    }

    /**
     * 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.
     * @throws BadLocationException 
     */
    private void performPairReplacement(IDocument document, DocumentCommand command) throws BadLocationException {
        PySelection ps = new PySelection(document, command.offset);

        char c = ps.getCharAtCurrentOffset();
        char peer = DocUtils.getPeer(c);
        StringBuffer doc = new StringBuffer(document.get());
        //it is not enough just counting the chars, we have to ignore those that are within comments or literals.
        ParsingUtils.removeCommentsWhitespacesAndLiterals(doc);
        int chars = PyAction.countChars(c, doc);
        int peers = PyAction.countChars(peer, doc);
        
        if( chars == peers){
            //if we have the same number of peers, we want to eat the char
            command.text = DocUtils.EMPTY_STRING;
            command.caretOffset = command.offset + 1;
        }
    }

    /**
     * @param ps
     * @param c the char to close
     * @return
     * @throws BadLocationException
     */
    private boolean shouldClose(PySelection ps, char c) throws BadLocationException {
        String line = ps.getLine();

        String lineContentsFromCursor = ps.getLineContentsFromCursor();

        for (int i = 0; i < lineContentsFromCursor.length(); i++) {
            if (!Character.isWhitespace(lineContentsFromCursor.charAt(i))) {
                return false;
            }
        }

        int i = PyAction.countChars(c, line);
        int j = PyAction.countChars(c, line);

        if (j > i) {
            return false;
        }

        return true;
    }

    /**
	 * 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
     * @param ps 
	 * @return indent, or -1 if smart indent could not be determined (fall back to default)
     * and a boolean indicating if we're inside a parenthesis
	 */
    public static Tuple<Integer,Boolean> determineSmartIndent(int offset, PySelection ps, IIndentPrefs prefs)
            throws BadLocationException {
        IDocument document = ps.getDoc();
        PythonPairMatcher matcher = new PythonPairMatcher(DocUtils.BRACKETS);
        int openingPeerOffset = matcher.searchForAnyOpeningPeer(offset, document);
        if(openingPeerOffset == -1){
            return new Tuple<Integer,Boolean>(-1, false);
        }
        
        //ok, now, if the opening peer is not on the line we're currently, we do not want to make
        //an 'auto-indent', but keep the current indentation level
        final IRegion lineInformationOfOffset = document.getLineInformationOfOffset(openingPeerOffset);
        if(!PySelection.isInside(offset, lineInformationOfOffset)){
            return new Tuple<Integer,Boolean>(-1, true);
        }
        
        int len = -1;
        String contents = "";
        if(prefs.getIndentToParLevel()){
        	
        	
        	//now, there's a little catch here, if we are in a line with an opening peer,
        	//we have to choose whether to indent to the opening peer or a little further
        	//e.g.: if the line is 
        	//method(  self <<- a new line here should indent to the start of the self and not
        	//to the opening peer.
        	if(openingPeerOffset < offset){
        		String fromParToCursor = document.get(openingPeerOffset, offset-openingPeerOffset);
        		if(fromParToCursor.length() > 0 && fromParToCursor.charAt(0) == '('){
        			fromParToCursor = fromParToCursor.substring(1);
        			if(!PySelection.containsOnlyWhitespaces(fromParToCursor)){
        				final int firstCharPosition = PySelection.getFirstCharPosition(fromParToCursor);
        				openingPeerOffset += firstCharPosition;
        			}
        		}
        	}
        	
        	
			int openingPeerLineOffset = lineInformationOfOffset.getOffset();
	        len = openingPeerOffset - openingPeerLineOffset;
	        contents = document.get(openingPeerLineOffset, len);
        }else{
        	//ok, we have to get the 
        	int line = document.getLineOfOffset(openingPeerOffset);
        	final String indent = prefs.getIndentationString();
			contents = PySelection.getLine(document, line);
			contents = PySelection.getIndentationFromLine(contents);
        	contents += indent.substring(0, indent.length()-1); //we have to make it -1 (that's what the smartindent expects)
        	len = contents.length();
        }
        //add more spaces for each tab
        for(int i = 0; i<contents.length(); i++){
        	if(contents.charAt(i) == '\t'){
        		len += prefs.getTabWidth() - 1;
        	}
        }
        return new Tuple<Integer,Boolean>(len, true);
        
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -