mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-9795 Move various indent operation on string to PyIndentUtil
This commit is contained in:
committed by
Mikhail Golubev
parent
8201381038
commit
9213f503e3
@@ -19,7 +19,6 @@ import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.jetbrains.python.psi.PyIndentUtil;
|
||||
@@ -259,33 +258,6 @@ public abstract class SectionBasedDocString extends DocStringLineParser implemen
|
||||
return line.split(":", 1);
|
||||
}
|
||||
|
||||
// like Python's textwrap.dedent()
|
||||
@NotNull
|
||||
protected static String stripCommonIndent(@NotNull Substring text, boolean ignoreFirstStringIfNonEmpty) {
|
||||
final List<Substring> lines = text.splitLines();
|
||||
if (lines.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
final String firstLine = lines.get(0).toString();
|
||||
final boolean skipFirstLine = ignoreFirstStringIfNonEmpty && !StringUtil.isEmptyOrSpaces(firstLine);
|
||||
final Iterable<Substring> workList = lines.subList(skipFirstLine ? 1 : 0, lines.size());
|
||||
int curMinIndent = Integer.MAX_VALUE;
|
||||
for (Substring line : workList) {
|
||||
if (StringUtil.isEmptyOrSpaces(line)) {
|
||||
continue;
|
||||
}
|
||||
curMinIndent = Math.min(curMinIndent, PyIndentUtil.getLineIndentSize(line));
|
||||
}
|
||||
final int minIndent = curMinIndent;
|
||||
final List<String> dedentedLines = ContainerUtil.map(workList, new Function<Substring, String>() {
|
||||
@Override
|
||||
public String fun(Substring line) {
|
||||
return line.substring(Math.min(line.length(), minIndent)).toString();
|
||||
}
|
||||
});
|
||||
return StringUtil.join(skipFirstLine ? ContainerUtil.prepend(dedentedLines, firstLine) : dedentedLines, "\n");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<Section> getSections() {
|
||||
return Collections.unmodifiableList(mySections);
|
||||
@@ -624,7 +596,7 @@ public abstract class SectionBasedDocString extends DocStringLineParser implemen
|
||||
|
||||
@NotNull
|
||||
public String getDescription() {
|
||||
return myDescription == null ? "" : stripCommonIndent(myDescription, true);
|
||||
return myDescription == null ? "" : PyIndentUtil.removeCommonIndent(myDescription.getValue(), true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
*/
|
||||
package com.jetbrains.python.psi;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.LineTokenizer;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
@@ -23,9 +25,14 @@ import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.jetbrains.python.PythonFileType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Mikhail Golubev
|
||||
*/
|
||||
@@ -99,4 +106,89 @@ public class PyIndentUtil {
|
||||
public static String getIndentFromSettings(@NotNull Project project) {
|
||||
return StringUtil.repeatSymbol(' ', getIndentSizeFromSettings(project));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<String> removeCommonIndent(@NotNull Iterable<String> lines, boolean ignoreFirstLine) {
|
||||
return changeIndent(lines, ignoreFirstLine, "");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String removeCommonIndent(@NotNull String s, boolean ignoreFirstLine) {
|
||||
final List<String> trimmed = removeCommonIndent(LineTokenizer.tokenizeIntoList(s, false), ignoreFirstLine);
|
||||
return StringUtil.join(trimmed, "\n");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String changeIndent(@NotNull String s, boolean ignoreFirstLine, String newIndent) {
|
||||
final List<String> trimmed = changeIndent(LineTokenizer.tokenizeIntoList(s, false), ignoreFirstLine, newIndent);
|
||||
return StringUtil.join(trimmed, "\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Not that all empty lines will be trimmed.
|
||||
*/
|
||||
@NotNull
|
||||
public static List<String> changeIndent(@NotNull Iterable<String> lines, boolean ignoreFirstLine, final String newIndent) {
|
||||
final String oldIndent = findCommonIndent(lines, ignoreFirstLine);
|
||||
if (Iterables.isEmpty(lines)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final List<String> result = ContainerUtil.map(Iterables.skip(lines, ignoreFirstLine ? 1 : 0), new Function<String, String>() {
|
||||
@Override
|
||||
public String fun(String line) {
|
||||
if (StringUtil.isEmptyOrSpaces(line)) {
|
||||
return "";
|
||||
}
|
||||
else {
|
||||
return newIndent + line.substring(oldIndent.length());
|
||||
}
|
||||
}
|
||||
});
|
||||
if (ignoreFirstLine) {
|
||||
return ContainerUtil.prepend(result, Iterables.get(lines, 0));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* If lines include non-empty lines, all empty lines or lines that contain only spaces are ignored.
|
||||
* Otherwise (all line are empty) their common indent are returned as expected. If any two lines
|
||||
* have different indentation (e.g. one contains tab character and another doesn't), empty prefix
|
||||
* is returned.
|
||||
*/
|
||||
@NotNull
|
||||
public static String findCommonIndent(@NotNull Iterable<String> lines, boolean ignoreFirstLine) {
|
||||
String minIndent = null;
|
||||
boolean allLinesEmpty = true;
|
||||
if (Iterables.isEmpty(lines)) {
|
||||
return "";
|
||||
}
|
||||
boolean hasBadEmptyLineIndent = false;
|
||||
for (String line : Iterables.skip(lines, ignoreFirstLine ? 1 : 0)) {
|
||||
final boolean lineEmpty = StringUtil.isEmptyOrSpaces(line);
|
||||
if (lineEmpty && !allLinesEmpty) {
|
||||
continue;
|
||||
}
|
||||
final String indent = (String)getLineIndent(line);
|
||||
if (minIndent == null || (!lineEmpty && allLinesEmpty) || minIndent.startsWith(indent)) {
|
||||
minIndent = indent;
|
||||
}
|
||||
else if (!indent.startsWith(minIndent)) {
|
||||
if (lineEmpty) {
|
||||
hasBadEmptyLineIndent = true;
|
||||
}
|
||||
else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
allLinesEmpty &= lineEmpty;
|
||||
}
|
||||
if (allLinesEmpty && hasBadEmptyLineIndent) {
|
||||
return "";
|
||||
}
|
||||
return StringUtil.notNullize(minIndent);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user