@@ -2,16 +2,20 @@ package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues
22
33import com.intellij.codeInspection.ProblemsHolder
44import com.intellij.openapi.project.Project
5+ import com.intellij.openapi.util.ModificationTracker
56import com.intellij.openapi.util.TextRange
67import com.intellij.openapi.util.text.Strings
7- import com.intellij.psi.search.FilenameIndex
8+ import com.intellij.openapi.vfs.newvfs.persistent.FSRecords
9+ import com.intellij.psi.search.FilenameIndex.processAllFileNames
10+ import com.intellij.psi.search.GlobalSearchScope
11+ import com.intellij.psi.util.CachedValueProvider
12+ import com.intellij.psi.util.CachedValuesManager
13+ import com.intellij.util.containers.CollectionFactory
814import net.sjrx.intellij.plugins.systemdunitfiles.psi.UnitFilePropertyType
915import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.SemanticDataRepository
1016import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.Validator
11- import java.io.BufferedReader
1217import java.io.IOException
1318import java.io.InputStream
14- import java.io.InputStreamReader
1519import java.util.*
1620
1721/* *
@@ -44,12 +48,8 @@ class UnitDependencyOptionValue : OptionValueInformation {
4448 }
4549
4650 override fun getAutoCompleteOptions (project : Project ): Set <String > {
47- val autoCompletionOptions: MutableSet <String > = HashSet (unitNames)
48- for (unitTypes in validUnitTypes) {
49- for (file in FilenameIndex .getAllFilesByExt(project, unitTypes)) {
50- autoCompletionOptions.add(file.name)
51- }
52- }
51+ val autoCompletionOptions = CollectionFactory .createSmallMemoryFootprintSet(unitNames ? : emptySet())
52+ autoCompletionOptions.addAll(getAllProjectUnitFileNames(project))
5353 return autoCompletionOptions
5454 }
5555
@@ -82,8 +82,8 @@ class UnitDependencyOptionValue : OptionValueInformation {
8282 val unitType = word.substring(lastDot + 1 )
8383 if (! validUnitTypes.contains(unitType)) {
8484 holder.registerProblem(
85- property.valueNode.psi, range,
86- " Unit type " + unitType + " is unsupported, valid types are: " + Strings .join(validUnitTypes, " , " )
85+ property.valueNode.psi, range,
86+ " Unit type " + unitType + " is unsupported, valid types are: " + Strings .join(validUnitTypes, " , " )
8787 )
8888 }
8989 } else {
@@ -97,6 +97,51 @@ class UnitDependencyOptionValue : OptionValueInformation {
9797 override val validatorName: String
9898 get() = VALIDATOR_NAME
9999
100+ /* *
101+ * That's a simplified version of `com.intellij.psi.search.FilenameIndex.getAllFilesByExt()`
102+ * since we need only file names, but not whole VirtualFile's
103+ */
104+ private fun getAllProjectUnitFileNames (project : Project ): Set <String > {
105+ return CachedValuesManager .getManager(project).getCachedValue(project, CachedValueProvider {
106+ return @CachedValueProvider CachedValueProvider .Result <Set <String >>(
107+ getAllProjectUnitFileNamesImpl(project),
108+ getFilenameIndexModificationTracker(),
109+ )
110+ })
111+ }
112+
113+ /*
114+ * Simplified copy of com.intellij.openapi.fileEditor.impl.UniqueVFilePathBuilderImpl.getFilenameIndexModificationTracker
115+ * Assuming FileBasedIndexExtension.USE_VFS_FOR_FILENAME_INDEX == true (it was set so at least since 2022.2)
116+ */
117+ private fun getFilenameIndexModificationTracker (): ModificationTracker {
118+ return ModificationTracker {
119+ @Suppress(" UnstableApiUsage" )
120+ FSRecords .getNamesIndexModCount()
121+ }
122+ }
123+
124+ private fun getAllProjectUnitFileNamesImpl (project : Project ): Set <String > {
125+ val names = CollectionFactory .createSmallMemoryFootprintSet<String >()
126+ val minNameLength = validUnitTypes.minOf { it.length } + 2 /* dot and at least on character in name */
127+ val maxExtLength = validUnitTypes.maxOf { it.length }
128+
129+ processAllFileNames({ name: String ->
130+ val length = name.length
131+ if (length >= minNameLength) {
132+ val dot = name.lastIndexOf(' .' )
133+ if (dot != - 1 && (length - (dot + 1 ) <= maxExtLength)) {
134+ val ext = name.substring(dot + 1 )
135+ if (ext in validUnitTypes || ext.lowercase() in validUnitTypes) {
136+ names.add(name)
137+ }
138+ }
139+ }
140+ true
141+ }, GlobalSearchScope .allScope(project), null )
142+ return names
143+ }
144+
100145 companion object {
101146 @Volatile
102147 private var unitNames: Set <String >? = null
0 commit comments