mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 04:51:24 +07:00
PY-61639 Move PyKeywordTypeHandler to python.syntax
GitOrigin-RevId: 3e0e70f5868b0fc09c35e571db0d0e553902eb6d
This commit is contained in:
committed by
intellij-monorepo-bot
parent
3b9b10b296
commit
f6cad19f19
@@ -0,0 +1,99 @@
|
||||
package com.jetbrains.python.codeInsight;
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.EditorCoreUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.ast.PyAstStatementWithElse;
|
||||
import com.jetbrains.python.ast.PyAstTryExceptStatement;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public final class PyUnindentUtil {
|
||||
/**
|
||||
* Unindent current line to be flush with a starting part, detecting the part if necessary.
|
||||
*
|
||||
* @return true if unindenting succeeded
|
||||
*/
|
||||
public static boolean unindentAsNeeded(Project project, Editor editor, PsiFile file) {
|
||||
// TODO: handle things other than "else"
|
||||
final Document document = editor.getDocument();
|
||||
int offset = editor.getCaretModel().getOffset();
|
||||
CharSequence text = document.getCharsSequence();
|
||||
if (offset >= text.length()) {
|
||||
offset = text.length() - 1;
|
||||
}
|
||||
|
||||
int line_start_offset = document.getLineStartOffset(document.getLineNumber(offset));
|
||||
int nonspace_offset = findBeginning(line_start_offset, text);
|
||||
|
||||
|
||||
Class<? extends PsiElement> parentClass = null;
|
||||
|
||||
int last_offset = nonspace_offset + PyNames.FINALLY.length(); // the longest of all
|
||||
if (last_offset > offset) last_offset = offset;
|
||||
int local_length = last_offset - nonspace_offset + 1;
|
||||
if (local_length > 0) {
|
||||
String piece = text.subSequence(nonspace_offset, last_offset + 1).toString();
|
||||
final int else_len = PyNames.ELSE.length();
|
||||
if (local_length >= else_len) {
|
||||
if ((piece.startsWith(PyNames.ELSE) || piece.startsWith(PyNames.ELIF)) &&
|
||||
(else_len == piece.length() || piece.charAt(else_len) < 'a' || piece.charAt(else_len) > 'z')) {
|
||||
parentClass = PyAstStatementWithElse.class;
|
||||
}
|
||||
}
|
||||
final int except_len = PyNames.EXCEPT.length();
|
||||
if (local_length >= except_len) {
|
||||
if (piece.startsWith(PyNames.EXCEPT) &&
|
||||
(except_len == piece.length() || piece.charAt(except_len) < 'a' || piece.charAt(except_len) > 'z')) {
|
||||
parentClass = PyAstTryExceptStatement.class;
|
||||
}
|
||||
}
|
||||
final int finally_len = PyNames.FINALLY.length();
|
||||
if (local_length >= finally_len) {
|
||||
if (piece.startsWith(PyNames.FINALLY) &&
|
||||
(finally_len == piece.length() || piece.charAt(finally_len) < 'a' || piece.charAt(finally_len) > 'z')) {
|
||||
parentClass = PyAstTryExceptStatement.class;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (parentClass == null) return false; // failed
|
||||
|
||||
PsiDocumentManager.getInstance(project).commitDocument(document); // reparse
|
||||
|
||||
PsiElement token = file.findElementAt(offset - 2); // -1 is our ':'; -2 is even safer.
|
||||
PsiElement outer = PsiTreeUtil.getParentOfType(token, parentClass);
|
||||
if (outer != null) {
|
||||
int outer_offset = outer.getTextOffset();
|
||||
int outer_indent = outer_offset - document.getLineStartOffset(document.getLineNumber(outer_offset));
|
||||
assert outer_indent >= 0;
|
||||
int current_indent = nonspace_offset - line_start_offset;
|
||||
int indent = outer_indent - current_indent;
|
||||
EditorCoreUtil.indentLine(project, editor, document.getLineNumber(offset), editor.getSettings().isUseTabCharacter(project)
|
||||
? indent * editor.getSettings().getTabSize(project)
|
||||
: indent, false);
|
||||
//TODO!!!: shouldUseSmartTabs! is it applicable?
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// finds offset of first non-space in the line
|
||||
private static int findBeginning(int start_offset, CharSequence text) {
|
||||
int current_offset = start_offset;
|
||||
int text_length = text.length();
|
||||
while (current_offset < text_length) {
|
||||
char current_char = text.charAt(current_offset);
|
||||
if (current_char != ' ' && current_char != '\t' && current_char != '\n') break;
|
||||
current_offset += 1;
|
||||
}
|
||||
return current_offset;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user