📄 pyautoindentstrategy.java
字号:
return new Tuple<String, Integer>(text, 0);
}
/**
* @see org.eclipse.jface.text.IAutoEditStrategy#customizeDocumentCommand(IDocument, DocumentCommand)
*/
public void customizeDocumentCommand(IDocument document, DocumentCommand command) {
// super idents newlines the same amount as the previous line
final boolean isNewLine = isNewLineText(document, command.length, command.text);
if(isNewLine){
autoIndentSameAsPrevious(document, command);
}
String contentType = ParsingUtils.getContentType(document, command.offset);
if(!contentType.equals( ParsingUtils.PY_DEFAULT)){
//the indentation is only valid for things in the code (comments should not be indented).
//(that is, if it is not a new line... in this case, it may have to be indented)
if(!isNewLine){
//we have to take care about tabs anyway
getIndentPrefs().convertToStd(document, command);
return;
}
}
try {
if (isNewLine) {
if(prefs.getSmartIndentPar()){
PySelection selection = new PySelection(document, command.offset);
if(selection.getCursorLineContents().trim().length() > 0){
command.text = autoIndentNewline(document, command.length, command.text, command.offset).o1;
if(PySelection.containsOnlyWhitespaces(selection.getLineContentsToCursor())){
command.caretOffset = command.offset + selection.countSpacesAfter(command.offset);
}
}
}else{
PySelection selection = new PySelection(document, command.offset);
if(selection.getCursorLineContents().trim().endsWith(":")){
command.text += prefs.getIndentationString();
}
}
}else if(command.text.equals("\t")){
PySelection ps = new PySelection(document, command.offset);
//it is a tab
String lineContentsToCursor = ps.getLineContentsToCursor();
int cursorLine = ps.getCursorLine();
if(cursorLine > 0){
//this is to know which would be expected if it was a new line in the previous line
//(so that we know the 'expected' output
IRegion prevLineInfo = document.getLineInformation(cursorLine-1);
int prevLineEndOffset = prevLineInfo.getOffset()+prevLineInfo.getLength();
String prevExpectedIndent = autoIndentSameAsPrevious(document, prevLineEndOffset, "\n", false);
String txt = prevExpectedIndent;
Tuple<String, Boolean> prevLineTup = autoIndentNewline(document, 0, txt, prevLineEndOffset);
txt = prevLineTup.o1;
txt = txt.substring(1);//remove the newline
prevExpectedIndent = prevExpectedIndent.substring(1);
if (txt.length() > 0){
//now, we should not apply that indent if we are already at the 'max' indent in this line
//(or better: we should go to that max if it would pass it)
int sizeApplied = ps.getStartLineOffset()+ lineContentsToCursor.length() + txt.length();
int sizeExpected = ps.getStartLineOffset()+ txt.length();
int currSize = ps.getAbsoluteCursorOffset();
if(currSize >= sizeExpected){
//do nothing (we already passed what we expected from the indentation)
int len = sizeApplied-sizeExpected;
if(prevLineTup.o2){
if(prevExpectedIndent.length() > len){
command.text = prevExpectedIndent.substring(len);
}
}
}else if(sizeExpected == sizeApplied){
if(command.length == 0){
ps.deleteSpacesAfter(command.offset);
}
command.text = txt;
}else if(sizeApplied > sizeExpected){
ps.deleteSpacesAfter(command.offset);
command.text = txt.substring(0, sizeExpected - currSize);
}
}
}
}
getIndentPrefs().convertToStd(document, command);
if (prefs.getAutoParentesis() && (command.text.equals("[") || command.text.equals("{")) ) {
PySelection ps = new PySelection(document, command.offset);
char c = command.text.charAt(0);
if (shouldClose(ps, c)) {
command.shiftsCaret = false;
command.text = c+""+DocUtils.getPeer(c);
command.caretOffset = command.offset+1;
}
}else if (command.text.equals("(")) {
/*
* Now, let's also check if we are in an 'elif ' that must be dedented in the doc
*/
autoDedentElif(document, command);
if(prefs.getAutoParentesis()){
PySelection ps = new PySelection(document, command.offset);
String line = ps.getLine();
if (shouldClose(ps, '(')) {
boolean hasClass = line.indexOf("class ") != -1;
boolean hasClassMethodDef = line.indexOf(" def ") != -1 || line.indexOf("\tdef ") != -1;
boolean hasMethodDef = line.indexOf("def ") != -1;
boolean hasNoDoublePoint = line.indexOf(":") == -1;
command.shiftsCaret = false;
if (hasNoDoublePoint && (hasClass || hasClassMethodDef || hasMethodDef)) {
if (hasClass) {
//command.text = "(object):"; //TODO: put some option in the interface for that
//command.caretOffset = command.offset + 7;
command.text = "():";
command.caretOffset = command.offset + 1;
} else if (hasClassMethodDef && prefs.getAutoAddSelf()) {
String prevLine = ps.getLine(ps.getCursorLine()-1);
if(prevLine.indexOf("@classmethod") != -1){
command.text = "(cls):";
command.caretOffset = command.offset + 4;
}else if(prevLine.indexOf("@staticmethod") != -1){
command.text = "():";
command.caretOffset = command.offset + 1;
}else{
boolean addRegular = true;
Tuple3<String, String, String> scopeStart = ps.getPreviousLineThatStartsScope(PySelection.CLASS_AND_FUNC_TOKENS, false);
if(scopeStart != null){
if(scopeStart.o1 != null && scopeStart.o1.indexOf("def ") != -1){
int iCurrDef = PySelection.getFirstCharPosition(line);
int iPrevDef = PySelection.getFirstCharPosition(scopeStart.o1);
if(iCurrDef > iPrevDef){
addRegular = false;
}
}
}
if(addRegular){
command.text = "(self):";
command.caretOffset = command.offset + 5;
}else{
command.text = "():";
command.caretOffset = command.offset + 1;
}
}
} else if (hasMethodDef) {
command.text = "():";
command.caretOffset = command.offset + 1;
} else {
throw new RuntimeException(getClass().toString() + ": customizeDocumentCommand()");
}
} else {
command.text = "()";
command.caretOffset = command.offset + 1;
}
}
}
}
else if (command.text.equals(":")) {
/*
* 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
*/
if(prefs.getAutoColon()){
performColonReplacement(document, command);
}
/*
* Now, let's also check if we are in an 'else:' or 'except:' or 'finally:' that must be dedented in the doc
*/
autoDedentAfterColon(document, command);
}
/*
* this is a space... so, if we are in 'from xxx ', we may auto-write
* the import
*/
else if (command.text.equals(" ")) {
if( prefs.getAutoWriteImport()){
PySelection ps = new PySelection(document, command.offset);
String completeLine = ps.getLineWithoutCommentsOrLiterals();
String lineToCursor = ps.getLineContentsToCursor().trim();
String lineContentsFromCursor = ps.getLineContentsFromCursor();
if( completeLine.indexOf(" import ") == -1 &&
StringUtils.leftTrim(completeLine).startsWith("from ")&&
!completeLine.startsWith("import ")&&
!completeLine.endsWith(" import") &&
!lineContentsFromCursor.startsWith("import")){
String importsTipperStr = ImportsSelection.getImportsTipperStr(lineToCursor, false).importsTipperStr;
if(importsTipperStr.length() > 0){
command.text = " import ";
}
}
}
/*
* Now, let's also check if we are in an 'elif ' that must be dedented in the doc
*/
autoDedentElif(document, command);
}
/*
* If the command is some kind of parentheses or brace, and there's
* already a matching one, don't insert it. Just move the cursor to
* the next space.
*/
else if (command.text.length() < 3 && prefs.getAutoBraces()) {
// you can only do the replacement if the next character already there is what the user is trying to input
if (command.offset < document.getLength() && document.get(command.offset, 1).equals(command.text)) {
// the following searches through each of the end braces and
// sees if the command has one of them
boolean found = false;
for (int i = 1; i <= DocUtils.BRACKETS.length && !found; i += 2) {
char c = DocUtils.BRACKETS[i];
if (c == command.text.charAt(0)) {
found = true;
performPairReplacement(document, command);
}
}
}
}
}
/*
* If something goes wrong, you want to know about it, especially in a
* unit test. If you don't rethrow the exception, unit tests will pass
* even though you threw an exception.
*/
catch (BadLocationException e) {
// screw up command.text so unit tests can pick it up
command.text = "BadLocationException";
throw new RuntimeException(e);
}
}
/**
* 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> autoDedentAfterColon(IDocument document, DocumentCommand command, String tok, String[] tokens) throws BadLocationException {
if(getIndentPrefs().getAutoDedentElse()){
PySelection ps = new PySelection(document, command.offset);
String lineContents = ps.getCursorLineContents();
if(lineContents.trim().equals(tok)){
String previousIfLine = ps.getPreviousLineThatStartsWithToken(tokens);
if(previousIfLine != null){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -