fix(LineEndCache): insert/delete line load old cache
This commit is contained in:
@@ -7,14 +7,16 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class LineInfo extends FileInfo {
|
||||
public final int lineCount;
|
||||
public final int lineNumber;
|
||||
public final int startOffset;
|
||||
public final int endOffset;
|
||||
public final @NotNull String text;
|
||||
|
||||
protected LineInfo(@NotNull FileInfo info, @NotNull String text,
|
||||
int lineNumber, int startOffset, int endOffset) {
|
||||
int lineCount, int lineNumber, int startOffset, int endOffset) {
|
||||
super(info.file, info.document, info.project, FuncEnum.LINE);
|
||||
this.lineCount = lineCount;
|
||||
this.lineNumber = lineNumber;
|
||||
this.startOffset = startOffset;
|
||||
this.endOffset = endOffset;
|
||||
@@ -30,8 +32,9 @@ public class LineInfo extends FileInfo {
|
||||
}
|
||||
|
||||
public static @Nullable LineInfo of(@NotNull FileInfo info, int lineNumber) {
|
||||
int lineCount = info.document.getLineCount();
|
||||
// lineNumber start 0, as 1 <= 1 should return
|
||||
if (info.document.getLineCount() <= lineNumber) {
|
||||
if (lineCount <= lineNumber) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
@@ -41,7 +44,7 @@ public class LineInfo extends FileInfo {
|
||||
return null;
|
||||
}
|
||||
@NotNull String text = info.document.getText(new TextRange(startOffset, endOffset));
|
||||
return new LineInfo(info, text, lineNumber, startOffset, endOffset);
|
||||
return new LineInfo(info, text, lineCount, lineNumber, startOffset, endOffset);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -3,20 +3,29 @@ package io.github.linwancen.plugin.show.cache;
|
||||
import com.intellij.openapi.editor.LineExtensionInfo;
|
||||
import io.github.linwancen.plugin.show.bean.LineInfo;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class LineEndCache {
|
||||
@NotNull public volatile String code;
|
||||
@NotNull public final List<LineExtensionInfo> lineExtList = new ArrayList<>(1);
|
||||
@NotNull
|
||||
public final Map<String, List<LineExtensionInfo>> map = new ConcurrentHashMap<>();
|
||||
public volatile boolean show = true;
|
||||
public volatile boolean selectChanged = false;
|
||||
/** null if updated */
|
||||
@Nullable public volatile LineInfo info;
|
||||
@NotNull
|
||||
public volatile LineInfo info;
|
||||
|
||||
public LineEndCache(@NotNull String code, @NotNull LineInfo info) {
|
||||
this.code = code;
|
||||
public LineEndCache(@NotNull LineInfo info) {
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public boolean needUpdate() {
|
||||
return show && selectChanged;
|
||||
}
|
||||
|
||||
public void updated() {
|
||||
show = false;
|
||||
selectChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -26,18 +27,35 @@ public class LineEndCacheUtils {
|
||||
|
||||
public static @Nullable Collection<LineExtensionInfo> get(@NotNull LineInfo info) {
|
||||
try {
|
||||
@NotNull LineEndCache lineCache = cache
|
||||
@NotNull Map<Integer, LineEndCache> lineMap = cache
|
||||
.computeIfAbsent(info.project, a -> new ConcurrentHashMap<>())
|
||||
.computeIfAbsent(info.file, a -> new ConcurrentHashMap<>())
|
||||
.computeIfAbsent(info.lineNumber, a -> new LineEndCache(info.text, info));
|
||||
if (lineCache.selectChanged) {
|
||||
lineCache.info = info;
|
||||
} else if (!info.text.equals(lineCache.code)) {
|
||||
lineCache.info = info;
|
||||
lineCache.lineExtList.clear();
|
||||
}
|
||||
.computeIfAbsent(info.file, a -> new ConcurrentHashMap<>());
|
||||
@NotNull LineEndCache lineCache = lineMap
|
||||
.computeIfAbsent(info.lineNumber, a -> new LineEndCache(info));
|
||||
@NotNull LineInfo oldInfo = lineCache.info;
|
||||
lineCache.info = info;
|
||||
lineCache.show = true;
|
||||
checkScheduleAndInit();
|
||||
return lineCache.lineExtList;
|
||||
@Nullable List<LineExtensionInfo> list = lineCache.map.get(info.text);
|
||||
// load from other line
|
||||
if (list == null && info.lineCount != oldInfo.lineCount) {
|
||||
int oldLineNumber = info.lineNumber - info.lineCount + oldInfo.lineCount;
|
||||
@Nullable LineEndCache oldLineCache = lineMap.get(oldLineNumber);
|
||||
if (oldLineCache != null) {
|
||||
list = oldLineCache.map.get(info.text);
|
||||
if (list != null) {
|
||||
lineCache.map.put(info.text, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (oldInfo.lineCount == info.lineCount) {
|
||||
lineCache.map.entrySet().removeIf(it -> !it.getKey().equals(info.text));
|
||||
}
|
||||
if (list == null) {
|
||||
// because may be updated
|
||||
list = lineCache.map.get(info.text);
|
||||
}
|
||||
return list;
|
||||
} catch (Throwable e) {
|
||||
LOG.info("LineEndCacheUtils catch Throwable but log to record.", e);
|
||||
return null;
|
||||
@@ -73,27 +91,32 @@ public class LineEndCacheUtils {
|
||||
if (DumbService.isDumb(project)) {
|
||||
return;
|
||||
}
|
||||
fileMap.forEach((file, lineMap) -> lineMap.forEach((lineNumber, lineEndCache) -> {
|
||||
if (lineEndCache.info == null) {
|
||||
fileMap.forEach((file, lineMap) -> lineMap.forEach((lineNumber, lineCache) -> {
|
||||
@NotNull LineInfo info = lineCache.info;
|
||||
@Nullable List<LineExtensionInfo> list = lineCache.map.get(info.text);
|
||||
if (!(lineCache.needUpdate() || list == null)) {
|
||||
return;
|
||||
}
|
||||
ApplicationManager.getApplication().runReadAction(() -> {
|
||||
try {
|
||||
@Nullable LineInfo info = lineEndCache.info;
|
||||
if (info == null) {
|
||||
@Nullable LineExtensionInfo lineExt = LineEnd.lineExt(info);
|
||||
@Nullable LineInfo info2 = LineInfo.of(info, lineNumber);
|
||||
if (info2 == null || !info2.text.equals(info.text)) {
|
||||
return;
|
||||
}
|
||||
lineEndCache.info = null;
|
||||
if (lineEndCache.selectChanged) {
|
||||
lineEndCache.selectChanged = false;
|
||||
lineEndCache.lineExtList.clear();
|
||||
if (list != null) {
|
||||
list.clear();
|
||||
}
|
||||
@Nullable LineExtensionInfo lineExt = LineEnd.lineExt(info);
|
||||
if (lineExt != null) {
|
||||
lineEndCache.lineExtList.add(lineExt);
|
||||
if (list != null) {
|
||||
list.add(lineExt);
|
||||
} else {
|
||||
lineCache.map.put(info.text, new ArrayList<>() {{
|
||||
add(lineExt);
|
||||
}});
|
||||
}
|
||||
}
|
||||
// change after ext is updated
|
||||
lineEndCache.code = info.text;
|
||||
lineCache.updated();
|
||||
} catch (Exception e) {
|
||||
LOG.info("LineEndCacheUtils lineMap.forEach catch Throwable but log to record.", e);
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ public abstract class BaseLangDoc extends EditorLinePainter {
|
||||
}
|
||||
|
||||
public static @Nullable String langDoc(@NotNull LineInfo info) {
|
||||
// psiFile.getText() may be not equals document.getText()
|
||||
@Nullable FileViewProvider viewProvider = PsiManager.getInstance(info.project).findViewProvider(info.file);
|
||||
if (viewProvider == null) {
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user