Skip to content

Commit 2932263

Browse files
committed
Update files that use symbolic links (#1840)
1 parent 74072b9 commit 2932263

File tree

5 files changed

+188
-0
lines changed

5 files changed

+188
-0
lines changed

CHANGELOG.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ This document provides a high-level view of the changes introduced by release.
1212
- Prevent "Read access not allowed" when using LLMs (#1822)
1313
- Prevent "InvalidVirtualFileAccessException" when iterating the file tree (#1825)
1414
- Build correct URL for content security policy in IntelliJ 2025.2 EAP (#1837)
15+
- Update files that use symbolic links (#1840)
1516

1617
=== 0.44.5
1718

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package org.asciidoc.intellij.psi.search;
2+
3+
import com.intellij.openapi.project.Project;
4+
import com.intellij.openapi.vfs.VirtualFile;
5+
import com.intellij.util.containers.CollectionFactory;
6+
import com.intellij.util.indexing.FileBasedIndex;
7+
import com.intellij.util.indexing.ID;
8+
import org.asciidoc.intellij.psi.AsciiDocSearchScope;
9+
import org.jetbrains.annotations.NonNls;
10+
import org.jetbrains.annotations.NotNull;
11+
12+
import java.util.Collection;
13+
import java.util.Set;
14+
15+
/**
16+
* Index that specifically contains only file system links
17+
* This should avoid a situation where IntelliJ sometime has outdated information about files that leads to PSI problems.
18+
*
19+
* @author Alexander Schwartz ([email protected])
20+
*/
21+
public class AsciiDocLinkIndex {
22+
@NonNls
23+
public static final ID<String, Void> NAME = ID.create("AsciiDocLinkIndex");
24+
25+
public static Collection<VirtualFile> getLinkSources(@NotNull Project project, String target) {
26+
Set<VirtualFile> files = CollectionFactory.createSmallMemoryFootprintSet();
27+
FileBasedIndex.getInstance().processValues(NAME, target, null, (file, value) -> {
28+
files.add(file);
29+
return true;
30+
}, new AsciiDocSearchScope(project), null);
31+
return files;
32+
}
33+
34+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package org.asciidoc.intellij.psi.search;
2+
3+
import com.intellij.openapi.fileTypes.FileType;
4+
import com.intellij.util.indexing.DataIndexer;
5+
import com.intellij.util.indexing.FileBasedIndex;
6+
import com.intellij.util.indexing.FileContent;
7+
import com.intellij.util.indexing.ID;
8+
import com.intellij.util.indexing.ScalarIndexExtension;
9+
import com.intellij.util.io.EnumeratorStringDescriptor;
10+
import com.intellij.util.io.KeyDescriptor;
11+
import org.asciidoc.intellij.file.AsciiDocFileType;
12+
import org.jetbrains.annotations.NotNull;
13+
14+
import java.util.Collection;
15+
import java.util.Collections;
16+
import java.util.Objects;
17+
18+
/**
19+
* Index implementation to contain all Antora playbooks.
20+
*
21+
* @author Alexander Schwartz ([email protected])
22+
*/
23+
public class AsciiDocLinkIndexImpl extends ScalarIndexExtension<String> {
24+
25+
@NotNull
26+
@Override
27+
public ID<String, Void> getName() {
28+
return AsciiDocLinkIndex.NAME;
29+
}
30+
31+
/**
32+
* Map all entries to a single key, so we can later retrieve them with a single lookup.
33+
*/
34+
@NotNull
35+
@Override
36+
public DataIndexer<String, Void, FileContent> getIndexer() {
37+
return inputData -> {
38+
String canonicalPath = inputData.getFile().getCanonicalPath();
39+
return Collections.singletonMap(canonicalPath, null);
40+
};
41+
}
42+
43+
@NotNull
44+
@Override
45+
public KeyDescriptor<String> getKeyDescriptor() {
46+
return EnumeratorStringDescriptor.INSTANCE;
47+
}
48+
49+
/**
50+
* Files to be indexed need to end with ".yml", and need to contain both "antora" and "playbook".
51+
*/
52+
@NotNull
53+
@Override
54+
public FileBasedIndex.InputFilter getInputFilter() {
55+
return vf -> {
56+
if (!vf.getFileType().equals(AsciiDocFileType.INSTANCE)) {
57+
return false;
58+
}
59+
return !Objects.equals(vf.getPath(), vf.getCanonicalPath());
60+
};
61+
}
62+
63+
@Override
64+
public @NotNull Collection<FileType> getFileTypesWithSizeLimitNotApplicable() {
65+
return super.getFileTypesWithSizeLimitNotApplicable();
66+
}
67+
68+
@Override
69+
public boolean dependsOnFileContent() {
70+
return false;
71+
}
72+
73+
@Override
74+
public boolean indexDirectories() {
75+
return false;
76+
}
77+
78+
@Override
79+
public int getVersion() {
80+
return 1;
81+
}
82+
83+
@Override
84+
public boolean traceKeyHashToVirtualFileMapping() {
85+
return true;
86+
}
87+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package org.asciidoc.intellij.psi.search;
2+
3+
import com.intellij.openapi.Disposable;
4+
import com.intellij.openapi.application.ApplicationManager;
5+
import com.intellij.openapi.project.DumbAware;
6+
import com.intellij.openapi.project.DumbService;
7+
import com.intellij.openapi.project.Project;
8+
import com.intellij.openapi.startup.StartupActivity;
9+
import com.intellij.openapi.vfs.LocalFileSystem;
10+
import com.intellij.openapi.vfs.VirtualFile;
11+
import com.intellij.openapi.vfs.VirtualFileManager;
12+
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
13+
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
14+
import com.intellij.util.messages.MessageBusConnection;
15+
import org.jetbrains.annotations.NotNull;
16+
17+
import java.util.HashSet;
18+
import java.util.List;
19+
import java.util.Set;
20+
21+
/**
22+
* Shows update notification.
23+
*/
24+
public class AsciiDocLinkProjectOpen implements StartupActivity, DumbAware, Disposable {
25+
26+
private MessageBusConnection connection;
27+
28+
@Override
29+
public void runActivity(@NotNull Project project) {
30+
connection = project.getMessageBus().connect(this);
31+
connection.subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener() {
32+
@Override
33+
public void after(@NotNull List<? extends VFileEvent> events) {
34+
// any modification of a file within the project refreshes the preview
35+
Set<VirtualFile> linkSources = new HashSet<>();
36+
for (VFileEvent event : events) {
37+
if (event.getFile() != null) {
38+
if (!project.isDisposed()) {
39+
VirtualFile file = event.getFile();
40+
if (!file.isValid()) {
41+
continue;
42+
}
43+
if (!DumbService.isDumb(project)) {
44+
linkSources.addAll(AsciiDocLinkIndex.getLinkSources(project, file.getCanonicalPath()));
45+
}
46+
}
47+
}
48+
}
49+
if (!linkSources.isEmpty()) {
50+
ApplicationManager.getApplication().invokeLater(() -> {
51+
ApplicationManager.getApplication().runWriteAction(() -> {
52+
LocalFileSystem.getInstance().refreshFiles(linkSources);
53+
});
54+
});
55+
}
56+
}
57+
});
58+
}
59+
60+
@Override
61+
public void dispose() {
62+
connection.disconnect();
63+
}
64+
}

src/main/resources/META-INF/plugin.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,5 +433,7 @@
433433
<errorHandler implementation="org.asciidoc.intellij.errorHandler.AsciiDocErrorHandler"/>
434434
<registryKey defaultValue="true" description="Whether the AsciiDoc view should be displayed in the off-screen mode." key="ide.browser.jcef.asciidocView.osr.enabled" />
435435
<fileBasedIndex implementation="org.asciidoc.intellij.psi.search.AsciiDocAntoraPlaybookIndexImpl"/>
436+
<fileBasedIndex implementation="org.asciidoc.intellij.psi.search.AsciiDocLinkIndexImpl"/>
437+
<postStartupActivity implementation="org.asciidoc.intellij.psi.search.AsciiDocLinkProjectOpen"/>
436438
</extensions>
437439
</idea-plugin>

0 commit comments

Comments
 (0)