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;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class LineInfo extends FileInfo {
|
public class LineInfo extends FileInfo {
|
||||||
|
public final int lineCount;
|
||||||
public final int lineNumber;
|
public final int lineNumber;
|
||||||
public final int startOffset;
|
public final int startOffset;
|
||||||
public final int endOffset;
|
public final int endOffset;
|
||||||
public final @NotNull String text;
|
public final @NotNull String text;
|
||||||
|
|
||||||
protected LineInfo(@NotNull FileInfo info, @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);
|
super(info.file, info.document, info.project, FuncEnum.LINE);
|
||||||
|
this.lineCount = lineCount;
|
||||||
this.lineNumber = lineNumber;
|
this.lineNumber = lineNumber;
|
||||||
this.startOffset = startOffset;
|
this.startOffset = startOffset;
|
||||||
this.endOffset = endOffset;
|
this.endOffset = endOffset;
|
||||||
@@ -30,8 +32,9 @@ public class LineInfo extends FileInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static @Nullable LineInfo of(@NotNull FileInfo info, int lineNumber) {
|
public static @Nullable LineInfo of(@NotNull FileInfo info, int lineNumber) {
|
||||||
|
int lineCount = info.document.getLineCount();
|
||||||
// lineNumber start 0, as 1 <= 1 should return
|
// lineNumber start 0, as 1 <= 1 should return
|
||||||
if (info.document.getLineCount() <= lineNumber) {
|
if (lineCount <= lineNumber) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@@ -41,7 +44,7 @@ public class LineInfo extends FileInfo {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@NotNull String text = info.document.getText(new TextRange(startOffset, endOffset));
|
@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) {
|
} catch (Exception e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,20 +3,29 @@ package io.github.linwancen.plugin.show.cache;
|
|||||||
import com.intellij.openapi.editor.LineExtensionInfo;
|
import com.intellij.openapi.editor.LineExtensionInfo;
|
||||||
import io.github.linwancen.plugin.show.bean.LineInfo;
|
import io.github.linwancen.plugin.show.bean.LineInfo;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
public class LineEndCache {
|
public class LineEndCache {
|
||||||
@NotNull public volatile String code;
|
@NotNull
|
||||||
@NotNull public final List<LineExtensionInfo> lineExtList = new ArrayList<>(1);
|
public final Map<String, List<LineExtensionInfo>> map = new ConcurrentHashMap<>();
|
||||||
|
public volatile boolean show = true;
|
||||||
public volatile boolean selectChanged = false;
|
public volatile boolean selectChanged = false;
|
||||||
/** null if updated */
|
@NotNull
|
||||||
@Nullable public volatile LineInfo info;
|
public volatile LineInfo info;
|
||||||
|
|
||||||
public LineEndCache(@NotNull String code, @NotNull LineInfo info) {
|
public LineEndCache(@NotNull LineInfo info) {
|
||||||
this.code = code;
|
|
||||||
this.info = 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.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@@ -26,18 +27,35 @@ public class LineEndCacheUtils {
|
|||||||
|
|
||||||
public static @Nullable Collection<LineExtensionInfo> get(@NotNull LineInfo info) {
|
public static @Nullable Collection<LineExtensionInfo> get(@NotNull LineInfo info) {
|
||||||
try {
|
try {
|
||||||
@NotNull LineEndCache lineCache = cache
|
@NotNull Map<Integer, LineEndCache> lineMap = cache
|
||||||
.computeIfAbsent(info.project, a -> new ConcurrentHashMap<>())
|
.computeIfAbsent(info.project, a -> new ConcurrentHashMap<>())
|
||||||
.computeIfAbsent(info.file, a -> new ConcurrentHashMap<>())
|
.computeIfAbsent(info.file, a -> new ConcurrentHashMap<>());
|
||||||
.computeIfAbsent(info.lineNumber, a -> new LineEndCache(info.text, info));
|
@NotNull LineEndCache lineCache = lineMap
|
||||||
if (lineCache.selectChanged) {
|
.computeIfAbsent(info.lineNumber, a -> new LineEndCache(info));
|
||||||
lineCache.info = info;
|
@NotNull LineInfo oldInfo = lineCache.info;
|
||||||
} else if (!info.text.equals(lineCache.code)) {
|
lineCache.info = info;
|
||||||
lineCache.info = info;
|
lineCache.show = true;
|
||||||
lineCache.lineExtList.clear();
|
|
||||||
}
|
|
||||||
checkScheduleAndInit();
|
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) {
|
} catch (Throwable e) {
|
||||||
LOG.info("LineEndCacheUtils catch Throwable but log to record.", e);
|
LOG.info("LineEndCacheUtils catch Throwable but log to record.", e);
|
||||||
return null;
|
return null;
|
||||||
@@ -73,27 +91,32 @@ public class LineEndCacheUtils {
|
|||||||
if (DumbService.isDumb(project)) {
|
if (DumbService.isDumb(project)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fileMap.forEach((file, lineMap) -> lineMap.forEach((lineNumber, lineEndCache) -> {
|
fileMap.forEach((file, lineMap) -> lineMap.forEach((lineNumber, lineCache) -> {
|
||||||
if (lineEndCache.info == null) {
|
@NotNull LineInfo info = lineCache.info;
|
||||||
|
@Nullable List<LineExtensionInfo> list = lineCache.map.get(info.text);
|
||||||
|
if (!(lineCache.needUpdate() || list == null)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ApplicationManager.getApplication().runReadAction(() -> {
|
ApplicationManager.getApplication().runReadAction(() -> {
|
||||||
try {
|
try {
|
||||||
@Nullable LineInfo info = lineEndCache.info;
|
@Nullable LineExtensionInfo lineExt = LineEnd.lineExt(info);
|
||||||
if (info == null) {
|
@Nullable LineInfo info2 = LineInfo.of(info, lineNumber);
|
||||||
|
if (info2 == null || !info2.text.equals(info.text)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lineEndCache.info = null;
|
if (list != null) {
|
||||||
if (lineEndCache.selectChanged) {
|
list.clear();
|
||||||
lineEndCache.selectChanged = false;
|
|
||||||
lineEndCache.lineExtList.clear();
|
|
||||||
}
|
}
|
||||||
@Nullable LineExtensionInfo lineExt = LineEnd.lineExt(info);
|
|
||||||
if (lineExt != null) {
|
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
|
lineCache.updated();
|
||||||
lineEndCache.code = info.text;
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOG.info("LineEndCacheUtils lineMap.forEach catch Throwable but log to record.", 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) {
|
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);
|
@Nullable FileViewProvider viewProvider = PsiManager.getInstance(info.project).findViewProvider(info.file);
|
||||||
if (viewProvider == null) {
|
if (viewProvider == null) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
Reference in New Issue
Block a user